Back to Home

ESO Lua File v100034

ingame/campaign/campaignbrowser_manager.lua

[◄ back to folders ]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
-- TODO: replace with CAMPAIGN_QUEUE_TYPE enum
-- this is used where the API expects a bool isGroup value instead of the enum
CAMPAIGN_QUEUE_INDIVIDUAL = false
CAMPAIGN_QUEUE_GROUP = true
ZO_CAMPAIGN_DATA_TYPE_CAMPAIGN = 1
ZO_CAMPAIGN_DATA_TYPE_QUEUE = 2
ZO_CAMPAIGN_QUEUE_STEP_INITIAL = 1
ZO_CAMPAIGN_QUEUE_STEP_COLLECTIBLE_CHECK = 2
ZO_CAMPAIGN_QUEUE_STEP_QUEUED_AS_GUEST_CHECK = 3
ZO_CAMPAIGN_QUEUE_STEP_ALLIANCE_LOCK_CHECK = 4
ZO_CAMPAIGN_QUEUE_STEP_SELECT_QUEUE_TYPE = 5
ZO_CAMPAIGN_QUEUE_STEP_PERFORM_QUEUE = 6
ZO_CampaignBrowser_Manager = ZO_CallbackObject:Subclass()
function ZO_CampaignBrowser_Manager:New(...)
    local object = ZO_CallbackObject.New(self)
    object:Initialize(...)
    return object
end
function ZO_CampaignBrowser_Manager:Initialize()
    self.selectionCampaignList = {}
    self.campaignRulesetsByType = {}
    self:RebuildCampaignData()
    local function OnCampaignSelectionDataChanged()
        self:RebuildCampaignData()
    end
    EVENT_MANAGER:RegisterForEvent("ZO_CampaignBrowserManager", EVENT_CAMPAIGN_SELECTION_DATA_CHANGED, OnCampaignSelectionDataChanged)
    local function OnCampaignQueueChanged(eventCode, campaignId)
        local campaignData = self:GetDataByCampaignId(campaignId)
        if campaignData then
            self:UpdateQueueDataState(campaignData)
        end
    end
    EVENT_MANAGER:RegisterForEvent("ZO_CampaignBrowserManager", EVENT_CAMPAIGN_QUEUE_JOINED, OnCampaignQueueChanged)
    EVENT_MANAGER:RegisterForEvent("ZO_CampaignBrowserManager", EVENT_CAMPAIGN_QUEUE_LEFT, OnCampaignQueueChanged)
    EVENT_MANAGER:RegisterForEvent("ZO_CampaignBrowserManager", EVENT_CAMPAIGN_QUEUE_STATE_CHANGED, OnCampaignQueueChanged)
    local function OnCampaignAllianceLockActivated(_, campaignId, lockedToAlliance)
        local campaignData = self:GetDataByCampaignId(campaignId)
        if campaignData then
            campaignData.lockedToAlliance = lockedToAlliance
        end
    end
    EVENT_MANAGER:RegisterForEvent("ZO_CampaignBrowserManager", EVENT_CAMPAIGN_ALLIANCE_LOCK_ACTIVATED, OnCampaignAllianceLockActivated)
