overlay/dynoverlay.lua

by hugeblank
591 days agolua
COPY
1
-- Dynmap 3d & 2d Overlay
2
-- hugeblank, May 2023
3
-- Displays the owner, name and color of the claim you're currently in. 
4
-- Extends functionality of dynoverlay.lua by adding the ability to view the claims as bounding boxes on a 3d canvas.
5
-- Partailly uses dead reckoning to keep location up to date instead of spamming gps calls.
6

7
-- Settings:
8
-- dynoverlay.canvas.x - The x coordinate that the 2d overlay displays on (default: 8)
9
-- dynoverlay.canvas.y - The y coordinate that the 2d overlay displays on (default: 16)
10
-- dynoverlay.cuboid.pollRate - The frequency at which to poll gps servers in seconds (default: 5)
11
-- dynoverlay.cuboid.renderDistance - The boundary at which claims no longer render (default: 64)
12
-- dynoverlay.cuboid.opacity - The opacity of the claim cuboid overlays (default: 32)
13
-- dynoverlay.cuboid.enable - Whether to enable the cuboid view on program start (default: false)
14
-- dynoverlay.cuboid.shaders - Whether to enable shader mode. Divides the colors of claims by 8. (default: false)
15

16
assert(chatbox, "Chatbox required")
17
local dynmap = require("dynmap") -- Get the dynmap API from: https://p.sc3.io/hxHMUvEx8y
18
local mods = peripheral.wrap("back")
19
assert(mods, "Must be used on a Neural Interface")
20
assert(peripheral.find("modem"), "Modem required")
21
assert(mods.canvas, "Overlay Glasses required")
22
-- If you do not have an introspection module, an entity sensor can suffice. Uncomment out the following line, and comment out the one below it.
23
--local getMeta = assert(function() return mods.getMetaByName(<USERNAME>) end, "Entity sensor required")
24
local getMeta = assert(mods.getMetaOwner, "Introspection Module & Entity Sensor required")
25
local canvas = mods.canvas3d()
26
local infocanvas, blockcanvas = mods.canvas().addGroup({settings.get("dynoverlay.canvas.x", 8),settings.get("dynoverlay.canvas.y", 16)}), canvas.create()
27
local name, owner, status = infocanvas.addText({0,0}, ""), infocanvas.addText({0,9}, ""), infocanvas.addText({0,17}, "")
28
local pollRate = settings.get("dynoverlay.cuboid.pollRate", 5)
29
local renderDistance = settings.get("dynoverlay.cuboid.renderDistance", 64)
30
local opacity = settings.get("dynoverlay.cuboid.opacity", 32)
31
local enabled = settings.get("dynoverlay.cuboid.enable", false)
32
local shaders = settings.get("dynoverlay.cuboid.shaders", false)
33
name.setScale(1)
34
owner.setScale(0.8)
35
status.setScale(0.8)
36

37
local _, claims, meta, refreshed
38
local x, y, z = gps.locate()
39
local rx, ry, rz = x, y, z
40
local function setClaimColor(element, color, shadersOverride)
41
    local c = tonumber(color:sub(2, -1), 16)
42
    local rgb = {}
43
    for i = 3, 1, -1 do
44
        rgb[i] = c%256
45
        if shaders and not shadersOverride then
46
            rgb[i] = rgb[i]/8
47
        end
48
        c = math.floor(c/256)
49
    end
50
    element.setColor(table.unpack(rgb))
51
end
52

53
local function place(claim, xoff, zoff)
54
    local box = blockcanvas.addBox(claim.xmin-xoff+0.5, -64, claim.zmin-zoff+0.5)
55

56
    setClaimColor(box, claim.color)
57
    box.setDepthTested(true)
58
    box.setSize(claim.xmax-claim.xmin-1, 320, claim.zmax-claim.zmin-1)
59
    box.setAlpha(opacity)
60
    claim.box = box
61
end
62

63
local poll = math.floor(30/pollRate)
64
local resetClaims = 0
65
local dimension = "overworld"
66

67
local function refreshClaims()
68
    local ok, results = dynmap.getClaims(true, nil, dimension)
69
    if ok then
70
        for _, claim in ipairs(results) do
71
            claim.label = claim.label:gsub("&amp;", "&"):gsub("&#39;", "'"):gsub("&quot;", '"')
72
        end
73
        claims = results
74
    end
75
    refreshed = true
76
    resetClaims = 0
77
end
78

79
local function refresh()
80
    while true do
81
        if resetClaims == poll then
82
            refreshClaims()
83
        else
84
            resetClaims = resetClaims+1
85
        end
86
        sleep(pollRate)
87
        local dx, dy, dz = gps.locate()
88
        if dx then
89
            x, y, z = dx, dy, dz
90
            if claims and enabled then
91
                rx, ry, rz = dx, dy, dz
92
                blockcanvas.recenter(0-meta.deltaPosX,0,0-meta.deltaPosZ)
93
                for _, claim in ipairs(claims) do
94
                    if claim.box then
95
                        local xminOff, zminOff = claim.xmin-dx+0.5, claim.zmin-dz+0.5
