Files
gtav-src/script/dev_ng/singleplayer/scripts/Minigames/Triathlon/tri_dialogue.sch
T
2025-09-29 00:52:08 +02:00

651 lines
25 KiB
Scheme
Executable File

// *****************************************************************************************
// *****************************************************************************************
// *****************************************************************************************
//
// SCRIPT NAME : TRI_Triathlon_Dialog.sch
// AUTHOR : Carlos Mijares (CM)
// DESCRIPTION : Manages Triathlon dialog.
//
// *****************************************************************************************
// *****************************************************************************************
// *****************************************************************************************
// =====================================
// FILE INCLUDES
// =====================================
// -----------------------------------
// GENERAL INCLUDES
// -----------------------------------
USING "minigames_helpers.sch"
USING "minigame_uiinputs.sch"
USING "commands_xml.sch"
USING "commands_water.sch"
USING "tri_head.sch"
// -----------------------------------
// SPR FILE INCLUDES
// -----------------------------------
USING "tri_helpers_triathlon.sch"
// =====================================
// E N D FILE INCLUDES
// =====================================
CONST_FLOAT OUT_OF_BREATH_THRESHOLD 30.0
// ===================================
// TRIATHLON DIALOG VARIABLES
// ===================================
// Contain all data for the clerk and cash bag synchronized scene.
STRUCT TRI_DIALOG_STRUCT
// Dialog conversation handle.
structPedsForConversation convoStruct
// Dialog group ID. "MGTR_Michael_1.dstar" is the filename
STRING szBlockOfText
// Dialog labels.
STRING szRootLabel_X
// Dialog line lables.
STRING szSpecificLabel_X
// Track at what time, in seconds, the dialog system starts.
FLOAT fSecondsBeforeDialogSystemStarts
// Track the seconds it takes between any dialog being allowed to play again.
FLOAT fSecondsBeforeAnyDialogCanPlay
// The bounds used to randomly determine whether the player or racer will play
// his dialog line, in dialog situations where both speakers have available dialog.
INT iMinBoundForRandomSpeakerSelector
INT iMaxBoundForRandomSpeakerSelector
INT iHalfOfMaxBoundForRandomSpeakerSelector
// Place dialog is played for a racer staying in one race position (1st, 2nd) for
// the random amount of time determined by the bounds below.
FLOAT fMinBoundForRandomTimeToPlayAnyPlaceDialog
FLOAT fMaxBoundForRandomTimeToPlayAnyPlaceDialog
ENDSTRUCT
TRI_DIALOG_STRUCT TriDialog
// Timers to control when to allow any dialog to play.
structTimer timerAnyDialogCanPlay
// Timers to control when to allow dialog to play again.
structTimer timerPlayerDialogCanPlay
structTimer timerPlayerStayInPlaceDialogCanPlay
structTimer timerPlayerStayFirstDialogCanPlay
structTimer timerPlayerStaySecondDialogCanPlay
structTimer timerPlayerStayLastDialogCanPlay
structTimer timerPlayerStaminaDialogCanPlay
// Selects which lines to play when player pushes other racers.
ENUM TRI_DIALOG_PUSH
TRI_DIALOG_PUSH_1,
TRI_DIALOG_PUSH_2,
TRI_DIALOG_PUSH_3,
TRI_DIALOG_PUSH_4,
TRI_DIALOG_PUSH_5,
TRI_DIALOG_PUSH_6,
TRI_DIALOG_PUSH_7,
TRI_DIALOG_NUM_OF_PUSH_LINES
ENDENUM
// Selects which lines to play when player overtakes another racer.
ENUM TRI_DIALOG_RANK_UP
TRI_DIALOG_RANK_UP_1,
TRI_DIALOG_RANK_UP_2,
TRI_DIALOG_RANK_UP_3,
TRI_DIALOG_RANK_UP_4,
TRI_DIALOG_RANK_UP_5,
TRI_DIALOG_RANK_UP_6,
TRI_DIALOG_LEG_UP_1,
TRI_DIALOG_LEG_UP_2,
TRI_DIALOG_LEG_UP_3,
TRI_DIALOG_LEG_UP_4,
TRI_DIALOG_NUM_OF_RANK_UP_LINES
ENDENUM
// Selects which lines to play when player overtakes another racer.
ENUM TRI_DIALOG_RANK_DOWN
TRI_DIALOG_RANK_DOWN_1,
TRI_DIALOG_RANK_DOWN_2,
TRI_DIALOG_RANK_DOWN_3,
TRI_DIALOG_RANK_DOWN_4,
TRI_DIALOG_RANK_DOWN_5,
TRI_DIALOG_RANK_DOWN_6,
TRI_DIALOG_LEG_DOWN_1,
TRI_DIALOG_LEG_DOWN_2,
TRI_DIALOG_LEG_DOWN_3,
TRI_DIALOG_LEG_DOWN_4,
TRI_DIALOG_NUM_OF_RANK_DOWN_LINES
ENDENUM
// Selects which lines to play when player remains in one place.
ENUM TRI_DIALOG_REMAIN_IN_PLACE
TRI_DIALOG_REMAIN_IN_PLACE_1,
TRI_DIALOG_REMAIN_IN_PLACE_2,
TRI_DIALOG_REMAIN_IN_PLACE_3,
TRI_DIALOG_REMAIN_IN_PLACE_4,
TRI_DIALOG_REMAIN_IN_PLACE_5,
TRI_DIALOG_NUM_OF_REMAIN_IN_PLACE_LINES
ENDENUM
// Selects which lines to play when player remains in first place
ENUM TRI_DIALOG_REMAIN_FIRST
TRI_DIALOG_REMAIN_FIRST_1,
TRI_DIALOG_REMAIN_FIRST_2,
TRI_DIALOG_REMAIN_FIRST_3,
TRI_DIALOG_REMAIN_FIRST_4,
TRI_DIALOG_REMAIN_FIRST_5,
TRI_DIALOG_NUM_OF_REMAIN_FIRST_LINES
ENDENUM
// Selects which lines to play when player remains in first place
ENUM TRI_DIALOG_REMAIN_SECOND
TRI_DIALOG_REMAIN_SECOND_1,
TRI_DIALOG_REMAIN_SECOND_2,
TRI_DIALOG_REMAIN_SECOND_3,
TRI_DIALOG_REMAIN_SECOND_4,
TRI_DIALOG_REMAIN_SECOND_5,
TRI_DIALOG_REMAIN_SECOND_6,
TRI_DIALOG_REMAIN_SECOND_7,
TRI_DIALOG_NUM_OF_REMAIN_SECOND_LINES
ENDENUM
// Selects which lines to play when player remains in first place
ENUM TRI_DIALOG_REMAIN_LAST
TRI_DIALOG_REMAIN_LAST_1,
TRI_DIALOG_REMAIN_LAST_2,
TRI_DIALOG_REMAIN_LAST_3,
TRI_DIALOG_REMAIN_LAST_4,
TRI_DIALOG_REMAIN_LAST_5,
TRI_DIALOG_NUM_OF_REMAIN_LAST_LINES
ENDENUM
// ===================================
// E N D TRIATHLON DIALOG VARIABLES
// ===================================
// ========================================
// DIALOG FUNCTIONS AND PROCEDURES
// ========================================
/// PURPOSE:
/// Plays cheers from scenario spectator peds, to be used during countdown and finish.
/// PARAMS:
/// thisRace -
PROC PLAY_TRI_BIG_CHEERS(TRI_RACE_STRUCT& thisRace)
PLAY_SOUND_FROM_COORD(thisRace.iCheerMasterSound, "CROWD_CHEER_MASTER", thisRace.sGate[thisRace.iGateCnt - 1].vPos)
CPRINTLN(DEBUG_TRIATHLON, "[tri_dialogue.sch::PLAY_TRI_BIG_CHEERS] They're CROWD_CHEER_MASTER for me, Michael!")
PLAY_SOUND_FROM_COORD(thisRace.iWallaSound, "POSITIONED_WALLA_MASTER", thisRace.sGate[thisRace.iGateCnt - 1].vPos)
CPRINTLN(DEBUG_TRIATHLON, "[tri_dialogue.sch::PLAY_TRI_BIG_CHEERS] They're POSITIONED_WALLA_MASTER for me, Michael!")
ENDPROC
PROC STOP_TRI_BIG_CHEERS(TRI_RACE_STRUCT& thisRace)
CPRINTLN(DEBUG_TRIATHLON, "[tri_dialogue.sch::STOP_TRI_BIG_CHEERS] Called Stop Sound on the cheers")
STOP_SOUND(thisRace.iCheerMasterSound)
STOP_SOUND(thisRace.iWallaSound)
ENDPROC
PROC PLAY_TRI_AMBIENT_SPEECH(PED_INDEX ped, STRING sContext, SPEECH_PARAMS eParams = SPEECH_PARAMS_FORCE_FRONTEND)
CDEBUG2LN(DEBUG_TRIATHLON, "PLAY_TRI_AMBIENT_SPEECH :: with sContext=", sContext)
PLAY_PED_AMBIENT_SPEECH(ped, sContext, eParams)
ENDPROC
PROC PLAY_TRI_AMBIENT_SPEECH_WITH_VOICE(PED_INDEX ped, STRING sContext, STRING sVoice, SPEECH_PARAMS eParams = SPEECH_PARAMS_FORCE_FRONTEND)
CDEBUG2LN(DEBUG_TRIATHLON, "PLAY_TRI_AMBIENT_SPEECH_WITH_VOICE :: with sContext=", sContext, ", sVoice=", sVoice)
PLAY_PED_AMBIENT_SPEECH_WITH_VOICE(ped, sContext, sVoice, eParams)
ENDPROC
PROC PLAY_SINGLE_LINE_FROM_TRI_CONVO(structPedsForConversation &pedStruct, STRING sBlockOfTextToLoad, STRING sRootLabel, STRING sLabel, enumConversationPriority ePriority, enumSubtitlesState eSubtitles = DISPLAY_SUBTITLES)
IF NOT IS_TRI_CONTROL_FLAG_SET(TCF_NEWS_CAM_ACTIVE)
PLAY_SINGLE_LINE_FROM_CONVERSATION(pedStruct, sBlockOfTextToLoad, sRootLabel, sLabel, ePriority, eSubtitles)
ENDIF
ENDPROC
/// PURPOSE:
/// Play player dialog when he finishes the race.
PROC PLAY_FINISHED_RACE_TRI_PLAYER_DIALOG(TRI_RACE_STRUCT& Race)
STRING sVoice, sContext
SWITCH Race.Racer[0].iRank
// Player won the race.
CASE 1
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
CASE CHAR_MICHAEL sVoice = "MICHAEL_NORMAL" BREAK
CASE CHAR_FRANKLIN sVoice = "FRANKLIN_NORMAL" BREAK
CASE CHAR_TREVOR sVoice = "TREVOR_NORMAL" BREAK
ENDSWITCH
// sContext = PICK_STRING(GET_PLAYER_SPRINT_STAMINA_REMAINING(PLAYER_ID()) < OUT_OF_BREATH_THRESHOLD, "RACE_WIN_POSITION_OUT_OF_BREATH", "GAME_WIN_SELF")
PLAY_TRI_AMBIENT_SPEECH_WITH_VOICE(PLAYER_PED_ID(), "RACE_WIN_POSITION_OUT_OF_BREATH", sVoice)
BREAK
// Player placed 2nd or 3rd in the race.
CASE 2
CASE 3
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
CASE CHAR_MICHAEL sVoice = "MICHAEL_NORMAL" BREAK
CASE CHAR_FRANKLIN sVoice = "FRANKLIN_NORMAL" BREAK
CASE CHAR_TREVOR sVoice = "TREVOR_NORMAL" BREAK
ENDSWITCH
sContext = PICK_STRING(GET_PLAYER_SPRINT_STAMINA_REMAINING(PLAYER_ID()) < OUT_OF_BREATH_THRESHOLD, "RACE_NEARLY_WIN_POSITION_OUT_OF_BREATH", "RACE_NEARLY_WIN")
PLAY_TRI_AMBIENT_SPEECH_WITH_VOICE(PLAYER_PED_ID(), sContext, sVoice)
BREAK
// Player placed in 4th, 5th, 6th or 7th place.
DEFAULT
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
CASE CHAR_MICHAEL sVoice = "MICHAEL_NORMAL" BREAK
CASE CHAR_FRANKLIN sVoice = "FRANKLIN_NORMAL" BREAK
CASE CHAR_TREVOR sVoice = "TREVOR_NORMAL" BREAK
ENDSWITCH
// sContext = PICK_STRING(GET_PLAYER_SPRINT_STAMINA_REMAINING(PLAYER_ID()) < OUT_OF_BREATH_THRESHOLD, "RACE_FINISHED_OUT_OF_BREATH", "GAME_LOSE_SELF")
PLAY_TRI_AMBIENT_SPEECH_WITH_VOICE(PLAYER_PED_ID(), "RACE_FINISHED_OUT_OF_BREATH", sVoice)
BREAK
ENDSWITCH
ENDPROC
/// PURPOSE:
/// Manage which dialog to play for player remaining in last place.
PROC Tri_Play_Dialog_For_Player_Staying_In_Last_Place(TRI_RACE_STRUCT& Race)
IF TIMER_DO_WHEN_READY(timerAnyDialogCanPlay, TriDialog.fSecondsBeforeAnyDialogCanPlay)
IF Tri_Is_Player_In_Last_Place(Race)
IF TIMER_DO_WHEN_READY(timerPlayerRemainingInLastPlace, 10.0)
IF TIMER_DO_WHEN_READY(timerPlayerStayLastDialogCanPlay, GET_RANDOM_FLOAT_IN_RANGE(TriDialog.fMinBoundForRandomTimeToPlayAnyPlaceDialog, TriDialog.fMaxBoundForRandomTimeToPlayAnyPlaceDialog))
STRING sVoice
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
CASE CHAR_MICHAEL sVoice = "MICHAEL_NORMAL" BREAK
CASE CHAR_FRANKLIN sVoice = "FRANKLIN_NORMAL" BREAK
CASE CHAR_TREVOR sVoice = "TREVOR_NORMAL" BREAK
ENDSWITCH
IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_MICHAEL
IF GET_RANDOM_FLOAT_IN_RANGE() < MICHAEL_LINES_GETTING_OLD_CHANCE
PLAY_TRI_AMBIENT_SPEECH_WITH_VOICE(PLAYER_PED_ID(), "GETTING_OLD", "MICHAEL_NORMAL")
CPRINTLN(DEBUG_TRIATHLON, "[tri_dialogue.sch :: Tri_Play_Dialog_For_Player_Staying_In_Last_Place] PLAY_PED_AMBIENT_SPEECH_WITH_VOICE(PLAYER_PED_ID(), GETTING_OLD, MICHAEL_NORMAL)")
ENDIF
ELSE
PLAY_TRI_AMBIENT_SPEECH_WITH_VOICE(PLAYER_PED_ID(), "RACE_STAY_POSITION_OUT_OF_BREATH", sVoice)
ENDIF
// Reset dialog timers
RESTART_TIMER_NOW(timerPlayerStayLastDialogCanPlay)
RESTART_TIMER_NOW(timerAnyDialogCanPlay)
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Manage which dialog to play for player remaining in second place.
PROC Tri_Play_Dialog_For_Player_Staying_In_Second_Place(TRI_RACE_STRUCT& Race)
IF TIMER_DO_WHEN_READY(timerAnyDialogCanPlay, TriDialog.fSecondsBeforeAnyDialogCanPlay)
IF Tri_Is_Player_In_Second_Place(Race)
IF TIMER_DO_WHEN_READY(timerPlayerRemainingInSecondPlace, 10.0)
IF TIMER_DO_WHEN_READY(timerPlayerStaySecondDialogCanPlay, GET_RANDOM_FLOAT_IN_RANGE(TriDialog.fMinBoundForRandomTimeToPlayAnyPlaceDialog, TriDialog.fMaxBoundForRandomTimeToPlayAnyPlaceDialog))
STRING sVoice
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
CASE CHAR_MICHAEL sVoice = "MICHAEL_NORMAL" BREAK
CASE CHAR_FRANKLIN sVoice = "FRANKLIN_NORMAL" BREAK
CASE CHAR_TREVOR sVoice = "TREVOR_NORMAL" BREAK
ENDSWITCH
PLAY_TRI_AMBIENT_SPEECH_WITH_VOICE(PLAYER_PED_ID(), "RACE_STAY_POSITION_OUT_OF_BREATH", sVoice)
// Reset dialog timers.
RESTART_TIMER_NOW(timerPlayerStaySecondDialogCanPlay)
RESTART_TIMER_NOW(timerAnyDialogCanPlay)
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
PROC Tri_Play_Dialog_For_Player_Losing_Stamina()
IF TIMER_DO_WHEN_READY(timerAnyDialogCanPlay, TriDialog.fSecondsBeforeAnyDialogCanPlay)
IF Tri_Player_Stamina.iCurrentEnergy <= 5
IF TIMER_DO_WHEN_READY(timerPlayerStaminaDialogCanPlay, GET_RANDOM_FLOAT_IN_RANGE(TriDialog.fMinBoundForRandomTimeToPlayAnyPlaceDialog, TriDialog.fMaxBoundForRandomTimeToPlayAnyPlaceDialog))
STRING sVoice
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
CASE CHAR_MICHAEL sVoice = "MICHAEL_NORMAL" BREAK
CASE CHAR_FRANKLIN sVoice = "FRANKLIN_NORMAL" BREAK
CASE CHAR_TREVOR sVoice = "TREVOR_NORMAL" BREAK
ENDSWITCH
PLAY_TRI_AMBIENT_SPEECH_WITH_VOICE(PLAYER_PED_ID(), "TRIATHLON_COMMENT", sVoice)
RESTART_TIMER_NOW(timerAnyDialogCanPlay)
RESTART_TIMER_NOW(timerPlayerStaminaDialogCanPlay)
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Manage which dialog to play for player remaining in first place.
PROC Tri_Play_Dialog_For_Player_Staying_In_First_Place(TRI_RACE_STRUCT& Race)
IF TIMER_DO_WHEN_READY(timerAnyDialogCanPlay, TriDialog.fSecondsBeforeAnyDialogCanPlay)
IF Tri_Is_Player_In_First_Place(Race)
IF TIMER_DO_WHEN_READY(timerPlayerRemainingInFirstPlace, 10.0)
IF TIMER_DO_WHEN_READY(timerPlayerStayFirstDialogCanPlay, GET_RANDOM_FLOAT_IN_RANGE(TriDialog.fMinBoundForRandomTimeToPlayAnyPlaceDialog, TriDialog.fMaxBoundForRandomTimeToPlayAnyPlaceDialog))
STRING sVoice
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
CASE CHAR_MICHAEL sVoice = "MICHAEL_NORMAL" BREAK
CASE CHAR_FRANKLIN sVoice = "FRANKLIN_NORMAL" BREAK
CASE CHAR_TREVOR sVoice = "TREVOR_NORMAL" BREAK
ENDSWITCH
PLAY_TRI_AMBIENT_SPEECH_WITH_VOICE(PLAYER_PED_ID(), "RACE_STAY_1ST_OUT_OF_BREATH", sVoice)
// Reset dialog timers.
RESTART_TIMER_NOW(timerPlayerStayFirstDialogCanPlay)
RESTART_TIMER_NOW(timerAnyDialogCanPlay)
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Manage which dialog to play for player remaining in one place during the race.
PROC Tri_Play_Dialog_For_Player_Staying_In_One_Place(TRI_RACE_STRUCT& Race)
IF TIMER_DO_WHEN_READY(timerAnyDialogCanPlay, TriDialog.fSecondsBeforeAnyDialogCanPlay)
IF Tri_Is_Player_In_One_Place(Race)
IF TIMER_DO_WHEN_READY(timerPlayerRemainingInPlace, 10.0)
IF TIMER_DO_WHEN_READY(timerPlayerStayInPlaceDialogCanPlay, GET_RANDOM_FLOAT_IN_RANGE(TriDialog.fMinBoundForRandomTimeToPlayAnyPlaceDialog, TriDialog.fMaxBoundForRandomTimeToPlayAnyPlaceDialog))
STRING sVoice
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
CASE CHAR_MICHAEL sVoice = "MICHAEL_NORMAL" BREAK
CASE CHAR_FRANKLIN sVoice = "FRANKLIN_NORMAL" BREAK
CASE CHAR_TREVOR sVoice = "TREVOR_NORMAL" BREAK
ENDSWITCH
PLAY_TRI_AMBIENT_SPEECH_WITH_VOICE(PLAYER_PED_ID(), "RACE_STAY_POSITION_OUT_OF_BREATH", sVoice)
// Reset dialog timers.
RESTART_TIMER_NOW(timerPlayerStayInPlaceDialogCanPlay)
RESTART_TIMER_NOW(timerAnyDialogCanPlay)
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Manage which dialog to play for AI racer passing player.
PROC Tri_Play_Dialog_For_Racer_Passing_Player(TRI_RACE_STRUCT& Race)
PED_INDEX closestPedToPlayerIndex
// TEXT_LABEL_31 texVoice
IF TIMER_DO_WHEN_READY(timerAnyDialogCanPlay, TriDialog.fSecondsBeforeAnyDialogCanPlay)
IF TIMER_DO_WHEN_READY(timerPlayerDialogCanPlay, GET_RANDOM_FLOAT_IN_RANGE(15.0, 25.0))
//CPRINTLN(DEBUG_TRIATHLON, "[TRI_Triathlon_Helpers->Tri_Update_Dialog_Status] Timer is ready for checking dropping rank at:", GET_TIMER_IN_SECONDS(timerPlayerDialogCanPlay))
IF Tri_Has_Player_Dropped_Rank(Race)
IF Tri_Is_A_Racer_Close_And_On_Screen(Race)
IF GET_RANDOM_INT_IN_RANGE(TriDialog.iMinBoundForRandomSpeakerSelector, TriDialog.iMaxBoundForRandomSpeakerSelector + 1) < TriDialog.iHalfOfMaxBoundForRandomSpeakerSelector
STRING sVoice
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
CASE CHAR_MICHAEL sVoice = "MICHAEL_NORMAL" BREAK
CASE CHAR_FRANKLIN sVoice = "FRANKLIN_NORMAL" BREAK
CASE CHAR_TREVOR sVoice = "TREVOR_NORMAL" BREAK
ENDSWITCH
STRING sContext = PICK_STRING(GET_PLAYER_SPRINT_STAMINA_REMAINING(PLAYER_ID()) < OUT_OF_BREATH_THRESHOLD, "RACE_RANKDOWN_OUT_OF_BREATH", "RACE_RANKDOWN")
PLAY_TRI_AMBIENT_SPEECH_WITH_VOICE(PLAYER_PED_ID(), sContext, sVoice)
ELSE
closestPedToPlayerIndex = Tri_Get_Closest_Racer_To_Player(Race)
IF NOT IS_ENTITY_DEAD(closestPedToPlayerIndex)
PLAY_TRI_AMBIENT_SPEECH(closestPedToPlayerIndex, "GENERIC_INSULT_MED")
ENDIF
ENDIF
// Reset dialog timers.
RESTART_TIMER_NOW(timerPlayerDialogCanPlay)
RESTART_TIMER_NOW(timerAnyDialogCanPlay)
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Manage which dialog to play for player passing AI racer.
PROC Tri_Play_Dialog_For_Player_Passing_Racer(TRI_RACE_STRUCT& Race)
PED_INDEX closestPedToPlayerIndex
//IF TIMER_DO_WHEN_READY(timerPlayerRankUpDialogCanPlay, 1.0)
IF TIMER_DO_WHEN_READY(timerAnyDialogCanPlay, TriDialog.fSecondsBeforeAnyDialogCanPlay)
IF TIMER_DO_WHEN_READY(timerPlayerDialogCanPlay, GET_RANDOM_FLOAT_IN_RANGE(15.0, 25.0))
//CPRINTLN(DEBUG_TRIATHLON, "[TRI_Triathlon_Helpers->Tri_Update_Dialog_Status] Timer is ready for checking improved rank at:", GET_TIMER_IN_SECONDS(timerPlayerDialogCanPlay))
IF Tri_Has_Player_Improved_Rank(Race)
IF Tri_Is_A_Racer_Close_And_On_Screen(Race)
IF GET_RANDOM_INT_IN_RANGE(TriDialog.iMinBoundForRandomSpeakerSelector, TriDialog.iMaxBoundForRandomSpeakerSelector + 1) < TriDialog.iHalfOfMaxBoundForRandomSpeakerSelector
STRING sVoice
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
CASE CHAR_MICHAEL sVoice = "MICHAEL_NORMAL" BREAK
CASE CHAR_FRANKLIN sVoice = "FRANKLIN_NORMAL" BREAK
CASE CHAR_TREVOR sVoice = "TREVOR_NORMAL" BREAK
ENDSWITCH
STRING sContext = PICK_STRING(GET_PLAYER_SPRINT_STAMINA_REMAINING(PLAYER_ID()) < OUT_OF_BREATH_THRESHOLD, "RACE_RANKUP_OUT_OF_BREATH", "RACE_RANKUP")
PLAY_TRI_AMBIENT_SPEECH_WITH_VOICE(PLAYER_PED_ID(), sContext, sVoice)
ELSE
closestPedToPlayerIndex = Tri_Get_Closest_Racer_To_Player(Race)
IF NOT IS_ENTITY_DEAD(closestPedToPlayerIndex)
PLAY_TRI_AMBIENT_SPEECH(closestPedToPlayerIndex, "GENERIC_CURSE_MED")
ENDIF
ENDIF
// Reset dialog timer.
RESTART_TIMER_NOW(timerPlayerDialogCanPlay)
RESTART_TIMER_NOW(timerAnyDialogCanPlay)
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Manage which dialog to play for player pushing AI racer.
PROC Tri_Play_Dialog_For_Racer_Being_Pushed(TRI_RACE_STRUCT& Race)
PED_INDEX closestPedToPlayerIndex
//IF TIMER_DO_WHEN_READY(timerPlayerPushDialogCanPlay, 2.0)
IF TIMER_DO_WHEN_READY(timerAnyDialogCanPlay, TriDialog.fSecondsBeforeAnyDialogCanPlay)
IF TIMER_DO_WHEN_READY(timerPlayerDialogCanPlay, GET_RANDOM_FLOAT_IN_RANGE(15.0, 25.0))
//CPRINTLN(DEBUG_TRIATHLON, "[TRI_Triathlon_Helpers->Tri_Update_Dialog_Status] Timer is ready for checking pushing at:", GET_TIMER_IN_SECONDS(timerPlayerDialogCanPlay))
IF Tri_Has_Player_Pushed_A_Racer(Race)
// Play a line of dialog of player bumping into a ped.
IF GET_RANDOM_INT_IN_RANGE(TriDialog.iMinBoundForRandomSpeakerSelector, TriDialog.iMaxBoundForRandomSpeakerSelector + 1) < TriDialog.iHalfOfMaxBoundForRandomSpeakerSelector
STRING sVoice
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
CASE CHAR_MICHAEL sVoice = "MICHAEL_NORMAL" BREAK
CASE CHAR_FRANKLIN sVoice = "FRANKLIN_NORMAL" BREAK
CASE CHAR_TREVOR sVoice = "TREVOR_NORMAL" BREAK
ENDSWITCH
PLAY_TRI_AMBIENT_SPEECH_WITH_VOICE(PLAYER_PED_ID(), "RACE_COLLIDE_OUT_OF_BREATH", sVoice)
ELSE
closestPedToPlayerIndex = Tri_Get_Closest_Racer_To_Player(Race)
IF NOT IS_ENTITY_DEAD(closestPedToPlayerIndex)
PLAY_TRI_AMBIENT_SPEECH(closestPedToPlayerIndex, "GENERIC_CURSE_MED")
ENDIF
ENDIF
// Reset dialog timers.
RESTART_TIMER_NOW(timerPlayerDialogCanPlay)
RESTART_TIMER_NOW(timerAnyDialogCanPlay)
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Returns TRUE when there are any objectives, warnings, or failure prints on screen.
FUNC BOOL Tri_Is_Important_Text_Being_Displayed_At_Bottom_Screen()
IF IS_THIS_PRINT_BEING_DISPLAYED("SPR_HELP_WARN")
OR IS_THIS_PRINT_BEING_DISPLAYED("SPR_RETR_FAIL")
OR IS_THIS_PRINT_BEING_DISPLAYED("SPR_RETR_DES")
OR IS_THIS_PRINT_BEING_DISPLAYED("SPR_RETR_WARN")
OR IS_THIS_PRINT_BEING_DISPLAYED("SPR_HELP_FAIL")
OR IS_THIS_PRINT_BEING_DISPLAYED("SPR_EXIT_WARN")
OR IS_THIS_PRINT_BEING_DISPLAYED("SPR_EXIT_FAIL")
OR IS_THIS_PRINT_BEING_DISPLAYED("SPR_EXIT_FAIL2")
OR IS_THIS_PRINT_BEING_DISPLAYED("SPR_TXIT_WARN")
OR IS_THIS_PRINT_BEING_DISPLAYED("SPR_TXIT_FAIL")
OR IS_THIS_PRINT_BEING_DISPLAYED("SPR_HELP_WANT")
OR IS_THIS_PRINT_BEING_DISPLAYED("SPR_OBJ_BIKE1")
OR IS_THIS_PRINT_BEING_DISPLAYED("SPR_OBJ_BIKE2")
OR IS_THIS_PRINT_BEING_DISPLAYED("TRI_OBJ_RUN")
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Manage when dialog should be played.
/// Does not play when player speed is below 0.75
PROC UPDATE_TRI_DIALOG(TRI_RACE_STRUCT& thisRace)
IF IS_TRI_CONTROL_FLAG_SET(TCF_NEWS_CAM_ACTIVE)
EXIT
ENDIF
TRI_TRI_RACE_LEG eLeg = Tri_Get_Racer_Current_Race_Leg(thisRace, thisRace.Racer[0])
IF GET_ENTITY_SPEED(thisRace.Racer[0].Driver) > 0.75 AND eLeg <> TRI_TRI_RACE_LEG_SWIM
// Manage which dialog for player pushing AI racer should play.
Tri_Play_Dialog_For_Racer_Being_Pushed(thisRace)
// Manage which dialog to play for player passing AI racer.
Tri_Play_Dialog_For_Player_Passing_Racer(thisRace)
// Manage which dialog to play for AI racer passing player.
Tri_Play_Dialog_For_Racer_Passing_Player(thisRace)
// Manage which dialog to play for player remaining in one place.
Tri_Play_Dialog_For_Player_Staying_In_One_Place(thisRace)
// Manage which dialog to play for player remaining in first place.
Tri_Play_Dialog_For_Player_Staying_In_First_Place(thisRace)
// Manage which dialog to play for player remaining in second place.
Tri_Play_Dialog_For_Player_Staying_In_Second_Place(thisRace)
// Manage which dialog to play for player remaining in last place.
Tri_Play_Dialog_For_Player_Staying_In_Last_Place(thisRace)
// Manage dialog for player stamina reduction
Tri_Play_Dialog_For_Player_Losing_Stamina()
ENDIF
ENDPROC
/// PURPOSE:
/// Setup Triathlon dialog system.
PROC SETUP_TRI_DIALOG()
CPRINTLN(DEBUG_TRIATHLON, "[TRI_Triathlon_Helpers.sch->SETUP_TRI_DIALOG] Procedure started.")
TriDialog.fSecondsBeforeDialogSystemStarts = 0.0
ENDPROC
/// PURPOSE:
/// Initialize Triathlon dialog system.
PROC INIT_TRI_DIALOG()
CPRINTLN(DEBUG_TRIATHLON, "[TRI_Triathlon_Helpers.sch->INIT_TRI_DIALOG] Procedure started.")
// Initialize the time it takes between any dialog being allowed to play again.
TriDialog.fSecondsBeforeAnyDialogCanPlay = 15.0
// Initialize the variables for determining whether the player or AI racer will play a situational type of dialog line.
TriDialog.iMinBoundForRandomSpeakerSelector = 0
TriDialog.iMaxBoundForRandomSpeakerSelector = 10
TriDialog.iHalfOfMaxBoundForRandomSpeakerSelector = TriDialog.iMaxBoundForRandomSpeakerSelector / 2
// Set the time bounds when place dialog can play again.
TriDialog.fMinBoundForRandomTimeToPlayAnyPlaceDialog = 25.0
TriDialog.fMaxBoundForRandomTimeToPlayAnyPlaceDialog = 40.0
// Update the time bounds when place dialog can play again for Ironman, so dialog
// plays less frequently in the lenghtier race.
IF eCurrentTriRace = TRIATHLON_RACE_IRONMAN
TriDialog.fMinBoundForRandomTimeToPlayAnyPlaceDialog = 60.0
TriDialog.fMaxBoundForRandomTimeToPlayAnyPlaceDialog = 120.0
ENDIF
// Fill out the conversation struct.
IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_MICHAEL
ADD_PED_FOR_DIALOGUE(TriDialog.convoStruct, 0, PLAYER_PED_ID(), "MICHAEL")
ELIF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_FRANKLIN
ADD_PED_FOR_DIALOGUE(TriDialog.convoStruct, 1, PLAYER_PED_ID(), "FRANKLIN")
ELIF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_TREVOR
ADD_PED_FOR_DIALOGUE(TriDialog.convoStruct, 2, PLAYER_PED_ID(), "TREVOR")
ENDIF
// Set the dialog labels.
TriDialog.szBlockOfText = "MGTRAUD"
ENDPROC
// ========================================
// E N D DIALOG FUNCTIONS AND PROCEDURES
// ========================================
// *****************************************************************************************
// *****************************************************************************************
// *****************************************************************************************
//
// END OF FILE - DO NOT ADD ANYTHING BELOW THIS BLOCK!
//
// *****************************************************************************************
// *****************************************************************************************
// *****************************************************************************************