end
do
    local function IsCampaignData(data)
        return data and data.type == ZO_CAMPAIGN_DATA_TYPE_CAMPAIGN
    end
    local function IsQueueData(data)
        return data and data.type == ZO_CAMPAIGN_DATA_TYPE_QUEUE
    end
    function ZO_CampaignBrowser_Manager:CanSetHomeCampaign(data)
        if IsCampaignData(data) then
            return not data.isImperialCityCampaign and GetAssignedCampaignId() ~= data.id and DoesPlayerMeetCampaignRequirements(data.id)
        end
        return false
    end
    function ZO_CampaignBrowser_Manager:DoSetHomeCampaign(data)
        if IsCampaignData(data) then
            if not ZO_CampaignBrowser_DoesPlayerMatchAllianceLock(data) then
                ZO_Dialogs_ShowPlatformDialog("CAMPAIGN_ALLIANCE_LOCKED", { campaignData = data } )
            else
                if IsInGamepadPreferredMode() then
                    local lockTimeLeft = GetCampaignReassignCooldown()
                    if lockTimeLeft > 0 then
                        ZO_Dialogs_ShowGamepadDialog(ZO_GAMEPAD_CAMPAIGN_LOCKED_DIALOG, { id = data.id, campaignData = data } )
                    else
                        ZO_Dialogs_ShowGamepadDialog(ZO_GAMEPAD_CAMPAIGN_SET_HOME_REVIEW_DIALOG, { id = data.id, campaignData = data })
                    end
                else
                    SELECT_HOME_CAMPAIGN_DIALOG:Show(data)
                end
            end
        end
    end
    function ZO_CampaignBrowser_Manager:IsPlayerInSameCampaignType(targetCampaignData)
        local currentCampaignId = GetCurrentCampaignId() 
        if currentCampaignId == targetCampaignData.id then
            return true
        end
        local currentCampaignData = self:GetDataByCampaignId(currentCampaignId) 
        if currentCampaignData == nil then
            return false
        end
        return currentCampaignData.isImperialCityCampaign == targetCampaignData.isImperialCityCampaign
    end
    function ZO_CampaignBrowser_Manager:CanQueueForCampaign(data)
        local canQueueIndividual = false
        local canQueueGroup = false
        if IsCampaignData(data) and not self:IsPlayerInSameCampaignType(data) and not IsQueuedForCampaign(data.id, CAMPAIGN_QUEUE_INDIVIDUAL) and DoesPlayerMeetCampaignRequirements(data.id) then
            if not IsActiveWorldBattleground() and not IsUnitDead("player") then
                canQueueIndividual = true
            end
            if canQueueIndividual and IsUnitGrouped("player") then
                canQueueGroup = true
            end
        end
        return canQueueIndividual, canQueueGroup
    end
    function ZO_CampaignBrowser_Manager:DoQueueForCampaign(data)
        if IsCampaignData(data) then
            local NO_QUEUE_TYPE = nil
            self:ContinueQueueForCampaignFlow(data, ZO_CAMPAIGN_QUEUE_STEP_INITIAL, NO_QUEUE_TYPE)
        end
    end
    function ZO_CampaignBrowser_Manager:ContinueQueueForCampaignFlow(campaignData, lastQueueStepExecuted, queueType)
        -- Queue steps are used to create an asynchronous flow that can be restarted by each individual dialog in the flow.
        -- each dialog knows which step it "comes from", but not which one it "goes to" so we can reorder them without changing each dialog.
        -- To finish a step without needing to stop and restart execution, we can just increment the step.
        local currentQueueStep = lastQueueStepExecuted + 1
        if currentQueueStep == ZO_CAMPAIGN_QUEUE_STEP_COLLECTIBLE_CHECK then
            if campaignData.isImperialCityCampaign then
                local collectibleData = ZO_COLLECTIBLE_DATA_MANAGER:GetCollectibleDataById(GetImperialCityCollectibleId())
                if not collectibleData:IsUnlocked() then
                    local collectibleName = collectibleData:GetName()
                    local categoryName = collectibleData:GetCategoryData():GetName()
                    local message = GetString(SI_COLLECTIBLE_LOCKED_FAILURE_CAUSED_BY_CAMPAIGN_QUEUE)
                    local marketOperation = MARKET_OPEN_OPERATION_DLC_FAILURE_CAMPAIGN_QUEUE
                    ZO_Dialogs_ShowPlatformDialog("COLLECTIBLE_REQUIREMENT_FAILED", { collectibleData = collectibleData, marketOpenOperation = marketOperation }, { mainTextParams = { message, collectibleName, categoryName } })
                    return
                end
            end
            currentQueueStep = currentQueueStep + 1
        end
        if currentQueueStep == ZO_CAMPAIGN_QUEUE_STEP_QUEUED_AS_GUEST_CHECK then
            if campaignData.id ~= GetAssignedCampaignId() then
                TUTORIAL_SYSTEM:TriggerTutorialWithDeferredAction(TUTORIAL_TRIGGER_QUEUED_FOR_CAMPAIGN_AS_GUEST, function()
                    self:ContinueQueueForCampaignFlow(campaignData, ZO_CAMPAIGN_QUEUE_STEP_QUEUED_AS_GUEST_CHECK)
                end)
                return
            end
            currentQueueStep = currentQueueStep + 1
        end
        if currentQueueStep == ZO_CAMPAIGN_QUEUE_STEP_ALLIANCE_LOCK_CHECK then
            if not ZO_CampaignBrowser_DoesPlayerMatchAllianceLock(campaignData) then
                ZO_Dialogs_ShowPlatformDialog("CAMPAIGN_ALLIANCE_LOCKED", {campaignData = campaignData})
                return
            elseif ZO_CampaignBrowserDialogs_ShouldShowAllianceLockWarning(campaignData) then
                ZO_Dialogs_ShowPlatformDialog("CAMPAIGN_ABOUT_TO_ALLIANCE_LOCK", {campaignData = campaignData})
                return
            end
            currentQueueStep = currentQueueStep + 1
        end
        if currentQueueStep == ZO_CAMPAIGN_QUEUE_STEP_SELECT_QUEUE_TYPE then
            local canQueueIndividual, canQueueGroup = self:CanQueueForCampaign(campaignData)
            if canQueueIndividual and canQueueGroup then
                if IsInGamepadPreferredMode() then
                    local campaignRulesetTypeString = GetString("SI_CAMPAIGNRULESETTYPE", campaignData.rulesetType)
                    ZO_Dialogs_ShowGamepadDialog(ZO_GAMEPAD_CAMPAIGN_QUEUE_DIALOG, {campaignData = campaignData}, {mainTextParams = {campaignRulesetTypeString, campaignData.name}})
                    return
                else
                    ZO_Dialogs_ShowDialog("CAMPAIGN_QUEUE", {campaignData = campaignData})
                    return
                end
            elseif canQueueIndividual then
                queueType = CAMPAIGN_QUEUE_TYPE_INDIVIDUAL
            elseif canQueueGroup then
                queueType = CAMPAIGN_QUEUE_TYPE_GROUP
            end
            currentQueueStep = currentQueueStep + 1
        end
        if currentQueueStep == ZO_CAMPAIGN_QUEUE_STEP_PERFORM_QUEUE then
            internalassert(queueType ~= nil, "Campaign queue flow completed without picking a queue type")
            local isGroup = queueType == CAMPAIGN_QUEUE_TYPE_GROUP
            QueueForCampaign(campaignData.id, isGroup)
            return
        end
    end
    function ZO_CampaignBrowser_Manager:CanLeaveCampaignQueue(data)
        if IsCampaignData(data) then
            local queueData = data.queue
            return CanLeaveCampaignQueue(queueData.id, queueData.isGroup) == LEAVE_CAMPAIGN_QUEUE_ERROR_NONE
        end
        return false
    end
    function ZO_CampaignBrowser_Manager:DoLeaveCampaignQueue(data)
        if IsCampaignData(data) then
            local queueData = data.queue
            if IsQueuedForCampaign(queueData.id, queueData.isGroup) then
                if queueData.state == CAMPAIGN_QUEUE_REQUEST_STATE_WAITING then
                    LeaveCampaignQueue(queueData.id, queueData.isGroup)
                elseif queueData.state == CAMPAIGN_QUEUE_REQUEST_STATE_CONFIRMING then
                    ConfirmCampaignEntry(queueData.id, queueData.isGroup, false)
                end
            end
        end
    end
