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.

331 lines
11 KiB

local _, T = ...
local EV, L, U, S = T.Evie, T.L, T.Util, T.Shadows
local SetAchievementReward do
local aid, missionCreditCriteria = 14844, {}
function SetAchievementReward(ar, mid)
if not next(missionCreditCriteria) then
for i=1,GetAchievementNumCriteria(aid) do
local _, ct, com, _, _, _, _, asid, _, cid = GetAchievementCriteriaInfo(aid, i)
if ct == 174 and asid then
missionCreditCriteria[asid] = cid*2 + (com and 1 or 0)
end
end
end
local mc = missionCreditCriteria[mid]
if (mc or 1) % 2 == 1 then
return ar:Hide()
elseif select(3, GetAchievementCriteriaInfoByID(aid, mc/2)) then
missionCreditCriteria[mid] = mc + 1
return ar:Hide()
end
ar.assetID = mid
ar.achievementID = aid
ar:Show()
end
end
local MissionPage, MissionList
function EV:GARRISON_MISSION_NPC_CLOSED()
if MissionList then
S[MissionList]:ReturnToTop()
end
end
local bufferedTentativeGroup = {}
local function ConfigureMission(me, mi, haveSpareCompanions, availAnima)
local mid = mi.missionID
local emi = C_Garrison.GetMissionEncounterIconInfo(mid)
local ms = S[me]
mi.encounterIconInfo, mi.isElite, mi.isRare = emi, emi.isElite, emi.isRare
ms.missionID, ms.baseXPReward = mid, mi.xp or 0
ms.Name:SetText(mi.name)
if (mi.description or "") ~= "" then
ms.Description:SetText(mi.description)
end
local timeNow = GetTime()
local expirePrefix, expireAt, expireRoundUp = false, nil, nil, false
ms.completableAfter = nil
if mi.offerEndTime then
expirePrefix = "|A:worldquest-icon-clock:0:0:0:0|a"
expireAt = mi.offerEndTime
elseif mi.timeLeftSeconds then
ms.completableAfter = timeNow+mi.timeLeftSeconds
ms.ProgressBar.Text:SetText("")
ms.ProgressBar:SetProgressCountdown(ms.completableAfter, mi.durationSeconds, L"Click to complete", true, true)
elseif mi.completed then
ms.completableAfter = timeNow-1
ms.ProgressBar:SetProgress(1)
ms.ProgressBar.Text:SetText(L"Click to complete")
end
ms.ProgressBar:SetMouseMotionEnabled(ms.completableAfter and ms.completableAfter <= timeNow)
ms.ExpireTime.tooltipHeader = L"Adventure Expires In:"
ms.ExpireTime.tooltipCountdownTo = expireAt
me:SetCountdown(expirePrefix, expireAt, nil, nil, 2, expireRoundUp)
ms.Rewards:SetRewards(mi.xp, mi.rewards)
SetAchievementReward(ms.AchievementReward, mid)
local cost = (mi.cost or 0) + (mi.hasTentativeGroup and U.GetTentativeMissionTroopCount(mid) or 0)
local isSufficientAnima = not availAnima or (cost <= availAnima)
local isMissionActive = not not (mi.completed or mi.timeLeftSeconds)
local veilShade = mi.timeLeftSeconds and 0.65 or 1
local showDoomRun = haveSpareCompanions and not isMissionActive and isSufficientAnima and not mi.hasTentativeGroup
local showTentative = not not mi.hasTentativeGroup and not isMissionActive
local showPendingStart = showTentative and mi.hasPendingStart
local shiftView = showDoomRun or showTentative
ms.Veil:SetShown(isMissionActive)
ms.ProgressBar:SetShown(isMissionActive and not mi.isFakeStart)
ms.ViewButton:SetShown(not isMissionActive)
ms.ViewButton:SetText(showPendingStart and L"Starting soon..." or isSufficientAnima and (showTentative and L"Edit party" or L"Select adventurers") or L"Insufficient anima")
ms.DoomRunButton:Hide()
ms.DoomRunButton:SetShown(showDoomRun)
ms.TentativeClear:SetShown(showTentative)
ms.ViewButton:SetPoint("BOTTOM", shiftView and 20 or 0, 12)
for i=1,#ms.Rewards do
ms.Rewards[i].RarityBorder:SetVertexColor(veilShade, veilShade, veilShade)
end
local mdi = C_Garrison.GetMissionDeploymentInfo(mid)
local hasNovelSpells, totalHP, totalATK, enemies = false, 0, 0, mdi.enemies
for i=1,#enemies do
local e = enemies[i]
for j=1, hasNovelSpells and 0 or #e.autoCombatSpells do
if not T.KnownSpells[e.autoCombatSpells[j].autoCombatSpellID] then
hasNovelSpells = true
end
end
totalHP, totalATK = totalHP + e.health, totalATK + e.attack
end
local tag = "[" .. (mi.missionScalar or 0) .. (mi.isElite and "+]" or mi.isRare and "*]" or "]")
if hasNovelSpells then
tag = tag .. " |TInterface/EncounterJournal/UI-EJ-WarningTextIcon:16:16|t"
end
ms.enemyATK:SetText(BreakUpLargeNumbers(totalATK))
ms.enemyHP:SetText(BreakUpLargeNumbers(totalHP))
ms.animaCost:SetText(BreakUpLargeNumbers(cost))
ms.duration:SetText(mi.duration)
ms.statLine:SetWidth(ms.duration:GetRight() - ms.statLine:GetLeft())
ms.TagText:SetText(tag)
ms:SetGroupPortraits(showTentative and U.GetTentativeGroup(mid, bufferedTentativeGroup) or U.GetInProgressGroup(mi.followers, bufferedTentativeGroup), isMissionActive, ms.Description)
me:Show()
end
local function cmpMissionInfo(a, b)
local ac, bc = a.timeLeftSeconds, b.timeLeftSeconds
if (not ac) ~= (not bc) then
return not ac
end
if ac ~= bc then
return ac < bc
end
ac, bc = a.hasPendingStart, b.hasPendingStart
if ac ~= bc then
return bc
end
ac, bc = a.hasTentativeGroup, b.hasTentativeGroup
if ac ~= bc then
return bc
end
ac, bc = a.sortGroup, b.sortGroup
if ac ~= bc then
return ac and ac > (bc or -1)
end
ac, bc = a.offerEndTime, b.offerEndTime
if ac and bc and ac ~= bc then
return ac < bc
end
ac, bc = a.durationSeconds, b.durationSeconds
if ac and bc and ac ~= bc then
return ac < bc
end
return a.name < b.name
end
local function pushMissionSet(ni, missions, skip, ...)
if not missions then return ni end
table.sort(missions, cmpMissionInfo)
for i=1, #missions do
local mid = missions[i].missionID
for j=skip and #skip or 0, 0, -1 do
if j == 0 then
ni = ni + 1, ConfigureMission(MissionList.Missions[ni], missions[i], ...)
elseif skip[j].missionID == mid then
break
end
end
end
return ni
end
local function UpdateMissions()
MissionList.dirty = nil
MissionList.clearedRewardSync = nil
local missions = C_Garrison.GetAvailableMissions(123) or {}
local inProgressMissions = C_Garrison.GetInProgressMissions(123)
local cMissions = C_Garrison.GetCompleteMissions(123)
local numFreeCompanions, numAssignedCompanions, haveUnassignedRookies, haveRookies = 0, 0, false, false do
local ft = C_Garrison.GetFollowers(123)
for i=1,#ft do
local fi = ft[i]
if fi.isCollected and fi.status ~= GARRISON_FOLLOWER_ON_MISSION then
numFreeCompanions = numFreeCompanions + 1
local hasTG = U.FollowerHasTentativeGroup(fi.followerID)
if hasTG then
numAssignedCompanions = numAssignedCompanions + 1
end
if not (haveUnassignedRookies or fi.isMaxLevel or hasTG) then
haveUnassignedRookies = true
end
end
haveRookies = haveRookies or (fi.isCollected and not fi.isMaxLevel)
end
end
EV("I_OBSERVE_AVAIL_MISSIONS", missions)
for i=1,#missions do
local m = missions[i]
local mid = m.missionID
if not m.timeLeftSeconds then
local sg = 0
for j=1, m.rewards and #m.rewards or 0 do
local i = m.rewards[j]
if i.currencyID == 1828 and sg < 3 then
sg = 3
elseif i.followerXP and sg < 2 then
sg = haveRookies and 2 or j == 1 and -1 or sg
elseif i.itemID and C_Item.IsAnimaItemByID(i.itemID) and sg < 1 then
sg = 1
elseif sg < 0 then
sg = 0
end
end
m.sortGroup = sg
end
m.hasTentativeGroup = U.MissionHasTentativeGroup(mid)
m.hasPendingStart = U.IsMissionStartingSoon(mid)
end
local ni, anima = 1, C_CurrencyInfo.GetCurrencyInfo(1813)
anima = (anima and anima.quantity or 0)
ni = pushMissionSet(ni, missions, nil, haveUnassignedRookies, anima)
ni = pushMissionSet(ni, cMissions, inProgressMissions, haveUnassignedRookies, anima)
ni = pushMissionSet(ni, inProgressMissions, nil, haveUnassignedRookies, anima)
MissionList.numMissions = ni-1
for i=ni, #MissionList.Missions do
MissionList.Missions[i]:Hide()
end
MissionPage.hasCompletedMissions = cMissions and #cMissions > 0 or false
MissionPage.UnButton:Sync()
MissionPage.CompanionCounter:SetText(numFreeCompanions-numAssignedCompanions)
end
local function CheckItemRewards(w)
local hadItems, hadUnknowns = false, false
for j=2,3 do
local rw = S[w].Rewards[j]
if rw and rw:IsShown() and rw.itemID and (not rw.itemLink or rw.itemLink:match("|h%[%]|h")) then
hadItems, hadUnknowns = true, hadUnknowns or (GetItemInfo(rw.itemLink or rw.itemID) == nil)
end
end
return hadItems, hadUnknowns
end
local function CheckRewardCache()
if MissionList.clearedRewardSync == true or not S[MissionList]:IsVisible() then
return
end
local mwa, isCleared = MissionList.Missions, true
for i=1,#mwa do
local w = mwa[i]
if w:IsShown() then
local refresh, unclear = CheckItemRewards(w)
local mi = refresh and C_Garrison.GetBasicMissionInfo(S[w].missionID)
if mi and mi.rewards then
S[w].Rewards:SetRewards(mi.xp, mi.rewards)
end
isCleared = isCleared and not unclear
end
end
MissionList.clearedRewardSync = isCleared
end
local function QueueListSync()
if S[MissionList]:IsShown() and not MissionList.dirty then
MissionList.dirty = true
C_Timer.After(0, UpdateMissions)
end
end
local function UBSync(e, o)
if MissionPage and MissionPage.UnButton then
MissionPage.UnButton:Sync()
end
if e == "I_TENTATIVE_GROUPS_CHANGED" then
QueueListSync()
elseif e == "I_COMPLETE_QUEUE_UPDATE" and (o == "DONE" or o == "ABORT") and MissionList then
S[MissionList]:CheckScrollRange()
end
end
local function MissionComplete_Toast(_, mid, won, mi)
local toast = MissionPage:AcquireToast()
local novel = T.GetMissionReportInfo and T.GetMissionReportInfo(mid)
local outSuf = novel == 1 and " |A:garrmission_countercheck:0:1.2|a" or novel == 2 and " |A:garrmission_counterhalfcheck:0:1.2|a" or novel == 3 and " |A:common-icon-redx:0:0|a" or ""
toast.Header:SetText((won and ("|cff00aaff" .. L"Victorious") or ("|cffff0000" .. L"Defeated")) .. outSuf)
if won then
toast.Sheen:SetVertexColor(0, 1, 0)
toast.PreGlow:SetVertexColor(1, 0.90, 0.90)
PlaySound(165974)
else
toast.Sheen:SetVertexColor(0, 0.66, 1)
toast.PreGlow:SetVertexColor(0.80, 0.90, 1)
PlaySound(165976)
end
toast.Detail:SetText(mi and mi.name or C_Garrison.GetMissionName(mid))
S[toast].Rewards:SetRewards(nil, mi and mi.rewards)
local nct = 0
for i=1, mi.followerInfo and #mi.followerInfo or 0 do
local fi = mi.followerInfo[i]
if fi.newLevel then
nct = nct + 1
C_Timer.After(0.075*nct, function()
local toast = MissionPage:AcquireToast(true)
toast.Sheen:SetVertexColor(0, 0.55, 1)
toast.PreGlow:SetVertexColor(1, 0.90, 0.90)
toast.Header:SetText(UNIT_LEVEL_TEMPLATE:format(fi.newLevel))
toast.Detail:SetText(fi.name)
toast.Portrait:SetTexture(fi.portraitIconID)
PlaySound(167127, nil, false)
end)
end
end
end
local function HookAndCallOnShow(frame, f)
frame:HookScript("OnShow", f)
if frame:IsVisible() then
f(frame)
end
end
function EV:I_ADVENTURES_UI_LOADED()
MissionPage = T.CreateObject("MissionPage", CovenantMissionFrame.MissionTab)
MissionList = MissionPage.MissionList
T.MissionList = MissionList
HookAndCallOnShow(CovenantMissionFrame.MissionTab.MissionList, function(self)
self:Hide()
S[MissionPage]:Show()
end)
HookAndCallOnShow(S[MissionList], function()
CovenantMissionFrameFollowers:Hide()
UpdateMissions()
end)
EV.GARRISON_MISSION_LIST_UPDATE = QueueListSync
EV.GARRISON_MISSION_FINISHED = QueueListSync
EV.I_MISSION_LIST_UPDATE = QueueListSync
EV.I_DELAYED_START_UPDATE = QueueListSync
EV.GET_ITEM_INFO_RECEIVED = CheckRewardCache
EV.I_TENTATIVE_GROUPS_CHANGED = UBSync
EV.I_MISSION_QUEUE_CHANGED = UBSync
EV.I_COMPLETE_QUEUE_UPDATE = UBSync
EV.I_MISSION_COMPLETION_STEP = MissionComplete_Toast
EV.I_UPDATE_CURRENCY_SHIFT = function(e, cid)
local p = MissionPage.ProgressCounter:GetScript("OnEvent")
p(MissionPage.ProgressCounter, e, cid)
end
return "remove"
end