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
153 lines
4.4 KiB
|
5 years ago
|
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
|