end
do
    local function CompareRulesetsByDuration(rulesetIdA, rulesetIdB)
        return (GetCampaignRulesetDurationInSeconds(rulesetIdA) > GetCampaignRulesetDurationInSeconds(rulesetIdB))
    end
    function ZO_CampaignBrowser_Manager:RebuildCampaignData()
        -- Get Campaign Data
        ZO_ClearNumericallyIndexedTable(self.selectionCampaignList)
        for selectionIndex = 1, GetNumSelectionCampaigns() do
            local campaignId = GetSelectionCampaignId(selectionIndex)
            local rulesetId = GetCampaignRulesetId(campaignId)
            local campaignData = {}
            campaignData.name = ZO_CachedStrFormat(SI_CAMPAIGN_NAME, GetCampaignName(campaignId))
            campaignData.type = ZO_CAMPAIGN_DATA_TYPE_CAMPAIGN
            campaignData.id = campaignId
            campaignData.selectionIndex = selectionIndex
            campaignData.rulesetId = rulesetId
            campaignData.rulesetType = GetCampaignRulesetType(rulesetId)
            campaignData.alliancePopulation1 = GetSelectionCampaignPopulationData(selectionIndex, 1)
            campaignData.alliancePopulation2 = GetSelectionCampaignPopulationData(selectionIndex, 2)
            campaignData.alliancePopulation3 = GetSelectionCampaignPopulationData(selectionIndex, 3)
            campaignData.numGroupMembers = GetNumSelectionCampaignGroupMembers(selectionIndex)
            campaignData.numFriends = GetNumSelectionCampaignFriends(selectionIndex)
            campaignData.numGuildMembers = GetNumSelectionCampaignGuildMembers(selectionIndex)
            campaignData.canBeAllianceLocked = CanCampaignBeAllianceLocked(campaignId)
            campaignData.lockedToAlliance = GetSelectionCampaignCurrentAllianceLock(selectionIndex)
            campaignData.allianceLockReason = GetSelectionCampaignAllianceLockReason(selectionIndex)
            campaignData.allianceLockConflictingCharacterName = GetSelectionCampaignAllianceLockConflictingCharacterName(selectionIndex)
            campaignData.isImperialCityCampaign = IsImperialCityCampaign(campaignId)
            campaignData.queue = self:CreateCampaignQueueData(campaignData, CAMPAIGN_QUEUE_INDIVIDUAL)
            self.selectionCampaignList[selectionIndex] = campaignData
        end
        -- Categorize campaign data
        ZO_ClearTable(self.campaignRulesetsByType)
        
        for _, campaignData in ipairs(self.selectionCampaignList) do
            local campaignRulesetId = campaignData.rulesetId
            local campaignRulesetType = campaignData.rulesetType
            
            if not self.campaignRulesetsByType[campaignRulesetType] then
                self.campaignRulesetsByType[campaignRulesetType] = {}
            end
            local rulesetIds = self.campaignRulesetsByType[campaignRulesetType]
            if not ZO_IsElementInNumericallyIndexedTable(rulesetIds, campaignRulesetId) then
                table.insert(rulesetIds, campaignRulesetId)
            end
        end
        for _, rulesetIds in pairs(self.campaignRulesetsByType) do
            table.sort(rulesetIds, CompareRulesetsByDuration)
        end
        self:FireCallbacks("OnCampaignDataUpdated")
    end
