5355 lines
187 KiB
Python
Executable File
5355 lines
187 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.
|
|
|
|
USING "rage_builtins.sch"
|
|
USING "globals.sch"
|
|
USING "select_mission_stage.sch"
|
|
USING "RC_Helper_Functions.sch"
|
|
USING "drunk_public.sch"
|
|
USING "commands_ped.sch"
|
|
USING "script_ped.sch"
|
|
USING "shared_hud_displays.sch"
|
|
USING "cellphone_public.sch"
|
|
USING "dialogue_public.sch"
|
|
USING "CompletionPercentage_public.sch"
|
|
USING "RC_Threat_public.sch"
|
|
USING "RC_Area_public.sch"
|
|
USING "RC_Setup_public.sch"
|
|
USING "initial_scenes_fanatic.sch"
|
|
USING "rgeneral_include.sch"
|
|
USING "cheat_controller_public.sch"
|
|
USING "commands_recording.sch"
|
|
|
|
// *****************************************************************************************
|
|
// *****************************************************************************************
|
|
// *****************************************************************************************
|
|
//
|
|
// MISSION NAME : Fanatic3.sc
|
|
// AUTHOR : Ian Gander
|
|
// DESCRIPTION : Franklin meets Mary-Ann on a beach, and after some flirting,
|
|
// she challenges him to a triathalon of swimming, cycling and
|
|
// jogging
|
|
//
|
|
// *****************************************************************************************
|
|
// *****************************************************************************************
|
|
|
|
g_structRCScriptArgs sRCLauncherDataLocal
|
|
|
|
ENUM MISSION_STAGE
|
|
MS_LEADIN = -1,
|
|
MS_INTRO = 0,
|
|
MS_SWIM = 1,
|
|
MS_TO_BIKE = 2,
|
|
MS_BIKE = 3,
|
|
MS_OFF_BIKE = 4,
|
|
MS_RUN = 5,
|
|
MS_DONE = 6,
|
|
MS_FAILED = 7,
|
|
MS_LOST
|
|
ENDENUM
|
|
|
|
ENUM SUB_STATE
|
|
SS_INIT = 0,
|
|
SS_RUNNING = 1,
|
|
SS_CLEANUP = 2
|
|
ENDENUM
|
|
|
|
ENUM FAILED_REASON
|
|
FAILED_GENERIC = 0,
|
|
FAILED_BIKE_DESTROYED,
|
|
FAILED_YOURBIKE_DESTROYED,
|
|
FAILED_OUT_OF_TIME,
|
|
FAILED_LOST_RACE,
|
|
FAILED_WOMAN_DIED,
|
|
FAILED_WOMAN_HURT,
|
|
FAILED_WOMAN_SCARED,
|
|
FAILED_LEFT_BIKE,
|
|
FAILED_LEFT_AREA
|
|
ENDENUM
|
|
|
|
MISSION_STAGE missionStage = MS_LEADIN
|
|
MISSION_STAGE opponentStage
|
|
SUB_STATE subState = SS_INIT
|
|
|
|
// Checkpoints
|
|
CONST_INT CP_SWIM 0
|
|
CONST_INT CP_BIKE 1
|
|
CONST_INT CP_JOG 2
|
|
CONST_INT CP_OUTRO 3
|
|
|
|
MODEL_NAMES bike_model = scorcher
|
|
MODEL_NAMES DOG_MODEL = A_C_RETRIEVER // Not sure if the dog model is final, so this'll make it easy to change
|
|
VEHICLE_INDEX bike_vehicle
|
|
VEHICLE_INDEX opponent_bike_vehicle
|
|
VEHICLE_INDEX players_bike = NULL
|
|
VEHICLE_INDEX opponent_goto_bike
|
|
VEHICLE_INDEX opponent_car
|
|
VEHICLE_INDEX bad_driver_car
|
|
VEHICLE_INDEX picniccar2
|
|
VEHICLE_INDEX EndingBikeMA
|
|
|
|
VECTOR vEndingBikeMASpawn = <<87.438637,7032.115234,12.044374>>
|
|
FLOAT fEndingBikeMASpawn = 151.459
|
|
|
|
PED_INDEX bad_driver_ped
|
|
PED_INDEX fence_worker
|
|
PED_INDEX binoculars_guy
|
|
PED_INDEX chinups_guy
|
|
PED_INDEX stretching_woman
|
|
PED_INDEX running_dog
|
|
PED_INDEX dog_owner
|
|
|
|
OBJECT_INDEX binocs
|
|
|
|
CONST_INT MAX_SWIM_POSITIONS 7
|
|
CONST_INT MAX_BIKE_POSITIONS 11
|
|
CONST_INT MAX_RUN_POSITIONS 11
|
|
|
|
VECTOR SWIM_POSITIONS[MAX_SWIM_POSITIONS]
|
|
VECTOR BIKE_POSITIONS[MAX_BIKE_POSITIONS]
|
|
VECTOR RUN_POSITIONS[MAX_RUN_POSITIONS]
|
|
|
|
VECTOR vSwimSkip = << -909.0488, 6142.6167, 4.2883 >>
|
|
VECTOR vBikeSkip = << -673.7409, 6138.0962, 1.0698 >>
|
|
VECTOR vJogSkip = << 51.9898, 6768.9653, 19.7661 >>
|
|
VECTOR vOutroSkip = << 64.17, 7048.68, 15.61 >>
|
|
|
|
FLOAT fSwimSkip = 270.65
|
|
FLOAT fBikeSkip = 264.38
|
|
FLOAT fJogSkip = 313.15
|
|
FLOAT fOutroSkip = 195.495
|
|
|
|
VECTOR opponent_pos
|
|
|
|
CHECKPOINT_INDEX checkpoint
|
|
CHECKPOINT_INDEX PrevCheckpoint
|
|
INT iPrevAlpha = 180
|
|
BLIP_INDEX blip
|
|
BLIP_INDEX nextblip
|
|
BLIP_INDEX additional_blip
|
|
BLIP_INDEX opponent_blip
|
|
int iStopTime
|
|
INT iPushTime
|
|
INT current_max_positions
|
|
INT current_position
|
|
INT current_opponent_position
|
|
INT current_opponent_max_positions
|
|
INT race_pos = 1
|
|
Bool won_last_stage = FALSE
|
|
HUD_COLOURS currentCPColour // Have to stick this here for the checkpoint reload
|
|
|
|
PED_INDEX opponent
|
|
STRING sOpponentWaypointName
|
|
CONST_FLOAT RACING_MODIFIER 0.5
|
|
|
|
BOOL bDoMAIntroBoost = FALSE
|
|
INT iMAIntroBoostTimer = -1
|
|
CONST_INT INTRO_BOOST_TIME 5000
|
|
|
|
int iPushStage = 0
|
|
int iBinocStage = 0
|
|
int iStretchStage = 0
|
|
int iChinupStage = 0
|
|
int iOwnerStage = 0
|
|
int iOutroStage = 0
|
|
int iFailStage = 0
|
|
FAILED_REASON FailReason = FAILED_GENERIC
|
|
|
|
int iOutroTimer
|
|
int iTrashTalkTimer
|
|
|
|
INT iCutsceneStage = 0
|
|
|
|
BOOL race_won = FALSE
|
|
BOOL intro_requested = FALSE
|
|
BOOL intro_playing = FALSE
|
|
BOOL bIntroSkipped = FALSE
|
|
//BOOL boat_launched = FALSE
|
|
//BOOL jetski_conv_launched = FALSE
|
|
//BOOL maryann_jetski_conv_launched = FALSE
|
|
BOOL get_back_on_said = FALSE
|
|
BOOL bike_around_trail_said = FALSE
|
|
BOOL bad_driver_launched = FALSE
|
|
BOOL bMADoingJump = FALSE
|
|
BOOL bMAJumpFailed = false
|
|
BOOL bMAPlayerFailComment = TRUE // True by default - we turn it false if the player fails the jump, so then the dialogue can be played
|
|
BOOL bCheated = FALSE
|
|
|
|
BOOL bDoneSwimDialogue = FALSE
|
|
BOOL bTrashTalkActive = FALSE
|
|
BOOL bGivePushWarning = FALSE
|
|
|
|
BOOL bZSkipActive = FALSE // Used for covering up the forced-run if the player skips the cutscene
|
|
|
|
BOOL bAbandonmentWarning = FALSE
|
|
BOOL bDebugRubberBanding = FALSE
|
|
BOOL bLoadedBike = false
|
|
BOOL bLoadedRun = false
|
|
BOOL bSkipped = FALSE
|
|
|
|
BOOL bConvoPaused = FALSE
|
|
//BOOL bCheat1Said = FALSE
|
|
BOOL bCheat2Said = FALSE
|
|
BOOL bCheat3Said = FALSE
|
|
|
|
BOOL bMissedCheckWarning = FALSE
|
|
|
|
BOOL bCheatReload = FALSE
|
|
|
|
BOOL bMaryAnnInFinalArea = FALSE
|
|
BOOL bOutroMALeave = FALSE
|
|
|
|
VECTOR vRoadDisableAA1 = <<-222.053223,6535.530273,2.351944>>
|
|
VECTOR vRoadDisableAA2 = <<-638.4162, 6057.3403,26.191582>>
|
|
FLOAT fRoadDisableAA = 176.25
|
|
|
|
REL_GROUP_HASH RelGroupBuddy
|
|
|
|
BOOL bLeadInConv = FALSE
|
|
|
|
FLOAT fHintFov = 30.0
|
|
FLOAT fHintFollow = 0.35
|
|
FLOAT fHintPitchOrbit = 0.000
|
|
FLOAT fHintSide = 0.10
|
|
FLOAT fHintVert = 0.075 //-0.050
|
|
|
|
// start_time - used to track the time at which the race started
|
|
// race_timer - the eventual total elapsed race time that is displayed
|
|
// replay_timer_addition - used to add any previous time that was accrued in previous attempts at the mission, if starting from a replay
|
|
INT start_time
|
|
int race_timer
|
|
int replay_timer_addition = 0
|
|
|
|
SEQUENCE_INDEX seq
|
|
|
|
BOOL bReplayTrackOn = FALSE
|
|
|
|
STRUCT SMACK_TALK
|
|
BOOL already_said
|
|
STRING ConvRoot
|
|
ENDSTRUCT
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
MissionStageMenuTextStruct s_skip_menu[5]
|
|
INT menu_option
|
|
BOOL bDebug_PrintToTTY = TRUE
|
|
WIDGET_GROUP_ID widgetGroup
|
|
#ENDIF
|
|
|
|
CONST_INT MAX_SMACK_TALK 3
|
|
SMACK_TALK smack[5][MAX_SMACK_TALK]
|
|
|
|
structPedsForConversation conversation
|
|
structPedsForConversation conv_frank
|
|
|
|
TEST_POLY innerBounds
|
|
TEST_POLY MaryAnnBikeBounds
|
|
|
|
// Replay consistency constant
|
|
CONST_INT F3_CHECKPOINT_TIME 0
|
|
|
|
|
|
/// PURPOSE:
|
|
/// Print a string
|
|
/// PARAMS:
|
|
/// s - the string
|
|
PROC DEBUG_PRINTSTRING(String s)
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF bDebug_PrintToTTY
|
|
CPRINTLN(DEBUG_MISSION, s)
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
// Stop release compile error
|
|
s = s
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Print a string, then an int
|
|
/// PARAMS:
|
|
/// s - The string
|
|
/// i - The int
|
|
PROC DEBUG_PRINTSTRINGINT(String s, int i)
|
|
#IF IS_DEBUG_BUILD
|
|
IF bDebug_PrintToTTY
|
|
CPRINTLN(DEBUG_MISSION, s, i)
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
// Stop release compile error
|
|
s = s
|
|
i = i
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Print a string, then a float
|
|
/// PARAMS:
|
|
/// s - The string
|
|
/// f - The float
|
|
PROC DEBUG_PRINTSTRINGF(String s, float f)
|
|
#IF IS_DEBUG_BUILD
|
|
IF bDebug_PrintToTTY
|
|
CPRINTLN(DEBUG_MISSION, s, f)
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
// Stop release compile error
|
|
s = s
|
|
f = f
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Checks whether a given conversation root is the one currently playing
|
|
/// PARAMS:
|
|
/// RootToCheck - The name of the root we want to check
|
|
/// RETURNS:
|
|
/// True if the root we're searching for is the root currently playing, false otherwise
|
|
FUNC BOOL IS_THIS_CONVERSATION_ROOT_PLAYING(STRING RootToCheck)
|
|
TEXT_LABEL_23 blah
|
|
blah = GET_CURRENTLY_PLAYING_STANDARD_CONVERSATION_ROOT()
|
|
IF ARE_STRINGS_EQUAL(blah,RootToCheck)
|
|
RETURN TRUE
|
|
ENDIF
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Set the mission as failed and start running the failed state
|
|
/// PARAMS:
|
|
/// Reason - The reason we're failing for
|
|
PROC MISSION_FAILED(FAILED_REASON Reason = FAILED_GENERIC)
|
|
|
|
DEBUG_PRINTSTRING("MISSION_FAILED CALLED!")
|
|
|
|
SWITCH Reason
|
|
CASE FAILED_GENERIC
|
|
DEBUG_PRINTSTRING("MISSION_FAILED reason=FAILED_GENERIC")
|
|
BREAK
|
|
|
|
CASE FAILED_BIKE_DESTROYED
|
|
DEBUG_PRINTSTRING("MISSION_FAILED reason=FAILED_BIKE_DESTROYED")
|
|
BREAK
|
|
|
|
CASE FAILED_YOURBIKE_DESTROYED
|
|
DEBUG_PRINTSTRING("MISSION_FAILED reason=FAILED_BIKE_DESTROYED")
|
|
BREAK
|
|
|
|
CASE FAILED_OUT_OF_TIME
|
|
DEBUG_PRINTSTRING("MISSION_FAILED reason=FAILED_OUT_OF_TIME")
|
|
BREAK
|
|
|
|
CASE FAILED_LOST_RACE
|
|
DEBUG_PRINTSTRING("MISSION_FAILED reason=FAILED_LOST_RACE")
|
|
BREAK
|
|
|
|
CASE FAILED_WOMAN_DIED
|
|
DEBUG_PRINTSTRING("MISSION_FAILED reason=FAILED_WOMAN_DIED")
|
|
BREAK
|
|
|
|
CASE FAILED_WOMAN_HURT
|
|
DEBUG_PRINTSTRING("MISSION_FAILED reason=FAILED_WOMAN_HURT")
|
|
BREAK
|
|
|
|
CASE FAILED_WOMAN_SCARED
|
|
DEBUG_PRINTSTRING("MISSION_FAILED reason=FAILED_WOMAN_SCARED")
|
|
BREAK
|
|
|
|
CASE FAILED_LEFT_AREA
|
|
DEBUG_PRINTSTRING("MISSION_FAILED reason=FAILED_LEFT_AREA")
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
FailReason = Reason
|
|
missionStage = MS_FAILED
|
|
|
|
ENDPROC
|
|
|
|
// *******************************************
|
|
// Mary-Ann AI brain
|
|
// *******************************************
|
|
|
|
/// PURPOSE:
|
|
/// Load the waypoint recordings for Mary Ann's bike section
|
|
/// RETURNS:
|
|
/// True when the recordings have loaded, false otherwise
|
|
FUNC BOOL ma_pLoadBikeRecs()
|
|
|
|
IF NOT GET_IS_WAYPOINT_RECORDING_LOADED("Fan3_pedBike")
|
|
OR NOT GET_IS_WAYPOINT_RECORDING_LOADED("Fan3_pedBikePanic")
|
|
OR NOT GET_IS_WAYPOINT_RECORDING_LOADED("Fan3_pedBikePrep")
|
|
OR NOT HAS_VEHICLE_RECORDING_BEEN_LOADED(500, "Fan3_MaryAnnBikeJump")
|
|
DEBUG_PRINTSTRING("Waiting for Mary Ann's bike recordings to load")
|
|
REQUEST_WAYPOINT_RECORDING("Fan3_pedBike")
|
|
REQUEST_WAYPOINT_RECORDING("Fan3_pedBikePanic")
|
|
REQUEST_WAYPOINT_RECORDING("Fan3_pedBikePrep")
|
|
REQUEST_VEHICLE_RECORDING(500, "Fan3_MaryAnnBikeJump")
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
RETURN TRUE
|
|
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Load the waypoint recording for Mary Ann's jogging section
|
|
/// RETURNS:
|
|
/// True when the recording has loaded, false otherwise
|
|
FUNC BOOL ma_pLoadJogRecs()
|
|
|
|
IF NOT GET_IS_WAYPOINT_RECORDING_LOADED("fan3_pedJog")
|
|
DEBUG_PRINTSTRING("Requesting Mary Ann's jog waypoint recording")
|
|
REQUEST_WAYPOINT_RECORDING("fan3_pedJog")
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
RETURN TRUE
|
|
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Track and check for player failing the bridge jump, and make Mary Ann comment if appropriate
|
|
PROC ma_pCommentOnPlayerJumpFail()
|
|
|
|
// If the player is in here, they've failed the bridge jump, so we want to try and do the convo
|
|
if IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-151.029358,6589.512207,7.479042>>, <<-164.083267,6577.416016,9.015114>>, 6.000000)
|
|
bMAPlayerFailComment = FALSE
|
|
DEBUG_PRINTSTRING("*** Detected player failed bridge jump")
|
|
ENDIF
|
|
|
|
// If the player has failed the jump, is in the area below the bridge and Mary Ann is close enough, do the convo
|
|
IF NOT bMAPlayerFailComment
|
|
if IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-149.377747,6592.477539,1.723418>>, <<-167.096405,6574.677246,7.915183>>, 21.250000)
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), opponent) < 30
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
IF CREATE_CONVERSATION(conversation, "FAN3AUD", "FAN3_JMPFAIL", CONV_PRIORITY_MEDIUM, DO_NOT_DISPLAY_SUBTITLES)
|
|
bMAPlayerFailComment = TRUE //Convo's been launched, stop trying to do it
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Checks the area below the broken bridge jump for Mary Ann for if she fails it during the bike section.
|
|
/// If so, switches her to the backup waypoint recording to make her proceed via the beach
|
|
PROC ma_pCheckJumpSwitch()
|
|
|
|
IF IS_VEHICLE_OK(opponent_goto_bike)
|
|
AND IS_ENTITY_ALIVE(opponent)
|
|
IF NOT bMAJumpFailed
|
|
if IS_ENTITY_IN_ANGLED_AREA(opponent_goto_bike, <<-149.377747,6592.477539,1.723418>>, <<-167.096405,6574.677246,5.515183>>, 21.250000)
|
|
bMAJumpFailed = TRUE
|
|
DEBUG_PRINTSTRING("*** Mary Ann has fallen below the bridge, switching waypoint recording...")
|
|
IF IS_WAYPOINT_PLAYBACK_GOING_ON_FOR_VEHICLE(opponent_goto_bike)
|
|
sOpponentWaypointName = "Fan3_pedBikePanic"
|
|
REMOVE_WAYPOINT_RECORDING("Fan3_pedBike")
|
|
TASK_VEHICLE_FOLLOW_WAYPOINT_RECORDING(opponent, opponent_goto_bike, sOpponentWaypointName, DRIVINGMODE_AVOIDCARS, 0, EWAYPOINT_START_FROM_CLOSEST_POINT)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Grab Mary Ann from the initial scene struct into the local ped index, and set relationships up
|
|
PROC ma_pCreate()
|
|
|
|
IF IS_ENTITY_ALIVE(sRCLauncherDataLocal.pedID[0])
|
|
opponent = sRCLauncherDataLocal.pedID[0]
|
|
SET_PED_FLEE_ATTRIBUTES(opponent, FA_USE_VEHICLE, TRUE)
|
|
ADD_RELATIONSHIP_GROUP("Buddy", RelGroupBuddy)
|
|
SET_PED_RELATIONSHIP_GROUP_HASH(opponent, RelGroupBuddy)
|
|
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_LIKE, RelGroupBuddy, RELGROUPHASH_PLAYER)
|
|
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_LIKE, RELGROUPHASH_PLAYER, RelGroupBuddy)
|
|
SET_DRIVER_RACING_MODIFIER(opponent, RACING_MODIFIER)
|
|
ELSE
|
|
REQUEST_MODEL(IG_MARYANN)
|
|
WHILE NOT HAS_MODEL_LOADED(IG_MARYANN)
|
|
WAIT(0)
|
|
ENDWHILE
|
|
opponent = CREATE_PED(PEDTYPE_MISSION, IG_MARYANN, <<809.66, 1279.76, 360.49>>, 122.53)
|
|
SET_PED_FLEE_ATTRIBUTES(opponent, FA_USE_VEHICLE, TRUE)
|
|
ADD_RELATIONSHIP_GROUP("Buddy", RelGroupBuddy)
|
|
SET_PED_RELATIONSHIP_GROUP_HASH(opponent, RelGroupBuddy)
|
|
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_LIKE, RelGroupBuddy, RELGROUPHASH_PLAYER)
|
|
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_LIKE, RELGROUPHASH_PLAYER, RelGroupBuddy)
|
|
SET_DRIVER_RACING_MODIFIER(opponent, RACING_MODIFIER)
|
|
ENDIF
|
|
|
|
opponentStage = MS_INTRO
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Set Mary Ann and other various peds to flee, then fail the mission for scaring her
|
|
PROC ma_pAggroFail()
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
|
|
ADD_NON_CRITICAL_STANDARD_CONVERSATION_TO_BUFFER(conversation, "FAN3AUD", "FAN3_SCARED", CONV_PRIORITY_VERY_HIGH, DO_NOT_DISPLAY_SUBTITLES)
|
|
ELSE
|
|
CREATE_CONVERSATION(conversation, "FAN3AUD", "FAN3_SCARED", CONV_PRIORITY_VERY_HIGH, DO_NOT_DISPLAY_SUBTITLES)
|
|
ENDIF
|
|
SAFE_REMOVE_BLIP(opponent_blip)
|
|
SET_PED_KEEP_TASK(opponent, true)
|
|
IF IS_PED_IN_ANY_VEHICLE(opponent)
|
|
TASK_VEHICLE_MISSION_PED_TARGET(opponent, GET_VEHICLE_PED_IS_IN(opponent), PLAYER_PED_ID(), MISSION_FLEE, 30, DRIVINGMODE_AVOIDCARS, 100, 0.1, TRUE)
|
|
SET_PED_FLEE_ATTRIBUTES(opponent, FA_USE_VEHICLE, TRUE)
|
|
DEBUG_PRINTSTRING("Setting Mary Ann Use Vehicle flee attribute")
|
|
ELSE
|
|
TASK_SMART_FLEE_PED(opponent, PLAYER_PED_ID(), 100, -1)
|
|
ENDIF
|
|
|
|
IF IS_ENTITY_ALIVE(binoculars_guy)
|
|
SET_PED_FLEE_ATTRIBUTES(binoculars_guy, FA_USE_VEHICLE | FA_DISABLE_HANDS_UP, TRUE)
|
|
SET_PED_KEEP_TASK(opponent, true)
|
|
TASK_SMART_FLEE_PED(opponent, PLAYER_PED_ID(), 100, -1)
|
|
endif
|
|
|
|
|
|
//PRINT_NOW("FATIC3_13", DEFAULT_GOD_TEXT_TIME, 1) //You scared Mary Ann.
|
|
MISSION_FAILED(FAILED_WOMAN_SCARED)
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// If able, make Mary Ann warn the player about pushing her while on the bike, and fail the mission on the third push
|
|
PROC ma_pGivePushWarning() // This needs to repeat until the warning has been given, since it takes AGES for the conversation to build
|
|
IF bGivePushWarning
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
|
|
ELSE
|
|
IF opponentStage = MS_BIKE
|
|
OR opponentStage = MS_TO_BIKE
|
|
SWITCH iPushStage
|
|
CASE 0
|
|
IF PLAY_SINGLE_LINE_FROM_CONVERSATION(conversation, "FAN3AUD", "FAN3_PUSH", "FAN3_PUSH_1", CONV_PRIORITY_HIGH)
|
|
iPushStage++
|
|
bGivePushWarning = FALSE
|
|
DEBUG_PRINTSTRING("Push warning given: 1...")
|
|
iPushTime = GET_GAME_TIMER() // Reset the timer
|
|
ENDIF
|
|
BREAK
|
|
CASE 1
|
|
IF PLAY_SINGLE_LINE_FROM_CONVERSATION(conversation, "FAN3AUD", "FAN3_PUSH", "FAN3_PUSH_2", CONV_PRIORITY_HIGH)
|
|
iPushStage++
|
|
bGivePushWarning = FALSE
|
|
DEBUG_PRINTSTRING("Push warning given: 2...")
|
|
iPushTime = GET_GAME_TIMER() // Reset the timer
|
|
ENDIF
|
|
BREAK
|
|
CASE 2
|
|
DEBUG_PRINTSTRING("Push warning given: 3, you fail...")
|
|
ma_pAggroFail()
|
|
BREAK
|
|
ENDSWITCH
|
|
ELIF opponentStage = MS_SWIM
|
|
SWITCH iPushStage
|
|
CASE 0
|
|
CASE 1
|
|
CASE 2
|
|
IF CREATE_CONVERSATION(conversation, "FAN3AUD", "FAN3_IMP", CONV_PRIORITY_MEDIUM)
|
|
bGivePushWarning = FALSE
|
|
DEBUG_PRINTSTRINGINT("Swim push warning given: ", iPushStage)
|
|
iPushTime = GET_GAME_TIMER() // Reset the timer
|
|
iPushStage++
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Check for any aggro against Mary Ann from the player, and call ma_pAggroFail() if so
|
|
PROC ma_pCheckAggro()
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
if IS_PLAYER_SHOOTING_NEAR_PED(opponent)
|
|
OR IS_BULLET_IN_AREA(GET_ENTITY_COORDS(opponent), 40, FALSE)
|
|
OR HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(opponent, PLAYER_PED_ID())
|
|
ma_pAggroFail()
|
|
ENDIF
|
|
|
|
// The melee check has to be separate since it's a horrible nested thing
|
|
IF GET_DISTANCE_BETWEEN_PEDS(PLAYER_PED_ID(), opponent) < 1
|
|
IF IS_PED_IN_MELEE_COMBAT(PLAYER_PED_ID())
|
|
// If the player is <1m from Mary Ann and is melee'ing, assume they're trying to hit Mary Ann and scare her off
|
|
// I'm not mad keen on this solution, but I'm not sure how else to handle it...
|
|
ma_pAggroFail()
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF opponentStage = MS_BIKE
|
|
OR opponentStage = MS_TO_BIKE
|
|
IF NOT IS_POINT_IN_POLY_2D(MaryAnnBikeBounds, GET_ENTITY_COORDS(opponent))
|
|
DEBUG_PRINTSTRING("Mary Ann not detected in race area! Failing the mission for this!!")
|
|
ma_pAggroFail() // Mary Ann has left the bike route area and is likely in a spot she can't recover from
|
|
ENDIF
|
|
IF NOT bGivePushWarning
|
|
IF IS_VEHICLE_OK(players_bike) AND IS_VEHICLE_OK(opponent_goto_bike)
|
|
IF IS_ENTITY_TOUCHING_ENTITY(players_bike, opponent_goto_bike)
|
|
OR IS_ENTITY_TOUCHING_ENTITY(PLAYER_PED_ID(), opponent_goto_bike)
|
|
IF IS_ENTITY_TOUCHING_ENTITY(players_bike, opponent_goto_bike)
|
|
DEBUG_PRINTSTRING("Player's bike touched Mary Ann's bike!")
|
|
ENDIF
|
|
IF IS_ENTITY_TOUCHING_ENTITY(PLAYER_PED_ID(), opponent_goto_bike)
|
|
DEBUG_PRINTSTRING("The player touched Mary Ann's bike!")
|
|
ENDIF
|
|
IF (GET_GAME_TIMER() - iPushTime) > 2000
|
|
bGivePushWarning = TRUE // Activates the push dialogue/check
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ELIF opponentStage = MS_SWIM
|
|
IF NOT bGivePushWarning // Reuse the push warning stuff as it's fairly good
|
|
IF IS_ENTITY_TOUCHING_ENTITY(PLAYER_PED_ID(), opponent)
|
|
AND race_pos = 1
|
|
DEBUG_PRINTSTRING("The player touched Mary Ann's during swim!")
|
|
IF (GET_GAME_TIMER() - iPushTime) > 2000
|
|
bGivePushWarning = TRUE // Activates the push dialogue/check
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
if race_pos = 2
|
|
if GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(opponent)) >= 300
|
|
//PRINT_NOW("FATIC3_16", DEFAULT_GOD_TEXT_TIME, 1) //You fell too far behind.
|
|
MISSION_FAILED(FAILED_OUT_OF_TIME)
|
|
ENDIF
|
|
//DEBUG_PRINTSTRINGF("Distance:", GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(opponent)))
|
|
ENDIF
|
|
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Give Mary Ann the very first task she needs when starting a new stage during the race (incl. getting on and off the bike)
|
|
/// PARAMS:
|
|
/// currentStage - The stage we want to call the first task for
|
|
PROC ma_pGiveFirstTask(MISSION_STAGE currentStage)
|
|
// The first task given to the opponent when switching to a new stage
|
|
current_opponent_position = 0
|
|
SWITCH currentStage
|
|
CASE MS_SWIM
|
|
current_opponent_max_positions = MAX_SWIM_POSITIONS
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
TASK_GO_STRAIGHT_TO_COORD(opponent, (SWIM_POSITIONS[current_opponent_position]), PEDMOVE_RUN, DEFAULT_TIME_BEFORE_WARP)
|
|
ENDIF
|
|
BREAK
|
|
CASE MS_TO_BIKE
|
|
IF IS_ENTITY_ALIVE(bike_vehicle) AND IS_ENTITY_ALIVE(opponent_bike_vehicle)
|
|
IF IS_VEHICLE_SEAT_FREE(opponent_bike_vehicle, VS_DRIVER)
|
|
opponent_goto_bike = opponent_bike_vehicle
|
|
ELIF IS_VEHICLE_SEAT_FREE(bike_vehicle, VS_DRIVER)
|
|
opponent_goto_bike = bike_vehicle
|
|
ELSE
|
|
SCRIPT_ASSERT("Both bikes are full?")
|
|
ENDIF
|
|
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
TASK_ENTER_VEHICLE(opponent, opponent_goto_bike, DEFAULT_TIME_BEFORE_WARP, VS_DRIVER, PEDMOVE_SPRINT)
|
|
ENDIF
|
|
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
IF race_pos = 1 // If the player is currently leading the race
|
|
CREATE_CONVERSATION(conversation, "FAN3AUD", "FAN3_SWIMWIN", CONV_PRIORITY_MEDIUM, DO_NOT_DISPLAY_SUBTITLES)
|
|
ELSE
|
|
CREATE_CONVERSATION(conversation, "FAN3AUD", "FAN3_SWIMLOS", CONV_PRIORITY_MEDIUM, DO_NOT_DISPLAY_SUBTITLES)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
iPushTime = GET_GAME_TIMER()
|
|
iPushStage = 0
|
|
|
|
ENDIF
|
|
BREAK
|
|
CASE MS_BIKE
|
|
current_opponent_max_positions = MAX_BIKE_POSITIONS
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
IF NOT IS_MESSAGE_BEING_DISPLAYED()
|
|
OR GET_PROFILE_SETTING(PROFILE_DISPLAY_SUBTITLES) = 0
|
|
CREATE_CONVERSATION(conversation, "FAN3AUD", "FAN3_RUNTO", CONV_PRIORITY_MEDIUM, DISPLAY_SUBTITLES)
|
|
ELSE
|
|
CREATE_CONVERSATION(conversation, "FAN3AUD", "FAN3_RUNTO", CONV_PRIORITY_MEDIUM, DO_NOT_DISPLAY_SUBTITLES)
|
|
ENDIF
|
|
ENDIF
|
|
ma_pLoadBikeRecs()
|
|
BREAK
|
|
CASE MS_OFF_BIKE
|
|
IF IS_ENTITY_ALIVE(opponent) AND IS_VEHICLE_OK(opponent_goto_bike)
|
|
IF IS_WAYPOINT_PLAYBACK_GOING_ON_FOR_VEHICLE(opponent_goto_bike)
|
|
REMOVE_WAYPOINT_RECORDING("Fan3_pedBike")
|
|
REMOVE_WAYPOINT_RECORDING("Fan3_pedBikePanic")
|
|
ENDIF
|
|
IF IS_PED_IN_VEHICLE(opponent, opponent_goto_bike)
|
|
BRING_VEHICLE_TO_HALT(opponent_goto_bike, 5, 10)
|
|
TASK_LEAVE_ANY_VEHICLE(opponent)
|
|
ENDIF
|
|
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
IF race_pos = 1 // If the player is currently leading the race
|
|
CREATE_CONVERSATION(conversation, "FAN3AUD", "FAN3_BIKEWIN", CONV_PRIORITY_MEDIUM, DO_NOT_DISPLAY_SUBTITLES)
|
|
ELSE
|
|
CREATE_CONVERSATION(conversation, "FAN3AUD", "FAN3_BIKELOS", CONV_PRIORITY_MEDIUM, DO_NOT_DISPLAY_SUBTITLES)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
BREAK
|
|
CASE MS_RUN
|
|
current_opponent_max_positions = MAX_RUN_POSITIONS
|
|
ma_pLoadJogRecs()
|
|
BREAK
|
|
CASE MS_FAILED
|
|
BREAK
|
|
DEFAULT
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Switch Mary Ann to a new state during the race, then call ma_pGiveFirstTask() to set her going
|
|
/// Note: does not teleport her, must be done before this is called if used for a skip!
|
|
/// PARAMS:
|
|
/// newStage - The stage we want Mary Ann to switch to
|
|
PROC ma_pSwitchState(MISSION_STAGE newStage)
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
KILL_ANY_CONVERSATION()
|
|
ENDIF
|
|
IF newStage <> opponentStage
|
|
opponentStage = newStage
|
|
ma_pGiveFirstTask(newStage)
|
|
ELIF bSkipped = TRUE
|
|
ma_pGiveFirstTask(newStage) //If we're currently skipping back to the start of the current stage, retask Mary Ann
|
|
ENDIF
|
|
bConvoPaused = FALSE
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// If Mary Ann falls too far behind in the bike race, secretly teleport her ahead a bit
|
|
PROC ma_pCheckForTeleport()
|
|
|
|
IF opponentStage = MS_BIKE
|
|
AND missionStage = MS_BIKE
|
|
IF race_pos = 1 // If the player is ahead
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
AND IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
IF ARE_STRINGS_EQUAL(sOpponentWaypointName, "Fan3_pedBike")
|
|
|
|
// Getting the player's current closest waypoint now to use in the IF check...
|
|
int iCurrPlayerWaypoint
|
|
WAYPOINT_RECORDING_GET_CLOSEST_WAYPOINT(sOpponentWaypointName, GET_ENTITY_COORDS(PLAYER_PED_ID()), iCurrPlayerWaypoint)
|
|
|
|
IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(opponent)) > 65 // If player is >65m ahead...
|
|
AND iCurrPlayerWaypoint > 26 // ... and past the 26th waypoint...
|
|
AND IS_WAYPOINT_PLAYBACK_GOING_ON_FOR_VEHICLE(opponent_goto_bike) // ... and if Mary Ann is doing a waypoint recording
|
|
IF IS_ENTITY_ALIVE(opponent_goto_bike)
|
|
// Get the nearest waypoints to Mary Ann
|
|
int iCurrOpponentWaypoint
|
|
|
|
IF IS_WAYPOINT_PLAYBACK_GOING_ON_FOR_VEHICLE(opponent_goto_bike)
|
|
WAYPOINT_RECORDING_GET_CLOSEST_WAYPOINT(sOpponentWaypointName, GET_ENTITY_COORDS(opponent_goto_bike), iCurrOpponentWaypoint)
|
|
WAYPOINT_RECORDING_GET_CLOSEST_WAYPOINT(sOpponentWaypointName, GET_ENTITY_COORDS(PLAYER_PED_ID()), iCurrPlayerWaypoint)
|
|
ENDIF
|
|
|
|
// We want to teleport Mary Ann about 5 waypoints behind the player, so let's take that amount off of the player's nearest WP
|
|
iCurrPlayerWaypoint -= 5
|
|
// And we need that waypoint's vector, and the vector of the next one
|
|
VECTOR vWaypointDestCoord
|
|
VECTOR vWayPointDestNextCoord
|
|
WAYPOINT_RECORDING_GET_COORD(sOpponentWaypointName, iCurrPlayerWaypoint, vWaypointDestCoord)
|
|
WAYPOINT_RECORDING_GET_COORD(sOpponentWaypointName, iCurrPlayerWaypoint+1, vWayPointDestNextCoord)
|
|
|
|
// Only teleport if we can't see the old AND the new locations
|
|
IF NOT IS_SPHERE_VISIBLE(GET_ENTITY_COORDS(opponent), 3)
|
|
AND NOT IS_SPHERE_VISIBLE(vWaypointDestCoord, 3)
|
|
FLOAT fOldSpeed = GET_ENTITY_SPEED(opponent)
|
|
SET_ENTITY_COORDS(opponent_goto_bike, vWaypointDestCoord)
|
|
SET_ENTITY_HEADING_FACE_COORDS(opponent_goto_bike, vWayPointDestNextCoord) // Face next checkpoint
|
|
IF NOT IS_PED_IN_VEHICLE(opponent, opponent_goto_bike)
|
|
SET_PED_INTO_VEHICLE(opponent, opponent_goto_bike)
|
|
ENDIF
|
|
TASK_VEHICLE_FOLLOW_WAYPOINT_RECORDING(opponent, opponent_goto_bike, sOpponentWaypointName, DRIVINGMODE_AVOIDCARS|DF_SteerAroundPeds, 0,
|
|
EWAYPOINT_START_FROM_CLOSEST_POINT|EWAYPOINT_VEHICLES_USE_AI_SLOWDOWN)
|
|
SET_VEHICLE_FORWARD_SPEED(opponent_goto_bike, fOldSpeed)
|
|
DEBUG_PRINTSTRINGINT("*** Teleported Mary Ann to waypoint ", iCurrPlayerWaypoint)
|
|
|
|
// Now we need to make sure she's not skipped over a checkpoint during the teleport...
|
|
IF iCurrPlayerWaypoint < 14
|
|
current_opponent_position = 0 // Mary Ann is before the first checkpoint (will this even get called?)
|
|
ELIF iCurrPlayerWaypoint < 26
|
|
current_opponent_position = 1 // Just before the second CP...
|
|
ELIF iCurrPlayerWaypoint < 35
|
|
current_opponent_position = 2 // and so on...
|
|
ELIF iCurrPlayerWaypoint < 45
|
|
current_opponent_position = 3 // ... so Mary Ann should hit the checkpoints ahead of these waypoints
|
|
ELIF iCurrPlayerWaypoint < 53
|
|
current_opponent_position = 4 // ... and her checkpoint counter will increment right after the teleport
|
|
ELIF iCurrPlayerWaypoint < 60
|
|
current_opponent_position = 5 // ... in theory
|
|
ELIF iCurrPlayerWaypoint < 68
|
|
current_opponent_position = 6 // Hey, if you're reading this, that means I checked it in because it worked
|
|
ELIF iCurrPlayerWaypoint < 79
|
|
current_opponent_position = 7
|
|
ELIF iCurrPlayerWaypoint < 98
|
|
current_opponent_position = 8
|
|
ELIF iCurrPlayerWaypoint < 135
|
|
current_opponent_position = 9
|
|
ELSE
|
|
// No idea where Mary Ann is, so let's just put her here
|
|
current_opponent_position = 9
|
|
ENDIF
|
|
// If Mary Ann was on the beach panic route, she won't get teleported
|
|
|
|
ELSE
|
|
DEBUG_PRINTSTRING("*** Trying to teleport, but points are visible!!")
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
FLOAT fPriorSpeed
|
|
|
|
PROC ma_pDoBridgeJump(int iCurrWaypoint = 0)
|
|
|
|
CONST_FLOAT BRIDGE_BOOST_SPEED 20.0
|
|
|
|
IF IS_ENTITY_ALIVE(opponent_goto_bike)
|
|
IF IS_WAYPOINT_PLAYBACK_GOING_ON_FOR_VEHICLE(opponent_goto_bike)
|
|
|
|
// When we get to waypoint 7 in the jump prep waypoint recording, transition Mary Ann to the vehicle recording for the actual jump
|
|
IF iCurrWaypoint >= 7
|
|
// This is for if I need to re-record the jump recording, leave commented out for release builds!
|
|
// IF NOT IS_RECORDING_GOING_ON_FOR_VEHICLE(opponent_goto_bike)
|
|
// START_RECORDING_VEHICLE(opponent_goto_bike, 500, "Fan3_MaryAnnBikeJump", TRUE)
|
|
// ENDIF
|
|
IF NOT IS_PLAYBACK_USING_AI_GOING_ON_FOR_VEHICLE(opponent_goto_bike)
|
|
AND NOT IS_PLAYBACK_GOING_ON_FOR_VEHICLE(opponent_goto_bike)
|
|
DEBUG_PRINTSTRING("******* USING RECORDING NOW")
|
|
bMADoingJump = TRUE
|
|
// Uses AI to smoothly transition from the waypoint playback position to the exact recorded position needed for the jump
|
|
START_PLAYBACK_RECORDED_VEHICLE_USING_AI(opponent_goto_bike, 500, "Fan3_MaryAnnBikeJump", BRIDGE_BOOST_SPEED+1.0, DRIVINGMODE_PLOUGHTHROUGH)
|
|
SET_PLAYBACK_TO_USE_AI_TRY_TO_REVERT_BACK_LATER(opponent_goto_bike, 1250, DRIVINGMODE_PLOUGHTHROUGH, TRUE)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
//***************
|
|
// Everything down here in this section is used for re-recording the jump vehicle recording and won't affect normal gameplay
|
|
//***************
|
|
|
|
// If the prior speed is 0 (basically if we haven't done it yet), get Mary Ann's current speed this frame
|
|
IF fPriorSpeed = 0.0
|
|
fPriorSpeed = GET_ENTITY_SPEED(opponent)
|
|
ENDIF
|
|
|
|
// The waypoint #'s will probably have to change if the jump prep waypoint rec changes
|
|
// It's a vehicle boost so Mary Ann can actually make the jump
|
|
IF iCurrWaypoint >= 7
|
|
AND iCurrWaypoint <= 16
|
|
float fPlaybackSpd = fPriorSpeed + 0.1
|
|
IF fPlaybackSpd > BRIDGE_BOOST_SPEED
|
|
fPlaybackSpd = BRIDGE_BOOST_SPEED
|
|
ENDIF
|
|
fPriorSpeed = fPlaybackSpd
|
|
//DEBUG_PRINTSTRINGF("Mary Ann bridge boost: setting fPlaybackSpd to ", fPlaybackSpd)
|
|
//DEBUG_PRINTSTRINGF("Actual entity speed is ", GET_ENTITY_SPEED(opponent))
|
|
//SET_VEHICLE_FORWARD_SPEED(opponent_goto_bike, fPlaybackSpd)
|
|
//VEHICLE_WAYPOINT_PLAYBACK_OVERRIDE_SPEED(opponent_goto_bike, fPlaybackSpd)
|
|
ENDIF
|
|
|
|
// Stop recording once we've reached waypoint 20 in the jump prep waypoint rec
|
|
IF iCurrWaypoint >= 20
|
|
DEBUG_PRINTSTRING("******* SWITCHING BACK TO WAYPOINT")
|
|
// IF IS_RECORDING_GOING_ON_FOR_VEHICLE(opponent_goto_bike)
|
|
// DEBUG_PRINTSTRING("******* STOPPING RECORDING")
|
|
// STOP_RECORDING_VEHICLE(opponent_goto_bike)
|
|
// ENDIF
|
|
IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(opponent_goto_bike)
|
|
DEBUG_PRINTSTRING("******* STOPPING PLAYBACK")
|
|
STOP_PLAYBACK_RECORDED_VEHICLE(opponent_goto_bike)
|
|
ENDIF
|
|
sOpponentWaypointName = "Fan3_pedBike"
|
|
TASK_VEHICLE_FOLLOW_WAYPOINT_RECORDING(opponent, opponent_goto_bike, sOpponentWaypointName, DRIVINGMODE_AVOIDCARS|DF_SteerAroundPeds, 0,
|
|
EWAYPOINT_START_FROM_CLOSEST_POINT|EWAYPOINT_VEHICLES_USE_AI_SLOWDOWN)
|
|
bMADoingJump = FALSE
|
|
ENDIF
|
|
|
|
ELSE
|
|
// If we're here, Mary Ann's doing the bridge jump via vehicle recording and we need to switch her back to waypoint when appropriate
|
|
WAYPOINT_RECORDING_GET_CLOSEST_WAYPOINT(sOpponentWaypointName, GET_ENTITY_COORDS(opponent_goto_bike), iCurrWaypoint)
|
|
DEBUG_PRINTSTRINGINT("DOING RECORDING, CLOSEST WP IS: ", iCurrWaypoint)
|
|
IF iCurrWaypoint >= 20
|
|
DEBUG_PRINTSTRING("******* SWITCHING BACK TO WAYPOINT")
|
|
IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(opponent_goto_bike)
|
|
or IS_PLAYBACK_USING_AI_GOING_ON_FOR_VEHICLE(opponent_goto_bike)
|
|
DEBUG_PRINTSTRING("******* STOPPING PLAYBACK")
|
|
STOP_PLAYBACK_RECORDED_VEHICLE(opponent_goto_bike)
|
|
ENDIF
|
|
// Retask to use the full route again - back to the rubber banding function!
|
|
sOpponentWaypointName = "Fan3_pedBike"
|
|
TASK_VEHICLE_FOLLOW_WAYPOINT_RECORDING(opponent, opponent_goto_bike, sOpponentWaypointName, DRIVINGMODE_AVOIDCARS|DF_SteerAroundPeds, 0,
|
|
EWAYPOINT_START_FROM_CLOSEST_POINT|EWAYPOINT_VEHICLES_USE_AI_SLOWDOWN)
|
|
bMADoingJump = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Rubber band Mary Ann's speed during all stages of the race
|
|
PROC ma_pRubberBanding()
|
|
float fDist
|
|
float fRatioModifier
|
|
float fMoveRatio = 2.0
|
|
|
|
fDist = GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(opponent))
|
|
IF fDist > 45
|
|
fDist = 45
|
|
ENDIF
|
|
fRatioModifier = (fDist / 100)
|
|
IF race_pos = 2 // If player is in second place...
|
|
IF opponentStage = MS_SWIM
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
fMoveRatio = fMoveRatio - fRatioModifier // Reduce opponent speed
|
|
SET_PED_DESIRED_MOVE_BLEND_RATIO(opponent, fMoveRatio + 0.2) // Slow her down just a little bit for swimming
|
|
IF bDebugRubberBanding
|
|
//DEBUG_PRINTSTRINGINT("race_pos:", race_pos)
|
|
DEBUG_PRINTSTRINGF("fDist is", fDist)
|
|
DEBUG_PRINTSTRINGF("Setting fMoveRatio to", fMoveRatio)
|
|
ENDIF
|
|
ENDIF
|
|
ELIF opponentStage = MS_RUN
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
fMoveRatio = fMoveRatio - fRatioModifier // Reduce opponent speed
|
|
fMoveRatio += 0.5
|
|
IF IS_WAYPOINT_PLAYBACK_GOING_ON_FOR_PED(opponent)
|
|
WAYPOINT_PLAYBACK_OVERRIDE_SPEED(opponent, fMoveRatio)
|
|
ENDIF
|
|
IF bDebugRubberBanding
|
|
//DEBUG_PRINTSTRINGINT("race_pos:", race_pos)
|
|
DEBUG_PRINTSTRINGF("fDist is", fDist)
|
|
DEBUG_PRINTSTRINGF("Setting fMoveRatio to", fMoveRatio)
|
|
ENDIF
|
|
ENDIF
|
|
ELIF opponentStage = MS_BIKE
|
|
// As Mary Ann gets closer to Franklin, the amount we're pulling her back by decreases until it's basically nil and then there's basically no rubber banding
|
|
// If the distance is <5m, can it to that so we're always slowing her down a little bit
|
|
IF fDist < 5
|
|
fDist = 5
|
|
fRatioModifier = (fDist / 100)
|
|
ENDIF
|
|
IF IS_ENTITY_ALIVE(opponent_goto_bike)
|
|
IF GET_IS_WAYPOINT_RECORDING_LOADED("Fan3_pedBike")
|
|
AND GET_IS_WAYPOINT_RECORDING_LOADED("Fan3_pedBikePrep")
|
|
IF IS_WAYPOINT_PLAYBACK_GOING_ON_FOR_VEHICLE(opponent_goto_bike)
|
|
// We get the nearest waypoint to the opponent's current position...
|
|
int iCurrWaypoint
|
|
|
|
WAYPOINT_RECORDING_GET_CLOSEST_WAYPOINT(sOpponentWaypointName, GET_ENTITY_COORDS(opponent_goto_bike), iCurrWaypoint)
|
|
// ... and then dial-down the speed of that waypoint to set the opponent's rubber-banded speed
|
|
// If Mary Ann is around the bridge, let her get up to the recorded speed so she makes the jump - otherwise, rubber band her
|
|
|
|
IF ARE_STRINGS_EQUAL(sOpponentWaypointName, "Fan3_pedBike")
|
|
|
|
IF iCurrWaypoint < 98
|
|
OR iCurrWaypoint >= 107
|
|
|
|
float fPlaybackSpd = WAYPOINT_RECORDING_GET_SPEED_AT_POINT(sOpponentWaypointName, iCurrWaypoint)
|
|
// The ratio modifier is by default calculated for on-foot speeds at 0.2, 0.3, etc, for the other two sections
|
|
// Here, we want it to apply to vehicle values, between 2.0, 3.0, etc - so multiply by 10
|
|
fRatioModifier = (fRatioModifier * 10)
|
|
fPlaybackSpd = ((fPlaybackSpd - fRatioModifier) - 7.5)
|
|
IF bDebugRubberBanding
|
|
DEBUG_PRINTSTRINGF("fRatioModifier is ", fRatioModifier)
|
|
DEBUG_PRINTSTRINGF("Setting fPlaybackSpd to ", fPlaybackSpd)
|
|
DEBUG_PRINTSTRINGF("Actual entity speed is ", GET_ENTITY_SPEED(opponent))
|
|
//DEBUG_PRINTSTRINGF("Distance is ", GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(opponent)))
|
|
ENDIF
|
|
VEHICLE_WAYPOINT_PLAYBACK_OVERRIDE_SPEED(opponent_goto_bike, fPlaybackSpd)
|
|
ENDIF
|
|
|
|
IF iCurrWaypoint > 93
|
|
AND iCurrWaypoint < 98
|
|
DEBUG_PRINTSTRING("**** SWITCHING TO JUMP PREP")
|
|
sOpponentWaypointName = "Fan3_pedBikePrep"
|
|
TASK_VEHICLE_FOLLOW_WAYPOINT_RECORDING(opponent, opponent_goto_bike, sOpponentWaypointName, DRIVINGMODE_PLOUGHTHROUGH, 0,
|
|
EWAYPOINT_START_FROM_CLOSEST_POINT|EWAYPOINT_VEHICLES_USE_AI_SLOWDOWN)
|
|
ENDIF
|
|
ELSE
|
|
ma_pDoBridgeJump(iCurrWaypoint)
|
|
ENDIF
|
|
ELSE
|
|
ma_pDoBridgeJump()
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ELSE // Player is in first place
|
|
IF opponentStage = MS_SWIM
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
fMoveRatio = fMoveRatio + fRatioModifier // Increase opponent speed
|
|
fMoveRatio+=0.9
|
|
IF fMoveRatio > 3.0
|
|
fMoveRatio = 3.0 // Cap the ratio to 3.0, because it's the max
|
|
ENDIF
|
|
SET_PED_DESIRED_MOVE_BLEND_RATIO(opponent, fMoveRatio)
|
|
IF bDebugRubberBanding
|
|
DEBUG_PRINTSTRINGF("fDist is ", fDist)
|
|
DEBUG_PRINTSTRINGF("Setting fMoveRatio to ", fMoveRatio)
|
|
DEBUG_PRINTSTRINGF("Actual speed is ", GET_ENTITY_SPEED(opponent))
|
|
ENDIF
|
|
ENDIF
|
|
ELIF opponentStage = MS_RUN
|
|
fMoveRatio = fMoveRatio + fRatioModifier // Increase opponent speed
|
|
fMoveRatio += 0.4 // Add extra speed for the running section
|
|
// If Mary Ann is 3m or less behind you, give her some extra speed so she doesn't hang back if you're just jogging
|
|
IF fDist <= 3.0
|
|
fMoveRatio += 0.12
|
|
ENDIF
|
|
IF fMoveRatio > 3.0
|
|
fMoveRatio = 3.0 // Cap the ratio to 3.0, because it's the max
|
|
ENDIF
|
|
IF IS_WAYPOINT_PLAYBACK_GOING_ON_FOR_PED(opponent)
|
|
WAYPOINT_PLAYBACK_OVERRIDE_SPEED(opponent, fMoveRatio)
|
|
ENDIF
|
|
IF bDebugRubberBanding
|
|
DEBUG_PRINTSTRINGF("fDist is ", fDist)
|
|
DEBUG_PRINTSTRINGF("Setting fMoveRatio to ", fMoveRatio)
|
|
DEBUG_PRINTSTRINGF("Actual speed is ", GET_ENTITY_SPEED(opponent))
|
|
ENDIF
|
|
ELIF opponentStage = MS_BIKE
|
|
IF IS_ENTITY_ALIVE(opponent_goto_bike)
|
|
IF IS_WAYPOINT_PLAYBACK_GOING_ON_FOR_VEHICLE(opponent_goto_bike)
|
|
// We get the nearest waypoint to the opponent's current position...
|
|
int iCurrWaypoint
|
|
WAYPOINT_RECORDING_GET_CLOSEST_WAYPOINT(sOpponentWaypointName, GET_ENTITY_COORDS(opponent_goto_bike), iCurrWaypoint)
|
|
// ... and then dial-up the speed of that waypoint to set the opponent's rubber-banded speed
|
|
|
|
IF ARE_STRINGS_EQUAL(sOpponentWaypointName, "Fan3_pedBike")
|
|
IF iCurrWaypoint < 98
|
|
OR iCurrWaypoint >= 107
|
|
|
|
float fPlaybackSpd = WAYPOINT_RECORDING_GET_SPEED_AT_POINT(sOpponentWaypointName, iCurrWaypoint)
|
|
// The ratio modifier is calculated for on-foot speeds at 0.2, 0.3, etc, for the other two sections
|
|
// Here, we want it to apply to vehicle values, between 2.0, 3.0, etc - so multiply by 10
|
|
fRatioModifier = (fRatioModifier * 10)
|
|
fPlaybackSpd = ((fPlaybackSpd + fRatioModifier) + 3.0)
|
|
IF bDebugRubberBanding
|
|
//DEBUG_PRINTSTRINGINT("race_pos:", race_pos)
|
|
DEBUG_PRINTSTRINGF("fRatioModifier is ", fRatioModifier)
|
|
DEBUG_PRINTSTRINGF("Setting fPlaybackSpd to ", fPlaybackSpd)
|
|
DEBUG_PRINTSTRINGF("Actual entity speed is ", GET_ENTITY_SPEED(opponent))
|
|
//DEBUG_PRINTSTRINGF("Distance is ", GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(opponent)))
|
|
ENDIF
|
|
VEHICLE_WAYPOINT_PLAYBACK_OVERRIDE_SPEED(opponent_goto_bike, fPlaybackSpd)
|
|
ENDIF
|
|
|
|
IF iCurrWaypoint > 93
|
|
AND iCurrWaypoint < 98
|
|
DEBUG_PRINTSTRING("**** SWITCHING TO JUMP PREP")
|
|
sOpponentWaypointName = "Fan3_pedBikePrep"
|
|
TASK_VEHICLE_FOLLOW_WAYPOINT_RECORDING(opponent, opponent_goto_bike, sOpponentWaypointName, DRIVINGMODE_PLOUGHTHROUGH|DF_SteerAroundPeds, 0,
|
|
EWAYPOINT_START_FROM_CLOSEST_POINT|EWAYPOINT_VEHICLES_USE_AI_SLOWDOWN)
|
|
ENDIF
|
|
ELSE
|
|
ma_pDoBridgeJump(iCurrWaypoint)
|
|
ENDIF
|
|
ELSE
|
|
ma_pDoBridgeJump()
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Actions that are called every frame or when the opponent's current checkpoint is updated, depending on the current stage
|
|
PROC ma_pPerformAction()
|
|
SWITCH opponentStage
|
|
CASE MS_SWIM
|
|
TASK_GO_STRAIGHT_TO_COORD(opponent, (SWIM_POSITIONS[current_opponent_position]), PEDMOVE_SPRINT, DEFAULT_TIME_BEFORE_WARP, DEFAULT_NAVMESH_RADIUS)//, ENAV_NO_STOPPING)
|
|
DEBUG_PRINTSTRINGINT("*** Updating Mary Ann swimming task to pos", current_opponent_position)
|
|
BREAK
|
|
CASE MS_TO_BIKE
|
|
// None - already told to go to bike
|
|
BREAK
|
|
CASE MS_BIKE
|
|
IF IS_ENTITY_ALIVE(opponent) AND IS_VEHICLE_OK(opponent_goto_bike)
|
|
IF NOT IS_WAYPOINT_PLAYBACK_GOING_ON_FOR_VEHICLE(opponent_goto_bike)
|
|
AND bMADoingJump = FALSE
|
|
IF current_opponent_position > 2
|
|
// This is to fix 739591, where Mary Ann gets herself into a position where she finishes the waypoint recording,
|
|
// but has missed a checkpoint along the way and thus never hits the final one, so ma_pDoCheckpoints() never returns true...
|
|
DEBUG_PRINTSTRING("*** Mary Ann has missed a position but reached the end of the bike route!!")
|
|
DEBUG_PRINTSTRING("*** Changing position to 11 so the check returns true...")
|
|
current_opponent_position = MAX_BIKE_POSITIONS
|
|
ENDIF
|
|
DEBUG_PRINTSTRING("*** Mary Ann: Doing start of bike section setup")
|
|
sOpponentWaypointName = "Fan3_pedBike"
|
|
SET_VEHICLE_DOORS_LOCKED(opponent_goto_bike, VEHICLELOCK_LOCKOUT_PLAYER_ONLY)
|
|
SET_ENTITY_CAN_BE_DAMAGED(opponent_goto_bike, FALSE)
|
|
TASK_VEHICLE_FOLLOW_WAYPOINT_RECORDING(opponent, opponent_goto_bike, sOpponentWaypointName, DRIVINGMODE_AVOIDCARS|DF_SteerAroundPeds, 0,
|
|
EWAYPOINT_START_FROM_CLOSEST_POINT|EWAYPOINT_VEHICLES_USE_AI_SLOWDOWN)
|
|
SAFE_REMOVE_BLIP(additional_blip)
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE MS_OFF_BIKE
|
|
IF IS_PED_SITTING_IN_VEHICLE(opponent, opponent_goto_bike)
|
|
BRING_VEHICLE_TO_HALT(opponent_goto_bike, 5, 10)
|
|
TASK_LEAVE_ANY_VEHICLE(opponent)
|
|
ENDIF
|
|
// Repeatedly try and get Mary Ann off her bike if she's STILL in it
|
|
BREAK
|
|
CASE MS_RUN
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
IF NOT IS_WAYPOINT_PLAYBACK_GOING_ON_FOR_PED(opponent)
|
|
DEBUG_PRINTSTRING("*** Telling Mary Ann to play waypoint recording")
|
|
TASK_FOLLOW_WAYPOINT_RECORDING(opponent, "fan3_pedJog")
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE MS_FAILED
|
|
BREAK
|
|
DEFAULT
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Continually check for Mary Ann hitting her current checkpoint along the route, updating as she goes, before returning true when she's reached the final
|
|
/// one for that leg of the race
|
|
/// PARAMS:
|
|
/// vCheckpoints - The checkpoint array we're checking
|
|
/// RETURNS:
|
|
/// True when Mary Ann has reached the final checkpoint on the current leg of the race
|
|
/// False otherwise
|
|
FUNC BOOL ma_pDoCheckpoints(VECTOR &vCheckpoints[])
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
IF current_opponent_position < current_opponent_max_positions
|
|
VECTOR vOpponentPos = GET_ENTITY_COORDS(opponent)
|
|
FLOAT fDist = GET_DISTANCE_BETWEEN_COORDS(vOpponentPos, vCheckpoints[current_opponent_position])
|
|
IF fDist < 6
|
|
current_opponent_position++
|
|
DEBUG_PRINTSTRINGINT("*** UPDATED Mary Ann position = ", current_opponent_position)
|
|
IF current_opponent_position >= current_opponent_max_positions
|
|
DEBUG_PRINTSTRING("*** Mary Ann position >= max positions")
|
|
RETURN TRUE
|
|
ENDIF
|
|
if opponentStage = MS_SWIM // Only care about clearing tasks and refreshing task during swimming
|
|
If current_opponent_position <> current_opponent_max_positions
|
|
CLEAR_PED_TASKS(opponent)
|
|
DEBUG_PRINTSTRING("*** Clearing Mary Ann tasks (ma_pDoCheckpoints())")
|
|
ma_pPerformAction()
|
|
ELSE
|
|
DEBUG_PRINTSTRING("*** Mary Ann position = max position and she is stuck... this wasn't caught by the previous check?!")
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ELIF current_opponent_position >= current_opponent_max_positions
|
|
DEBUG_PRINTSTRING("*** Mary Ann's checkpoints have been manipulated by some sort of fix before being checked")
|
|
DEBUG_PRINTSTRING("... and she should finish the race without hitting the final checkpoint")
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Continually check for Mary Ann finishing the swim section of the race, then switch her to get on a bike
|
|
PROC ma_pDoSwimTask()
|
|
IF ma_pDoCheckpoints(SWIM_POSITIONS)
|
|
DEBUG_PRINTSTRING("*** Mary Ann swim complete")
|
|
ma_pSwitchState(MS_TO_BIKE)
|
|
ENDIF
|
|
IF current_opponent_position >= 6
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
SET_PED_MIN_MOVE_BLEND_RATIO(opponent, PEDMOVEBLENDRATIO_RUN)
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Continually check Mary Ann is in a bike, and switch her to doing the bike race section when she's in it
|
|
/// Before that, keep checking whether the seat on the bike she's going for is free (in case the player nicks it), and make her go to the other bike if needed
|
|
PROC ma_pDoToBikeTask()
|
|
IF IS_ENTITY_ALIVE(opponent) AND IS_VEHICLE_OK(opponent_goto_bike)
|
|
IF IS_PED_IN_VEHICLE(opponent, opponent_goto_bike)
|
|
// Add bike to audio scene now Mary Ann is on it
|
|
IF IS_AUDIO_SCENE_ACTIVE("FANATIC_MIX_SCENE")
|
|
IF DOES_ENTITY_EXIST(opponent_goto_bike)
|
|
DEBUG_PRINTSTRING("Adding Mary Ann's bike to mix group!")
|
|
ADD_ENTITY_TO_AUDIO_MIX_GROUP(opponent_goto_bike,"FANATIC_MIX_MARY_BIKE")
|
|
ENDIF
|
|
ENDIF
|
|
//MODIFY_VEHICLE_TOP_SPEED(opponent_goto_bike, 110.0)
|
|
ma_pSwitchState(MS_BIKE)
|
|
ELSE // Check whether player has got on Mary-Ann's bike in the meantime
|
|
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), opponent_goto_bike, TRUE)
|
|
IF opponent_goto_bike = opponent_bike_vehicle
|
|
opponent_goto_bike = bike_vehicle
|
|
CLEAR_PED_TASKS_IMMEDIATELY(opponent)
|
|
DEBUG_PRINTSTRING("*** Clearing Mary Ann tasks (ma_pDoToBikeTask())")
|
|
IF IS_ENTITY_ALIVE(opponent_goto_bike) AND IS_ENTITY_ALIVE(opponent)
|
|
DEBUG_PRINTSTRING("Making Mary Ann use default player's bike")
|
|
TASK_ENTER_VEHICLE(opponent, opponent_goto_bike, DEFAULT_TIME_BEFORE_WARP, VS_DRIVER, PEDMOVE_SPRINT)
|
|
ENDIF
|
|
ELIF opponent_goto_bike = bike_vehicle
|
|
opponent_goto_bike = opponent_bike_vehicle
|
|
CLEAR_PED_TASKS_IMMEDIATELY(opponent)
|
|
DEBUG_PRINTSTRING("*** Clearing Mary Ann tasks (ma_pDoToBikeTask())")
|
|
IF IS_ENTITY_ALIVE(opponent_goto_bike) AND IS_ENTITY_ALIVE(opponent)
|
|
DEBUG_PRINTSTRING("Making Mary Ann use default opponent bike")
|
|
TASK_ENTER_VEHICLE(opponent, opponent_goto_bike, DEFAULT_TIME_BEFORE_WARP, VS_DRIVER, PEDMOVE_SPRINT)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Continually check for Mary Ann finishing the bike section of the race, then switch her to get off the bike
|
|
/// Meanwhile, check to see if she failed the broken bridge jump
|
|
PROC ma_pDoBikeTask()
|
|
IF ma_pLoadBikeRecs()
|
|
IF ma_pDoCheckpoints(BIKE_POSITIONS)
|
|
ma_pSwitchState(MS_OFF_BIKE)
|
|
ELSE
|
|
ma_pCommentOnPlayerJumpFail()
|
|
//ma_pCheckJumpSwitch()
|
|
ma_pPerformAction()
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Continually check for Mary Ann not being on her bike, and switch her to the jogging section when she's off
|
|
PROC ma_pDoOffBikeTask()
|
|
IF IS_ENTITY_ALIVE(opponent) AND IS_VEHICLE_OK(opponent_goto_bike)
|
|
IF NOT IS_PED_IN_VEHICLE(opponent, opponent_goto_bike)
|
|
ma_pSwitchState(MS_RUN)
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Continually check for Mary Ann finishing the jogging section of the race, then switch her to the 'done' state
|
|
PROC ma_pDoJogTask()
|
|
IF ma_pLoadJogRecs()
|
|
IF ma_pDoCheckpoints(RUN_POSITIONS)
|
|
ma_pSwitchState(MS_DONE)
|
|
ELSE
|
|
ma_pPerformAction()
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
|
|
/// PURPOSE:
|
|
/// Called to update Mary Ann every frame, to monitor checkpoints, rubber banding, aggro checks, tasks during the race sections, etc
|
|
PROC ma_pUpdate()
|
|
|
|
ma_pCheckAggro()
|
|
ma_pGivePushWarning()
|
|
MANAGE_SLIDY_BLIP_FOR_ENTITY(opponent_blip, opponent, TRUE)
|
|
|
|
SWITCH opponentStage
|
|
CASE MS_SWIM
|
|
ma_pDoSwimTask()
|
|
ma_pRubberBanding()
|
|
BREAK
|
|
CASE MS_TO_BIKE
|
|
ma_pDoToBikeTask()
|
|
BREAK
|
|
CASE MS_BIKE
|
|
ma_pDoBikeTask()
|
|
ma_pRubberBanding()
|
|
ma_pCheckForTeleport()
|
|
BREAK
|
|
CASE MS_OFF_BIKE
|
|
ma_pDoOffBikeTask()
|
|
BREAK
|
|
CASE MS_RUN
|
|
ma_pDoJogTask()
|
|
ma_pRubberBanding()
|
|
BREAK
|
|
CASE MS_DONE
|
|
IF not race_won // If player hasn't already won the race, then fail the mission
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
KILL_ANY_CONVERSATION()
|
|
ENDIF
|
|
IF CREATE_CONVERSATION(conversation, "FAN3AUD", "FAN3_MAWIN", CONV_PRIORITY_HIGH)
|
|
missionStage = MS_LOST // Set the player into the pre-mission-fail lost state
|
|
subState = SS_INIT
|
|
DELETE_CHECKPOINT(checkpoint)
|
|
SAFE_REMOVE_BLIP(blip)
|
|
SAFE_REMOVE_BLIP(nextblip)
|
|
ma_pSwitchState(MS_LOST)
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE MS_LOST
|
|
BREAK
|
|
CASE MS_FAILED
|
|
BREAK
|
|
DEFAULT
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Deals with Mary Ann for stage skipping (teleporting, switching state, etc)
|
|
/// Called AFTER we set what mission state we want to go to
|
|
PROC ma_pSkip()
|
|
SWITCH missionStage
|
|
CASE MS_INTRO
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
CLEAR_PED_TASKS_IMMEDIATELY(opponent)
|
|
DEBUG_PRINTSTRING("*** Clearing Mary Ann tasks (ma_pSkip())")
|
|
SET_ENTITY_COORDS(opponent, << -910.3204, 6144.2480, 4.2755 >>)
|
|
SET_ENTITY_HEADING(opponent, 312.68)
|
|
SAFE_REMOVE_BLIP(opponent_blip)
|
|
ma_pSwitchState(MS_INTRO)
|
|
ENDIF
|
|
BREAK
|
|
CASE MS_SWIM
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
CLEAR_PED_TASKS_IMMEDIATELY(opponent)
|
|
DEBUG_PRINTSTRING("*** Clearing Mary Ann tasks (ma_pSkip() CASE MS_SWIM)")
|
|
SET_ENTITY_COORDS(opponent, <<-903.2273, 6142.6387, 4.1911>>, TRUE, TRUE)
|
|
SET_ENTITY_HEADING(opponent, 264.8848)
|
|
SAFE_REMOVE_BLIP(opponent_blip)
|
|
ma_pSwitchState(MS_SWIM)
|
|
ENDIF
|
|
BREAK
|
|
CASE MS_TO_BIKE
|
|
FALLTHRU
|
|
CASE MS_BIKE
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
CLEAR_PED_TASKS_IMMEDIATELY(opponent)
|
|
DEBUG_PRINTSTRING("*** Clearing Mary Ann tasks (ma_pSkip() CASE MS_BIKE)")
|
|
SET_ENTITY_COORDS(opponent, << -674.4872, 6134.1387, 1.0720 >>)
|
|
SET_ENTITY_HEADING(opponent, 259.44)
|
|
SAFE_REMOVE_BLIP(opponent_blip)
|
|
ma_pSwitchState(MS_TO_BIKE)
|
|
ENDIF
|
|
BREAK
|
|
CASE MS_OFF_BIKE
|
|
FALLTHRU
|
|
CASE MS_RUN
|
|
opponent_goto_bike = opponent_bike_vehicle // Reassigning this for the skip to ensure Mary Ann progress if we skip the bike section
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
CLEAR_PED_TASKS_IMMEDIATELY(opponent)
|
|
DEBUG_PRINTSTRING("*** Clearing Mary Ann tasks (ma_pSkip() CASE MS_RUN)")
|
|
SET_ENTITY_COORDS(opponent, << 51.1448, 6773.2119, 19.2801 >>)
|
|
SET_ENTITY_HEADING(opponent, 313.1460)
|
|
//FORCE_PED_MOTION_STATE(opponent, MS_ON_FOOT_RUN, FALSE, FAUS_DEFAULT)
|
|
SAFE_REMOVE_BLIP(opponent_blip)
|
|
ma_pSwitchState(MS_RUN)
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Do the race logic for the mission, keeping track of where Mary Ann and the player are and setting the race position accordingly
|
|
/// Also dealing with the race HUD, including the timer
|
|
PROC m_pDoRaceLogic()
|
|
//INT total_stage
|
|
VECTOR player_pos = GET_ENTITY_COORDS(PLAYER_PED_ID())
|
|
if DOES_ENTITY_EXIST(opponent)
|
|
if not IS_ENTITY_DEAD(opponent)
|
|
opponent_pos = GET_ENTITY_COORDS(opponent)
|
|
ENDIF
|
|
ENDIF
|
|
FLOAT player_distance
|
|
FLOAT opponent_distance
|
|
|
|
IF ENUM_TO_INT(missionStage) <> ENUM_TO_INT(MS_FAILED) // Don't run this stuff if we've just failed the mission
|
|
OR NOT IS_SCREEN_FADED_OUT()
|
|
IF ENUM_TO_INT(missionStage) < ENUM_TO_INT(MS_TO_BIKE)
|
|
//total_stage = current_position
|
|
IF current_position < 7
|
|
player_distance = GET_DISTANCE_BETWEEN_COORDS(player_pos, SWIM_POSITIONS[current_position])
|
|
ELIF current_position = 7
|
|
player_distance = GET_DISTANCE_BETWEEN_COORDS(player_pos, SWIM_POSITIONS[6])
|
|
ENDIF
|
|
ELIF ENUM_TO_INT(missionStage) < ENUM_TO_INT(MS_OFF_BIKE)
|
|
//total_stage = MAX_SWIM_POSITIONS + current_position
|
|
IF current_position < 11
|
|
player_distance = GET_DISTANCE_BETWEEN_COORDS(player_pos, BIKE_POSITIONS[current_position])
|
|
ELIF current_position = 11
|
|
player_distance = GET_DISTANCE_BETWEEN_COORDS(player_pos, BIKE_POSITIONS[10])
|
|
ENDIF
|
|
ELIF (ENUM_TO_INT(missionStage) = ENUM_TO_INT(MS_OFF_BIKE))
|
|
OR (ENUM_TO_INT(missionStage) = ENUM_TO_INT(MS_RUN))
|
|
//total_stage = MAX_SWIM_POSITIONS + MAX_BIKE_POSITIONS + current_position
|
|
IF current_position < MAX_RUN_POSITIONS
|
|
player_distance = GET_DISTANCE_BETWEEN_COORDS(player_pos, RUN_POSITIONS[current_position])
|
|
ELIF current_position = MAX_RUN_POSITIONS
|
|
player_distance = GET_DISTANCE_BETWEEN_COORDS(player_pos, RUN_POSITIONS[current_position-1])
|
|
ENDIF
|
|
ELSE // Not in any of the race stages - failed? Let's spit out a debug print...
|
|
DEBUG_PRINTSTRING("Trying to update the race logic when not in a race stage? Mission failed just now?")
|
|
ENDIF
|
|
|
|
IF ENUM_TO_INT(opponentStage) < ENUM_TO_INT(MS_TO_BIKE)
|
|
opponent_distance = GET_DISTANCE_BETWEEN_COORDS(opponent_pos, SWIM_POSITIONS[current_opponent_position])
|
|
ELIF ENUM_TO_INT(opponentStage) < ENUM_TO_INT(MS_OFF_BIKE)
|
|
IF current_opponent_position < 11
|
|
opponent_distance = GET_DISTANCE_BETWEEN_COORDS(opponent_pos, BIKE_POSITIONS[current_opponent_position])
|
|
ELIF current_opponent_position = 11
|
|
opponent_distance = GET_DISTANCE_BETWEEN_COORDS(opponent_pos, BIKE_POSITIONS[10])
|
|
ENDIF
|
|
ELIF opponentStage <> MS_DONE
|
|
opponent_distance = GET_DISTANCE_BETWEEN_COORDS(opponent_pos, RUN_POSITIONS[current_opponent_position])
|
|
ENDIF
|
|
|
|
IF NOT race_won
|
|
IF ENUM_TO_INT(missionStage) < ENUM_TO_INT(opponentStage)
|
|
// If the player has gone from BIKE -> TO_BIKE because of getting off the bike for some reason, ignore changing the race pos,
|
|
// use the current_position checks before instead
|
|
// Otherwise the mission fails when Mary Ann is far behind you because you're suddenly 'last' - should fix #1085937
|
|
// Shouldn't really be an issue when Mary Ann works correctly
|
|
race_pos = 2
|
|
ELIF ENUM_TO_INT(missionStage) > ENUM_TO_INT(opponentStage)
|
|
race_pos = 1
|
|
ELSE
|
|
IF current_position < current_opponent_position
|
|
race_pos = 2
|
|
ELIF current_position > current_opponent_position
|
|
race_pos = 1
|
|
ELSE
|
|
IF player_distance < opponent_distance
|
|
race_pos = 1
|
|
ELSE
|
|
race_pos = 2
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Race timer is calculated by taking the start time away from the current game timer (as normal), then adding on any extra from prior replays
|
|
race_timer = (GET_GAME_TIMER() - start_time) + replay_timer_addition
|
|
|
|
// Add +1 for the current/total checkpoints so we start on CP 1 and there are 30 total
|
|
//DRAW_BIG_DOUBLE_SCORE_HUD(total_stage+1, MAX_SWIM_POSITIONS+MAX_BIKE_POSITIONS+MAX_RUN_POSITIONS+1, "FATIC3_CP", HUD_COLOUR_YELLOW)
|
|
SET_FAR_RIGHT_TITLE_POSITION_HUD_THIS_FRAME()
|
|
DRAW_RACE_HUD(race_timer, "", -1, -1, "", race_pos, 2, "")
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
|
|
PROC ma_pDoIntroBoost()
|
|
|
|
IF bDoMAIntroBoost
|
|
AND IS_ENTITY_ALIVE(opponent)
|
|
IF (GET_GAME_TIMER() - iMAIntroBoostTimer) <= INTRO_BOOST_TIME
|
|
//DEBUG_PRINTSTRING("Doing Mary Ann intro boost")
|
|
SET_PED_MIN_MOVE_BLEND_RATIO(opponent, 3.0)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Get an offset number for the current stage - used in calculating which smack talk dialogue to perform depending on whether the player won or lost a stage
|
|
/// PARAMS:
|
|
/// stage - The stage we're checking
|
|
/// RETURNS:
|
|
/// An appropriate offset value used for the smack[] array
|
|
FUNC INT GET_OFFSET_FROM_MISSION_STAGE(MISSION_STAGE stage)
|
|
INT return_offset
|
|
IF (stage = MS_SWIM)
|
|
return_offset = 0
|
|
ELIF (stage = MS_TO_BIKE)
|
|
return_offset = -1
|
|
ELIF (stage = MS_BIKE)
|
|
return_offset = 1
|
|
ELIF (stage = MS_OFF_BIKE)
|
|
return_offset = -1
|
|
ELSE
|
|
return_offset = 3
|
|
ENDIF
|
|
return return_offset
|
|
ENDFUNC
|
|
|
|
|
|
/// PURPOSE: Works out which checkpoint type is needed based upon angle between checkpoints
|
|
FUNC CHECKPOINT_TYPE GET_RACE_CHECKPOINT_TYPE(INT iCheckNum, VECTOR& checkpoints[])
|
|
|
|
VECTOR pos, pos2, pos3
|
|
VECTOR vec1, vec2
|
|
|
|
FLOAT fReturnAngle
|
|
FLOAT fChevron1 = 180.0
|
|
FLOAT fChevron2 = 140.0
|
|
FLOAT fChevron3 = 80.0
|
|
|
|
pos = checkpoints[iCheckNum]
|
|
|
|
// If we're checking the last checkpoint of the current array, just return the appropriate flag checkpoint, we don't care about angles
|
|
IF (iCheckNum = current_max_positions-1)
|
|
SWITCH missionStage
|
|
CASE MS_SWIM
|
|
RETURN CHECKPOINT_RACE_GROUND_FLAG
|
|
BREAK
|
|
CASE MS_BIKE
|
|
RETURN CHECKPOINT_RACE_GROUND_FLAG
|
|
BREAK
|
|
CASE MS_RUN
|
|
RETURN CHECKPOINT_RACE_GROUND_FLAG
|
|
BREAK
|
|
ENDSWITCH
|
|
ELSE
|
|
// Otherwise, we need to do the angle shit
|
|
// If this is the first checkpoint, we need to check the PREVIOUS array for the 'before' CP
|
|
// But if this is the swimming array then...
|
|
// Whatever, I'll just use Franklin's starting position since it's behind that one and it makes sense
|
|
IF iCheckNum = 0
|
|
SWITCH missionStage
|
|
CASE MS_SWIM
|
|
pos3 = <<64.1700, 7048.6797, 15.6112>> // Franklin's rough start position after the cutscene
|
|
BREAK
|
|
CASE MS_BIKE
|
|
pos3 = SWIM_POSITIONS[MAX_SWIM_POSITIONS-1] // Final swim CP
|
|
BREAK
|
|
CASE MS_RUN
|
|
pos3 = BIKE_POSITIONS[MAX_BIKE_POSITIONS-1] // Final bike CP
|
|
BREAK
|
|
ENDSWITCH
|
|
// And the next CP is just the... next one
|
|
pos2 = checkpoints[iCheckNum + 1]
|
|
ELSE
|
|
// The checkpoint is neither first nor last, wooo, straightforward
|
|
pos3 = checkpoints[iCheckNum - 1]
|
|
pos2 = checkpoints[iCheckNum + 1]
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Create some vectors via maths magic
|
|
vec1 = pos3 - pos
|
|
vec2 = pos2 - pos
|
|
|
|
// Get the final angle value via code magic
|
|
fReturnAngle = GET_ANGLE_BETWEEN_2D_VECTORS(vec1.x, vec1.y, vec2.x, vec2.y)
|
|
|
|
// Make sure reflex angles don't break things via more maths magic
|
|
IF fReturnAngle > 180
|
|
fReturnAngle = (360.0 - fReturnAngle)
|
|
ENDIF
|
|
|
|
// We have our angles through MAGIC!!!!, now to return the correct checkpoint type
|
|
SWITCH missionStage
|
|
CASE MS_SWIM
|
|
IF fReturnAngle < fChevron3
|
|
RETURN CHECKPOINT_RACE_GROUND_CHEVRON_3
|
|
ELIF fReturnAngle < fChevron2
|
|
RETURN CHECKPOINT_RACE_GROUND_CHEVRON_2
|
|
ELIF fReturnAngle < fChevron1
|
|
RETURN CHECKPOINT_RACE_GROUND_CHEVRON_1
|
|
ELSE
|
|
RETURN CHECKPOINT_RACE_GROUND_CHEVRON_1
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE MS_TO_BIKE
|
|
FALLTHRU
|
|
|
|
CASE MS_BIKE
|
|
IF fReturnAngle < fChevron3
|
|
RETURN CHECKPOINT_RACE_GROUND_CHEVRON_3
|
|
ELIF fReturnAngle < fChevron2
|
|
RETURN CHECKPOINT_RACE_GROUND_CHEVRON_2
|
|
ELIF fReturnAngle < fChevron1
|
|
RETURN CHECKPOINT_RACE_GROUND_CHEVRON_1
|
|
ELSE
|
|
RETURN CHECKPOINT_RACE_GROUND_CHEVRON_1
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE MS_RUN
|
|
IF fReturnAngle < fChevron3
|
|
RETURN CHECKPOINT_RACE_GROUND_CHEVRON_3
|
|
ELIF fReturnAngle < fChevron2
|
|
RETURN CHECKPOINT_RACE_GROUND_CHEVRON_2
|
|
ELIF fReturnAngle < fChevron1
|
|
RETURN CHECKPOINT_RACE_GROUND_CHEVRON_1
|
|
ELSE
|
|
RETURN CHECKPOINT_RACE_GROUND_CHEVRON_1
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
// If we've got here, return this as a default, even though we REALLY REALLY SHOULDN'T and this would concern me greatly
|
|
RETURN CHECKPOINT_RACE_GROUND_CHEVRON_1
|
|
ENDFUNC
|
|
|
|
/// PURPOSE: Gets appropriate checkpoint colour based on chevron type
|
|
FUNC HUD_COLOURS GET_RACE_CHECKPOINT_COLOUR(CHECKPOINT_TYPE cpType)
|
|
|
|
// IF cpType = CHECKPOINT_RACE_GROUND_CHEVRON_3
|
|
// RETURN HUD_COLOUR_YELLOWDARK
|
|
// ELIF cpType = CHECKPOINT_RACE_GROUND_CHEVRON_2
|
|
// RETURN HUD_COLOUR_YELLOW
|
|
// ELIF cpType = CHECKPOINT_RACE_GROUND_FLAG
|
|
// RETURN HUD_COLOUR_YELLOW
|
|
// ELSE
|
|
// RETURN HUD_COLOUR_YELLOWLIGHT
|
|
// ENDIF
|
|
|
|
// Returning YELLOWDARK for all checkpoints (B*1454575)
|
|
cpType = cpType // Compile fix - no point changing the function because this will change back
|
|
RETURN HUD_COLOUR_YELLOWLIGHT
|
|
|
|
ENDFUNC
|
|
|
|
|
|
/// PURPOSE:
|
|
/// Remove both race checkpoint blips from the map
|
|
PROC REMOVE_BLIP_IF_EXISTS()
|
|
SAFE_REMOVE_BLIP(blip)
|
|
SAFE_REMOVE_BLIP(nextblip)
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Delete the existing checkpoint halo
|
|
PROC REMOVE_CHECKPOINT_IF_EXISTS()
|
|
DELETE_CHECKPOINT(checkpoint)
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Main mission cleanup function
|
|
PROC MISSION_CLEANUP()
|
|
|
|
// Ensure launcher is terminated
|
|
RC_CLEANUP_LAUNCHER()
|
|
|
|
IF (Random_Character_Cleanup_If_Triggered())
|
|
PRINTSTRING("...Random Character Script was triggered so additional cleanup required") PRINTNL()
|
|
ENDIF
|
|
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
KILL_ANY_CONVERSATION()
|
|
ENDIF
|
|
|
|
SAFE_REMOVE_BLIP(opponent_blip)
|
|
|
|
REMOVE_BLIP_IF_EXISTS()
|
|
REMOVE_CHECKPOINT_IF_EXISTS()
|
|
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
IF IS_VEHICLE_OK(EndingBikeMA)
|
|
IF NOT IS_PED_IN_VEHICLE(opponent, EndingBikeMA)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_ENTER_VEHICLE(null, EndingBikeMA, DEFAULT_TIME_BEFORE_WARP, VS_DRIVER, PEDMOVE_WALK)
|
|
TASK_GO_TO_COORD_ANY_MEANS(null, <<253.0988, 6751.9966, 14.2161>>, 1.0, NULL)
|
|
TASK_VEHICLE_DRIVE_WANDER(null, EndingBikeMA, 15, DRIVINGMODE_AVOIDCARS_STOPFORPEDS_OBEYLIGHTS)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(opponent, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
ENDIF
|
|
ELSE
|
|
// Wander on foot if the bike's fucked
|
|
TASK_WANDER_STANDARD(opponent, GET_ENTITY_HEADING(opponent))
|
|
ENDIF
|
|
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(opponent, TRUE)
|
|
SAFE_RELEASE_VEHICLE(EndingBikeMA)
|
|
ENDIF
|
|
|
|
IF IS_AUDIO_SCENE_ACTIVE("FANATIC_MIX_SCENE")
|
|
IF DOES_ENTITY_EXIST(opponent_goto_bike)
|
|
REMOVE_ENTITY_FROM_AUDIO_MIX_GROUP(opponent_goto_bike)
|
|
ENDIF
|
|
IF DOES_ENTITY_EXIST(opponent)
|
|
REMOVE_ENTITY_FROM_AUDIO_MIX_GROUP(opponent)
|
|
ENDIF
|
|
STOP_AUDIO_SCENE("FANATIC_MIX_SCENE")
|
|
ENDIF
|
|
|
|
SAFE_RELEASE_PED(bad_driver_ped)
|
|
|
|
SAFE_RELEASE_PED(fence_worker)
|
|
|
|
SAFE_RELEASE_VEHICLE(bad_driver_car)
|
|
|
|
IF IS_ENTITY_ALIVE(binoculars_guy)
|
|
SET_PED_FLEE_ATTRIBUTES(binoculars_guy, FA_USE_VEHICLE, TRUE)
|
|
SET_PED_KEEP_TASK(binoculars_guy, true)
|
|
IF IS_ENTITY_ALIVE(picniccar2) AND IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_ENTER_VEHICLE(NULL, picniccar2, DEFAULT_TIME_BEFORE_WARP, VS_DRIVER, PEDMOVEBLENDRATIO_SPRINT, ECF_JACK_ANYONE)
|
|
TASK_SMART_FLEE_PED(NULL, PLAYER_PED_ID(), 100, -1)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(binoculars_guy, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
ENDIF
|
|
SAFE_RELEASE_PED(binoculars_guy)
|
|
ENDIF
|
|
|
|
SAFE_RELEASE_PED(stretching_woman)
|
|
|
|
SAFE_RELEASE_PED(chinups_guy)
|
|
|
|
SAFE_RELEASE_VEHICLE(picniccar2)
|
|
|
|
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
|
|
|
|
SAFE_RELEASE_PED(opponent, TRUE, TRUE)
|
|
|
|
TRIGGER_MUSIC_EVENT("FANATIC2_STOP")
|
|
|
|
SET_ALL_VEHICLE_GENERATORS_ACTIVE_IN_AREA(<<129.221359,6658.974609,30.177034>>, <<140.878265,6646.863281,36.364159>>, TRUE)
|
|
SET_ALL_VEHICLE_GENERATORS_ACTIVE_IN_AREA(<<-191.098450,6550.963867,10.097297>>, <<-199.409927,6542.312012,11.097295>>, TRUE)
|
|
SET_ALL_VEHICLE_GENERATORS_ACTIVE_IN_AREA(<<-226.3857, 6498.8770, 9.2147>>, <<-173.1313, 6595.7710, 20.7218>>, TRUE)
|
|
SET_ROADS_BACK_TO_ORIGINAL_IN_ANGLED_AREA(vRoadDisableAA1, vRoadDisableAA2, fRoadDisableAA)
|
|
|
|
SET_WANTED_LEVEL_MULTIPLIER(1.0)
|
|
|
|
IF GET_IS_WAYPOINT_RECORDING_LOADED("fanatic3_assist")
|
|
USE_WAYPOINT_RECORDING_AS_ASSISTED_MOVEMENT_ROUTE("fanatic3_assist", FALSE)
|
|
REMOVE_WAYPOINT_RECORDING("fanatic3_assist")
|
|
ENDIF
|
|
|
|
IF GET_IS_WAYPOINT_RECORDING_LOADED("fan3_pedJog")
|
|
REMOVE_WAYPOINT_RECORDING("fan3_pedJog")
|
|
ENDIF
|
|
|
|
IF GET_IS_WAYPOINT_RECORDING_LOADED("Fan3_jetskiRoute")
|
|
REMOVE_WAYPOINT_RECORDING("Fan3_jetskiRoute")
|
|
ENDIF
|
|
|
|
DISABLE_CHEAT(CHEAT_TYPE_FAST_RUN, FALSE)
|
|
DISABLE_CHEAT(CHEAT_TYPE_FAST_SWIM, FALSE)
|
|
|
|
DISABLE_CELLPHONE(FALSE)
|
|
|
|
TERMINATE_THIS_THREAD()
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Main mission passed function
|
|
PROC MISSION_PASSED()
|
|
//race_won = TRUE
|
|
IF bCheated = FALSE
|
|
INFORM_STAT_SYSTEM_OF_BOOL_STAT_HAPPENED(FA3_SHORTCUT_USED)
|
|
ENDIF
|
|
SET_MULTIHEAD_SAFE(FALSE) //Deactivate blinders
|
|
REMOVE_BLIP_IF_EXISTS()
|
|
REMOVE_CHECKPOINT_IF_EXISTS()
|
|
|
|
Random_Character_Passed(CP_RAND_C_FAN3)
|
|
ADD_CONTACT_TO_PHONEBOOK(CHAR_MARY_ANN, FRANKLIN_BOOK)
|
|
MISSION_CLEANUP()
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Delete every entity and blip in the mission
|
|
PROC DeleteEverything()
|
|
SAFE_REMOVE_BLIP(opponent_blip)
|
|
|
|
SAFE_REMOVE_BLIP(blip)
|
|
|
|
SAFE_REMOVE_BLIP(additional_blip)
|
|
|
|
SAFE_REMOVE_BLIP(nextblip)
|
|
|
|
DELETE_CHECKPOINT(checkpoint)
|
|
|
|
SAFE_DELETE_VEHICLE(opponent_car)
|
|
|
|
SAFE_DELETE_PED(bad_driver_ped)
|
|
|
|
SAFE_DELETE_PED(fence_worker)
|
|
|
|
SAFE_DELETE_VEHICLE(bad_driver_car)
|
|
|
|
SAFE_DELETE_VEHICLE(picniccar2)
|
|
|
|
SAFE_DELETE_PED(binoculars_guy)
|
|
|
|
SAFE_DELETE_PED(opponent)
|
|
|
|
SAFE_DELETE_VEHICLE(bike_vehicle)
|
|
|
|
SAFE_DELETE_VEHICLE(opponent_bike_vehicle)
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Handles whether the player needs to see the global stamina help message low on stamina. B*1416022.
|
|
PROC HANDLE_GLOBAL_STAMINA_HELP()
|
|
IF NOT g_savedGlobals.sRandomChars.g_bFanaticStamina
|
|
IF GET_PLAYER_SPRINT_TIME_REMAINING(PLAYER_ID()) <= 5.0
|
|
IF NOT IS_HELP_MESSAGE_BEING_DISPLAYED()
|
|
PRINT_HELP("AM_H_NOSTAM")
|
|
g_savedGlobals.sRandomChars.g_bFanaticStamina = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
CAMERA_INDEX chase_cam
|
|
|
|
/// PURPOSE:
|
|
/// Get the script ready to start the scriped cutscene
|
|
PROC CUTSCENE_START()
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
CLEAR_PED_TASKS(PLAYER_PED_ID())
|
|
FORCE_PED_MOTION_STATE(PLAYER_PED_ID(), MS_ON_FOOT_IDLE, TRUE, FAUS_DEFAULT)
|
|
ENDIF
|
|
RESOLVE_VEHICLES_INSIDE_ANGLED_AREA_WITH_SIZE_LIMIT(<<62.860977,7052.178711,21.198898>>, <<67.866425,7037.953125,12.469742>>, 13.0, <<84.29, 7038.63, 12.66>>, 267.13,
|
|
GET_DEFAULT_ALLOWABLE_VEHICLE_SIZE_VECTOR())
|
|
RC_START_CUTSCENE_MODE(<< 200.53, 6626.14, 30.56 >>, DEFAULT, DEFAULT, FALSE, DEFAULT, DEFAULT, FALSE)
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Get the script ready to end the scripted cutscene
|
|
PROC CUTSCENE_END(BOOL skipped = FALSE)
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
KILL_ANY_CONVERSATION()
|
|
ENDIF
|
|
|
|
IF bOutroMALeave = FALSE
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
AND IS_VEHICLE_OK(EndingBikeMA)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_ENTER_VEHICLE(NULL, EndingBikeMA)
|
|
TASK_VEHICLE_MISSION_COORS_TARGET(NULL, EndingBikeMA, <<104.65, 7003.12, 6.43>>, MISSION_GOTO, 10.0, DRIVINGMODE_PLOUGHTHROUGH, 1.0, -1)
|
|
TASK_VEHICLE_DRIVE_WANDER(NULL, EndingBikeMA, 15.0, DRIVINGMODE_AVOIDCARS_STOPFORPEDS_OBEYLIGHTS)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(opponent, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
TASK_CLEAR_LOOK_AT(opponent)
|
|
FORCE_PED_MOTION_STATE(opponent, MS_ON_FOOT_RUN, FALSE, FAUS_DEFAULT)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
SET_PED_CAN_BE_KNOCKED_OFF_VEHICLE(opponent, KNOCKOFFVEHICLE_DEFAULT)
|
|
ENDIF
|
|
|
|
IF skipped = FALSE
|
|
STOP_RENDERING_SCRIPT_CAMS_USING_CATCH_UP()
|
|
ELSE
|
|
RENDER_SCRIPT_CAMS(FALSE, FALSE, 0)
|
|
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0)
|
|
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
|
|
ENDIF
|
|
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
|
|
FREEZE_ENTITY_POSITION(PLAYER_PED_ID(), FALSE)
|
|
//CLEAR_PED_TASKS(PLAYER_PED_ID())
|
|
TASK_CLEAR_LOOK_AT(PLAYER_PED_ID())
|
|
|
|
REMOVE_ANIM_DICT("rcmfanatic1out_of_breath")
|
|
SAFE_RELEASE_PED(opponent)
|
|
SAFE_RELEASE_VEHICLE(EndingBikeMA)
|
|
RC_END_CUTSCENE_MODE()
|
|
SAFE_FADE_SCREEN_IN_FROM_BLACK()
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Do the scripted cutscene outro, controlling cameras, conversations, and animations
|
|
PROC DO_OUTRO()
|
|
|
|
// Realtime controllable end sequence
|
|
// RC_DISABLE_CONTROL_ACTIONS_FOR_LEAD_IN() // Disable these actions while we're playing the outro
|
|
// DISABLE_CELLPHONE_THIS_FRAME_ONLY() // Disable the phone too
|
|
//
|
|
// SWITCH iOutroStage
|
|
// CASE 0
|
|
// REQUEST_ANIM_DICT("rcmfanatic3leadinoutef_3_mcs_1")
|
|
// IF HAS_ANIM_DICT_LOADED("rcmfanatic3leadinoutef_3_mcs_1")
|
|
// iOutroStage++
|
|
// ENDIF
|
|
//
|
|
// BREAK
|
|
// CASE 1
|
|
// int i
|
|
// IF IS_ENTITY_ALIVE(opponent)
|
|
// WAYPOINT_RECORDING_GET_CLOSEST_WAYPOINT("Fan3_PedJog", GET_ENTITY_COORDS(opponent), i)
|
|
// ENDIF
|
|
// IF i >= 199
|
|
// OPEN_SEQUENCE_TASK(seq)
|
|
// TASK_PLAY_ANIM(NULL, "rcmfanatic3leadinoutef_3_mcs_1", "leadout_ef_3_mcs_maryann", SLOW_BLEND_IN, SLOW_BLEND_OUT, -1, AF_DEFAULT, 0.142)
|
|
// CLOSE_SEQUENCE_TASK(seq)
|
|
// TASK_PERFORM_SEQUENCE(opponent, seq)
|
|
// CLEAR_SEQUENCE_TASK(seq)
|
|
// bMaryAnnInFinalArea = TRUE
|
|
// iOutroStage++
|
|
// ELIF i>= 194
|
|
// OPEN_SEQUENCE_TASK(seq)
|
|
// TASK_PLAY_ANIM(NULL, "rcmfanatic3leadinoutef_3_mcs_1", "leadout_ef_3_mcs_maryann", FAST_BLEND_IN, SLOW_BLEND_OUT, -1, AF_DEFAULT)
|
|
// CLOSE_SEQUENCE_TASK(seq)
|
|
// TASK_PERFORM_SEQUENCE(opponent, seq)
|
|
// CLEAR_SEQUENCE_TASK(seq)
|
|
// iOutroStage++
|
|
// ENDIF
|
|
// BREAK
|
|
// CASE 2
|
|
// IF bMaryAnnInFinalArea = FALSE
|
|
// WAIT(1000)
|
|
// ENDIF
|
|
// iOutroStage++
|
|
// BREAK
|
|
// CASE 3
|
|
// ADD_PED_FOR_DIALOGUE(conversation, ENUM_TO_INT(CHAR_FRANKLIN) , PLAYER_PED_ID(), "FRANKLIN")
|
|
// ADD_PED_FOR_DIALOGUE(conversation, 3 , opponent , "MARYANN")
|
|
// IF CREATE_CONVERSATION(conversation, "FAN3AUD", "FAN3_2", CONV_PRIORITY_MEDIUM)
|
|
// TASK_LOOK_AT_ENTITY(PLAYER_PED_ID(), opponent, -1)
|
|
// TASK_LOOK_AT_ENTITY(opponent, PLAYER_PED_ID(), -1, SLF_EXTEND_PITCH_LIMIT|SLF_EXTEND_YAW_LIMIT)
|
|
// iOutroStage++
|
|
// ENDIF
|
|
// BREAK
|
|
// CASE 4
|
|
// IF IS_ENTITY_ALIVE(opponent)
|
|
// IF NOT IS_ENTITY_PLAYING_ANIM(opponent, "rcmfanatic3leadinoutef_3_mcs_1", "leadout_ef_3_mcs_maryann")
|
|
// IF bOutroMALeave = FALSE
|
|
// IF IS_VEHICLE_OK(EndingBikeMA)
|
|
// OPEN_SEQUENCE_TASK(seq)
|
|
// TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, GET_ENTITY_COORDS(EndingBikeMA), PEDMOVEBLENDRATIO_RUN, DEFAULT, 1.0, ENAV_NO_STOPPING|ENAV_DONT_AVOID_PEDS)
|
|
// TASK_ENTER_VEHICLE(null, EndingBikeMA)
|
|
// CLOSE_SEQUENCE_TASK(seq)
|
|
// TASK_PERFORM_SEQUENCE(opponent, seq)
|
|
// CLEAR_SEQUENCE_TASK(seq)
|
|
// bOutroMALeave = TRUE
|
|
// ENDIF
|
|
// ENDIF
|
|
// ELSE
|
|
// IF GET_ENTITY_ANIM_CURRENT_TIME(opponent, "rcmfanatic3leadinoutef_3_mcs_1", "leadout_ef_3_mcs_maryann") >= 0.98
|
|
// IF bOutroMALeave = FALSE
|
|
// IF IS_VEHICLE_OK(EndingBikeMA)
|
|
// OPEN_SEQUENCE_TASK(seq)
|
|
// TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, GET_ENTITY_COORDS(EndingBikeMA), PEDMOVEBLENDRATIO_RUN, DEFAULT, 1.0, ENAV_NO_STOPPING|ENAV_DONT_AVOID_PEDS)
|
|
// TASK_ENTER_VEHICLE(null, EndingBikeMA)
|
|
// CLOSE_SEQUENCE_TASK(seq)
|
|
// TASK_PERFORM_SEQUENCE(opponent, seq)
|
|
// CLEAR_SEQUENCE_TASK(seq)
|
|
// bOutroMALeave = TRUE
|
|
// ENDIF
|
|
// ENDIF
|
|
// ENDIF
|
|
// ENDIF
|
|
// ENDIF
|
|
// IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
// CUTSCENE_END()
|
|
// MISSION_PASSED()
|
|
// ENDIF
|
|
// BREAK
|
|
// ENDSWITCH
|
|
|
|
// Scripted cutscene sequence
|
|
SWITCH iOutroStage
|
|
CASE 0
|
|
DEBUG_PRINTSTRING("WAITING FOR OUTRO ASSETS")
|
|
REQUEST_ANIM_DICT("rcmfanatic3leadinoutef_3_mcs_1")
|
|
bOutroMALeave = FALSE
|
|
bMaryAnnInFinalArea = FALSE
|
|
IF HAS_ANIM_DICT_LOADED("rcmfanatic3leadinoutef_3_mcs_1")
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
|
|
ENDIF
|
|
SAFE_DELETE_VEHICLE(EndingBikeMA)
|
|
IF NOT IS_VEHICLE_OK(EndingBikeMA)
|
|
SAFE_DELETE_VEHICLE(EndingBikeMA)
|
|
EndingBikeMA = CREATE_VEHICLE(scorcher, vEndingBikeMASpawn, fEndingBikeMASpawn)
|
|
SET_VEHICLE_ON_GROUND_PROPERLY(EndingBikeMA)
|
|
ELSE
|
|
SET_ENTITY_COORDS(EndingBikeMA, vEndingBikeMASpawn)
|
|
SET_ENTITY_HEADING(EndingBikeMA, fEndingBikeMASpawn)
|
|
SET_VEHICLE_ON_GROUND_PROPERLY(EndingBikeMA)
|
|
ENDIF
|
|
// IF IS_ENTITY_ALIVE(opponent)
|
|
// IF IS_ENTITY_IN_ANGLED_AREA(opponent, <<61.838440,7052.195801,19.092598>>, <<66.701202,7032.781738,11.118760>>, 14.00)
|
|
// bMaryAnnInFinalArea = TRUE
|
|
// DEBUG_PRINTSTRING("Mary Ann's in area")
|
|
// ELSE
|
|
// DEBUG_PRINTSTRING("Mary Ann's not in area")
|
|
// ENDIF
|
|
// ELSE
|
|
// DEBUG_PRINTSTRING("Mary Ann's not alive?!")
|
|
// ENDIF
|
|
iOutroStage++
|
|
DEBUG_PRINTSTRING("DOING OUTRO")
|
|
ENDIF
|
|
BREAK
|
|
CASE 1
|
|
chase_cam = CREATE_CAM_WITH_PARAMS("DEFAULT_ANIMATED_CAMERA", <<71.2335, 7032.0923, 25.1157>>, <<-2.4036, -0.0000, 17.3552>>, 25, FALSE)
|
|
// SET_CAM_COORD(chase_cam, <<71.2335, 7032.0923, 25.1157>>)
|
|
// SET_CAM_ROT(chase_cam, <<-2.4036, -0.0000, 17.3552>>)
|
|
// SET_CAM_FOV(chase_cam, 25.000000)
|
|
// SET_CAM_ACTIVE(chase_cam, TRUE)
|
|
iOutroStage++
|
|
CLEAR_AREA_OF_PEDS(GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE), 25.0) // for B*1978412
|
|
DEBUG_PRINTSTRING("Going to case 2")
|
|
BREAK
|
|
CASE 2
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
CLEAR_PED_TASKS(opponent)
|
|
DEBUG_PRINTSTRING("*** Clearing Mary Ann tasks (Cutscene)")
|
|
IF bMaryAnnInFinalArea
|
|
SET_ENTITY_COORDS(opponent, << 64.0768, 7045.1631, 14.9558 >>)
|
|
SET_ENTITY_HEADING(opponent, 70.469)
|
|
ELSE
|
|
SET_ENTITY_COORDS(opponent, << 65.61, 7038.87, 13.69 >>)
|
|
SET_ENTITY_HEADING(opponent, 13.469)
|
|
ENDIF
|
|
IF bMaryAnnInFinalArea
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_PLAY_ANIM(NULL, "rcmfanatic3leadinoutef_3_mcs_1", "leadout_ef_3_mcs_maryann", NORMAL_BLEND_IN, SLOW_BLEND_OUT, -1, AF_DEFAULT, 0.164)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
ELSE
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_PLAY_ANIM(NULL, "rcmfanatic3leadinoutef_3_mcs_1", "leadout_ef_3_mcs_maryann", NORMAL_BLEND_IN, SLOW_BLEND_OUT, -1)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
ENDIF
|
|
TASK_PERFORM_SEQUENCE(opponent, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
CLEAR_PED_TASKS(PLAYER_PED_ID())
|
|
SET_PED_STEALTH_MOVEMENT(PLAYER_PED_ID(), FALSE) // Get player out of stealth if they're in it (#1070718)
|
|
SET_PED_MAX_MOVE_BLEND_RATIO(PLAYER_PED_ID(), 0)
|
|
//FORCE_PED_MOTION_STATE(PLAYER_PED_ID(), MS_ON_FOOT_IDLE, TRUE, FAUS_DEFAULT, TRUE)
|
|
SAFE_TELEPORT_ENTITY(PLAYER_PED_ID(), vOutroSkip, fOutroSkip, TRUE)
|
|
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE)
|
|
//FREEZE_ENTITY_POSITION(PLAYER_PED_ID(), TRUE)
|
|
ENDIF
|
|
PLAY_CAM_ANIM(chase_cam, "leadout_ef_3_mcs_maryann_cam", "rcmfanatic3leadinoutef_3_mcs_1", GET_ENTITY_COORDS(opponent), GET_ENTITY_ROTATION(opponent))
|
|
SET_CAM_ACTIVE(chase_cam, TRUE)
|
|
ENDIF
|
|
|
|
REPLAY_START_EVENT(REPLAY_IMPORTANCE_LOW)
|
|
|
|
CUTSCENE_START()
|
|
RENDER_SCRIPT_CAMS(TRUE, FALSE)
|
|
SAFE_FADE_SCREEN_IN_FROM_BLACK(500, FALSE)
|
|
//SET_CAM_PARAMS(chase_cam, <<78.8691, 7035.9004, 19.6013>>, <<-10.0271, -0.0066, 51.8204>>, 25.0, 3000)
|
|
ADD_PED_FOR_DIALOGUE(conversation, ENUM_TO_INT(CHAR_FRANKLIN) , PLAYER_PED_ID(), "FRANKLIN")
|
|
ADD_PED_FOR_DIALOGUE(conversation, 3 , opponent , "MARYANN")
|
|
TASK_LOOK_AT_ENTITY(PLAYER_PED_ID(), opponent, -1)
|
|
WAIT(1000)
|
|
IF CREATE_CONVERSATION(conversation, "FAN3AUD", "FAN3_2", CONV_PRIORITY_HIGH)
|
|
iOutroTimer = GET_GAME_TIMER()
|
|
iOutroStage++
|
|
DEBUG_PRINTSTRING("Going to case 3")
|
|
ENDIF
|
|
BREAK
|
|
CASE 3
|
|
IF (GET_GAME_TIMER() - iOutroTimer) < 3000
|
|
IF IS_CUTSCENE_SKIP_BUTTON_JUST_PRESSED_WITH_DELAY()
|
|
SAFE_FADE_SCREEN_OUT_TO_BLACK()
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
CLEAR_PED_TASKS(opponent)
|
|
ENDIF
|
|
RENDER_SCRIPT_CAMS(FALSE, FALSE)
|
|
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0)
|
|
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
|
|
DEBUG_PRINTSTRING("Intro skip case 3")
|
|
WAIT(750)
|
|
CUTSCENE_END(TRUE)
|
|
MISSION_PASSED()
|
|
ENDIF
|
|
ELSE
|
|
//behind winner
|
|
//SET_CAM_COORD(chase_cam,<<61.6170, 7053.4175, 17.8992>>)
|
|
//SET_CAM_ROT(chase_cam, <<-12.1134, -0.0000, -159.1954>>)
|
|
//SET_CAM_FOV(chase_cam, 15.5)
|
|
iOutroTimer = GET_GAME_TIMER()
|
|
iOutroStage++
|
|
DEBUG_PRINTSTRING("Going to case 4")
|
|
ENDIF
|
|
BREAK
|
|
CASE 4
|
|
IF (GET_GAME_TIMER() - iOutroTimer) < 10000
|
|
IF IS_CUTSCENE_SKIP_BUTTON_JUST_PRESSED_WITH_DELAY()
|
|
SAFE_FADE_SCREEN_OUT_TO_BLACK()
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
CLEAR_PED_TASKS(opponent)
|
|
ENDIF
|
|
RENDER_SCRIPT_CAMS(FALSE, FALSE)
|
|
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0)
|
|
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
|
|
DEBUG_PRINTSTRING("Intro skip case 4")
|
|
WAIT(750)
|
|
CUTSCENE_END(TRUE)
|
|
MISSION_PASSED()
|
|
ENDIF
|
|
ELSE
|
|
//SET_CAM_COORD(chase_cam, <<65.5304, 7054.8721, 18.8393>>)
|
|
//SET_CAM_ROT(chase_cam, <<-16.6934, 0.0000, 178.1698>>)
|
|
//SET_CAM_FOV(chase_cam, 35.0)
|
|
iOutroStage++
|
|
DEBUG_PRINTSTRING("Going to case 5")
|
|
ENDIF
|
|
BREAK
|
|
CASE 5
|
|
IF IS_SCRIPTED_CONVERSATION_ONGOING()
|
|
IF IS_CUTSCENE_SKIP_BUTTON_JUST_PRESSED_WITH_DELAY()
|
|
SAFE_FADE_SCREEN_OUT_TO_BLACK()
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
CLEAR_PED_TASKS(opponent)
|
|
ENDIF
|
|
RENDER_SCRIPT_CAMS(FALSE, FALSE)
|
|
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0)
|
|
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
|
|
DEBUG_PRINTSTRING("Intro skip case 5")
|
|
WAIT(750)
|
|
CUTSCENE_END(TRUE)
|
|
MISSION_PASSED()
|
|
ENDIF
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
IF IS_ENTITY_PLAYING_ANIM(opponent, "rcmfanatic3leadinoutef_3_mcs_1", "leadout_ef_3_mcs_maryann")
|
|
IF GET_ENTITY_ANIM_CURRENT_TIME(opponent, "rcmfanatic3leadinoutef_3_mcs_1", "leadout_ef_3_mcs_maryann") >= 0.90
|
|
//SET_CAM_COORD(chase_cam, <<62.4712, 7051.8481, 18.3172>>)
|
|
//SET_CAM_ROT(chase_cam, <<-13.8410, -0.0000, -152.9137>>)
|
|
//SET_CAM_FOV(chase_cam, 40.0)
|
|
//SET_CAM_PARAMS(chase_cam, <<62.5742, 7051.6470, 19.2351>>, <<-13.8410, -0.0000, -152.9137>>, 40.0, 5000, GRAPH_TYPE_LINEAR, GRAPH_TYPE_LINEAR)
|
|
iOutroStage++
|
|
DEBUG_PRINTSTRING("Going to case 6")
|
|
ENDIF
|
|
IF GET_ENTITY_ANIM_CURRENT_TIME(opponent, "rcmfanatic3leadinoutef_3_mcs_1", "leadout_ef_3_mcs_maryann") >= 0.98
|
|
IF bOutroMALeave = FALSE
|
|
IF IS_VEHICLE_OK(EndingBikeMA)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_GO_STRAIGHT_TO_COORD(NULL, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(EndingBikeMA, <<-2.5, 0, 0>>), PEDMOVEBLENDRATIO_RUN, DEFAULT, DEFAULT)
|
|
//TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, GET_ENTITY_COORDS(EndingBikeMA), PEDMOVEBLENDRATIO_RUN, DEFAULT, 1.0, ENAV_NO_STOPPING|ENAV_DONT_AVOID_PEDS)
|
|
TASK_ENTER_VEHICLE(null, EndingBikeMA)
|
|
TASK_VEHICLE_MISSION_COORS_TARGET(NULL, EndingBikeMA, <<104.65, 7003.12, 6.43>>, MISSION_GOTO, 10.0, DRIVINGMODE_PLOUGHTHROUGH, 1.0, -1)
|
|
TASK_VEHICLE_DRIVE_WANDER(NULL, EndingBikeMA, 15.0, DRIVINGMODE_AVOIDCARS_STOPFORPEDS_OBEYLIGHTS)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(opponent, seq)
|
|
FORCE_PED_AI_AND_ANIMATION_UPDATE(opponent, TRUE)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
bOutroMALeave = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
IF bOutroMALeave = FALSE
|
|
IF IS_VEHICLE_OK(EndingBikeMA)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_GO_STRAIGHT_TO_COORD(NULL, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(EndingBikeMA, <<-2.5, 0, 0>>), PEDMOVEBLENDRATIO_RUN, DEFAULT, DEFAULT)
|
|
//TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, GET_ENTITY_COORDS(EndingBikeMA), PEDMOVEBLENDRATIO_RUN, DEFAULT, 1.0, ENAV_NO_STOPPING|ENAV_DONT_AVOID_PEDS)
|
|
TASK_ENTER_VEHICLE(null, EndingBikeMA)
|
|
TASK_VEHICLE_MISSION_COORS_TARGET(NULL, EndingBikeMA, <<104.65, 7003.12, 6.43>>, MISSION_GOTO, 10.0, DRIVINGMODE_PLOUGHTHROUGH, 1.0, -1)
|
|
TASK_VEHICLE_DRIVE_WANDER(NULL, EndingBikeMA, 15.0, DRIVINGMODE_AVOIDCARS_STOPFORPEDS_OBEYLIGHTS)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(opponent, seq)
|
|
FORCE_PED_AI_AND_ANIMATION_UPDATE(opponent, TRUE)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
bOutroMALeave = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
CUTSCENE_END()
|
|
REPLAY_STOP_EVENT()
|
|
MISSION_PASSED()
|
|
ENDIF
|
|
BREAK
|
|
CASE 6
|
|
IF IS_SCRIPTED_CONVERSATION_ONGOING()
|
|
IF IS_CUTSCENE_SKIP_BUTTON_JUST_PRESSED_WITH_DELAY()
|
|
SAFE_FADE_SCREEN_OUT_TO_BLACK()
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
CLEAR_PED_TASKS(opponent)
|
|
ENDIF
|
|
RENDER_SCRIPT_CAMS(FALSE, FALSE)
|
|
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0)
|
|
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
|
|
DEBUG_PRINTSTRING("Intro skip case 6")
|
|
WAIT(750)
|
|
CUTSCENE_END(TRUE)
|
|
MISSION_PASSED()
|
|
ENDIF
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
IF NOT IS_ENTITY_PLAYING_ANIM(opponent, "rcmfanatic3leadinoutef_3_mcs_1", "leadout_ef_3_mcs_maryann")
|
|
IF bOutroMALeave = FALSE
|
|
IF IS_VEHICLE_OK(EndingBikeMA)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_GO_STRAIGHT_TO_COORD(NULL, <<86.60, 7032.51, 11.35>>, PEDMOVEBLENDRATIO_RUN, DEFAULT, DEFAULT, 1.5)
|
|
//TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, GET_ENTITY_COORDS(EndingBikeMA), PEDMOVEBLENDRATIO_RUN, DEFAULT, 1.0, ENAV_NO_STOPPING|ENAV_DONT_AVOID_PEDS)
|
|
TASK_ENTER_VEHICLE(null, EndingBikeMA)
|
|
TASK_VEHICLE_MISSION_COORS_TARGET(NULL, EndingBikeMA, <<104.65, 7003.12, 6.43>>, MISSION_GOTO, 10.0, DRIVINGMODE_PLOUGHTHROUGH, 1.0, -1)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(opponent, seq)
|
|
FORCE_PED_AI_AND_ANIMATION_UPDATE(opponent, TRUE)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
bOutroMALeave = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
IF GET_ENTITY_ANIM_CURRENT_TIME(opponent, "rcmfanatic3leadinoutef_3_mcs_1", "leadout_ef_3_mcs_maryann") >= 0.98
|
|
IF bOutroMALeave = FALSE
|
|
IF IS_VEHICLE_OK(EndingBikeMA)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_GO_STRAIGHT_TO_COORD(NULL, <<86.60, 7032.51, 11.35>>, PEDMOVEBLENDRATIO_RUN, DEFAULT, DEFAULT, 1.5)
|
|
//TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, GET_ENTITY_COORDS(EndingBikeMA), PEDMOVEBLENDRATIO_RUN, DEFAULT, 1.0, ENAV_NO_STOPPING|ENAV_DONT_AVOID_PEDS)
|
|
TASK_ENTER_VEHICLE(null, EndingBikeMA)
|
|
TASK_VEHICLE_MISSION_COORS_TARGET(NULL, EndingBikeMA, <<104.65, 7003.12, 6.43>>, MISSION_GOTO, 10.0, DRIVINGMODE_PLOUGHTHROUGH, 1.0, -1)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(opponent, seq)
|
|
FORCE_PED_AI_AND_ANIMATION_UPDATE(opponent, TRUE)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
bOutroMALeave = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
WAIT(500)
|
|
CUTSCENE_END()
|
|
MISSION_PASSED()
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Main mission failed fade process
|
|
PROC FAILED()
|
|
|
|
SWITCH iFailStage
|
|
CASE 0
|
|
SAFE_REMOVE_BLIP(opponent_blip)
|
|
SAFE_REMOVE_BLIP(blip)
|
|
SAFE_REMOVE_BLIP(additional_blip)
|
|
SAFE_REMOVE_BLIP(nextblip)
|
|
|
|
DELETE_CHECKPOINT(checkpoint)
|
|
|
|
CLEAR_PRINTS()
|
|
|
|
TRIGGER_MUSIC_EVENT("FANATIC3_FAIL")
|
|
|
|
STRING sFailReason
|
|
|
|
SWITCH failReason
|
|
CASE FAILED_GENERIC
|
|
DEBUG_PRINTSTRING("MISSION_FAILED reason=FAILED_GENERIC")
|
|
BREAK
|
|
|
|
CASE FAILED_BIKE_DESTROYED
|
|
sFailReason = "FATIC3_11" // ~r~One of the bikes was wrecked.
|
|
DEBUG_PRINTSTRING("MISSION_FAILED reason=FAILED_BIKE_DESTROYED")
|
|
BREAK
|
|
|
|
CASE FAILED_YOURBIKE_DESTROYED
|
|
sFailReason = "FATIC3_YOURBIKE" // ~r~Your bike was wrecked.
|
|
DEBUG_PRINTSTRING("MISSION_FAILED reason=FAILED_BIKE_DESTROYED")
|
|
BREAK
|
|
|
|
CASE FAILED_OUT_OF_TIME
|
|
sFailReason = "FATIC3_16" // ~r~Mary-Ann left you behind.
|
|
DEBUG_PRINTSTRING("MISSION_FAILED reason=FAILED_OUT_OF_TIME")
|
|
BREAK
|
|
|
|
CASE FAILED_LOST_RACE
|
|
sFailReason = "FATIC3_8" // ~r~The opponent won the race.
|
|
DEBUG_PRINTSTRING("MISSION_FAILED reason=FAILED_LOST_RACE")
|
|
BREAK
|
|
|
|
CASE FAILED_WOMAN_DIED
|
|
sFailReason = "FATIC3_7" // ~r~The opponent was killed.
|
|
DEBUG_PRINTSTRING("MISSION_FAILED reason=FAILED_WOMAN_DIED")
|
|
BREAK
|
|
|
|
CASE FAILED_WOMAN_HURT
|
|
sFailReason = "FATIC3_10" // ~r~Mary Ann was hurt.
|
|
DEBUG_PRINTSTRING("MISSION_FAILED reason=FAILED_WOMAN_HURT")
|
|
BREAK
|
|
|
|
CASE FAILED_WOMAN_SCARED
|
|
sFailReason = "FATIC3_13" // ~r~Mary Ann was scared off.
|
|
DEBUG_PRINTSTRING("MISSION_FAILED reason=FAILED_WOMAN_SCARED")
|
|
BREAK
|
|
|
|
CASE FAILED_LEFT_AREA
|
|
sFailReason = "FATIC3_14" // ~r~You wandered too far from the race.
|
|
DEBUG_PRINTSTRING("MISSION_FAILED reason=FAILED_LEFT_AREA")
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
IF failReason = FAILED_GENERIC
|
|
Random_Character_Failed()
|
|
ELSE
|
|
Random_Character_Failed_With_Reason(sFailReason)
|
|
ENDIF
|
|
|
|
iFailStage = 1
|
|
BREAK
|
|
|
|
CASE 1
|
|
IF GET_MISSION_FLOW_SAFE_TO_CLEANUP()
|
|
|
|
// Do a check here to see if we need to warp the player at all
|
|
// (only set the fail warp locations if we can't leave the player where he was)
|
|
//MISSION_FLOW_SET_FAIL_WARP_LOCATION(<< -922.8657, 6164.7632, 3.7645 >>, 195.2908)
|
|
//SET_REPLAY_DECLINED_VEHICLE_WARP_LOCATION(<<-917.715, 6162.175, 4.250>>, 174.554)
|
|
|
|
DeleteEverything()
|
|
|
|
MISSION_CLEANUP()
|
|
ELSE
|
|
// not finished fading out
|
|
// you may want to handle dialogue etc here.
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Create a line of checkpoints, given an array of coords and number of points we want in this line
|
|
/// Used for the swim section, as manually placing checkpoints would be reasonably difficult
|
|
/// PARAMS:
|
|
/// v1 - The start of the checkpoint line
|
|
/// v2 - The end of the checkpoint line
|
|
/// checkpoints - The checkpoint coord array we want to make a line from
|
|
/// number_of_points - The amount of checkpoints we want in this line
|
|
PROC CREATE_CHECKPOINT_LINE(VECTOR v1, VECTOR v2, VECTOR& checkpoints[], INT number_of_points)
|
|
INT i = 0
|
|
VECTOR diff = v2 - v1
|
|
diff /= TO_FLOAT(number_of_points-1)
|
|
REPEAT number_of_points i
|
|
checkpoints[i] = v1 + (diff * TO_FLOAT(i))
|
|
ENDREPEAT
|
|
ENDPROC
|
|
|
|
PROC SPAWN_CHECKPOINT(VECTOR& checkpoints[])
|
|
|
|
IF (current_position = (current_max_positions - 1))
|
|
currentCPColour = GET_RACE_CHECKPOINT_COLOUR(GET_RACE_CHECKPOINT_TYPE(current_position, checkpoints))
|
|
INT iR, iG, iB, iA
|
|
GET_HUD_COLOUR(currentCPColour, iR, iG, iB, iA)
|
|
SWITCH missionStage
|
|
CASE MS_SWIM
|
|
checkpoint = CREATE_CHECKPOINT(CHECKPOINT_RACE_GROUND_FLAG, checkpoints[current_position], BIKE_POSITIONS[0], 3.2, iR, iG, iB, iA)
|
|
BREAK
|
|
CASE MS_TO_BIKE
|
|
FALLTHRU // If we're here, the player has jumped off the bike before the final checkpoint and we're recreating it after he got back on
|
|
CASE MS_BIKE
|
|
checkpoint = CREATE_CHECKPOINT(CHECKPOINT_RACE_GROUND_FLAG, checkpoints[current_position]+<<0,0,2.0>>, RUN_POSITIONS[0], 3.2, iR, iG, iB, iA)
|
|
BREAK
|
|
CASE MS_RUN
|
|
checkpoint = CREATE_CHECKPOINT(CHECKPOINT_RACE_GROUND_FLAG, checkpoints[current_position]+<<0,0,0.1>>, checkpoints[current_position], 3.2, iR, iG, iB, iA)
|
|
BREAK
|
|
ENDSWITCH
|
|
SET_CHECKPOINT_CYLINDER_HEIGHT(checkpoint,1.6,1.6,100)
|
|
IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID())
|
|
FLOAT fDis = GET_DISTANCE_BETWEEN_COORDS(checkpoints[current_position],GET_ENTITY_COORDS(PLAYER_PED_ID()))
|
|
|
|
IF checkpoint != NULL // Make sure the checkpoint exists first
|
|
IF fDis > 100.0
|
|
GET_HUD_COLOUR(HUD_COLOUR_YELLOWLIGHT, iR, iG, iB, iA)
|
|
iA = 240
|
|
SET_CHECKPOINT_RGBA(checkPoint, iR, iG, iB, iA)
|
|
GET_HUD_COLOUR(HUD_COLOUR_NORTH_BLUE, iR, iG, iB, iA)
|
|
iA = 240
|
|
SET_CHECKPOINT_RGBA2(checkPoint, iR, iG, iB, iA)
|
|
ELSE
|
|
GET_HUD_COLOUR(HUD_COLOUR_YELLOWLIGHT, iR, iG, iB, iA)
|
|
iA = ROUND(fDis*2.4)
|
|
IF iA < 60
|
|
iA = 60
|
|
ENDIF
|
|
SET_CHECKPOINT_RGBA(checkPoint, iR, iG, iB, iA)
|
|
GET_HUD_COLOUR(HUD_COLOUR_NORTH_BLUE, iR, iG, iB, iA)
|
|
iA = ROUND(fDis*2.4)
|
|
IF iA < 60
|
|
iA = 60
|
|
ENDIF
|
|
SET_CHECKPOINT_RGBA2(checkPoint, iR, iG, iB, iA)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
// Otherwise, do a normal checkpoint
|
|
ELSE
|
|
currentCPColour = GET_RACE_CHECKPOINT_COLOUR(GET_RACE_CHECKPOINT_TYPE(current_position, checkpoints))
|
|
INT iR, iG, iB, iA
|
|
GET_HUD_COLOUR(currentCPColour, iR, iG, iB, iA)
|
|
IF missionStage = MS_SWIM
|
|
AND current_position = 0
|
|
// Hacky way to make the colour correct for the very first checkpoint
|
|
currentCPColour = GET_RACE_CHECKPOINT_COLOUR(CHECKPOINT_RACE_GROUND_CHEVRON_1)
|
|
GET_HUD_COLOUR(currentCPColour, iR, iG, iB, iA)
|
|
checkpoint = CREATE_CHECKPOINT(CHECKPOINT_RACE_GROUND_CHEVRON_1, checkpoints[current_position]+<<0,0,2.0>>, checkpoints[current_position+1], 3.2, iR, iG, iB, iA)
|
|
ELSE
|
|
currentCPColour = GET_RACE_CHECKPOINT_COLOUR(CHECKPOINT_RACE_GROUND_CHEVRON_1)
|
|
GET_HUD_COLOUR(currentCPColour, iR, iG, iB, iA)
|
|
checkpoint = CREATE_CHECKPOINT(GET_RACE_CHECKPOINT_TYPE(current_position, checkpoints), checkpoints[current_position]+<<0,0,1.7>>, checkpoints[current_position+1], 3.2, iR, iG, iB, iA)
|
|
ENDIF
|
|
GET_HUD_COLOUR(HUD_COLOUR_YELLOWLIGHT, iR, iG, iB, iA)
|
|
SET_CHECKPOINT_RGBA(checkPoint, iR, iG, iB, iA)
|
|
GET_HUD_COLOUR(HUD_COLOUR_NORTH_BLUE, iR, iG, iB, iA)
|
|
SET_CHECKPOINT_RGBA2(checkPoint, iR, iG, iB, iA)
|
|
SET_CHECKPOINT_CYLINDER_HEIGHT(checkpoint,1.6,1.6,100)
|
|
IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID())
|
|
FLOAT fDis = GET_DISTANCE_BETWEEN_COORDS(checkpoints[current_position],GET_ENTITY_COORDS(PLAYER_PED_ID()))
|
|
|
|
IF checkpoint != NULL // Make sure the checkpoint exists first
|
|
IF fDis > 100.0
|
|
GET_HUD_COLOUR(HUD_COLOUR_YELLOWLIGHT, iR, iG, iB, iA)
|
|
iA = 240
|
|
SET_CHECKPOINT_RGBA(checkPoint, iR, iG, iB, iA)
|
|
GET_HUD_COLOUR(HUD_COLOUR_NORTH_BLUE, iR, iG, iB, iA)
|
|
iA = 240
|
|
SET_CHECKPOINT_RGBA2(checkPoint, iR, iG, iB, iA)
|
|
ELSE
|
|
GET_HUD_COLOUR(HUD_COLOUR_YELLOWLIGHT, iR, iG, iB, iA)
|
|
iA = ROUND(fDis*2.4.4)
|
|
IF iA < 60
|
|
iA = 60
|
|
ENDIF
|
|
SET_CHECKPOINT_RGBA(checkPoint, iR, iG, iB, iA)
|
|
GET_HUD_COLOUR(HUD_COLOUR_NORTH_BLUE, iR, iG, iB, iA)
|
|
iA = ROUND(fDis*2.4)
|
|
IF iA < 60
|
|
iA = 60
|
|
ENDIF
|
|
SET_CHECKPOINT_RGBA2(checkPoint, iR, iG, iB, iA)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Create the very first blip in a given array of checkpoint coords with a special triathlon radar icon
|
|
/// PARAMS:
|
|
/// checkpoints - The checkpoint coord array
|
|
PROC CREATE_FIRST_BLIP(VECTOR& checkpoints[])
|
|
|
|
DEBUG_PRINTSTRING("*** Creating first blip")
|
|
blip = CREATE_COORD_BLIP(checkpoints[current_position], BLIPPRIORITY_MED, FALSE)
|
|
SET_BLIP_COLOUR(blip, BLIP_COLOUR_YELLOW)
|
|
SET_BLIP_SCALE(blip, 1.2)
|
|
SHOW_HEIGHT_ON_BLIP(blip, FALSE)
|
|
IF (current_position < (current_max_positions-1))
|
|
nextblip = CREATE_COORD_BLIP(checkpoints[current_position+1], BLIPPRIORITY_MED, FALSE)
|
|
SET_BLIP_COLOUR(nextblip, BLIP_COLOUR_YELLOW)
|
|
IF (current_position = (current_max_positions-2))
|
|
SET_BLIP_SCALE(nextblip, 1.2)
|
|
SET_BLIP_SPRITE(nextblip, RADAR_TRACE_RACEFLAG)
|
|
SHOW_HEIGHT_ON_BLIP(nextblip, FALSE)
|
|
ELSE
|
|
SET_BLIP_SCALE(nextblip, 0.7)
|
|
SHOW_HEIGHT_ON_BLIP(nextblip, FALSE)
|
|
ENDIF
|
|
ENDIF
|
|
DEBUG_PRINTSTRINGINT("***current_position: ", current_position)
|
|
|
|
SPAWN_CHECKPOINT(checkpoints)
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Reset both bikes to their starting location at the beginning of the bike section
|
|
PROC m_pResetBikes()
|
|
|
|
// Reset bike mix group entity in audio scene in case Mary Ann gets on a different bike after the reset
|
|
IF IS_VEHICLE_OK(opponent_goto_bike)
|
|
IF IS_AUDIO_SCENE_ACTIVE("FANATIC_MIX_SCENE")
|
|
REMOVE_ENTITY_FROM_AUDIO_MIX_GROUP(opponent_goto_bike)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF IS_VEHICLE_OK(bike_vehicle) AND IS_VEHICLE_OK(opponent_bike_vehicle)
|
|
IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(bike_vehicle)
|
|
STOP_PLAYBACK_RECORDED_VEHICLE(bike_vehicle)
|
|
ENDIF
|
|
IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(opponent_bike_vehicle)
|
|
STOP_PLAYBACK_RECORDED_VEHICLE(opponent_bike_vehicle)
|
|
ENDIF
|
|
SET_ENTITY_COORDS(bike_vehicle, << -664.34, 6138.38, 1.20 >>)
|
|
SET_ENTITY_HEADING(bike_vehicle, 235)
|
|
SET_VEHICLE_DOORS_LOCKED(bike_vehicle, VEHICLELOCK_UNLOCKED)
|
|
SET_ENTITY_COORDS(opponent_bike_vehicle, << -664.32, 6133.73, 2.40 >>)
|
|
SET_ENTITY_HEADING(opponent_bike_vehicle, -84.69)
|
|
SET_VEHICLE_DOORS_LOCKED(opponent_bike_vehicle, VEHICLELOCK_UNLOCKED)
|
|
SET_VEHICLE_ON_GROUND_PROPERLY(bike_vehicle)
|
|
SET_VEHICLE_ON_GROUND_PROPERLY(opponent_bike_vehicle)
|
|
ELSE
|
|
IF NOT IS_VEHICLE_OK(bike_vehicle)
|
|
bike_vehicle = CREATE_VEHICLE(bike_model, << -664.34, 6138.38, 1.20 >>, 235)
|
|
SET_ENTITY_HEADING(bike_vehicle, 235)
|
|
SET_VEHICLE_COLOUR_COMBINATION(bike_vehicle, 1)
|
|
ENDIF
|
|
IF NOT IS_VEHICLE_OK(opponent_bike_vehicle)
|
|
opponent_bike_vehicle = CREATE_VEHICLE(bike_model, << -664.32, 6133.73, 2.40 >>, -84.69)
|
|
SET_ENTITY_HEADING(opponent_bike_vehicle, -84.69)
|
|
SET_VEHICLE_COLOUR_COMBINATION(opponent_bike_vehicle, 2)
|
|
ENDIF
|
|
SET_VEHICLE_ON_GROUND_PROPERLY(bike_vehicle)
|
|
SET_VEHICLE_ON_GROUND_PROPERLY(opponent_bike_vehicle)
|
|
ENDIF
|
|
// Reset vehicle indexes used for making Mary Ann go to the right bike
|
|
opponent_goto_bike = NULL
|
|
players_bike = NULL
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Sets up the smacktalk conversations, checkpoints, and Mary-Ann settings
|
|
PROC m_pInitialiseRace()
|
|
INT i
|
|
REPEAT MAX_SMACK_TALK i
|
|
smack[0][i].already_said = FALSE
|
|
smack[1][i].already_said = FALSE
|
|
smack[2][i].already_said = FALSE
|
|
ENDREPEAT
|
|
|
|
// Swimming
|
|
smack[0][0].ConvRoot = "FAN3_SW1"
|
|
smack[0][1].ConvRoot = "FAN3_SW2"
|
|
|
|
// Cycling - player lost swimming
|
|
smack[1][0].ConvRoot = "FAN3_1WON1"
|
|
smack[1][2].ConvRoot = "FAN3_GEN2"
|
|
|
|
// Cycling - player won swimming
|
|
smack[2][1].ConvRoot = "FAN3_1LOSS2"
|
|
smack[2][2].ConvRoot = "FAN3_GEN2"
|
|
|
|
// Running - player lost cycling
|
|
smack[3][1].ConvRoot = "FAN3_2WON2"
|
|
smack[3][2].ConvRoot = "FAN3_GEN3"
|
|
|
|
// Running - player won cycling
|
|
smack[4][0].ConvRoot = "FAN3_2LOSS1"
|
|
smack[4][2].ConvRoot = "FAN3_GEN3"
|
|
|
|
// Outfit specific variants
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
IF IS_OUTFIT_SUITABLE_FOR_FANATIC_MISSION(3)
|
|
smack[2][0].ConvRoot = "FAN3_1LOSS1B"
|
|
smack[1][1].ConvRoot = "FAN3_1WON2B"
|
|
smack[3][0].ConvRoot = "FAN3_2WON1B"
|
|
smack[4][1].ConvRoot = "FAN3_2LOSS2B"
|
|
ELSE
|
|
smack[2][0].ConvRoot = "FAN3_1LOSS1A"
|
|
smack[3][0].ConvRoot = "FAN3_2WON1A"
|
|
smack[1][1].ConvRoot = "FAN3_1WON2A"
|
|
smack[4][1].ConvRoot = "FAN3_2LOSS2A"
|
|
ENDIF
|
|
ENDIF
|
|
|
|
BIKE_POSITIONS[0] = << -624.82, 6164.18, 2.71 >>
|
|
BIKE_POSITIONS[1] = << -569.97, 6172.85, 5.51 >>
|
|
BIKE_POSITIONS[2] = << -510.38, 6213.40, 9.35 >>
|
|
BIKE_POSITIONS[3] = << -497.67, 6272.69, 10.60 >>
|
|
BIKE_POSITIONS[4] = << -476.6988, 6310.2969, 12.6412 >>
|
|
BIKE_POSITIONS[5] = << -452.44, 6356.24, 11.58 >>
|
|
BIKE_POSITIONS[6] = << -410.0162, 6381.5264, 13.0197 >>
|
|
BIKE_POSITIONS[7] = << -324.23, 6429.89, 11.94 >>
|
|
BIKE_POSITIONS[8] = << -197.2431, 6543.6426, 10.0969 >>
|
|
BIKE_POSITIONS[9] = << -5.04, 6728.77, 18.69 >>
|
|
BIKE_POSITIONS[10] = << 50.60, 6770.79, 19.50 >>
|
|
|
|
RUN_POSITIONS[0] = << 90.94, 6804.34, 18.40 >>
|
|
RUN_POSITIONS[1] = << 117.87, 6829.98, 15.70 >>
|
|
RUN_POSITIONS[2] = << 101.52, 6851.33, 14.67 >>
|
|
RUN_POSITIONS[3] = << 67.33, 6889.14, 12.48 >>
|
|
RUN_POSITIONS[4] = << 48.75, 6927.61, 13.21 >>
|
|
RUN_POSITIONS[5] = << 61.77, 6955.45, 10.81 >>
|
|
RUN_POSITIONS[6] = << 47.11, 6965.58, 9.81 >>
|
|
RUN_POSITIONS[7] = << 36.23, 6995.43, 7.34 >>
|
|
RUN_POSITIONS[8] = << 51.32, 7024.07, 8.87 >>
|
|
RUN_POSITIONS[9] = << 68.42, 7030.54, 11.75 >>
|
|
RUN_POSITIONS[10] = << 61.60, 7049.50, 15.45 >>
|
|
//RUN_POSITIONS[10] = << 65.36, 7047.99, 15.59 >> // For realtime version
|
|
|
|
OPEN_TEST_POLY(MaryAnnBikeBounds)
|
|
ADD_TEST_POLY_VERT(MaryAnnBikeBounds, <<-669.58, 6153.29, 0.45>>)
|
|
ADD_TEST_POLY_VERT(MaryAnnBikeBounds, <<-522.75, 6317.60, 9.79>>)
|
|
ADD_TEST_POLY_VERT(MaryAnnBikeBounds, <<-221.87, 6550.84, 8.87>>)
|
|
ADD_TEST_POLY_VERT(MaryAnnBikeBounds, <<-220.85, 6657.39, 0.47>>)
|
|
ADD_TEST_POLY_VERT(MaryAnnBikeBounds, <<-98.01, 6746.05, 0.66>>)
|
|
ADD_TEST_POLY_VERT(MaryAnnBikeBounds, <<82.53, 6814.59, 17.29>>) // end of coast-side boundary
|
|
|
|
ADD_TEST_POLY_VERT(MaryAnnBikeBounds, <<100.83, 6770.48, 28.49>>) // first point on Paleto Bay side boundary
|
|
ADD_TEST_POLY_VERT(MaryAnnBikeBounds, <<-346.80, 6373.35, 20.40>>)
|
|
ADD_TEST_POLY_VERT(MaryAnnBikeBounds, <<-464.00, 6242.33, 27.31>>)
|
|
ADD_TEST_POLY_VERT(MaryAnnBikeBounds, <<-478.26, 6133.85, 13.53>>)
|
|
ADD_TEST_POLY_VERT(MaryAnnBikeBounds, <<-632.49, 6112.85, 9.95>>)
|
|
ADD_TEST_POLY_VERT(MaryAnnBikeBounds, <<-679.62, 6097.66, 2.07>>)
|
|
ADD_TEST_POLY_VERT(MaryAnnBikeBounds, <<-721.78, 6112.86, -0.68>>)
|
|
CLOSE_TEST_POLY(MaryAnnBikeBounds)
|
|
|
|
CREATE_CHECKPOINT_LINE(<< -888.0333, 6142.6577, 2.3874 >>, << -679.05, 6139.86, 0.70 >>, SWIM_POSITIONS, MAX_SWIM_POSITIONS) //propr
|
|
|
|
bike_model = scorcher
|
|
|
|
sOpponentWaypointName = "Fan3_pedBike"
|
|
|
|
IF IS_REPLAY_IN_PROGRESS()
|
|
// Get the previously-accrued amount of time from the last play attempt to add on to the existing time
|
|
replay_timer_addition = g_replay.iReplayInt[F3_CHECKPOINT_TIME]
|
|
ENDIF
|
|
|
|
SET_ALL_VEHICLE_GENERATORS_ACTIVE_IN_AREA(<<-191.098450,6550.963867,10.097297>>, <<-199.409927,6542.312012,11.097295>>, FALSE)
|
|
SET_ALL_VEHICLE_GENERATORS_ACTIVE_IN_AREA(<<-226.3857, 6498.8770, 9.2147>>, <<-173.1313, 6595.7710, 20.7218>>, FALSE)
|
|
SET_ROADS_IN_ANGLED_AREA(vRoadDisableAA1, vRoadDisableAA2, fRoadDisableAA, FALSE, FALSE)
|
|
|
|
SET_WANTED_LEVEL_MULTIPLIER(0.1)
|
|
|
|
REQUEST_MODEL(bike_model)
|
|
REQUEST_ANIM_SET("FEMALE_FAST_RUNNER")
|
|
|
|
WHILE NOT HAS_MODEL_LOADED(bike_model)
|
|
OR NOT HAS_ANIM_SET_LOADED("FEMALE_FAST_RUNNER")
|
|
WAIT(0)
|
|
ENDWHILE
|
|
|
|
m_pResetBikes()
|
|
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
SET_PED_DIES_IN_WATER(opponent, FALSE)
|
|
SET_PED_PATH_PREFER_TO_AVOID_WATER(opponent, FALSE)
|
|
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(opponent, TRUE)
|
|
SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(opponent, TRUE)
|
|
SET_PED_CAN_BE_TARGETTED(opponent, false)
|
|
SET_ENTITY_LOAD_COLLISION_FLAG(opponent, TRUE)
|
|
SET_PED_CAN_BE_KNOCKED_OFF_VEHICLE(opponent, KNOCKOFFVEHICLE_NEVER)
|
|
SET_PED_MOVEMENT_CLIPSET(opponent, "FEMALE_FAST_RUNNER")
|
|
SET_PED_CAN_RAGDOLL_FROM_PLAYER_IMPACT(opponent, FALSE)
|
|
//SET_DRIVER_RACING_MODIFIER(opponent, 0.1)
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Load all models and recordings we need for the swim section, and create entities as needed
|
|
PROC m_pLoadSwim()
|
|
|
|
ma_pSwitchState(MS_SWIM) // Do this here so Mary Ann continues to run after the cutscene
|
|
|
|
REQUEST_MODEL(bike_model)
|
|
//REQUEST_MODEL(boat_model_1)
|
|
//REQUEST_MODEL(A_M_Y_Jetski_01)
|
|
REQUEST_WAYPOINT_RECORDING("Fan3_RollingStart")
|
|
//REQUEST_WAYPOINT_RECORDING("Fan3_jetskiRoute")
|
|
//REQUEST_WAYPOINT_RECORDING("Fan3_jetskiRoute2")
|
|
REQUEST_ADDITIONAL_TEXT("FATIC3", MISSION_TEXT_SLOT)
|
|
|
|
WHILE NOT //HAS_MODEL_LOADED(boat_model_1)
|
|
//OR NOT HAS_MODEL_LOADED(A_M_Y_Jetski_01)
|
|
GET_IS_WAYPOINT_RECORDING_LOADED("Fan3_RollingStart")
|
|
//OR NOT GET_IS_WAYPOINT_RECORDING_LOADED("Fan3_jetskiRoute")
|
|
//OR NOT GET_IS_WAYPOINT_RECORDING_LOADED("Fan3_jetskiRoute2")
|
|
OR NOT HAS_ADDITIONAL_TEXT_LOADED(MISSION_TEXT_SLOT)
|
|
OR NOT HAS_MODEL_LOADED(bike_model)
|
|
ma_pDoIntroBoost()
|
|
DEBUG_PRINTSTRING("Waiting for swim assets...")
|
|
WAIT(0)
|
|
ENDWHILE
|
|
|
|
OPEN_TEST_POLY(innerBounds)
|
|
ADD_TEST_POLY_VERT(innerBounds, <<-911.33, 6156.95, 3.78>>)
|
|
ADD_TEST_POLY_VERT(innerBounds, <<-833.30, 6159.46, 1.19>>)
|
|
ADD_TEST_POLY_VERT(innerBounds, <<-712.84, 6161.51, 0.18>>)
|
|
ADD_TEST_POLY_VERT(innerBounds, <<-653.84, 6154.68, 1.39>>)
|
|
ADD_TEST_POLY_VERT(innerBounds, <<-651.92, 6134.70, 3.20>>)
|
|
ADD_TEST_POLY_VERT(innerBounds, <<-683.51, 6108.33, 1.60>>)
|
|
ADD_TEST_POLY_VERT(innerBounds, <<-922.48, 6125.13, 5.71>>)
|
|
CLOSE_TEST_POLY(innerBounds)
|
|
|
|
// SAFE_DELETE_PED(jetski_guy1)
|
|
// SAFE_DELETE_VEHICLE(jetski1)
|
|
//
|
|
// jetski1 = CREATE_VEHICLE(boat_model_1, <<-847.760010,6295.217773,-0.160587>>, -165.894836)
|
|
// IF IS_VEHICLE_OK(jetski1)
|
|
// SET_VEHICLE_DOORS_LOCKED(jetski1, VEHICLELOCK_LOCKOUT_PLAYER_ONLY)
|
|
// SET_ENTITY_LOAD_COLLISION_FLAG(jetski1, TRUE)
|
|
// ENDIF
|
|
//
|
|
// jetski_guy1 = CREATE_PED_INSIDE_VEHICLE(jetski1, PEDTYPE_MISSION, A_M_Y_Jetski_01)
|
|
//
|
|
// SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(jetski_guy1, TRUE)
|
|
//
|
|
// SAFE_DELETE_PED(jetski_guy2)
|
|
// SAFE_DELETE_VEHICLE(jetski2)
|
|
//
|
|
// jetski2 = CREATE_VEHICLE(boat_model_1, <<-864.4749, 6291.2881, -4.71977>>, 215.8633)
|
|
// IF IS_VEHICLE_OK(jetski2)
|
|
// SET_VEHICLE_DOORS_LOCKED(jetski2, VEHICLELOCK_LOCKOUT_PLAYER_ONLY)
|
|
// SET_ENTITY_LOAD_COLLISION_FLAG(jetski2, TRUE)
|
|
// ENDIF
|
|
//
|
|
// jetski_guy2 = CREATE_PED_INSIDE_VEHICLE(jetski2, PEDTYPE_MISSION, A_M_Y_Jetski_01)
|
|
//
|
|
// SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(jetski_guy2, TRUE)
|
|
//
|
|
// SET_MODEL_AS_NO_LONGER_NEEDED(boat_model_1)
|
|
// SET_MODEL_AS_NO_LONGER_NEEDED(A_M_Y_Jetski_01)
|
|
|
|
ADD_PED_FOR_DIALOGUE(conversation, ENUM_TO_INT(CHAR_FRANKLIN), PLAYER_PED_ID(), "FRANKLIN")
|
|
ADD_PED_FOR_DIALOGUE(conversation, 3, opponent, "MARYANN")
|
|
|
|
USE_WAYPOINT_RECORDING_AS_ASSISTED_MOVEMENT_ROUTE("Fan3_RollingStart", TRUE)
|
|
|
|
current_position = 0
|
|
current_max_positions = MAX_SWIM_POSITIONS
|
|
|
|
missionStage = MS_SWIM
|
|
|
|
CREATE_FIRST_BLIP(SWIM_POSITIONS)
|
|
|
|
IF NOT bSkipped
|
|
TRIGGER_MUSIC_EVENT("FANATIC3_START")
|
|
DEBUG_PRINTSTRING("Starting swim music")
|
|
ENDIF
|
|
|
|
intro_playing = FALSE
|
|
// boat_launched = FALSE
|
|
// jetski_conv_launched = FALSE
|
|
// maryann_jetski_conv_launched = FALSE
|
|
bDoneSwimDialogue = FALSE
|
|
iTrashTalkTimer = GET_GAME_TIMER()
|
|
|
|
IF NOT IS_REPLAY_BEING_SET_UP()
|
|
RC_END_CUTSCENE_MODE()
|
|
ENDIF
|
|
|
|
PRINT_NOW("FATIC3_1", DEFAULT_GOD_TEXT_TIME, 1) //Swim across the ~y~bay.
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Unload the peds from the swim section
|
|
PROC m_pUnloadSwim()
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Load all models and recordings we need for the bike section, and create entities as needed
|
|
/// RETURNS:
|
|
/// TRUE when all resources have loaded and been created, FALSE otherwise
|
|
FUNC BOOL m_pLoadBike()
|
|
REQUEST_MODEL(Patriot)
|
|
REQUEST_MODEL(A_F_M_KTown_02)
|
|
REQUEST_WAYPOINT_RECORDING("Fan3_baddriver")
|
|
REQUEST_VEHICLE_RECORDING(500, "Fan3_MaryAnnBikeJump")
|
|
REQUEST_WAYPOINT_RECORDING("Fan3_pedBike")
|
|
REQUEST_MODEL(S_M_M_DockWork_01)
|
|
REQUEST_ANIM_DICT("rcmfanatic3")
|
|
|
|
IF NOT HAS_MODEL_LOADED(Patriot)
|
|
OR NOT HAS_MODEL_LOADED(A_F_M_KTown_02)
|
|
OR NOT HAS_MODEL_LOADED(S_M_M_DockWork_01)
|
|
OR NOT GET_IS_WAYPOINT_RECORDING_LOADED("Fan3_baddriver")
|
|
OR NOT HAS_VEHICLE_RECORDING_BEEN_LOADED(500, "Fan3_MaryAnnBikeJump")
|
|
OR NOT GET_IS_WAYPOINT_RECORDING_LOADED("Fan3_pedBike")
|
|
OR NOT HAS_ANIM_DICT_LOADED("rcmfanatic3")
|
|
DEBUG_PRINTSTRING("Waiting for bike resources")
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
SAFE_DELETE_VEHICLE(bad_driver_car)
|
|
bad_driver_car = CREATE_VEHICLE(Patriot, << -206.0824, 6557.3765, 11.0625 >>, 220.94)
|
|
|
|
SAFE_DELETE_PED(bad_driver_ped)
|
|
IF IS_VEHICLE_OK(bad_driver_car) AND NOT IS_ENTITY_ALIVE(bad_driver_ped)
|
|
bad_driver_ped = CREATE_PED_INSIDE_VEHICLE(bad_driver_car, PEDTYPE_MISSION, A_F_M_KTown_02)
|
|
ENDIF
|
|
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(Patriot)
|
|
|
|
if IS_ENTITY_ALIVE(bad_driver_ped)
|
|
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(bad_driver_ped, TRUE)
|
|
ENDIF
|
|
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(A_F_M_KTown_02)
|
|
|
|
SAFE_DELETE_PED(fence_worker)
|
|
fence_worker = CREATE_PED(PEDTYPE_MISSION, S_M_M_DockWork_01, << -185.1444, 6561.3379, 10.1026 >>, 310)
|
|
IF IS_ENTITY_ALIVE(fence_worker)
|
|
TASK_PLAY_ANIM(fence_worker, "rcmfanatic3", "KNEEL_IDLE_A", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_LOOPING)
|
|
ENDIF
|
|
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(S_M_M_DockWork_01)
|
|
|
|
CLEAR_ANGLED_AREA_OF_VEHICLES(vRoadDisableAA1, vRoadDisableAA2, fRoadDisableAA) // Clear any ambient cars that've sneaked onto the road when they SHOULDN'T HAVE
|
|
|
|
OPEN_TEST_POLY(innerBounds)
|
|
ADD_TEST_POLY_VERT(innerBounds, <<-669.58, 6153.29, 0.45>>)
|
|
ADD_TEST_POLY_VERT(innerBounds, <<-522.75, 6317.60, 9.79>>)
|
|
ADD_TEST_POLY_VERT(innerBounds, <<-221.87, 6550.84, 8.87>>)
|
|
ADD_TEST_POLY_VERT(innerBounds, <<-220.85, 6657.39, 0.47>>)
|
|
ADD_TEST_POLY_VERT(innerBounds, <<-98.01, 6746.05, 0.66>>)
|
|
ADD_TEST_POLY_VERT(innerBounds, <<58.62, 6800.74, 19.35>>) // end of coast-side boundary
|
|
|
|
ADD_TEST_POLY_VERT(innerBounds, <<92.21, 6746.91, 37.55>>) // first point on Paleto Bay side boundary
|
|
ADD_TEST_POLY_VERT(innerBounds, <<-346.80, 6373.35, 20.40>>)
|
|
ADD_TEST_POLY_VERT(innerBounds, <<-464.00, 6242.33, 27.31>>)
|
|
ADD_TEST_POLY_VERT(innerBounds, <<-478.26, 6133.85, 13.53>>)
|
|
ADD_TEST_POLY_VERT(innerBounds, <<-632.49, 6112.85, 9.95>>)
|
|
ADD_TEST_POLY_VERT(innerBounds, <<-679.62, 6097.66, 2.07>>)
|
|
ADD_TEST_POLY_VERT(innerBounds, <<-721.78, 6112.86, -0.68>>)
|
|
CLOSE_TEST_POLY(innerBounds)
|
|
|
|
ADD_PED_FOR_DIALOGUE(conversation, ENUM_TO_INT(CHAR_FRANKLIN), PLAYER_PED_ID(), "FRANKLIN")
|
|
ADD_PED_FOR_DIALOGUE(conversation, 3, opponent, "MARYANN")
|
|
|
|
bMADoingJump = FALSE
|
|
|
|
IF NOT bSkipped
|
|
TRIGGER_MUSIC_EVENT("FANATIC3_CYCLE")
|
|
DEBUG_PRINTSTRING("Starting bike music")
|
|
ENDIF
|
|
|
|
RETURN TRUE
|
|
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Unload all resources for the bike section
|
|
PROC m_pUnloadBike()
|
|
SAFE_RELEASE_PED(bad_driver_ped)
|
|
SAFE_RELEASE_PED(fence_worker)
|
|
SAFE_RELEASE_VEHICLE(bad_driver_car)
|
|
REMOVE_WAYPOINT_RECORDING("Fan3_baddriver")
|
|
REMOVE_ANIM_DICT("rcmfanatic3")
|
|
SET_ALL_VEHICLE_GENERATORS_ACTIVE_IN_AREA(<<-191.098450,6550.963867,10.097297>>, <<-199.409927,6542.312012,11.097295>>, TRUE)
|
|
SET_ALL_VEHICLE_GENERATORS_ACTIVE_IN_AREA(<<-226.3857, 6498.8770, 9.2147>>, <<-173.1313, 6595.7710, 20.7218>>, TRUE)
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Load all the resources for the jog section of the mission and create them
|
|
/// RETURNS:
|
|
/// TRUE when all resources have been loaded and created, FALSE otherwise
|
|
FUNC BOOL m_pLoadJog()
|
|
REQUEST_MODEL(BALLER)
|
|
REQUEST_MODEL(A_M_Y_BeachVesp_01)
|
|
REQUEST_MODEL(A_M_Y_MusclBeac_02)
|
|
REQUEST_MODEL(A_F_Y_Runner_01)
|
|
REQUEST_MODEL(DOG_MODEL)
|
|
REQUEST_MODEL(scorcher)
|
|
REQUEST_ANIM_DICT("rcmfanatic3")
|
|
REQUEST_ANIM_DICT("rcmfanatic1maryann_stretchidle_b")
|
|
REQUEST_WAYPOINT_RECORDING("fan3_pedJog")
|
|
REQUEST_WAYPOINT_RECORDING("fan3_dogroute")
|
|
REQUEST_WAYPOINT_RECORDING("fan3_ownerroute")
|
|
|
|
|
|
IF NOT HAS_ANIM_DICT_LOADED("rcmfanatic3")
|
|
OR NOT HAS_ANIM_DICT_LOADED("rcmfanatic1maryann_stretchidle_b")
|
|
OR NOT HAS_MODEL_LOADED(BALLER)
|
|
OR NOT HAS_MODEL_LOADED(scorcher)
|
|
OR NOT HAS_MODEL_LOADED(A_M_Y_BeachVesp_01)
|
|
OR NOT HAS_MODEL_LOADED(A_F_Y_Runner_01)
|
|
OR NOT HAS_MODEL_LOADED(DOG_MODEL)
|
|
OR NOT HAS_MODEL_LOADED(A_M_Y_MusclBeac_02)
|
|
OR NOT GET_IS_WAYPOINT_RECORDING_LOADED("fan3_pedJog")
|
|
OR NOT GET_IS_WAYPOINT_RECORDING_LOADED("fan3_dogroute")
|
|
OR NOT GET_IS_WAYPOINT_RECORDING_LOADED("fan3_ownerroute")
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
iBinocStage = 0
|
|
iStretchStage = 0
|
|
iChinupStage = 0
|
|
iOwnerStage = 0
|
|
|
|
SAFE_DELETE_VEHICLE(picniccar2)
|
|
picniccar2 = CREATE_VEHICLE(BALLER, <<12.086388,6967.021484,10.150966>>, 0.588968)
|
|
|
|
if IS_VEHICLE_OK(picniccar2)
|
|
SET_VEHICLE_ON_GROUND_PROPERLY(picniccar2)
|
|
SET_VEHICLE_ENGINE_HEALTH(picniccar2, 400)
|
|
ENDIF
|
|
|
|
SAFE_DELETE_PED(binoculars_guy)
|
|
SAFE_DELETE_OBJECT(binocs)
|
|
|
|
binoculars_guy = CREATE_PED(PEDTYPE_MISSION, A_M_Y_BeachVesp_01, << 14.1481, 6966.5366, 9.4860 >>, 335.3788)
|
|
binocs = CREATE_OBJECT(PROP_BINOC_01, << 14.1481, 6966.5366, 9.4860 >>)
|
|
|
|
if IS_ENTITY_ALIVE(binoculars_guy)
|
|
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(binoculars_guy, true)
|
|
SET_PED_COMPONENT_VARIATION(binoculars_guy, INT_TO_ENUM(PED_COMPONENT, 0), 0, 0)
|
|
SET_PED_COMPONENT_VARIATION(binoculars_guy, INT_TO_ENUM(PED_COMPONENT, 2), 0, 0)
|
|
SET_PED_COMPONENT_VARIATION(binoculars_guy, INT_TO_ENUM(PED_COMPONENT, 3), 0, 0)
|
|
SET_PED_COMPONENT_VARIATION(binoculars_guy, INT_TO_ENUM(PED_COMPONENT, 4), 0, 0)
|
|
SET_PED_COMPONENT_VARIATION(binoculars_guy, INT_TO_ENUM(PED_COMPONENT, 8), 0, 0)
|
|
SET_PED_CAN_RAGDOLL(binoculars_guy, FALSE)
|
|
ATTACH_ENTITY_TO_ENTITY(binocs, binoculars_guy, GET_PED_BONE_INDEX(binoculars_guy, BONETAG_L_HAND), <<0.12,0,0.1>>, <<-22,90,-20>>, true)
|
|
TASK_PLAY_ANIM(binoculars_guy, "rcmfanatic3", "binoculars", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_LOOPING)
|
|
ADD_PED_FOR_DIALOGUE(conv_frank, 4, binoculars_guy, "FAN3BIRDWATCHER")
|
|
ENDIF
|
|
|
|
SAFE_DELETE_PED(chinups_guy)
|
|
chinups_guy = CREATE_PED(PEDTYPE_MISSION, A_M_Y_MusclBeac_02, <<64.7329, 6938.6245, 12.2245>>, 241.60)
|
|
|
|
if IS_ENTITY_ALIVE(chinups_guy)
|
|
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(chinups_guy, true)
|
|
SET_PED_COMPONENT_VARIATION(chinups_guy, INT_TO_ENUM(PED_COMPONENT, 0), 0, 0)
|
|
SET_PED_COMPONENT_VARIATION(chinups_guy, INT_TO_ENUM(PED_COMPONENT, 2), 0, 0)
|
|
SET_PED_COMPONENT_VARIATION(chinups_guy, INT_TO_ENUM(PED_COMPONENT, 3), 1, 1)
|
|
SET_PED_COMPONENT_VARIATION(chinups_guy, INT_TO_ENUM(PED_COMPONENT, 4), 0, 0)
|
|
SET_PED_COMPONENT_VARIATION(chinups_guy, INT_TO_ENUM(PED_COMPONENT, 8), 0, 0)
|
|
// SET_PED_CAN_RAGDOLL(chinups_guy, FALSE)
|
|
TASK_PLAY_ANIM(chinups_guy, "rcmfanatic3", "base", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_LOOPING)
|
|
// ADD_PED_FOR_DIALOGUE(conv_frank, 4, binoculars_guy, "FAN3BIRDWATCHER")
|
|
ENDIF
|
|
|
|
SAFE_DELETE_PED(stretching_woman)
|
|
stretching_woman = CREATE_PED(PEDTYPE_MISSION, A_F_Y_Runner_01, <<76.5829, 6957.7534, 10.3747>>, 30.24)
|
|
|
|
if IS_ENTITY_ALIVE(stretching_woman)
|
|
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(stretching_woman, true)
|
|
TASK_PLAY_ANIM(stretching_woman, "rcmfanatic1maryann_stretchidle_b", "idle_e", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_LOOPING)
|
|
ENDIF
|
|
|
|
SAFE_DELETE_PED(running_dog)
|
|
running_dog = CREATE_PED(PEDTYPE_MISSION, DOG_MODEL, <<114.038,6900.039,20.455>>, 56.723)
|
|
IF IS_ENTITY_ALIVE(running_dog)
|
|
SET_PED_DEFAULT_COMPONENT_VARIATION(running_dog)
|
|
ENDIF
|
|
|
|
SAFE_DELETE_PED(dog_owner)
|
|
// Do not create the dog owner ped here!
|
|
// She gets created in DO_OWNER_SCENE(), so the player can't (un)intentionally miss checkpoints
|
|
// and go to where she spawns to see her gawping in place waiting for the trigger
|
|
|
|
SAFE_DELETE_VEHICLE(EndingBikeMA)
|
|
EndingBikeMA = CREATE_VEHICLE(scorcher, vEndingBikeMASpawn, fEndingBikeMASpawn)
|
|
if IS_VEHICLE_OK(EndingBikeMA)
|
|
SET_VEHICLE_ON_GROUND_PROPERLY(EndingBikeMA)
|
|
ENDIF
|
|
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(A_M_Y_Hiker_01)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(Patriot)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(A_M_Y_MusclBeac_02)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(DOG_MODEL)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(BALLER)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(PROP_BINOC_01)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(A_M_Y_Hiker_01)
|
|
|
|
OPEN_TEST_POLY(innerBounds)
|
|
ADD_TEST_POLY_VERT(innerBounds, <<42.25, 6775.99, 20.035>>)
|
|
ADD_TEST_POLY_VERT(innerBounds, <<70.90, 6811.02, 16.56>>)
|
|
ADD_TEST_POLY_VERT(innerBounds, <<30.55, 6908.24, 12.57>>)
|
|
ADD_TEST_POLY_VERT(innerBounds, <<17.22, 6966.57, 9.87>>)
|
|
ADD_TEST_POLY_VERT(innerBounds, <<42.16, 7088.71, 0.65>>)
|
|
ADD_TEST_POLY_VERT(innerBounds, <<133.71, 7050.03, 0.35>>)
|
|
ADD_TEST_POLY_VERT(innerBounds, <<119.44, 6923.47, 19.92>>)
|
|
ADD_TEST_POLY_VERT(innerBounds, <<144.19, 6821.13, 21.80>>)
|
|
ADD_TEST_POLY_VERT(innerBounds, <<128.37, 6764.95, 26.39>>)
|
|
ADD_TEST_POLY_VERT(innerBounds, <<49.68, 6736.11, 30.31>>)
|
|
CLOSE_TEST_POLY(innerBounds)
|
|
|
|
ADD_PED_FOR_DIALOGUE(conversation, ENUM_TO_INT(CHAR_FRANKLIN), PLAYER_PED_ID(), "FRANKLIN")
|
|
ADD_PED_FOR_DIALOGUE(conversation, 3, opponent, "MARYANN")
|
|
|
|
IF NOT bSkipped
|
|
TRIGGER_MUSIC_EVENT("FANATIC3_RUN")
|
|
DEBUG_PRINTSTRING("Starting run music")
|
|
ENDIF
|
|
|
|
RETURN TRUE
|
|
|
|
ENDFUNC
|
|
|
|
PROC m_pUnloadJog()
|
|
SAFE_RELEASE_VEHICLE(picniccar2)
|
|
SAFE_RELEASE_PED(binoculars_guy)
|
|
SAFE_RELEASE_OBJECT(binocs)
|
|
SAFE_RELEASE_PED(stretching_woman)
|
|
SAFE_RELEASE_PED(running_dog)
|
|
SAFE_RELEASE_PED(dog_owner)
|
|
SAFE_RELEASE_VEHICLE(EndingBikeMA)
|
|
SAFE_RELEASE_PED(chinups_guy)
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Keep track of and update the player's checkpoints one by one as they progress through the current race section
|
|
/// PARAMS:
|
|
/// checkpoints - The checkpoint coord array we're keeping track of at this time
|
|
/// RETURNS:
|
|
/// TRUE when the player has completed this section of the race, FALSE otherwise
|
|
FUNC BOOL DO_CHECKPOINT_UPDATES(VECTOR& checkpoints[])
|
|
VECTOR player_pos = GET_ENTITY_COORDS(PLAYER_PED_ID())
|
|
FLOAT dist = GET_DISTANCE_BETWEEN_COORDS(player_pos, checkpoints[current_position], FALSE)
|
|
#IF IS_DEBUG_BUILD
|
|
CPRINTLN(DEBUG_MISSION, "Player: <<", GET_STRING_FROM_VECTOR(player_pos), ">> checkpoint: <<", GET_STRING_FROM_VECTOR(checkpoints[current_position]), ">> dist: ", dist)
|
|
#ENDIF
|
|
IF dist < 5.5
|
|
|
|
SAFE_REMOVE_BLIP(blip)
|
|
|
|
SAFE_REMOVE_BLIP(nextblip)
|
|
|
|
PLAY_SOUND_FRONTEND(-1, "CHECKPOINT_NORMAL", "HUD_MINI_GAME_SOUNDSET", FALSE)
|
|
|
|
IF checkpoint != NULL
|
|
DEBUG_PRINTSTRING("Create prev CP")
|
|
INT PreviR, PreviG, PreviB
|
|
GET_HUD_COLOUR(HUD_COLOUR_WHITE, PreviR, PreviG, PreviB, iPrevAlpha)
|
|
iPrevAlpha = 180
|
|
VECTOR tempPos = checkpoints[current_position]
|
|
SWITCH missionStage
|
|
CASE MS_SWIM
|
|
IF (current_position = (current_max_positions - 1))
|
|
tempPos +=<<0,0,1.7>>
|
|
ELSE
|
|
FLOAT fAdjust
|
|
IF current_position = 6
|
|
fAdjust = 1.5
|
|
ELSE
|
|
fAdjust = 0.4
|
|
ENDIF
|
|
tempPos +=<<0,0,fAdjust>>
|
|
ENDIF
|
|
BREAK
|
|
CASE MS_BIKE
|
|
IF (current_position = (current_max_positions - 1))
|
|
tempPos +=<<0,0,1.7>>
|
|
ELSE
|
|
tempPos +=<<0,0,2.0>>
|
|
ENDIF
|
|
BREAK
|
|
CASE MS_RUN
|
|
IF (current_position = (current_max_positions - 1))
|
|
tempPos +=<<0,0,1.7>>
|
|
ELSE
|
|
tempPos +=<<0,0,2.0>>
|
|
ENDIF
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
IF (current_position = (current_max_positions - 1))
|
|
VECTOR to_position = checkpoints[current_position]
|
|
|
|
PrevCheckpoint = CREATE_CHECKPOINT(CHECKPOINT_RACE_GROUND_FLAG, tempPos, to_position, 3.2, PreviR, PreviG, PreviB, iPrevAlpha)
|
|
ELSE
|
|
VECTOR to_position = checkpoints[current_position+1]
|
|
|
|
IF missionStage = MS_SWIM
|
|
AND current_position = 0
|
|
tempPos = checkpoints[current_position]+<<0,0,2.0>>
|
|
PrevCheckpoint = CREATE_CHECKPOINT(CHECKPOINT_RACE_GROUND_CHEVRON_1, tempPos, to_position, 3.2, PreviR, PreviG, PreviB, iPrevAlpha)
|
|
ELIF missionStage = MS_BIKE
|
|
AND current_position = 0
|
|
tempPos -=<<0,0,0.3>> // Bring this down to 1.7 to match, not 2.0
|
|
PrevCheckpoint = CREATE_CHECKPOINT(CHECKPOINT_RACE_GROUND_CHEVRON_2, tempPos, to_position, 3.2, PreviR, PreviG, PreviB, iPrevAlpha)
|
|
ELSE
|
|
PrevCheckpoint = CREATE_CHECKPOINT(GET_RACE_CHECKPOINT_TYPE(current_position, checkpoints), tempPos, to_position, 3.2, PreviR, PreviG, PreviB, iPrevAlpha)
|
|
ENDIF
|
|
|
|
ENDIF
|
|
SET_CHECKPOINT_RGBA(PrevCheckpoint, PreviR, PreviG, PreviB, iPrevAlpha)
|
|
SET_CHECKPOINT_RGBA2(PrevCheckpoint, PreviR,PreviG, PreviB, iPrevAlpha)
|
|
ENDIF
|
|
|
|
DELETE_CHECKPOINT(checkpoint)
|
|
|
|
current_position++
|
|
|
|
IF current_position = current_max_positions
|
|
return TRUE
|
|
ELSE
|
|
blip = CREATE_COORD_BLIP(checkpoints[current_position], BLIPPRIORITY_MED, FALSE)
|
|
SET_BLIP_COLOUR(blip, BLIP_COLOUR_YELLOW)
|
|
SET_BLIP_SCALE(blip, 1.2)
|
|
SHOW_HEIGHT_ON_BLIP(blip, FALSE)
|
|
IF (current_position = (current_max_positions-1)) // If it's the final blip, give it a flag sprite
|
|
SET_BLIP_SPRITE(blip, RADAR_TRACE_RACEFLAG)
|
|
ENDIF
|
|
IF (current_position < (current_max_positions-1))
|
|
nextblip = CREATE_COORD_BLIP(checkpoints[current_position+1], BLIPPRIORITY_MED, FALSE)
|
|
SET_BLIP_COLOUR(nextblip, BLIP_COLOUR_YELLOW)
|
|
IF (current_position = (current_max_positions-2))
|
|
SET_BLIP_SCALE(nextblip, 1.2)
|
|
SET_BLIP_SPRITE(nextblip, RADAR_TRACE_RACEFLAG)
|
|
SHOW_HEIGHT_ON_BLIP(nextblip, FALSE)
|
|
ELSE
|
|
SET_BLIP_SCALE(nextblip, 0.7)
|
|
SHOW_HEIGHT_ON_BLIP(nextblip, FALSE)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
VECTOR to_position
|
|
|
|
// If this is the last checkpoint, do a checkpoint flag instead
|
|
IF (current_position = (current_max_positions - 1))
|
|
to_position = checkpoints[current_position]
|
|
currentCPColour = GET_RACE_CHECKPOINT_COLOUR(GET_RACE_CHECKPOINT_TYPE(current_position, checkpoints))
|
|
INT iR, iG, iB, iA
|
|
GET_HUD_COLOUR(currentCPColour, iR, iG, iB, iA)
|
|
SWITCH missionStage
|
|
CASE MS_SWIM
|
|
checkpoint = CREATE_CHECKPOINT(CHECKPOINT_RACE_GROUND_FLAG, checkpoints[current_position]+<<0,0,1.7>>, to_position, 3.2, iR, iG, iB, iA)
|
|
BREAK
|
|
CASE MS_BIKE
|
|
checkpoint = CREATE_CHECKPOINT(CHECKPOINT_RACE_GROUND_FLAG, checkpoints[current_position]+<<0,0,1.7>>, to_position, 3.2, iR, iG, iB, iA)
|
|
BREAK
|
|
CASE MS_RUN
|
|
checkpoint = CREATE_CHECKPOINT(CHECKPOINT_RACE_GROUND_FLAG, checkpoints[current_position]+<<0,0,1.7>>, to_position, 3.2, iR, iG, iB, iA)
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
GET_HUD_COLOUR(HUD_COLOUR_YELLOWLIGHT, iR, iG, iB, iA)
|
|
SET_CHECKPOINT_RGBA(checkPoint, iR, iG, iB, iA)
|
|
GET_HUD_COLOUR(HUD_COLOUR_NORTH_BLUE, iR, iG, iB, iA)
|
|
SET_CHECKPOINT_RGBA2(checkPoint, iR, iG, iB, iA)
|
|
|
|
SET_CHECKPOINT_CYLINDER_HEIGHT(checkpoint,1.6,1.6,100)
|
|
IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID())
|
|
FLOAT fDis = GET_DISTANCE_BETWEEN_COORDS(checkpoints[current_position],GET_ENTITY_COORDS(PLAYER_PED_ID()))
|
|
|
|
IF checkpoint != NULL // Make sure the checkpoint exists first
|
|
IF fDis > 100.0
|
|
GET_HUD_COLOUR(HUD_COLOUR_YELLOWLIGHT, iR, iG, iB, iA)
|
|
iA = 240
|
|
SET_CHECKPOINT_RGBA(checkPoint, iR, iG, iB, iA)
|
|
GET_HUD_COLOUR(HUD_COLOUR_NORTH_BLUE, iR, iG, iB, iA)
|
|
iA = 240
|
|
SET_CHECKPOINT_RGBA2(checkPoint, iR, iG, iB, iA)
|
|
ELSE
|
|
GET_HUD_COLOUR(HUD_COLOUR_YELLOWLIGHT, iR, iG, iB, iA)
|
|
iA = ROUND(fDis*2.4)
|
|
IF iA < 60
|
|
iA = 60
|
|
ENDIF
|
|
SET_CHECKPOINT_RGBA(checkPoint, iR, iG, iB, iA)
|
|
GET_HUD_COLOUR(HUD_COLOUR_NORTH_BLUE, iR, iG, iB, iA)
|
|
iA = ROUND(fDis*2.4)
|
|
IF iA < 60
|
|
iA = 60
|
|
ENDIF
|
|
SET_CHECKPOINT_RGBA2(checkPoint, iR, iG, iB, iA)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
// Otherwise, do a normal checkpoint
|
|
ELSE
|
|
currentCPColour = GET_RACE_CHECKPOINT_COLOUR(GET_RACE_CHECKPOINT_TYPE(current_position, checkpoints))
|
|
INT iR, iG, iB, iA
|
|
GET_HUD_COLOUR(currentCPColour, iR, iG, iB, iA)
|
|
to_position = checkpoints[current_position+1]
|
|
IF missionStage = MS_SWIM
|
|
// The swim checkpoints are autogenerated (see CREATE_CHECKPOINT_LINE()) and don't take into account that the sea is lower than the
|
|
// start and end positions of the autogen we've done - so we'll manually lower them by 2m to compensate
|
|
FLOAT fAdjust
|
|
IF current_position = 6
|
|
fAdjust = 1.5
|
|
ELSE
|
|
fAdjust = 0.4
|
|
ENDIF
|
|
checkpoint = CREATE_CHECKPOINT(GET_RACE_CHECKPOINT_TYPE(current_position, checkpoints), checkpoints[current_position]+<<0,0,fAdjust>>, to_position, 3.2, iR, iG, iB, iA)
|
|
ELIF missionStage = MS_BIKE
|
|
// Otherwise we'll use the checkpoint vecs as they are (because I've manually placed the bastards)
|
|
checkpoint = CREATE_CHECKPOINT(GET_RACE_CHECKPOINT_TYPE(current_position, checkpoints), checkpoints[current_position]+<<0,0,2.0>>, to_position, 3.2, iR, iG, iB, iA)
|
|
ELSE
|
|
// Otherwise we'll use the checkpoint vecs as they are (because I've manually placed the bastards)
|
|
checkpoint = CREATE_CHECKPOINT(GET_RACE_CHECKPOINT_TYPE(current_position, checkpoints), checkpoints[current_position]+<<0,0,2.0>>, to_position, 3.2, iR, iG, iB, iA)
|
|
ENDIF
|
|
GET_HUD_COLOUR(HUD_COLOUR_YELLOWLIGHT, iR, iG, iB, iA)
|
|
SET_CHECKPOINT_RGBA(checkPoint, iR, iG, iB, iA)
|
|
GET_HUD_COLOUR(HUD_COLOUR_NORTH_BLUE, iR, iG, iB, iA)
|
|
SET_CHECKPOINT_RGBA2(checkPoint, iR, iG, iB, iA)
|
|
SET_CHECKPOINT_CYLINDER_HEIGHT(checkpoint,1.6,1.6,100)
|
|
IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID())
|
|
FLOAT fDis = GET_DISTANCE_BETWEEN_COORDS(checkpoints[current_position],GET_ENTITY_COORDS(PLAYER_PED_ID()))
|
|
|
|
IF checkpoint != NULL // Make sure the checkpoint exists first
|
|
IF fDis > 100.0
|
|
GET_HUD_COLOUR(HUD_COLOUR_YELLOWLIGHT, iR, iG, iB, iA)
|
|
iA = 240
|
|
SET_CHECKPOINT_RGBA(checkPoint, iR, iG, iB, iA)
|
|
GET_HUD_COLOUR(HUD_COLOUR_NORTH_BLUE, iR, iG, iB, iA)
|
|
iA = 240
|
|
SET_CHECKPOINT_RGBA2(checkPoint, iR, iG, iB, iA)
|
|
ELSE
|
|
GET_HUD_COLOUR(HUD_COLOUR_YELLOWLIGHT, iR, iG, iB, iA)
|
|
iA = ROUND(fDis*2.4)
|
|
IF iA < 60
|
|
iA = 60
|
|
ENDIF
|
|
SET_CHECKPOINT_RGBA(checkPoint, iR, iG, iB, iA)
|
|
GET_HUD_COLOUR(HUD_COLOUR_NORTH_BLUE, iR, iG, iB, iA)
|
|
iA = ROUND(fDis*2.4)
|
|
IF iA < 60
|
|
iA = 60
|
|
ENDIF
|
|
SET_CHECKPOINT_RGBA2(checkPoint, iR, iG, iB, iA)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
// CHECKPOINT ALPHA STUFF
|
|
currentCPColour = GET_RACE_CHECKPOINT_COLOUR(GET_RACE_CHECKPOINT_TYPE(current_position, checkpoints))
|
|
INT iR, iG, iB, iA
|
|
GET_HUD_COLOUR(currentCPColour, iR, iG, iB, iA)
|
|
|
|
IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID())
|
|
FLOAT fDis = GET_DISTANCE_BETWEEN_COORDS(checkpoints[current_position],GET_ENTITY_COORDS(PLAYER_PED_ID()))
|
|
|
|
IF checkpoint != NULL // Make sure the checkpoint exists first
|
|
IF fDis > 100.0
|
|
GET_HUD_COLOUR(HUD_COLOUR_YELLOWLIGHT, iR, iG, iB, iA)
|
|
iA = 240
|
|
SET_CHECKPOINT_RGBA(checkPoint, iR, iG, iB, iA)
|
|
GET_HUD_COLOUR(HUD_COLOUR_NORTH_BLUE, iR, iG, iB, iA)
|
|
iA = 240
|
|
SET_CHECKPOINT_RGBA2(checkPoint, iR, iG, iB, iA)
|
|
ELSE
|
|
GET_HUD_COLOUR(HUD_COLOUR_YELLOWLIGHT, iR, iG, iB, iA)
|
|
iA = ROUND(fDis*2.4)
|
|
IF iA < 60
|
|
iA = 60
|
|
ENDIF
|
|
SET_CHECKPOINT_RGBA(checkPoint, iR, iG, iB, iA)
|
|
GET_HUD_COLOUR(HUD_COLOUR_NORTH_BLUE, iR, iG, iB, iA)
|
|
iA = ROUND(fDis*2.4)
|
|
IF iA < 60
|
|
iA = 60
|
|
ENDIF
|
|
SET_CHECKPOINT_RGBA2(checkPoint, iR, iG, iB, iA)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
return FALSE
|
|
ENDFUNC
|
|
|
|
///// PURPOSE:
|
|
///// Handle the jetski pair at the start of the mission
|
|
//PROC DO_BOATS()
|
|
// SWITCH subState
|
|
// CASE SS_INIT
|
|
// IF NOT boat_launched
|
|
// if IS_ENTITY_ALIVE(jetski1) AND IS_ENTITY_ALIVE(jetski_guy1)
|
|
// IF NOT IS_WAYPOINT_PLAYBACK_GOING_ON_FOR_VEHICLE(jetski1)
|
|
// TASK_VEHICLE_FOLLOW_WAYPOINT_RECORDING(jetski_guy1, jetski1, "Fan3_jetskiRoute", DRIVINGMODE_AVOIDCARS_RECKLESS)
|
|
// ENDIF
|
|
// ENDIF
|
|
// if IS_ENTITY_ALIVE(jetski2) AND IS_ENTITY_ALIVE(jetski_guy2)
|
|
// IF NOT IS_WAYPOINT_PLAYBACK_GOING_ON_FOR_VEHICLE(jetski2)
|
|
// TASK_VEHICLE_FOLLOW_WAYPOINT_RECORDING(jetski_guy2, jetski2, "Fan3_jetskiRoute2", DRIVINGMODE_AVOIDCARS_RECKLESS)
|
|
// ENDIF
|
|
// ENDIF
|
|
// boat_launched = TRUE
|
|
// jetski_conv_launched = FALSE
|
|
// maryann_jetski_conv_launched = FALSE
|
|
// ENDIF
|
|
// BREAK
|
|
// CASE SS_RUNNING
|
|
// if IS_ENTITY_ALIVE(jetski1) AND IS_ENTITY_ALIVE(jetski_guy1)
|
|
// IF NOT IS_WAYPOINT_PLAYBACK_GOING_ON_FOR_VEHICLE(jetski1)
|
|
// DEBUG_PRINTSTRING("Letting go of jetski_guy1")
|
|
// SET_PED_KEEP_TASK(jetski_guy1, true)
|
|
// TASK_VEHICLE_MISSION_COORS_TARGET(jetski_guy1, jetski1, <<-1366.24, 6852.42, 0.82>>, MISSION_FLEE, 200.0, DRIVINGMODE_PLOUGHTHROUGH, -1, -1)
|
|
// SET_ENTITY_LOAD_COLLISION_FLAG(jetski1, FALSE)
|
|
// SAFE_RELEASE_PED(jetski_guy1)
|
|
// SAFE_RELEASE_VEHICLE(jetski1)
|
|
// REMOVE_WAYPOINT_RECORDING("Fan3_jetskiRoute")
|
|
// ENDIF
|
|
// ENDIF
|
|
// if IS_ENTITY_ALIVE(jetski2) AND IS_ENTITY_ALIVE(jetski_guy2)
|
|
// // If this jetski guy gets close to Franklin, have him say a comment
|
|
// IF NOT jetski_conv_launched
|
|
// IF GET_DISTANCE_BETWEEN_ENTITIES(jetski2, PLAYER_PED_ID()) < 13
|
|
// ADD_PED_FOR_DIALOGUE(conv_frank, 6, jetski_guy2, "Fan3_Jetski")
|
|
// IF CREATE_CONVERSATION(conv_frank, "FAN3AUD", "FAN3_JETSKI", CONV_PRIORITY_HIGH)
|
|
// jetski_conv_launched = TRUE
|
|
// TASK_DRIVE_BY(jetski_guy2, PLAYER_PED_ID(), NULL, <<0,0,0>>, 25, 100, TRUE, FIRING_PATTERN_FULL_AUTO)
|
|
// ENDIF
|
|
// ENDIF
|
|
// ENDIF
|
|
// IF NOT IS_WAYPOINT_PLAYBACK_GOING_ON_FOR_VEHICLE(jetski2)
|
|
// DEBUG_PRINTSTRING("Letting go of jetski_guy2")
|
|
// SET_PED_KEEP_TASK(jetski_guy2, true)
|
|
// TASK_VEHICLE_MISSION_COORS_TARGET(jetski_guy2, jetski2, <<-1366.24, 6852.42, 0.82>>, MISSION_FLEE, 200.0, DRIVINGMODE_PLOUGHTHROUGH, -1, -1)
|
|
// SET_ENTITY_LOAD_COLLISION_FLAG(jetski2, FALSE)
|
|
// SAFE_RELEASE_PED(jetski_guy2)
|
|
// SAFE_RELEASE_VEHICLE(jetski2)
|
|
// REMOVE_WAYPOINT_RECORDING("Fan3_jetskiRoute2")
|
|
// ENDIF
|
|
// IF jetski_conv_launched
|
|
// IF maryann_jetski_conv_launched = FALSE
|
|
// IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
// IF CREATE_CONVERSATION(conversation, "FAN3AUD", "FAN3_YELL", CONV_PRIORITY_HIGH)
|
|
// maryann_jetski_conv_launched = TRUE
|
|
// ENDIF
|
|
// ENDIF
|
|
// ENDIF
|
|
// ENDIF
|
|
// ENDIF
|
|
// BREAK
|
|
// ENDSWITCH
|
|
//ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Handle the small conversation about the water being cold as Franklin gets out
|
|
PROC DO_EXIT_SWIM_DIALOGUE()
|
|
// Only try playing this after the 4th checkpoint - when we're waaaaaaayy out in the water and there's no chance of this triggering by mistake
|
|
IF current_position > 4
|
|
IF NOT bDoneSwimDialogue
|
|
IF NOT IS_PED_SWIMMING(PLAYER_PED_ID())
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
IF CREATE_CONVERSATION(conversation, "FAN3AUD", "FAN3_COLD", CONV_PRIORITY_HIGH)
|
|
bDoneSwimDialogue = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Handle the bad driver on the wrong side of the road during the bike section
|
|
PROC DO_BAD_DRIVER()
|
|
if missionStage = MS_BIKE
|
|
if IS_VEHICLE_OK(bad_driver_car)
|
|
AND IS_ENTITY_ALIVE(bad_driver_ped)
|
|
if IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-402.280090,6407.980957,9.086394>>, <<-382.600891,6364.856934,16.762478>>, 5.000000)
|
|
if not bad_driver_launched
|
|
DEBUG_PRINTSTRING("Starting bad driver")
|
|
SET_ENTITY_LOAD_COLLISION_FLAG(bad_driver_car, TRUE)
|
|
ADD_PED_FOR_DIALOGUE(conv_frank, ENUM_TO_INT(CHAR_FRANKLIN), PLAYER_PED_ID(), "FRANKLIN")
|
|
TASK_VEHICLE_FOLLOW_WAYPOINT_RECORDING(bad_driver_ped, bad_driver_car, "Fan3_baddriver", DRIVINGMODE_AVOIDCARS)
|
|
bad_driver_launched = TRUE
|
|
ENDIf
|
|
ELIF bad_driver_launched
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(bad_driver_car, PLAYER_PED_ID()) < 15.0
|
|
START_VEHICLE_HORN(bad_driver_car, 4000)
|
|
ENDIF
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(bad_driver_car, PLAYER_PED_ID()) < 6.0
|
|
DEBUG_PRINTSTRING("Play conversation")
|
|
if NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
CREATE_CONVERSATION(conv_frank, "FAN3AUD", "FAN3_SHOUT", CONV_PRIORITY_MEDIUM)
|
|
ENDIF
|
|
ENDIF
|
|
IF NOT IS_WAYPOINT_PLAYBACK_GOING_ON_FOR_VEHICLE(bad_driver_car)
|
|
DEBUG_PRINTSTRING("bad_driver_car no longer needed")
|
|
SET_ENTITY_LOAD_COLLISION_FLAG(bad_driver_car, FALSE)
|
|
SET_ENTITY_SHOULD_FREEZE_WAITING_ON_COLLISION(bad_driver_car, TRUE)
|
|
SAFE_RELEASE_VEHICLE(bad_driver_car)
|
|
bad_driver_launched = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
PROC START_CONVERSATION()
|
|
IF NOT IS_MESSAGE_BEING_DISPLAYED() // Only do conversation if no god text is being displayed
|
|
OR GET_PROFILE_SETTING(PROFILE_DISPLAY_SUBTITLES) = 0
|
|
INT rand
|
|
// There's only two conversations we can use in the swimming section, so do this
|
|
IF missionStage = MS_SWIM
|
|
rand = GET_RANDOM_INT_IN_RANGE(0, MAX_SMACK_TALK-1)
|
|
ELSE
|
|
rand = GET_RANDOM_INT_IN_RANGE(0, MAX_SMACK_TALK)
|
|
ENDIF
|
|
INT mission_offset = GET_OFFSET_FROM_MISSION_STAGE(missionStage)
|
|
IF NOT (mission_offset = -1)
|
|
if won_last_stage = TRUE
|
|
mission_offset++
|
|
// 0 = currently swimming
|
|
// 1 = currently cycling, lost swimming
|
|
// 2 = currently cycling, won swimming
|
|
// 3 = currently running, lost cycling
|
|
// 4 = currently running, won cycling
|
|
ENDIF
|
|
IF (smack[mission_offset][rand].already_said = FALSE)
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
ADD_PED_FOR_DIALOGUE(conversation, ENUM_TO_INT(CHAR_FRANKLIN), PLAYER_PED_ID(), "FRANKLIN")
|
|
ENDIF
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
ADD_PED_FOR_DIALOGUE(conversation, 3, opponent, "MARYANN")
|
|
ENDIF
|
|
CREATE_CONVERSATION(conversation, "FAN3AUD", smack[mission_offset][rand].ConvRoot, CONV_PRIORITY_MEDIUM)
|
|
smack[mission_offset][rand].already_said = TRUE
|
|
bTrashTalkActive = TRUE
|
|
iTrashTalkTimer = GET_GAME_TIMER()
|
|
DEBUG_PRINTSTRING("*** CREATING TRASH TALK")
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
DEBUG_PRINTSTRING("*** Trying to start trash talk, but god text is preventing it")
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Handle the trash talk conversations between Franklin and Mary Ann during the race, including pausing in-progress convos for distance
|
|
PROC PROCESS_CONVERSATION()
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
IF bTrashTalkActive
|
|
bTrashTalkActive = FALSE
|
|
ENDIF
|
|
IF (GET_GAME_TIMER() - iTrashTalkTimer) > 13000
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), opponent) < 30
|
|
AND (opponentStage = missionStage) //Make sure we are both on the same stage, as it makes more sense.
|
|
IF missionStage = MS_SWIM
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
// If we're in the swimming bit, make sure both Mary Ann and Franklin are swimming before trying to do trash talk
|
|
// The dialogue's written as if they're both in the water, so if one of them isn't, it'd sound weeeiird
|
|
IF IS_PED_SWIMMING(opponent)
|
|
AND IS_PED_SWIMMING(PLAYER_PED_ID())
|
|
START_CONVERSATION()
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
START_CONVERSATION()
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
IF NOT bConvoPaused
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), opponent) > 40
|
|
AND NOT bad_driver_launched
|
|
AND bTrashTalkActive
|
|
PAUSE_SCRIPTED_CONVERSATION(TRUE)
|
|
DEBUG_PRINTSTRING("*** PAUSING TRASH TALK")
|
|
bConvoPaused = TRUE
|
|
ENDIF
|
|
ELSE
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), opponent) < 30
|
|
RESTART_SCRIPTED_CONVERSATION()
|
|
DEBUG_PRINTSTRING("*** RESTARTING TRASH TALK")
|
|
bConvoPaused = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Check whether the given model is a bike
|
|
/// PARAMS:
|
|
/// model - The model we're checking
|
|
/// RETURNS:
|
|
/// TRUE if the model is a bike, false otherwise
|
|
FUNC BOOL IS_MODEL_VALID_BIKE(MODEL_NAMES model)
|
|
IF model = BMX OR model = scorcher OR model = scorcher OR model = CRUISER
|
|
return TRUE
|
|
ENDIF
|
|
return FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Check for the player cheating during the mission by getting in a car or something
|
|
PROC CHECK_PLAYER_CHEATING()
|
|
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
|
|
VEHICLE_INDEX player_vehicle = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID())
|
|
IF (missionStage = MS_TO_BIKE) OR (missionStage = MS_BIKE) OR (missionStage = MS_OFF_BIKE)
|
|
//Check that we aren't on another bike.
|
|
IF IS_MODEL_VALID_BIKE(GET_ENTITY_MODEL(player_vehicle))
|
|
EXIT
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// To match the proper triathlon minigame/activity, we just force the player out of the vehicle instead of doing the cheat detection stuff
|
|
// I'm adding a little bit of dialogue for colour though
|
|
|
|
IF missionStage <> MS_FAILED
|
|
IF NOT IS_MODEL_VALID_BIKE(GET_ENTITY_MODEL(player_vehicle))
|
|
IF IS_ENTITY_ALIVE(opponent) AND IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
AND NOT IS_PED_GETTING_INTO_A_VEHICLE(PLAYER_PED_ID()) // Only start playing after Franklin has finished getting into the vehicle
|
|
IF GET_DISTANCE_BETWEEN_PEDS(PLAYER_PED_ID(), opponent) < 20
|
|
CREATE_CONVERSATION(conversation, "FAN3AUD", "FAN3_CHEAT2", CONV_PRIORITY_HIGH)
|
|
ELSE
|
|
CREATE_CONVERSATION(conversation, "FAN3AUD", "FAN3_CHEAT1", CONV_PRIORITY_HIGH)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
TASK_LEAVE_ANY_VEHICLE(PLAYER_PED_ID())
|
|
DEBUG_PRINTSTRING("Telling player to leave any vehicle...")
|
|
ENDIF
|
|
|
|
// Going to keep the Pauls old code that fails the mission anyway though. Just in case.
|
|
// JUST IN CASE.
|
|
// IF cheated_on_vehicle = NOT_CHEATED
|
|
// IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
// KILL_ANY_CONVERSATION()
|
|
// ENDIF
|
|
// SETTIMERA(0)
|
|
// MODEL_NAMES vehicle_model
|
|
// vehicle_model = GET_ENTITY_MODEL(player_vehicle)
|
|
// IF IS_MODEL_VALID_BIKE(vehicle_model)
|
|
// PRINT_NOW("FATIC3_4", DEFAULT_GOD_TEXT_TIME, 1)
|
|
// ELSE
|
|
// PRINT_NOW("FATIC3_5", DEFAULT_GOD_TEXT_TIME, 1)
|
|
// ENDIF
|
|
// cheated_on_vehicle = IN_CHEATING_VEHICLE
|
|
// ELIF cheated_on_vehicle = IN_CHEATING_VEHICLE
|
|
// IF TIMERA() > 5000
|
|
// IF IS_PED_SITTING_IN_ANY_VEHICLE(PLAYER_PED_ID())
|
|
// //You didn't get off the vehicle.
|
|
// cheated_on_vehicle = CHEATED_TOO_MUCH
|
|
// IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
// KILL_ANY_CONVERSATION()
|
|
// ENDIF
|
|
// PRINT_NOW("FATIC3_9", DEFAULT_GOD_TEXT_TIME, 1)
|
|
// MISSION_FAILED()
|
|
// ENDIF
|
|
// ENDIF
|
|
// ELIF cheated_on_vehicle = CHEATED
|
|
// IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
// KILL_ANY_CONVERSATION()
|
|
// ENDIF
|
|
// //You got back on after getting off a vehicle. YOU WERE WARNED!!!!
|
|
// cheated_on_vehicle = CHEATED_TOO_MUCH
|
|
// PRINT_NOW("FATIC3_9", DEFAULT_GOD_TEXT_TIME, 1)
|
|
// MISSION_FAILED()
|
|
// ENDIF
|
|
//
|
|
// ELSE
|
|
// IF cheated_on_vehicle = IN_CHEATING_VEHICLE
|
|
// CLEAR_PRINTS()
|
|
// cheated_on_vehicle = CHEATED
|
|
// ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Check the both bikes are alive and fail the mission if either are destroyed when they're needed
|
|
PROC CHECK_BIKES_ALIVE()
|
|
IF NOT IS_ENTITY_ALIVE(bike_vehicle) OR NOT IS_ENTITY_ALIVE(opponent_bike_vehicle)
|
|
//PRINT_NOW("FATIC3_11", 7500, 0) //One of the bikes was wrecked.
|
|
IF opponentStage >= MS_BIKE
|
|
MISSION_FAILED(FAILED_YOURBIKE_DESTROYED)
|
|
ELSE
|
|
MISSION_FAILED(FAILED_BIKE_DESTROYED)
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Make sure the player is within the currently-defined TEST_POLY area
|
|
/// Reminder: the TEST_POLY area is cleared and redefined at the start of each race stage because the mission area is so goddamn huge
|
|
PROC CHECK_PLAYER_IN_MISSION_AREA()
|
|
|
|
IF NOT IS_POINT_IN_POLY_2D(innerBounds, GET_ENTITY_COORDS(PLAYER_PED_ID()))
|
|
if bAbandonmentWarning
|
|
IF (GET_GAME_TIMER() - iStopTime) > 10000
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
|
|
ENDIF
|
|
//PRINT_NOW("FATIC3_14", DEFAULT_GOD_TEXT_TIME, 1) // You wandered too far from the race
|
|
bAbandonmentWarning = false
|
|
MISSION_FAILED(FAILED_LEFT_AREA)
|
|
ENDIF
|
|
ELSE
|
|
PRINT_NOW("FATIC3_15", 5000, 1) //Return to the ~y~race.
|
|
iStopTime = GET_GAME_TIMER()
|
|
bAbandonmentWarning = TRUE
|
|
ENDIF
|
|
EXIT
|
|
ELSE
|
|
if bAbandonmentWarning
|
|
iStopTime = 0
|
|
CLEAR_THIS_PRINT("FATIC3_15")
|
|
bAbandonmentWarning = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Skip to the mission intro cutscene
|
|
PROC SKIP_TO_INTRO()
|
|
REMOVE_BLIP_IF_EXISTS()
|
|
REMOVE_CHECKPOINT_IF_EXISTS()
|
|
|
|
missionStage = MS_INTRO
|
|
subState = SS_INIT
|
|
|
|
DEBUG_PRINTSTRING("Skipping to intro")
|
|
|
|
current_opponent_position = 0
|
|
current_position = 0
|
|
current_max_positions = MAX_SWIM_POSITIONS
|
|
current_opponent_max_positions = MAX_SWIM_POSITIONS
|
|
|
|
TRIGGER_MUSIC_EVENT("FANATIC2_STOP")
|
|
|
|
iCutsceneStage = 0
|
|
intro_requested = FALSE
|
|
intro_playing = FALSE
|
|
bCheatReload = FALSE // Just in case
|
|
bDoMAIntroBoost = FALSE
|
|
iMAIntroBoostTimer = -1
|
|
|
|
SET_ENTITY_COORDS(PLAYER_PED_ID(), << -909.0488, 6142.6167, 4.2883 >>)
|
|
ma_pSkip()
|
|
|
|
RC_END_Z_SKIP()
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Skip to the start of the swim section
|
|
proc SKIP_TO_SWIM()
|
|
IF IS_CUTSCENE_ACTIVE()
|
|
STOP_CUTSCENE()
|
|
ENDIF
|
|
start_time = GET_GAME_TIMER() // Reset the race timer
|
|
REMOVE_BLIP_IF_EXISTS()
|
|
REMOVE_CHECKPOINT_IF_EXISTS()
|
|
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
SET_ENTITY_COORDS(opponent, <<-903.2273, 6142.6387, 4.1911>>, TRUE, TRUE)
|
|
SET_ENTITY_HEADING(opponent, 264.8848)
|
|
ENDIF
|
|
|
|
IF NOT IS_REPLAY_BEING_SET_UP()
|
|
SET_ENTITY_COORDS(PLAYER_PED_ID(), vSwimSkip)
|
|
SET_ENTITY_HEADING(PLAYER_PED_ID(), fSwimSkip)
|
|
WAIT_FOR_WORLD_TO_LOAD(GET_ENTITY_COORDS(PLAYER_PED_ID()))
|
|
ENDIF
|
|
|
|
TRIGGER_MUSIC_EVENT("FANATIC3_RESTART1")
|
|
|
|
DEBUG_PRINTSTRING("Skipping to swim")
|
|
|
|
missionStage = MS_SWIM
|
|
subState = SS_INIT
|
|
|
|
current_opponent_position = 0
|
|
current_position = 0
|
|
current_max_positions = MAX_SWIM_POSITIONS
|
|
current_opponent_max_positions = MAX_SWIM_POSITIONS
|
|
bZSkipActive = FALSE
|
|
bCheatReload = FALSE // Just in case
|
|
race_won = FALSE
|
|
bLoadedBike = FALSE
|
|
bLoadedRun = FALSE
|
|
bDoMAIntroBoost = TRUE
|
|
iMAIntroBoostTimer = GET_GAME_TIMER()
|
|
|
|
m_pUnloadJog()
|
|
m_pUnloadBike()
|
|
m_pLoadSwim()
|
|
m_pResetBikes()
|
|
ma_pSkip()
|
|
IF IS_REPLAY_BEING_SET_UP()
|
|
END_REPLAY_SETUP()
|
|
SIMULATE_PLAYER_INPUT_GAIT(PLAYER_ID(), PEDMOVEBLENDRATIO_RUN, 4000)
|
|
WAIT(500)
|
|
ENDIF
|
|
RC_END_Z_SKIP()
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Skip to the start of the bike section
|
|
PROC SKIP_TO_BIKE()
|
|
IF NOT IS_REPLAY_BEING_SET_UP()
|
|
SET_ENTITY_COORDS(PLAYER_PED_ID(), vBikeSkip)
|
|
SET_ENTITY_HEADING(PLAYER_PED_ID(), fBikeSkip)
|
|
WAIT_FOR_WORLD_TO_LOAD(GET_ENTITY_COORDS(PLAYER_PED_ID()))
|
|
ENDIF
|
|
|
|
TRIGGER_MUSIC_EVENT("FANATIC3_RESTART2")
|
|
|
|
start_time = GET_GAME_TIMER() // Reset the race timer
|
|
fPriorSpeed = 0.0 // Reset Mary Ann's speed boost value
|
|
|
|
IF NOT IS_REPLAY_BEING_SET_UP()
|
|
FORCE_PED_MOTION_STATE(PLAYER_PED_ID(), MS_ON_FOOT_RUN, FALSE, FAUS_DEFAULT)
|
|
SIMULATE_PLAYER_INPUT_GAIT(PLAYER_ID(), 2.0, 1200)
|
|
ENDIF
|
|
|
|
REMOVE_BLIP_IF_EXISTS()
|
|
REMOVE_CHECKPOINT_IF_EXISTS()
|
|
blip = CREATE_VEHICLE_BLIP(bike_vehicle)
|
|
|
|
missionStage = MS_TO_BIKE
|
|
subState = SS_INIT
|
|
|
|
opponent_goto_bike = opponent_bike_vehicle
|
|
current_position = 0
|
|
current_max_positions = MAX_BIKE_POSITIONS
|
|
|
|
IF NOT IS_ENTITY_ALIVE(bike_vehicle) OR NOT IS_ENTITY_ALIVE(opponent_bike_vehicle)
|
|
SCRIPT_ASSERT("No bike.")
|
|
ENDIF
|
|
|
|
bCheatReload = FALSE // Just in case
|
|
bGivePushWarning = FALSE
|
|
bLoadedBike = FALSE
|
|
bLoadedRun = FALSE
|
|
race_won = FALSE
|
|
iPushTime = 0
|
|
iPushStage = 0
|
|
bDoMAIntroBoost = FALSE
|
|
iMAIntroBoostTimer = -1
|
|
|
|
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_BIKE, "Bike section")
|
|
//g_replay.iReplayInt[F3_CHECKPOINT_TIME] = race_timer
|
|
|
|
m_pUnloadSwim()
|
|
m_pUnloadJog()
|
|
WHILE NOT m_pLoadBike()
|
|
WAIT(0)
|
|
bLoadedBike = TRUE
|
|
ENDWHILE
|
|
m_pResetBikes()
|
|
|
|
ma_pSkip()
|
|
|
|
IF IS_REPLAY_BEING_SET_UP()
|
|
END_REPLAY_SETUP()
|
|
SIMULATE_PLAYER_INPUT_GAIT(PLAYER_ID(), 2.0, 1200)
|
|
FORCE_PED_MOTION_STATE(PLAYER_PED_ID(), MS_ON_FOOT_RUN, FALSE, FAUS_DEFAULT)
|
|
wait(1000)
|
|
ENDIF
|
|
|
|
RC_END_Z_SKIP()
|
|
|
|
CLEAR_PRINTS()
|
|
PRINT_NOW("FATIC3_2", DEFAULT_GOD_TEXT_TIME, 1) //Get on a ~b~bike.
|
|
|
|
//SET_STUNT_JUMPS_CAN_TRIGGER(FALSE)
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Skip to the start of the running section
|
|
PROC SKIP_TO_RUN()
|
|
REMOVE_BLIP_IF_EXISTS()
|
|
REMOVE_CHECKPOINT_IF_EXISTS()
|
|
|
|
IF NOT IS_REPLAY_BEING_SET_UP()
|
|
SET_ENTITY_COORDS(PLAYER_PED_ID(), vJogSkip)
|
|
SET_ENTITY_HEADING(PLAYER_PED_ID(), fJogSkip)
|
|
WAIT_FOR_WORLD_TO_LOAD(GET_ENTITY_COORDS(PLAYER_PED_ID()))
|
|
ENDIF
|
|
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
CLEAR_PED_TASKS_IMMEDIATELY(opponent)
|
|
DEBUG_PRINTSTRING("*** Clearing Mary Ann tasks (Run skip)")
|
|
ENDIF
|
|
|
|
TRIGGER_MUSIC_EVENT("FANATIC3_RESTART3")
|
|
|
|
start_time = GET_GAME_TIMER() // Reset the race timer
|
|
|
|
IF NOT IS_REPLAY_BEING_SET_UP()
|
|
FORCE_PED_MOTION_STATE(PLAYER_PED_ID(), MS_ON_FOOT_RUN, FALSE, FAUS_DEFAULT)
|
|
SIMULATE_PLAYER_INPUT_GAIT(PLAYER_ID(), 2.0, 2000)
|
|
ENDIF
|
|
|
|
missionStage = MS_OFF_BIKE
|
|
subState = SS_INIT
|
|
|
|
bCheatReload = FALSE // Just in case
|
|
race_won = FALSE
|
|
|
|
current_position = 0
|
|
current_max_positions = MAX_RUN_POSITIONS
|
|
|
|
m_pResetBikes() // Reset the bikes so I can safely reference them now...
|
|
// The bikes up behind the starting position so they're present if we retry from this point
|
|
IF IS_VEHICLE_OK(bike_vehicle)
|
|
SET_ENTITY_COORDS(bike_vehicle, <<49.016113,6771.453125,20.055803>>)
|
|
SET_ENTITY_HEADING(bike_vehicle, -62.490368)
|
|
ENDIF
|
|
IF IS_VEHICLE_OK(opponent_bike_vehicle)
|
|
SET_ENTITY_COORDS(opponent_bike_vehicle, <<52.37, 6767.48, 20.66>>)
|
|
SET_ENTITY_HEADING(opponent_bike_vehicle, 312.42)
|
|
ENDIF
|
|
|
|
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_JOG, "Jog section", TRUE)
|
|
//g_replay.iReplayInt[F3_CHECKPOINT_TIME] = race_timer
|
|
|
|
bDoMAIntroBoost = FALSE
|
|
iMAIntroBoostTimer = -1
|
|
|
|
m_pUnloadBike()
|
|
m_pUnloadJog()
|
|
WHILE NOT m_pLoadJog()
|
|
OR NOT ma_pLoadJogRecs()
|
|
WAIT(0)
|
|
ENDWHILE
|
|
|
|
bSkipped = FALSE
|
|
|
|
ma_pSkip()
|
|
|
|
IF IS_REPLAY_BEING_SET_UP()
|
|
END_REPLAY_SETUP()
|
|
FORCE_PED_MOTION_STATE(PLAYER_PED_ID(), MS_ON_FOOT_RUN, FALSE, FAUS_DEFAULT)
|
|
SIMULATE_PLAYER_INPUT_GAIT(PLAYER_ID(), 2.0, 2000)
|
|
WAIT(1000)
|
|
ENDIF
|
|
|
|
RC_END_Z_SKIP()
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Skip to the outro sequence
|
|
PROC SKIP_TO_OUTRO()
|
|
REMOVE_BLIP_IF_EXISTS()
|
|
REMOVE_CHECKPOINT_IF_EXISTS()
|
|
CLEAR_PRINTS()
|
|
|
|
TRIGGER_MUSIC_EVENT("FANATIC2_STOP")
|
|
|
|
iOutroStage = 0
|
|
missionStage = MS_DONE
|
|
|
|
bCheatReload = FALSE // Just in case
|
|
|
|
WHILE NOT m_pLoadJog()
|
|
WAIT(0)
|
|
ENDWHILE
|
|
|
|
intro_playing = FALSE
|
|
bSkipped = FALSE
|
|
|
|
ma_pSkip()
|
|
|
|
IF IS_REPLAY_BEING_SET_UP()
|
|
END_REPLAY_SETUP()
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Skip one stage forwards in the race
|
|
PROC SKIP_FORWARD()
|
|
IF ENUM_TO_INT(missionStage) < ENUM_TO_INT(MS_SWIM)
|
|
SKIP_TO_SWIM()
|
|
ELIF ENUM_TO_INT(missionStage) < ENUM_TO_INT(MS_TO_BIKE)
|
|
SKIP_TO_BIKE()
|
|
ELIF ENUM_TO_INT(missionStage) < ENUM_TO_INT(MS_OFF_BIKE)
|
|
SKIP_TO_RUN()
|
|
ELSE
|
|
DEBUG_PRINTSTRING("Skipping to outro")
|
|
SKIP_TO_OUTRO()
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Skip one stage back in the race
|
|
PROC SKIP_BACK()
|
|
IF ENUM_TO_INT(missionStage) = ENUM_TO_INT(MS_DONE)
|
|
RENDER_SCRIPT_CAMS(FALSE, FALSE, 0)
|
|
CLEAR_PED_TASKS(PLAYER_PED_ID())
|
|
TASK_CLEAR_LOOK_AT(PLAYER_PED_ID())
|
|
REMOVE_ANIM_DICT("rcmfanatic1out_of_breath")
|
|
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0)
|
|
RC_END_CUTSCENE_MODE()
|
|
SAFE_FADE_SCREEN_IN_FROM_BLACK()
|
|
SKIP_TO_RUN()
|
|
DEBUG_PRINTSTRING("Skipping to run")
|
|
ELIF ENUM_TO_INT(missionStage) = ENUM_TO_INT(MS_RUN)
|
|
OR ENUM_TO_INT(missionStage) = ENUM_TO_INT(MS_OFF_BIKE)
|
|
SKIP_TO_BIKE()
|
|
ELIF ENUM_TO_INT(missionStage) = ENUM_TO_INT(MS_BIKE)
|
|
OR ENUM_TO_INT(missionStage) = ENUM_TO_INT(MS_TO_BIKE)
|
|
SKIP_TO_SWIM()
|
|
ELIF ENUM_TO_INT(missionStage) = ENUM_TO_INT(MS_SWIM)
|
|
SKIP_TO_INTRO()
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Jump to a specific, given stage in the mission
|
|
/// PARAMS:
|
|
/// iNewStage - The stage int we want to jump to
|
|
/// bRepeatPlaySkip - Are we skipping for a repeat play (we usually aren't)
|
|
PROC JUMP_TO_STAGE(int iNewStage, BOOL bRepeatPlaySkip = FALSE)
|
|
IF missionStage = MS_DONE
|
|
RENDER_SCRIPT_CAMS(FALSE, FALSE, 0)
|
|
CLEAR_PED_TASKS(PLAYER_PED_ID())
|
|
TASK_CLEAR_LOOK_AT(PLAYER_PED_ID())
|
|
REMOVE_ANIM_DICT("rcmfanatic1out_of_breath")
|
|
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0)
|
|
RC_END_CUTSCENE_MODE()
|
|
SAFE_FADE_SCREEN_IN_FROM_BLACK()
|
|
ENDIF
|
|
|
|
RESET_PLAYER_STAMINA(PLAYER_ID())
|
|
|
|
// If we're immediately skipping to a stage for a replay, don't call the Z skip function again, otherwise the screen will flicker
|
|
IF bRepeatPlaySkip = FALSE
|
|
RC_START_Z_SKIP()
|
|
ENDIF
|
|
|
|
bSkipped = true
|
|
|
|
IF iNewStage = 0
|
|
IF IS_AUDIO_SCENE_ACTIVE("FANATIC_MIX_SCENE")
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
REMOVE_ENTITY_FROM_AUDIO_MIX_GROUP(opponent)
|
|
ENDIF
|
|
STOP_AUDIO_SCENE("FANATIC_MIX_SCENE")
|
|
ENDIF
|
|
ELSE
|
|
IF NOT IS_AUDIO_SCENE_ACTIVE("FANATIC_MIX_SCENE")
|
|
START_AUDIO_SCENE("FANATIC_MIX_SCENE")
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
ADD_ENTITY_TO_AUDIO_MIX_GROUP(opponent,"FANATIC_MIX_MARY_ANNE")
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
|
|
IF iNewStage = 0
|
|
SKIP_TO_INTRO()
|
|
ELIF iNewStage = 1
|
|
WAIT_FOR_CUTSCENE_TO_STOP()
|
|
SKIP_TO_SWIM()
|
|
ELIF iNewStage = 2
|
|
WAIT_FOR_CUTSCENE_TO_STOP()
|
|
SKIP_TO_BIKE()
|
|
ELIF iNewStage = 3
|
|
WAIT_FOR_CUTSCENE_TO_STOP()
|
|
SKIP_TO_RUN()
|
|
ELIF iNewStage = 4
|
|
WAIT_FOR_CUTSCENE_TO_STOP()
|
|
SKIP_TO_OUTRO()
|
|
ENDIF
|
|
//WAIT(500)
|
|
ENDPROC
|
|
|
|
PROC m_pLeadIn()
|
|
|
|
// Disable controls and exit current vehicle
|
|
RC_PLAYER_TRIGGER_SCENE_LOCK_IN()
|
|
|
|
INT iReplayStage
|
|
SWITCH subState
|
|
|
|
CASE SS_INIT
|
|
|
|
DEBUG_PRINTSTRING("Doing leadin init")
|
|
|
|
IF Is_Replay_In_Progress()
|
|
AND NOT bSkipped
|
|
DEBUG_PRINTSTRING("Replay in progress - skipping leadin & cutscene and jumping to checkpointed stage...")
|
|
m_pInitialiseRace()
|
|
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
FREEZE_ENTITY_POSITION(opponent, FALSE)
|
|
ENDIF
|
|
|
|
iReplayStage = Get_Replay_Mid_Mission_Stage()
|
|
|
|
DEBUG_PRINTSTRINGINT("ReplayStage: ", iReplayStage)
|
|
|
|
IF g_bShitskipAccepted = TRUE
|
|
iReplayStage++ // player is skipping this stage
|
|
DEBUG_PRINTSTRINGINT("ReplayStage after shitskip: ", iReplayStage)
|
|
ENDIF
|
|
|
|
SWITCH iReplayStage
|
|
CASE CP_SWIM
|
|
IF Is_Replay_In_Progress()
|
|
START_REPLAY_SETUP(vSwimSkip, fSwimSkip)
|
|
ENDIF
|
|
JUMP_TO_STAGE(1, TRUE)
|
|
BREAK
|
|
CASE CP_BIKE
|
|
IF Is_Replay_In_Progress()
|
|
START_REPLAY_SETUP(vBikeSkip, fBikeSkip)
|
|
ENDIF
|
|
JUMP_TO_STAGE(2, TRUE)
|
|
BREAK
|
|
CASE CP_JOG
|
|
IF Is_Replay_In_Progress()
|
|
START_REPLAY_SETUP(vJogSkip, fJogSkip)
|
|
ENDIF
|
|
JUMP_TO_STAGE(3, TRUE)
|
|
BREAK
|
|
CASE CP_OUTRO
|
|
IF Is_Replay_In_Progress()
|
|
START_REPLAY_SETUP(vOutroSkip, fOutroSkip)
|
|
ENDIF
|
|
JUMP_TO_STAGE(4, TRUE)
|
|
BREAK
|
|
DEFAULT
|
|
SCRIPT_ASSERT("Replay in progress: Unknown checkpoint selected?")
|
|
BREAK
|
|
ENDSWITCH
|
|
ELIF IS_REPEAT_PLAY_ACTIVE()
|
|
DEBUG_PRINTSTRING("Skipping leadin because repeat play is active")
|
|
subState = SS_CLEANUP
|
|
ENDIF
|
|
|
|
REQUEST_ANIM_DICT("rcmfanatic3")
|
|
|
|
ADD_PED_FOR_DIALOGUE(conversation, ENUM_TO_INT(CHAR_FRANKLIN), PLAYER_PED_ID(), "FRANKLIN")
|
|
ADD_PED_FOR_DIALOGUE(conversation, 3, opponent, "MARYANN")
|
|
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), opponent) <= 1.5
|
|
// Kill the leadin convo early if it's started
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
|
|
ENDIF
|
|
DEBUG_PRINTSTRING("Player too close to Mary Ann, starting cutscene early")
|
|
subState = SS_CLEANUP
|
|
ENDIF
|
|
IF HAS_ANIM_DICT_LOADED("rcmfanatic3")
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
IF IS_ENTITY_PLAYING_ANIM(opponent, "rcmfanatic3", "ef_3_rcm_loop_maryann")
|
|
IF GET_ENTITY_ANIM_CURRENT_TIME(opponent, "rcmfanatic3", "ef_3_rcm_loop_maryann") <0.1
|
|
TASK_PLAY_ANIM(opponent, "rcmfanatic3", "ef_3_rcm_action_maryann", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_HOLD_LAST_FRAME)
|
|
FREEZE_ENTITY_POSITION(opponent, FALSE)
|
|
REMOVE_CUTSCENE()
|
|
REQUEST_CUTSCENE_WITH_PLAYBACK_LIST("EF_3_RCM_CONCAT", CS_SECTION_2) // Request the concatinated version of the cutscene for the leadin instead
|
|
intro_requested = TRUE // Don't try to request the cutscene anymore
|
|
IF NOT IS_GAMEPLAY_HINT_ACTIVE()
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
SET_GAMEPLAY_ENTITY_HINT(opponent, <<0,0,-0.5>>, TRUE, 30000)
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), opponent) <= 7.0
|
|
DEBUG_PRINTSTRING("Using FOV 40 instead")
|
|
fHintFov = 40
|
|
ENDIF
|
|
SET_GAMEPLAY_HINT_FOV(fHintFov)
|
|
SET_GAMEPLAY_HINT_FOLLOW_DISTANCE_SCALAR(fHintFollow)
|
|
SET_GAMEPLAY_HINT_BASE_ORBIT_PITCH_OFFSET(fHintPitchOrbit)
|
|
SET_GAMEPLAY_HINT_CAMERA_RELATIVE_SIDE_OFFSET(fHintSide)
|
|
SET_GAMEPLAY_HINT_CAMERA_RELATIVE_VERTICAL_OFFSET(fHintVert)
|
|
SET_GAMEPLAY_HINT_CAMERA_BLEND_TO_FOLLOW_PED_MEDIUM_VIEW_MODE(TRUE)
|
|
ENDIF
|
|
ELSE
|
|
STOP_GAMEPLAY_HINT_BEING_CANCELLED_THIS_UPDATE(TRUE)
|
|
ENDIF
|
|
SET_SCRIPTS_SAFE_FOR_CUTSCENE(TRUE,DEFAULT,FALSE)
|
|
DEBUG_PRINTSTRING("Done Mary Ann leadin anim")
|
|
subState = SS_RUNNING
|
|
ENDIF
|
|
ELSE
|
|
//Fix for B*2185316, was changing subState to SS_CLEANUP here when retrying mission then going into MS_SWIM and immediately cleaning up
|
|
IF missionStage = MS_LEADIN
|
|
DEBUG_PRINTSTRING("Mary Ann not in leadin loop, starting cutscene early")
|
|
subState = SS_CLEANUP
|
|
ELSE
|
|
DEBUG_PRINTSTRING("Mary Ann not in leadin loop, but not in leadin stage, not doing anything!")
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE SS_RUNNING
|
|
IF IS_PED_UNINJURED(opponent)
|
|
IF IS_ENTITY_PLAYING_ANIM(opponent, "rcmfanatic3", "ef_3_rcm_action_maryann")
|
|
IF NOT bLeadInConv
|
|
IF GET_ENTITY_ANIM_CURRENT_TIME(opponent, "rcmfanatic3", "ef_3_rcm_action_maryann") > 0.17
|
|
IF CREATE_CONVERSATION(conversation, "FAN3AUD", "FAN3_LDI", CONV_PRIORITY_HIGH)
|
|
bLeadInConv = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
IF NOT IS_GAMEPLAY_HINT_ACTIVE()
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
SET_GAMEPLAY_ENTITY_HINT(opponent, <<0,0,-0.5>>, TRUE, 30000)
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), opponent) <= 7.0
|
|
DEBUG_PRINTSTRING("Using FOV 40 instead")
|
|
fHintFov = 40
|
|
ENDIF
|
|
SET_GAMEPLAY_HINT_FOV(fHintFov)
|
|
SET_GAMEPLAY_HINT_FOLLOW_DISTANCE_SCALAR(fHintFollow)
|
|
SET_GAMEPLAY_HINT_BASE_ORBIT_PITCH_OFFSET(fHintPitchOrbit)
|
|
SET_GAMEPLAY_HINT_CAMERA_RELATIVE_SIDE_OFFSET(fHintSide)
|
|
SET_GAMEPLAY_HINT_CAMERA_RELATIVE_VERTICAL_OFFSET(fHintVert)
|
|
SET_GAMEPLAY_HINT_CAMERA_BLEND_TO_FOLLOW_PED_MEDIUM_VIEW_MODE(TRUE)
|
|
ENDIF
|
|
ELSE
|
|
STOP_GAMEPLAY_HINT_BEING_CANCELLED_THIS_UPDATE(TRUE)
|
|
ENDIF
|
|
IF GET_ENTITY_ANIM_CURRENT_TIME(opponent, "rcmfanatic3", "ef_3_rcm_action_maryann") > 0.90
|
|
FREEZE_ENTITY_POSITION(opponent, FALSE)
|
|
DEBUG_PRINTSTRING("Mary Ann leadin anim over")
|
|
subState = SS_CLEANUP
|
|
ENDIF
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), opponent) <= 2.5
|
|
// Kill the leadin convo early if it's started
|
|
TASK_TURN_PED_TO_FACE_ENTITY(PLAYER_PED_ID(), opponent)
|
|
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE)
|
|
DEBUG_PRINTSTRING("Player too close to Mary Ann, starting cutscene early")
|
|
ENDIF
|
|
ELSE
|
|
DEBUG_PRINTSTRING("Mary Ann not playing leadin anim anymore - skip to cutscene for safety")
|
|
subState = SS_CLEANUP
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE SS_CLEANUP
|
|
DEBUG_PRINTSTRING("Doing leadin cleanup")
|
|
subState = SS_INIT
|
|
missionStage = MS_INTRO
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
FUNC BOOL DO_FRANKLIN_EXIT()
|
|
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Franklin")
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
FORCE_PED_MOTION_STATE(PLAYER_PED_ID(), MS_ON_FOOT_RUN, FALSE, FAUS_CUTSCENE_EXIT)
|
|
SIMULATE_PLAYER_INPUT_GAIT(PLAYER_ID(), PEDMOVEBLENDRATIO_RUN, 5000)
|
|
DEBUG_PRINTSTRING("*** Forcing player's move state")
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
PROC DO_MARY_ANN_EXIT()
|
|
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Mary_Ann", IG_MARYANN)
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
//FORCE_PED_AI_AND_ANIMATION_UPDATE(opponent)
|
|
SET_PED_MIN_MOVE_BLEND_RATIO(opponent, 3.0)
|
|
FORCE_PED_MOTION_STATE(opponent, MS_ON_FOOT_SPRINT, FALSE, FAUS_CUTSCENE_EXIT)
|
|
TASK_GO_STRAIGHT_TO_COORD(opponent, (SWIM_POSITIONS[0]), PEDMOVE_RUN, DEFAULT_TIME_BEFORE_WARP)
|
|
iMAIntroBoostTimer = GET_GAME_TIMER()
|
|
bDoMAIntroBoost = TRUE
|
|
DEBUG_PRINTSTRING("*** Forcing opponent's move state")
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Main mission process for the initial cutscene stage
|
|
PROC INIT_MISSION()
|
|
|
|
bike_model = scorcher
|
|
|
|
IF Is_Replay_In_Progress()
|
|
AND NOT bSkipped
|
|
DEBUG_PRINTSTRING("Replay in progress - skipping cutscene and jumping to checkpointed stage...")
|
|
m_pInitialiseRace()
|
|
|
|
INT iReplayStage = Get_Replay_Mid_Mission_Stage()
|
|
|
|
DEBUG_PRINTSTRINGINT("ReplayStage: ", iReplayStage)
|
|
|
|
IF g_bShitskipAccepted = TRUE
|
|
iReplayStage++ // player is skipping this stage
|
|
DEBUG_PRINTSTRINGINT("ReplayStage after shitskip: ", iReplayStage)
|
|
ENDIF
|
|
|
|
SWITCH iReplayStage
|
|
CASE CP_SWIM
|
|
JUMP_TO_STAGE(1)
|
|
BREAK
|
|
CASE CP_BIKE
|
|
JUMP_TO_STAGE(2)
|
|
BREAK
|
|
CASE CP_JOG
|
|
JUMP_TO_STAGE(3)
|
|
BREAK
|
|
CASE CP_OUTRO
|
|
JUMP_TO_STAGE(4)
|
|
BREAK
|
|
DEFAULT
|
|
SCRIPT_ASSERT("Replay in progress: Unknown checkpoint selected?")
|
|
BREAK
|
|
ENDSWITCH
|
|
ELSE
|
|
if intro_playing = FALSE
|
|
|
|
IF intro_requested = FALSE
|
|
RC_REQUEST_CUTSCENE("ef_3_rcm_concat")
|
|
DEBUG_PRINTSTRING("Requesting cutscene...")
|
|
intro_requested = TRUE
|
|
ELSE
|
|
DEBUG_PRINTSTRING("Waiting for cutscene...")
|
|
ENDIF
|
|
|
|
IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY()
|
|
DEBUG_PRINTSTRING("Trying to set Mary Ann component variation")
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Mary_Ann", opponent)
|
|
ENDIF
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Franklin", PLAYER_PED_ID())
|
|
ENDIF
|
|
ENDIF
|
|
|
|
iCutsceneStage = 0
|
|
|
|
IF RC_IS_CUTSCENE_OK_TO_START()
|
|
m_pInitialiseRace()
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
REGISTER_ENTITY_FOR_CUTSCENE(opponent, "Mary_Ann", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
|
|
ENDIF
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
REGISTER_ENTITY_FOR_CUTSCENE(PLAYER_PED_ID(), "Franklin", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
|
|
ENDIF
|
|
|
|
// Cleanup launcher which will remove lead-in blip
|
|
RC_CLEANUP_LAUNCHER()
|
|
|
|
RESET_PLAYER_STAMINA(PLAYER_ID())
|
|
STOP_GAMEPLAY_HINT()
|
|
|
|
REPLAY_START_EVENT(REPLAY_IMPORTANCE_LOW)
|
|
|
|
START_CUTSCENE()
|
|
WAIT(0)
|
|
RESOLVE_VEHICLES_INSIDE_ANGLED_AREA_WITH_SIZE_LIMIT(<<-921.506714,6138.839355,3.262831>>, <<-903.901855,6142.160156,9.201322>>, 14.5,
|
|
<< -913.52, 6151.76, 4.74 >>, 317.56, GET_DEFAULT_ALLOWABLE_VEHICLE_SIZE_VECTOR())
|
|
RESOLVE_VEHICLES_INSIDE_ANGLED_AREA_WITH_SIZE_LIMIT(<<-867.752686,6134.873535,-0.996085>>, <<-913.163574,6140.982910,7.133643>>, 13.5,
|
|
<< -913.52, 6151.76, 4.74 >>, 317.56, GET_DEFAULT_ALLOWABLE_VEHICLE_SIZE_VECTOR())
|
|
RC_START_CUTSCENE_MODE(<< -915.46, 6139.21, 4.52 >>, TRUE, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT)
|
|
DEBUG_PRINTSTRING("Starting cutscene...")
|
|
intro_playing = TRUE
|
|
//The cutscene is now running. We can load other assets.
|
|
ENDIF
|
|
ELSE
|
|
REQUEST_MODEL(bike_model)
|
|
REQUEST_WAYPOINT_RECORDING("Fan3_RollingStart")
|
|
REQUEST_ADDITIONAL_TEXT("FATIC3", MISSION_TEXT_SLOT)
|
|
|
|
IF iCutsceneStage = 0
|
|
|
|
SET_GAMEPLAY_CAM_RELATIVE_PITCH()
|
|
SET_GAMEPLAY_CAM_RELATIVE_HEADING()
|
|
|
|
IF WAS_CUTSCENE_SKIPPED()
|
|
DEBUG_PRINTSTRING("*** Cam exit state pitch/heading")
|
|
SET_GAMEPLAY_CAM_RELATIVE_PITCH()
|
|
SET_GAMEPLAY_CAM_RELATIVE_HEADING()
|
|
bIntroSkipped = TRUE
|
|
iCutsceneStage = 1
|
|
ENDIF
|
|
|
|
IF DO_FRANKLIN_EXIT()
|
|
iCutsceneStage = 1
|
|
ENDIF
|
|
|
|
DO_MARY_ANN_EXIT()
|
|
|
|
ma_pDoIntroBoost()
|
|
|
|
ELIF iCutsceneStage = 1
|
|
|
|
// In case if being missed
|
|
DO_MARY_ANN_EXIT()
|
|
|
|
ma_pDoIntroBoost()
|
|
|
|
// In case of skip?
|
|
DO_FRANKLIN_EXIT()
|
|
|
|
IF NOT IS_CUTSCENE_ACTIVE()
|
|
|
|
REPLAY_STOP_EVENT()
|
|
|
|
IF bIntroSkipped = TRUE
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
SET_ENTITY_COORDS(opponent, <<-903.2273, 6142.6387, 4.1911>>, TRUE, TRUE)
|
|
SET_ENTITY_HEADING(opponent, 264.8848)
|
|
ENDIF
|
|
IF NOT bZSkipActive
|
|
DEBUG_PRINTSTRING("*** Cutscene skip detected")
|
|
RC_START_Z_SKIP()
|
|
ma_pSwitchState(MS_SWIM)
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0)
|
|
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
|
|
ENDIF
|
|
bZSkipActive = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_SWIM, "Swim section") // Set the checkpoint
|
|
start_time = GET_GAME_TIMER() // Start the race timer
|
|
IF NOT IS_AUDIO_SCENE_ACTIVE("FANATIC_MIX_SCENE")
|
|
START_AUDIO_SCENE("FANATIC_MIX_SCENE")
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
ADD_ENTITY_TO_AUDIO_MIX_GROUP(opponent,"FANATIC_MIX_MARY_ANNE")
|
|
ENDIF
|
|
ENDIF
|
|
m_pLoadSwim()
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Main mission process for the swim section
|
|
PROC m_pSwim()
|
|
ma_pUpdate() // Update Mary Ann every frame
|
|
m_pDoRaceLogic()
|
|
PROCESS_CONVERSATION()
|
|
SWITCH subState
|
|
CASE SS_INIT
|
|
|
|
DEBUG_PRINTSTRING("DOING SWIM SETUP")
|
|
|
|
RC_SET_ENTITY_PROOFS_FOR_CUTSCENE(sRCLauncherDataLocal, FALSE)
|
|
|
|
CHECK_PLAYER_CHEATING()
|
|
CHECK_BIKES_ALIVE()
|
|
CHECK_PLAYER_IN_MISSION_AREA()
|
|
|
|
//DO_BOATS()
|
|
DO_EXIT_SWIM_DIALOGUE()
|
|
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
ADD_PED_FOR_DIALOGUE(conversation, ENUM_TO_INT(CHAR_FRANKLIN), PLAYER_PED_ID(), "FRANKLIN")
|
|
ENDIF
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
ADD_PED_FOR_DIALOGUE(conversation, 3, opponent, "MARYANN")
|
|
ENDIF
|
|
|
|
bSkipped = FALSE
|
|
|
|
SIMULATE_PLAYER_INPUT_GAIT(PLAYER_ID(), PEDMOVEBLENDRATIO_RUN, 4000)
|
|
|
|
ma_pDoIntroBoost()
|
|
|
|
RC_END_Z_SKIP(FALSE)
|
|
|
|
CREATE_CONVERSATION(conversation, "FAN3AUD", "FAN3_OPENER", CONV_PRIORITY_HIGH, DO_NOT_DISPLAY_SUBTITLES)
|
|
|
|
PRINT_NOW("FATIC3_1", DEFAULT_GOD_TEXT_TIME, 1) //Swim across the ~y~bay.
|
|
|
|
DEBUG_PRINTSTRING("DOING SWIM RUNNING")
|
|
|
|
REPLAY_RECORD_BACK_FOR_TIME(0.0, 15.0, REPLAY_IMPORTANCE_LOW)
|
|
subState = SS_RUNNING
|
|
BREAK
|
|
|
|
CASE SS_RUNNING
|
|
|
|
// B*1422947
|
|
IF NOT g_savedGlobals.sRandomChars.g_bFanaticHelp
|
|
IF NOT IS_HELP_MESSAGE_BEING_DISPLAYED()
|
|
PRINT_HELP("FAN_HELP")
|
|
g_savedGlobals.sRandomChars.g_bFanaticHelp = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
CHECK_PLAYER_CHEATING()
|
|
CHECK_BIKES_ALIVE()
|
|
CHECK_PLAYER_IN_MISSION_AREA()
|
|
//DO_BOATS()
|
|
DO_EXIT_SWIM_DIALOGUE()
|
|
ma_pDoIntroBoost()
|
|
|
|
IF PrevCheckpoint != NULL
|
|
//DEBUG_PRINTSTRING("Fade previous CP")
|
|
iPrevAlpha -= 25
|
|
INT PreviR, PreviG, PreviB, iA
|
|
IF iPrevAlpha > 0
|
|
GET_HUD_COLOUR(HUD_COLOUR_WHITE, PreviR, PreviG, PreviB, iA)
|
|
SET_CHECKPOINT_RGBA(PrevCheckpoint, PreviR, PreviG, PreviB, iPrevAlpha)
|
|
SET_CHECKPOINT_RGBA2(PrevCheckpoint, PreviR, PreviG, PreviB, iPrevAlpha)
|
|
ELSE
|
|
DELETE_CHECKPOINT(PrevCheckpoint)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF (DO_CHECKPOINT_UPDATES(SWIM_POSITIONS))
|
|
subState = SS_CLEANUP
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE SS_CLEANUP
|
|
|
|
DEBUG_PRINTSTRING("DOING SWIM CLEANUP")
|
|
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
IF NOT IS_THIS_CONVERSATION_ROOT_PLAYING("FAN3_SWIMWIN")
|
|
OR NOT IS_THIS_CONVERSATION_ROOT_PLAYING("FAN3_SWIMLOS")
|
|
KILL_ANY_CONVERSATION()
|
|
// We want to kill any conversation that displays subtitles at this point, to ensure we always show the god text
|
|
// The two exceptions above are conversations that may be playing at this point that don't have subtitles, so we can ignore them
|
|
ENDIF
|
|
ENDIF
|
|
|
|
blip = CREATE_VEHICLE_BLIP(bike_vehicle)
|
|
|
|
current_position = 0
|
|
current_max_positions = MAX_BIKE_POSITIONS
|
|
|
|
IF DOES_ENTITY_EXIST(opponent_goto_bike)
|
|
PRINT_NOW("FATIC3_12", DEFAULT_GOD_TEXT_TIME, 1) //Get on the ~b~bike.
|
|
ELSE
|
|
PRINT_NOW("FATIC3_2", DEFAULT_GOD_TEXT_TIME, 1) //Get on a ~b~bike.
|
|
additional_blip = CREATE_VEHICLE_BLIP(opponent_bike_vehicle)
|
|
ENDIF
|
|
|
|
IF missionStage < opponentStage
|
|
DEBUG_PRINTSTRING("Player lost swimming")
|
|
won_last_stage = FALSE
|
|
ELSE
|
|
DEBUG_PRINTSTRING("Player won swimming")
|
|
won_last_stage = TRUE
|
|
ENDIF
|
|
|
|
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_BIKE, "Bike section")
|
|
g_replay.iReplayInt[F3_CHECKPOINT_TIME] = race_timer
|
|
bLoadedBike = FALSE
|
|
subState = SS_INIT
|
|
missionStage = MS_TO_BIKE
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Check for the player's bike being 'dead' or in the water
|
|
PROC CHECK_BIKE_IN_WATER()
|
|
IF DOES_ENTITY_EXIST(players_bike)
|
|
IF IS_ENTITY_DEAD(players_bike)
|
|
//IF IS_ENTITY_IN_WATER(players_bike)
|
|
//PRINT_NOW("FATIC3_11", DEFAULT_GOD_TEXT_TIME, 1)
|
|
IF opponentStage >= MS_BIKE
|
|
MISSION_FAILED(FAILED_YOURBIKE_DESTROYED)
|
|
ELSE
|
|
MISSION_FAILED(FAILED_BIKE_DESTROYED)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Main mission process for the "get on a bike" section
|
|
PROC m_pToBike()
|
|
|
|
// Do all of these every frame
|
|
ma_pUpdate()
|
|
m_pDoRaceLogic()
|
|
PROCESS_CONVERSATION()
|
|
CHECK_PLAYER_CHEATING()
|
|
CHECK_BIKE_IN_WATER()
|
|
CHECK_BIKES_ALIVE()
|
|
CHECK_PLAYER_IN_MISSION_AREA()
|
|
//DO_BOATS()
|
|
DO_BAD_DRIVER()
|
|
|
|
IF PrevCheckpoint != NULL
|
|
//DEBUG_PRINTSTRING("Fade previous CP")
|
|
iPrevAlpha -= 25
|
|
INT PreviR, PreviG, PreviB, iA
|
|
IF iPrevAlpha > 0
|
|
GET_HUD_COLOUR(HUD_COLOUR_WHITE, PreviR, PreviG, PreviB, iA)
|
|
SET_CHECKPOINT_RGBA(PrevCheckpoint, PreviR, PreviG, PreviB, iPrevAlpha)
|
|
SET_CHECKPOINT_RGBA2(PrevCheckpoint, PreviR, PreviG, PreviB, iPrevAlpha)
|
|
ELSE
|
|
DELETE_CHECKPOINT(PrevCheckpoint)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
SWITCH subState
|
|
CASE SS_INIT
|
|
DEBUG_PRINTSTRING("DOING TO BIKE SETUP")
|
|
subState = SS_RUNNING
|
|
bMAJumpFailed = FALSE
|
|
bad_driver_launched = FALSE
|
|
bSkipped = FALSE
|
|
DEBUG_PRINTSTRING("DOING TO BIKE RUNNING")
|
|
BREAK
|
|
CASE SS_RUNNING
|
|
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
|
|
players_bike = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID())
|
|
|
|
IF (bike_vehicle = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()))
|
|
OR (opponent_bike_vehicle = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()))
|
|
|
|
SAFE_REMOVE_BLIP(blip)
|
|
|
|
SAFE_REMOVE_BLIP(additional_blip)
|
|
|
|
REPLAY_RECORD_BACK_FOR_TIME(5.0, 15.0, REPLAY_IMPORTANCE_LOW)
|
|
|
|
subState = SS_CLEANUP
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE SS_CLEANUP
|
|
DEBUG_PRINTSTRING("DOING TO BIKE CLEANUP")
|
|
if not bLoadedBike
|
|
m_pUnloadSwim()
|
|
IF m_pLoadBike()
|
|
DEBUG_PRINTSTRING("Loaded bike resources")
|
|
bLoadedBike = TRUE
|
|
ENDIF
|
|
ELSE
|
|
IF players_bike = NULL
|
|
players_bike = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID())
|
|
ENDIF
|
|
|
|
CLEAR_THIS_PRINT("FATIC3_12")
|
|
|
|
if not bCheatReload
|
|
// Load bike stuff normally
|
|
CREATE_FIRST_BLIP(BIKE_POSITIONS)
|
|
ELSE
|
|
// The player has got off and then back on the bike, so blip up the last known checkpoint
|
|
blip = CREATE_COORD_BLIP(BIKE_POSITIONS[current_position], BLIPPRIORITY_MED, FALSE)
|
|
SET_BLIP_COLOUR(blip, BLIP_COLOUR_YELLOW)
|
|
IF (current_position = (current_max_positions-1)) // If it's the final blip, give it a flag sprite
|
|
SET_BLIP_SPRITE(blip, RADAR_TRACE_RACEFLAG)
|
|
ENDIF
|
|
|
|
IF (current_position = (current_max_positions-2))
|
|
nextblip = CREATE_COORD_BLIP(BIKE_POSITIONS[current_position+1], BLIPPRIORITY_MED, FALSE)
|
|
SET_BLIP_SCALE(nextblip, 1.2)
|
|
SET_BLIP_SPRITE(nextblip, RADAR_TRACE_RACEFLAG)
|
|
SHOW_HEIGHT_ON_BLIP(nextblip, FALSE)
|
|
ELIF (current_position < (current_max_positions-1))
|
|
nextblip = CREATE_COORD_BLIP(BIKE_POSITIONS[current_position+1], BLIPPRIORITY_MED, FALSE)
|
|
SET_BLIP_SCALE(nextblip, 0.7)
|
|
SHOW_HEIGHT_ON_BLIP(nextblip, FALSE)
|
|
ENDIF
|
|
|
|
bCheatReload = FALSE
|
|
SPAWN_CHECKPOINT(BIKE_POSITIONS) // Respawn the current bike checkpoint
|
|
ENDIF
|
|
|
|
IF bike_around_trail_said = FALSE
|
|
PRINT_NOW("FATIC3_3", DEFAULT_GOD_TEXT_TIME, 1) //Cycle around the ~y~trail.
|
|
bike_around_trail_said = TRUE
|
|
ENDIF
|
|
|
|
iTrashTalkTimer = GET_GAME_TIMER()
|
|
missionStage = MS_BIKE
|
|
subState = SS_INIT
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Do a speed boost for the player as they approach the broken bridge jump, in case they're sliiiiightly going to miss it
|
|
/// This will increment the player's speed by 0.25 every frame when they go for the jump, if their current speed is between 15.0 and 18.5
|
|
PROC DO_JUMP_BOOST()
|
|
// Theoretical maximum: 21.74
|
|
IF IS_ENTITY_IN_ANGLED_AREA( PLAYER_PED_ID(), <<-158.218292,6583.302246,10.344661>>, <<-176.636276,6564.860840,17.576939>>, 6.000000)
|
|
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
|
|
VEHICLE_INDEX player_vehicle = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID())
|
|
IF IS_VEHICLE_OK(player_vehicle)
|
|
if GET_ENTITY_SPEED(player_vehicle) < 21.5
|
|
AND GET_ENTITY_SPEED(player_vehicle) > 15.0
|
|
FLOAT newSpeed = GET_ENTITY_SPEED(player_vehicle) + 0.25
|
|
DEBUG_PRINTSTRINGF("Speed now", newSpeed)
|
|
SET_VEHICLE_FORWARD_SPEED(player_vehicle, newSpeed)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
PROC CHECK_JUMP_REPLAY()
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
AND IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
|
|
IF IS_ENTITY_ALIVE(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()))
|
|
IF NOT bReplayTrackOn
|
|
IF IS_ENTITY_IN_ANGLED_AREA(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()), <<-162.930511,6574.679199,11.035428>>, <<-166.721405,6578.558594,15.140646>>, 3.50)
|
|
REPLAY_START_EVENT()
|
|
bReplayTrackOn = TRUE
|
|
DEBUG_PRINTSTRING("*** Started tracking jump replay")
|
|
ENDIF
|
|
ELSE
|
|
// If you hit the other side of the bridge, or the ground, or you somehow escape this huge 70m-wide box, stop tracking for replay
|
|
IF IS_ENTITY_IN_ANGLED_AREA(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()), <<-152.121078,6592.195313,8.325163>>, <<-149.194519,6588.718262,13.289552>>, 5.250000)
|
|
OR IS_ENTITY_IN_ANGLED_AREA(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()), <<-183.968750,6611.616211,-1.050815>>, <<-146.163025,6575.146973,7.485405>>, 46.500)
|
|
OR NOT IS_ENTITY_IN_ANGLED_AREA(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()), <<-182.590408,6607.473633,0.027168>>, <<-143.880035,6571.711914,37.029289>>, 70.75)
|
|
REPLAY_STOP_EVENT()
|
|
bReplayTrackOn = FALSE
|
|
DEBUG_PRINTSTRING("*** Stopped tracking jump replay")
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
IF bReplayTrackOn
|
|
DEBUG_PRINTSTRING("*** Stopped tracking jump replay (player not in vehicle)")
|
|
bReplayTrackOn = FALSE
|
|
REPLAY_STOP_EVENT()
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Handle the dog owner who appears near the end of the race
|
|
PROC DO_OWNER_SCENE()
|
|
|
|
SWITCH iOwnerStage
|
|
CASE 0 // Spawn ped when at the right checkpoint
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
IF IS_ENTITY_IN_RANGE_COORDS(PLAYER_PED_ID(), <<52.11, 6965.68, 9.73>>, 5.0)
|
|
dog_owner = CREATE_PED(PEDTYPE_MISSION, A_F_Y_Runner_01, <<56.3978, 7015.1646, 8.8828>>, 101.1728)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(A_F_Y_Runner_01)
|
|
DEBUG_PRINTSTRING("*** Dog owner created")
|
|
iOwnerStage++
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE 1 // Start playing waypoint recording
|
|
IF IS_ENTITY_ALIVE(dog_owner)
|
|
IF NOT IS_WAYPOINT_PLAYBACK_GOING_ON_FOR_PED(dog_owner)
|
|
TASK_FOLLOW_WAYPOINT_RECORDING(dog_owner, "fan3_ownerroute")
|
|
DEBUG_PRINTSTRING("*** Dog owner playing back recording")
|
|
iOwnerStage++
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE 2 // Play dog conversation when close enough to Franklin
|
|
IF IS_ENTITY_ALIVE(dog_owner)
|
|
IF IS_WAYPOINT_PLAYBACK_GOING_ON_FOR_PED(dog_owner)
|
|
if GET_DISTANCE_BETWEEN_PEDS(PLAYER_PED_ID(), dog_owner) < 16
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
ADD_PED_FOR_DIALOGUE(conv_frank, 5, dog_owner, "FAN3DOGOWNER")
|
|
ADD_PED_FOR_DIALOGUE(conv_frank, ENUM_TO_INT(CHAR_FRANKLIN), PLAYER_PED_ID(), "FRANKLIN")
|
|
IF CREATE_CONVERSATION(conv_frank, "FAN3AUD", "FAN3_DOG", CONV_PRIORITY_MEDIUM)
|
|
TASK_LOOK_AT_ENTITY(dog_owner, PLAYER_PED_ID(), 6000)
|
|
TASK_LOOK_AT_ENTITY(PLAYER_PED_ID(), dog_owner, 6000)
|
|
iOwnerStage++
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE 3 // Carry on until the waypoint recording has finished
|
|
IF IS_ENTITY_ALIVE(dog_owner)
|
|
IF NOT IS_WAYPOINT_PLAYBACK_GOING_ON_FOR_PED(dog_owner)
|
|
iOwnerStage++
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE 4 // Remove from world
|
|
IF IS_ENTITY_ALIVE(dog_owner)
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() // In case "FAN3_DSCARE" is queued when we get here
|
|
SET_PED_KEEP_TASK(dog_owner, TRUE)
|
|
SET_PED_AS_NO_LONGER_NEEDED(dog_owner)
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
// Aggro check
|
|
IF IS_ENTITY_ALIVE(dog_owner)
|
|
IF HAS_PLAYER_THREATENED_PED(dog_owner)
|
|
OR IS_PED_IN_COMBAT(dog_owner)
|
|
CLEAR_PED_TASKS(dog_owner)
|
|
TASK_SMART_FLEE_PED(dog_owner, PLAYER_PED_ID(), 100, -1)
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
// Only kill the convo and play the scared dialogue if the current convo is the owner asking Franklin about the dog
|
|
// Otherwise it doesn't make much sense, and trash talk should take priority anyway
|
|
TEXT_LABEL_23 RootCheck
|
|
RootCheck = GET_CURRENTLY_PLAYING_STANDARD_CONVERSATION_ROOT()
|
|
IF ARE_STRINGS_EQUAL(RootCheck,"FAN3_DOG")
|
|
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
|
|
ADD_PED_FOR_DIALOGUE(conv_frank, 5, dog_owner, "FAN3DOGOWNER")
|
|
ADD_PED_FOR_DIALOGUE(conv_frank, ENUM_TO_INT(CHAR_FRANKLIN), PLAYER_PED_ID(), "FRANKLIN")
|
|
ADD_NON_CRITICAL_STANDARD_CONVERSATION_TO_BUFFER(conv_frank, "FAN3AUD", "FAN3_DSCARE", CONV_PRIORITY_MEDIUM)
|
|
ENDIF
|
|
ELSE
|
|
ADD_PED_FOR_DIALOGUE(conv_frank, 5, dog_owner, "FAN3DOGOWNER")
|
|
ADD_PED_FOR_DIALOGUE(conv_frank, ENUM_TO_INT(CHAR_FRANKLIN), PLAYER_PED_ID(), "FRANKLIN")
|
|
CREATE_CONVERSATION(conv_frank, "FAN3AUD", "FAN3_DSCARE", CONV_PRIORITY_MEDIUM)
|
|
ENDIF
|
|
iOwnerStage = 4
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Handle setting the dog off running during the jog section
|
|
PROC DO_DOG_SCENE()
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
IF IS_ENTITY_IN_RANGE_COORDS(PLAYER_PED_ID(), RUN_POSITIONS[1], 5.0)
|
|
IF IS_ENTITY_ALIVE(running_dog)
|
|
IF NOT IS_WAYPOINT_PLAYBACK_GOING_ON_FOR_PED(running_dog)
|
|
TASK_FOLLOW_WAYPOINT_RECORDING(running_dog, "fan3_dogroute")
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Handle checking the chinups guy during the jog section for player aggro
|
|
PROC CHECK_CHINUPS_GUY()
|
|
|
|
IF IS_ENTITY_ALIVE(chinups_guy)
|
|
SWITCH iChinupStage
|
|
CASE 0
|
|
IF HAS_PLAYER_THREATENED_PED(chinups_guy)
|
|
CLEAR_PED_TASKS(chinups_guy)
|
|
TASK_SMART_FLEE_PED(chinups_guy, PLAYER_PED_ID(), 100, -1)
|
|
iChinupStage++
|
|
ENDIF
|
|
BREAK
|
|
DEFAULT
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Handle checking the chinups guy during the jog section for player aggro
|
|
PROC CHECK_STRETCHING_WOMAN()
|
|
|
|
IF IS_ENTITY_ALIVE(stretching_woman)
|
|
SWITCH iStretchStage
|
|
CASE 0
|
|
IF HAS_PLAYER_THREATENED_PED(stretching_woman)
|
|
CLEAR_PED_TASKS(stretching_woman)
|
|
TASK_SMART_FLEE_PED(stretching_woman, PLAYER_PED_ID(), 100, -1)
|
|
iStretchStage++
|
|
ENDIF
|
|
BREAK
|
|
DEFAULT
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Handle checking the binoculars birdwatcher type guy during the jog section for player aggro
|
|
PROC CHECK_BINOCS_GUY()
|
|
IF IS_ENTITY_ALIVE(binoculars_guy)
|
|
SWITCH iBinocStage
|
|
CASE 0
|
|
// Standard behaviour - flee if threatened
|
|
IF HAS_PLAYER_THREATENED_PED(binoculars_guy)
|
|
CLEAR_PED_TASKS(binoculars_guy)
|
|
SET_PED_FLEE_ATTRIBUTES(binoculars_guy, FA_USE_VEHICLE, TRUE)
|
|
SET_PED_KEEP_TASK(binoculars_guy, true)
|
|
IF DOES_ENTITY_EXIST(binocs)
|
|
DETACH_ENTITY(binocs)
|
|
ENDIF
|
|
PLAY_PED_AMBIENT_SPEECH(binoculars_guy, "GENERIC_CURSE_MED", SPEECH_PARAMS_FORCE_FRONTEND)
|
|
IF IS_VEHICLE_OK(picniccar2)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_ENTER_VEHICLE(NULL, picniccar2, DEFAULT_TIME_BEFORE_WARP, VS_DRIVER, PEDMOVEBLENDRATIO_SPRINT, ECF_JACK_ANYONE)
|
|
TASK_VEHICLE_MISSION_PED_TARGET(NULL, picniccar2,PLAYER_PED_ID(), MISSION_FLEE, 30, DRIVINGMODE_AVOIDCARS_RECKLESS, 300, 10)
|
|
//TASK_SMART_FLEE_PED(NULL, PLAYER_PED_ID(), 100, -1)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(binoculars_guy, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
DEBUG_PRINTSTRING("iBinocStage = 1")
|
|
iBinocStage = 1
|
|
ELIF NOT IS_VEHICLE_OK(picniccar2)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_SMART_FLEE_PED(NULL, PLAYER_PED_ID(), 100, -1)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(binoculars_guy, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
DEBUG_PRINTSTRING("iBinocStage = 2")
|
|
iBinocStage = 2
|
|
ENDIF
|
|
ENDIF
|
|
IF IS_ENTITY_ALIVE(picniccar2)
|
|
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), picniccar2)
|
|
IF DOES_ENTITY_EXIST(binocs)
|
|
DETACH_ENTITY(binocs)
|
|
ENDIF
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_SMART_FLEE_PED(NULL, PLAYER_PED_ID(), 100, -1)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(binoculars_guy, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
DEBUG_PRINTSTRING("iBinocStage = 2")
|
|
iBinocStage = 2
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE 1
|
|
// Guy is fleeing in a vehicle - get out and flee on foot if player steals vehicle or wrecks it
|
|
IF IS_VEHICLE_OK(picniccar2)
|
|
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), picniccar2)
|
|
CLEAR_PED_TASKS(binoculars_guy)
|
|
SET_PED_FLEE_ATTRIBUTES(binoculars_guy, FA_USE_VEHICLE, FALSE)
|
|
SET_PED_KEEP_TASK(binoculars_guy, true)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
IF IS_PED_IN_VEHICLE(binoculars_guy, picniccar2)
|
|
TASK_LEAVE_ANY_VEHICLE(null, 0, ECF_DONT_CLOSE_DOOR | ECF_DONT_WAIT_FOR_VEHICLE_TO_STOP)
|
|
ENDIF
|
|
TASK_SMART_FLEE_PED(NULL, PLAYER_PED_ID(), 100, -1)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(binoculars_guy, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
DEBUG_PRINTSTRING("iBinocStage = 2")
|
|
iBinocStage = 2
|
|
ENDIF
|
|
ELSE
|
|
// Car is not drivable anymore, so flee on foot
|
|
CLEAR_PED_TASKS(binoculars_guy)
|
|
SET_PED_FLEE_ATTRIBUTES(binoculars_guy, FA_USE_VEHICLE, FALSE)
|
|
SET_PED_KEEP_TASK(binoculars_guy, true)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
IF IS_PED_IN_VEHICLE(binoculars_guy, picniccar2)
|
|
TASK_LEAVE_ANY_VEHICLE(null, 0, ECF_DONT_CLOSE_DOOR | ECF_DONT_WAIT_FOR_VEHICLE_TO_STOP)
|
|
ENDIF
|
|
TASK_SMART_FLEE_PED(NULL, PLAYER_PED_ID(), 100, -1)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(binoculars_guy, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
DEBUG_PRINTSTRING("Car wrecked - iBinocStage = 2")
|
|
iBinocStage = 2
|
|
ENDIF
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), binoculars_guy) > 300
|
|
DEBUG_PRINTSTRING("iBinocStage = 3")
|
|
iBinocStage = 3
|
|
ENDIF
|
|
BREAK
|
|
CASE 2
|
|
// Guy is fleeing on foot
|
|
IF IS_ENTITY_ALIVE(binoculars_guy)
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), binoculars_guy) > 100
|
|
DEBUG_PRINTSTRING("iBinocStage = 3")
|
|
iBinocStage = 3
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE 3
|
|
// Remove ped and vehicle now they're far enough away
|
|
SAFE_RELEASE_PED(binoculars_guy)
|
|
SAFE_RELEASE_VEHICLE(picniccar2)
|
|
BREAK
|
|
ENDSWITCH
|
|
ELIF IS_ENTITY_DEAD(binoculars_guy)
|
|
IF DOES_ENTITY_EXIST(binocs)
|
|
IF IS_ENTITY_ATTACHED(binocs)
|
|
DETACH_ENTITY(binocs)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Main mission function for the bike section of the race
|
|
PROC m_pBike()
|
|
|
|
ma_pUpdate()
|
|
m_pDoRaceLogic()
|
|
|
|
IF PrevCheckpoint != NULL
|
|
//DEBUG_PRINTSTRING("Fade previous CP")
|
|
iPrevAlpha -= 25
|
|
INT PreviR, PreviG, PreviB, iA
|
|
IF iPrevAlpha > 0
|
|
GET_HUD_COLOUR(HUD_COLOUR_WHITE, PreviR, PreviG, PreviB, iA)
|
|
SET_CHECKPOINT_RGBA(PrevCheckpoint, PreviR, PreviG, PreviB, iPrevAlpha)
|
|
SET_CHECKPOINT_RGBA2(PrevCheckpoint, PreviR, PreviG, PreviB, iPrevAlpha)
|
|
ELSE
|
|
DELETE_CHECKPOINT(PrevCheckpoint)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
SWITCH subState
|
|
CASE SS_INIT
|
|
DEBUG_PRINTSTRING("DOING BIKE SETUP")
|
|
subState = SS_RUNNING
|
|
DEBUG_PRINTSTRING("DOING BIKE RUNNING")
|
|
BREAK
|
|
CASE SS_RUNNING
|
|
|
|
PROCESS_CONVERSATION()
|
|
CHECK_PLAYER_CHEATING()
|
|
CHECK_BIKE_IN_WATER()
|
|
CHECK_BIKES_ALIVE()
|
|
CHECK_PLAYER_IN_MISSION_AREA()
|
|
//DO_BOATS()
|
|
DO_BAD_DRIVER()
|
|
//DO_JUMP_BOOST()
|
|
CHECK_JUMP_REPLAY()
|
|
IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
|
|
SAFE_REMOVE_BLIP(blip)
|
|
SAFE_REMOVE_BLIP(nextblip)
|
|
blip = CREATE_VEHICLE_BLIP(players_bike)
|
|
DELETE_CHECKPOINT(checkpoint)
|
|
IF get_back_on_said = FALSE
|
|
PRINT_NOW("FATIC3_BACKON", DEFAULT_GOD_TEXT_TIME, 1) //Get back on the ~b~bike.
|
|
get_back_on_said = TRUE
|
|
ENDIF
|
|
bCheatReload = TRUE // Mark that we're reloading the bike bit due to cheating (or getting off the bike)
|
|
missionStage = MS_TO_BIKE
|
|
subState = SS_INIT
|
|
ELSE
|
|
IF IS_THIS_PRINT_BEING_DISPLAYED("FATIC3_BACKON")
|
|
DEBUG_PRINTSTRING("Clearing 'FATIC3_BACKON' print")
|
|
CLEAR_PRINTS()
|
|
ENDIF
|
|
IF (DO_CHECKPOINT_UPDATES(BIKE_POSITIONS))
|
|
DEBUG_PRINTSTRING("Player finished bike section, going into cleanup")
|
|
subState = SS_CLEANUP
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE SS_CLEANUP
|
|
DEBUG_PRINTSTRING("DOING BIKE CLEANUP")
|
|
current_position = 0
|
|
current_max_positions = MAX_RUN_POSITIONS
|
|
bCheatReload = FALSE // Make sure we reset this
|
|
IF missionStage < opponentStage
|
|
DEBUG_PRINTSTRING("Player lost cycling")
|
|
won_last_stage = FALSE
|
|
ELSE
|
|
DEBUG_PRINTSTRING("Player won cycling")
|
|
won_last_stage = TRUE
|
|
ENDIF
|
|
|
|
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_JOG, "Jog section")
|
|
g_replay.iReplayInt[F3_CHECKPOINT_TIME] = race_timer
|
|
missionStage = MS_OFF_BIKE
|
|
subState = SS_INIT
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Main mission function for the "get off the bike" section
|
|
PROC m_pOffBike()
|
|
m_pDoRaceLogic()
|
|
ma_pUpdate()
|
|
PROCESS_CONVERSATION()
|
|
CHECK_PLAYER_CHEATING()
|
|
IF NOT bSkipped // If we've skipped to the running section, the bikes generally won't have been made and we don't care about them
|
|
//DEBUG_PRINTSTRING("checking bikes")
|
|
CHECK_BIKE_IN_WATER()
|
|
CHECK_BIKES_ALIVE()
|
|
ENDIF
|
|
CHECK_PLAYER_IN_MISSION_AREA()
|
|
//DO_BOATS()
|
|
DO_BAD_DRIVER()
|
|
|
|
IF PrevCheckpoint != NULL
|
|
//DEBUG_PRINTSTRING("Fade previous CP")
|
|
iPrevAlpha -= 25
|
|
INT PreviR, PreviG, PreviB, iA
|
|
IF iPrevAlpha > 0
|
|
GET_HUD_COLOUR(HUD_COLOUR_WHITE, PreviR, PreviG, PreviB, iA)
|
|
SET_CHECKPOINT_RGBA(PrevCheckpoint, PreviR, PreviG, PreviB, iPrevAlpha)
|
|
SET_CHECKPOINT_RGBA2(PrevCheckpoint, PreviR, PreviG, PreviB, iPrevAlpha)
|
|
ELSE
|
|
DELETE_CHECKPOINT(PrevCheckpoint)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
SWITCH subState
|
|
CASE SS_INIT
|
|
REPLAY_RECORD_BACK_FOR_TIME(5.0, 15.0, REPLAY_IMPORTANCE_LOW)
|
|
|
|
DEBUG_PRINTSTRING("DOING OFF BIKE SETUP")
|
|
subState = SS_RUNNING
|
|
DEBUG_PRINTSTRING("DOING OFF BIKE RUNNING")
|
|
BREAK
|
|
CASE SS_RUNNING
|
|
IF IS_PED_SITTING_IN_ANY_VEHICLE(PLAYER_PED_ID())
|
|
IF BRING_VEHICLE_TO_HALT_AND_DISABLE_VEH_CONTROLS(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()), 7, 10)
|
|
TASK_LEAVE_ANY_VEHICLE(PLAYER_PED_ID())
|
|
DEBUG_PRINTSTRING("Telling player to leave bike...")
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
|
|
IF NOT bLoadedRun
|
|
m_pUnloadBike()
|
|
IF m_pLoadJog()
|
|
bLoadedRun = TRUE
|
|
ENDIF
|
|
ELSE
|
|
subState = SS_CLEANUP
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE SS_CLEANUP
|
|
DEBUG_PRINTSTRING("DOING OFF BIKE CLEANUP")
|
|
current_max_positions = MAX_RUN_POSITIONS
|
|
CLEAR_PRINTS()
|
|
PRINT_NOW("FATIC3_6", DEFAULT_GOD_TEXT_TIME, 1) //Run along the ~y~route.
|
|
|
|
IF bCheatReload
|
|
// If we've come back here because the player cheated, we want to go back to the checkpoint we left off, so recreate it and its blip
|
|
// then reset the cheat 'flag'
|
|
blip = CREATE_COORD_BLIP(RUN_POSITIONS[current_position], BLIPPRIORITY_MED, FALSE)
|
|
SET_BLIP_COLOUR(blip, BLIP_COLOUR_YELLOW)
|
|
IF (current_position = (current_max_positions - 1))
|
|
currentCPColour = GET_RACE_CHECKPOINT_COLOUR(GET_RACE_CHECKPOINT_TYPE(current_position, RUN_POSITIONS))
|
|
INT iR, iG, iB, iA
|
|
GET_HUD_COLOUR(currentCPColour, iR, iG, iB, iA)
|
|
VECTOR to_position
|
|
to_position = RUN_POSITIONS[current_position]
|
|
checkpoint = CREATE_CHECKPOINT(CHECKPOINT_RACE_TRI_RUN_FLAG, RUN_POSITIONS[current_position]+<<0,0,0.1>>, to_position, 3.2, 254, 207, 12)
|
|
ELSE
|
|
currentCPColour = GET_RACE_CHECKPOINT_COLOUR(GET_RACE_CHECKPOINT_TYPE(current_position, RUN_POSITIONS))
|
|
INT iR, iG, iB, iA
|
|
GET_HUD_COLOUR(currentCPColour, iR, iG, iB, iA)
|
|
VECTOR to_position
|
|
to_position = RUN_POSITIONS[current_position+1]
|
|
checkpoint = CREATE_CHECKPOINT(GET_RACE_CHECKPOINT_TYPE(current_position, RUN_POSITIONS), RUN_POSITIONS[current_position], to_position, 3.2, 254, 207, 12)
|
|
ENDIF
|
|
bCheatReload = FALSE
|
|
ELSE
|
|
// Otherwise, do the first blip and reset the current checkpoint position
|
|
CREATE_FIRST_BLIP(RUN_POSITIONS)
|
|
current_position = 0
|
|
// Also, this is a horrible hack and I feel like a bad man for doing it
|
|
ENDIF
|
|
|
|
iTrashTalkTimer = GET_GAME_TIMER()
|
|
|
|
IF bSkipped
|
|
bSkipped = FALSE
|
|
ENDIF
|
|
|
|
missionStage = MS_RUN
|
|
subState = SS_INIT
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Checks whether the player has used any of the shortcuts during the jog section, and plays a colour conversation if so
|
|
PROC CHECK_JOGGING_SHORTCUTS()
|
|
// IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<100.684044,6836.642090,14.557539>>, <<93.206673,6817.831543,19.754509>>, 11.000000)
|
|
// IF NOT bCheat1Said
|
|
// IF IS_ENTITY_ALIVE(opponent)
|
|
// IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), opponent) < 20
|
|
// IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
// KILL_ANY_CONVERSATION()
|
|
// ADD_NON_CRITICAL_STANDARD_CONVERSATION_TO_BUFFER(conversation, "FAN3AUD", "FAN3_JOGCH1", CONV_PRIORITY_HIGH)
|
|
// ELSE
|
|
// CREATE_CONVERSATION(conversation, "FAN3AUD", "FAN3_JOGCH1", CONV_PRIORITY_HIGH)
|
|
// ENDIF
|
|
// bCheat1Said = TRUE
|
|
// bConvoPaused = FALSE
|
|
// bCheated = TRUE
|
|
// ENDIF
|
|
// ENDIF
|
|
// ENDIF
|
|
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<59.708908,6931.385742,10.608230>>, <<69.710922,6899.878418,15.374324>>, 11.000000)
|
|
IF NOT bCheat2Said
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), opponent) < 20
|
|
IF g_savedGlobals.sRandomChars.g_bFanaticCheated = TRUE
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
KILL_ANY_CONVERSATION()
|
|
ADD_NON_CRITICAL_STANDARD_CONVERSATION_TO_BUFFER(conversation, "FAN3AUD", "FAN3_JOGCH2B", CONV_PRIORITY_HIGH)
|
|
ELSE
|
|
CREATE_CONVERSATION(conversation, "FAN3AUD", "FAN3_JOGCH2B", CONV_PRIORITY_HIGH)
|
|
ENDIF
|
|
ELSE
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
KILL_ANY_CONVERSATION()
|
|
ADD_NON_CRITICAL_STANDARD_CONVERSATION_TO_BUFFER(conversation, "FAN3AUD", "FAN3_JOGCH2A", CONV_PRIORITY_HIGH)
|
|
ELSE
|
|
CREATE_CONVERSATION(conversation, "FAN3AUD", "FAN3_JOGCH2A", CONV_PRIORITY_HIGH)
|
|
ENDIF
|
|
ENDIF
|
|
bCheat2Said = TRUE
|
|
bConvoPaused = FALSE
|
|
bCheated = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ELIF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<42.007938,6994.049805,5.189813>>, <<51.558426,6969.847168,12.566551>>, 7.000000)
|
|
IF NOT bCheat3Said
|
|
IF IS_ENTITY_ALIVE(opponent)
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), opponent) < 20
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
KILL_ANY_CONVERSATION()
|
|
ADD_NON_CRITICAL_STANDARD_CONVERSATION_TO_BUFFER(conversation, "FAN3AUD", "FAN3_JOGCH3", CONV_PRIORITY_HIGH)
|
|
ELSE
|
|
CREATE_CONVERSATION(conversation, "FAN3AUD", "FAN3_JOGCH3", CONV_PRIORITY_HIGH)
|
|
ENDIF
|
|
bCheat3Said = TRUE
|
|
bConvoPaused = FALSE
|
|
bCheated = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Main mission function for the jogging section of the race
|
|
PROC m_pRun()
|
|
m_pDoRaceLogic()
|
|
ma_pUpdate()
|
|
PROCESS_CONVERSATION()
|
|
CHECK_JOGGING_SHORTCUTS()
|
|
CHECK_PLAYER_CHEATING()
|
|
CHECK_PLAYER_IN_MISSION_AREA()
|
|
CHECK_CHINUPS_GUY()
|
|
CHECK_STRETCHING_WOMAN()
|
|
CHECK_BINOCS_GUY()
|
|
DO_DOG_SCENE()
|
|
DO_OWNER_SCENE()
|
|
|
|
IF PrevCheckpoint != NULL
|
|
//DEBUG_PRINTSTRING("Fade previous CP")
|
|
iPrevAlpha -= 25
|
|
INT PreviR, PreviG, PreviB, iA
|
|
IF iPrevAlpha > 0
|
|
GET_HUD_COLOUR(HUD_COLOUR_WHITE, PreviR, PreviG, PreviB, iA)
|
|
SET_CHECKPOINT_RGBA(PrevCheckpoint, PreviR, PreviG, PreviB, iPrevAlpha)
|
|
SET_CHECKPOINT_RGBA2(PrevCheckpoint, PreviR, PreviG, PreviB, iPrevAlpha)
|
|
ELSE
|
|
DELETE_CHECKPOINT(PrevCheckpoint)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
SWITCH subState
|
|
CASE SS_INIT
|
|
DEBUG_PRINTSTRING("DOING RUN SETUP")
|
|
subState = SS_RUNNING
|
|
bMissedCheckWarning = FALSE
|
|
bSkipped = FALSE
|
|
REQUEST_ANIM_DICT("rcmfanatic3leadinoutef_3_mcs_1")
|
|
DEBUG_PRINTSTRING("DOING RUN RUNNING")
|
|
BREAK
|
|
CASE SS_RUNNING
|
|
|
|
IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), RUN_POSITIONS[current_position]) > 75
|
|
IF NOT bMissedCheckWarning
|
|
PRINT("FATIC3_15", DEFAULT_GOD_TEXT_TIME, 1) //Return to the ~y~race.
|
|
bMissedCheckWarning = TRUE
|
|
ENDIF
|
|
ELSE
|
|
bMissedCheckWarning = FALSE
|
|
ENDIF
|
|
|
|
IF (DO_CHECKPOINT_UPDATES(RUN_POSITIONS))
|
|
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE, SPC_LEAVE_CAMERA_CONTROL_ON)
|
|
//CLEAR_PED_TASKS(PLAYER_PED_ID())
|
|
TASK_PLAY_ANIM(PLAYER_PED_ID(), "rcmfanatic3leadinoutef_3_mcs_1", "Fra_outofbreath_intro", REALLY_SLOW_BLEND_IN)
|
|
TRIGGER_MUSIC_EVENT("FANATIC2_STOP")
|
|
SET_MULTIHEAD_SAFE(TRUE) //Set multihead blinders on early
|
|
race_won = TRUE
|
|
subState = SS_CLEANUP
|
|
ENDIF
|
|
BREAK
|
|
CASE SS_CLEANUP
|
|
IF IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), "rcmfanatic3leadinoutef_3_mcs_1", "Fra_outofbreath_intro")
|
|
IF GET_ENTITY_ANIM_CURRENT_TIME(PLAYER_PED_ID(), "rcmfanatic3leadinoutef_3_mcs_1", "Fra_outofbreath_intro") >= 0.90
|
|
DEBUG_PRINTSTRING("Player done lead-out info")
|
|
missionStage = MS_DONE
|
|
ENDIF
|
|
ELSE
|
|
DEBUG_PRINTSTRING("Player not playing anim, cut to outro")
|
|
missionStage = MS_DONE
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
PROC m_pLost()
|
|
|
|
SWITCH subState
|
|
CASE SS_INIT
|
|
DEBUG_PRINTSTRING("DOING LOST SETUP")
|
|
// Do a Mary Ann winning anim here?
|
|
subState = SS_RUNNING
|
|
BREAK
|
|
CASE SS_RUNNING
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
subState = SS_CLEANUP
|
|
ELSE
|
|
DEBUG_PRINTSTRING("Waiting for Lost race convo to finish...")
|
|
ENDIF
|
|
BREAK
|
|
CASE SS_CLEANUP
|
|
MISSION_FAILED(FAILED_LOST_RACE)
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
/// PURPOSE: Check for Forced Pass or Fail
|
|
PROC DEBUG_Check_Debug_Keys()
|
|
IF missionStage <> MS_FAILED
|
|
IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_S)
|
|
bSkipped = TRUE
|
|
WAIT_FOR_CUTSCENE_TO_STOP()
|
|
CLEAR_PRINTS()
|
|
MISSION_PASSED()
|
|
ENDIF
|
|
IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_F)
|
|
bSkipped = TRUE
|
|
WAIT_FOR_CUTSCENE_TO_STOP()
|
|
CLEAR_PRINTS()
|
|
MISSION_FAILED()
|
|
ENDIF
|
|
|
|
IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_J)
|
|
bSkipped = TRUE
|
|
WAIT_FOR_CUTSCENE_TO_STOP()
|
|
RC_START_Z_SKIP()
|
|
SKIP_FORWARD()
|
|
ENDIF
|
|
IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_P)
|
|
bSkipped = TRUE
|
|
WAIT_FOR_CUTSCENE_TO_STOP()
|
|
RC_START_Z_SKIP()
|
|
SKIP_BACK()
|
|
ENDIF
|
|
|
|
IF LAUNCH_MISSION_STAGE_MENU(s_skip_menu, menu_option)
|
|
IF IS_ENTITY_ALIVE(opponent_bike_vehicle)
|
|
IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(opponent_bike_vehicle)
|
|
STOP_PLAYBACK_RECORDED_VEHICLE(opponent_bike_vehicle)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF IS_ENTITY_ALIVE(bike_vehicle)
|
|
IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(bike_vehicle)
|
|
STOP_PLAYBACK_RECORDED_VEHICLE(bike_vehicle)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
|
|
|
|
JUMP_TO_STAGE(menu_option)
|
|
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
#ENDIF
|
|
|
|
SCRIPT(g_structRCScriptArgs sRCLauncherDataIn)
|
|
|
|
sRCLauncherDataLocal = sRCLauncherDataIn
|
|
RC_TakeEntityOwnership(sRCLauncherDataLocal)
|
|
|
|
SET_MISSION_FLAG(TRUE)
|
|
|
|
// Setup callback when player is killed, arrested or goes to multiplayer
|
|
IF (HAS_FORCE_CLEANUP_OCCURRED(DEFAULT_FORCE_CLEANUP_FLAGS|FORCE_CLEANUP_FLAG_DEBUG_MENU))
|
|
PRINT_LAUNCHER_DEBUG("Force cleanup [TERMINATING]")
|
|
Random_Character_Failed()
|
|
MISSION_CLEANUP()
|
|
ENDIF
|
|
|
|
IF Is_Replay_In_Progress() // Set up the initial scene for replays
|
|
|
|
INT iReplayStage = Get_Replay_Mid_Mission_Stage()
|
|
|
|
IF g_bShitskipAccepted = TRUE
|
|
iReplayStage++ // player is skipping this stage
|
|
ENDIF
|
|
|
|
IF iReplayStage = CP_SWIM
|
|
g_bSceneAutoTrigger = TRUE
|
|
eInitialSceneStage = IS_REQUEST_SCENE
|
|
WHILE NOT SetupScene_FANATIC_3(sRCLauncherDataLocal)
|
|
WAIT(0)
|
|
ENDWHILE
|
|
g_bSceneAutoTrigger = FALSE
|
|
ENDIF
|
|
|
|
RC_SET_ENTITY_PROOFS_FOR_CUTSCENE(sRCLauncherDataLocal, FALSE)
|
|
ENDIF
|
|
|
|
ma_pCreate()
|
|
|
|
IF NOT IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
SCRIPT_ASSERT("Player not alive.")
|
|
ENDIF
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
s_skip_menu[0].sTxtLabel = "Intro"
|
|
s_skip_menu[0].bSelectable = true
|
|
s_skip_menu[1].sTxtLabel = "Swim section"
|
|
s_skip_menu[1].bSelectable = true
|
|
s_skip_menu[2].sTxtLabel = "Bike section"
|
|
s_skip_menu[2].bSelectable = true
|
|
s_skip_menu[3].sTxtLabel = "Jog section"
|
|
s_skip_menu[3].bSelectable = true
|
|
s_skip_menu[4].sTxtLabel = "Outro"
|
|
s_skip_menu[4].bSelectable = true
|
|
|
|
IF NOT DOES_WIDGET_GROUP_EXIST(widgetGroup)
|
|
widgetGroup= START_WIDGET_GROUP("Fanatic 3 widgets")
|
|
ADD_WIDGET_BOOL("TTY Toggle - Print Mission Debug Info", bDebug_PrintToTTY)
|
|
ADD_WIDGET_BOOL("Debug Mary Ann rubber banding", bDebugRubberBanding)
|
|
STOP_WIDGET_GROUP()
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
DISABLE_CHEAT(CHEAT_TYPE_FAST_RUN, TRUE)
|
|
DISABLE_CHEAT(CHEAT_TYPE_FAST_SWIM, TRUE)
|
|
|
|
// Disable controls and exit current vehicle
|
|
RC_PLAYER_TRIGGER_SCENE_LOCK_IN()
|
|
|
|
WHILE(TRUE)
|
|
|
|
REPLAY_CHECK_FOR_EVENT_THIS_FRAME("SF_EDF")
|
|
|
|
WAIT(0)
|
|
|
|
UPDATE_MISSION_NAME_DISPLAYING(sRCLauncherDataLocal.sIntroCutscene, TRUE)
|
|
|
|
HANDLE_GLOBAL_STAMINA_HELP()
|
|
|
|
SWITCH missionStage
|
|
CASE MS_LEADIN
|
|
m_pLeadIn()
|
|
BREAK
|
|
CASE MS_INTRO
|
|
INIT_MISSION()
|
|
BREAK
|
|
CASE MS_SWIM
|
|
m_pSwim()
|
|
BREAK
|
|
CASE MS_TO_BIKE
|
|
m_pToBike()
|
|
BREAK
|
|
CASE MS_BIKE
|
|
m_pBike()
|
|
BREAK
|
|
CASE MS_OFF_BIKE
|
|
m_pOffBike()
|
|
BREAK
|
|
CASE MS_RUN
|
|
m_pRun()
|
|
BREAK
|
|
CASE MS_LOST
|
|
m_pLost()
|
|
BREAK
|
|
CASE MS_DONE
|
|
DO_OUTRO()
|
|
BREAK
|
|
CASE MS_FAILED
|
|
FAILED()
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
DEBUG_Check_Debug_Keys()
|
|
#ENDIF
|
|
|
|
ENDWHILE
|
|
|
|
// Script should never reach here. Always terminate with cleanup function.
|
|
ENDSCRIPT
|