ESO Lua File v100010

ingame/gamepad/playermenu/playermenu.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
local function ShowLogoutDialog()
    ZO_Dialogs_ShowPlatformDialog("LOG_OUT")
end
-- a table of layout information to display a list of scenes available to the user
-- Entries are addded to the list in order, so the first entry added to the table appears at the top of the list
-- If you disable a category in PlayerMenu.lua you should also disable it in MainMenu.lua
local function GetLayoutData()
    local layoutData = {}
    local MARK_NOTIFICATIONS_NEW = true -- when we have notifications, we are always new
    local notifications = ZO_GamepadEntryData:New(
                        "",
                        "EsoUI/Art/MenuBar/Gamepad/gp_playerMenu_icon_notifications.dds")
    notifications:SetNew(MARK_NOTIFICATIONS_NEW)
    notifications.scene = "gamepad_notifications_root"
    notifications.isVisibleCallback =   function()
                                            if GAMEPAD_NOTIFICATIONS then
                                                return GAMEPAD_NOTIFICATIONS:GetNumNotifications() > 0
                                            else
                                                return false
                                            end
                                        end
    notifications.refreshCallback =     function()
                                            local numNotifications = GAMEPAD_NOTIFICATIONS and GAMEPAD_NOTIFICATIONS:GetNumNotifications() or 0
                                            local textString = zo_strformat(SI_GAMEPAD_MAIN_MENU_NOTIFICATIONS, numNotifications)
                                            notifications:SetText(textString)
                                        end
    notifications:refreshCallback()
    table.insert(layoutData, notifications)
    local market = ZO_GamepadEntryData:New(
                     GetString(SI_GAMEPAD_MAIN_MENU_MARKET_ENTRY), 
                     "EsoUI/Art/MenuBar/Gamepad/gp_PlayerMenu_icon_store.dds")
    market.scene = "gamepad_market"
    market:SetHeader(GetString(SI_GAMEPAD_MAIN_MENU_MARKET_CATEGORY_LABEL))
    market.disableWhenDead = true
    market.disableWhenSwimming = true
    market.disableWhenWerewolfForm = true
    table.insert(layoutData, market)
    local inventory = ZO_GamepadEntryData:New(
                     GetString(SI_MAIN_MENU_INVENTORY),                                     --name
                     "EsoUI/Art/MenuBar/Gamepad/gp_playerMenu_icon_inventory.dds",          --icon
                     nil,                                                                   --selected icon
                     nil,                                                                   --highlight
                     function()
                         return SHARED_INVENTORY:AreAnyItemsNew(nil, nil, BAG_BACKPACK)     --is new?
                     end)
    inventory.scene = "gamepad_inventory_root"                                              --scene name
    inventory:SetHeader(GetString(SI_PLAYER_MENU_PLAYER))                                   --header
    table.insert(layoutData, inventory)                                                     --don't forget to put it in the table!
    local skills = ZO_GamepadEntryData:New(
                     GetString(SI_MAIN_MENU_SKILLS),
                     "EsoUI/Art/MenuBar/Gamepad/gp_playerMenu_icon_skills.dds",
                     nil,
                     nil,
                     nil)
    skills.canLevel = function() return GetAttributeUnspentPoints() > 0 end
    skills.scene = "gamepad_skills_root"
    skills.canAnimate = true
    table.insert(layoutData, skills)
    
    if IsChampionSystemUnlocked() then
        local champion = ZO_GamepadEntryData:New(
                         GetString(SI_MAIN_MENU_CHAMPION), 
                         "EsoUI/Art/MenuBar/Gamepad/gp_playerMenu_icon_champion.dds",
                         nil,
                         nil,
                         function()
                            if CHAMPION_PERKS then
                                return CHAMPION_PERKS:IsChampionSystemNew()
                            end
                         end)
        champion.scene = "gamepad_championPerks_root"
        champion.canLevel = function()
            if CHAMPION_PERKS then
                return CHAMPION_PERKS:HasAnyUnspentPoints()
            end
        end 
        table.insert(layoutData, champion)
    end
    
    local character = ZO_GamepadEntryData:New(
                     GetString(SI_MAIN_MENU_CHARACTER),
                     "EsoUI/Art/MenuBar/Gamepad/gp_playerMenu_icon_character.dds")
    character.scene = "gamepad_stats_root"
    table.insert(layoutData, character)
    local journal = ZO_GamepadEntryData:New(
                     GetString(SI_MAIN_MENU_JOURNAL),
                     "EsoUI/Art/MenuBar/Gamepad/gp_playerMenu_icon_quests.dds")
    journal.scene = "gamepad_quest_journal"
    table.insert(layoutData, journal)
   local emotes = ZO_GamepadEntryData:New(
                     GetString(SI_GAMEPAD_MAIN_MENU_EMOTES),
                     "EsoUI/Art/MenuBar/Gamepad/gp_playerMenu_icon_quests.dds")
    emotes.scene = "gamepad_player_emote"
    table.insert(layoutData, emotes)
    local group = ZO_GamepadEntryData:New(
                     GetString(SI_PLAYER_MENU_GROUP),
                     "EsoUI/Art/MenuBar/Gamepad/gp_playerMenu_icon_groups.dds")
    group.scene = "gamepad_groupList"
    group:SetHeader(GetString(SI_PLAYER_MENU_MULTIPLAYER))
    table.insert(layoutData, group)
    local contacts = ZO_GamepadEntryData:New(
                     GetString(SI_MAIN_MENU_CONTACTS),
                     "EsoUI/Art/MenuBar/Gamepad/gp_playerMenu_icon_contacts.dds")
    contacts.scene = "gamepad_contacts_root"
    table.insert(layoutData, contacts)
    local guilds = ZO_GamepadEntryData:New(
                     GetString(SI_MAIN_MENU_GUILDS), 
                     "EsoUI/Art/MenuBar/Gamepad/gp_playerMenu_icon_guilds.dds")
    guilds.scene = "gamepad_guild_hub"
    table.insert(layoutData, guilds)
    local currentLevel = GetUnitLevel("player")
    if currentLevel >= GetMinLevelForCampaignTutorial() then
        local allianceWar = ZO_GamepadEntryData:New(
                         GetString(SI_MAIN_MENU_ALLIANCE_WAR),
                         "EsoUI/Art/MenuBar/Gamepad/gp_playerMenu_icon_allianceWar.dds",
                         nil,
                         nil,
                         function()
                            local tutorialId = GetTutorialId(TUTORIAL_TRIGGER_CAMPAIGN_BROWSER_OPENED)
                            if CanTutorialBeSeen(tutorialId) then
                                return not HasSeenTutorial(tutorialId)
                            end
                            return false
                         end)
        allianceWar.scene = "gamepad_campaign_root",
        table.insert(layoutData, allianceWar)
    end
    local voiceChat = ZO_GamepadEntryData:New(
                    GetString(SI_MAIN_MENU_GAMEPAD_VOICECHAT), 
                    "EsoUI/Art/MenuBar/Gamepad/gp_playerMenu_icon_VOIP.dds")
    voiceChat.scene = "gamepad_voice_chat"
    voiceChat:SetHeader(GetString(SI_PLAYER_MENU_COMMUNICATIONS))
    table.insert(layoutData, voiceChat)
    local mailbox = ZO_GamepadEntryData:New(
                    GetString(SI_MAIN_MENU_MAIL), 
                    "EsoUI/Art/MenuBar/Gamepad/gp_playerMenu_icon_mail.dds")
    mailbox:SetNew(function()
                        return CHAT_SYSTEM:HasUnreadMail()
                    end)
    mailbox.scene = "mailManagerGamepad"
    mailbox.disableWhenDead = true
    table.insert(layoutData, mailbox)
    do
        local UNPINNED_STRING = GetString(SI_GAMEPAD_TEXT_CHAT)
        local PINNED_STRING = GetString(SI_GAMEPAD_TEXT_CHAT_PINNED)
        local textChat = ZO_GamepadEntryData:New(
                            UNPINNED_STRING, 
                            "EsoUI/Art/MenuBar/Gamepad/gp_playerMenu_icon_textChat.dds")
        textChat.scene = "gamepad_text_chat"
        textChat.isVisibleCallback =     function() return IsConsoleUI() end
        textChat.refreshCallback =    function()
                                            local textString = UNPINNED_STRING
                                            if CHAT_SYSTEM:IsPinnable() and CHAT_SYSTEM:IsWindowPinned() then
                                                textString = PINNED_STRING
                                            end
                                            textChat:SetText(textString)
                                        end
        textChat.refreshCallback() -- trigger an initial refresh
        table.insert(layoutData, textChat)
    end
    local settings = ZO_GamepadEntryData:New(
                     GetString(SI_GAMEPAD_OPTIONS_MENU), 
                     "EsoUI/Art/MenuBar/Gamepad/gp_playerMenu_icon_settings.dds")
    settings.scene = "gamepad_options"
    settings:SetHeader(GetString(SI_PLAYER_MENU_MISC))
    table.insert(layoutData, settings)
    local help = ZO_GamepadEntryData:New(
                     GetString(SI_MAIN_MENU_HELP), 
                     "EsoUI/Art/MenuBar/Gamepad/gp_playerMenu_icon_help.dds")
    help.scene = "helpRootGamepad"
    table.insert(layoutData, help)
    local leaderboards = ZO_GamepadEntryData:New(
                     GetString(SI_JOURNAL_MENU_LEADERBOARDS), 
                     "EsoUI/Art/MenuBar/Gamepad/gp_playerMenu_icon_leaderBoards.dds")
    leaderboards.scene = "gamepad_leaderboards"
    table.insert(layoutData, leaderboards)
    local loreLibrary = ZO_GamepadEntryData:New(
                     GetString(SI_GAMEPAD_MAIN_MENU_JOURNAL_LORE_LIBRARAY), 
                     "EsoUI/Art/MenuBar/Gamepad/gp_playerMenu_icon_loreLibrary.dds")
    loreLibrary.scene = "loreLibraryGamepad"
    table.insert(layoutData, loreLibrary)
    -- TODO: How will the player access this? It isn't in the menu design.
    -- TODO: Should this use a different icon?
    local cadwellsJournal = ZO_GamepadEntryData:New(
                        GetString(SI_GAMEPAD_MAIN_MENU_JOURNAL_CADWELL), 
                        "EsoUI/Art/MenuBar/Gamepad/gp_playerMenu_icon_cadwell.dds")
    cadwellsJournal.scene = "cadwellGamepad"
    cadwellsJournal.isVisibleCallback =   function()
                                    return GetPlayerDifficultyLevel() > PLAYER_DIFFICULTY_LEVEL_FIRST_ALLIANCE
                                end
    table.insert(layoutData, cadwellsJournal)
    local achievements = ZO_GamepadEntryData:New(
                     GetString(SI_GAMEPAD_MAIN_MENU_JOURNAL_ACHIEVEMENTS), 
                     "EsoUI/Art/MenuBar/Gamepad/gp_playerMenu_icon_achievements.dds")
    achievements.scene = "achievementsGamepad"
    table.insert(layoutData, achievements)
    local collections = ZO_GamepadEntryData:New(
                     GetString(SI_MAIN_MENU_COLLECTIONS), 
                     "EsoUI/Art/MenuBar/Gamepad/gp_playerMenu_icon_collections.dds") -- TODO replace with gamepad icon
    collections.scene = "gamepadCollectionsBook"
    collections.disableWhenDead = true
    collections.disableWhenSwimming = true
    collections.disableWhenWerewolfForm = true
    table.insert(layoutData, collections)
    local logOut = ZO_GamepadEntryData:New(GetString(SI_GAME_MENU_LOGOUT))
    table.insert(layoutData, logOut)
    return layoutData
