3 -- You can use this with regular lua, but if you use something
4 -- luajit, you'll be able to get stack traces when things go
5 -- wrong in the coroutine.
7 function IsInInstance() return false end
8 function UnitIsDeadOrGhost() return false end
12 QuestHelper_Pref = {perf_scale=1}
14 math.randomseed(os.time())
16 loadfile("../routing.lua")()
18 function QuestHelper:DumpRoute(file)
19 local stream = io.open(file or "routetest.svg", "w")
21 stream:write([[<?xml version="1.0" standalone="no"?>]], "\n",
22 [[<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">]], "\n",
23 [[<svg width="512" height="512">]], "\n")
25 stream:write([[<circle cx="]], self.pos[3]*32, [[" cy="]], self.pos[4]*32,
26 [[" r="16" fill="green" stroke="black" stroke-width="1" />]], "\n")
27 for i, obj in pairs(self.route) do
28 stream:write([[<circle cx="]], obj.pos[3]*32, [[" cy="]], obj.pos[4]*32,
29 [[" r="16" fill="yellow" stroke="black" stroke-width="1" />]], "\n")
33 stream:write([[<polyline points="]])
34 stream:write(self.pos[3]*32,",",self.pos[4]*32)
35 for i, obj in pairs(self.route) do
36 stream:write(",",obj.pos[3]*32,",",obj.pos[4]*32)
38 stream:write([[" fill="none" stroke="orange" stroke-width="4"/>]], "\n")
40 stream:write([[<text x="]], self.pos[3]*32, [[" y="]], self.pos[4]*32, [[" fill="black" font-size="12" text-anchor="middle">]], "player", "</text>\n")
41 for i, obj in pairs(self.route) do
42 stream:write([[<text x="]], obj.pos[3]*32, [[" y="]], obj.pos[4]*32, [[" fill="black" font-size="12" text-anchor="middle">]], obj.name, "</text>\n")
45 stream:write("</svg>\n")
70 local function colour(a, r, g, b)
72 a, r, g, b = tonumber(a, 16), tonumber(r, 16), tonumber(g, 16), tonumber(b, 16)
74 if r and g and b and a then
75 a = a*0.00001537870049980776624375240292195309496347558631295655517108804306
76 r, g, b = r*a, g*a, b*a
78 for code, values in pairs(colours) do
79 local u, v, w = values[1]-r, values[2]-g, values[3]-b
81 if not best or d < dist then
86 return ("\027[%dm"):format(best)
89 -- Not a valid colour code, keep original string.
93 local function convertcodes(text)
94 return (text:gsub("|c(..)(..)(..)(..)", colour):gsub("|r", "\027[93m"):gsub("||", "|"))
98 return x ~= nil and (tostring(x) or "???") or "nil"
101 -- We'll also create a print function that understands Warcraft's colour codes.
102 function QuestHelper:TextOut(...)
103 local c = select("#", ...)
106 io.write("\027[96mQuestHelper: \027[93m")
107 io.write(convertcodes(ts(...)))
111 io.write("\027[97m, \027[93m")
112 io.write(convertcodes(ts(select(c, ...))))
116 io.write("\027[39m\n")
120 QuestHelper.to_add = {}
121 QuestHelper.route = {}
122 QuestHelper.to_remove = {}
126 function QuestHelper:CreateTable()
127 local tbl = next(mem)
136 function QuestHelper:ReleaseTable(tbl)
139 for key in pairs(tbl) do tbl[key] = nil end
142 function QuestHelper:ComputeTravelTime(a, b)
143 local x, y = a[3]-b[3], a[4]-b[4]
144 return math.sqrt(x*x+y*y)
147 function QuestHelper:CreateWorldMapWalker()
150 RouteChanged = function()
151 io.write("Route changed: ")
153 for i, obj in ipairs(QuestHelper.route) do
154 io.write(obj.name, " ")
157 if #QuestHelper.route == 0 then
158 io.write("<empty route>")
168 function QuestHelper:CreateMipmapDodad()
171 SetObjective = function(self, obj)
172 print("First objective set to "..(obj and obj.name or "(NONE)"))
177 QuestHelper.pos, QuestHelper.i, QuestHelper.c, QuestHelper.z, QuestHelper.x, QuestHelper.y = {nil, {}}, 1, 1, 1, math.random()*14+1, math.random()*14+1
178 QuestHelper.zone_nodes = {{c=1,z=1,i=1}}
179 QuestHelper.continent_scales_x = {1}
180 QuestHelper.continent_scales_y = {1}
182 QuestHelper.Astrolabe =
184 TranslateWorldMapPosition = function(self, c, z, x, y, c2, z2)
189 local function createNode(name, x, y)
193 position = {{c=1}, nil, x, y},
199 p = QuestHelper.zone_nodes[QuestHelper.i],
200 zones = {[QuestHelper.i] = true},
204 PrepareRouting = function (self)
205 self.location = self.position
206 self.prepared = self.prepared + 1
208 DoneRouting = function (self)
209 assert(self.prepared > 0)
210 if self.prepared == 1 then
213 self.prepared = self.prepared - 1
215 TravelTime = function(self, pos)
216 if not pos then error("Oh no!", 2) end
217 assert(self.prepared > 0)
218 local x, y = self.position[3]-pos[3], self.position[4]-pos[4]
219 return math.sqrt(x*x+y*y), self.position
221 TravelTime2 = function(self, pos1, pos2)
222 assert(self.prepared > 0)
223 if not pos1 then error("Oh no1!", 2) end
224 if not pos2 then error("Oh no2!", 2) end
225 local x1, y1 = self.position[3]-pos1[3], self.position[4]-pos1[4]
226 local x2, y2 = self.position[3]-pos2[3], self.position[4]-pos2[4]
227 return math.sqrt(x1*x1+y1*y1), math.sqrt(x2*x2+y2*y2), self.position
233 QuestHelper.to_add[createNode(string.format("R%02d", i),math.random()*14+1, math.random()*14+1)] = true
237 QuestHelper.to_add[createNode(string.format("O%02d", i),8+math.cos(i/10*math.pi)*7, 8+math.sin(i/10*math.pi)*7)] = true
241 QuestHelper.to_add[createNode(string.format("M%02d", i),8+math.cos(i/9*math.pi)*5, 8+math.sin(i/9*math.pi)*5)] = true
245 QuestHelper.to_add[createNode(string.format("I%02d", i),8+math.cos(i/5*math.pi)*3, 8+math.sin(i/5*math.pi)*3)] = true
248 local future_remove = {}
249 for o in pairs(QuestHelper.to_add) do
250 future_remove[o] = true
255 QuestHelper.minimap_dodad = QuestHelper:CreateMipmapDodad()
258 QuestHelper:RunCoroutine()
262 if count == 500000 then
263 print("Now removing objectives.")
264 for o in pairs(future_remove) do
265 QuestHelper.to_remove[o] = true
269 if #QuestHelper.route == 0 then break end
271 --[[for i, o in ipairs(QuestHelper.route) do
272 io.write(o.name, " ")