Module:RandomUnitArchive

local cargo = mw.ext.cargo local List = require 'Module:ListUtil' local Hash = require 'Module:HashUtil' local Datetime = require 'Module:DatetimeUtil'

local LAUNCH = os.time {year = 2017, month = 2, day = 2, hour = 7}

local SUMMONING_EVENT_EXCEPTIONS = { [os.time {year = 2019, month = 10, day = 19, hour = 7}] = 'New Heroes: The Chosen Ones', [os.time {year = 2019, month = 12, day = 7, hour = 7}] = 'New Heroes: Desert Mercenaries', [os.time {year = 2019, month = 12, day = 19, hour = 7}] = 'New Heroes: Guardians of Peace', [os.time {year = 2020, month = 1, day =  6, hour = 7}] = 'Book IV Begins: Peony and More', }

local main = function (_, frame) local pool = cargo.query('RandomUnitPool=R,Units=U', 'R.Unit=wikiname,R.StartTime=t0,R.EndTime=t1', {		join = 'R.Unit=U.WikiName',		orderBy = 'R.StartTime,U.IntID',		limit = 5000,	}) local deltas = {} for _, v in ipairs(pool) do		v.t0 = Datetime.from_cargo(v.t0) deltas[v.t0] = deltas[v.t0] or {add = {}, del = {}} table.insert(deltas[v.t0].add, v.wikiname)

v.t1 = Datetime.from_cargo(v.t1) deltas[v.t1] = deltas[v.t1] or {add = {}, del = {}} table.insert(deltas[v.t1].del, v.wikiname) end deltas[LAUNCH] = nil -- launch time deltas[0x7FFFFFFF] = nil -- max time

local focuses = List.group_by(cargo.query( 'SummoningEvents=SE,SummoningEventFocuses=SEF,Units=U', 'SE._pageName=page,MIN(SE.StartTime)=t0,U.WikiName=wikiname', { join = 'SE.WikiName=SEF.WikiName,SEF.Unit=U.WikiName', where = "SE.EventType='New Heroes' AND U.WikiName IS NOT NULL", groupBy = 'SE._pageName,U.WikiName', limit = 5000, }), function (v) return v.page end) Hash.map_self(focuses, function (vs)		return {			t0 = Datetime.from_cargo(vs[1].t0),			units = Hash.from_ipairs(vs, function (v) return v.wikiname, true end),		}	end)

local heroes = Hash.from_ipairs(cargo.query('Units=U,MoveTypes=M,WeaponTypes=W', 'U._pageName=page,U.WikiName=wikiname,M.Sort=msort,W.Sort=wsort', { join = 'U.MoveType=M.WikiName,U.WeaponType=W.WikiName', where = "IFNULL(U.Properties__full,'') NOT LIKE '%enemy%'", limit = 1000, }), function (v) return v.wikiname, v end)

local tbl = mw.html.create('table'):addClass('wikitable'):addClass('default'):css('text-align', 'center') local row = tbl:tag('tr') row:tag('th'):wikitext('Time') row:tag('th'):css('width', '35%'):wikitext('Heroes added') row:tag('th'):css('width', '35%'):wikitext('Heroes removed') row:tag('th'):wikitext('Associated summoning event(s)')

for t, vs in Hash.sorted_pairs(deltas) do		local additions = List.to_set(vs.add)

-- associated summoning focus: -- * the summoning focus occurs before the additions -- * either all focus heroes are added to the pool, or all pool additions are part of the focus -- * the heuristic fails for 92_monsyou02 because of phina (focus-only) and bantu (pool-only) local assocFocuses = #vs.add > 0 and #vs.del == 0 and Hash.select(focuses, function (focus, focusPage)			return focus.t0 < t and ( focusPage == SUMMONING_EVENT_EXCEPTIONS[t] or				List.all(vs.add, function (v) return focus.units[v] end) or				Hash.all(focus.units, function (_, k) return additions[k] end))		end) or {}

row = tbl:tag('tr') row:tag('td'):wikitext(Datetime.ht(t)) List.reduce(vs.add, function (elem, wikiname)			local v = heroes[wikiname]			return elem:wikitext(frame:expandTemplate {title = 'UnitType', args = { name = v.page, moveSort = v.msort, weaponSort = v.wsort, size = '52'}}, '&ensp;')		end, row:tag('td')) List.reduce(vs.del, function (elem, wikiname)			local v = heroes[wikiname]			return elem:wikitext(frame:expandTemplate {title = 'UnitType', args = { name = v.page, moveSort = v.msort, weaponSort = v.wsort, size = '52'}}, '&ensp;')		end, row:tag('td')) List.reduce(Hash.keys(assocFocuses), function (elem, page)			return elem:wikitext('', page, ' ')		end, row:tag('td')) end

return tbl end

return require 'Module:MakeMWModule'.makeMWModule {main = main}