Merge branch 'master' of git://cams.pavlovian.net/questhelper
[QuestHelper.git] / radar.lua
blob2315a2f7a56523a902629fdc9b92c837618c0bcc
1 QuestHelper_File["radar.lua"] = "Development Version"
2 QuestHelper_Loadtime["radar.lua"] = GetTime()
4 local tick = GetTime()
6 local anchor = nil
8 local rc = nil
10 local map = {}
12 local widgets = {}
13 local lwidth = 1.5
14 local lheight = 1.5
15 local quieted = true
17 local texparent = CreateFrame("Frame")
19 local grid = 3
21 QH_OnUpdate(function()
22 if not QuestHelper_Pref.radar then
23 if not quieted then
24 for _, v in ipairs(widgets) do
25 v[3] = nil
26 v[1]:Hide()
27 end
28 quieted = true
29 end
30 return
31 end
32 quieted = false
34 if not rc then rc = LibStub("LibRangeCheck-2.0") end
36 if tick <= GetTime() then
37 tick = tick + 1
38 if tick < GetTime() then
39 tick = GetTime()
40 end
42 local targ = UnitGUID("target")
43 if targ ~= anchor or UnitIsDead("target") then
44 for _, v in pairs(map) do QuestHelper:ReleaseTable(v) end
45 wipe(map)
46 for _, v in ipairs(widgets) do
47 v[3] = nil
48 v[1]:Hide()
49 end
50 anchor = targ
51 end
53 local minRange, maxRange = rc:GetRange('target')
55 if minRange then
56 if not maxRange then maxRange = 120 end
58 minRange = math.max(0, minRange - 1)
59 maxRange = maxRange + 1
61 local mnr, mxr = minRange * minRange, maxRange * maxRange
62 local px, py = QuestHelper.routing_ax, QuestHelper.routing_ay
64 -- first we blur
65 local newmap = QuestHelper:CreateTable("radar")
66 for x, d in pairs(map) do
67 if not newmap[x - grid] then newmap[x - grid] = QuestHelper:CreateTable("radar") end
68 if not newmap[x] then newmap[x] = QuestHelper:CreateTable("radar") end
69 if not newmap[x + grid] then newmap[x + grid] = QuestHelper:CreateTable("radar") end
71 for y, v in pairs(d) do
72 newmap[x - grid][y - grid] = (newmap[x - grid][y - grid] or 0) + v
73 newmap[x - grid][y] = (newmap[x - grid][y] or 0) + v * 2
74 newmap[x - grid][y + grid] = (newmap[x - grid][y + grid] or 0) + v
75 newmap[x][y - grid] = (newmap[x][y - grid] or 0) + v * 2
76 newmap[x][y] = (newmap[x][y] or 0) + v * 4
77 newmap[x][y + grid] = (newmap[x][y + grid] or 0) + v * 2
78 newmap[x + grid][y - grid] = (newmap[x + grid][y - grid] or 0) + v
79 newmap[x + grid][y] = (newmap[x + grid][y] or 0) + v * 2
80 newmap[x + grid][y + grid] = (newmap[x + grid][y + grid] or 0) + v
81 end
83 QuestHelper:ReleaseTable(d)
84 end
85 QuestHelper:ReleaseTable(map)
86 map = newmap
89 -- then we crop
90 local highest = 0
91 local newmap = QuestHelper:CreateTable("radar")
92 for x, d in pairs(map) do
93 local newk = QuestHelper:CreateTable("radar")
94 local something = false
95 local dx = px - x
96 dx = dx * dx
97 for y, v in pairs(d) do
98 local dy = py - y
99 dy = dy * dy
100 --print(dx + dy, mnr, mxr)
101 if dx + dy >= mnr and dx + dy <= mxr then
102 newk[y] = v
103 highest = max(highest, v)
104 something = true
108 if something then
109 newmap[x] = newk
111 QuestHelper:ReleaseTable(d)
113 QuestHelper:ReleaseTable(map)
114 map = newmap
116 -- then we normalize
117 if highest > 0 then
118 highest = 1 / highest -- I don't know if mult is faster in lua or not, but it often is
119 for x, d in pairs(map) do
120 for y, v in pairs(d) do
121 d[y] = v * highest
126 -- then we add
127 -- probably a more efficient way to do this
128 px, py = math.floor(px / grid + 0.5) * grid, math.floor(py / grid + 0.5) * grid
129 for dx = 0, maxRange, grid do
130 for dy = 0, maxRange, grid do
131 local ofs = dx * dx + dy * dy
132 if ofs >= mnr and ofs <= mxr then
133 if not map[px + dx] then map[px + dx] = QuestHelper:CreateTable("radar") end
134 if not map[px - dx] then map[px - dx] = QuestHelper:CreateTable("radar") end
135 map[px + dx][py + dy] = (map[px + dx][py + dy] or 0) + 0.001
136 if dx > 0 then
137 map[px - dx][py + dy] = (map[px - dx][py + dy] or 0) + 0.001
138 if dy > 0 then
139 map[px - dx][py - dy] = (map[px - dx][py - dy] or 0) + 0.001
142 if dy > 0 then
143 map[px + dx][py - dy] = (map[px + dx][py - dy] or 0) + 0.001
149 -- then we post
150 local widgetofs = 1
151 for x, d in pairs(map) do
152 for y, v in pairs(d) do
153 if v > 0.1 then
154 local widg = widgets[widgetofs]
155 if not widg then
156 widg = {texparent:CreateTexture()}
157 table.insert(widgets, widg)
158 widg[1]:SetWidth(lwidth)
159 widg[1]:SetHeight(lheight)
161 widgetofs = widgetofs + 1
163 widg[1]:SetTexture(0, 1, 0, math.min(1, v * 1.2))
164 widg[1]:Show()
165 widg[2] = x
166 widg[3] = y
171 for rem = widgetofs, #widgets do
172 widgets[rem][1]:Hide()
173 widgets[rem][3] = nil
178 -- here we replace the widgets
180 local rotatey = (GetCVar("rotateMinimap") == "0") and 0 or GetPlayerFacing()
181 rotatey = rotatey * 180 / 3.14159
183 local mapdiam = QuestHelper.Astrolabe:GetMapDiameter()
184 local minimap = QuestHelper.Astrolabe:GetMinimapObject()
185 local mapwid, maphei = minimap:GetWidth(), minimap:GetHeight()
187 local xds, yds = mapwid / mapdiam, maphei / mapdiam
189 local nwidth, nheight = xds * grid, yds * grid
190 if nwidth ~= lwidth or nheight ~= lheight then
191 for _, widg in pairs(widgets) do
192 widg[1]:SetWidth(nwidth)
193 widg[1]:SetHeight(nheight)
196 lwidth, lheight = nwidth, nheight
198 local xdx, xdy, ydx, ydy = cos(rotatey), -sin(rotatey), -sin(rotatey), -cos(rotatey) -- this will be wrong, but I'll figure it out
199 xdx, ydx = xdx * xds, ydx * xds
200 xdy, ydy = xdy * yds, ydy * yds
202 local px, py = QuestHelper.routing_ax, QuestHelper.routing_ay
204 for _, v in pairs(widgets) do
205 if not v[3] then break end
207 local dx, dy = v[2] - px, v[3] - py
209 v[1]:SetPoint("CENTER", Minimap, "CENTER", dx * xdx + dy * ydx, dx * xdy + dy * ydy)
210 --print("placing", dx * xdx + dy * ydx, dx * xdy + dy * ydy)
212 end, "radar")
216 if ( minimapRotationEnabled ) then
217 minimapRotationOffset = -Astrolabe.GetFacing()