end
function ZO_CampaignBrowser_Manager:CreateCampaignQueueData(campaignData, isGroup)
    return
    {
        type = ZO_CAMPAIGN_DATA_TYPE_QUEUE,
        id = campaignData.id,
        isGroup = isGroup,
        isQueued = IsQueuedForCampaign(campaignData.id, isGroup),
        state = GetCampaignQueueState(campaignData.id, isGroup),
        name = campaignData.name,
    }
end
function ZO_CampaignBrowser_Manager:UpdateQueueDataState(campaignData)
    local queueData = campaignData.queue
    queueData.isQueued = IsQueuedForCampaign(queueData.id, queueData.isGroup)
    queueData.state = GetCampaignQueueState(queueData.id, queueData.isGroup)
    self:FireCallbacks("OnCampaignQueueStateUpdated", campaignData)
end
function ZO_CampaignBrowser_Manager:GetCampaignDataList()
    return self.selectionCampaignList
end
function ZO_CampaignBrowser_Manager:GetActiveCampaignRulesetsByType()
    return self.campaignRulesetsByType
end
function ZO_CampaignBrowser_Manager:GetDataByCampaignId(campaignId)
    if campaignId ~= 0 then -- zero means "no campaign"
        for _, campaignData in ipairs(self.selectionCampaignList) do
            if campaignData.id == campaignId then
                return campaignData
            end
        end
    end
    return nil
