· 9 years ago · Oct 26, 2016, 03:54 PM
1-- ..\Steam\steamapps\common\Sid Meier's Civilization VI\Base\Assets\UI\FrontEnd\MainMenu.lua
2
3include("InstanceManager");
4include("LobbyTypes"); --MPLobbyMode
5include("PopupDialogSupport");
6
7-- ===========================================================================
8-- Members
9-- ===========================================================================
10local m_mainOptionIM : table = InstanceManager:new( "MenuOption", "Top", Controls.MainMenuOptionStack );
11local m_subOptionIM : table = InstanceManager:new( "MenuOption", "Top", Controls.SubMenuOptionStack );
12local m_preSaveMainMenuOptions: table = {};
13local m_defaultMainMenuOptions: table = {};
14local m_singlePlayerListOptions:table = {};
15local m_hasSaves:boolean = false;
16local m_kPopupDialog;
17local m_currentOptions:table = {}; --Track which main menu options are being displayed and selected. Indices follow the format of {optionControl:table, isSelected:boolean}
18local m_initialPause = 1.5; --How long to wait before building the main menu options when the game first loads
19local m_internetButton:table = nil; --Cache internet button so it can be updated when online status events fire
20local mm_resumeButton:table = nil; --Cache resume button so it can be updated when FileListQueryResults event fires
21
22-- ===========================================================================
23-- Constants
24-- ===========================================================================
25local PAUSE_INCREMENT = .18; --How long to wait (in seconds) between main menu flyouts - length of the menu cascade
26local TRACK_PADDING = 40; --The amount of Y pixels to add to the track on top of the list heigh
27
28-- ===========================================================================
29-- Globals
30-- ===========================================================================
31
32g_LastFileQueryRequestID = nil; -- The file list ID used to determine whether the call-back is for us or not.
33g_MostRecentSave = nil; -- The most recent single player save a user has (locally)
34
35-- ===========================================================================
36-- Button Handlers
37-- ===========================================================================
38function OnResumeGame()
39 if(g_MostRecentSave) then
40 local serverType : number = ServerType.SERVER_TYPE_NONE;
41 Network.LeaveGame();
42 Network.LoadGame(g_MostRecentSave, serverType);
43 end
44end
45
46-- ==========================================================================
47function OnCivilopedia()
48 LuaEvents.OpenCivilopedia();
49 Close();
50end
51
52function UpdateResumeGame(resumeButton)
53 if (resumeButton ~= nil) then
54 m_resumeButton = resumeButton;
55 end
56 if(m_resumeButton ~= nil) then
57 if(g_MostRecentSave ~= nil) then
58
59 local mods = g_MostRecentSave.RequiredMods or {};
60
61 -- Test for errors.
62 -- Will return a combination array/map of any errors regarding this combination of mods.
63 -- Array messages are generalized error codes regarding the set.
64 -- Map messages are error codes specific to the mod Id.
65 local errors = Modding.CheckRequirements(mods, SaveTypes.SINGLE_PLAYER);
66 local success = (errors == nil or errors.Success);
67
68 m_resumeButton.Top:SetHide(not success);
69 else
70 m_resumeButton.Top:SetHide(true);
71 end
72 end
73end
74
75
76function OnPlayCiv6()
77 local save = Options.GetAppOption("Debug", "PlayNowSave");
78 if(save ~= nil) then
79 Network.LeaveGame();
80
81 local serverType : number = ServerType.SERVER_TYPE_NONE;
82 Network.LoadGame(save, serverType);
83 else
84 GameConfiguration.SetToDefaults();
85 Network.HostGame(ServerType.SERVER_TYPE_NONE);
86 end
87end
88
89-- ===========================================================================
90function OnAdvancedSetup()
91 GameConfiguration.SetToDefaults();
92 UIManager:QueuePopup(Controls.AdvancedSetup, PopupPriority.Current);
93end
94
95-- ===========================================================================
96function OnLoadSinglePlayer()
97 GameConfiguration.SetToDefaults();
98 LuaEvents.MainMenu_SetLoadGameServerType(ServerType.SERVER_TYPE_NONE);
99 UIManager:QueuePopup(Controls.LoadGameMenu, PopupPriority.Current);
100 Close();
101end
102
103-- ===========================================================================
104function OnOptions()
105 UIManager:QueuePopup(Controls.Options, PopupPriority.Current);
106 Close();
107end
108
109-- ===========================================================================
110function OnMods()
111 GameConfiguration.SetToDefaults();
112 UIManager:QueuePopup(Controls.ModsContext, PopupPriority.Current);
113 Close();
114end
115
116-- ===========================================================================
117function OnPlayMultiplayer()
118 UIManager:QueuePopup(Controls.MultiplayerSelect, PopupPriority.Current);
119 Close();
120end
121
122-- ===========================================================================
123function OnMy2KLogin()
124 Events.Begin2KLoginProcess();
125 Close();
126end
127
128-- ===========================================================================
129function OnExitToDesktop()
130 if ( not m_kPopupDialog:IsOpen()) then
131 m_kPopupDialog:AddText(Locale.Lookup("LOC_CONFIRM_EXIT_TXT"));
132 m_kPopupDialog:AddTitle(Locale.ToUpper(Locale.Lookup("LOC_MAIN_MENU_EXIT_TO_DESKTOP")), Controls.PopupTitle);
133 m_kPopupDialog:AddButton(Locale.Lookup("LOC_CANCEL_BUTTON"), ExitCancel);
134 m_kPopupDialog:AddButton(Locale.Lookup("LOC_OK_BUTTON"), ExitOK, nil, nil, "PopupButtonAltInstance");
135 m_kPopupDialog:Open();
136 end
137end
138
139-- ===========================================================================
140function ExitOK()
141 m_kPopupDialog:Close();
142 Steam.ClearRichPresence();
143 Events.UserConfirmedClose();
144end
145
146-- ===========================================================================
147function ExitCancel()
148 m_kPopupDialog:Close();
149end
150
151 -- ===========================================================================
152function OnBenchmark()
153 Benchmark.Run("Benchmark.Civ6Save");
154end
155
156-- ===========================================================================
157function OnCredits()
158 UIManager:QueuePopup( Controls.CreditsScreen, PopupPriority.Current );
159 Close();
160end
161
162-- ===========================================================================
163-- Multiplayer Select Screen
164-- ===========================================================================
165local InternetButtonOnlineStr : string = Locale.Lookup("LOC_MULTIPLAYER_INTERNET_GAME_TT");
166local InternetButtonOfflineStr : string = Locale.Lookup("LOC_MULTIPLAYER_INTERNET_GAME_OFFLINE_TT");
167
168-- ===========================================================================
169function OnInternet()
170 LuaEvents.ChangeMPLobbyMode(MPLobbyTypes.STANDARD_INTERNET);
171 UIManager:QueuePopup( Controls.Lobby, PopupPriority.Current );
172 Close();
173end
174
175-- ===========================================================================
176-- WB: This callback is complicated by these events which can happen at any time.
177-- Because NO other buttons in the shell function in this way, using a special
178-- variable to save this control (instead of a more general solution).
179-- ===========================================================================
180function UpdateInternetButton(buttonControl: table)
181 if (buttonControl ~=nil) then
182 m_internetButton = buttonControl;
183 end
184 -- Internet available?
185 if(m_internetButton ~= nil) then
186 if (Network.IsInternetLobbyServiceAvailable()) then
187 m_internetButton.OptionButton:SetDisabled(false);
188 m_internetButton.Top:SetToolTipString(InternetButtonOnlineStr);
189 m_internetButton.ButtonLabel:SetText(Locale.Lookup("LOC_MULTIPLAYER_INTERNET_GAME"));
190 m_internetButton.ButtonLabel:SetColorByName( "ButtonCS" );
191 else
192 m_internetButton.OptionButton:SetDisabled(true);
193 m_internetButton.Top:SetToolTipString(InternetButtonOfflineStr);
194 m_internetButton.ButtonLabel:SetText(Locale.Lookup("LOC_MULTIPLAYER_INTERNET_GAME_OFFLINE"));
195 m_internetButton.ButtonLabel:SetColorByName( "ButtonDisabledCS" );
196 end
197 end
198end
199
200-- ===========================================================================
201function OnLANGame()
202 LuaEvents.ChangeMPLobbyMode(MPLobbyTypes.STANDARD_LAN);
203 UIManager:QueuePopup( Controls.Lobby, PopupPriority.Current );
204 Close();
205end
206
207-- ===========================================================================
208function OnHotSeat()
209 LuaEvents.ChangeMPLobbyMode(MPLobbyTypes.HOTSEAT);
210 LuaEvents.MainMenu_RaiseHostGame();
211 Close();
212end
213
214-- ===========================================================================
215function OnCloud()
216 UIManager:QueuePopup( Controls.CloudGameScreen, PopupPriority.Current );
217end
218
219-- ===========================================================================
220function OnGameLaunched()
221end
222
223-- ===========================================================================
224-- ESC handler
225-- ===========================================================================
226function InputHandler( uiMsg, wParam, lParam )
227 if uiMsg == KeyEvents.KeyUp then
228 if wParam == Keys.VK_ESCAPE then
229 if(m_kPopupDialog ~= nil) then
230 if(m_kPopupDialog:IsOpen()) then
231 m_kPopupDialog:Close();
232 end
233 end
234 end
235 return true;
236 end
237end
238
239-- ===========================================================================
240function Close()
241 -- Set pause to 0 so it loads in right away when returning from any screen.
242 m_initialPause = 0;
243end
244
245
246--[[
247--UINETTODO - Do we need this so that multiplayer game invites skip straight into the invited game?
248-------------------------------------------------
249-------------------------------------------------
250-- The UI has requested that we go to the multiplayer select. Show ourself
251function OnUpdateUI( type, tag, iData1, iData2, strData1 )
252 if (type == SystemUpdateUI.RestoreUI and tag == "MultiplayerSelect") then
253 if (ContextPtr:IsHidden()) then
254 UIManager:QueuePopup(ContextPtr, PopupPriority.Current );
255 end
256 end
257end
258Events.SystemUpdateUI.Add( OnUpdateUI );
259--]]
260
261-- ===========================================================================
262-- ToggleOption - called from button handlers
263-- ===========================================================================
264-- Toggles the specified index within the main menu
265-- ARG0: optionIndex - the index of the button control to deselect
266-- ARG1: submenu - if the specified index has a submenu, then build that menu
267-- ===========================================================================
268function ToggleOption(optionIndex, submenu)
269 if (not Controls.SubMenuSlide:IsStopped()) then
270 return;
271 end
272 local optionControl = m_currentOptions[optionIndex].control;
273 if(m_currentOptions[optionIndex].isSelected) then
274 -- If the thing I selected was already selected, then toggle it off
275 UI.PlaySound("Main_Main_Panel_Collapse");
276 --Controls.SubMenuContainer:SetHide(true);
277 Controls.SubMenuAlpha:Reverse();
278 Controls.SubMenuSlide:Reverse();
279 DeselectOption(optionIndex);
280 else
281 -- OTHERWISE - I am selecting a new thing
282 -- Was anything else OTHER than the optionIndex selected? If so, we should hide its selection fanciness and turn it off
283 -- Let's also check to see if the submenu was already open
284 local subMenuClosed = true;
285 for i=1, table.count(m_currentOptions) do
286 if (i ~= optionIndex) then
287 if(m_currentOptions[i].isSelected) then
288 subMenuClosed = false;
289 DeselectOption(i);
290 end
291 end
292 end
293
294 if(subMenuClosed) then
295 --If the submenu wasn't opened yet, then let's slide it out
296 Controls.SubMenuAlpha:SetToBeginning();
297 Controls.SubMenuAlpha:Play();
298 Controls.SubMenuSlide:SetToBeginning();
299 Controls.SubMenuSlide:Play();
300 end
301 -- Now show the selector around the new thing
302 optionControl.SelectionAnimAlpha:SetToBeginning();
303 optionControl.SelectionAnimSlide:SetToBeginning();
304 optionControl.SelectionAnimAlpha:Play();
305 optionControl.SelectionAnimSlide:Play();
306 optionControl.LabelAlphaAnim:SetPauseTime(0);
307 optionControl.LabelAlphaAnim:SetSpeed(6);
308 optionControl.LabelAlphaAnim:Reverse();
309 if (submenu ~= nil) then
310 BuildSubMenu(submenu);
311 end
312 m_currentOptions[optionIndex].isSelected = true;
313 end
314end
315
316-- ===========================================================================
317-- Called from ToggleOption
318-- Visually deselects the specified index and tracks within m_currentOptions
319-- ARG0: index - the index of the button control to deselect
320-- ===========================================================================
321function DeselectOption(index:number)
322 local control:table = m_currentOptions[index].control;
323 control.LabelAlphaAnim:SetSpeed(1);
324 control.LabelAlphaAnim:SetPauseTime(.4);
325 control.SelectionAnimAlpha:Reverse();
326 control.SelectionAnimSlide:Reverse();
327 control.LabelAlphaAnim:SetToBeginning();
328 control.LabelAlphaAnim:Play();
329 m_currentOptions[index].isSelected = false;
330end
331
332-- ===========================================================================
333function OnTutorial()
334 GameConfiguration.SetToDefaults();
335 UIManager:QueuePopup(Controls.TutorialSetup, PopupPriority.Current);
336end
337
338
339-- ===========================================================================
340-- Callbacks for the main menu options which have submenus
341-- ARG0: optionIndex - which index of the current options to toggle
342-- ARG1: submenu - the submenu table to draw in
343-- ===========================================================================
344function OnSinglePlayer( optionIndex:number, submenu:table )
345 ToggleOption(optionIndex, submenu);
346end
347
348function OnMultiPlayer( optionIndex:number, submenu:table )
349 ToggleOption(optionIndex, submenu);
350end
351
352function OnMore( optionIndex:number, submenu:table )
353 ToggleOption(optionIndex, submenu);
354end
355
356-- *******************************************************************************
357-- MENUS need to be defined here as the callbacks reference functions which
358-- are defined above.
359-- *******************************************************************************
360
361
362-- ===============================================================================
363-- Sub Menu Option Tables
364-- --------------------------------------------------------------------------
365-- label - the text string for the button (un-localized)
366-- callback - the function to call from this button
367-- tooltip - the tooltip for this button
368-- buttonState - a function to call which will update the buttonstate and tooltip
369-- ===============================================================================
370local m_SinglePlayerSubMenu :table = {
371 {label = "LOC_SETUP_CREATE_GAME", callback = OnAdvancedSetup, tooltip = "LOC_MAINMENU_CREATE_GAME_TT"},
372 {label = "LOC_LOAD_GAME", callback = OnLoadSinglePlayer, tooltip = "LOC_MAINMENU_LOAD_GAME_TT",},
373 {label = "LOC_MAIN_MENU_RESUME_GAME", callback = OnResumeGame, tooltip = "LOC_MAINMENU_RESUME_GAME_TT", buttonState = UpdateResumeGame},
374 {label = "LOC_PLAY_CIVILIZATION_6", callback = OnPlayCiv6, tooltip = "LOC_MAINMENU_PLAY_NOW_TT"},
375 };
376
377local m_MultiPlayerSubMenu :table = {
378 {label = "LOC_MULTIPLAYER_LAN_GAME", callback = OnLANGame, tooltip = "LOC_MULTIPLAYER_LAN_GAME_TT"},
379 {label = "LOC_MULTIPLAYER_INTERNET_GAME", callback = OnInternet, tooltip = "LOC_MULTIPLAYER_INTERNET_GAME_TT", buttonState = UpdateInternetButton},
380 {label = "LOC_MULTIPLAYER_HOTSEAT_GAME", callback = OnHotSeat, tooltip = "LOC_MULTIPLAYER_HOTSEAT_GAME_TT"},
381 --{label = "LOC_MULTIPLAYER_CLOUD_GAME", callback = OnCloud, tooltip = "LOC_MULTIPLAYER_CLOUD_GAME_TT"},
382 };
383
384local m_MoreSubMenu :table = {
385 {label = "LOC_MAIN_MENU_CIVILOPEDIA", callback = OnCivilopedia, tooltip = "LOC_MAINMENU_CIVILOPEDIA_TT"},
386 {label = "LOC_MAIN_MENU_OPTIONS", callback = OnOptions, tooltip = "LOC_MAINMENU_GAME_OPTIONS_TT"},
387 {label = "LOC_MAIN_MENU_ADDITIONAL_CONTENT", callback = OnMods, tooltip = "LOC_MAIN_MENU_ADDITIONAL_CONTENT_TT"},
388 {label = "LOC_MAIN_MENU_TUTORIAL", callback = OnTutorial, tooltip = "LOC_MAINMENU_TUTORIAL_TT"},
389 {label = "LOC_MAIN_MENU_BENCH", callback = OnBenchmark, tooltip = "LOC_MAINMENU_BENCHMARK_TT"},
390 {label = "LOC_MAIN_MENU_CREDITS", callback = OnCredits, tooltip = "LOC_MAINMENU_CREDITS_TT"},
391 };
392
393-- ===========================================================================
394-- Main Menu Option Tables
395-- --------------------------------------------------------------------------
396-- label - the text string for the button (un-localized)
397-- callback - the function to call from this button
398-- submenu - the submenu table to open for this button (defined above)
399-- ===========================================================================
400local m_preSaveMainMenuOptions :table = { {label = "LOC_PLAY_CIVILIZATION_6", callback = OnPlayCiv6}};
401local m_defaultMainMenuOptions :table = {
402 {label = "LOC_SINGLE_PLAYER", callback = null, tooltip = "LOC_MAINMENU_SINGLE_PLAYER_TT", submenu = m_SinglePlayerSubMenu},
403 {label = " Create Game", callback = OnAdvancedSetup, tooltip = "LOC_MAINMENU_CREATE_GAME_TT"},
404 {label = " Load Game", callback = OnLoadSinglePlayer, tooltip = "LOC_MAINMENU_LOAD_GAME_TT",},
405 {label = "LOC_PLAY_MULTIPLAYER", callback = null, tooltip = "LOC_MAINMENU_MULTIPLAYER_TT", submenu = m_MultiPlayerSubMenu},
406 {label = " Local Area (LAN)", callback = OnLANGame, tooltip = "LOC_MULTIPLAYER_LAN_GAME_TT"},
407 {label = " Internet (Online)", callback = OnInternet, tooltip = "LOC_MULTIPLAYER_INTERNET_GAME_TT", buttonState = UpdateInternetButton},
408 {label = " Hotseat", callback = OnHotSeat, tooltip = "LOC_MULTIPLAYER_HOTSEAT_GAME_TT"},
409 {label = "More...", callback = OnMore, tooltip = "More additional content and settings.", submenu = m_MoreSubMenu},
410 {label = "Exit", callback = OnExitToDesktop, tooltip = "LOC_MAINMENU_EXIT_GAME_TT"}
411 };--
412
413
414-- ===========================================================================
415-- Animation callback for top-menu option controls.
416-- ===========================================================================
417function TopMenuOptionAnimationCallback(control, progress)
418 local progress :number = control:GetProgress();
419
420 -- Only if the animation has just begun, play its sound
421 if(not control:IsReversing() and progress <.1) then
422 UI.PlaySound("Main_Menu_Expand_Notch");
423 elseif(not control:IsReversing() and progress >.65) then
424 control:SetSpeed(.9); -- As the flag is nearing the top of its bounce, slow it down
425 end
426
427 -- After the flag animation has bounced, stop it at the correct position
428 if(control:IsReversing() and progress > .2) then
429 control:SetProgress( 0.2 );
430 control:Stop();
431 elseif(control:IsReversing() and progress < .03) then
432 control:SetSpeed(.4); -- Right after the flag animation has bounced, slow it down dramatically
433 end
434end
435
436-- ===========================================================================
437-- Animation callback for sub-menu option controls.
438-- ===========================================================================
439function SubMenuOptionAnimationCallback(control, progress)
440 if(not control:IsReversing() and progress <.1) then
441 UI.PlaySound("Main_Menu_Panel_Expand_Short");
442 elseif(not control:IsReversing() and progress >.65) then
443 control:SetSpeed(2);
444 end
445 if(control:IsReversing() and progress > .2) then
446 control:SetProgress( 0.2 );
447 control:Stop();
448 elseif(control:IsReversing() and progress < .03) then
449 control:SetSpeed(1);
450 end
451end
452
453
454function MenuOptionMouseEnterCallback()
455 UI.PlaySound("Main_Menu_Mouse_Over");
456end
457
458-- ===========================================================================
459-- Animates the main menu options in
460-- ARG0: menuOptions - Expects the table of options that is to appear on
461-- the topmost level - either [m_preSave/m_default]MainMenuOptions
462-- ===========================================================================
463function BuildMenu(menuOptions:table)
464 m_mainOptionIM:ResetInstances();
465 UI.PlaySound("Main_Menu_Panel_Expand_Top_Level");
466 local pauseAccumulator = m_initialPause + PAUSE_INCREMENT;
467 for i, menuOption in ipairs(menuOptions) do
468
469 -- Add the instances to the table and play the animations and add the sounds
470 local option = m_mainOptionIM:GetInstance();
471 option.ButtonLabel:LocalizeAndSetText(menuOption.label);
472 option.SelectedLabel:LocalizeAndSetText(menuOption.label);
473 option.LabelAlphaAnim:SetToBeginning();
474 option.LabelAlphaAnim:Play();
475 -- The label begin its alpha animation slightly after the flag begins to fly out
476 option.LabelAlphaAnim:SetPauseTime(pauseAccumulator + .2);
477 option.OptionButton:RegisterCallback( Mouse.eLClick, function()
478 --If a submenu exists, specify the index and pass the submenu along to the callback
479 if (menuOption.submenu ~= nil) then
480 menuOption.callback(i, menuOption.submenu);
481 else
482 menuOption.callback();
483 end
484 end);
485 option.OptionButton:RegisterCallback( Mouse.eMouseEnter, MenuOptionMouseEnterCallback);
486
487 -- Define a custom animation curve and sounds for the button flag - this function is called for every frame
488 option.FlagAnim:RegisterAnimCallback(TopMenuOptionAnimationCallback);
489 -- Will not be called due to "Bounce" cycle being used: option.FlagAnim:RegisterEndCallback( function() print("done!"); end );
490 option.FlagAnim:SetPauseTime(pauseAccumulator);
491 option.FlagAnim:SetSpeed(4);
492 option.FlagAnim:SetToBeginning();
493 option.FlagAnim:Play();
494
495
496 option.Top:LocalizeAndSetToolTip(menuOption.tooltip);
497
498 -- Accumulate a pause so that the flags appear one at a time
499 pauseAccumulator = pauseAccumulator + PAUSE_INCREMENT;
500 -- Track which options are being displayed and preserve the selection state so that we can rebuild a submenu
501 m_currentOptions[i] = {control = option, isSelected = false};
502 end
503 Controls.MainMenuOptionStack:CalculateSize();
504 Controls.MainMenuOptionStack:ReprocessAnchoring();
505
506
507 local trackHeight = Controls.MainMenuOptionStack:GetSizeY() + TRACK_PADDING;
508 -- Make sure the vertical div line is correctly sized for the number of options and draw it in
509 Controls.MainButtonTrack:SetSizeY(trackHeight);
510 Controls.MainButtonTrackAnim:SetBeginVal(0,-trackHeight);
511 Controls.MainButtonTrackAnim:Play();
512 Controls.MainMenuClip:SetSizeY(trackHeight);
513end
514
515-- ===========================================================================
516-- Builds the table of submenu options
517-- ARG0: menuOptions - Expects the table specified in the 'submenu' field
518-- of the m_defaultMainMenuOptions table
519--
520-- WB: While this function shares a fair amount of code with BuildMenu,
521-- I have decided to keep them separate as I continue differentiate behavior
522-- and tweak the animations.
523-- ===========================================================================
524function BuildSubMenu(menuOptions:table)
525 m_subOptionIM:ResetInstances();
526
527 for i, menuOption in ipairs(menuOptions) do
528 -- Add the instances to the table and play the animations and add the sounds
529 -- * Submenu options animate in all at once, instead of one at at a time
530 local option = m_subOptionIM:GetInstance();
531 option.ButtonLabel:LocalizeAndSetText(menuOption.label);
532 option.SelectedLabel:LocalizeAndSetText(menuOption.label);
533 option.LabelAlphaAnim:SetToBeginning();
534 option.LabelAlphaAnim:Play();
535 option.LabelAlphaAnim:SetPauseTime(0);
536 option.OptionButton:RegisterCallback( Mouse.eLClick, menuOption.callback);
537 option.OptionButton:RegisterCallback( Mouse.eMouseEnter, MenuOptionMouseEnterCallback);
538
539 -- * Submenu options have a slightly different animation curve as well as a different animation sound
540 option.FlagAnim:RegisterAnimCallback(SubMenuOptionAnimationCallback);
541
542 -- Will not be called due to "Bounce" cycle being used: option.FlagAnim:RegisterEndCallback( function() print("done!"); end );
543 option.FlagAnim:SetSpeed(4);
544 option.FlagAnim:SetToBeginning();
545 option.FlagAnim:Play();
546
547 option.Top:LocalizeAndSetToolTip(menuOption.tooltip);
548
549 -- Set a special disabled state for buttons (right now, only the Internet button has this function)
550 if (menuOption.buttonState ~= nil) then
551 menuOption.buttonState(option);
552 else
553 --ATTN:TRON For some reason my instances are not being completely reset when I rebuild the my list here
554 -- So I have to reset my tooltip string and button state.
555 option.OptionButton:SetDisabled(false);
556 option.ButtonLabel:SetColorByName( "ButtonCS" );
557 end
558 end
559
560 Controls.SubMenuOptionStack:CalculateSize();
561 Controls.SubMenuOptionStack:ReprocessAnchoring();
562 local trackHeight = Controls.SubMenuOptionStack:GetSizeY() + TRACK_PADDING;
563 Controls.SubButtonTrack:SetSizeY(trackHeight);
564 Controls.SubButtonTrackAnim:SetBeginVal(0,-trackHeight);
565 -- * The track line for the submenu also draws in more quickly since all the options are feeding in at once
566 Controls.SubButtonTrackAnim:SetSpeed(5);
567 Controls.SubButtonTrackAnim:SetToBeginning();
568 Controls.SubButtonTrackAnim:Play();
569 Controls.SubMenuClip:SetSizeY(trackHeight);
570 Controls.SubMenuAlpha:SetSizeY(trackHeight);
571 Controls.SubMenuContainer:SetSizeY(Controls.MainMenuClip:GetSizeY());
572end
573
574
575-- =============================================================================
576-- Searches the menu table for a value which contains a matching [label]. If
577-- found, that index is removed
578-- ARG0: menu - the parent menu table. Expects options to have a name
579-- string in the [label] field to compare against
580-- ARG1: option - the table containing both the [label] and [callback]
581-- for the submenu option
582-- =============================================================================
583function RemoveOptionFromMenu(menu:table, option:table)
584 for i=1, table.count(menu) do
585 if(menu[i] ~= nil) then
586 if(menu[i].label == option.label) then
587 table.remove(menu,i);
588 end
589 end
590 end
591end
592
593-- =============================================================================
594-- Searches the menu table for a value which contains a matching [label]. If
595-- that value is NOT found, the submenu option is inserted at the first index
596-- ARG0: menu - the parent menu table. Expects options to have a name
597-- string in the [label] field to compare against
598-- ARG1: option - the table containing both the [label] and [callback]
599-- for the submenu option
600-- ARG2: (OPTIONAL) index - the index of the submenu where the option should
601-- be inserted.
602-- =============================================================================
603function AddOptionToMenu(menu:table, option:table, index:number)
604 local hasOption = false;
605 if (index == nil) then
606 index = 1;
607 end
608 for i=1, table.count(menu) do
609 if(menu[i].label == option) then
610 hasOption = true;
611 end
612 end
613 if (not hasOption) then
614 table.insert(menu,submenu,1);
615 end
616end
617
618-- =============================================================================
619-- Called from the ESC handler and also when we show the screen
620-- Rebuilds the menu taking into account any submenus that were already open
621-- =============================================================================
622function BuildAllMenus()
623
624 -- Reset cached buttons to make sure we don't reference reused instances
625 m_resumeButton = nil;
626 m_internetButton = nil;
627
628 -- WISHLIST: When we rebuild the menus, let's check to see if there are ANY saved games whatsoever.
629 -- If none exist, then do not display the option in the submenu. (See: OnFileListQueryResults)
630 local selectedIndex = -1;
631 for i=1, table.count(m_currentOptions) do
632 if(m_currentOptions[i].isSelected) then
633 selectedIndex = i;
634 end
635 end
636 if(selectedIndex ~= -1) then
637 if(m_defaultMainMenuOptions[selectedIndex].submenu ~= nil) then
638 BuildSubMenu(m_defaultMainMenuOptions[selectedIndex].submenu);
639 else
640 BuildMenu(m_defaultMainMenuOptions);
641 end
642 else
643 BuildMenu(m_defaultMainMenuOptions);
644 end
645end
646
647function Resize()
648 local screenX, screenY:number = UIManager:GetScreenSizeVal();
649 local adjustedWidth = screenY*1.9;
650 Controls.Logo:ReprocessAnchoring();
651 Controls.ShellMenuAndLogo:ReprocessAnchoring();
652 Controls.VersionLabel:ReprocessAnchoring();
653 Controls.ShellStack:ReprocessAnchoring();
654 Controls.My2KContents:ReprocessAnchoring();
655end
656-- ===========================================================================
657-- UI Callback
658-- Restart animation on show
659-- ===========================================================================
660function OnShow()
661 local save = Options.GetAppOption("Debug", "PlayNowSave");
662 if (save ~= nil) then
663 --If we have a save specified in AppOptions, then only display the play button
664 BuildMenu(m_preSaveMainMenuOptions);
665 else
666 BuildAllMenus();
667 end
668 GameConfiguration.SetToDefaults();
669 UI.SetSoundStateValue("Game_Views", "Main_Menu");
670 LuaEvents.UpdateFiraxisLiveState();
671
672 Steam.SetRichPresence("location", "LOC_PRESENCE_IN_SHELL");
673
674 local gameType = SaveTypes.SINGLE_PLAYER;
675 local saveLocation = SaveLocations.LOCAL_STORAGE;
676
677 g_MostRecentSave = nil;
678 g_LastFileQueryRequestID = nil;
679 local options = SaveLocationOptions.NORMAL + SaveLocationOptions.AUTOSAVE + SaveLocationOptions.QUICKSAVE + SaveLocationOptions.MOST_RECENT_ONLY + SaveLocationOptions.LOAD_METADATA ;
680 g_LastFileQueryRequestID = UI.QuerySaveGameList( saveLocation, gameType, options );
681end
682
683function OnHide()
684 -- Set the pause to 0 as soon as we hide the main menu, so it loads in right
685 -- away when we return from any screen.
686 m_initialPause = 0;
687end
688
689function OnUpdateUI( type:number, tag:string, iData1:number, iData2:number, strData1:string )
690 if type == SystemUpdateUI.ScreenResize then
691 Resize();
692 end
693end
694
695-- Call-back for when the list of files have been updated.
696function OnFileListQueryResults( fileList, queryID )
697 if g_LastFileQueryRequestID ~= nil then
698 if (g_LastFileQueryRequestID == queryID) then
699 g_MostRecentSave = nil;
700 if (fileList ~= nil) then
701 for i, v in ipairs(fileList) do
702 g_MostRecentSave = v; -- There really should only be one or
703 end
704
705 UpdateResumeGame();
706 end
707
708 UI.CloseFileListQuery(g_LastFileQueryRequestID);
709 g_LastFileQueryRequestID = nil;
710 end
711 end
712
713end
714
715-- ===========================================================================
716function Initialize()
717 m_kPopupDialog = PopupDialogLogic:new( "MainMenu", Controls.PopupDialog, Controls.StackContents );
718 m_kPopupDialog:SetInstanceNames( "PopupButtonInstance", "Button", "PopupTextInstance", "Text", "RowInstance", "Row");
719 m_kPopupDialog:SetOpenAnimationControls( Controls.PopupAlphaIn, Controls.PopupSlideIn );
720 m_kPopupDialog:SetSize(400,200);
721
722 ContextPtr:SetShowHandler( OnShow );
723 ContextPtr:SetInputHandler( InputHandler );
724 Controls.VersionLabel:SetText( UI.GetAppVersion() );
725 Controls.My2KLogin:RegisterCallback( Mouse.eLClick, OnMy2KLogin );
726 Controls.My2KLogin:RegisterCallback( Mouse.eMouseEnter, function() UI.PlaySound("Main_Menu_Mouse_Over"); end);
727
728 -- Game Events
729 Events.SteamServersConnected.Add( UpdateInternetButton );
730 Events.SteamServersDisconnected.Add( UpdateInternetButton );
731 Events.MultiplayerGameLaunched.Add( OnGameLaunched );
732 Events.SystemUpdateUI.Add( OnUpdateUI );
733 Events.UserRequestClose.Add( OnExitToDesktop );
734
735 -- LUA Events
736 LuaEvents.FileListQueryResults.Add( OnFileListQueryResults );
737
738 BuildAllMenus();
739 Resize();
740end
741Initialize();