96
                        claim.box.setPosition(xminOff, -64, zminOff)
97
                    end
98
                end
99
            end
100
        end
101
    end
102
end
103

104
local function getClaimInfo()
105
    while true do
106
        if x and claims then
107
            local found = false
108
            for _, claim in ipairs(claims) do
109
                if claim.xmin < x and claim.zmin < z and claim.xmax > x and claim.zmax > z then
110
                    setClaimColor(name, claim.color, true)
111
                    setClaimColor(owner, claim.color, true)
112
                    setClaimColor(status, claim.color, true)
113
                    name.setText(claim.label)
114
                    owner.setText(claim.owner)
115
                    found = true
116
                    break
117
                end
118
            end
119
            if not found then
120
                name.setText("")
121
                owner.setText("")
122
            end
123

124
        end
125
        sleep()
126
    end
127
end
128

129
local function velocity()
130
    while true do
131
        meta = getMeta()
132
        x, z = x+meta.deltaPosX, z+meta.deltaPosZ
133
    end
134
end
135

136
local function testOffsetPair(xoff, zoff, orr)
137
    if orr then
138
        return xoff <= renderDistance or zoff <= renderDistance
139
    else
140
        return xoff <= renderDistance and zoff <= renderDistance
141
    end
142
end
143

144
local function replace()
145
    while true do
146
        if x and claims and enabled then
147
            if refreshed then
148
                blockcanvas.clear()
149
            end
150
            for _, claim in ipairs(claims) do
151
                if refreshed and claim.box then
152
                    claim.box.remove()
153
                    claim.box = nil
154
                end
155
                local xminOff, zminOff, xmaxOff, zmaxOff = math.abs(claim.xmin-x), math.abs(claim.zmin-z), math.abs(claim.xmax-x), math.abs(claim.zmax-z)
156
                --                                  Test x edges                                                                 Test z edges                                           Test -x -z corner                   Test -x +z corner                   Test +x +z corner                    Test +x -z corner
157
                if ((claim.xmin < x and claim.xmax > x) and testOffsetPair(zminOff, zmaxOff, true)) or ((claim.zmin < z and claim.zmax > z) and testOffsetPair(xminOff, xmaxOff, true)) or (testOffsetPair(xminOff, zminOff) or testOffsetPair(xminOff, zmaxOff) or testOffsetPair(xmaxOff, zmaxOff) or testOffsetPair(xmaxOff, zminOff)) then 
158
                    if not claim.box then
159
                        place(claim, rx, rz)
160
                    end
161
                    if claim.xmin < x and claim.zmin < z and claim.xmax >= x and claim.zmax >= z then
162
                        claim.box.setAlpha(0)
163
                    else
164
                        claim.box.setAlpha(opacity)
165
                    end
166
                elseif claim.box then
167
                    claim.box.remove()
168
                    claim.box = nil
169
                end
170
            end
171
            if refreshed then
172
                refreshed = false
173
            end
174
        end
175
        sleep()
176
    end 
177
end
178

179
local function keybind()
180
    local ctrl = false
181
    while true do
182
        local e, key = os.pullEvent()
183
        if e == "key" then
184
            if keys.leftCtrl == key then
185
                ctrl = true
186
            elseif keys.c == key and ctrl then
187
                enabled = not enabled
188
                for _, claim in ipairs(claims) do
189
                    if claim.box then
190
                        claim.box.remove()
191
                        claim.box = nil
192
                    end
193
                end
194
                blockcanvas.clear()
195
            end
196
        elseif e == "key_up" then
197
            if keys.leftCtrl == key then
198
                ctrl = false
199
            end
200
        end
201
    end
202
end
203

204
local function renderstatus()
205
    local prevenabled = enabled
206
    local hold, fade = 0, 0
207
    while true do
208
        if prevenabled ~= enabled then
209
            if enabled then
210
                status.setText("Claim rendering enabled")
211
                status.setAlpha(255)
212
                hold, fade = 20, 20
213
            else
214
                status.setText("Claim rendering disabled")
215
                status.setAlpha(255)
216
                hold, fade = 20, 20
217
            end
218
            prevenabled = enabled
219
        end
220
        if hold == 0 and fade ~= 0 then
221
            status.setAlpha(255*(fade/20))
222
            fade = fade-1
223
            if fade == 0 then
224
                hold, fade = 0, 0
225
            end
226
        elseif fade ~= 0 then
227
            hold = hold-1
228
        end
229
        sleep()
230
    end
231
end
232

233
local function worldcheck()
234
    local username = getMeta().name
235
    local players = chatbox.getPlayers()
236
    for _, player in ipairs(players) do
237
        if player.name == username then
238
            dimension = player.world:gsub("minecraft:", "")
239
        end
240
    end
241
    refreshClaims()
242
    while true do
243
        local _, name, _, destination = os.pullEvent("world_change")
244
        if name == username then
245
            dimension = destination:gsub("minecraft:", "")
246
            refreshClaims()
247
        end
248
    end
249

250
end
251

252
parallel.waitForAny(worldcheck, refresh, getClaimInfo, velocity, replace, keybind, renderstatus)
253