Merge branch 'master' of git://cams.pavlovian.net/questhelper
[QuestHelper.git] / collect_traveled.lua
blob02407b34d3ec4f7e9f96cefb5b1faa38c54c9f4f
1 QuestHelper_File["collect_traveled.lua"] = "Development Version"
2 QuestHelper_Loadtime["collect_traveled.lua"] = GetTime()
4 local debug_output = false
5 if QuestHelper_File["collect_traveled.lua"] == "Development Version" then debug_output = true end
7 --[[
9 Meaningful symbols it generates:
11 %d,%d,%d,%d|COMPRESSED
13 First four values: continent ID as per client, X coordinate in yards as per client via Astrolabe, Y coordinate in yards as per client via Astrolabe, faction ID (Alliance/Horde)
14 Compressed data is complicated lzw'ed hideousness.
15 Version number is probably contained in the |, I'll change that when I need to change meaning.
16 User is assumed to start facing right, all turns are 90 degrees.
18 Allowed values, post-lookup-table listed below, are:
20 ^ - forward
21 < - turn left and move forward
22 > - turn right and move forward
23 v - turn around and move forward
24 C - combo indicator, each one indicates that another next UDLR is part of a single move (the toggles are zero-time anyway)
25 S - swim toggle
26 X - taxi toggle
27 M - mount toggle
28 Y - flying mount toggle
29 D - dead/ghost toggle
33 local QHCT
34 local Merger
35 local LZW
36 local Bolus
38 local cc, cx, cy, cd = nil, nil, nil, nil
39 local flags = {}
41 local nx, ny = nil, nil
43 local function round(x) return math.floor(x + 0.5) end
44 local function dist(x, y) return math.abs(x) + math.abs(y) end -- fuck it, manhattan distance
46 -- ++ is turning right
47 local dx = {1, 0, -1, 0}
48 local dy = {0, 1, 0, -1}
50 local function InitWorking()
51 QHCT.working = {}
52 QHCT.working.prefix = ""
53 end
55 local function AddDataPrefix(data)
56 QHCT.working.prefix = QHCT.working.prefix .. data
57 end
59 local function AddData(data)
60 Merger.Add(QHCT.working, data)
61 end
63 local function FinishData()
64 return Merger.Finish(QHCT.working)
65 end
67 local function TestDirection(nd, kar)
68 if nd < 1 then nd = nd + 4 end
69 if nd > 4 then nd = nd - 4 end
71 if dist(cx + dx[nd] - nx , cy + dy[nd] - ny) < dist(cx - nx, cy - ny) then
72 AddData(kar)
73 cd = nd
74 cx = cx + dx[cd]
75 cy = cy + dy[cd]
76 return true
77 else
78 return false
79 end
80 end
82 local function CompressAndComplete(ki)
83 --QuestHelper:TextOut(string.format("%d tokens", #QHCT.compressing[ki].data))
84 local tim = GetTime()
85 local lzwed = LZW.Compress_Dicts(QHCT.compressing[ki].data, "^<>vCSXMYD")
86 if debug_output then
87 QuestHelper:TextOut(string.format("%d tokens: compressed to %d in %f", #QHCT.compressing[ki].data, #lzwed, GetTime() - tim))
88 end
90 if not QHCT.done then QHCT.done = {} end
91 table.insert(QHCT.done, QHCT.compressing[ki].prefix .. lzwed)
92 QHCT.compressing[ki] = nil
93 end
95 local function CompressFromKey(ki)
96 QH_Timeslice_Add(function () CompressAndComplete(ki) end, "lzw")
97 end
99 local function CompileData()
100 local data = FinishData()
101 local prefix = QHCT.working.prefix
103 InitWorking()
105 if #data > 0 then
106 if not QHCT.compressing then QHCT.compressing = {} end
107 local ki = GetTime()
108 while QHCT.compressing[ki] do ki = ki + 1 end -- if this ever triggers, I'm shocked
110 QHCT.compressing[ki] = {data = data, prefix = prefix}
112 CompressFromKey(ki)
116 local function AppendFlag(flagval, flagid)
117 flagval = not not flagval
118 flags[flagid] = not not flags[flagid]
119 if flagval ~= flags[flagid] then
120 if debug_output then
121 --QuestHelper:TextOut(string.format("Status toggle %s", flagid))
123 flags[flagid] = flagval
124 AddData(flagid)
128 local function QH_Collect_Traveled_Point(c, x, y, rc, rz)
129 if not c or not x or not y then return end
131 nx, ny = round(x), round(y)
132 if c ~= cc or dist(nx - cx, ny - cy) > 10 then
133 if debug_output then
134 QuestHelper:TextOut(string.format("finishing thanks to differences, %s,%s,%s vs %s,%s,%s (%s)", tostring(cc), tostring(cx), tostring(cy), tostring(c), tostring(nx), tostring(ny), cc and tostring(dist(nx - cx, ny - cy)) or "lol"))
136 CompileData()
138 cc, cx, cy, cd = c, nx, ny, 1
139 swim, mount, flying, taxi = false, false, false, false
140 AddDataPrefix(Bolus(c, x, y, rc, rz) .. strchar(tostring(QuestHelper:PlayerFaction()))) -- The playerfaction can be removed, as it's now encoded in the collection shard. Not removing it for compatibility reasons.
143 AppendFlag(IsMounted(), 'M')
144 AppendFlag(IsFlying(), 'Y')
145 AppendFlag(IsSwimming(), 'S')
146 AppendFlag(UnitOnTaxi("player"), 'X')
147 AppendFlag(UnitIsDeadOrGhost("player"), 'D')
149 for x = 1, dist(nx - cx, ny - cy) - 1 do
150 AddData('C')
153 -- first we go forward as much as is reasonable
154 while TestDirection(cd, '^') do end
156 if TestDirection(cd + 1, '>') then -- if we can go right, we do so, then we go forward again
157 while TestDirection(cd, '^') do end
158 -- In theory, if the original spot was back-and-to-the-right of us, we could need to go right *again* and then forward *again*. So we do.
159 if TestDirection(cd + 1, '>') then
160 while TestDirection(cd, '^') do end
162 elseif TestDirection(cd - 1, '<') then -- the same logic applies for left.
163 while TestDirection(cd, '^') do end
164 if TestDirection(cd - 1, '<') then
165 while TestDirection(cd, '^') do end
167 else
168 -- And we also test back, just in case.
169 if TestDirection(cd + 2, 'v') then
170 while TestDirection(cd, '^') do end
174 QuestHelper: Assert(cx == nx and cy == ny)
175 -- Done!
178 local GetRawLocation
180 local function OnUpdate()
181 QH_Collect_Traveled_Point(GetRawLocation())
184 function QH_Collect_Traveled_Init(QHCData, API)
185 -- We're actually just going to disable this for now.
186 --[[
187 Merger = API.Utility_Merger
188 QuestHelper: Assert(Merger) -- I need to get rid of this stupid space hack someday
190 LZW = API.Utility_LZW
191 QuestHelper: Assert(LZW)
193 Bolus = API.Callback_LocationBolus
194 QuestHelper: Assert(Bolus)
196 if not QHCData.traveled then QHCData.traveled = {} end
197 QHCT = QHCData.traveled
199 if not QHCT.working then InitWorking() end
201 if QHCT.compressing then for k, v in pairs(QHCT.compressing) do
202 CompressFromKey(k)
203 end end
205 GetRawLocation = API.Callback_RawLocation
206 API.Registrar_OnUpdateHook(OnUpdate)]]
209 --[[
210 function hackeryflush()
211 CompileData()
212 cc = nil