end
local CATEGORY_LAYOUT_INFO = GetLayoutData()
--
--[[ ZO_PlayerMenuManager ]]--
--
local ZO_PlayerMenuManager = ZO_Object:Subclass()
function ZO_PlayerMenuManager:New(control)
    local manager = ZO_Object.New(self)
    manager:Initialize(control)
    return manager
end
function ZO_PlayerMenuManager:Initialize(control)
    self.control = control
    self.list = ZO_GamepadVerticalParametricScrollList:New(self.control:GetNamedChild("Menu"):GetNamedChild("Container"):GetNamedChild("List"))
    self.list:AddDataTemplateWithHeader("ZO_GamepadNewMenuEntryTemplate", ZO_SharedGamepadEntry_OnSetup, ZO_GamepadMenuEntryTemplateParametricListFunction, nil, "ZO_GamepadMenuEntryHeaderTemplate")
    
    local function AnimatingLabelEntrySetup(control, data, selected, reselectingDuringRebuild, enabled, active)
        ZO_SharedGamepadEntry_OnSetup(control, data, selected, reselectingDuringRebuild, enabled, active)
        local totalSpendablePoints = GetAttributeUnspentPoints()
        if totalSpendablePoints ~= nil then
            local shouldAnimate = totalSpendablePoints > 0
            local animatingControl = control.label
            local animatingControlTimeline = animatingControl.animationTimeline
            local isAnimating = animatingControlTimeline:IsPlaying()
            if(shouldAnimate ~= isAnimating) then
                animatingControl:SetText(animatingControl.text[1])
                if(shouldAnimate) then
                    animatingControl.textIndex = 1
                    animatingControlTimeline:PlayFromStart()
                else
                    animatingControlTimeline:Stop()
                    animatingControl:SetAlpha(1)
                end
            end
        end
    end
       
    PLAYER_MENU_SCENE = ZO_RemoteScene:New("playerMenu", SCENE_MANAGER)
    PLAYER_MENU_SCENE:RegisterCallback("StateChange", function(oldState, newState)
        if newState == SCENE_SHOWING then
            self:RefreshList()
            self:PerformDeferredInitialization()
            self.list:Activate()
            KEYBIND_STRIP:AddKeybindButtonGroup(self.keybindStripDescriptor)
        elseif newState == SCENE_HIDDEN then
            KEYBIND_STRIP:RemoveKeybindButtonGroup(self.keybindStripDescriptor)
            self.list:Deactivate()
        end
    end)
    control:RegisterForEvent(EVENT_LEVEL_UPDATE,
            function(_, unitTag)
                if(unitTag == "player") then
                    self:RefreshLayoutData()
                end
            end)
    control:RegisterForEvent(EVENT_DIFFICULTY_LEVEL_CHANGED, function() self:RefreshLayoutData() end)
