//Compile out Title Update changes to header functions. //Must be before includes. //CONST_INT USE_TU_CHANGES 0 // Removed by Kenneth R. //╒═════════════════════════════════════════════════════════════════════════════╕ //│ Author: Ben Rollinson Date: 09/02/12 │ //╞═════════════════════════════════════════════════════════════════════════════╡ //│ │ //│ Flow Help Text Controller │ //│ │ //│ A controller for queuing and displaying help text. │ //│ │ //╘═════════════════════════════════════════════════════════════════════════════╛ USING "rage_builtins.sch" USING "globals.sch" USING "flow_help_private.sch" USING "flow_help_public.sch" USING "cellphone_public.sch" USING "dialogue_public.sch" USING "flow_mission_data_public.sch" USING "code_control_public.sch" USING "mission_stat_public.sch" USING "savegame_public.sch" Displayed_FlowHelp sDisplayHelp INT m_iFrameQueueIndex = 0 PROC CLEANUP_HELP_CONTROLLER() CPRINTLN(DEBUG_FLOW_HELP, "Controller cleaning up for termination.") IF g_bFlowHelpDisplaying IF ARE_STRINGS_EQUAL(sDisplayHelp.tAddText, "") IF IS_THIS_HELP_MESSAGE_BEING_DISPLAYED(sDisplayHelp.tHelpText) CPRINTLN(DEBUG_FLOW_HELP, "Clearing displaying help as we cleanup.") CLEAR_HELP() ENDIF ELSE IF IS_THIS_HELP_MESSAGE_WITH_STRING_BEING_DISPLAYED(sDisplayHelp.tHelpText, sDisplayHelp.tAddText) CPRINTLN(DEBUG_FLOW_HELP, "Clearing displaying help with substring as we cleanup.") CLEAR_HELP() ENDIF ENDIF ENDIF g_iFlowHelpDisplayStartTime = 0 g_bFlowHelpDisplaying = FALSE CPRINTLN(DEBUG_FLOW_HELP, "Controller terminating.") TERMINATE_THIS_THREAD() ENDPROC FUNC BOOL IS_IT_SAFE_TO_DISPLAY_QUEUED_HELP_TEXT() IF IS_CUTSCENE_PLAYING() RETURN FALSE ENDIF IF Is_Player_Timetable_Scene_In_Progress() RETURN FALSE ENDIF //Help being displayed. Check if we need to clear it. IF (sDisplayHelp.iDuration != FLOW_HELP_DISPLAY_FOREVER AND (GET_GAME_TIMER() - g_iFlowHelpDisplayStartTime) > sDisplayHelp.iDuration) CDEBUG1LN(DEBUG_FLOW_HELP, "Current help message being cleared due to timeout, g_iFlowHelpDisplayStartTime: ",g_iFlowHelpDisplayStartTime) RETURN FALSE ENDIF IF g_bFlowHelpPaused CDEBUG1LN(DEBUG_FLOW_HELP, "Current help message being cleared due to help system being paused.") RETURN FALSE ENDIF IF IS_CUTSCENE_PLAYING() CDEBUG1LN(DEBUG_FLOW_HELP, "Current help message being cleared due to cutscene playing.") RETURN FALSE ENDIF IF ARE_STRINGS_EQUAL(sDisplayHelp.tAddText, "") IF NOT IS_THIS_HELP_MESSAGE_BEING_DISPLAYED(sDisplayHelp.tHelpText) CDEBUG1LN(DEBUG_FLOW_HELP, "Current help message being cleared as some other system already cleared it.") sDisplayHelp.bSkipTimeOnScreenCheck = true RETURN FALSE ENDIF ELSE IF NOT IS_THIS_HELP_MESSAGE_WITH_STRING_BEING_DISPLAYED(sDisplayHelp.tHelpText, sDisplayHelp.tAddText) CDEBUG1LN(DEBUG_FLOW_HELP, "Current help message being cleared as some other system already cleared it.") sDisplayHelp.bSkipTimeOnScreenCheck = true RETURN FALSE ENDIF ENDIF RETURN TRUE ENDFUNC FUNC BOOL IS_SAFE_TO_START_DISPLAYING_HELP_TEXT(FlowHelp &sHelp) IF IS_HELP_MESSAGE_BEING_DISPLAYED() CDEBUG3LN(DEBUG_FLOW_HELP, "Could not start [", sHelp.tHelpText, "] because another help message is already displaying.") RETURN FALSE ENDIF IF IS_CUTSCENE_PLAYING() CDEBUG3LN(DEBUG_FLOW_HELP, "Could not start [", sHelp.tHelpText, "] because a cutscene is playing.") RETURN FALSE ENDIF IF NOT IS_SCREEN_FADED_IN() CDEBUG3LN(DEBUG_FLOW_HELP, "Could not start [", sHelp.tHelpText, "] because the screen isn't faded in.") RETURN FALSE ENDIF IF IS_WARNING_MESSAGE_ACTIVE() CDEBUG3LN(DEBUG_FLOW_HELP, "Could not start [", sHelp.tHelpText, "] because a warning message is active.") RETURN FALSE ENDIF IF IS_PLAYER_PED_SWITCH_IN_PROGRESS() CDEBUG3LN(DEBUG_FLOW_HELP, "Could not start [", sHelp.tHelpText, "] because a ped switch is in progress.") RETURN FALSE ENDIF IF Is_Player_Timetable_Scene_In_Progress() CDEBUG3LN(DEBUG_FLOW_HELP, "Could not start [", sHelp.tHelpText, "] because a player timetable scene is in progress.") RETURN FALSE ENDIF IF sHelp.ePriority < FHP_VERY_HIGH IF IS_RESULT_SCREEN_DISPLAYING() #IF IS_DEBUG_BUILD IF (GET_FRAME_COUNT() % 60) = 0 CDEBUG1LN(DEBUG_FLOW_HELP, "Could not start [", sHelp.tHelpText, "] because Passed screen is displayed. Priority: ", ENUM_TO_INT(sHelp.ePriority)) CDEBUG1LN(DEBUG_FLOW_HELP, "Very high priority: ", ENUM_TO_INT(FHP_VERY_HIGH)) ENDIF #ENDIF RETURN FALSE ENDIF //Are we playing a cutscene? IF g_bScriptsSetSafeForCutscene #IF IS_DEBUG_BUILD IF (GET_FRAME_COUNT() % 60) = 0 CDEBUG1LN(DEBUG_FLOW_HELP, "Could not start [", sHelp.tHelpText, "] because scripts are configured to run a cutscene.") ENDIF #ENDIF RETURN FALSE ENDIF //Is the player locked in to a trigger scene? IF g_bPlayerLockedInToTrigger #IF IS_DEBUG_BUILD IF (GET_FRAME_COUNT() % 60) = 0 CDEBUG1LN(DEBUG_FLOW_HELP, "Could not start [", sHelp.tHelpText, "] because the player is locked in to a trigger scene.") ENDIF #ENDIF RETURN FALSE ENDIF //Is the player in a mission trigger area? IF NOT IS_BIT_SET(sHelp.iSettingsFlags, FHF_INDEX_ALLOW_IN_TRIGGER) IF g_bTriggerSceneActive #IF IS_DEBUG_BUILD IF (GET_FRAME_COUNT() % 60) = 0 CDEBUG1LN(DEBUG_FLOW_HELP, "Could not start [", sHelp.tHelpText, "] because the player is in an active trigger scene.") ENDIF #ENDIF RETURN FALSE ENDIF ENDIF ENDIF RETURN TRUE ENDFUNC SCRIPT CPRINTLN(DEBUG_FLOW_HELP, "Flow help text controller started.") // Terminate this thread if multiplayer starts. IF HAS_FORCE_CLEANUP_OCCURRED( FORCE_CLEANUP_FLAG_SP_TO_MP|FORCE_CLEANUP_FLAG_MAGDEMO|FORCE_CLEANUP_FLAG_DEBUG_MENU) CLEANUP_HELP_CONTROLLER() ENDIF // Main loop. WHILE TRUE IF g_savedGlobals.sFlowHelp.iFlowHelpCount > 0 or g_bFlowHelpDisplaying //Check for displaying and clearing of queued message. IF NOT g_bFlowHelpDisplaying IF g_OnMissionState != MISSION_TYPE_FRIEND_ACTIVITY AND g_OnMissionState != MISSION_TYPE_OFF_MISSION AND NOT g_bHeistBoardViewActive CPRINTLN(DEBUG_FLOW_HELP, "Cleaning up due to mission launching.") CLEANUP_HELP_CONTROLLER() ENDIF IF NOT g_bFlowHelpPaused IF g_savedGlobals.sFlowHelp.iFlowHelpCount > 0 IF IS_SAFE_TO_START_DISPLAYING_HELP_TEXT(g_savedGlobals.sFlowHelp.sHelpQueue[m_iFrameQueueIndex]) IF IS_PLAYER_PED_PLAYABLE(GET_CURRENT_PLAYER_PED_ENUM()) IF IS_BIT_SET(g_savedGlobals.sFlowHelp.sHelpQueue[m_iFrameQueueIndex].iCharBitset, GET_CURRENT_PLAYER_PED_INT()) IF g_savedGlobals.sFlowHelp.sHelpQueue[m_iFrameQueueIndex].ePriority = g_savedGlobals.sFlowHelp.eFlowHelpPriority[GET_CURRENT_PLAYER_PED_INT()] IF GET_GAME_TIMER() > g_iFlowHelpDelayTime IF GET_GAME_TIMER() > g_savedGlobals.sFlowHelp.sHelpQueue[m_iFrameQueueIndex].iStartTime CPRINTLN(DEBUG_FLOW_HELP, "Started displaying queued help message ", g_savedGlobals.sFlowHelp.sHelpQueue[m_iFrameQueueIndex].tHelpText, ".") IF ARE_STRINGS_EQUAL(g_savedGlobals.sFlowHelp.sHelpQueue[m_iFrameQueueIndex].tAddText, "") ADD_NEXT_MESSAGE_TO_PREVIOUS_BRIEFS(TRUE) PRINT_HELP_FOREVER(g_savedGlobals.sFlowHelp.sHelpQueue[m_iFrameQueueIndex].tHelpText) ELSE ADD_NEXT_MESSAGE_TO_PREVIOUS_BRIEFS(TRUE) PRINT_HELP_FOREVER_WITH_STRING( g_savedGlobals.sFlowHelp.sHelpQueue[m_iFrameQueueIndex].tHelpText, g_savedGlobals.sFlowHelp.sHelpQueue[m_iFrameQueueIndex].tAddText) ENDIF //Does this help message have a code ID to run as it starts displaying? IF g_savedGlobals.sFlowHelp.sHelpQueue[m_iFrameQueueIndex].eCodeIDStart != CID_BLANK Execute_Code_ID(g_savedGlobals.sFlowHelp.sHelpQueue[m_iFrameQueueIndex].eCodeIDStart) ENDIF sDisplayHelp.tHelpText = g_savedGlobals.sFlowHelp.sHelpQueue[m_iFrameQueueIndex].tHelpText sDisplayHelp.tAddText = g_savedGlobals.sFlowHelp.sHelpQueue[m_iFrameQueueIndex].tAddText sDisplayHelp.iStartTime = g_savedGlobals.sFlowHelp.sHelpQueue[m_iFrameQueueIndex].iStartTime sDisplayHelp.iExpirationTime = g_savedGlobals.sFlowHelp.sHelpQueue[m_iFrameQueueIndex].iExpirationTime sDisplayHelp.iDuration = g_savedGlobals.sFlowHelp.sHelpQueue[m_iFrameQueueIndex].iDuration sDisplayHelp.iCharBitset = g_savedGlobals.sFlowHelp.sHelpQueue[m_iFrameQueueIndex].iCharBitset sDisplayHelp.ePriority = g_savedGlobals.sFlowHelp.sHelpQueue[m_iFrameQueueIndex].ePriority sDisplayHelp.eCodeIDStart = g_savedGlobals.sFlowHelp.sHelpQueue[m_iFrameQueueIndex].eCodeIDStart sDisplayHelp.eCodeIDDisplayed = g_savedGlobals.sFlowHelp.sHelpQueue[m_iFrameQueueIndex].eCodeIDDisplayed sDisplayHelp.iSettingsFlags = g_savedGlobals.sFlowHelp.sHelpQueue[m_iFrameQueueIndex].iSettingsFlags sDisplayHelp.bSkipTimeOnScreenCheck = FALSE CPRINTLN(DEBUG_FLOW_HELP,"sDisplayHelp.tHelpText: ",sDisplayHelp.tHelpText," " ,"sDisplayHelp.tAddText: ",sDisplayHelp.tAddText," " ,"sDisplayHelp.iStartTime: ",sDisplayHelp.iStartTime," " ,"sDisplayHelp.iExpirationTime: ",sDisplayHelp.iExpirationTime," " ,"sDisplayHelp.iDuration: ",sDisplayHelp.iDuration," ") g_txtFlowHelpLastDisplayed = g_savedGlobals.sFlowHelp.sHelpQueue[m_iFrameQueueIndex].tHelpText g_iFlowHelpDisplayStartTime = GET_GAME_TIMER() //Remove this queued help text item. INT iDisplayedItem FOR iDisplayedItem = m_iFrameQueueIndex TO (g_savedGlobals.sFlowHelp.iFlowHelpCount-2) PRIVATE_Copy_Queued_Help_From_Index_To_Index(iDisplayedItem, iDisplayedItem+1) ENDFOR PRIVATE_Clear_Queued_Help_At_Index(g_savedGlobals.sFlowHelp.iFlowHelpCount-1) g_savedGlobals.sFlowHelp.iFlowHelpCount-- //Check if queue priority has changed after removing an item. PRIVATE_Update_Flow_Help_Queue_Priority_Level() g_bFlowHelpDisplaying = TRUE ENDIF ELSE //g_iFlowHelpDelayTime = GET_GAME_TIMER() + FLOW_HELP_DELAY_BETWEEN_MESSAGES ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ELSE CDEBUG3LN(DEBUG_FLOW_HELP, "Help controller has [", g_txtFlowHelpLastDisplayed, "] flagged as currently displaying.") IF not IS_IT_SAFE_TO_DISPLAY_QUEUED_HELP_TEXT() //Stop the help displaying and set controller state to not displaying. IF ARE_STRINGS_EQUAL(sDisplayHelp.tAddText, "") IF IS_THIS_HELP_MESSAGE_BEING_DISPLAYED(sDisplayHelp.tHelpText) CDEBUG1LN(DEBUG_FLOW_HELP, "Help message [",sDisplayHelp.tHelpText,"] is still on screen. Clearing.") CLEAR_HELP(FALSE) ENDIF ELSE IF IS_THIS_HELP_MESSAGE_WITH_STRING_BEING_DISPLAYED(sDisplayHelp.tHelpText, sDisplayHelp.tAddText) CDEBUG1LN(DEBUG_FLOW_HELP, "Help message [",sDisplayHelp.tHelpText,"] is still on screen. Clearing.") CLEAR_HELP(FALSE) ENDIF ENDIF CPRINTLN(DEBUG_FLOW_HELP, "Finished displaying help [", sDisplayHelp.tHelpText, "].") //Did the help display long enough to count as being displayed? IF (GET_GAME_TIMER() - g_iFlowHelpDisplayStartTime) > 4000 or sDisplayHelp.bSkipTimeOnScreenCheck CPRINTLN(DEBUG_FLOW_HELP, "[", sDisplayHelp.tHelpText, "] sucessfully displayed to the player.") //Does this help message have a code ID to run as it finishes displaying? IF sDisplayHelp.eCodeIDDisplayed != CID_BLANK Execute_Code_ID(sDisplayHelp.eCodeIDDisplayed) ENDIF g_iFlowHelpDelayTime = GET_GAME_TIMER() + FLOW_HELP_DELAY_BETWEEN_MESSAGES ELSE Int iExptime IF sDisplayHelp.iExpirationTime != FLOW_HELP_NEVER_EXPIRES iExptime = 20000 ELSE iExptime = FLOW_HELP_NEVER_EXPIRES ENDIF PRIVATE_Add_Help_To_Flow_Queue(sDisplayHelp.tHelpText,sDisplayHelp.tAddText,sDisplayHelp.ePriority, 1000,iExptime,sDisplayHelp.iDuration, sDisplayHelp.iCharBitset, sDisplayHelp.eCodeIDStart, sDisplayHelp.eCodeIDDisplayed, sDisplayHelp.iSettingsFlags) CPRINTLN(DEBUG_FLOW_HELP, "[", sDisplayHelp.tHelpText, "] was not on screen long enough to sucessfully display.") ENDIF sDisplayHelp.tHelpText = "" sDisplayHelp.tAddText = "" sDisplayHelp.iStartTime = 0 sDisplayHelp.iDuration = 0 sDisplayHelp.iExpirationTime = FLOW_HELP_NEVER_EXPIRES sDisplayHelp.iCharBitset = BIT_NOBODY sDisplayHelp.ePriority = FHP_LOW sDisplayHelp.eCodeIDStart = CID_BLANK sDisplayHelp.eCodeIDDisplayed = CID_BLANK sDisplayHelp.iSettingsFlags = 0 sDisplayHelp.bSkipTimeOnScreenCheck = FALSE g_iFlowHelpDisplayStartTime = 0 g_bFlowHelpDisplaying = FALSE ENDIF ENDIF //Check for queued messages that have expired. IF NOT ARE_STRINGS_EQUAL(g_savedGlobals.sFlowHelp.sHelpQueue[m_iFrameQueueIndex].tHelpText,sDisplayHelp.tHelpText) AND NOT ARE_STRINGS_EQUAL(g_savedGlobals.sFlowHelp.sHelpQueue[m_iFrameQueueIndex].tHelpText,"") IF g_savedGlobals.sFlowHelp.sHelpQueue[m_iFrameQueueIndex].iExpirationTime != FLOW_HELP_NEVER_EXPIRES IF GET_GAME_TIMER() > g_savedGlobals.sFlowHelp.sHelpQueue[m_iFrameQueueIndex].iExpirationTime CPRINTLN(DEBUG_FLOW_HELP, "Queued help message ", g_savedGlobals.sFlowHelp.sHelpQueue[m_iFrameQueueIndex].tHelpText, " timed-out and was cancelled.") CPRINTLN(DEBUG_FLOW_HELP, "Expiration time was ", g_savedGlobals.sFlowHelp.sHelpQueue[m_iFrameQueueIndex].iExpirationTime, " for index ", m_iFrameQueueIndex, ".") //Remove this queued help text item. INT currentItem FOR currentItem = m_iFrameQueueIndex TO (g_savedGlobals.sFlowHelp.iFlowHelpCount-2) PRIVATE_Copy_Queued_Help_From_Index_To_Index(currentItem, currentItem+1) ENDFOR PRIVATE_Clear_Queued_Help_At_Index(g_savedGlobals.sFlowHelp.iFlowHelpCount-1) g_savedGlobals.sFlowHelp.iFlowHelpCount-- //Check if queue priority has changed after removing an item. PRIVATE_Update_Flow_Help_Queue_Priority_Level() ENDIF ENDIF ENDIF //Step index forward for next frame. m_iFrameQueueIndex++ IF m_iFrameQueueIndex >= g_savedGlobals.sFlowHelp.iFlowHelpCount m_iFrameQueueIndex = 0 ENDIF ELIF g_OnMissionState != MISSION_TYPE_FRIEND_ACTIVITY AND g_OnMissionState != MISSION_TYPE_OFF_MISSION AND NOT g_bHeistBoardViewActive //Allow this to run when on a planning board view. CPRINTLN(DEBUG_FLOW_HELP, "Cleaning up due to mission launching.") CLEANUP_HELP_CONTROLLER() ENDIF WAIT(0) ENDWHILE ENDSCRIPT