pretend the user's at the flightpoint ending
[QuestHelper.git] / Development / routetest
blob3815a48a950ed8d3301d554040de61a93f079228
1 #!/usr/bin/env lua
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
10 QuestHelper = {}
11 QuestHelper_File = {}
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")
20   if stream then
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")
24     
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")
30     end
31     
32     
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)
37     end
38     stream:write([[" fill="none" stroke="orange" stroke-width="4"/>]], "\n")
39     
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")
43     end
44     
45     stream:write("</svg>\n")
46     io.close(stream)
47   end
48 end
50 local colours =
51  {
52   [30] = {0, 0, 0},
53   [31] = {.5, 0, 0},
54   [32] = {0, .5, 0},
55   [33] = {.5, .5, 0},
56   [34] = {0, 0, .5},
57   [35] = {.5, 0, .5},
58   [36] = {0, .5, .5},
59   [37] = {.7, .7, .7},
60   [90] = {.4, .4, .4},
61   [91] = {1, 0, 0},
62   [92] = {0, 1, 0},
63   [93] = {1, 1, 0},
64   [94] = {0, 0, 1},
65   [95] = {1, 0, 1},
66   [96] = {0, 1, 1},
67   [97] = {1, 1, 1}
68  }
70 local function colour(a, r, g, b)
71   local best, dist
72   a, r, g, b = tonumber(a, 16), tonumber(r, 16), tonumber(g, 16), tonumber(b, 16)
73   
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
77     
78     for code, values in pairs(colours) do
79       local u, v, w = values[1]-r, values[2]-g, values[3]-b
80       local d = u*u+v*v+w*w
81       if not best or d < dist then
82         best, dist = code, d
83       end
84     end
85     
86     return ("\027[%dm"):format(best)
87   end
88   
89   -- Not a valid colour code, keep original string.
90   return
91 end
93 local function convertcodes(text)
94   return (text:gsub("|c(..)(..)(..)(..)", colour):gsub("|r", "\027[93m"):gsub("||", "|"))
95 end
97 local function ts(x)
98  return x ~= nil and (tostring(x) or "???") or "nil"
99 end
101 -- We'll also create a print function that understands Warcraft's colour codes.
102 function QuestHelper:TextOut(...)
103   local c = select("#", ...)
104   
105   if c > 0 then
106     io.write("\027[96mQuestHelper: \027[93m")
107     io.write(convertcodes(ts(...)))
108     
109     if c > 1 then
110       for c = 2,c do
111         io.write("\027[97m, \027[93m")
112         io.write(convertcodes(ts(select(c, ...))))
113       end
114     end
115     
116     io.write("\027[39m\n")
117   end
120 QuestHelper.to_add = {}
121 QuestHelper.route = {}
122 QuestHelper.to_remove = {}
124 local mem = {}
126 function QuestHelper:CreateTable()
127   local tbl = next(mem)
128   if tbl then
129     mem[tbl] = nil
130     return tbl
131   else
132     return {}
133   end
136 function QuestHelper:ReleaseTable(tbl)
137   assert(not mem[tbl])
138   mem[tbl] = true
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()
148   return
149    {
150     RouteChanged = function()
151       io.write("Route changed: ")
152       
153       for i, obj in ipairs(QuestHelper.route) do
154         io.write(obj.name, " ")
155       end
156       
157       if #QuestHelper.route == 0 then
158         io.write("<empty route>")
159       end
160       
161       io.write("\n")
162       
163       self:DumpRoute()
164     end
165    }
168 function QuestHelper:CreateMipmapDodad()
169   return
170    {
171     SetObjective = function(self, obj)
172       print("First objective set to "..(obj and obj.name or "(NONE)"))
173     end
174    }
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)
185     return x, y
186   end
189 local function createNode(name, x, y)
190   return
191    {
192     name = name,
193     position = {{c=1}, nil, x, y},
194     before = {},
195     after = {},
196     prepared = 0,
197     priority = 3,
198     real_priority = 3,
199     p = QuestHelper.zone_nodes[QuestHelper.i],
200     zones = {[QuestHelper.i] = true},
201     Known = function ()
202       return true
203     end,
204     PrepareRouting = function (self)
205       self.location = self.position
206       self.prepared = self.prepared + 1
207     end,
208     DoneRouting = function (self)
209       assert(self.prepared > 0)
210       if self.prepared == 1 then
211         self.location = nil
212       end
213       self.prepared = self.prepared - 1
214     end,
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
220     end,
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
228     end
229    }
232 for i = 1,30 do
233   QuestHelper.to_add[createNode(string.format("R%02d", i),math.random()*14+1, math.random()*14+1)] = true
236 for i = 1,20 do
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
240 for i = 1,18 do
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
244 for i = 1,10 do
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
253 local count = 0
255 QuestHelper.minimap_dodad = QuestHelper:CreateMipmapDodad()
257 while true do
258   QuestHelper:RunCoroutine()
259   
260   count = count + 1
261   
262   if count == 500000 then
263     print("Now removing objectives.")
264     for o in pairs(future_remove) do
265       QuestHelper.to_remove[o] = true
266     end
267   end
268   
269   if #QuestHelper.route == 0 then break end
270   
271   --[[for i, o in ipairs(QuestHelper.route) do
272     io.write(o.name, " ")
273   end
274   io.write("\n")]]