You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

153 lines
4.4 KiB

local _, T = ...
local EV = T.Evie
local function GetCompletedMissionInfo(mid)
local ma = C_Garrison.GetCompleteMissions(123)
for i=1,#ma do
if ma[i].missionID == mid then
return ma[i]
end
end
end
local LR_MissionID, LR_Novelty
local generateCheckpoints do
local hex = {}
for i=0,12 do hex[i] = ("%x"):format(i) end
local function checkpointBoard(b)
local r = ""
for i=0,12 do
local lh = b[i] or 0
if lh > 0 then
r = (r ~= "" and r .. "_" or "") .. hex[i] .. ":" .. lh
end
end
return r
end
function generateCheckpoints(cr)
local eei = cr.environment
local envs = eei and eei.autoCombatSpellInfo
local checkpoints, b = {}, {[-1]=envs and true or nil}
for i=1,#cr.encounters do
local e = cr.encounters[i]
b[e.boardIndex] = e.health
end
for _, v in pairs(cr.followers) do
b[v.boardIndex] = v.health
end
checkpoints[0] = checkpointBoard(b)
for t=1,#cr.log do
local e = cr.log[t].events
for i=1,#e do
local ti = e[i].targetInfo
local cidx = e[i].casterBoardIndex
if not b[cidx] then
return false
end
for i=1,ti and #ti or 0 do
local tii = ti[i]
local tidx = tii.boardIndex
if not b[tidx] then
return false
elseif tii.newHealth then
b[tidx] = tii.newHealth
end
end
end
checkpoints[t] = checkpointBoard(b)
end
if checkpoints[#checkpoints] == checkpoints[#checkpoints-1] then
checkpoints[#checkpoints] = nil
end
return true, checkpoints
end
end
local function checkpointMatch(truth, sim)
if truth == sim then return true end
for u, top, range in sim:gmatch("(.:)(%d+)%-?(%d*)") do
local rh = truth:match(u .. "(%d+)")
if not rh then return false end
rh = rh + 0
top, range = top + 0, range ~= "" and range+0 or 0
if not (rh <= top and rh >= (top-range)) then
return false
end
end
for u in truth:gmatch("(.:)") do
if not sim:match(u .. "%d") then
return false
end
end
return true
end
local function checkSim(cr, checkpoints)
local eei = cr.environment
local envs = eei and eei.autoCombatSpellInfo
local sim = T.VSim:New(cr.followers, cr.encounters, envs, cr.missionID, cr.missionScalar, 0)
sim:AddFightLogOracles(cr.log)
sim:Run()
local outcome = (not sim.won) == (not cr.winner)
if #checkpoints ~= #sim.checkpoints then
return false, outcome
end
for i=0,#checkpoints do
if not checkpointMatch(checkpoints[i], sim.checkpoints[i]) then
return false, outcome
end
end
return true, outcome
end
local function isNovelLog(cr, checkpoints)
local ok, ret, ret2 = pcall(checkSim, cr, checkpoints)
return not (ok and ret), ok, ret2
end
function EV:GARRISON_MISSION_COMPLETE_RESPONSE(mid, _canCom, _suc, _bonusOK, _followerDeaths, autoCombatResult)
if not (autoCombatResult and autoCombatResult.combatLog and mid and C_Garrison.GetFollowerTypeByMissionID(mid) == 123) then return end
local cr = {
log=autoCombatResult.combatLog, winner=autoCombatResult.winner, missionID=mid,
}
cr.encounters = C_Garrison.GetMissionCompleteEncounters(mid)
cr.environment = C_Garrison.GetAutoMissionEnvironmentEffect(mid)
for _, v in pairs(cr.encounters) do
v.scale, v.portraitFileDataID, v.mechanics, v.height, v.displayID = nil
if v.autoCombatSpells then
for _, s in pairs(v.autoCombatSpells) do
s.previewMask, s.schoolMask, s.icon, s.spellTutorialFlag = nil
end
end
end
if cr.environment and cr.environment.autoCombatSpellInfo then
local s = cr.environment.autoCombatSpellInfo
s.previewMask, s.schoolMask, s.icon, s.spellTutorialFlag = nil
end
local fm, mi = {}, GetCompletedMissionInfo(mid)
for i=1,#mi.followers do
local fid = mi.followers[i]
local mci = C_Garrison.GetFollowerMissionCompleteInfo(fid)
local stat = C_Garrison.GetFollowerAutoCombatStats(fid)
local spa = C_Garrison.GetFollowerAutoCombatSpells(fid, mci.level)
for _, s in pairs(spa) do
s.previewMask, s.schoolMask, s.icon, s.spellTutorialFlag = nil
end
fm[fid] = {
name=mci.name, role=mci.role, level=mci.level,
boardIndex=mci.boardIndex, health=stat.currentHealth, maxHealth=stat.maxHealth, attack=stat.attack,
spells=spa,
}
end
cr.followers = fm
cr.missionScalar = mi.missionScalar
cr.missionName = mi.name
local ok, checkpoints = generateCheckpoints(cr)
if ok then
local novel, nok, om = isNovelLog(cr, checkpoints)
LR_MissionID, LR_Novelty = mid, nok and (novel and (om and 2 or 3) or 1) or 0
end
end
function T.GetMissionReportInfo(mid)
if mid == LR_MissionID then
return LR_Novelty
end
end