Sleeping in a bed and pressing "Skip Time" from the Hub Menu both utilize the Time Skip Popup, and fire the same events when completed. This can make it challenging to differentiate between whether or not the player has just finished "waiting", or if they slept in a bed.
One way to detect this difference reliably is to catch the player's input on the Hub Menu. If the player has clicked on the "Skip Time" button from this menu, then we know that they decided to wait instead of sleeping in a bed. We can store whether or not this occurred and then clear it as soon as the Time Skip event is complete.
The UI sends many inkPointerEvents to menus, so it's important to filter these events by whether or not the action was a click.
These examples use a Scriptable System and Codeware's GetGameInstance() for convenience; however, you could also manage this data on any class that you prefer, including base game scripts using @addField().
module MySleepingSystemModule// Catch pressing the Skip Time button from the Hub Menu.@wrapMethod(HubTimeSkipController)protected cb funcOnTimeSkipButtonPressed(e: ref<inkPointerEvent>) ->Bool {if e.IsAction(n"click") { MySleepingSystem.GetInstance(GetGameInstance()).SetSkippingTimeFromHubMenu(true); }returnwrappedMethod(e);}// When the Time Skip Popup is initialized, check if the Skipping Time from Hub Menu flag // was just set. If so, we are not sleeping. This step is necessary because the Skipping Time // from Hub Menu flag is transient, and will be cleared as soon as the Time Skip Popup is // uninitialized (see below).@wrapMethod(TimeskipGameController)protected cb funcOnInitialize() ->Bool {let SleepingSystem = MySleepingSystem.GetInstance(GetGameInstance());ifEquals(SleepingSystem.GetSkippingTimeFromHubMenu(), true) { SleepingSystem.SetWasSleeping(false); } else { SleepingSystem.SetWasSleeping(true); }returnwrappedMethod();}// Event that fires regardless of the Time Skip outcome (Finished, cancelled, etc).// Always clear the "Skipping Time from Hub Menu" flag when this happens.@wrapMethod(TimeskipGameController)protected cb funcOnUninitialize() ->Bool { MySleepingSystem.GetInstance(GetGameInstance()).SetSkippingTimeFromHubMenu(false);returnwrappedMethod();}// Event that fires after successfully sleeping or skipping time. (Player didn't cancel out of the menu)@wrapMethod(TimeskipGameController)protected cb funcOnCloseAfterFinishing(proxy: ref<inkAnimProxy>) ->Bool { MySleepingSystem.GetInstance(GetGameInstance()).OnTimeSkipFinished();returnwrappedMethod(proxy);}// Example class that we're using to handle this gameplay event.publicfinalclassMySleepingSystem extends ScriptableSystem {privatelet skippingTimeFromHubMenu: Bool=false;privatelet wasSleeping: Bool=false;publicfinalstaticfuncGetInstance(gameInstance: GameInstance) -> ref<MySleepingSystem> { let instance: ref<MySleepingSystem> = GameInstance.GetScriptableSystemsContainer(gameInstance).Get(n"MySleepingSystemModule.MySleepingSystem") as MySleepingSystem;
return instance; }publicfinalfuncSetSkippingTimeFromHubMenu(value: Bool) ->Void { this.skippingTimeFromHubMenu = value; }publicfinalfuncGetSkippingTimeFromHubMenu() ->Bool {return this.skippingTimeFromHubMenu; }publicfinalfuncSetWasSleeping(value: Bool) { this.wasSleeping = value; }publicfinalfuncOnTimeSkipFinished() ->Void {if this.wasSleeping {FTLog("The player was sleeping in a bed! How cozy.");// Do something cool when the player sleeps in a bed. } else {FTLog("The player was NOT sleeping. They Skipped Time from the Menu.");// Do something cool when the player skips time. } }}