Files
2025-09-29 00:52:08 +02:00

371 lines
16 KiB
Python
Executable File

//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