end
do
    local CATEGORY_ENABLED = 0
    local CATEGORY_DISABLED_WHILE_DEAD = 1
    local CATEGORY_DISABLED_WHILE_SWIMMING = 2
    local CATEGORY_DISABLED_WHILE_WEREWOLF = 3
    local function GetCategoryState(categoryInfo)
        if MAIN_MENU_SINGLETON:IsPlayerDead() and categoryInfo.disableWhenDead then
            return CATEGORY_DISABLED_WHILE_DEAD
        elseif MAIN_MENU_SINGLETON:IsPlayerSwimming() and categoryInfo.disableWhenSwimming then
            return CATEGORY_DISABLED_WHILE_SWIMMING
        elseif MAIN_MENU_SINGLETON:IsPlayerWerewolf() and categoryInfo.disableWhenWerewolfForm then
            return CATEGORY_DISABLED_WHILE_WEREWOLF
        else
            return CATEGORY_ENABLED
        end
    end
    function ZO_PlayerMenuManager:UpdateCategories()
        for i = 1, #CATEGORY_LAYOUT_INFO do
            local categoryInfo = CATEGORY_LAYOUT_INFO[i]
            local shouldBeEnabled = GetCategoryState(categoryInfo) == CATEGORY_ENABLED
            --TODO: hide the scene if it's showing
            categoryInfo:SetEnabled(shouldBeEnabled)
        end
        self:RefreshLayoutData()
    end