end
function ZO_CampaignBrowser_Manager:GetMasterHomeData()
end
do
    local function IsAnyGroupMemberOffline()
        for i = 1, GROUP_SIZE_MAX do
            local unitTag = ZO_Group_GetUnitTagForGroupIndex(i)
            if not IsUnitOnline(unitTag) then
                return true
            end
        end
    
        return false
    end
    local QUEUE_MESSAGES = {
        [CAMPAIGN_QUEUE_REQUEST_STATE_PENDING_JOIN] = GetString(SI_CAMPAIGN_BROWSER_QUEUE_PENDING_JOIN),
        [CAMPAIGN_QUEUE_REQUEST_STATE_PENDING_LEAVE] = GetString(SI_CAMPAIGN_BROWSER_QUEUE_PENDING_LEAVE),
        [CAMPAIGN_QUEUE_REQUEST_STATE_PENDING_ACCEPT] = GetString(SI_CAMPAIGN_BROWSER_QUEUE_PENDING_ACCEPT),
    }
    
    function ZO_CampaignBrowser_Manager:GetQueueMessage(id, isGroup, state)
        local queueMessage = QUEUE_MESSAGES[state]
        
        if queueMessage then
            return true, queueMessage
        else
            local descriptionText
            local iconTexture
            if state == CAMPAIGN_QUEUE_REQUEST_STATE_WAITING then
                iconTexture = "EsoUI/Art/Campaign/campaignBrowser_queued.dds"
            elseif state == CAMPAIGN_QUEUE_REQUEST_STATE_CONFIRMING then
                iconTexture = "EsoUI/Art/Campaign/campaignBrowser_ready.dds"
            end
    
            if state == CAMPAIGN_QUEUE_REQUEST_STATE_WAITING then
                local positionInQueue = GetCampaignQueuePosition(id, isGroup)
                descriptionText = zo_strformat(SI_CAMPAIGN_BROWSER_QUEUED, positionInQueue)
            elseif state == CAMPAIGN_QUEUE_REQUEST_STATE_CONFIRMING then
                local timeString = ZO_FormatTime(GetCampaignQueueRemainingConfirmationSeconds(id, isGroup), TIME_FORMAT_STYLE_COLONS, TIME_FORMAT_PRECISION_TWELVE_HOUR)
                descriptionText = zo_strformat(SI_CAMPAIGN_BROWSER_READY, timeString)
            end
            return false, descriptionText, iconTexture
        end
    end
end
function ZO_CampaignBrowser_Manager:GenerateAllianceLockStatusMessage(campaignData)
    local _, secondsUntilCampaignEnd = GetSelectionCampaignTimes(campaignData.selectionIndex)
    local message = GetString("SI_CAMPAIGNALLIANCELOCKREASON", campaignData.allianceLockReason)
    local allianceString = ZO_SELECTED_TEXT:Colorize(ZO_CampaignBrowser_FormatPlatformAllianceIconAndName(campaignData.lockedToAlliance))
    local characterNameString = campaignData.allianceLockConflictingCharacterName and ZO_SELECTED_TEXT:Colorize(ZO_FormatUserFacingCharacterName(campaignData.allianceLockConflictingCharacterName))
    local campaignEndCooldownString = ZO_SELECTED_TEXT:Colorize(ZO_FormatTime(secondsUntilCampaignEnd, TIME_FORMAT_STYLE_SHOW_LARGEST_TWO_UNITS, TIME_FORMAT_PRECISION_TWELVE_HOUR, TIME_FORMAT_DIRECTION_DESCENDING))
    if campaignData.allianceLockReason == CAMPAIGN_ALLIANCE_LOCK_REASON_ENTERED_CAMPAIGN then
        return zo_strformat(message, allianceString, campaignEndCooldownString)
    elseif campaignData.allianceLockReason == CAMPAIGN_ALLIANCE_LOCK_REASON_CHARACTER_ASSIGNED then
        return zo_strformat(message, allianceString, characterNameString)
    elseif campaignData.allianceLockReason == CAMPAIGN_ALLIANCE_LOCK_REASON_CAMPAIGN_ENTERED_AND_ASSIGNED then
        return zo_strformat(message, allianceString, campaignEndCooldownString, characterNameString)
    end
