better error handling with a possible flight bug
[QuestHelper.git] / collect_traveled.lua
bloba2b116a8d93571a75fe176534fca5518ffe92689
1 QuestHelper_File["collect_traveled.lua"] = "Development Version"
3 local debug_output = false
4 if QuestHelper_File["collect_traveled.lua"] == "Development Version" then debug_output = true end
6 --[[
8 Meaningful symbols it generates:
10 %d,%d,%d,%d|COMPRESSED
12 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)
13 Compressed data is complicated lzw'ed hideousness.
14 Version number is probably contained in the |, I'll change that when I need to change meaning.
15 User is assumed to start facing right, all turns are 90 degrees.
17 Allowed values, post-lookup-table listed below, are:
19 ^ - forward
20 < - turn left and move forward
21 > - turn right and move forward
22 v - turn around and move forward
23 C - combo indicator, each one indicates that another next UDLR is part of a single move (the toggles are zero-time anyway)
24 S - swim toggle
25 X - taxi toggle
26 M - mount toggle
27 Y - flying mount toggle
28 D - dead/ghost toggle
32 local QHCT
33 local Merger
34 local LZW
35 local Bolus
37 local cc, cx, cy, cd = nil, nil, nil, nil
38 local flags = {}
40 local nx, ny = nil, nil
42 local function round(x) return math.floor(x + 0.5) end
43 local function dist(x, y) return math.abs(x) + math.abs(y) end -- fuck it, manhattan distance
45 -- ++ is turning right
46 local dx = {1, 0, -1, 0}
47 local dy = {0, 1, 0, -1}
49 local function InitWorking()
50 QHCT.working = {}
51 QHCT.working.prefix = ""
52 end
54 local function AddDataPrefix(data)
55 QHCT.working.prefix = QHCT.working.prefix .. data
56 end
58 local function AddData(data)
59 Merger.Add(QHCT.working, data)
60 end
62 local function FinishData()
63 return Merger.Finish(QHCT.working)
64 end
66 local function TestDirection(nd, kar)
67 if nd < 1 then nd = nd + 4 end
68 if nd > 4 then nd = nd - 4 end
70 if dist(cx + dx[nd] - nx , cy + dy[nd] - ny) < dist(cx - nx, cy - ny) then
71 AddData(kar)
72 cd = nd
73 cx = cx + dx[cd]
74 cy = cy + dy[cd]
75 return true
76 else
77 return false
78 end
79 end
81 local function CompressAndComplete(ki)
82 --QuestHelper:TextOut(string.format("%d tokens", #QHCT.compressing[ki].data))
83 local tim = GetTime()
84 local lzwed = LZW.Compress_Dicts(QHCT.compressing[ki].data, "^<>vCSXMYD")
85 if debug_output then
86 QuestHelper:TextOut(string.format("%d tokens: compressed to %d in %f", #QHCT.compressing[ki].data, #lzwed, GetTime() - tim))
87 end
89 if not QHCT.done then QHCT.done = {} end
90 table.insert(QHCT.done, QHCT.compressing[ki].prefix .. lzwed)
91 QHCT.compressing[ki] = nil
92 end
94 local function CompressFromKey(ki)
95 QH_Timeslice_Add(function () CompressAndComplete(ki) end, "lzw")
96 end
98 local function CompileData()
99 local data = FinishData()
100 local prefix = QHCT.working.prefix
102 InitWorking()
104 if #data > 0 then
105 if not QHCT.compressing then QHCT.compressing = {} end
106 local ki = GetTime()
107 while QHCT.compressing[ki] do ki = ki + 1 end -- if this ever triggers, I'm shocked
109 QHCT.compressing[ki] = {data = data, prefix = prefix}
111 CompressFromKey(ki)
115 local function AppendFlag(flagval, flagid)
116 flagval = not not flagval
117 flags[flagid] = not not flags[flagid]
118 if flagval ~= flags[flagid] then
119 if debug_output then
120 QuestHelper:TextOut(string.format("Status toggle %s", flagid))
122 flags[flagid] = flagval
123 AddData(flagid)
127 local function QH_Collect_Traveled_Point(c, x, y, rc, rz)
128 if not c or not x or not y then return end
130 nx, ny = round(x), round(y)
131 if c ~= cc or dist(nx - cx, ny - cy) > 10 then
132 if debug_output then
133 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"))
135 CompileData()
137 cc, cx, cy, cd = c, nx, ny, 1
138 swim, mount, flying, taxi = false, false, false, false
139 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.
142 AppendFlag(IsMounted(), 'M')
143 AppendFlag(IsFlying(), 'Y')
144 AppendFlag(IsSwimming(), 'S')
145 AppendFlag(UnitOnTaxi("player"), 'X')
146 AppendFlag(UnitIsDeadOrGhost("player"), 'D')
148 for x = 1, dist(nx - cx, ny - cy) - 1 do
149 AddData('C')
152 -- first we go forward as much as is reasonable
153 while TestDirection(cd, '^') do end
155 if TestDirection(cd + 1, '>') then -- if we can go right, we do so, then we go forward again
156 while TestDirection(cd, '^') do end
157 -- 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.
158 if TestDirection(cd + 1, '>') then
159 while TestDirection(cd, '^') do end
161 elseif TestDirection(cd - 1, '<') then -- the same logic applies for left.
162 while TestDirection(cd, '^') do end
163 if TestDirection(cd - 1, '<') then
164 while TestDirection(cd, '^') do end
166 else
167 -- And we also test back, just in case.
168 if TestDirection(cd + 2, 'v') then
169 while TestDirection(cd, '^') do end
173 QuestHelper: Assert(cx == nx and cy == ny)
174 -- Done!
177 local GetRawLocation
179 local function OnUpdate()
180 QH_Collect_Traveled_Point(GetRawLocation())
183 function QH_Collect_Traveled_Init(QHCData, API)
184 Merger = API.Utility_Merger
185 QuestHelper: Assert(Merger) -- I need to get rid of this stupid space hack someday
187 LZW = API.Utility_LZW
188 QuestHelper: Assert(LZW)
190 Bolus = API.Callback_LocationBolus
191 QuestHelper: Assert(Bolus)
193 if not QHCData.traveled then QHCData.traveled = {} end
194 QHCT = QHCData.traveled
196 if not QHCT.working then InitWorking() end
198 if QHCT.compressing then for k, v in pairs(QHCT.compressing) do
199 CompressFromKey(k)
200 end end
202 GetRawLocation = API.Callback_RawLocation
203 API.Registrar_OnUpdateHook(OnUpdate)
206 --[[
207 function hackeryflush()
208 CompileData()
209 cc = nil