class SaveGameMenuGameController extends gameuiSaveHandlingController { private editable var m_list : inkCompoundRef; private editable var m_buttonHintsManagerRef : inkWidgetRef; private editable var m_gogButtonWidgetRef : inkWidgetRef; private editable var m_gogContainer : inkWidgetRef; private editable var m_scrollbar : inkWidgetRef; private var m_eventDispatcher : weak< inkMenuEventDispatcher >; private var m_handler : weak< inkISystemRequestsHandler >; private var m_buttonHintsController : weak< ButtonHints >; private var m_saveInfo : SaveMetadataInfo; private var m_saves : array< String >; private var m_pendingRegistration : Bool; private var m_hasEmptySlot : Bool; private var m_saveInProgress : Bool; private var m_loadComplete : Bool; private var m_saveFilesReady : Bool; private var m_cloudSynced : Bool; private var m_emptySlotController : weak< LoadListItem >; private var m_isEp1Enabled : Bool; protected event OnInitialize() { m_handler = GetSystemRequestsHandler(); m_handler.RegisterToCallback( 'OnSavesForSaveReady', this, 'OnSavesForSaveReady' ); m_handler.RegisterToCallback( 'OnSaveMetadataReady', this, 'OnSaveMetadataReady' ); m_handler.RegisterToCallback( 'OnSaveDeleted', this, 'OnSaveDeleted' ); m_handler.RegisterToCallback( 'OnGogLoginStatusChanged', this, 'OnGogLoginStatusChanged' ); m_handler.RegisterToCallback( 'OnSavingComplete', this, 'OnSavingComplete' ); m_handler.RegisterToCallback( 'OnCloudSavesQueryStatusChanged', this, 'OnCloudSavesQueryStatusChanged' ); m_handler.RegisterToCallback( 'OnCloudSaveUploadFinish', this, 'OnCloudSaveUploadFinish' ); m_handler.RequestSavesForSave(); inkCompoundRef.RemoveAllChildren( m_list ); m_hasEmptySlot = false; m_emptySlotController = NULL; PlayLibraryAnimation( 'intro' ); m_buttonHintsController = ( ( ButtonHints )( SpawnFromExternal( inkWidgetRef.Get( m_buttonHintsManagerRef ), R"base\gameplay\gui\common\buttonhints.inkwidget", 'Root' ).GetController() ) ); m_buttonHintsController.AddButtonHint( 'back', GetLocalizedText( "Common-Access-Close" ) ); m_buttonHintsController.AddButtonHint( 'delete_save', GetLocalizedText( "UI-Menus-DeleteSave" ) ); m_buttonHintsController.AddButtonHint( 'select', GetLocalizedText( "UI-UserActions-Select" ) ); if( IsTransferSavedExportSupported() ) { m_buttonHintsController.AddButtonHint( 'transfer_save', GetLocalizedText( "UI-Menus-ExportSave" ) ); } InitCrossProgression(); PlayLoadingAnimation(); RegisterToGlobalInputCallback( 'OnPostOnRelease', this, 'OnButtonRelease' ); ShowCompatibilityLimitationPopup(); m_isEp1Enabled = IsEP1(); } protected event OnUninitialize() { if( GameInstance.GetOnlineSystem( GetPlayerControlledObject().GetGame() ) ) { inkWidgetRef.UnregisterFromCallback( m_gogButtonWidgetRef, 'OnRelease', this, 'OnGogPressed' ); } UnregisterFromGlobalInputCallback( 'OnPostOnRelease', this, 'OnButtonRelease' ); } protected event OnButtonRelease( evt : inkPointerEvent ) { if( evt.IsAction( 'next_menu' ) && inkWidgetRef.IsVisible( m_gogButtonWidgetRef ) ) { PlaySound( 'Button', 'OnPress' ); GogLogin(); evt.Handle(); } } protected event OnRefreshGOGState( evt : RefreshGOGState ) { if( evt.status == GOGRewardsSystemStatus.RegistrationPending ) { m_pendingRegistration = true; } else if( m_pendingRegistration && evt.status == GOGRewardsSystemStatus.Registered ) { m_pendingRegistration = false; m_saveFilesReady = false; m_cloudSynced = false; PlayLoadingAnimation(); m_handler.RequestSavesForSave(); } } private function InitCrossProgression() { var hudGroup : ConfigGroup; var settingsVar : ConfigVarBool; var gameInst : GameInstance; gameInst = GetPlayerControlledObject().GetGame(); hudGroup = GameInstance.GetSettingsSystem( gameInst ).GetGroup( '/gameplay/misc' ); settingsVar = ( ( ConfigVarBool )( hudGroup.GetVar( 'EnableCloudSaves' ) ) ); if( ( GameInstance.GetOnlineSystem( gameInst ) && settingsVar.GetValue() ) && settingsVar.IsVisible() ) { inkWidgetRef.RegisterToCallback( m_gogButtonWidgetRef, 'OnRelease', this, 'OnGogPressed' ); inkWidgetRef.SetVisible( m_gogButtonWidgetRef, true ); inkWidgetRef.SetInteractive( m_gogButtonWidgetRef, true ); } else { inkWidgetRef.SetVisible( m_gogButtonWidgetRef, false ); inkWidgetRef.SetInteractive( m_gogButtonWidgetRef, false ); } } private function TryToCreateEmptySlot() { var currButton : weak< inkCompoundWidget >; var allSlotsTaken : Bool; allSlotsTaken = !( m_handler.HasFreeSaveSlot( "ManualSave-" ) ); if( m_hasEmptySlot ) { m_emptySlotController.SetData( -1, true, allSlotsTaken ); return; } currButton = ( ( inkCompoundWidget )( SpawnFromLocal( inkCompoundRef.Get( m_list ), 'LoadListItem' ) ) ); currButton.RegisterToCallback( 'OnRelease', this, 'OnSaveFile' ); inkCompoundRef.ReorderChild( m_list, currButton, 0 ); m_emptySlotController = ( ( LoadListItem )( currButton.GetController() ) ); m_emptySlotController.SetData( -1, true, allSlotsTaken ); m_hasEmptySlot = true; } private function SetupLoadItems( const saves : ref< array< String > > ) { var i : Int32; for( i = 0; i < saves.Size(); i += 1 ) { CreateLoadItem( i ); } } private function CreateLoadItem( index : Int32 ) { var currButton : weak< inkCompoundWidget >; var currLogic : weak< LoadListItem >; currButton = ( ( inkCompoundWidget )( SpawnFromLocal( inkCompoundRef.Get( m_list ), 'LoadListItem' ) ) ); currButton.RegisterToCallback( 'OnRelease', this, 'OnSaveFile' ); currLogic = ( ( LoadListItem )( currButton.GetController() ) ); currLogic.SetData( index ); GetSystemRequestsHandler().RequestSavedGameScreenshot( index, currLogic.GetPreviewImageWidget() ); } protected event OnSaveFile( e : inkPointerEvent ) { var button : weak< inkWidget >; var controller : weak< LoadListItem >; var transferSaveData : TransferSaveData; var showXbCompatWarning : Bool; if( ( ( !( m_loadComplete ) || m_saveInProgress ) || IsSaveFailedNotificationActive() ) || IsGameSavedNotificationActive() ) { PlaySound( 'Button', 'OnPress' ); return false; } button = ( ( inkWidget )( e.GetCurrentTarget() ) ); controller = ( ( LoadListItem )( button.GetController() ) ); if( e.IsAction( 'click' ) ) { PlaySound( 'Button', 'OnPress' ); if( controller.EmptySlot() && m_handler.HasFreeSaveSlot( "ManualSave-" ) ) { m_saveInProgress = true; GetSystemRequestsHandler().ManualSave( "ManualSave-" ); } else { showXbCompatWarning = false; if( GetPlatformShortName() == "xseriesx" || GetPlatformShortName() == "xseriess" ) { if( controller.GetPlatform() == "xbox1" ) { showXbCompatWarning = true; } } OverrideSavedGame( controller.Index(), showXbCompatWarning ); } return true; } if( e.IsAction( 'transfer_save' ) && IsTransferSavedExportSupported() ) { if( !( controller.EmptySlot() ) ) { transferSaveData = new TransferSaveData; transferSaveData.saveIndex = controller.Index(); transferSaveData.action = TransferSaveAction.Export; TransferSavedGame( transferSaveData ); } } if( e.IsAction( 'delete_save' ) ) { if( !( controller.EmptySlot() ) ) { PlaySound( 'SaveDeleteButton', 'OnPress' ); if( controller.IsCloud() ) { m_handler.RequestSystemNotificationGeneric( 'UI-CrossProgression-Title', 'UI-CrossProgression-DeleteSaveRestriction' ); } else { DeleteSavedGame( controller.Index() ); } } else { PlaySound( 'SaveDeleteButton', 'OnPress' ); } return true; } } private function GogLogin() { var container : weak< inkCompoundWidget >; var gogPopupWidget : inkWidget; var gogPopupController : weak< GOGProfileLogicController >; container = ( ( inkCompoundWidget )( inkWidgetRef.Get( m_gogContainer ) ) ); if( container.GetNumChildren() ) { container.RemoveAllChildren(); } else { gogPopupWidget = SpawnFromExternal( container, R"base\gameplay\gui\fullscreen\main_menu\gog_popup.inkwidget", 'Root' ); if( gogPopupWidget != NULL ) { gogPopupController = ( ( GOGProfileLogicController )( gogPopupWidget.GetController() ) ); if( gogPopupController != NULL ) { gogPopupController.SetMenuState( EGOGMenuState.LoadGame ); } } } } protected event OnSaveDeleted( result : Bool, idx : Int32 ) { var i : Int32; var button : weak< inkWidget >; var controller : weak< LoadListItem >; if( result ) { for( i = 0; i < inkCompoundRef.GetNumChildren( m_list ); i += 1 ) { button = inkCompoundRef.GetWidgetByIndex( m_list, i ); controller = ( ( LoadListItem )( button.GetController() ) ); if( controller.Index() == idx ) { inkCompoundRef.RemoveChild( m_list, button ); break; } } TryToCreateEmptySlot(); } } protected event OnGogLoginStatusChanged( bIsSignedIn : Bool ) { var handler : weak< inkISystemRequestsHandler >; handler = GetSystemRequestsHandler(); if( bIsSignedIn ) { handler.RequestSavesForSave(); } } protected event OnOverrideSaveAccepted() { m_saveInProgress = true; } protected event OnSavingComplete( success : Bool, locks : array< gameSaveLock > ) { if( success ) { m_handler.RequestSavesForSave(); RequestGameSavedNotification(); } else { ShowSavingLockedNotification( locks ); RequestSaveFailedNotification(); } m_saveInProgress = false; } protected event OnSavesForSaveReady( saves : array< String > ) { m_saves = saves; m_saveFilesReady = true; UpdateSavesList(); } protected event OnCloudSavesQueryStatusChanged( status : CloudSavesQueryStatus ) { m_cloudSynced = true; UpdateSavesList(); } protected event OnCloudSaveUploadFinish( success : Bool ) { m_handler.RequestSavesForSave(); } private function UpdateSavesList() { if( m_saveFilesReady && m_cloudSynced ) { m_saveFilesReady = false; m_cloudSynced = false; inkCompoundRef.RemoveAllChildren( m_list ); m_hasEmptySlot = false; m_emptySlotController = NULL; TryToCreateEmptySlot(); SetupLoadItems( m_saves ); m_loadComplete = true; StopLoadingAnimation(); } } protected event OnSaveMetadataReady( info : SaveMetadataInfo ) { var i : Int32; var button : weak< inkWidget >; var controller : weak< LoadListItem >; for( i = 0; i < inkCompoundRef.GetNumChildren( m_list ); i += 1 ) { button = inkCompoundRef.GetWidgetByIndex( m_list, i ); controller = ( ( LoadListItem )( button.GetController() ) ); if( controller.Index() == info.saveIndex ) { if( info.isValid ) { controller.SetMetadata( info, m_isEp1Enabled ); } else { controller.SetInvalid( info.internalName ); } break; } } } protected event OnGogPressed( evt : inkPointerEvent ) { if( evt.IsAction( 'click' ) ) { PlaySound( 'Button', 'OnPress' ); GogLogin(); evt.Handle(); } } protected event OnSetMenuEventDispatcher( menuEventDispatcher : weak< inkMenuEventDispatcher > ) { m_eventDispatcher = menuEventDispatcher; } private function PlayLoadingAnimation() { var i : Int32; inkCompoundRef.RemoveAllChildren( m_list ); for( i = 0; i < 7; i += 1 ) { SpawnFromLocal( inkCompoundRef.Get( m_list ), 'LoadListItemPlaceholder' ); } inkWidgetRef.SetVisible( m_scrollbar, false ); } private function StopLoadingAnimation() { inkWidgetRef.SetVisible( m_scrollbar, true ); } private function ShowCompatibilityLimitationPopup() { var uiSystem : UISystem; if( GetPlatformShortName() == "xseriesx" || GetPlatformShortName() == "xseriess" ) { uiSystem = GameInstance.GetUISystem( GetPlayerControlledObject().GetGame() ); if( !( uiSystem.GetOneTimeMessageSeen( gameuiOneTimeMessage.XboxCompatibilityLimitation ) ) ) { GetSystemRequestsHandler().RequestSystemNotificationGeneric( 'UI-Wardrobe-LabelWarning', 'UI-Menus-Saving-XboxCompatibilityLimitation' ); uiSystem.SetOneTimeMessageSeen( gameuiOneTimeMessage.XboxCompatibilityLimitation, true ); } } } }