end
CAMPAIGN_BROWSER_MANAGER = ZO_CampaignBrowser_Manager:New()
-- Global functions
do
    internalassert(CAMPAIGN_RULESET_TYPE_MAX_VALUE == 4, "Update ruleset icons")
    local CAMPAIGN_RULESET_TYPE_KEYBOARD_ICONS =
    {
        [CAMPAIGN_RULESET_TYPE_CYRODIIL] = 
        {
            up = "EsoUI/Art/LFG/LFG_indexIcon_allianceWar_up.dds",
            down = "EsoUI/Art/LFG/LFG_indexIcon_allianceWar_down.dds",
            over = "EsoUI/Art/LFG/LFG_indexIcon_allianceWar_over.dds",
        },
        [CAMPAIGN_RULESET_TYPE_IMPERIAL_CITY] = 
        {
            up = "EsoUI/Art/LFG/LFG_indexIcon_imperialCity_up.dds",
            down = "EsoUI/Art/LFG/LFG_indexIcon_imperialCity_down.dds",
            over = "EsoUI/Art/LFG/LFG_indexIcon_imperialCity_over.dds",
        },
    }
    local CAMPAIGN_RULESET_TYPE_GAMEPAD_ICONS =
    {
        [CAMPAIGN_RULESET_TYPE_CYRODIIL] = "EsoUI/Art/LFG/Gamepad/LFG_activityIcon_cyrodiil.dds",
        [CAMPAIGN_RULESET_TYPE_IMPERIAL_CITY] = "EsoUI/Art/LFG/Gamepad/LFG_activityIcon_imperialCity.dds",
    }
        return CAMPAIGN_RULESET_TYPE_KEYBOARD_ICONS[rulesetType]
    end
    function ZO_CampaignBrowser_GetGamepadIconForRulesetType(rulesetType)
        return CAMPAIGN_RULESET_TYPE_GAMEPAD_ICONS[rulesetType]
    end
end
do
    local POPULATION_ICONS =
    {
        [CAMPAIGN_POP_LOW] = "EsoUI/Art/Campaign/campaignBrowser_lowPop.dds",
        [CAMPAIGN_POP_MEDIUM] = "EsoUI/Art/Campaign/campaignBrowser_medPop.dds",
        [CAMPAIGN_POP_HIGH] = "EsoUI/Art/Campaign/campaignBrowser_hiPop.dds",
        [CAMPAIGN_POP_FULL] = "EsoUI/Art/Campaign/campaignBrowser_fullPop.dds",
    }
    function ZO_CampaignBrowser_GetPopulationIcon(population)
        return POPULATION_ICONS[population]
    end
end
    return campaignData.lockedToAlliance == ALLIANCE_NONE or campaignData.lockedToAlliance == GetUnitAlliance("player")
end
    -- Only show warning if the campaign hasn't already been entered
   return campaignData.canBeAllianceLocked and
        campaignData.allianceLockReason ~= CAMPAIGN_ALLIANCE_LOCK_REASON_ENTERED_CAMPAIGN and
        campaignData.allianceLockReason ~= CAMPAIGN_ALLIANCE_LOCK_REASON_CAMPAIGN_ENTERED_AND_ASSIGNED
end
    local ICON_SIZE = "100%"
    return zo_iconTextFormatNoSpace(GetPlatformAllianceSymbolIcon(alliance), ICON_SIZE, ICON_SIZE, GetAllianceName(alliance))
end