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
331 lines
11 KiB
|
5 years ago
|
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
|