end
function ZO_PlayerMenuManager:RefreshLayoutData()
    self:RefreshList()
end
function ZO_PlayerMenuManager:PerformDeferredInitialization()
    if self.keybindStripDescriptor then return end
    local function MarkNewnessDirty()
        self:MarkNewnessDirty()
    end
    SHARED_INVENTORY:RegisterCallback("FullInventoryUpdate", MarkNewnessDirty)
    SHARED_INVENTORY:RegisterCallback("SingleSlotInventoryUpdate", MarkNewnessDirty)
    EVENT_MANAGER:RegisterForEvent("PlayerMenu", EVENT_LEVEL_UPDATE, MarkNewnessDirty)
    MAIN_MENU_SINGLETON:RegisterCallback("OnPlayerStateUpdate", function() self:UpdateCategories() end)
    -- notifications will appear at the top of the list if there are any available
    local INVENTORY_LIST_INDEX = GAMEPAD_NOTIFICATIONS:GetNumNotifications() == 0 and 2 or 3
    self.list:SetSelectedIndex(INVENTORY_LIST_INDEX)
end
function ZO_PlayerMenuManager:InitializeKeybindStrip()
    self.keybindStripDescriptor = {}
    ZO_Gamepad_AddListTriggerKeybindDescriptors(self.keybindStripDescriptor, self.list)
    ZO_Gamepad_AddForwardNavigationKeybindDescriptors(self.keybindStripDescriptor, GAME_NAVIGATION_TYPE_BUTTON, function() self:SwitchToSelectedScene() end)
    ZO_Gamepad_AddBackNavigationKeybindDescriptors(self.keybindStripDescriptor, GAME_NAVIGATION_TYPE_BUTTON, function() self:Exit() end)
