2 -- I don't know why print is giving me so much trouble, but it is, sooooo
5 for i
= 1, select("#", ...) do
7 local tst
= tostring(select(i
, ...))
8 pad
= (" "):rep(#tst
- math
.floor(#tst
/ 6) * 6 + 4)
15 require("luarocks.require")
16 require("persistence")
17 require("compile_chain")
18 require("compile_debug")
24 ll
, err
= package
.loadlib("/nfs/build/libcompile_core.so", "init")
25 if not ll
then print(err
) return end
29 -- we pretend to be WoW
33 world
.QuestHelper_File
= {}
34 world
.QuestHelper_Loadtime
= {}
35 world
.GetTime
= function() return 0 end
36 world
.QuestHelper
= { Assert
= function (self
, ...) assert(...) end, CreateTable
= function() return {} end, ReleaseTable
= function() end, IsWrath32
= function () return false end }
40 world
.bit
= {mod = function(a
, b
) return a
- math
.floor(a
/ b
) * b
end, lshift
= bit
.lshift
, rshift
= bit
.rshift
, band
= bit
.band
}
42 world
.strbyte = string.byte
43 world
.strchar = string.char
46 world
.print = function(...) print(...) end
47 world
.QH_Timeslice_Yield
= function() end
48 setfenv(loadfile("../questhelper/collect_merger.lua"), world
)()
49 setfenv(loadfile("../questhelper/collect_bitstream.lua"), world
)()
50 setfenv(loadfile("../questhelper/collect_lzw.lua"), world
)()
52 world
.QH_Collect_Merger_Init(nil, api
)
53 world
.QH_Collect_Bitstream_Init(nil, api
)
54 world
.QH_Collect_LZW_Init(nil, api
)
56 Merger
= api
.Utility_Merger
57 Bitstream
= api
.Utility_Bitstream
80 for _
, v
in ipairs(cropy
) do
83 world
.getfenv
= function (x
) assert(x
== 0 or not x
) return world
end
87 world
.GetPlayerFacing
= function () return 0 end
88 world
.MinimapCompassTexture
= {GetTexCoord
= function() return 0, 1 end}
89 world
.CreateFrame
= function () return {Hide
= function () end, SetParent
= function () end, UnregisterAllEvents
= function () end, RegisterEvent
= function () end, SetScript
= function () end} end
90 world
.GetMapContinents
= function () return "Kalimdor", "Eastern Kingdoms", "Outland", "Northrend" end
91 world
.GetMapZones
= function (z
)
93 {"Ashenvale", "Azshara", "Azuremyst Isle", "Bloodmyst Isle", "Darkshore", "Darnassus", "Desolace", "Durotar", "Dustwallow Marsh", "Felwood", "Feralas", "Moonglade", "Mulgore", "Orgrimmar", "Silithus", "Stonetalon Mountains", "Tanaris", "Teldrassil", "The Barrens", "The Exodar", "Thousand Needles", "Thunder Bluff", "Un'Goro Crater", "Winterspring"},
94 {"Alterac Mountains", "Arathi Highlands", "Badlands", "Blasted Lands", "Burning Steppes", "Deadwind Pass", "Dun Morogh", "Duskwood", "Eastern Plaguelands", "Elwynn Forest", "Eversong Woods", "Ghostlands", "Hillsbrad Foothills", "Ironforge", "Isle of Quel'Danas", "Loch Modan", "Redridge Mountains", "Searing Gorge", "Silvermoon City", "Silverpine Forest", "Stormwind City", "Stranglethorn Vale", "Swamp of Sorrows", "The Hinterlands", "Tirisfal Glades", "Undercity", "Western Plaguelands", "Westfall", "Wetlands"},
95 {"Blade's Edge Mountains", "Hellfire Peninsula", "Nagrand", "Netherstorm", "Shadowmoon Valley", "Shattrath City", "Terokkar Forest", "Zangarmarsh"},
96 {"Borean Tundra", "Crystalsong Forest", "Dalaran", "Dragonblight", "Grizzly Hills", "Howling Fjord", "Icecrown", "Sholazar Basin", "The Storm Peaks", "Wintergrasp", "Zul'Drak"},
102 world
.SetMapZoom
= function (c
, z
) tc
, tz
= c
, z
end
103 world
.GetMapInfo
= function ()
105 {"Ashenvale", "Aszhara", "AzuremystIsle", "BloodmystIsle", "Darkshore", "Darnassis", "Desolace", "Durotar", "Dustwallow", "Felwood", "Feralas", "Moonglade", "Mulgore", "Ogrimmar", "Silithus", "StonetalonMountains", "Tanaris", "Teldrassil", "Barrens", "TheExodar", "ThousandNeedles", "ThunderBluff", "UngoroCrater", "Winterspring", [0] = "Kalimdor"},
106 {"Alterac", "Arathi", "Badlands", "BlastedLands", "BurningSteppes", "DeadwindPass", "DunMorogh", "Duskwood", "EasternPlaguelands", "Elwynn", "EversongWoods", "Ghostlands", "Hilsbrad", "Ironforge", "Sunwell", "LochModan", "Redridge", "SearingGorge", "SilvermoonCity", "Silverpine", "Stormwind", "Stranglethorn", "SwampOfSorrows", "Hinterlands", "Tirisfal", "Undercity", "WesternPlaguelands", "Westfall", "Wetlands", [0] = "Azeroth"},
107 {"BladesEdgeMountains", "Hellfire", "Nagrand", "Netherstorm", "ShadowmoonValley", "ShattrathCity", "TerokkarForest", "Zangarmarsh", [0] = "Expansion01"},
108 {"BoreanTundra", "CrystalsongForest", "Dalaran", "Dragonblight", "GrizzlyHills", "HowlingFjord", "IcecrownGlacier", "SholazarBasin", "TheStormPeaks", "LakeWintergrasp", "ZulDrak", [0] = "Northrend"},
113 world
.IsLoggedIn
= function () end
115 world
.QuestHelper_File
= {}
116 world
.QuestHelper_Loadtime
= {}
117 world
.GetTime
= function() return 0 end
118 world
.QuestHelper
= { Assert
= function (self
, ...) assert(...) end, CreateTable
= function() return {} end, ReleaseTable
= function() end, TextOut
= function(qh
, ...) print(...) end, IsWrath32
= function () return false end }
120 setfenv(loadfile("../questhelper/AstrolabeQH/DongleStub.lua"), world
)()
121 setfenv(loadfile("../questhelper/AstrolabeQH/AstrolabeMapMonitor.lua"), world
)()
122 setfenv(loadfile("../questhelper/AstrolabeQH/Astrolabe.lua"), world
)()
123 setfenv(loadfile("../questhelper/upgrade.lua"), world
)()
125 world
.QuestHelper
.Astrolabe
= world
.DongleStub("Astrolabe-0.4-QuestHelper")
126 Astrolabe
= world
.QuestHelper
.Astrolabe
129 world
.QuestHelper_BuildZoneLookup()
131 QuestHelper_IndexLookup
= world
.QuestHelper_IndexLookup
132 QuestHelper_ZoneLookup
= world
.QuestHelper_ZoneLookup
135 -- LuaSrcDiet embedding
137 local world
= {arg
= {}}
138 world
.string = string
142 world
.ipairs
= ipairs
144 setfenv(loadfile("LuaSrcDiet.lua"), world
)()
147 world
.tonumber = tonumber
149 local files
= {input
= {}, output
= {}}
151 local function readgeneral(target
)
152 local rv
= target
[target
.cline
]
153 target
.cline
= target
.cline
+ 1
158 open
= function(fname
, typ
)
159 if fname
== "input" then
162 read = function(_
, wut
)
164 return readgeneral(files
.input
)
166 close
= function() end
168 elseif fname
== "output" then
172 write = function(_
, wut
, nilo
)
174 assert(not files
.output_beta
)
175 Merger
.Add(files
.output
, wut
)
177 close
= function() end
179 elseif typ
== "rb" then
180 files
.output_beta
= {}
181 for k
in Merger
.Finish(files
.output
):gmatch("[^\n]*") do
182 table.insert(files
.output_beta
, k
)
184 files
.output_beta
.cline
= 1
187 read = function(_
, wut
)
189 return readgeneral(files
.output_beta
)
191 close
= function() end
199 close
= function() end,
204 world
.arg
= {"input", "-o", "output", "--quiet", "--maximum"}
206 for k
in inp
:gmatch("[^\n]*") do
207 table.insert(files
.input
, k
)
209 files
.input
.cline
= 1
211 files
.output_beta
= nil
213 local ok
= pcall(world
.main
)
214 if not ok
then return end
216 return Merger
.Finish(files
.output
)
219 --assert(Diet(" q = 15 ") == "q=15")
220 --assert(Diet(" jbx = 15 ") == "jbx=15")
225 ChainBlock_Init("/nfs/build", "compile.lua", function ()
226 os
.execute("rm -rf intermed")
227 os
.execute("mkdir intermed")
229 os
.execute("rm -rf final")
230 os
.execute("mkdir final") end, ...)
232 math
.umod
= function (val
, med
)
234 return math
.mod(val
+ math
.ceil(-val
/ med
+ 10) * med
, med
)
236 return math
.mod(val
, med
)
240 zone_image_chunksize
= 1024
241 zone_image_descale
= 4
242 zone_image_outchunk
= zone_image_chunksize
/ zone_image_descale
247 *****************************************************************
251 function version_parse(x
)
252 if not x
then return end
255 for t
in x
:gmatch("[%d]+") do
256 table.insert(rv
, tonumber(t
))
261 function sortversion(a
, b
)
262 local ap
, bp
= version_parse(a
), version_parse(b
)
263 if not ap
and not bp
then return false end
264 if not ap
then return false end
265 if not bp
then return true end
267 if ap
[x
] ~= bp
[x
] then
274 function tablesize(tab
)
276 for _
, _
in pairs(tab
) do
282 function loc_version(ver
)
283 local major
= ver
:match("([0-9])%..*")
285 return sortversion("0.96", ver
) and 0 or 1
286 elseif major
== "1" then
287 return sortversion("1.0.2", ver
) and 0 or 1
293 function convert_loc(loc
, locale
)
294 if not loc
then return end
296 if locale
~= "enUS" then return end -- arrrgh, to be fixed eventually
298 local lr
= loc
.relative
300 loc
.c
, loc
.x
, loc
.y
= Astrolabe
:GetAbsoluteContinentPosition(loc
.rc
, loc
.rz
, loc
.x
, loc
.y
)
304 if not loc
.c
or not QuestHelper_IndexLookup
[loc
.rc
] then return end
306 if not QuestHelper_IndexLookup
[loc
.rc
] or not QuestHelper_IndexLookup
[loc
.rc
][loc
.rz
] then
307 print(loc
.c
, loc
.rc
, loc
.rz
, QuestHelper_IndexLookup
, QuestHelper_IndexLookup
[loc
.rc
])
308 print(loc
.c
, loc
.rc
, loc
.rz
, QuestHelper_IndexLookup
, QuestHelper_IndexLookup
[loc
.rc
], QuestHelper_IndexLookup
[loc
.rc
][loc
.rz
])
310 loc
.p
= QuestHelper_IndexLookup
[loc
.rc
][loc
.rz
]
311 loc
.rc
, loc
.rz
= nil, nil
316 function convert_multiple_loc(locs
, locale
)
317 if not locs
then return end
319 for _
, v
in ipairs(locs
) do
321 convert_loc(v
.loc
, locale
)
327 *****************************************************************
328 Weighted multi-concept accumulation
331 function weighted_concept_finalize(data
, fraction
, minimum
, total_needed
)
332 if #data
== 0 then return end
334 fraction
= fraction
or 0.9
335 minimum
= minimum
or 1
337 table.sort(data
, function (a
, b
) return a
.w
> b
.w
end)
339 local tw
= total_needed
342 for _
, v
in ipairs(data
) do
349 for k
, v
in ipairs(data
) do
352 if wacu
>= tw
* fraction
or (data
[k
+ 1] and data
[k
+ 1].w
< minimum
) or not data
[k
+ 1] then
360 for k
, v
in ipairs(data
) do
367 while #data
> ept
do table.remove(data
) end
373 *****************************************************************
377 function list_accumulate(item
, id
, inp
)
378 if not inp
then return end
380 if not item
[id
] then item
[id
] = {} end
383 if type(inp
) == "table" then
384 for k
, v
in pairs(inp
) do
385 t
[v
] = (t
[v
] or 0) + 1
388 t
[inp
] = (t
[inp
] or 0) + 1
392 function list_most_common(tbl
, mv
)
395 for k
, v
in pairs(tbl
) do
396 if not mcvw
or v
> mcvw
then mcv
, mcvw
= k
, v
end
402 *****************************************************************
403 Position accumulation
406 function distance(a
, b
)
409 return math
.sqrt(x
*x
+y
*y
)
412 function valid_pos(ite
)
413 if not ite
then return end
414 if not ite
.p
or not ite
.x
or not ite
.y
then return end
415 if QuestHelper_ZoneLookup
[ite
.p
][2] == 0 then return end -- this should get rid of locations showing up in "northrend" or whatever
419 function position_accumulate(accu
, tpos
)
420 if not valid_pos(tpos
) then return end
422 assert(tpos
.priority
)
424 if not accu
[tpos
.priority
] then accu
[tpos
.priority
] = {} end
425 accu
= accu
[tpos
.priority
] -- this is a bit grim
427 if not accu
[tpos
.p
] then
431 local conti
= accu
[tpos
.p
]
434 for k
, v
in ipairs(conti
) do
435 local cdist
= distance(tpos
, v
)
436 if cdist
< clodist
then
443 closest
.x
= (closest
.x
* closest
.w
+ tpos
.x
) / (closest
.w
+ 1)
444 closest
.y
= (closest
.y
* closest
.w
+ tpos
.y
) / (closest
.w
+ 1)
445 closest
.w
= closest
.w
+ 1
447 closest
= {x
= tpos
.x
, y
= tpos
.y
, w
= 1}
448 table.insert(conti
, closest
)
451 accu
.weight
= (accu
.weight
or 0) + 1
454 function position_has(accu
)
455 for c
, v
in pairs(accu
) do
461 function position_finalize(sacu
, mostest
)
462 if not position_has(sacu
) then return end
464 --[[local hi = sacu[1] and sacu[1].weight or 0
465 local lo = sacu[2] and sacu[2].weight or 0]]
468 for k
, v
in pairs(sacu
) do
469 if mostest
and k
> mostest
then continue
end
470 highest
= math
.max(highest
, k
)
472 assert(highest
> 0 or mostest
)
473 if highest
== 0 then return end
475 local accu
= sacu
[highest
] -- highest priority! :D
479 for p
, pi
in pairs(accu
) do
480 if type(p
) == "string" then continue
end
481 for _
, v
in ipairs(pi
) do
482 table.insert(pozes
, {p
= p
, x
= math
.floor(v
.x
+ 0.5), y
= math
.floor(v
.y
+ 0.5), w
= v
.w
})
486 if #pozes
== 0 then return position_finalize(sacu
, highest
- 1) end
488 return weighted_concept_finalize(pozes
, 0.8, 10)
492 *****************************************************************
493 Locale name accum functions
496 function name_accumulate(accum
, name
, locale
)
497 if not name
then return end
498 if not accum
[locale
] then accum
[locale
] = {} end
499 accum
[locale
][name
] = (accum
[locale
][name
] or 0) + 1
502 function name_resolve(accum
)
504 for k
, v
in pairs(accum
) do
505 rv
[k
] = list_most_common(v
)
511 *****************************************************************
512 Loot accumulation functions
526 loot
= {ignoreyesno
= true},
527 loot_trivial
= {ignoreyesno
= true, become
= "loot"},
529 rob
= {ignoreyesno
= true},
530 fish
= {ignoreyesno
= true},
533 function loot_accumulate(source
, sourcetok
, Output
)
534 for typ
, specs
in pairs(srces
) do
535 if not specs
.ignoreyesno
then
536 local yes
= source
[typ
.. "_yes"] or 0
537 local no
= source
[typ
.. "_no"] or 0
539 if yes
+ no
< 10 then continue
end -- DENY
541 if yes
/ (yes
+ no
) < 0.95 then continue
end -- DOUBLEDENY
544 -- We don't actually care about frequency at the moment, just where people tend to get it from. This works in most cases.
545 if source
[typ
.. "_loot"] then for k
, c
in pairs(source
[typ
.. "_loot"]) do
547 Output(tostring(k
), nil, {source
= sourcetok
, count
= c
, type = specs
.become
or typ
}, "loot")
552 for k
, _
in pairs(source
) do
553 if type(k
) ~= "string" then continue
end
554 local tag = k
:match("([^_]+)_items")
555 assert(not tag or srces
[tag])
560 *****************************************************************
561 Standard data accumulation functions
564 function standard_pos_accum(accum
, value
, lv
, locale
, fluff
)
565 if not fluff
then fluff
= 0 end
566 for _
, v
in ipairs(value
) do
567 if math
.mod(#v
, 11 + fluff
) ~= 0 then
572 for _
, v
in ipairs(value
) do
573 for off
= 1, #v
, 11 + fluff
do
574 local tite
= convert_loc(slice_loc(v
:sub(off
, off
+ 10), lv
), locale
)
575 if tite
then position_accumulate(accum
.loc
, tite
) end
580 function standard_name_accum(accum
, value
)
581 for k
, v
in pairs(value
) do
582 if type(k
) == "string" then
583 local q
= string.match(k
, "name_(.*)")
584 if q
then name_accumulate(accum
, q
, value
.locale
) end