end
function ZO_PlayerMenuManager:SwitchToSelectedScene()
    local selectedData = self.list:GetSelectedData()
    if selectedData.enabled then
        local scene = selectedData.scene
        if scene then
            SCENE_MANAGER:Push(scene)
        end
        local activatedCallback = selectedData.activatedCallback
        if activatedCallback then
            activatedCallback()
        end
    else
        PlaySound(SOUNDS.PLAYER_MENU_ENTRY_DISABLED)
    end
end
function ZO_PlayerMenuManager:Exit()
    SCENE_MANAGER:Hide("playerMenu")
end
function ZO_PlayerMenuManager:RefreshList()
    self.list:Clear()
    for i, layout in ipairs(CATEGORY_LAYOUT_INFO) do
        if not layout.isVisibleCallback or layout.isVisibleCallback() then
            if layout.refreshCallback then
                layout.refreshCallback()
            end
            layout:SetIconTintOnSelection(true)
            layout:SetIconDisabledTintOnSelection(true)
            if layout.header then
                self.list:AddEntry("ZO_GamepadNewMenuEntryTemplateWithHeader", layout)
            elseif layout.canAnimate then
                self.list:AddEntry("ZO_GamepadNewAnimatingMenuEntryTemplate", layout)   --will need new case if header entries want to animate
            else
                self.list:AddEntry("ZO_GamepadNewMenuEntryTemplate", layout)
            end
        end
    end
    self.list:Commit()
end
function ZO_PlayerMenuManager:IsShowing()
    return SCENE_MANAGER:IsShowing("playerMenu")
end
function ZO_PlayerMenuManager:ShowLastCategory()
    SCENE_MANAGER:Show("playerMenu")
end
function ZO_PlayerMenuManager:MarkNewnessDirty()
    if self:IsShowing() then
        self:RefreshList()
    end
end
function ZO_PlayerMenuManager:OnNumNotificationsChanged(numNotifications)
end
    PLAYER_MENU = ZO_PlayerMenuManager:New(self)
end