5272 lines
184 KiB
Python
Executable File
5272 lines
184 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 "commands_cutscene.sch"
|
|
USING "commands_entity.sch"
|
|
USING "commands_event.sch"
|
|
USING "commands_script.sch"
|
|
USING "cutscene_public.sch"
|
|
USING "dialogue_public.sch"
|
|
USING "randomChar_public.sch"
|
|
USING "rgeneral_include.sch"
|
|
USING "RC_Helper_Functions.sch"
|
|
USING "replay_public.sch"
|
|
USING "script_ped.sch"
|
|
USING "script_player.sch"
|
|
USING "shared_hud_displays.sch"
|
|
USING "CompletionPercentage_public.sch"
|
|
USING "RC_Threat_public.sch"
|
|
USING "RC_Setup_public.sch"
|
|
USING "initial_scenes_fanatic.sch"
|
|
USING "cheat_controller_public.sch"
|
|
USING "commands_recording.sch"
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
USING "select_mission_stage.sch"
|
|
#ENDIF
|
|
|
|
// *****************************************************************************************
|
|
// *****************************************************************************************
|
|
// *****************************************************************************************
|
|
//
|
|
// MISSION NAME : Fanatic1.sc
|
|
// AUTHOR : Neil Beggs (originally)/Ian Gander (June 12 onwards)
|
|
// DESCRIPTION : Foot race against Mary Ann, a fitness fanatic
|
|
//
|
|
// *****************************************************************************************
|
|
// *****************************************************************************************
|
|
// *****************************************************************************************
|
|
|
|
//----------------------
|
|
// CHECKPOINTS
|
|
//----------------------
|
|
CONST_INT CP_AFTER_MOCAP 0
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------------------------------------
|
|
// ENUMS:
|
|
//-------------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
ENUM MISSION_STAGE
|
|
MS_LEADIN,
|
|
MS_CUTSCENE,
|
|
MS_START_RUNNING,
|
|
MS_ROAD_RUNNING_SECTION,
|
|
MS_STEPS_DOWN,
|
|
MS_SPRINT_TO_FINISH,
|
|
MS_DEBUG_NEAR_FINISH_LINE,
|
|
MS_PLAYER_IN_VEHICLE,
|
|
MS_END_CUTSCENE,
|
|
MS_LOST_RACE,
|
|
MS_FAIL_WAIT_FOR_FADE
|
|
ENDENUM
|
|
|
|
ENUM FINISH_TACTIC
|
|
FINISHED_BY_STEROIDS,
|
|
FINISHED_BY_SHORTCUT
|
|
ENDENUM
|
|
|
|
ENUM STAGE_STAGE
|
|
SS_SETUP,
|
|
SS_STAGE
|
|
ENDENUM
|
|
|
|
ENUM STUCK_STAGE
|
|
STUCK_UPDATE,
|
|
STUCK_LOOP,
|
|
STUCK_FIX
|
|
ENDENUM
|
|
|
|
ENUM debugSkipToMissionStage
|
|
DEBUG_TO_INTRO = 0,
|
|
DEBUG_TO_START,
|
|
DEBUG_TO_ROAD,
|
|
DEBUG_TO_STEPS_DOWN,
|
|
DEBUG_TO_BEACH,
|
|
DEBUG_TO_FINISH_LINE,
|
|
DEBUG_NEXT_TO_FINISH
|
|
ENDENUM
|
|
|
|
ENUM FAIL_REASON
|
|
FAIL_FANATIC_KILLED,
|
|
FAIL_FANATIC_INJURED,
|
|
FAIL_FANATIC_SCARED,
|
|
FAIL_IN_CAR,
|
|
FAIL_YOU_DIDNT_KEEP_UP,
|
|
FAIL_SHE_BEAT_YOU_TO_BIKE,
|
|
FAIL_LEFT_RACE,
|
|
REASON_SILENT
|
|
ENDENUM
|
|
|
|
ENUM CUTSCENE_ENUM
|
|
CS_PLAYER_WINS,
|
|
CS_WAIT_FOR_ANN,
|
|
CS_MARY_ANN_LEAVES,
|
|
CS_SAY_FINAL_LINE,
|
|
CS_CUTSCENE_ENDS
|
|
ENDENUM
|
|
|
|
ENUM CAMERA_TARGET
|
|
CAM_TARGET_PLAYER,
|
|
CAM_MARY_ANN_LEAVES
|
|
ENDENUM
|
|
|
|
ENUM SPRINT_STATE
|
|
SPRINT_WAITING,
|
|
SPRINT_ACTIVE,
|
|
SPRINT_REDUCE,
|
|
SPRINT_COOLDOWN
|
|
ENDENUM
|
|
|
|
ENUM DRIVE_BY_STATE
|
|
DRIVE_BY_LOAD,
|
|
DRIVE_BY_PRE_TASK,
|
|
DRIVE_BY_SET_DRIVE_TASK,
|
|
DRIVE_BY_DRIVE,
|
|
DRIVE_BY_SET_FINGER_TASK,
|
|
DRIVE_BY_FINGERING,
|
|
DRIVE_BY_RELEASE
|
|
ENDENUM
|
|
|
|
ENUM MARY_ANN_DIALOGUE_STATE
|
|
MA_WITHIN_TALKING_RANGE,
|
|
MA_OUT_OF_TALKING_RANGE,
|
|
MA_SHOUTING_TO_KEEP_UP,
|
|
MA_SAYING_YOU_CAUGHT_UP
|
|
ENDENUM
|
|
|
|
ENUM DOG_STATE_ENUM
|
|
DOG_LOADING,
|
|
DOG_WAITING,
|
|
DOG_FOLLOWING_PLAYER
|
|
ENDENUM
|
|
|
|
ENUM CPR_STATE
|
|
CPR_LOADING,
|
|
CPR_WAITING,
|
|
CPR_GOING_TO_SCENE,
|
|
CPR_INTRO,
|
|
CPR_IDLE,
|
|
CPR_GETTING_UP,
|
|
CPR_INTERUPTED,
|
|
CPR_WATCHING_PLAYER,
|
|
CPR_FLEE
|
|
ENDENUM
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------------------------------------
|
|
// :STRUCTS:
|
|
//-------------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
STRUCT JOGGERS
|
|
PED_INDEX thisIndex
|
|
MODEL_NAMES thisModel
|
|
VECTOR thisPosition
|
|
VECTOR thisGoToPos1
|
|
VECTOR thisGoToPos2
|
|
Float thisHeading
|
|
ENDSTRUCT
|
|
|
|
STRUCT VEHICLE_STRUCT
|
|
PED_INDEX Driver
|
|
PED_INDEX Passenger
|
|
VEHICLE_INDEX thisCarIndex
|
|
MODEL_NAMES thisPedModel
|
|
MODEL_NAMES thisCarModel
|
|
VECTOR thisPosition
|
|
VECTOR thisGoToPos
|
|
Float thisHeading
|
|
FLOAT thisSpeed
|
|
ENDSTRUCT
|
|
|
|
STRUCT CONV_STRUCT
|
|
STRING rootLabel
|
|
STRING dialogueLine
|
|
BOOL hasBeenPlayed = FALSE
|
|
BOOL hasBeenInterrupted = FALSE
|
|
INT restartLine = -1
|
|
ENDSTRUCT
|
|
|
|
STRUCT RANDOM_CONV_STRUCT
|
|
STRING dialogueLine
|
|
INT timesPlayed = 0
|
|
INT restartLine = -1
|
|
ENDSTRUCT
|
|
|
|
STRUCT GOD_TEXT_STRUCT
|
|
STRING textLabel
|
|
BOOL hasBeenShown = FALSE
|
|
ENDSTRUCT
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------------------------------------
|
|
// :VARIABLES:
|
|
//-------------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
// The Random Character - sRCLauncherDataLocal.pedID[0]
|
|
g_structRCScriptArgs sRCLauncherDataLocal
|
|
|
|
// Mission stuff
|
|
STAGE_STAGE stageStage = SS_SETUP
|
|
MISSION_STAGE missionStage = MS_LEADIN
|
|
MISSION_STAGE currentMissionStage
|
|
FAIL_REASON failReason
|
|
FINISH_TACTIC finishReason = FINISHED_BY_STEROIDS
|
|
|
|
BOOL b_LeadInConvo = FALSE
|
|
BOOL b_CutsceneSkipped = FALSE
|
|
BOOL b_MusicTriggered = FALSE
|
|
BOOL b_DoneOutOfBreath = FALSE
|
|
BOOL b_CheatedLine = FALSE
|
|
BOOL b_IsTheRoadSwitchedOn = TRUE
|
|
BOOL b_PlayerJumpedDownTheCliff = FALSE
|
|
BOOL b_ForcePlayerRunningAtStart = TRUE
|
|
BOOL b_ScriptedEnding = FALSE
|
|
BOOL b_PlayerOnMAsBike = FALSE
|
|
BOOL b_MaryAnnFinalOrdersGiven = FALSE
|
|
BOOL b_DrivebyHorn = FALSE
|
|
BOOL bHasChanged
|
|
|
|
GOD_TEXT_STRUCT leftBehindWarning
|
|
GOD_TEXT_STRUCT leftRaceWarning
|
|
GOD_TEXT_STRUCT vehicleWarning
|
|
|
|
REL_GROUP_HASH relGroupFriendly
|
|
sequence_index seq
|
|
|
|
structPedsForConversation MyLocalPedStruct
|
|
|
|
// Mary Ann stuff
|
|
MARY_ANN_DIALOGUE_STATE MADialogueState = MA_WITHIN_TALKING_RANGE
|
|
PED_INDEX MARY_ANN
|
|
BLIP_INDEX FANATIC_BLIP
|
|
SPRINT_STATE MASprintState = SPRINT_WAITING
|
|
INT iSprintTimer
|
|
INT iSprintLength = 1800
|
|
INT iSprintDelay = 4500
|
|
FLOAT fMBRMax = 1.025
|
|
FLOAT fMBR_IncreaseRatio = fMBRMax
|
|
FLOAT fMBR_MaxRunSpeed = 3.00
|
|
FLOAT fMBR_RunSpeed = fMBR_MaxRunSpeed
|
|
FLOAT fMBR_SprintCap = -1.0
|
|
BOOL b_DoPedOvertake = FALSE
|
|
BOOL b_LoadCollisionAroudMaryAnn = FALSE
|
|
BOOL bMARY_ANN_CHASING_YOU_IN_CAR = FALSE
|
|
BOOL bMARY_ANN_IS_GOING_TO_RUN_SCARED = FALSE
|
|
|
|
STUCK_STAGE StuckStage = STUCK_UPDATE
|
|
INT iStuckTimer
|
|
INT iWaypointStuckCheck
|
|
|
|
// Running Dialogue Stuff
|
|
|
|
CONST_INT MAX_CHECKPOINTS 10
|
|
|
|
INT iHurryUpLineNumber = 0
|
|
CONST_INT iMAXHurryUpLineNumber 2
|
|
STRING HURRY_UP_LINE[iMAXHurryUpLineNumber]
|
|
|
|
INT iCatchUpLineNumber = 0
|
|
CONST_INT iMAXCatchUpLineNumber 2
|
|
|
|
INT iRaceLineNumber = 0
|
|
CONST_INT iMAXRaceLineNumber 3
|
|
STRING RACE_LINE[iMAXRaceLineNumber]
|
|
|
|
TEXT_LABEL tDialogueRoot
|
|
|
|
RANDOM_CONV_STRUCT MikePushMALine
|
|
RANDOM_CONV_STRUCT MikePushPedLine
|
|
RANDOM_CONV_STRUCT OvertakeLines
|
|
|
|
INT iOvertakeTimer
|
|
BOOL bOvertaken
|
|
BOOL bOvertakenSkip = FALSE
|
|
|
|
BOOL bCatchupCheatLineSaid = FALSE
|
|
|
|
INT iOneLinerSeq = 0
|
|
INT iOneLinerTimer
|
|
|
|
INT iRoadCounter = 0
|
|
INT iRoadTimer
|
|
|
|
CONV_STRUCT pushLine[3]
|
|
CONV_STRUCT startRunConversation
|
|
CONV_STRUCT road1Conversation
|
|
CONV_STRUCT road2Conversation
|
|
CONV_STRUCT raceConversation
|
|
CONV_STRUCT cheatedRanAcrossGrass
|
|
CONV_STRUCT cheatedLeaptFence
|
|
CONV_STRUCT returnAfterCheatedLine
|
|
|
|
// Mary Anns Bike stuff
|
|
VEHICLE_INDEX MAS_BIKE
|
|
VECTOR MAS_BIKE_POS = <<-2002.52, -503.53, 11.27>>
|
|
FLOAT MAS_BIKE_DIR = 0.13
|
|
MODEL_NAMES MARYSBIKEMODEL = SCORCHER
|
|
|
|
// Cutscene stuff
|
|
CUTSCENE_ENUM cutsceneStage
|
|
CAMERA_TARGET myCam = CAM_TARGET_PLAYER
|
|
BOOL b_TIRED_ANIM_PLAYING = FALSE
|
|
STRING dialogueOptionFinish
|
|
CAMERA_INDEX camCutsceneStart
|
|
INT iCutsceneStage = 0
|
|
//BOOL bCutsceneSkipped = FALSE
|
|
|
|
ANIM_DATA adBreathEnter
|
|
ANIM_DATA adBreathIdle1
|
|
ANIM_DATA adBreathIdle2
|
|
ANIM_DATA adBreathIdle3
|
|
|
|
// World filler stuff
|
|
VEHICLE_STRUCT DRIVEBY_FINGER_CAR
|
|
DRIVE_BY_STATE driveByState = DRIVE_BY_LOAD
|
|
|
|
VEHICLE_STRUCT FOLLOWING_CAR
|
|
|
|
JOGGERS OtherJoggers[4]
|
|
MODEL_NAMES JOGGERMODEL = A_F_Y_FITNESS_01
|
|
BOOL b_FinalPedsStartedWalking = FALSE
|
|
|
|
PED_INDEX QUAD_DRIVER
|
|
PED_INDEX INJURED_PED
|
|
PED_INDEX cprWatcher1
|
|
PED_INDEX cprWatcher2
|
|
VEHICLE_INDEX CHEAT_QUAD
|
|
VECTOR vPos_CHEAT_QUAD = <<-1818.96, -751.50, 7.99>>
|
|
VECTOR vPos_CPRScene
|
|
VECTOR vRot_CPRScene
|
|
INT CPRSynchSceneID
|
|
INT IdleSynchSceneID
|
|
INT NavBlockerID = -1
|
|
INT CutsceneNavBlockerID = -1
|
|
SCENARIO_BLOCKING_INDEX sbiCutscene // For the benches in the background that occasionally spawn peds in view around 15 secs into the cutscene
|
|
|
|
SCENARIO_BLOCKING_INDEX sbiWallPeds
|
|
SCENARIO_BLOCKING_INDEX sbiPathPeds
|
|
SCENARIO_BLOCKING_INDEX sbiMobilePed
|
|
|
|
|
|
PED_INDEX BEACH_DOG
|
|
VECTOR vPos_DOG = <<-1957.213013,-555.261414,11.083831>>
|
|
FLOAT fDir_DOG = -87.356987
|
|
DOG_STATE_ENUM beachDogState = DOG_LOADING
|
|
|
|
// Race Stuff
|
|
STRING sFANATIC_ROUTE = "Fanatic1MaryAnn"
|
|
INT place
|
|
INT iNum_WAYPOINTS
|
|
INT iNum_PlayerClosestWaypoint
|
|
INT iNum_NPCClosestWaypoint
|
|
VECTOR vPos_PlayerClosestWaypoint
|
|
|
|
VECTOR vPos_StartOfRoadRunning
|
|
VECTOR vPos_StartOfBeachRunning
|
|
VECTOR vPos_FinishLine = <<-2005.65, -508.08, 10.76>>
|
|
|
|
BLIP_INDEX DESTINATION_BLIP
|
|
BLIP_INDEX NEXT_DESTINATION_BLIP
|
|
CHECKPOINT_INDEX Checkpoint
|
|
CHECKPOINT_INDEX PrevCheckpoint
|
|
INT iPrevAlpha
|
|
INT iMaxRacePositions
|
|
VECTOR RACE_POSITIONS[10]
|
|
INT iCURRENT_RACE_POS = 0
|
|
INT iNPC_RACE_POS = 1
|
|
|
|
INT start_time = 0
|
|
INT iRollingStartTimer
|
|
INT iConversationTimer
|
|
INT iDrivebyTimer
|
|
INT iVehicleFailTimer
|
|
|
|
INT iHeartbeatAudioID
|
|
BOOL bHeartbeatStarted = FALSE
|
|
|
|
FLOAT fHintFov = 40.0
|
|
FLOAT fHintFollow = 0.35
|
|
FLOAT fHintPitchOrbit = 0.000
|
|
FLOAT fHintSide = -0.80
|
|
FLOAT fHintVert = -0.050
|
|
|
|
// Debug Stuff
|
|
#if IS_DEBUG_BUILD
|
|
CONST_INT MAX_SKIP_MENU_LENGTH 7
|
|
INT i_debug_jump_stage = 0
|
|
MissionStageMenuTextStruct s_skip_menu[MAX_SKIP_MENU_LENGTH]
|
|
BOOL bDebug_PrintToTTY = TRUE
|
|
BOOL bDebug_SpeedDebug = FALSE
|
|
FLOAT fPlayerSprintRemaining
|
|
WIDGET_GROUP_ID widgetGroup
|
|
#ENDIF
|
|
|
|
CPR_STATE cprState = CPR_LOADING
|
|
|
|
// ===========================================================================================================
|
|
// Debug prints
|
|
// ===========================================================================================================
|
|
|
|
/// PURPOSE: Print a string to the console
|
|
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 with a float to the console
|
|
PROC DEBUG_PRINTSF(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: Print a string with an int to the console
|
|
PROC DEBUG_PRINTSI(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: Checks that a particular conversation root is currently playing.
|
|
//PARAMS: RootToCheck - The conversation root we want to check is playing.
|
|
//RETURNS: TRUE if the root is 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
|
|
|
|
// ===========================================================================================================
|
|
// Termination
|
|
// ===========================================================================================================
|
|
|
|
// -----------------------------------------------------------------------------------------------------------
|
|
// Script Cleanup
|
|
// -----------------------------------------------------------------------------------------------------------
|
|
|
|
//PURPOSE: general cutscene cleanup
|
|
PROC FINISH_CUTSCENE(BOOL bInterp = TRUE, BOOL bResetGamePlayCamera = TRUE)
|
|
CLEAR_HELP()
|
|
DISPLAY_HUD(TRUE)
|
|
DISPLAY_RADAR(TRUE)
|
|
SET_WIDESCREEN_BORDERS(FALSE, 500)
|
|
RENDER_SCRIPT_CAMS(FALSE, bInterp)
|
|
|
|
IF DOES_CAM_EXIST(camCutsceneStart)
|
|
SET_CAM_ACTIVE(camCutsceneStart, FALSE)
|
|
DESTROY_CAM (camCutsceneStart)
|
|
ENDIF
|
|
|
|
IF bResetGamePlayCamera
|
|
SET_GAMEPLAY_CAM_RELATIVE_HEADING()
|
|
SET_GAMEPLAY_CAM_RELATIVE_PITCH(-5)
|
|
ENDIF
|
|
|
|
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
|
|
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
|
|
ENDIF
|
|
|
|
// RC_SETUP_SCRIPT_FOR_CUTSCENE(FALSE, <<0,0,0>>, <<0,0,0>>, 0)
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Cleanup peds and resources loaded for the CPR synced scene
|
|
PROC CLEANUP_QUAD_SCENE()
|
|
|
|
SAFE_RELEASE_PED(QUAD_DRIVER)
|
|
|
|
SAFE_RELEASE_PED(INJURED_PED)
|
|
|
|
SAFE_RELEASE_PED(cprWatcher1)
|
|
|
|
SAFE_RELEASE_PED(cprWatcher2)
|
|
|
|
REMOVE_ANIM_DICT("mini@cpr@char_a@cpr_def")
|
|
REMOVE_ANIM_DICT("mini@cpr@char_b@cpr_def")
|
|
REMOVE_ANIM_DICT("mini@cpr@char_a@cpr_str")
|
|
REMOVE_ANIM_DICT("mini@cpr@char_b@cpr_str")
|
|
REMOVE_ANIM_DICT("rcmfanatic1")
|
|
|
|
SET_PED_PATHS_IN_AREA(<<-1875.16, -630.82, 10.00>>, <<-1867.90, -625.78, 10.25>>, TRUE)
|
|
DISABLE_NAVMESH_IN_AREA(<<-1875.16, -630.82, 10.00>>, <<-1867.90, -625.78, 10.25>>, FALSE)
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Turn the road where the driveby fingering occurs back on
|
|
PROC TURN_ROADS_ON(BOOL on = TRUE)
|
|
IF b_IsTheRoadSwitchedOn <> on
|
|
SET_ROADS_IN_ANGLED_AREA(<<-1708.313965,-574.026611,36.873383>>, <<-2044.766357,-370.916718,9.152167>>, 27.250000, FALSE, on)
|
|
b_IsTheRoadSwitchedOn = on
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
PROC Script_Cleanup()
|
|
|
|
// Ensure launcher is terminated
|
|
RC_CLEANUP_LAUNCHER()
|
|
|
|
// If the mission was triggered then additional mission cleanup will be required.
|
|
IF (Random_Character_Cleanup_If_Triggered())
|
|
DEBUG_PRINTSTRING("...Random Character Script was triggered so additional cleanup required")
|
|
ENDIF
|
|
|
|
IF IS_ENTITY_ALIVE(MARY_ANN)
|
|
SET_PED_CAN_BE_KNOCKED_OFF_VEHICLE(MARY_ANN, KNOCKOFFVEHICLE_DEFAULT)
|
|
ENDIF
|
|
|
|
REMOVE_RELATIONSHIP_GROUP(relGroupFriendly)
|
|
|
|
IF IS_AUDIO_SCENE_ACTIVE("FANATIC_MIX_SCENE")
|
|
IF DOES_ENTITY_EXIST(MARY_ANN)
|
|
REMOVE_ENTITY_FROM_AUDIO_MIX_GROUP(MARY_ANN)
|
|
ENDIF
|
|
STOP_AUDIO_SCENE("FANATIC_MIX_SCENE")
|
|
ENDIF
|
|
|
|
TRIGGER_MUSIC_EVENT("RC6A_FAIL") // In case this wasn't triggered before
|
|
|
|
SAFE_RELEASE_VEHICLE(MAS_BIKE)
|
|
SAFE_RELEASE_PED(MARY_ANN)
|
|
|
|
SAFE_REMOVE_BLIP(DESTINATION_BLIP)
|
|
SAFE_REMOVE_BLIP(FANATIC_BLIP)
|
|
|
|
INT j
|
|
FOR j = 0 TO 3
|
|
SAFE_RELEASE_PED(OtherJoggers[j].thisIndex)
|
|
ENDFOR
|
|
|
|
SAFE_RELEASE_PED(DRIVEBY_FINGER_CAR.Driver)
|
|
|
|
IF IS_ENTITY_ALIVE(DRIVEBY_FINGER_CAR.Passenger)
|
|
SET_PED_COMBAT_ATTRIBUTES(DRIVEBY_FINGER_CAR.Passenger, CA_LEAVE_VEHICLES, TRUE)
|
|
SAFE_RELEASE_PED(DRIVEBY_FINGER_CAR.Passenger)
|
|
ENDIF
|
|
|
|
SAFE_RELEASE_VEHICLE(DRIVEBY_FINGER_CAR.thisCarIndex)
|
|
|
|
SAFE_RELEASE_PED(BEACH_DOG)
|
|
|
|
REMOVE_WAYPOINT_RECORDING(sFANATIC_ROUTE)
|
|
REMOVE_WAYPOINT_RECORDING("Fanatic1RollingStart")
|
|
|
|
// REMOVE_ANIM_DICT("GESTURES@MALE")
|
|
REMOVE_ANIM_DICT("rcmfanatic1out_of_breath")
|
|
REMOVE_ANIM_DICT("move_f@runner")
|
|
REMOVE_ANIM_DICT("rcmfanatic1")
|
|
REMOVE_ANIM_SET("FEMALE_FAST_RUNNER")
|
|
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(JOGGERMODEL)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(A_M_Y_BEACH_01)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(A_F_Y_BEACH_01)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(BANSHEE)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(MARYSBIKEMODEL)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(A_C_ROTTWEILER)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(BLAZER2)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(S_M_Y_BayWatch_01)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(G_M_Y_SALVAGOON_01)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(A_M_M_TRAMPBEAC_01)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(IG_MARYANN)
|
|
|
|
CLEANUP_QUAD_SCENE()
|
|
TURN_ROADS_ON()
|
|
|
|
//Re-enable vehicle generators near steps
|
|
SET_ALL_VEHICLE_GENERATORS_ACTIVE_IN_AREA(<<-1842.30, -517.70, 26.68>>, <<-1823.52, -515.43, 29.27>>, TRUE)
|
|
SET_PED_PATHS_BACK_TO_ORIGINAL(<<-1864.08, -632.07, 10.09>>, <<-1863.31, -631.53, 10.15>>)
|
|
SET_PED_PATHS_BACK_TO_ORIGINAL(<<-1820.57, -552.41, 17.40>>, <<-1865.76, -617.48, 10.58>>)
|
|
CLEAR_PED_NON_CREATION_AREA()
|
|
REMOVE_SCENARIO_BLOCKING_AREA(sbiWallPeds)
|
|
REMOVE_SCENARIO_BLOCKING_AREA(sbiPathPeds)
|
|
REMOVE_SCENARIO_BLOCKING_AREA(sbiMobilePed)
|
|
REMOVE_SCENARIO_BLOCKING_AREAS()
|
|
|
|
STOP_SOUND(iHeartbeatAudioID)
|
|
|
|
CLEAR_ADDITIONAL_TEXT(MISSION_TEXT_SLOT, TRUE)
|
|
|
|
DISABLE_CHEAT(CHEAT_TYPE_FAST_RUN, FALSE)
|
|
|
|
RC_CleanupSceneEntities(sRCLauncherDataLocal, FALSE)
|
|
|
|
TERMINATE_THIS_THREAD()
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Snap a given ped the closest Z-coord
|
|
PROC SET_PED_ON_THE_GROUND(PED_INDEX ped)
|
|
IF IS_PED_UNINJURED(ped)
|
|
VECTOR pos = GET_ENTITY_COORDS(ped)
|
|
FLOAT zCoord
|
|
GET_GROUND_Z_FOR_3D_COORD(pos, zCoord)
|
|
SET_ENTITY_COORDS(ped, <<pos.x, pos.y, zCoord>>)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
// -----------------------------------------------------------------------------------------------------------
|
|
// Script Pass
|
|
// -----------------------------------------------------------------------------------------------------------
|
|
|
|
PROC Script_Passed()
|
|
|
|
IF IS_SCRIPTED_CONVERSATION_ONGOING()
|
|
DEBUG_PRINTSTRING("Stopping scripted convo at script_passed")
|
|
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
|
|
ENDIF
|
|
|
|
IF finishReason <> FINISHED_BY_SHORTCUT
|
|
INFORM_STAT_SYSTEM_OF_BOOL_STAT_HAPPENED(FA1_SHORTCUT_USED)
|
|
ENDIF
|
|
|
|
CLEAR_PRINTS()
|
|
|
|
ADD_CONTACT_TO_PHONEBOOK(CHAR_MARY_ANN, MICHAEL_BOOK, TRUE)
|
|
|
|
Random_Character_Passed(CP_RAND_C_FAN1)
|
|
Script_Cleanup()
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Check whether the player has jumped down the cliff instead of going down the stairs, and start a conversation for this
|
|
PROC CHECK_IF_PLAYER_JUMPS_THE_CLIFF()
|
|
IF b_PlayerJumpedDownTheCliff = FALSE
|
|
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-1827.530396,-538.121277,21.831240>>, <<-1805.926025,-555.623901,31.773228>>, 2.000000)
|
|
IF MADialogueState = MA_WITHIN_TALKING_RANGE
|
|
IF IS_SCRIPTED_CONVERSATION_ONGOING()
|
|
DEBUG_PRINTSTRING("Stopping scripted convo at check if player jumps off cliff")
|
|
KILL_ANY_CONVERSATION()
|
|
CLEAR_PRINTS()
|
|
ENDIF
|
|
IF CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", "FAN1_5", CONV_PRIORITY_MEDIUM)
|
|
finishReason = FINISHED_BY_SHORTCUT
|
|
b_PlayerJumpedDownTheCliff = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
g_savedGlobals.sRandomChars.g_bFanaticCheated = TRUE // Set this even if the conversation doesn't trigger
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
|
|
/// PURPOSE: Load the resources for the driveby sequence, and return TRUE when finished loading
|
|
FUNC BOOL LOAD_DRIVEBY()
|
|
REQUEST_MODEL(G_M_Y_SALVAGOON_01)
|
|
REQUEST_MODEL(BANSHEE)
|
|
|
|
IF HAS_MODEL_LOADED(G_M_Y_SALVAGOON_01)
|
|
AND HAS_MODEL_LOADED(BANSHEE)
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
/// PURPOSE: Load the resources for the CPR synced scene, and return TRUE when finished loading
|
|
FUNC BOOL LOAD_CPR()
|
|
|
|
REQUEST_ANIM_DICT("mini@cpr@char_a@cpr_def")
|
|
REQUEST_ANIM_DICT("mini@cpr@char_b@cpr_def")
|
|
REQUEST_ANIM_DICT("mini@cpr@char_a@cpr_str")
|
|
REQUEST_ANIM_DICT("mini@cpr@char_b@cpr_str")
|
|
REQUEST_ANIM_DICT("rcmfanatic1")
|
|
REQUEST_WAYPOINT_RECORDING("Fanatic1Quad")
|
|
REQUEST_MODEL(BLAZER2)
|
|
REQUEST_MODEL(A_F_Y_BEACH_01)
|
|
REQUEST_MODEL(S_M_Y_BayWatch_01)
|
|
REQUEST_MODEL(A_M_M_Beach_01)
|
|
|
|
IF HAS_ANIM_DICT_LOADED("mini@cpr@char_a@cpr_def")
|
|
AND HAS_ANIM_DICT_LOADED("mini@cpr@char_b@cpr_def")
|
|
AND HAS_ANIM_DICT_LOADED("mini@cpr@char_a@cpr_str")
|
|
AND HAS_ANIM_DICT_LOADED("mini@cpr@char_b@cpr_str")
|
|
AND HAS_ANIM_DICT_LOADED("rcmfanatic1")
|
|
AND GET_IS_WAYPOINT_RECORDING_LOADED("Fanatic1Quad")
|
|
AND HAS_MODEL_LOADED(A_F_Y_BEACH_01)
|
|
AND HAS_MODEL_LOADED(S_M_Y_BayWatch_01)
|
|
AND HAS_MODEL_LOADED(A_M_M_Beach_01)
|
|
AND HAS_MODEL_LOADED(BLAZER2)
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
|
|
ENDFUNC
|
|
|
|
/// PURPOSE: Load the resources for the dog on the final stretch, and return TRUE when finished loading
|
|
FUNC BOOL LOAD_DOG()
|
|
REQUEST_MODEL(A_C_ROTTWEILER)
|
|
|
|
IF HAS_MODEL_LOADED(A_C_ROTTWEILER)
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE: Load the basic resources needed for the mission, such as Mary Ann's model, animations and route
|
|
PROC LOAD_OTHER_ASSETS()
|
|
|
|
REQUEST_ANIM_DICT("rcmfanatic1")
|
|
REQUEST_ANIM_DICT("rcmfanatic1celebrate")
|
|
REQUEST_ANIM_DICT("rcmfanatic1yell")
|
|
REQUEST_ANIM_DICT("move_f@runner")
|
|
REQUEST_ANIM_SET("FEMALE_FAST_RUNNER")
|
|
REQUEST_WAYPOINT_RECORDING(sFANATIC_ROUTE)
|
|
REQUEST_WAYPOINT_RECORDING("Fanatic1RollingStart")
|
|
REQUEST_ADDITIONAL_TEXT("FATIC1", MISSION_TEXT_SLOT)
|
|
REQUEST_MODEL(IG_MARYANN)
|
|
|
|
WHILE NOT HAS_ANIM_DICT_LOADED("rcmfanatic1")
|
|
OR NOT HAS_ANIM_DICT_LOADED("rcmfanatic1celebrate")
|
|
OR NOT HAS_ANIM_DICT_LOADED("rcmfanatic1yell")
|
|
OR NOT HAS_ANIM_DICT_LOADED("move_f@runner")
|
|
OR NOT HAS_ANIM_SET_LOADED("FEMALE_FAST_RUNNER")
|
|
OR NOT GET_IS_WAYPOINT_RECORDING_LOADED(sFANATIC_ROUTE)
|
|
OR NOT GET_IS_WAYPOINT_RECORDING_LOADED("Fanatic1RollingStart")
|
|
OR NOT HAS_ADDITIONAL_TEXT_LOADED(MISSION_TEXT_SLOT)
|
|
OR NOT HAS_MODEL_LOADED(IG_MARYANN)
|
|
DEBUG_PRINTSTRING("Loading other assets")
|
|
WAIT(0)
|
|
ENDWHILE
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Load the resources and create the joggers on the final stretch if they don't already exist
|
|
PROC CREATE_JOGGERS()
|
|
IF NOT IS_ENTITY_ALIVE(OtherJoggers[0].thisIndex)
|
|
REQUEST_MODEL(JOGGERMODEL)
|
|
REQUEST_MODEL(A_M_Y_BEACH_01)
|
|
REQUEST_MODEL(A_F_Y_BEACH_01)
|
|
|
|
IF HAS_MODEL_LOADED(JOGGERMODEL)
|
|
AND HAS_MODEL_LOADED(A_M_Y_BEACH_01)
|
|
AND HAS_MODEL_LOADED(A_F_Y_BEACH_01)
|
|
|
|
IF NOT DOES_ENTITY_EXIST(OtherJoggers[0].thisIndex) // 1ST JOGGER
|
|
OtherJoggers[0].thisPosition = <<-1951.48, -556.16, 11.71>>
|
|
OtherJoggers[0].thisHeading = -121.42
|
|
OtherJoggers[0].thisGoToPos1 = <<-1910.10, -591.56, 10.67>>
|
|
OtherJoggers[0].thisGoToPos2 = <<-1843.73, -649.16, 9.53>>
|
|
OtherJoggers[0].thisModel = JOGGERMODEL
|
|
OtherJoggers[0].thisIndex = CREATE_PED(PEDTYPE_CIVFEMALE, OtherJoggers[0].thisModel, OtherJoggers[0].thisPosition, OtherJoggers[0].thisHeading)
|
|
SET_PED_COMBAT_MOVEMENT(OtherJoggers[0].thisIndex, CM_WILLRETREAT)
|
|
SET_PED_COMBAT_ATTRIBUTES(OtherJoggers[0].thisIndex, CA_ALWAYS_FLEE, TRUE)
|
|
SET_PED_ON_THE_GROUND(OtherJoggers[0].thisIndex)
|
|
IF IS_PED_UNINJURED(OtherJoggers[0].thisIndex)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, OtherJoggers[0].thisGoToPos1, 2.0, DEFAULT_TIME_BEFORE_WARP)
|
|
TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, OtherJoggers[0].thisGoToPos2, 2.0, DEFAULT_TIME_BEFORE_WARP)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(OtherJoggers[0].thisIndex, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF NOT DOES_ENTITY_EXIST(OtherJoggers[1].thisIndex) // 2ND JOGGER
|
|
OtherJoggers[1].thisPosition = <<-1953.85, -555.66, 11>>
|
|
OtherJoggers[1].thisHeading = -121.42
|
|
OtherJoggers[1].thisGoToPos1 = <<-1911.54, -591.70, 10.61>>
|
|
OtherJoggers[1].thisGoToPos2 = <<-1839.87, -651.49, 9.53>>
|
|
OtherJoggers[1].thisModel = JOGGERMODEL
|
|
OtherJoggers[1].thisIndex = CREATE_PED(PEDTYPE_CIVFEMALE, OtherJoggers[1].thisModel, OtherJoggers[1].thisPosition, OtherJoggers[1].thisHeading)
|
|
SET_PED_COMBAT_MOVEMENT(OtherJoggers[1].thisIndex, CM_WILLRETREAT)
|
|
SET_PED_COMBAT_ATTRIBUTES(OtherJoggers[1].thisIndex, CA_ALWAYS_FLEE, TRUE)
|
|
IF IS_PED_UNINJURED(OtherJoggers[1].thisIndex)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, OtherJoggers[1].thisGoToPos1, 2.05, DEFAULT_TIME_BEFORE_WARP)
|
|
TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, OtherJoggers[1].thisGoToPos2, 2.05, DEFAULT_TIME_BEFORE_WARP)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(OtherJoggers[1].thisIndex, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF NOT DOES_ENTITY_EXIST(OtherJoggers[2].thisIndex) // GIRL WALKER AT END
|
|
OtherJoggers[2].thisPosition = <<-1999.40, -508.02, 11>>
|
|
OtherJoggers[2].thisHeading = 167.30
|
|
OtherJoggers[2].thisGoToPos1 = <<-1997.21, -517.17, 10.73>>
|
|
OtherJoggers[2].thisGoToPos2 = <<-1961.31, -547.96, 10.70>>
|
|
OtherJoggers[2].thisModel = A_F_Y_BEACH_01
|
|
OtherJoggers[2].thisIndex = CREATE_PED(PEDTYPE_CIVFEMALE, OtherJoggers[2].thisModel, OtherJoggers[2].thisPosition, OtherJoggers[2].thisHeading)
|
|
SET_PED_COMBAT_MOVEMENT(OtherJoggers[2].thisIndex, CM_WILLRETREAT)
|
|
SET_PED_COMBAT_ATTRIBUTES(OtherJoggers[2].thisIndex, CA_ALWAYS_FLEE, TRUE)
|
|
SET_PED_ON_THE_GROUND(OtherJoggers[2].thisIndex)
|
|
ELSE
|
|
IF IS_PED_UNINJURED(OtherJoggers[2].thisIndex)
|
|
CLEAR_PED_TASKS_IMMEDIATELY(OtherJoggers[2].thisIndex)
|
|
SET_ENTITY_COORDS(OtherJoggers[2].thisIndex, OtherJoggers[2].thisPosition)
|
|
SET_ENTITY_HEADING(OtherJoggers[2].thisIndex, OtherJoggers[2].thisHeading)
|
|
SET_PED_ON_THE_GROUND(OtherJoggers[2].thisIndex)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF NOT DOES_ENTITY_EXIST(OtherJoggers[3].thisIndex) // GUY WALKER AT END
|
|
OtherJoggers[3].thisPosition = <<-2000.19, -507.37, 11>>
|
|
OtherJoggers[3].thisHeading = 83.65
|
|
OtherJoggers[3].thisGoToPos1 = <<-1998.27, -517.46, 10.67>>
|
|
OtherJoggers[3].thisGoToPos2 = <<-1962.75, -549.56, 10.62>>
|
|
OtherJoggers[3].thisModel = A_M_Y_BEACH_01
|
|
OtherJoggers[3].thisIndex = CREATE_PED(PEDTYPE_CIVMALE, OtherJoggers[3].thisModel, OtherJoggers[3].thisPosition, OtherJoggers[3].thisHeading)
|
|
SET_PED_COMBAT_MOVEMENT(OtherJoggers[3].thisIndex, CM_WILLRETREAT)
|
|
SET_PED_COMBAT_ATTRIBUTES(OtherJoggers[3].thisIndex, CA_ALWAYS_FLEE, TRUE)
|
|
SET_PED_ON_THE_GROUND(OtherJoggers[3].thisIndex)
|
|
ELSE
|
|
IF IS_PED_UNINJURED(OtherJoggers[3].thisIndex)
|
|
CLEAR_PED_TASKS_IMMEDIATELY(OtherJoggers[3].thisIndex)
|
|
SET_ENTITY_COORDS(OtherJoggers[3].thisIndex, OtherJoggers[3].thisPosition)
|
|
SET_ENTITY_HEADING(OtherJoggers[3].thisIndex, OtherJoggers[3].thisHeading)
|
|
SET_PED_ON_THE_GROUND(OtherJoggers[3].thisIndex)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(A_F_Y_BEACH_01)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(A_M_Y_BEACH_01)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(JOGGERMODEL)
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Create Mary Ann's bike at the end of the mission
|
|
PROC CREATE_MARY_ANNS_BIKE()
|
|
IF NOT IS_VEHICLE_OK(MAS_BIKE)
|
|
REQUEST_MODEL(MARYSBIKEMODEL)
|
|
IF HAS_MODEL_LOADED(MARYSBIKEMODEL)
|
|
MAS_BIKE = CREATE_VEHICLE(MARYSBIKEMODEL, MAS_BIKE_POS, MAS_BIKE_DIR)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(MARYSBIKEMODEL)
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Load and create the resources for the driveby sequence
|
|
PROC CREATE_CARS()
|
|
|
|
REQUEST_MODEL(G_M_Y_SALVAGOON_01)
|
|
REQUEST_MODEL(BANSHEE)
|
|
REQUEST_MODEL(REGINA)
|
|
|
|
WHILE NOT HAS_MODEL_LOADED(G_M_Y_SALVAGOON_01)
|
|
OR NOT HAS_MODEL_LOADED(BANSHEE)
|
|
OR NOT HAS_MODEL_LOADED(REGINA)
|
|
WAIT(0)
|
|
ENDWHILE
|
|
|
|
CLEAR_AREA_OF_VEHICLES(<<1829.384277, -516.190002, 27.857389>>, 7.0) // Try and delete any vehicle parked where checkpoint 4 is
|
|
|
|
IF NOT IS_VEHICLE_OK(DRIVEBY_FINGER_CAR.thisCarIndex) // PARKED HONKING CAR
|
|
DRIVEBY_FINGER_CAR.thisPosition = <<-1833.329956,-513.388306,28.210709>>
|
|
DRIVEBY_FINGER_CAR.thisHeading = 286.3430
|
|
DRIVEBY_FINGER_CAR.thisGoToPos = <<-1721.02, -559.70, 37.46>>
|
|
DRIVEBY_FINGER_CAR.thisSpeed = 18
|
|
DRIVEBY_FINGER_CAR.thisCarModel = BANSHEE
|
|
DRIVEBY_FINGER_CAR.thisCarIndex = CREATE_VEHICLE(DRIVEBY_FINGER_CAR.thisCarModel, DRIVEBY_FINGER_CAR.thisPosition, DRIVEBY_FINGER_CAR.thisHeading)
|
|
SET_VEHICLE_COLOURS(DRIVEBY_FINGER_CAR.thisCarIndex, 1, 1)
|
|
DRIVEBY_FINGER_CAR.Driver = CREATE_PED_INSIDE_VEHICLE(DRIVEBY_FINGER_CAR.thisCarIndex, PEDTYPE_CIVMALE, G_M_Y_SALVAGOON_01)
|
|
DRIVEBY_FINGER_CAR.Passenger = CREATE_PED_INSIDE_VEHICLE(DRIVEBY_FINGER_CAR.thisCarIndex, PEDTYPE_CIVMALE, G_M_Y_SALVAGOON_01, VS_FRONT_RIGHT)
|
|
SET_PED_COMBAT_ATTRIBUTES(DRIVEBY_FINGER_CAR.Passenger, CA_LEAVE_VEHICLES, FALSE)
|
|
SET_PED_COMBAT_ATTRIBUTES(DRIVEBY_FINGER_CAR.Passenger, CA_CAN_TAUNT_IN_VEHICLE, TRUE)
|
|
SET_PED_COMBAT_ATTRIBUTES(DRIVEBY_FINGER_CAR.Driver, CA_ALWAYS_FLEE, TRUE)
|
|
/*
|
|
ELSE
|
|
IF IS_PED_UNINJURED(DRIVEBY_FINGER_CAR.Driver)
|
|
IF IS_VEHICLE_OK(DRIVEBY_FINGER_CAR.thisCarIndex)
|
|
CLEAR_PED_TASKS_IMMEDIATELY(DRIVEBY_FINGER_CAR.Driver)
|
|
SET_ENTITY_COORDS(DRIVEBY_FINGER_CAR.thisCarIndex, DRIVEBY_FINGER_CAR.thisPosition)
|
|
SET_ENTITY_HEADING(DRIVEBY_FINGER_CAR.thisCarIndex, DRIVEBY_FINGER_CAR.thisHeading)
|
|
IF NOT IS_PED_IN_VEHICLE(DRIVEBY_FINGER_CAR.Driver, DRIVEBY_FINGER_CAR.thisCarIndex)
|
|
TASK_WARP_PED_INTO_VEHICLE(DRIVEBY_FINGER_CAR.Driver, DRIVEBY_FINGER_CAR.thisCarIndex)
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
DRIVEBY_FINGER_CAR.Driver = CREATE_PED_INSIDE_VEHICLE(DRIVEBY_FINGER_CAR.thisCarIndex, PEDTYPE_CIVMALE, G_M_Y_SALVAGOON_01)
|
|
ENDIF
|
|
*/
|
|
ENDIF
|
|
|
|
IF NOT IS_VEHICLE_OK(FOLLOWING_CAR.thisCarIndex) // PARKED HONKING CAR
|
|
FOLLOWING_CAR.thisPosition = <<-2000.79, -494.35, 11.09>>
|
|
FOLLOWING_CAR.thisHeading = 321.61
|
|
FOLLOWING_CAR.thisGoToPos = <<-1719.08, -559.41, 36.33>>
|
|
FOLLOWING_CAR.thisSpeed = 12
|
|
FOLLOWING_CAR.thisCarModel = REGINA
|
|
FOLLOWING_CAR.thisCarIndex = CREATE_VEHICLE(FOLLOWING_CAR.thisCarModel, FOLLOWING_CAR.thisPosition, FOLLOWING_CAR.thisHeading)
|
|
FOLLOWING_CAR.Driver = CREATE_PED_INSIDE_VEHICLE(FOLLOWING_CAR.thisCarIndex, PEDTYPE_CIVMALE, G_M_Y_SALVAGOON_01)
|
|
FOLLOWING_CAR.Passenger = CREATE_PED_INSIDE_VEHICLE(FOLLOWING_CAR.thisCarIndex, PEDTYPE_CIVMALE, G_M_Y_SALVAGOON_01, VS_FRONT_RIGHT)
|
|
SET_PED_COMBAT_ATTRIBUTES(FOLLOWING_CAR.Driver, CA_ALWAYS_FLEE, TRUE)
|
|
SET_PED_COMBAT_ATTRIBUTES(FOLLOWING_CAR.Passenger, CA_ALWAYS_FLEE, TRUE)
|
|
ENDIF
|
|
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(G_M_Y_SALVAGOON_01)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(BANSHEE)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(REGINA)
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Create the dog on the final stretch
|
|
PROC CREATE_DOGS()
|
|
IF NOT IS_ENTITY_ALIVE(BEACH_DOG)
|
|
BEACH_DOG = CREATE_PED(PEDTYPE_MISSION, A_C_ROTTWEILER, vPos_DOG, fDir_DOG)
|
|
SET_PED_CAN_RAGDOLL(BEACH_DOG, TRUE)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Create the peds and vehicles for the CPR synced scene, and return TRUE when finished loading
|
|
PROC CREATE_QUAD_BIKE_SCENE(BOOL fromStart = TRUE)
|
|
IF NOT IS_VEHICLE_OK(CHEAT_QUAD)
|
|
|
|
SET_PED_PATHS_IN_AREA(<<-1875.16, -630.82, 10.00>>, <<-1867.90, -625.78, 10.25>>, FALSE)
|
|
DISABLE_NAVMESH_IN_AREA(<<-1875.16, -630.82, 10.00>>, <<-1867.90, -625.78, 10.25>>, TRUE)
|
|
IF NavBlockerID > -1
|
|
REMOVE_NAVMESH_BLOCKING_OBJECT(NavBlockerID)
|
|
NavBlockerID = -1
|
|
ENDIF
|
|
NavBlockerID = ADD_NAVMESH_BLOCKING_OBJECT(<<-1870.54, -628.10, 10.09>>, <<4, 4, 4>>, 0)
|
|
|
|
IF NavBlockerID = -1
|
|
SCRIPT_ASSERT("Failed to add a navmesh blocking object to CPR scene! You may see peds walking through it. Please send a message to Ian Gander @ Leeds about this...")
|
|
ENDIF
|
|
|
|
INJURED_PED = CREATE_PED(PEDTYPE_CIVMALE, A_M_M_Beach_01, <<-1870.54, -628.10, 10.09>>, 80)
|
|
SET_ENTITY_LOAD_COLLISION_FLAG(INJURED_PED, TRUE)
|
|
CLEAR_PED_TASKS_IMMEDIATELY(INJURED_PED)
|
|
SET_PED_MONEY(INJURED_PED, 0)
|
|
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(INJURED_PED, TRUE)
|
|
SET_PED_CAN_BE_TARGETTED(INJURED_PED, FALSE)
|
|
|
|
vPos_CPRScene = GET_ENTITY_COORDS(INJURED_PED)
|
|
GET_GROUND_Z_FOR_3D_COORD(GET_ENTITY_COORDS(INJURED_PED), vPos_CPRScene.z)
|
|
vRot_CPRScene = GET_ENTITY_ROTATION(INJURED_PED)
|
|
|
|
IdleSynchSceneID = CREATE_SYNCHRONIZED_SCENE(vPos_CPRScene, vRot_CPRScene)
|
|
TASK_SYNCHRONIZED_SCENE (INJURED_PED, IdleSynchSceneID, "mini@cpr@char_b@cpr_def", "cpr_intro", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, SYNCED_SCENE_NONE, RBF_PLAYER_IMPACT)
|
|
SET_SYNCHRONIZED_SCENE_RATE(IdleSynchSceneID, 0.0)
|
|
|
|
cprWatcher1 = CREATE_PED(PEDTYPE_CIVFEMALE, A_F_Y_BEACH_01, <<-1869.76, -627.70, 10.10>>)
|
|
SET_PED_COMBAT_ATTRIBUTES(cprWatcher1, CA_ALWAYS_FLEE, TRUE)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_TURN_PED_TO_FACE_ENTITY(NULL, INJURED_PED)
|
|
TASK_PLAY_ANIM(null, "rcmfanatic1", "idle_a", SLOW_BLEND_IN, SLOW_BLEND_OUT)
|
|
TASK_PLAY_ANIM(null, "rcmfanatic1", "base", NORMAL_BLEND_IN, SLOW_BLEND_OUT)
|
|
TASK_PLAY_ANIM(null, "rcmfanatic1", "base", NORMAL_BLEND_IN, SLOW_BLEND_OUT)
|
|
TASK_PLAY_ANIM(null, "rcmfanatic1", "idle_C", NORMAL_BLEND_IN, SLOW_BLEND_OUT)
|
|
TASK_PLAY_ANIM(null, "rcmfanatic1", "base", NORMAL_BLEND_IN, SLOW_BLEND_OUT)
|
|
TASK_PLAY_ANIM(null, "rcmfanatic1", "idle_b", NORMAL_BLEND_IN, SLOW_BLEND_OUT)
|
|
TASK_PLAY_ANIM(null, "rcmfanatic1", "base", NORMAL_BLEND_IN, SLOW_BLEND_OUT)
|
|
TASK_PLAY_ANIM(null, "rcmfanatic1", "base", NORMAL_BLEND_IN, SLOW_BLEND_OUT)
|
|
TASK_PLAY_ANIM(null, "rcmfanatic1", "base", NORMAL_BLEND_IN, SLOW_BLEND_OUT)
|
|
TASK_PLAY_ANIM(null, "rcmfanatic1", "idle_b", NORMAL_BLEND_IN, SLOW_BLEND_OUT)
|
|
SET_SEQUENCE_TO_REPEAT(seq, REPEAT_FOREVER)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(cprWatcher1, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
|
|
|
|
cprWatcher2 = CREATE_PED(PEDTYPE_CIVFEMALE, A_F_Y_BEACH_01, <<-1873.61, -628.88, 11.16>>)
|
|
SET_PED_COMBAT_ATTRIBUTES(cprWatcher2, CA_ALWAYS_FLEE, TRUE)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_TURN_PED_TO_FACE_ENTITY(NULL, INJURED_PED)
|
|
TASK_PLAY_ANIM(null, "rcmfanatic1", "base", SLOW_BLEND_IN, SLOW_BLEND_OUT)
|
|
TASK_PLAY_ANIM(null, "rcmfanatic1", "idle_b", NORMAL_BLEND_IN, SLOW_BLEND_OUT)
|
|
TASK_PLAY_ANIM(null, "rcmfanatic1", "idle_a", NORMAL_BLEND_IN, SLOW_BLEND_OUT)
|
|
TASK_PLAY_ANIM(null, "rcmfanatic1", "base", NORMAL_BLEND_IN, SLOW_BLEND_OUT)
|
|
TASK_PLAY_ANIM(null, "rcmfanatic1", "base", NORMAL_BLEND_IN, SLOW_BLEND_OUT)
|
|
TASK_PLAY_ANIM(null, "rcmfanatic1", "idle_a", NORMAL_BLEND_IN, SLOW_BLEND_OUT)
|
|
TASK_PLAY_ANIM(null, "rcmfanatic1", "idle_b", NORMAL_BLEND_IN, SLOW_BLEND_OUT)
|
|
TASK_PLAY_ANIM(null, "rcmfanatic1", "base", NORMAL_BLEND_IN, SLOW_BLEND_OUT)
|
|
TASK_PLAY_ANIM(null, "rcmfanatic1", "base", NORMAL_BLEND_IN, SLOW_BLEND_OUT)
|
|
SET_SEQUENCE_TO_REPEAT(seq, REPEAT_FOREVER)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(cprWatcher2, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
|
|
if fromStart
|
|
CHEAT_QUAD = CREATE_VEHICLE(BLAZER2, vPos_CHEAT_QUAD, 36.64)
|
|
SET_VEHICLE_ON_GROUND_PROPERLY(CHEAT_QUAD)
|
|
SET_ENTITY_LOAD_COLLISION_FLAG(CHEAT_QUAD, TRUE)
|
|
QUAD_DRIVER = CREATE_PED_INSIDE_VEHICLE(CHEAT_QUAD, PEDTYPE_MEDIC, S_M_Y_BAYWATCH_01)
|
|
cprState = CPR_WAITING
|
|
ELSE
|
|
CHEAT_QUAD = CREATE_VEHICLE(BLAZER2, <<-1871.55, -640.01, 10.65>>, 297.76)
|
|
SET_VEHICLE_ON_GROUND_PROPERLY(CHEAT_QUAD)
|
|
SET_ENTITY_LOAD_COLLISION_FLAG(CHEAT_QUAD, TRUE)
|
|
QUAD_DRIVER = CREATE_PED_INSIDE_VEHICLE(CHEAT_QUAD, PEDTYPE_CIVMALE, S_M_Y_BAYWATCH_01)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_LOOK_AT_ENTITY(NULL, INJURED_PED, -1)
|
|
TASK_LEAVE_VEHICLE(NULL, CHEAT_QUAD)
|
|
TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, GET_ENTITY_COORDS(INJURED_PED), 1.8)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(QUAD_DRIVER, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
cprState = CPR_GOING_TO_SCENE
|
|
ENDIF
|
|
SET_PED_COMBAT_ATTRIBUTES(QUAD_DRIVER, CA_ALWAYS_FLEE, TRUE)
|
|
SET_ENTITY_LOAD_COLLISION_FLAG(QUAD_DRIVER, TRUE)
|
|
|
|
SET_PED_KEEP_TASK(INJURED_PED, TRUE)
|
|
|
|
ENDIF
|
|
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(BLAZER2)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(A_F_Y_BEACH_01)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(S_M_Y_BayWatch_01)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(A_M_M_Beach_01)
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Works out which checkpoint type is needed based upon angle between checkpoints
|
|
FUNC CHECKPOINT_TYPE GET_RACE_CHECKPOINT_TYPE(INT iCheckNum)
|
|
|
|
VECTOR pos, pos2, pos3
|
|
VECTOR vec1, vec2
|
|
|
|
FLOAT fReturnAngle
|
|
FLOAT fChevron1 = 180.0
|
|
FLOAT fChevron2 = 140.0
|
|
FLOAT fChevron3 = 80.0
|
|
|
|
pos = RACE_POSITIONS[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 = iMaxRacePositions-1)
|
|
RETURN CHECKPOINT_RACE_GROUND_FLAG
|
|
ELSE
|
|
// Otherwise, we need to do the angle shit
|
|
// If this is the first checkpoint, we need to check a position behind it
|
|
IF iCheckNum = 0
|
|
pos3 = <<-1869.12, -445.17, 45.17>>
|
|
pos2 = RACE_POSITIONS[iCheckNum + 1]
|
|
ELSE
|
|
// The checkpoint is neither first nor last, wooo, straightforward
|
|
pos3 = RACE_POSITIONS[iCheckNum - 1]
|
|
pos2 = RACE_POSITIONS[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
|
|
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
|
|
|
|
// 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
|
|
// OR cpType = CHECKPOINT_RACE_GROUND_FLAG
|
|
// RETURN HUD_COLOUR_YELLOWLIGHT
|
|
// ELSE
|
|
// RETURN HUD_COLOUR_YELLOWLIGHT
|
|
// ENDIF
|
|
// Returning YELLOWDARK for all checkpoints (B*1454575)
|
|
cpType = cpType // Compile fix
|
|
RETURN HUD_COLOUR_YELLOWLIGHT
|
|
ENDFUNC
|
|
|
|
/// PURPOSE: Work out and update the coord of the waypoint the player is closest to on Mary Ann's route,
|
|
/// and update which number waypoint the player and Mary Ann is closest to
|
|
PROC DETERMINE_CLOSEST_WAYPOINTS()
|
|
|
|
IF GET_IS_WAYPOINT_RECORDING_LOADED(sFANATIC_ROUTE)
|
|
WAYPOINT_RECORDING_GET_CLOSEST_WAYPOINT(sFANATIC_ROUTE, GET_ENTITY_COORDS(PLAYER_PED_ID()), iNum_PlayerClosestWaypoint)
|
|
WAYPOINT_RECORDING_GET_CLOSEST_WAYPOINT(sFANATIC_ROUTE, GET_ENTITY_COORDS(MARY_ANN), iNum_NPCClosestWaypoint)
|
|
|
|
IF iCURRENT_RACE_POS < iMaxRacePositions
|
|
WAYPOINT_RECORDING_GET_COORD(sFANATIC_ROUTE, iNum_PlayerClosestWaypoint, vPos_PlayerClosestWaypoint)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Work out the coord of the NEXT waypoint on Mary Ann's route to the one Mary Ann is currently closest to
|
|
FUNC VECTOR GET_COORD_FURTHER_ALONG_ROUTE()
|
|
|
|
DETERMINE_CLOSEST_WAYPOINTS()
|
|
|
|
VECTOR vPos
|
|
IF iNum_NPCClosestWaypoint < iNum_WAYPOINTS - 1
|
|
WAYPOINT_RECORDING_GET_COORD(sFANATIC_ROUTE, iNum_NPCClosestWaypoint + 1, vPos)
|
|
ELSE
|
|
WAYPOINT_RECORDING_GET_COORD(sFANATIC_ROUTE, iNum_WAYPOINTS - 1, vPos)
|
|
ENDIF
|
|
RETURN vPos
|
|
ENDFUNC
|
|
|
|
/// PURPOSE: Return the number of Mary Ann's NEXT waypoint
|
|
FUNC INT GET_MARY_ANNS_NEXT_WAYPOINT()
|
|
INT i
|
|
WAYPOINT_RECORDING_GET_CLOSEST_WAYPOINT(sFANATIC_ROUTE, GET_COORD_FURTHER_ALONG_ROUTE(), i)
|
|
RETURN i
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Debug function to keep Mary Ann running after skipping
|
|
/// PARAMS:
|
|
/// nextMS - sets the mission stage that we are skipping to
|
|
PROC KEEP_RUNNING(MISSION_STAGE nextMS, BOOL bSkipping = TRUE)
|
|
IF IS_PED_UNINJURED(MARY_ANN)
|
|
IF NOT IS_STRING_NULL(sFANATIC_ROUTE)
|
|
IF GET_IS_WAYPOINT_RECORDING_LOADED(sFANATIC_ROUTE)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(NULL, TRUE)
|
|
TASK_FOLLOW_WAYPOINT_RECORDING(NULL, sFANATIC_ROUTE, GET_MARY_ANNS_NEXT_WAYPOINT(), EWAYPOINT_START_FROM_CLOSEST_POINT | EWAYPOINT_VEHICLES_USE_AI_SLOWDOWN | EWAYPOINT_ALLOW_STEERING_AROUND_PEDS | EWAYPOINT_NAVMESH_BACK_TO_WAYPOINT_IF_LEFT_ROUTE , -1)
|
|
TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), -1)
|
|
TASK_PLAY_ANIM(null, "move_f@runner", "idle", SLOW_BLEND_IN, SLOW_BLEND_OUT, -1, AF_LOOPING)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(MARY_ANN, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
DEBUG_PRINTSTRING("Keep Running used")
|
|
SET_PED_CAN_RAGDOLL_FROM_PLAYER_IMPACT(MARY_ANN, FALSE)
|
|
|
|
IF bSkipping = TRUE
|
|
stageStage = SS_SETUP
|
|
missionStage = nextMS
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Makes Mary Ann say a single line, possibly interrupt conversation
|
|
/// PARAMS:
|
|
/// blockOfText - blockOfText
|
|
/// rootLabel - rootLabel
|
|
/// bShouldInterrupt - if true will stop the conversation to play line
|
|
FUNC BOOL CAN_MARY_ANN_SAY_SINGLE_LINE(STRING blockOfText, STRING rootLabel, BOOL bShouldInterrupt, INT& interruptedLine)
|
|
IF MADialogueState = MA_WITHIN_TALKING_RANGE
|
|
AND NOT IS_MESSAGE_BEING_DISPLAYED()
|
|
if bShouldInterrupt
|
|
IF IS_SCRIPTED_CONVERSATION_ONGOING()
|
|
interruptedLine = GET_CURRENT_SCRIPTED_CONVERSATION_LINE()
|
|
DEBUG_PRINTSTRING("Stopping scripted convo at can Mary Ann say single line")
|
|
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
|
|
CLEAR_PRINTS()
|
|
ENDIF
|
|
IF PLAY_SINGLE_LINE_FROM_CONVERSATION(MyLocalPedStruct, "FAN1AU", blockOfText, rootLabel, CONV_PRIORITY_MEDIUM)
|
|
RETURN TRUE
|
|
ENDIF
|
|
ELSE
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
IF PLAY_SINGLE_LINE_FROM_CONVERSATION(MyLocalPedStruct, "FAN1AU", blockOfText, rootLabel, CONV_PRIORITY_MEDIUM)
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Tries to create a conversation with the given root label and returns true if it triggers - for random lines during the mission
|
|
/// PARAMS:
|
|
/// rootLabel - the label we're trying to play
|
|
/// RETURNS:
|
|
/// TRUE if the conversation plays, FALSE if it fails or can't be played
|
|
FUNC BOOL CAN_MARY_ANN_SAY_RANDOM_LINE(STRING rootLabel)
|
|
IF MADialogueState = MA_WITHIN_TALKING_RANGE
|
|
AND NOT IS_MESSAGE_BEING_DISPLAYED()
|
|
IF CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", rootLabel, CONV_PRIORITY_MEDIUM)
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE: Checks if she can start her standard run conversation, not random comment
|
|
FUNC BOOL CAN_CREATE_RUNNING_CONVERSATION()
|
|
IF MADialogueState = MA_WITHIN_TALKING_RANGE
|
|
AND NOT IS_MESSAGE_BEING_DISPLAYED()
|
|
AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
RETURN TRUE
|
|
ELSE
|
|
RETURN FALSE
|
|
ENDIF
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Play a one-liner for Mary Ann
|
|
PROC PLAY_MARY_ANN_ONE_LINER()
|
|
IF place = 2 // only do a Mary Ann one-liner if the player is behind
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
AND MADialogueState = MA_WITHIN_TALKING_RANGE
|
|
AND NOT IS_MESSAGE_BEING_DISPLAYED()
|
|
IF CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", "FAN1_TAUNT", CONV_PRIORITY_MEDIUM)
|
|
iOneLinerSeq++
|
|
iOneLinerTimer = GET_GAME_TIMER()
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Play a one-liner for Michael
|
|
PROC PLAY_MICHAEL_ONE_LINER()
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
AND MADialogueState = MA_WITHIN_TALKING_RANGE
|
|
AND NOT IS_MESSAGE_BEING_DISPLAYED()
|
|
IF CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", "FAN1_ONELIN", CONV_PRIORITY_MEDIUM)
|
|
iOneLinerSeq++
|
|
iOneLinerTimer = GET_GAME_TIMER()
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Try and play a one-liner for one of the characters
|
|
PROC TRY_ONE_LINER()
|
|
|
|
IF (GET_GAME_TIMER() - iOneLinerTimer) > 10000 // Possibly randomise this value a bit?
|
|
SWITCH iOneLinerSeq
|
|
CASE 0
|
|
PLAY_MARY_ANN_ONE_LINER()
|
|
BREAK
|
|
CASE 1
|
|
PLAY_MICHAEL_ONE_LINER()
|
|
BREAK
|
|
CASE 2
|
|
PLAY_MARY_ANN_ONE_LINER()
|
|
BREAK
|
|
CASE 3
|
|
PLAY_MICHAEL_ONE_LINER()
|
|
BREAK
|
|
CASE 4
|
|
PLAY_MARY_ANN_ONE_LINER()
|
|
BREAK
|
|
CASE 5
|
|
PLAY_MICHAEL_ONE_LINER()
|
|
BREAK
|
|
CASE 6
|
|
PLAY_MARY_ANN_ONE_LINER()
|
|
BREAK
|
|
CASE 7
|
|
PLAY_MICHAEL_ONE_LINER()
|
|
BREAK
|
|
CASE 8
|
|
PLAY_MARY_ANN_ONE_LINER()
|
|
BREAK
|
|
CASE 9
|
|
PLAY_MICHAEL_ONE_LINER()
|
|
BREAK
|
|
DEFAULT
|
|
// No more lines available to play
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Keeps trying to play the keep up or catch up lines while we're waiting for any prior conversation to finish
|
|
PROC TRY_KEEPUP_OR_CATCHUP_LINES()
|
|
|
|
IF MADialogueState = MA_SHOUTING_TO_KEEP_UP
|
|
IF iHurryUpLineNumber < iMAXHurryUpLineNumber
|
|
IF (cheatedRanAcrossGrass.hasBeenPlayed
|
|
OR cheatedLeaptFence.hasBeenPlayed)
|
|
AND missionStage = MS_START_RUNNING
|
|
MADialogueState = MA_OUT_OF_TALKING_RANGE
|
|
DEBUG_PRINTSTRING("MA Dialogue: Now in MA_OUT_OF_TALKING_RANGE")
|
|
ELSE
|
|
IF place = 2 // Only say this if the player is behind
|
|
IF PLAY_SINGLE_LINE_FROM_CONVERSATION(MyLocalPedStruct, "FAN1AU", "FAN1_FALLB", HURRY_UP_LINE[iHurryUpLineNumber], CONV_PRIORITY_HIGH)
|
|
iHurryUpLineNumber++
|
|
MADialogueState = MA_OUT_OF_TALKING_RANGE
|
|
DEBUG_PRINTSTRING("MA Dialogue: Played keep up line, now in MA_OUT_OF_TALKING_RANGE")
|
|
ENDIF
|
|
ELSE
|
|
MADialogueState = MA_OUT_OF_TALKING_RANGE
|
|
DEBUG_PRINTSTRING("MA Dialogue: Player in 1st place so no need for keep up line, now in MA_OUT_OF_TALKING_RANGE")
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
DEBUG_PRINTSTRING("MA Dialogue: Said all keep up lines, now in MA_OUT_OF_TALKING_RANGE")
|
|
MADialogueState = MA_OUT_OF_TALKING_RANGE
|
|
ENDIF
|
|
ELIF MADialogueState = MA_SAYING_YOU_CAUGHT_UP
|
|
IF iCatchUpLineNumber < iMAXCatchUpLineNumber
|
|
IF (cheatedRanAcrossGrass.hasBeenPlayed
|
|
OR cheatedLeaptFence.hasBeenPlayed)
|
|
AND missionStage = MS_START_RUNNING
|
|
IF bCatchupCheatLineSaid = FALSE
|
|
IF CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", "FAN1_CATCHC", CONV_PRIORITY_HIGH)
|
|
bCatchupCheatLineSaid = TRUE
|
|
b_CheatedLine = FALSE // Stop the other cheated line from playing if we've done this instead
|
|
ENDIF
|
|
ENDIF
|
|
MADialogueState = MA_WITHIN_TALKING_RANGE
|
|
DEBUG_PRINTSTRING("MA Dialogue: Now in MA_WITHIN_TALKING_RANGE")
|
|
ELSE
|
|
IF place = 2 // Only say this if the player is behind
|
|
IF CAN_MARY_ANN_SAY_RANDOM_LINE("FAN1_CATCHU")
|
|
iCatchUpLineNumber++
|
|
MADialogueState = MA_WITHIN_TALKING_RANGE
|
|
DEBUG_PRINTSTRING("MA Dialogue: Played catchup line, now in MA_WITHIN_TALKING_RANGE")
|
|
ENDIF
|
|
ELSE
|
|
MADialogueState = MA_WITHIN_TALKING_RANGE
|
|
DEBUG_PRINTSTRING("MA Dialogue: Player in 1st place so no need for catchup line, now in MA_WITHIN_TALKING_RANGE")
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// This function switches her Dialogue State and plays a "Catch up" line if player gets too far, or "Welcome back" line if they catch up.
|
|
/// The dialogue state is used to make sure she is nearby before talking
|
|
PROC SET_MARY_ANN_DIALOGUE_STATE(MARY_ANN_DIALOGUE_STATE newState)
|
|
IF MADialogueState <> newState
|
|
SWITCH MADialogueState
|
|
|
|
CASE MA_WITHIN_TALKING_RANGE
|
|
IF newstate = MA_OUT_OF_TALKING_RANGE
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
KILL_ANY_CONVERSATION()
|
|
ENDIF
|
|
DEBUG_PRINTSTRING("MA Dialogue: Kill convo, switch to MA_OUT_OF_TALKING_RANGE, trying keep up line if possible")
|
|
MADialogueState = MA_SHOUTING_TO_KEEP_UP
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE MA_OUT_OF_TALKING_RANGE
|
|
IF newstate = MA_WITHIN_TALKING_RANGE
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
KILL_ANY_CONVERSATION()
|
|
ENDIF
|
|
DEBUG_PRINTSTRING("MA Dialogue: Kill convo, switch to MA_WITHIN_TALKING_RANGE, trying you caught up line if possible")
|
|
MADialogueState = MA_SAYING_YOU_CAUGHT_UP
|
|
ENDIF
|
|
BREAK
|
|
|
|
// Shouting to keep up and Saying you caught up now handled in TRY_KEEPUP_OR_CATCHUP_LINES()
|
|
|
|
ENDSWITCH
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
PROC TELEPORT_STUCK_MARY_ANN(int iTeleportTo)
|
|
VECTOR vTeleCoord
|
|
FLOAT fNewHeading
|
|
WAYPOINT_RECORDING_GET_COORD(sFANATIC_ROUTE, iTeleportTo, vTeleCoord)
|
|
|
|
VECTOR vNextCoord
|
|
WAYPOINT_RECORDING_GET_COORD(sFANATIC_ROUTE, iTeleportTo+1, vNextCoord)
|
|
fNewHeading = GET_HEADING_FROM_COORDS(vTeleCoord, vNextCoord)
|
|
|
|
SAFE_TELEPORT_ENTITY(MARY_ANN, vTeleCoord, fNewHeading, TRUE)
|
|
IF iTeleportTo < 6
|
|
iNPC_RACE_POS = 1
|
|
ELIF iTeleportTo < 30
|
|
iNPC_RACE_POS = 1
|
|
ELIF iTeleportTo < 36
|
|
iNPC_RACE_POS = 2
|
|
ELIF iTeleportTo < 48
|
|
iNPC_RACE_POS = 3
|
|
ELIF iTeleportTo < 62
|
|
iNPC_RACE_POS = 4
|
|
ELIF iTeleportTo < 81
|
|
iNPC_RACE_POS = 5
|
|
ELIF iTeleportTo < 95
|
|
iNPC_RACE_POS = 6
|
|
ELIF iTeleportTo < 106
|
|
iNPC_RACE_POS = 7
|
|
ELSE
|
|
iNPC_RACE_POS = 8
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
PROC CHECK_FOR_GETTING_STUCK()
|
|
switch StuckStage
|
|
CASE STUCK_UPDATE
|
|
// Change the waypoint we're checking to Mary Ann's the nearest one
|
|
iWaypointStuckCheck = iNum_NPCClosestWaypoint
|
|
iStuckTimer = GET_GAME_TIMER()
|
|
StuckStage = STUCK_LOOP
|
|
BREAK
|
|
CASE STUCK_LOOP
|
|
IF iWaypointStuckCheck = iNum_NPCClosestWaypoint
|
|
IF (GET_GAME_TIMER() - iStuckTimer) > 20000 // If Mary Ann's closest waypoint doesn't change for 20 secs, something needs fixing
|
|
DEBUG_PRINTSTRING("Mary Ann got stuck!")
|
|
StuckStage = STUCK_FIX
|
|
ENDIF
|
|
ELSE
|
|
StuckStage = STUCK_UPDATE // If the closest waypoint doesn't match anymore, update it
|
|
ENDIF
|
|
BREAK
|
|
CASE STUCK_FIX
|
|
INT iMaxPoints
|
|
WAYPOINT_RECORDING_GET_NUM_POINTS(sFANATIC_ROUTE, iMaxPoints)
|
|
IF (iWaypointStuckCheck+4) > iMaxPoints
|
|
TELEPORT_STUCK_MARY_ANN(iMaxPoints-1) // Teleport to the one before last waypoint so there's somewhere to go
|
|
ELSE
|
|
TELEPORT_STUCK_MARY_ANN(iWaypointStuckCheck+4)
|
|
ENDIF
|
|
KEEP_RUNNING(missionStage, FALSE) // This isn't a debug teleport, so don't do the stage-skippy stuff
|
|
StuckStage = STUCK_UPDATE
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Speed Mary Ann up where required at a constantly increasing ratio until it hits a cap
|
|
PROC SPEED_MARY_ANN_UP()
|
|
fMBR_IncreaseRatio += GET_FRAME_TIME()/20
|
|
IF fMBR_IncreaseRatio > fMBRMax
|
|
fMBR_IncreaseRatio = fMBRMax
|
|
ENDIF
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF bDebug_SpeedDebug
|
|
//DEBUG_PRINTSF("SPEED UP: fMBR_IncreaseRatio = ", fMBR_IncreaseRatio)
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
fMBR_RunSpeed += 0.02
|
|
IF fMBR_RunSpeed > fMBR_MaxRunSpeed
|
|
fMBR_RunSpeed = fMBR_MaxRunSpeed
|
|
ENDIF
|
|
//
|
|
#IF IS_DEBUG_BUILD
|
|
IF bDebug_SpeedDebug
|
|
IF MASprintState <> SPRINT_ACTIVE
|
|
DEBUG_PRINTSF("SPEED UP: fMBR_RunSpeed = ", fMBR_RunSpeed)
|
|
ENDIF
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Slow Mary Ann down where required at a constantly increasing ratio until it hits a cap
|
|
PROC SLOW_MARY_ANN_DOWN()
|
|
IF fMBR_IncreaseRatio > 1
|
|
fMBR_IncreaseRatio -= 0.02
|
|
ELSE
|
|
fMBR_IncreaseRatio = 1
|
|
ENDIF
|
|
|
|
// Re-cap
|
|
IF fMBR_IncreaseRatio > fMBRMax
|
|
fMBR_IncreaseRatio = fMBRMax
|
|
ENDIF
|
|
|
|
FLOAT slowDownValue
|
|
|
|
slowDownValue = 4.5 - (GET_DISTANCE_BETWEEN_PEDS(PLAYER_PED_ID(), MARY_ANN)/2)
|
|
IF slowDownValue < 1.8
|
|
slowDownValue = 1.8
|
|
ELIF slowDownValue > fMBR_MaxRunSpeed
|
|
slowDownValue = fMBR_MaxRunSpeed
|
|
ENDIF
|
|
|
|
IF fMBR_RunSpeed > slowDownValue
|
|
fMBR_RunSpeed -= 0.01
|
|
ELSE
|
|
fMBR_RunSpeed = slowDownValue
|
|
ENDIF
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF bDebug_SpeedDebug
|
|
IF MASprintState <> SPRINT_ACTIVE
|
|
DEBUG_PRINTSF("SLOW DOWN: fMBR_RunSpeed = ", fMBR_RunSpeed)
|
|
ENDIF
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Because of B*886738, we need to keep Mary Ann sprinting for a few seconds whenever she goes >2.5 MBR, so she doesn't quickly slow down again and keep jerking
|
|
/// back and forth between her running and sprint animations as her MBR keeps flicking above and below 2.5MBR
|
|
PROC HANDLE_SPRINT_BOOST()
|
|
|
|
SWITCH MASprintState
|
|
CASE SPRINT_WAITING
|
|
IF IS_ENTITY_ALIVE(MARY_ANN)
|
|
// Don't do the sprint if Mary Ann is in this area (basically on the steps down to the bridge) - tries to prevent B*1426943
|
|
IF NOT IS_ENTITY_IN_ANGLED_AREA(MARY_ANN, <<-1809.172852,-549.010559,14.031675>>, <<-1841.728638,-529.457520,33.641205>>, 21.75)
|
|
IF fMBR_RunSpeed >= 2.5
|
|
IF IS_ENTITY_ALIVE(MARY_ANN)
|
|
TASK_LOOK_AT_ENTITY(MARY_ANN, PLAYER_PED_ID(), 1500, SLF_WIDEST_PITCH_LIMIT|SLF_WIDEST_YAW_LIMIT|SLF_USE_TORSO|SLF_WHILE_NOT_IN_FOV, SLF_LOOKAT_VERY_HIGH)
|
|
ENDIF
|
|
fMBR_SprintCap = fMBR_RunSpeed
|
|
MASprintState = SPRINT_ACTIVE
|
|
iSprintTimer = GET_GAME_TIMER()
|
|
#IF IS_DEBUG_BUILD
|
|
IF bDebug_SpeedDebug
|
|
DEBUG_PRINTSTRING("*** SPRINT BOOST ACTIVE")
|
|
ENDIF
|
|
#ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE SPRINT_ACTIVE
|
|
IF (GET_GAME_TIMER() - iSprintTimer) < iSprintLength
|
|
IF fMBR_SprintCap < fMBR_RunSpeed
|
|
fMBR_SprintCap = fMBR_RunSpeed
|
|
ENDIF
|
|
ELSE
|
|
fMBR_RunSpeed = fMBR_SprintCap
|
|
#IF IS_DEBUG_BUILD
|
|
IF bDebug_SpeedDebug
|
|
DEBUG_PRINTSTRING("*** SPRINT BOOST REDUCE")
|
|
ENDIF
|
|
#ENDIF
|
|
MASprintState = SPRINT_REDUCE
|
|
ENDIF
|
|
BREAK
|
|
CASE SPRINT_REDUCE
|
|
// Gradually reduce Mary Ann's speed if she's ahead
|
|
IF place = 2
|
|
IF fMBR_RunSpeed > 2.49
|
|
fMBR_RunSpeed -= 0.002
|
|
ELSE
|
|
#IF IS_DEBUG_BUILD
|
|
IF bDebug_SpeedDebug
|
|
DEBUG_PRINTSTRING("*** SPRINT BOOST COOLDOWN")
|
|
ENDIF
|
|
#ENDIF
|
|
MASprintState = SPRINT_COOLDOWN
|
|
iSprintTimer = GET_GAME_TIMER()
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE SPRINT_COOLDOWN
|
|
IF (GET_GAME_TIMER() - iSprintTimer) > iSprintDelay
|
|
DEBUG_PRINTSTRING("*** SPRINT BOOST WAITING")
|
|
MASprintState = SPRINT_WAITING
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Handles the rubber-banding behaviour in the final section
|
|
PROC DO_MA_FINISH_SPRINT_STYLE()
|
|
|
|
CONST_FLOAT fBehindMaxSpeed 2.55
|
|
|
|
IF IS_ENTITY_ALIVE(MARY_ANN)
|
|
IF place = 2
|
|
// IF IS_PED_SPRINTING(PLAYER_PED_ID())
|
|
// FLOAT fSprintTimeLeft = GET_PLAYER_SPRINT_TIME_REMAINING(PLAYER_ID())
|
|
//
|
|
// ENDIF
|
|
|
|
FLOAT fDistance = GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), MARY_ANN)
|
|
IF fDistance < 15
|
|
FLOAT fSpeedReduce = fDistance / 100
|
|
IF fMBR_RunSpeed > 2.42
|
|
fMBR_RunSpeed -= fSpeedReduce
|
|
ENDIF
|
|
ELSE
|
|
IF fMBR_RunSpeed < 2.52
|
|
fMBR_RunSpeed += 0.002
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
FLOAT fDistance = GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), MARY_ANN)
|
|
// FLOAT fPlayerMBR = GET_PED_DESIRED_MOVE_BLEND_RATIO(PLAYER_PED_ID())
|
|
FLOAT fSpeedModifier = fDistance / 300
|
|
IF fDistance < 10
|
|
// IF fMBR_RunSpeed < fPlayerMBR
|
|
// fMBR_RunSpeed += fSpeedModifier
|
|
// ELIF fMBR_RunSpeed > fPlayerMBR
|
|
// fMBR_RunSpeed -= fSpeedModifier
|
|
// ENDIF
|
|
|
|
// Have a minimum speed that Mary Ann can run at, so the player can't jog and win
|
|
IF fMBR_RunSpeed < 2.487
|
|
fMBR_RunSpeed += 0.002
|
|
// But also have a max speed so she can be outrun
|
|
ELIF fMBR_RunSpeed > 2.492
|
|
fMBR_RunSpeed -= 0.002
|
|
ENDIF
|
|
ELSE
|
|
IF fMBR_RunSpeed < fBehindMaxSpeed
|
|
fMBR_RunSpeed += fSpeedModifier
|
|
ELIF fMBR_RunSpeed > fBehindMaxSpeed
|
|
fMBR_RunSpeed -= fSpeedModifier
|
|
ENDIF
|
|
|
|
IF fMBR_RunSpeed > 3.0
|
|
fMBR_RunSpeed = 3.0
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
#IF IS_DEBUG_BUILD
|
|
IF bDebug_SpeedDebug
|
|
DEBUG_PRINTSF("RACE TO FINISH SPEED: fMBR_RunSpeed = ", fMBR_RunSpeed)
|
|
ENDIF
|
|
#ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Handles the normal rubber-banding behaviour
|
|
PROC DO_MA_RUBBER_BANDING()
|
|
IF iNum_PlayerClosestWaypoint = iNum_NPCClosestWaypoint
|
|
vector nextPoint
|
|
WAYPOINT_RECORDING_GET_COORD(sFANATIC_ROUTE, iNum_NPCClosestWaypoint + 1, nextPoint)
|
|
IF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), nextPoint) < GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(MARY_ANN, nextPoint)
|
|
SPEED_MARY_ANN_UP()
|
|
ELSE
|
|
SLOW_MARY_ANN_DOWN()
|
|
ENDIF
|
|
ELIF iNum_PlayerClosestWaypoint > iNum_NPCClosestWaypoint
|
|
SPEED_MARY_ANN_UP()
|
|
ELSE
|
|
SLOW_MARY_ANN_DOWN()
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Update Mary Ann's running speed every frame
|
|
PROC UPDATE_HER_RUN_SPEED()
|
|
|
|
IF missionStage <> MS_END_CUTSCENE
|
|
IF missionStage = MS_SPRINT_TO_FINISH
|
|
|
|
MASprintState = SPRINT_COOLDOWN // Ensure the sprint boost is never active here
|
|
DO_MA_FINISH_SPRINT_STYLE()
|
|
|
|
ELSE
|
|
// Don't do the normal rubber banding stuff if Mary Ann is reducing her speed
|
|
IF MASprintState <> SPRINT_REDUCE
|
|
DO_MA_RUBBER_BANDING()
|
|
// Otherwise, if she's meant to be reducing her speed but is behind the player, do the rubber banding stuff anyway
|
|
ELIF place = 1
|
|
DO_MA_RUBBER_BANDING()
|
|
ENDIF
|
|
|
|
// The SPRINT_REDUCE stage will skip over reducing her speed if she's behind
|
|
HANDLE_SPRINT_BOOST()
|
|
|
|
ENDIF
|
|
|
|
// Prints for Mary Ann
|
|
#IF IS_DEBUG_BUILD
|
|
IF bDebug_SpeedDebug
|
|
IF MASprintState = SPRINT_WAITING
|
|
//DEBUG_PRINTSF("SPRINT WAITING SPEED: fMBR_RunSpeed = ", fMBR_RunSpeed)
|
|
ELIF MASprintState = SPRINT_ACTIVE
|
|
DEBUG_PRINTSF("SPRINT ACTIVE SPEED: fMBR_SprintCap = ", fMBR_SprintCap)
|
|
ELIF MASprintState = SPRINT_REDUCE
|
|
DEBUG_PRINTSF("SPRINT REDUCE SPEED: fMBR_RunSpeed = ", fMBR_RunSpeed)
|
|
ELIF MASprintState = SPRINT_COOLDOWN
|
|
//DEBUG_PRINTSF("SPRINT COOLDOWN SPEED: fMBR_RunSpeed = ", fMBR_RunSpeed)
|
|
ENDIF
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
IF IS_WAYPOINT_PLAYBACK_GOING_ON_FOR_PED(MARY_ANN)
|
|
// If the sprint boost (to stop 886738) is active, use the sprint cap value instead of the calculated fMBR_RunSpeed
|
|
IF MASprintState = SPRINT_ACTIVE
|
|
WAYPOINT_PLAYBACK_OVERRIDE_SPEED(MARY_ANN, fMBR_SprintCap)
|
|
ELSE
|
|
WAYPOINT_PLAYBACK_OVERRIDE_SPEED(MARY_ANN, fMBR_RunSpeed)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// SHE HAS A MINIMUM SPEED SO THAT SHE CAN RUN DOWN THE STEPS QUICKLY LIKE THE PLAYER. SHOULD BE A TEMP FIX WHILE CODE SORTS THIS
|
|
SET_PED_MIN_MOVE_BLEND_RATIO(MARY_ANN, fMBR_RunSpeed - 0.5)
|
|
|
|
SET_PED_MOVE_RATE_OVERRIDE(MARY_ANN, fMBR_IncreaseRatio)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Check to make a ped ragdoll if Mary Ann collides with them
|
|
PROC CHECK_IF_MARY_ANN_RUNS_INTO_A_PED()
|
|
IF HAS_ENTITY_COLLIDED_WITH_ANYTHING(MARY_ANN)
|
|
PED_INDEX ped
|
|
GET_CLOSEST_PED(GET_ENTITY_COORDS(MARY_ANN), 0.75, TRUE, TRUE, ped)
|
|
IF DOES_ENTITY_EXIST(ped)
|
|
AND NOT IS_ENTITY_DEAD(ped)
|
|
IF NOT IS_PED_RAGDOLL(ped)
|
|
AND IS_ENTITY_TOUCHING_ENTITY(MARY_ANN, ped)
|
|
CLEAR_PED_TASKS(ped)
|
|
SET_PED_TO_RAGDOLL(ped, 800, 1500, TASK_NM_BALANCE)
|
|
VECTOR pushDir = -GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(MARY_ANN, GET_ENTITY_COORDS(ped))
|
|
APPLY_FORCE_TO_ENTITY(ped, APPLY_TYPE_IMPULSE, pushDir, <<0,0,0>>, GET_PED_RAGDOLL_BONE_INDEX(ped, RAGDOLL_SPINE), FALSE, FALSE, TRUE)
|
|
|
|
if not IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
IF PED_HAS_SEXINESS_FLAG_SET(ped, SF_HOT_PERSON)
|
|
IF pushLine[2].hasBeenPlayed = FALSE
|
|
INT temp
|
|
IF CAN_MARY_ANN_SAY_SINGLE_LINE("FAN1_PUSH", pushLine[2].dialogueLine, FALSE, temp)
|
|
pushLine[2].hasBeenPlayed = TRUE
|
|
ENDIF
|
|
ELSE
|
|
IF pushLine[0].hasBeenPlayed = FALSE
|
|
INT temp
|
|
IF CAN_MARY_ANN_SAY_SINGLE_LINE("FAN1_PUSH", pushLine[0].dialogueLine, FALSE, temp)
|
|
pushLine[0].hasBeenPlayed = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
IF pushLine[1].hasBeenPlayed = FALSE
|
|
INT temp
|
|
IF CAN_MARY_ANN_SAY_SINGLE_LINE("FAN1_PUSH", pushLine[1].dialogueLine, FALSE, temp)
|
|
pushLine[1].hasBeenPlayed = TRUE
|
|
ENDIF
|
|
ELSE
|
|
IF pushLine[0].hasBeenPlayed = FALSE
|
|
INT temp
|
|
IF CAN_MARY_ANN_SAY_SINGLE_LINE("FAN1_PUSH", pushLine[0].dialogueLine, FALSE, temp)
|
|
pushLine[0].hasBeenPlayed = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
//DEBUG_PRINTSTRING("SHE COLLIDED WITH SOMETHING")
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Large, encompassing process to control Mary Ann's behaviour throughout the mission
|
|
PROC DEAL_WITH_MARY_ANN()
|
|
IF IS_PED_UNINJURED(MARY_ANN)
|
|
|
|
IF missionStage <> MS_END_CUTSCENE
|
|
CHECK_IF_MARY_ANN_RUNS_INTO_A_PED()
|
|
ELSE
|
|
// B*1765019 - If player manages to make Mary Ann quit her task, keep retasking her until she gets on the goddamn bike
|
|
IF cutsceneStage >= CS_SAY_FINAL_LINE
|
|
IF NOT IsPedPerformingTask(MARY_ANN, SCRIPT_TASK_PERFORM_SEQUENCE)
|
|
AND NOT b_PlayerOnMAsBike
|
|
IF IS_VEHICLE_OK(MAS_BIKE)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_ENTER_VEHICLE(NULL, MAS_BIKE, DEFAULT_TIME_BEFORE_WARP, VS_DRIVER, PEDMOVEBLENDRATIO_RUN)
|
|
TASK_CLEAR_LOOK_AT(NULL)
|
|
TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), 2000)
|
|
TASK_VEHICLE_DRIVE_TO_COORD(NULL, MAS_BIKE, <<-2018.17, -461.00, 10.56>>, 10, DRIVINGSTYLE_NORMAL, MARYSBIKEMODEL, DF_SteerAroundStationaryCars, 3, 50)
|
|
TASK_VEHICLE_DRIVE_TO_COORD(NULL, MAS_BIKE, <<-2014.96, -455.47, 10.48>>, 10, DRIVINGSTYLE_NORMAL, MARYSBIKEMODEL, DF_SteerAroundStationaryCars, 3, 50)
|
|
TASK_VEHICLE_DRIVE_WANDER(NULL, MAS_BIKE, 10, DRIVINGMODE_AVOIDCARS_STOPFORPEDS_OBEYLIGHTS)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(MARY_ANN, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
SET_PED_KEEP_TASK(MARY_ANN, TRUE)
|
|
DEBUG_PRINTSTRING("Emergency retasked Mary Ann!")
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
TRY_KEEPUP_OR_CATCHUP_LINES() // Keep trying to play these lines if we're waiting for a prior conversation to finish
|
|
|
|
// If she gets far from the player we need to load the world around her so that she keeps running
|
|
IF GET_DISTANCE_BETWEEN_PEDS(PLAYER_PED_ID(), MARY_ANN) > 80
|
|
IF b_LoadCollisionAroudMaryAnn = FALSE
|
|
SET_ENTITY_LOAD_COLLISION_FLAG(MARY_ANN, TRUE)
|
|
b_LoadCollisionAroudMaryAnn = TRUE
|
|
ENDIF
|
|
ELSE
|
|
IF b_LoadCollisionAroudMaryAnn = TRUE
|
|
SET_ENTITY_LOAD_COLLISION_FLAG(MARY_ANN, FALSE)
|
|
b_LoadCollisionAroudMaryAnn = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF missionStage <> MS_END_CUTSCENE
|
|
AND missionStage <> MS_PLAYER_IN_VEHICLE
|
|
AND missionStage <> MS_LOST_RACE
|
|
IF MADialogueState <> MA_OUT_OF_TALKING_RANGE
|
|
IF GET_DISTANCE_BETWEEN_PEDS(PLAYER_PED_ID(), MARY_ANN) > 25
|
|
SET_MARY_ANN_DIALOGUE_STATE(MA_OUT_OF_TALKING_RANGE)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF MADialogueState <> MA_WITHIN_TALKING_RANGE
|
|
IF GET_DISTANCE_BETWEEN_PEDS(PLAYER_PED_ID(), MARY_ANN) < 24
|
|
SET_MARY_ANN_DIALOGUE_STATE(MA_WITHIN_TALKING_RANGE)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
UPDATE_HER_RUN_SPEED()
|
|
|
|
IF missionStage <> MS_END_CUTSCENE
|
|
AND missionStage <> MS_CUTSCENE
|
|
AND missionStage <> MS_LOST_RACE
|
|
IF NOT IS_ENTITY_IN_ANGLED_AREA(MARY_ANN, <<-1809.172852,-549.010559,14.031675>>, <<-1841.728638,-529.457520,33.641205>>, 21.75)
|
|
IF b_DoPedOvertake = FALSE
|
|
SET_PED_STEERS_AROUND_PEDS(MARY_ANN, true)
|
|
b_DoPedOvertake = TRUE
|
|
DEBUG_PRINTSTRING("Set Mary Ann to steer round peds")
|
|
ENDIF
|
|
ELSE
|
|
IF b_DoPedOvertake = TRUE
|
|
SET_PED_STEERS_AROUND_PEDS(MARY_ANN, FALSE)
|
|
b_DoPedOvertake = FALSE
|
|
DEBUG_PRINTSTRING("Unset Mary Ann to steer round peds")
|
|
ENDIF
|
|
ENDIF
|
|
CHECK_FOR_GETTING_STUCK()
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Set all the models we may have requested as no longer needed
|
|
PROC UNLOAD_ALL_MODELS()
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(G_M_Y_SALVAGOON_01)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(JOGGERMODEL)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(A_M_Y_BEACH_01)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(A_F_Y_BEACH_01)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(A_C_ROTTWEILER)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(S_M_Y_BayWatch_01)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(IG_MARYANN)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(MARYSBIKEMODEL)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(BLAZER2)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(BANSHEE)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(REGINA)
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Part of the race tracking might check the distance between Michael and Mary Ann's next checkpoint in order to determine who is in front
|
|
/// The problem is that if the player is just in front and has just hit a CP, Mary Ann may be very close to that CP behind Michael,
|
|
/// so the check thinks that Mary Ann in 1st position because she is closer to "her" CP (until she hits it, and it starts checking the same CP again)
|
|
/// Instead of checking each individual's CP, let's check the one furthest away and return that
|
|
/// RETURNS:
|
|
/// The furthest away checkpoint
|
|
FUNC INT RETURN_FURTHEST_CHECKPOINT()
|
|
IF iCURRENT_RACE_POS > iNPC_RACE_POS
|
|
IF iCURRENT_RACE_POS >= MAX_CHECKPOINTS
|
|
RETURN 9
|
|
ELSE
|
|
RETURN iCURRENT_RACE_POS
|
|
ENDIF
|
|
ELSE
|
|
IF iNPC_RACE_POS >= MAX_CHECKPOINTS
|
|
RETURN 9
|
|
ELSE
|
|
RETURN iNPC_RACE_POS
|
|
ENDIF
|
|
ENDIF
|
|
ENDFUNC
|
|
|
|
/// PURPOSE: Control the race checkpoints througout the mission as it progresses
|
|
PROC DEAL_WITH_RACE_BLIPS()
|
|
|
|
HUD_COLOURS currentCPColour
|
|
INT iR, iG, iB, iA
|
|
INT PreviR, PreviG, PreviB
|
|
|
|
IF iCURRENT_RACE_POS < iMaxRacePositions
|
|
|
|
IF iCURRENT_RACE_POS < iMaxRacePositions - 1
|
|
IF IS_ENTITY_AT_COORD(PLAYER_PED_ID(), RACE_POSITIONS[iCURRENT_RACE_POS], <<4,4,3>>)
|
|
OR NOT DOES_BLIP_EXIST(DESTINATION_BLIP)
|
|
|
|
SAFE_REMOVE_BLIP(DESTINATION_BLIP)
|
|
SAFE_REMOVE_BLIP(NEXT_DESTINATION_BLIP)
|
|
|
|
IF checkPoint != NULL
|
|
DEBUG_PRINTSTRING("Create prev CP")
|
|
iPrevAlpha = 180
|
|
currentCPColour = HUD_COLOUR_WHITE
|
|
GET_HUD_COLOUR(currentCPColour, PreviR, PreviG, PreviB, iPrevAlpha)
|
|
PrevCheckpoint = CREATE_CHECKPOINT(GET_RACE_CHECKPOINT_TYPE(iCURRENT_RACE_POS), RACE_POSITIONS[iCURRENT_RACE_POS]+<<0, 0, 2.0>>, RACE_POSITIONS[iCURRENT_RACE_POS + 1], 3.2, PreviR, PreviG, PreviB, iPrevAlpha)
|
|
SET_CHECKPOINT_RGBA(PrevCheckpoint, PreviR, PreviG, PreviB, iPrevAlpha)
|
|
SET_CHECKPOINT_RGBA2(PrevCheckpoint, PreviR,PreviG, PreviB, iPrevAlpha)
|
|
ENDIF
|
|
|
|
DELETE_CHECKPOINT(checkPoint)
|
|
|
|
IF iCURRENT_RACE_POS != 0
|
|
// Play the checkpoint sound - only want to do this after the very first pass through, otherwise we get the sfx after the cutscene
|
|
PLAY_SOUND_FRONTEND(-1, "CHECKPOINT_NORMAL", "HUD_MINI_GAME_SOUNDSET", FALSE)
|
|
ENDIF
|
|
|
|
iCURRENT_RACE_POS++
|
|
|
|
// If we're not at the final checkpoint, do a small blip for the next one too
|
|
IF iCURRENT_RACE_POS < iMaxRacePositions - 1
|
|
checkpoint = CREATE_CHECKPOINT(GET_RACE_CHECKPOINT_TYPE(iCURRENT_RACE_POS), RACE_POSITIONS[iCURRENT_RACE_POS]+<<0, 0, 2.0>>, RACE_POSITIONS[iCURRENT_RACE_POS + 1], 3.2, iR, iG, iB, iA)
|
|
SET_CHECKPOINT_CYLINDER_HEIGHT(checkpoint,1.6,1.6,100)
|
|
|
|
currentCPColour = HUD_COLOUR_YELLOWLIGHT
|
|
GET_HUD_COLOUR(currentCPColour, iR, iG, iB, iA)
|
|
SET_CHECKPOINT_RGBA(checkpoint, iR, iG, iB, iA)
|
|
|
|
currentCPColour = HUD_COLOUR_NORTH_BLUE
|
|
GET_HUD_COLOUR(currentCPColour, iR, iG, iB, iA)
|
|
SET_CHECKPOINT_RGBA2(checkpoint, iR, iG, iB, iA)
|
|
|
|
DESTINATION_BLIP = ADD_BLIP_FOR_COORD(RACE_POSITIONS[iCURRENT_RACE_POS])
|
|
SHOW_HEIGHT_ON_BLIP(DESTINATION_BLIP, FALSE)
|
|
SET_BLIP_SCALE(DESTINATION_BLIP, 1.2)
|
|
NEXT_DESTINATION_BLIP = ADD_BLIP_FOR_COORD(RACE_POSITIONS[iCURRENT_RACE_POS + 1])
|
|
IF (iCURRENT_RACE_POS + 1) = iMaxRacePositions - 1
|
|
SET_BLIP_SCALE(NEXT_DESTINATION_BLIP, 1.2) // The final next-checkpoint blip has a scale of 1.2
|
|
SET_BLIP_SPRITE(NEXT_DESTINATION_BLIP, RADAR_TRACE_RACEFLAG)
|
|
SHOW_HEIGHT_ON_BLIP(NEXT_DESTINATION_BLIP, FALSE)
|
|
ELSE
|
|
SET_BLIP_SCALE(NEXT_DESTINATION_BLIP, 0.7)
|
|
SHOW_HEIGHT_ON_BLIP(NEXT_DESTINATION_BLIP, FALSE)
|
|
ENDIF
|
|
ELIF iCURRENT_RACE_POS = iMaxRacePositions - 1
|
|
currentCPColour = GET_RACE_CHECKPOINT_COLOUR(GET_RACE_CHECKPOINT_TYPE(iCURRENT_RACE_POS))
|
|
GET_HUD_COLOUR(currentCPColour, iR, iG, iB, iA)
|
|
checkpoint = CREATE_CHECKPOINT(GET_RACE_CHECKPOINT_TYPE(iCURRENT_RACE_POS), RACE_POSITIONS[iCURRENT_RACE_POS]+<<0, 0, 2.0>>, RACE_POSITIONS[iCURRENT_RACE_POS], 3.2, iR, iG, iB, iA)
|
|
SET_CHECKPOINT_CYLINDER_HEIGHT(checkpoint,1.6,1.6,100)
|
|
DESTINATION_BLIP = ADD_BLIP_FOR_COORD(RACE_POSITIONS[iCURRENT_RACE_POS])
|
|
SET_BLIP_SCALE(DESTINATION_BLIP, 1.2)
|
|
SET_BLIP_SPRITE(DESTINATION_BLIP, RADAR_TRACE_RACEFLAG)
|
|
SHOW_HEIGHT_ON_BLIP(DESTINATION_BLIP, FALSE)
|
|
ENDIF
|
|
|
|
ENDIF
|
|
ELSE
|
|
IF iCURRENT_RACE_POS = iMaxRacePositions - 1
|
|
IF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), vPos_FinishLine) < 4
|
|
IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
|
|
|
|
IF checkPoint != NULL
|
|
DEBUG_PRINTSTRING("Create prev CP")
|
|
iPrevAlpha = 180
|
|
currentCPColour = HUD_COLOUR_WHITE
|
|
GET_HUD_COLOUR(currentCPColour, PreviR, PreviG, PreviB, iPrevAlpha)
|
|
PrevCheckpoint = CREATE_CHECKPOINT(CHECKPOINT_RACE_GROUND_FLAG, RACE_POSITIONS[iCURRENT_RACE_POS]+<<0, 0, 2.0>>, RACE_POSITIONS[iCURRENT_RACE_POS], 3.2, PreviR, PreviG, PreviB, iPrevAlpha)
|
|
SET_CHECKPOINT_RGBA(PrevCheckpoint, PreviR, PreviG, PreviB, iPrevAlpha)
|
|
SET_CHECKPOINT_RGBA2(PrevCheckpoint, PreviR,PreviG, PreviB, iPrevAlpha)
|
|
ENDIF
|
|
|
|
// Play the checkpoint sound
|
|
PLAY_SOUND_FRONTEND(-1, "CHECKPOINT_NORMAL", "HUD_MINI_GAME_SOUNDSET", FALSE)
|
|
cutsceneStage = CS_WAIT_FOR_ANN
|
|
stageStage = SS_SETUP
|
|
missionStage = MS_END_CUTSCENE
|
|
DEBUG_PRINTSTRING("PLAYER_AT_FINISH_LINE")
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID())
|
|
FLOAT fDis = GET_DISTANCE_BETWEEN_COORDS(RACE_POSITIONS[iCURRENT_RACE_POS],GET_ENTITY_COORDS(PLAYER_PED_ID()))
|
|
|
|
IF checkpoint != NULL // Make sure the checkpoint exists first
|
|
IF fDis > 100.0
|
|
iA = 240
|
|
currentCPColour = HUD_COLOUR_YELLOWLIGHT
|
|
GET_HUD_COLOUR(currentCPColour, iR, iG, iB, iA)
|
|
SET_CHECKPOINT_RGBA(checkpoint, iR, iG, iB, iA)
|
|
currentCPColour = HUD_COLOUR_NORTH_BLUE
|
|
GET_HUD_COLOUR(currentCPColour, iR, iG, iB, iA)
|
|
SET_CHECKPOINT_RGBA2(checkpoint, iR, iG, iB, iA)
|
|
ELSE
|
|
//DEBUG_PRINTSTRING("Dim current CP")
|
|
currentCPColour = HUD_COLOUR_YELLOWLIGHT
|
|
GET_HUD_COLOUR(currentCPColour, iR, iG, iB, iA)
|
|
iA = ROUND(fDis*2.4)
|
|
IF iA < 60
|
|
iA = 60
|
|
ENDIF
|
|
SET_CHECKPOINT_RGBA(checkpoint, iR, iG, iB, iA)
|
|
currentCPColour = HUD_COLOUR_NORTH_BLUE
|
|
GET_HUD_COLOUR(currentCPColour, 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
|
|
|
|
IF PrevCheckpoint != NULL
|
|
//DEBUG_PRINTSTRING("Fade previous CP")
|
|
iPrevAlpha -= 25
|
|
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 iNPC_RACE_POS < iMaxRacePositions
|
|
IF IS_ENTITY_AT_COORD(MARY_ANN, RACE_POSITIONS[iNPC_RACE_POS], <<3,3,3>>)
|
|
iNPC_RACE_POS++
|
|
ENDIF
|
|
ENDIF
|
|
/*
|
|
DEBUG_PRINTSI("current player pos - ",iCURRENT_RACE_POS)
|
|
DEBUG_PRINTSI("current NPC pos - ",iNPC_RACE_POS)
|
|
DEBUG_PRINTSI("MAX POSITIONS - ",iMaxRacePositions)
|
|
*/
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Track the locations of the player and Mary Ann and update the race positions accordingly
|
|
PROC DEAL_WITH_THE_RACE_TRACKING()
|
|
IF IS_PED_UNINJURED(MARY_ANN)
|
|
IF ENUM_TO_INT(missionStage) < ENUM_TO_INT(MS_END_CUTSCENE)
|
|
AND ENUM_TO_INT(missionStage) > ENUM_TO_INT(MS_CUTSCENE)
|
|
|
|
DEAL_WITH_RACE_BLIPS()
|
|
UPDATE_CHASE_BLIP(FANATIC_BLIP, MARY_ANN, 70, 0.72)
|
|
|
|
IF iNum_PlayerClosestWaypoint > iNum_NPCClosestWaypoint
|
|
IF place != 1
|
|
place = 1
|
|
IF (GET_GAME_TIMER() - iOvertakeTimer) > 3000
|
|
DEBUG_PRINTSTRING("Trying an overtake line...")
|
|
bOvertaken = TRUE
|
|
iOvertakeTimer = GET_GAME_TIMER()
|
|
ELSE
|
|
DEBUG_PRINTSI("Can't do overtake line, overtake timer is = ", (GET_GAME_TIMER() - iOvertakeTimer))
|
|
ENDIF
|
|
ENDIF
|
|
ELIF iNum_PlayerClosestWaypoint < iNum_NPCClosestWaypoint
|
|
IF place != 2
|
|
place = 2
|
|
ENDIF
|
|
ELSE
|
|
IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(MARY_ANN), RACE_POSITIONS[RETURN_FURTHEST_CHECKPOINT()]) < GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), RACE_POSITIONS[RETURN_FURTHEST_CHECKPOINT()])
|
|
IF place != 2
|
|
place = 2
|
|
ENDIF
|
|
ELSE
|
|
IF place != 1
|
|
place = 1
|
|
IF (GET_GAME_TIMER() - iOvertakeTimer) > 3000
|
|
DEBUG_PRINTSTRING("Trying an overtake line...")
|
|
bOvertaken = TRUE
|
|
iOvertakeTimer = GET_GAME_TIMER()
|
|
ELSE
|
|
DEBUG_PRINTSI("Can't do overtake line, overtake timer is = ", (GET_GAME_TIMER() - iOvertakeTimer))
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// IF iNPC_RACE_POS > iCURRENT_RACE_POS
|
|
// IF place != 2
|
|
// place = 2
|
|
// ENDIF
|
|
// ELIF iNPC_RACE_POS < iCURRENT_RACE_POS
|
|
// IF place != 1
|
|
// place = 1
|
|
// IF (GET_GAME_TIMER() - iOvertakeTimer) > 3000
|
|
// DEBUG_PRINTSTRING("Trying an overtake line...")
|
|
// bOvertaken = TRUE
|
|
// iOvertakeTimer = GET_GAME_TIMER()
|
|
// ENDIF
|
|
// ENDIF
|
|
// ELSE
|
|
// IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(MARY_ANN), RACE_POSITIONS[iNPC_RACE_POS]) < GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), RACE_POSITIONS[iCURRENT_RACE_POS])
|
|
// IF place != 2
|
|
// place = 2
|
|
// ENDIF
|
|
// ELSE
|
|
// IF place != 1
|
|
// place = 1
|
|
// IF (GET_GAME_TIMER() - iOvertakeTimer) > 3000
|
|
// DEBUG_PRINTSTRING("Trying an overtake line...")
|
|
// bOvertaken = TRUE
|
|
// iOvertakeTimer = GET_GAME_TIMER()
|
|
// ENDIF
|
|
// ENDIF
|
|
// ENDIF
|
|
// ENDIF
|
|
|
|
//DRAW_BIG_DOUBLE_SCORE_HUD(iCURRENT_RACE_POS, iMaxRacePositions, "FATIC1_CP", HUD_COLOUR_YELLOWLIGHT )
|
|
SET_FAR_RIGHT_TITLE_POSITION_HUD_THIS_FRAME()
|
|
DRAW_RACE_HUD((GET_GAME_TIMER() - start_time), "", -1, -1, "", place, 2, "", DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
|
|
DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, TRUE) // turn milliseconds off!
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Delete every entity in the mission
|
|
PROC DELETE_EVERYTHING()
|
|
IF IS_AUDIO_SCENE_ACTIVE("FANATIC_MIX_SCENE")
|
|
REMOVE_ENTITY_FROM_AUDIO_MIX_GROUP(MARY_ANN)
|
|
ENDIF
|
|
SAFE_DELETE_PED(MARY_ANN)
|
|
SAFE_DELETE_PED(QUAD_DRIVER)
|
|
SAFE_DELETE_PED(cprWatcher1)
|
|
SAFE_DELETE_PED(cprWatcher2)
|
|
SAFE_DELETE_PED(INJURED_PED)
|
|
|
|
SAFE_DELETE_PED(BEACH_DOG)
|
|
SAFE_DELETE_PED(OtherJoggers[0].thisIndex)
|
|
SAFE_DELETE_PED(OtherJoggers[1].thisIndex)
|
|
SAFE_DELETE_PED(OtherJoggers[2].thisIndex)
|
|
SAFE_DELETE_PED(OtherJoggers[3].thisIndex)
|
|
SAFE_DELETE_PED(DRIVEBY_FINGER_CAR.Driver)
|
|
SAFE_DELETE_PED(DRIVEBY_FINGER_CAR.Passenger)
|
|
SAFE_DELETE_PED(FOLLOWING_CAR.Driver)
|
|
SAFE_DELETE_PED(FOLLOWING_CAR.Passenger)
|
|
|
|
SAFE_DELETE_VEHICLE(DRIVEBY_FINGER_CAR.thisCarIndex)
|
|
SAFE_DELETE_VEHICLE(FOLLOWING_CAR.thisCarIndex)
|
|
SAFE_DELETE_VEHICLE(CHEAT_QUAD)
|
|
SAFE_DELETE_VEHICLE(MAS_BIKE)
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Reset all of the bools used to track which conversations have been said to the default
|
|
PROC RESET_DIALOGUE_BOOLS()
|
|
|
|
bCatchupCheatLineSaid = FALSE
|
|
bOvertaken = FALSE
|
|
iOvertakeTimer = GET_GAME_TIMER()
|
|
iOneLinerTimer = GET_GAME_TIMER()
|
|
iRoadTimer = GET_GAME_TIMER()
|
|
iRoadCounter = 0
|
|
OvertakeLines.timesPlayed = 0
|
|
MikePushMALine.timesPlayed = 0
|
|
MikePushPedLine.timesPlayed = 0
|
|
pushLine[0].hasBeenPlayed = FALSE
|
|
pushLine[1].hasBeenPlayed = FALSE
|
|
pushLine[2].hasBeenPlayed = FALSE
|
|
cheatedLeaptFence.hasBeenPlayed = FALSE
|
|
cheatedRanAcrossGrass.hasBeenPlayed = FALSE
|
|
returnAfterCheatedLine.hasBeenPlayed = FALSE
|
|
startRunConversation.hasBeenPlayed = FALSE
|
|
road1Conversation.hasBeenPlayed = FALSE
|
|
road2Conversation.hasBeenPlayed = FALSE
|
|
raceConversation.hasBeenPlayed = FALSE
|
|
leftRaceWarning.hasBeenShown = FALSE
|
|
leftBehindWarning.hasBeenShown = FALSE
|
|
vehicleWarning.hasBeenShown = FALSE
|
|
iHurryUpLineNumber = 0
|
|
iCatchUpLineNumber = 0
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Handle Z-skipping from stage to stage in a mission
|
|
PROC JUMP_TO_STAGE(debugSkipToMissionStage newStage)
|
|
|
|
RC_START_Z_SKIP()
|
|
|
|
CLEAR_PRINTS()
|
|
SET_PLAYER_WANTED_LEVEL(PLAYER_ID(), 0)
|
|
FINISH_CUTSCENE(FALSE, TRUE)
|
|
DISPLAY_RADAR(TRUE)
|
|
STOP_SOUND(iHeartbeatAudioID)
|
|
bHeartbeatStarted = FALSE
|
|
|
|
CLEAR_PED_TASKS(PLAYER_PED_ID())
|
|
RESET_PLAYER_STAMINA(PLAYER_ID())
|
|
|
|
b_FinalPedsStartedWalking = FALSE
|
|
b_DrivebyHorn = FALSE
|
|
|
|
SAFE_REMOVE_BLIP(DESTINATION_BLIP)
|
|
SAFE_REMOVE_BLIP(NEXT_DESTINATION_BLIP)
|
|
DELETE_CHECKPOINT(checkPoint)
|
|
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
DEBUG_PRINTSTRING("Stopping scripted convo at jump_to_stage")
|
|
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
|
|
ENDIF
|
|
|
|
REMOVE_RELATIONSHIP_GROUP(relGroupFriendly)
|
|
ADD_RELATIONSHIP_GROUP("FRIENDLIES", relGroupFriendly)
|
|
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_LIKE, relGroupFriendly, RELGROUPHASH_PLAYER)
|
|
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_LIKE, RELGROUPHASH_PLAYER, relGroupFriendly)
|
|
|
|
REQUEST_MODEL(IG_MARYANN)
|
|
WHILE NOT HAS_MODEL_LOADED(IG_MARYANN)
|
|
WAIT(0)
|
|
ENDWHILE
|
|
|
|
DELETE_EVERYTHING()
|
|
RESET_DIALOGUE_BOOLS()
|
|
|
|
iOvertakeTimer = GET_GAME_TIMER()
|
|
iOneLinerTimer = GET_GAME_TIMER()
|
|
bOvertaken = FALSE
|
|
|
|
MARY_ANN = CREATE_PED(PEDTYPE_MISSION, IG_MARYANN, <<-1865.90, -448.81, 45.13>>, -143.87)
|
|
SET_PED_RELATIONSHIP_GROUP_HASH(MARY_ANN, relGroupFriendly)
|
|
SET_PED_MOVEMENT_CLIPSET(MARY_ANN, "FEMALE_FAST_RUNNER")
|
|
SET_PED_COMPONENT_VARIATION(MARY_ANN, PED_COMP_LEG, 1, 0)
|
|
ADD_PED_FOR_DIALOGUE(MyLocalPedStruct, 3, MARY_ANN, "MARYANN")
|
|
|
|
IF newStage <= DEBUG_TO_STEPS_DOWN
|
|
iSprintLength = 1800
|
|
iSprintDelay = 4500
|
|
ENDIF
|
|
|
|
IF newStage = DEBUG_TO_INTRO
|
|
IF IS_AUDIO_SCENE_ACTIVE("FANATIC_MIX_SCENE")
|
|
REMOVE_ENTITY_FROM_AUDIO_MIX_GROUP(MARY_ANN)
|
|
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(MARY_ANN)
|
|
ADD_ENTITY_TO_AUDIO_MIX_GROUP(MARY_ANN,"FANATIC_MIX_MARY_ANNE")
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
SWITCH newStage
|
|
CASE DEBUG_TO_INTRO
|
|
|
|
RC_REQUEST_CUTSCENE("ef_1_rcm")
|
|
|
|
IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY()
|
|
DEBUG_PRINTSTRING("Trying to set Mary Ann component variation")
|
|
SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Mary_Ann", MARY_ANN, CS_MARYANN)
|
|
ENDIF
|
|
|
|
iCURRENT_RACE_POS = 0
|
|
iNPC_RACE_POS = 1
|
|
|
|
REMOVE_RELATIONSHIP_GROUP(relGroupFriendly)
|
|
|
|
TURN_ROADS_ON(FALSE)
|
|
LOAD_OTHER_ASSETS()
|
|
|
|
CREATE_CARS()
|
|
|
|
UNLOAD_ALL_MODELS()
|
|
|
|
stageStage = SS_SETUP
|
|
missionStage = MS_CUTSCENE
|
|
BREAK
|
|
CASE DEBUG_TO_START
|
|
|
|
iCURRENT_RACE_POS = 0
|
|
iNPC_RACE_POS = 1
|
|
|
|
IF NOT IS_REPLAY_BEING_SET_UP()
|
|
SET_ENTITY_COORDS(PLAYER_PED_ID(), <<-1878.2344, -439.6985, 45.0299>>)
|
|
SET_ENTITY_HEADING(PLAYER_PED_ID(), 241.0468)
|
|
ENDIF
|
|
CLEAR_AREA_OF_PEDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), 7)
|
|
|
|
SET_ENTITY_COORDS(MARY_ANN, <<-1869.24, -444.99, 45.17>>)
|
|
SET_ENTITY_HEADING(MARY_ANN, -143.87)
|
|
|
|
TURN_ROADS_ON(FALSE)
|
|
|
|
LOAD_OTHER_ASSETS()
|
|
|
|
CREATE_CARS()
|
|
|
|
UNLOAD_ALL_MODELS()
|
|
|
|
KEEP_RUNNING(MS_START_RUNNING)
|
|
|
|
IF NOT IS_REPLAY_BEING_SET_UP() // Can't do these while a replay is being set up, will do them at the end instead
|
|
// This is to keep Michael running when the mission is replayed after a fail (or a skip I guess)
|
|
FORCE_PED_MOTION_STATE(PLAYER_PED_ID(), MS_ON_FOOT_RUN, TRUE, FAUS_DEFAULT)
|
|
SIMULATE_PLAYER_INPUT_GAIT(PLAYER_ID(), PEDMOVEBLENDRATIO_RUN, 5000)
|
|
SET_CURRENT_PED_WEAPON(PLAYER_PED_ID(), WEAPONTYPE_UNARMED, TRUE)
|
|
ENDIF
|
|
BREAK
|
|
CASE DEBUG_TO_ROAD
|
|
|
|
iCURRENT_RACE_POS = 3
|
|
iNPC_RACE_POS = 4
|
|
|
|
CLEAR_PED_TASKS(PLAYER_PED_ID())
|
|
SET_ENTITY_COORDS(PLAYER_PED_ID(), <<-1731.05, -549.78, 36.40>>)
|
|
SET_ENTITY_HEADING(PLAYER_PED_ID(), 104.26)
|
|
|
|
CLEAR_PED_TASKS(MARY_ANN)
|
|
SET_ENTITY_COORDS(MARY_ANN, <<-1732.880493,-551.763245,36.5>>)
|
|
SET_ENTITY_HEADING(MARY_ANN, 115.26)
|
|
|
|
TURN_ROADS_ON(FALSE)
|
|
CLEAR_AREA_OF_VEHICLES(<<-1806.495483,-525.869629,29.925911>> , 100)
|
|
|
|
LOAD_OTHER_ASSETS()
|
|
|
|
CREATE_CARS()
|
|
|
|
UNLOAD_ALL_MODELS()
|
|
|
|
KEEP_RUNNING(MS_ROAD_RUNNING_SECTION)
|
|
BREAK
|
|
CASE DEBUG_TO_STEPS_DOWN
|
|
|
|
iCURRENT_RACE_POS = 5
|
|
iNPC_RACE_POS = 6
|
|
|
|
CLEAR_PED_TASKS(PLAYER_PED_ID())
|
|
SET_ENTITY_COORDS(PLAYER_PED_ID(), <<-1832.52, -519.37, 27.89>>)
|
|
SET_ENTITY_HEADING(PLAYER_PED_ID(), 162.59)
|
|
|
|
CLEAR_PED_TASKS(MARY_ANN)
|
|
SET_ENTITY_COORDS(MARY_ANN, <<-1833.81, -523.70, 28.14>>)
|
|
SET_ENTITY_HEADING(MARY_ANN, 172.66)
|
|
|
|
LOAD_OTHER_ASSETS()
|
|
|
|
WHILE NOT LOAD_CPR()
|
|
OR NOT LOAD_DOG()
|
|
WAIT(0)
|
|
ENDWHILE
|
|
|
|
CREATE_DOGS()
|
|
CREATE_QUAD_BIKE_SCENE()
|
|
CREATE_JOGGERS()
|
|
|
|
UNLOAD_ALL_MODELS()
|
|
|
|
TURN_ROADS_ON()
|
|
|
|
KEEP_RUNNING(MS_STEPS_DOWN)
|
|
BREAK
|
|
|
|
CASE DEBUG_TO_BEACH
|
|
|
|
iCURRENT_RACE_POS = 6
|
|
iNPC_RACE_POS = 7
|
|
|
|
CLEAR_PED_TASKS(PLAYER_PED_ID())
|
|
SET_ENTITY_COORDS(PLAYER_PED_ID(), <<-1850.10, -592.21, 18.2>>)
|
|
SET_ENTITY_HEADING(PLAYER_PED_ID(), 124.19)
|
|
|
|
CLEAR_PED_TASKS(MARY_ANN)
|
|
SET_ENTITY_COORDS(MARY_ANN, <<-1849.61, -592.90, 18.2>>)
|
|
SET_ENTITY_HEADING(MARY_ANN, 135.16)
|
|
|
|
LOAD_OTHER_ASSETS()
|
|
|
|
WHILE NOT LOAD_CPR()
|
|
OR NOT LOAD_DOG()
|
|
WAIT(0)
|
|
ENDWHILE
|
|
|
|
CREATE_DOGS()
|
|
CREATE_QUAD_BIKE_SCENE(FALSE)
|
|
CREATE_JOGGERS()
|
|
|
|
IF IS_PED_UNINJURED(INJURED_PED)
|
|
ADD_SHOCKING_EVENT_FOR_ENTITY(EVENT_SHOCKING_INJURED_PED, INJURED_PED, -1)
|
|
ENDIF
|
|
|
|
UNLOAD_ALL_MODELS()
|
|
|
|
TURN_ROADS_ON()
|
|
IF IS_OUTFIT_SUITABLE_FOR_FANATIC_MISSION(1)
|
|
CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", "FAN1_BCHB", CONV_PRIORITY_MEDIUM)
|
|
ELSE
|
|
CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", "FAN1_BCHA", CONV_PRIORITY_MEDIUM)
|
|
ENDIF
|
|
|
|
KEEP_RUNNING(MS_SPRINT_TO_FINISH)
|
|
BREAK
|
|
CASE DEBUG_TO_FINISH_LINE
|
|
|
|
iCURRENT_RACE_POS = 8
|
|
iNPC_RACE_POS = 9
|
|
|
|
LOAD_OTHER_ASSETS()
|
|
|
|
WHILE NOT LOAD_CPR()
|
|
OR NOT LOAD_DOG()
|
|
WAIT(0)
|
|
ENDWHILE
|
|
|
|
CREATE_DOGS()
|
|
CREATE_QUAD_BIKE_SCENE()
|
|
CREATE_JOGGERS()
|
|
|
|
UNLOAD_ALL_MODELS()
|
|
|
|
CLEAR_PED_TASKS(PLAYER_PED_ID())
|
|
SET_ENTITY_COORDS(PLAYER_PED_ID(), vPos_FinishLine)
|
|
SET_ENTITY_HEADING(PLAYER_PED_ID(), 19.95)
|
|
|
|
IF IS_PED_UNINJURED(MARY_ANN)
|
|
CLEAR_PED_TASKS(MARY_ANN)
|
|
SET_ENTITY_COORDS(MARY_ANN, <<-1986.93, -526.39, 11.70>>)
|
|
SET_ENTITY_HEADING(MARY_ANN, 44.46)
|
|
ENDIF
|
|
|
|
TURN_ROADS_ON()
|
|
|
|
KEEP_RUNNING(MS_DEBUG_NEAR_FINISH_LINE)
|
|
BREAK
|
|
CASE DEBUG_NEXT_TO_FINISH
|
|
// This is a special option in case you want to let Mary Ann win, and see the "you lost" cutscene.
|
|
iCURRENT_RACE_POS = 8
|
|
iNPC_RACE_POS = 9
|
|
|
|
LOAD_OTHER_ASSETS()
|
|
|
|
WHILE NOT LOAD_CPR()
|
|
OR NOT LOAD_DOG()
|
|
WAIT(0)
|
|
ENDWHILE
|
|
|
|
CREATE_DOGS()
|
|
CREATE_QUAD_BIKE_SCENE()
|
|
CREATE_JOGGERS()
|
|
|
|
UNLOAD_ALL_MODELS()
|
|
|
|
CLEAR_PED_TASKS(PLAYER_PED_ID())
|
|
SET_ENTITY_COORDS(PLAYER_PED_ID(), <<-2001.27, -514.18, 11>>)
|
|
SET_ENTITY_HEADING(PLAYER_PED_ID(), 19.95)
|
|
|
|
IF IS_PED_UNINJURED(MARY_ANN)
|
|
CLEAR_PED_TASKS(MARY_ANN)
|
|
SET_ENTITY_COORDS(MARY_ANN, <<-1986.93, -526.39, 11.70>>)
|
|
SET_ENTITY_HEADING(MARY_ANN, 44.46)
|
|
ENDIF
|
|
|
|
TURN_ROADS_ON()
|
|
|
|
KEEP_RUNNING(MS_DEBUG_NEAR_FINISH_LINE)
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
SET_PED_ON_THE_GROUND(MARY_ANN)
|
|
SET_PED_ON_THE_GROUND(PLAYER_PED_ID())
|
|
|
|
IF DOES_ENTITY_EXIST(MARY_ANN)
|
|
AND DOES_ENTITY_EXIST(PLAYER_PED_ID())
|
|
DETERMINE_CLOSEST_WAYPOINTS()
|
|
DEAL_WITH_THE_RACE_TRACKING()
|
|
ENDIF
|
|
|
|
IF IS_REPLAY_BEING_SET_UP()
|
|
DEBUG_PRINTSTRING("JUMP_TO_STAGE: replay being set up")
|
|
END_REPLAY_SETUP()
|
|
// This stuff wouldn't be done before because of the replay being set up
|
|
SIMULATE_PLAYER_INPUT_GAIT(PLAYER_ID(), PEDMOVEBLENDRATIO_RUN, 5000)
|
|
FORCE_PED_MOTION_STATE(PLAYER_PED_ID(), MS_ON_FOOT_RUN, TRUE, FAUS_DEFAULT)
|
|
SET_CURRENT_PED_WEAPON(PLAYER_PED_ID(), WEAPONTYPE_UNARMED, TRUE)
|
|
wait(1000)
|
|
RC_END_Z_SKIP()
|
|
ELSE
|
|
DEBUG_PRINTSTRING("JUMP_TO_STAGE: replay not being set up")
|
|
|
|
IF missionStage = MS_CUTSCENE
|
|
WHILE NOT RC_IS_CUTSCENE_OK_TO_START()
|
|
IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY()
|
|
IF IS_ENTITY_ALIVE(MARY_ANN)
|
|
DEBUG_PRINTSTRING("Trying to set Mary Ann component variation")
|
|
SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Mary_Ann", MARY_ANN, CS_MARYANN)
|
|
ENDIF
|
|
ENDIF
|
|
RC_REQUEST_CUTSCENE("ef_1_rcm")
|
|
WAIT(0)
|
|
ENDWHILE
|
|
ELSE
|
|
wait(1000)
|
|
RC_END_Z_SKIP()
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
// ===========================================================================================================
|
|
// DEBUG FUNCTIONS
|
|
// ===========================================================================================================
|
|
|
|
/// PURPOSE: Check for Forced Pass or Fail
|
|
PROC DEBUG_Check_Debug_Keys()
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
|
|
|
|
// Check for Pass
|
|
IF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_S))
|
|
WAIT_FOR_CUTSCENE_TO_STOP()
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
CLEAR_PED_TASKS(PLAYER_PED_ID())
|
|
ENDIF
|
|
Script_Passed()
|
|
ENDIF
|
|
|
|
// Check for Fail
|
|
IF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_F))
|
|
WAIT_FOR_CUTSCENE_TO_STOP()
|
|
TRIGGER_MUSIC_EVENT("RC6A_FAIL")
|
|
failReason = REASON_SILENT
|
|
stageStage = SS_SETUP
|
|
missionStage = MS_FAIL_WAIT_FOR_FADE
|
|
ENDIF
|
|
|
|
IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_J)
|
|
SWITCH missionStage
|
|
CASE MS_CUTSCENE
|
|
WAIT_FOR_CUTSCENE_TO_STOP()
|
|
JUMP_TO_STAGE(DEBUG_TO_START)
|
|
BREAK
|
|
CASE MS_START_RUNNING
|
|
JUMP_TO_STAGE(DEBUG_TO_ROAD)
|
|
BREAK
|
|
CASE MS_ROAD_RUNNING_SECTION
|
|
JUMP_TO_STAGE(DEBUG_TO_STEPS_DOWN)
|
|
BREAK
|
|
CASE MS_STEPS_DOWN
|
|
JUMP_TO_STAGE(DEBUG_TO_BEACH)
|
|
BREAK
|
|
CASE MS_SPRINT_TO_FINISH
|
|
IF NOT IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-2015.758545,-501.566437,10.732570>>, <<-1992.435425,-522.269409,11.678237>>, 17.750000, FALSE, FALSE)
|
|
JUMP_TO_STAGE(DEBUG_TO_FINISH_LINE)
|
|
ELSE
|
|
RC_END_CUTSCENE_MODE()
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
CLEAR_PED_TASKS(PLAYER_PED_ID())
|
|
ENDIF
|
|
Script_Passed()
|
|
ENDIF
|
|
BREAK
|
|
CASE MS_DEBUG_NEAR_FINISH_LINE
|
|
RC_END_CUTSCENE_MODE()
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
CLEAR_PED_TASKS(PLAYER_PED_ID())
|
|
ENDIF
|
|
Script_Passed()
|
|
BREAK
|
|
CASE MS_END_CUTSCENE
|
|
RC_END_CUTSCENE_MODE()
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
CLEAR_PED_TASKS(PLAYER_PED_ID())
|
|
ENDIF
|
|
Script_Passed()
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDIF
|
|
|
|
IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_P)
|
|
SWITCH missionStage
|
|
CASE MS_START_RUNNING
|
|
JUMP_TO_STAGE(DEBUG_TO_INTRO)
|
|
BREAK
|
|
CASE MS_ROAD_RUNNING_SECTION
|
|
JUMP_TO_STAGE(DEBUG_TO_START)
|
|
BREAK
|
|
CASE MS_STEPS_DOWN
|
|
JUMP_TO_STAGE(DEBUG_TO_ROAD)
|
|
BREAK
|
|
CASE MS_SPRINT_TO_FINISH
|
|
IF NOT IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-2015.758545,-501.566437,10.732570>>, <<-1992.435425,-522.269409,11.678237>>, 17.750000, FALSE, FALSE)
|
|
JUMP_TO_STAGE(DEBUG_TO_STEPS_DOWN)
|
|
ELSE
|
|
JUMP_TO_STAGE(DEBUG_TO_BEACH)
|
|
ENDIF
|
|
BREAK
|
|
CASE MS_DEBUG_NEAR_FINISH_LINE
|
|
JUMP_TO_STAGE(DEBUG_TO_BEACH)
|
|
BREAK
|
|
CASE MS_END_CUTSCENE
|
|
JUMP_TO_STAGE(DEBUG_TO_BEACH)
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDIF
|
|
|
|
IF LAUNCH_MISSION_STAGE_MENU(s_skip_menu, i_debug_jump_stage)
|
|
WAIT_FOR_CUTSCENE_TO_STOP()
|
|
INT e_stage = i_debug_jump_stage
|
|
JUMP_TO_STAGE(INT_TO_ENUM(debugSkipToMissionStage, e_stage))
|
|
ENDIF
|
|
// Update the amount of sprint time remaining in the RAG widget
|
|
fPlayerSprintRemaining = GET_PLAYER_SPRINT_TIME_REMAINING(PLAYER_ID())
|
|
#ENDIF
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Handle the behaviour of the dog on the final stretch
|
|
PROC DEAL_WITH_THE_DOG()
|
|
IF IS_PED_UNINJURED(BEACH_DOG)
|
|
SWITCH beachDogState
|
|
CASE DOG_LOADING
|
|
IF LOAD_DOG()
|
|
IF NOT IS_ENTITY_ALIVE(BEACH_DOG)
|
|
BEACH_DOG = CREATE_PED(PEDTYPE_MISSION, A_C_ROTTWEILER, vPos_DOG, fDir_DOG)
|
|
SET_PED_CAN_RAGDOLL(BEACH_DOG, TRUE)
|
|
ENDIF
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(A_C_ROTTWEILER)
|
|
DEBUG_PRINTSTRING("Loaded and created dog - progressing")
|
|
beachDogState = DOG_WAITING
|
|
ENDIF
|
|
BREAK
|
|
CASE DOG_WAITING
|
|
IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
|
|
IF iNum_PlayerClosestWaypoint = 109
|
|
TASK_FOLLOW_TO_OFFSET_OF_ENTITY(BEACH_DOG, PLAYER_PED_ID(), <<-2, 2, 0>>, 2.5, -1, 0.2)
|
|
beachDogState = DOG_FOLLOWING_PLAYER
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Check to see if the player has threatened any ped involved in the CPR synced scene
|
|
FUNC BOOL HAS_PLAYER_THREATENED_THE_CPR_SCENE()
|
|
IF HAS_PLAYER_THREATENED_PED(QUAD_DRIVER)
|
|
OR HAS_PLAYER_THREATENED_PED(INJURED_PED)
|
|
OR HAS_PLAYER_THREATENED_PED(cprWatcher1)
|
|
OR HAS_PLAYER_THREATENED_PED(cprWatcher2)
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE: Handle the overall behaviour and events in the CPR synced scene by the beach
|
|
PROC DEAL_WITH_THE_QUAD()
|
|
|
|
SWITCH cprState
|
|
CASE CPR_LOADING
|
|
IF LOAD_CPR()
|
|
DEBUG_PRINTSTRING("CPR scene resources loaded - progressing")
|
|
CREATE_QUAD_BIKE_SCENE()
|
|
cprState = CPR_WAITING
|
|
ENDIF
|
|
BREAK
|
|
CASE CPR_WAITING
|
|
IF iCURRENT_RACE_POS >= 7
|
|
IF IS_VEHICLE_OK(CHEAT_QUAD)
|
|
IF IS_PED_UNINJURED(QUAD_DRIVER)
|
|
AND IS_PED_UNINJURED(INJURED_PED)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_VEHICLE_FOLLOW_WAYPOINT_RECORDING(NULL, CHEAT_QUAD, "Fanatic1Quad", DF_SteerAroundPeds, 14)
|
|
TASK_LEAVE_VEHICLE(NULL, CHEAT_QUAD)
|
|
TASK_LOOK_AT_ENTITY(NULL, INJURED_PED, -1)
|
|
TASK_GO_STRAIGHT_TO_COORD(NULL, GET_ENTITY_COORDS(INJURED_PED), 1.8)//GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(INJURED_PED, <<-0.5, 0, 0>>), 1.8)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(QUAD_DRIVER, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
|
|
SET_VEHICLE_FORWARD_SPEED(CHEAT_QUAD, 5)
|
|
|
|
SET_VEHICLE_AS_NO_LONGER_NEEDED(CHEAT_QUAD)
|
|
|
|
cprState = CPR_GOING_TO_SCENE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE CPR_GOING_TO_SCENE
|
|
IF IS_PED_UNINJURED(QUAD_DRIVER)
|
|
AND IS_PED_UNINJURED(INJURED_PED)
|
|
|
|
IF IS_PED_RAGDOLL(INJURED_PED)
|
|
cprState = CPR_INTERUPTED
|
|
ENDIF
|
|
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(INJURED_PED, QUAD_DRIVER) < 2
|
|
|
|
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(QUAD_DRIVER, TRUE)
|
|
|
|
CPRSynchSceneID = CREATE_SYNCHRONIZED_SCENE(vPos_CPRScene, vRot_CPRScene)
|
|
TASK_SYNCHRONIZED_SCENE(QUAD_DRIVER, CPRSynchSceneID, "mini@cpr@char_a@cpr_def", "cpr_intro", SLOW_BLEND_IN, NORMAL_BLEND_OUT, SYNCED_SCENE_USE_PHYSICS, RBF_NONE, SLOW_BLEND_IN)
|
|
TASK_SYNCHRONIZED_SCENE(INJURED_PED, CPRSynchSceneID, "mini@cpr@char_b@cpr_def", "cpr_intro", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, SYNCED_SCENE_DONT_INTERRUPT)
|
|
|
|
cprState = CPR_INTRO
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE CPR_INTRO
|
|
IF IS_PED_UNINJURED(QUAD_DRIVER)
|
|
AND IS_PED_UNINJURED(INJURED_PED)
|
|
|
|
IF IS_PED_RAGDOLL(QUAD_DRIVER)
|
|
OR IS_PED_RAGDOLL(INJURED_PED)
|
|
cprState = CPR_INTERUPTED
|
|
ELSE
|
|
IF GET_SYNCHRONIZED_SCENE_PHASE(CPRSynchSceneID) > 0.99
|
|
|
|
CPRSynchSceneID = CREATE_SYNCHRONIZED_SCENE(vPos_CPRScene, vRot_CPRScene)
|
|
TASK_SYNCHRONIZED_SCENE(QUAD_DRIVER, CPRSynchSceneID, "mini@cpr@char_a@cpr_str", "cpr_pumpchest", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, SYNCED_SCENE_USE_PHYSICS, RBF_NONE)
|
|
TASK_SYNCHRONIZED_SCENE (INJURED_PED, CPRSynchSceneID, "mini@cpr@char_b@cpr_str", "cpr_pumpchest", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, SYNCED_SCENE_DONT_INTERRUPT, RBF_NONE)
|
|
|
|
SET_SYNCHRONIZED_SCENE_LOOPED(CPRSynchSceneID, TRUE)
|
|
cprState = CPR_IDLE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF HAS_PLAYER_THREATENED_THE_CPR_SCENE()
|
|
IF GET_SYNCHRONIZED_SCENE_PHASE(CPRSynchSceneID) > 0.23
|
|
cprState = CPR_GETTING_UP
|
|
ELSE
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), -1)
|
|
TASK_SMART_FLEE_PED(NULL, PLAYER_PED_ID(), 80, -1)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(QUAD_DRIVER, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
|
|
IF IS_PED_UNINJURED(cprWatcher1)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_PAUSE(NULL, 200)
|
|
TASK_SMART_FLEE_PED(NULL, PLAYER_PED_ID(), 80, -1)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(cprWatcher1, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
ENDIF
|
|
|
|
IF IS_PED_UNINJURED(cprWatcher2)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_PAUSE(NULL, 500)
|
|
TASK_SMART_FLEE_PED(NULL, PLAYER_PED_ID(), 80, -1)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(cprWatcher2, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
ENDIF
|
|
cprState = CPR_FLEE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE CPR_IDLE
|
|
IF IS_PED_UNINJURED(QUAD_DRIVER)
|
|
AND IS_PED_UNINJURED(INJURED_PED)
|
|
IF IS_PED_RAGDOLL(QUAD_DRIVER)
|
|
OR IS_PED_RAGDOLL(INJURED_PED)
|
|
cprState = CPR_INTERUPTED
|
|
ELSE
|
|
IF HAS_PLAYER_THREATENED_THE_CPR_SCENE()
|
|
cprState = CPR_GETTING_UP
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE CPR_GETTING_UP
|
|
IF IS_PED_UNINJURED(QUAD_DRIVER)
|
|
AND NOT IS_PED_FLEEING(QUAD_DRIVER)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), -1)
|
|
TASK_PLAY_ANIM(NULL, "rcmfanatic1", "KNEEL_EXIT", SLOW_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_EXIT_AFTER_INTERRUPTED)
|
|
TASK_SMART_FLEE_PED(NULL, PLAYER_PED_ID(), 80, -1)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(QUAD_DRIVER, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
ENDIF
|
|
IF IS_PED_UNINJURED(cprWatcher1)
|
|
AND NOT IS_PED_FLEEING(cprWatcher1)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_PAUSE(NULL, 200)
|
|
TASK_SMART_FLEE_PED(NULL, PLAYER_PED_ID(), 80, -1)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(cprWatcher1, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
ENDIF
|
|
IF IS_PED_UNINJURED(cprWatcher2)
|
|
AND NOT IS_PED_FLEEING(cprWatcher2)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_PAUSE(NULL, 500)
|
|
TASK_SMART_FLEE_PED(NULL, PLAYER_PED_ID(), 80, -1)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(cprWatcher2, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
ENDIF
|
|
IF IS_PED_UNINJURED(INJURED_PED)
|
|
SET_ENTITY_HEALTH(INJURED_PED, 0)
|
|
ENDIF
|
|
|
|
cprState = CPR_FLEE
|
|
BREAK
|
|
CASE CPR_INTERUPTED
|
|
IF IS_PED_UNINJURED(QUAD_DRIVER)
|
|
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(QUAD_DRIVER, FALSE)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
IF NOT IS_PED_RAGDOLL(QUAD_DRIVER)
|
|
TASK_PLAY_ANIM(NULL, "rcmfanatic1", "KNEEL_EXIT", SLOW_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_EXIT_AFTER_INTERRUPTED)
|
|
ENDIF
|
|
TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), -1)
|
|
TASK_TURN_PED_TO_FACE_ENTITY(NULL, PLAYER_PED_ID(), 0)
|
|
// TASK_PLAY_ANIM(NULL, "GESTURES@MALE", "HOW_COULD_YOU", NORMAL_BLEND_IN, SLOW_BLEND_OUT, -1, AF_UPPERBODY)
|
|
TASK_LOOK_AT_ENTITY(NULL, INJURED_PED, -1)
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(QUAD_DRIVER, INJURED_PED) > 2
|
|
TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, GET_ENTITY_COORDS(INJURED_PED), 1, DEFAULT_TIME_BEFORE_WARP, 1.5)
|
|
ENDIF
|
|
TASK_TURN_PED_TO_FACE_ENTITY(NULL, INJURED_PED, 0)
|
|
TASK_USE_MOBILE_PHONE_TIMED(NULL, 10000)
|
|
TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), -1)
|
|
TASK_TURN_PED_TO_FACE_ENTITY(NULL, PLAYER_PED_ID(), -1)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(QUAD_DRIVER, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
ENDIF
|
|
IF IS_PED_UNINJURED(cprWatcher1)
|
|
STOP_ANIM_PLAYBACK(cprWatcher1, AF_PRIORITY_LOW)
|
|
TASK_LOOK_AT_ENTITY(cprWatcher1, INJURED_PED, 2000)
|
|
TASK_TURN_PED_TO_FACE_ENTITY(cprWatcher1, INJURED_PED)
|
|
SAFE_RELEASE_PED(cprWatcher1)
|
|
ENDIF
|
|
IF IS_PED_UNINJURED(cprWatcher2)
|
|
STOP_ANIM_PLAYBACK(cprWatcher2, AF_PRIORITY_LOW)
|
|
TASK_LOOK_AT_ENTITY(cprWatcher2, INJURED_PED, 2000)
|
|
TASK_TURN_PED_TO_FACE_ENTITY(cprWatcher2, INJURED_PED)
|
|
SAFE_RELEASE_PED(cprWatcher2)
|
|
ENDIF
|
|
IF IS_PED_UNINJURED(INJURED_PED)
|
|
SET_ENTITY_HEALTH(INJURED_PED, 0)
|
|
ENDIF
|
|
cprState = CPR_WATCHING_PLAYER
|
|
BREAK
|
|
CASE CPR_WATCHING_PLAYER
|
|
IF IS_PED_UNINJURED(QUAD_DRIVER)
|
|
if GET_SCRIPT_TASK_STATUS(QUAD_DRIVER, SCRIPT_TASK_DUCK) <> PERFORMING_TASK
|
|
AND GET_SCRIPT_TASK_STATUS(QUAD_DRIVER, SCRIPT_TASK_DUCK) <> WAITING_TO_START_TASK
|
|
AND IS_PED_RAGDOLL(QUAD_DRIVER)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), -1)
|
|
TASK_TURN_PED_TO_FACE_ENTITY(NULL, PLAYER_PED_ID(), 0)
|
|
// TASK_PLAY_ANIM(NULL, "GESTURES@MALE", "HOW_COULD_YOU", NORMAL_BLEND_IN, SLOW_BLEND_OUT, -1, AF_UPPERBODY)
|
|
TASK_LOOK_AT_ENTITY(NULL, INJURED_PED, -1)
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(QUAD_DRIVER, INJURED_PED) > 2
|
|
TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, GET_ENTITY_COORDS(INJURED_PED), 1, DEFAULT_TIME_BEFORE_WARP, 1.5)
|
|
ENDIF
|
|
TASK_TURN_PED_TO_FACE_ENTITY(NULL, INJURED_PED, 0)
|
|
TASK_USE_MOBILE_PHONE_TIMED(NULL, 10000)
|
|
TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), -1)
|
|
TASK_TURN_PED_TO_FACE_ENTITY(NULL, PLAYER_PED_ID(), -1)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(QUAD_DRIVER, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
ENDIF
|
|
ENDIF
|
|
IF HAS_PLAYER_THREATENED_THE_CPR_SCENE()
|
|
IF IS_PED_UNINJURED(QUAD_DRIVER)
|
|
AND NOT IS_PED_FLEEING(QUAD_DRIVER)
|
|
TASK_SMART_FLEE_PED(QUAD_DRIVER, PLAYER_PED_ID(), 80, -1)
|
|
ENDIF
|
|
IF IS_PED_UNINJURED(cprWatcher1)
|
|
AND NOT IS_PED_FLEEING(cprWatcher1)
|
|
TASK_SMART_FLEE_PED(cprWatcher1, PLAYER_PED_ID(), 80, -1)
|
|
ENDIF
|
|
IF IS_PED_UNINJURED(cprWatcher2)
|
|
AND NOT IS_PED_FLEEING(cprWatcher2)
|
|
TASK_SMART_FLEE_PED(cprWatcher2, PLAYER_PED_ID(), 80, -1)
|
|
ENDIF
|
|
cprState = CPR_FLEE
|
|
ENDIF
|
|
BREAK
|
|
CASE CPR_FLEE
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
IF IS_PED_UNINJURED(cprWatcher1)
|
|
and NOT IS_PED_FLEEING(cprWatcher1)
|
|
IF IS_PED_RAGDOLL(cprWatcher1)
|
|
CLEAR_PED_TASKS(cprWatcher1)
|
|
SAFE_RELEASE_PED(cprWatcher1)
|
|
ENDIF
|
|
ENDIF
|
|
IF IS_PED_UNINJURED(cprWatcher2)
|
|
and NOT IS_PED_FLEEING(cprWatcher2)
|
|
IF IS_PED_RAGDOLL(cprWatcher2)
|
|
CLEAR_PED_TASKS(cprWatcher2)
|
|
SAFE_RELEASE_PED(cprWatcher2)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
|
|
IF IS_PED_UNINJURED(INJURED_PED)
|
|
ADD_SHOCKING_EVENT_FOR_ENTITY(EVENT_SHOCKING_DEAD_BODY, INJURED_PED, 1)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Handle the two final jogging peds at the end of the final stretch of the race
|
|
PROC DEAL_WITH_THE_TWO_FINAL_PEDS()
|
|
|
|
// Use this function to check the first set of two joggers near the start and make them flee if the player bumps into them
|
|
INT j
|
|
FOR j = 0 TO 1
|
|
IF IS_PED_UNINJURED(OtherJoggers[j].thisIndex)
|
|
AND IS_PED_RAGDOLL(OtherJoggers[j].thisIndex)
|
|
CLEAR_PED_TASKS(OtherJoggers[j].thisIndex)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(OtherJoggers[j].thisIndex, PLAYER_PED_ID()) < GET_DISTANCE_BETWEEN_ENTITIES(OtherJoggers[j].thisIndex, MARY_ANN)
|
|
TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), -1)
|
|
TASK_TURN_PED_TO_FACE_ENTITY(NULL, PLAYER_PED_ID(), 0)
|
|
ELSE
|
|
TASK_LOOK_AT_ENTITY(NULL, MARY_ANN, -1)
|
|
TASK_TURN_PED_TO_FACE_ENTITY(NULL, MARY_ANN, 0)
|
|
ENDIF
|
|
TASK_PAUSE(NULL, 3000)
|
|
TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, OtherJoggers[j].thisGoToPos2, 0.7, DEFAULT_TIME_BEFORE_WARP, 1, ENAV_NO_STOPPING)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(OtherJoggers[j].thisIndex, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
ENDIF
|
|
IF IS_ENTITY_ALIVE(OtherJoggers[j].thisIndex)
|
|
IF IS_ENTITY_TOUCHING_ENTITY(PLAYER_PED_ID(), OtherJoggers[j].thisIndex)
|
|
CLEAR_PED_TASKS(OtherJoggers[j].thisIndex)
|
|
TASK_SMART_FLEE_PED(OtherJoggers[j].thisIndex, PLAYER_PED_ID(), 200, -1, TRUE)
|
|
SAFE_RELEASE_PED(OtherJoggers[j].thisIndex)
|
|
ENDIF
|
|
ENDIF
|
|
ENDFOR
|
|
|
|
IF b_FinalPedsStartedWalking = FALSE
|
|
IF iNum_PlayerClosestWaypoint > 114
|
|
IF IS_PED_UNINJURED(OtherJoggers[2].thisIndex)
|
|
AND IS_PED_UNINJURED(OtherJoggers[3].thisIndex)
|
|
INT k
|
|
FOR k = 2 TO 3
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, OtherJoggers[k].thisGoToPos1, 0.7, DEFAULT_TIME_BEFORE_WARP, 1, ENAV_NO_STOPPING)
|
|
TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, OtherJoggers[k].thisGoToPos2, 0.7, DEFAULT_TIME_BEFORE_WARP, 1, ENAV_NO_STOPPING)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(OtherJoggers[k].thisIndex, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
ENDFOR
|
|
|
|
TASK_LOOK_AT_ENTITY(OtherJoggers[2].thisIndex, OtherJoggers[3].thisIndex, -1)
|
|
TASK_LOOK_AT_ENTITY(OtherJoggers[3].thisIndex, OtherJoggers[2].thisIndex, -1)
|
|
ENDIF
|
|
IF IS_PED_UNINJURED(BEACH_DOG)
|
|
CLEAR_PED_TASKS(BEACH_DOG)
|
|
ENDIF
|
|
|
|
b_FinalPedsStartedWalking = TRUE
|
|
ENDIF
|
|
ELSE
|
|
INT k
|
|
FOR k = 2 TO 3
|
|
IF IS_PED_UNINJURED(OtherJoggers[k].thisIndex)
|
|
AND IS_PED_RAGDOLL(OtherJoggers[k].thisIndex)
|
|
CLEAR_PED_TASKS(OtherJoggers[k].thisIndex)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(OtherJoggers[k].thisIndex, PLAYER_PED_ID()) < GET_DISTANCE_BETWEEN_ENTITIES(OtherJoggers[k].thisIndex, MARY_ANN)
|
|
TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), -1)
|
|
TASK_TURN_PED_TO_FACE_ENTITY(NULL, PLAYER_PED_ID(), 0)
|
|
ELSE
|
|
TASK_LOOK_AT_ENTITY(NULL, MARY_ANN, -1)
|
|
TASK_TURN_PED_TO_FACE_ENTITY(NULL, MARY_ANN, 0)
|
|
ENDIF
|
|
TASK_PAUSE(NULL, 3000)
|
|
TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, OtherJoggers[k].thisGoToPos2, 0.7, DEFAULT_TIME_BEFORE_WARP, 1, ENAV_NO_STOPPING)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(OtherJoggers[k].thisIndex, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
ENDIF
|
|
IF IS_ENTITY_ALIVE(OtherJoggers[k].thisIndex)
|
|
IF IS_ENTITY_TOUCHING_ENTITY(PLAYER_PED_ID(), OtherJoggers[k].thisIndex)
|
|
CLEAR_PED_TASKS(OtherJoggers[k].thisIndex)
|
|
TASK_SMART_FLEE_PED(OtherJoggers[k].thisIndex, PLAYER_PED_ID(), 200, -1, TRUE)
|
|
SAFE_RELEASE_PED(OtherJoggers[k].thisIndex)
|
|
ENDIF
|
|
ENDIF
|
|
ENDFOR
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Handle the behaviour and events for the driveby fingering near the steps
|
|
PROC UPDATE_DRIVEBY_FINGERING()
|
|
IF IS_PED_UNINJURED(DRIVEBY_FINGER_CAR.Passenger)
|
|
AND IS_VEHICLE_OK(DRIVEBY_FINGER_CAR.thisCarIndex)
|
|
AND IS_PED_UNINJURED(DRIVEBY_FINGER_CAR.Driver)
|
|
|
|
SWITCH driveByState
|
|
CASE DRIVE_BY_LOAD
|
|
IF LOAD_DRIVEBY()
|
|
DEBUG_PRINTSTRING("Driveby scene resources loaded - progressing")
|
|
driveByState = DRIVE_BY_PRE_TASK
|
|
ENDIF
|
|
BREAK
|
|
CASE DRIVE_BY_PRE_TASK
|
|
// Wait here until told to progress in ROAD_RUNNING_SECTION
|
|
BREAK
|
|
CASE DRIVE_BY_SET_DRIVE_TASK
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_PAUSE(NULL, 1500)
|
|
TASK_VEHICLE_DRIVE_TO_COORD(NULL, DRIVEBY_FINGER_CAR.thisCarIndex, DRIVEBY_FINGER_CAR.thisGoToPos, DRIVEBY_FINGER_CAR.thisSpeed,
|
|
DRIVINGSTYLE_NORMAL, DRIVEBY_FINGER_CAR.thisCarModel, DF_SteerAroundPeds, 10, 10)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(DRIVEBY_FINGER_CAR.Driver, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
b_DrivebyHorn = FALSE
|
|
driveByState = DRIVE_BY_DRIVE
|
|
BREAK
|
|
CASE DRIVE_BY_DRIVE
|
|
IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(DRIVEBY_FINGER_CAR.thisCarIndex), GET_ENTITY_COORDS(MARY_ANN)) <= 45
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
KILL_FACE_TO_FACE_CONVERSATION()
|
|
ENDIF
|
|
IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(DRIVEBY_FINGER_CAR.thisCarIndex), GET_ENTITY_COORDS(MARY_ANN)) <= 20
|
|
IF b_DrivebyHorn = FALSE
|
|
START_VEHICLE_HORN(DRIVEBY_FINGER_CAR.thisCarIndex, 4500)
|
|
IF IS_PED_UNINJURED(MARY_ANN)
|
|
TASK_LOOK_AT_ENTITY(MARY_ANN, DRIVEBY_FINGER_CAR.thisCarIndex, 3000, SLF_WIDEST_PITCH_LIMIT|SLF_WIDEST_YAW_LIMIT|SLF_USE_TORSO)
|
|
ENDIF
|
|
b_DrivebyHorn = TRUE
|
|
ENDIF
|
|
IF MADialogueState = MA_WITHIN_TALKING_RANGE
|
|
IF NOT IS_MESSAGE_BEING_DISPLAYED()
|
|
IF CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", road2Conversation.rootLabel, CONV_PRIORITY_VERY_HIGH)
|
|
road2Conversation.hasBeenPlayed = TRUE
|
|
DEBUG_PRINTSTRING("Doing Mary Ann's anim...")
|
|
TASK_PLAY_ANIM(MARY_ANN, "rcmfanatic1yell", "yell_d", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_UPPERBODY|AF_SECONDARY)
|
|
driveByState = DRIVE_BY_SET_FINGER_TASK
|
|
MADialogueState = MA_WITHIN_TALKING_RANGE
|
|
IF MASprintState = SPRINT_ACTIVE
|
|
MASprintState = SPRINT_REDUCE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
IF CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", road2Conversation.rootLabel, CONV_PRIORITY_VERY_HIGH, DO_NOT_DISPLAY_SUBTITLES)
|
|
road2Conversation.hasBeenPlayed = TRUE
|
|
DEBUG_PRINTSTRING("Doing Mary Ann's anim...")
|
|
TASK_PLAY_ANIM(MARY_ANN, "rcmfanatic1yell", "yell_d", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_UPPERBODY|AF_SECONDARY)
|
|
driveByState = DRIVE_BY_SET_FINGER_TASK
|
|
MADialogueState = MA_OUT_OF_TALKING_RANGE
|
|
IF MASprintState = SPRINT_ACTIVE
|
|
MASprintState = SPRINT_REDUCE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE DRIVE_BY_SET_FINGER_TASK
|
|
CLEAR_PED_TASKS(DRIVEBY_FINGER_CAR.Driver)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_VEHICLE_DRIVE_WANDER(NULL, DRIVEBY_FINGER_CAR.thisCarIndex, 6, DF_SteerAroundPeds)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(DRIVEBY_FINGER_CAR.Driver, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
|
|
TASK_DRIVE_BY(DRIVEBY_FINGER_CAR.Passenger, MARY_ANN, NULL, <<0,0,0>>, 25, 100, FALSE, FIRING_PATTERN_FULL_AUTO)
|
|
|
|
iOneLinerTimer = GET_GAME_TIMER() - 3000 // Reset the one-liner timer so there's a gap after Mary Ann finishes her above line
|
|
|
|
driveByState = DRIVE_BY_FINGERING
|
|
BREAK
|
|
|
|
CASE DRIVE_BY_FINGERING
|
|
|
|
IF IS_ENTITY_PLAYING_ANIM(MARY_ANN, "rcmfanatic1yell", "yell_d")
|
|
IF GET_ENTITY_ANIM_CURRENT_TIME(MARY_ANN, "rcmfanatic1yell", "yell_d") > 0.44
|
|
CLEAR_PED_SECONDARY_TASK(MARY_ANN)
|
|
iDrivebyTimer = GET_GAME_TIMER()
|
|
driveByState = DRIVE_BY_RELEASE
|
|
TURN_ROADS_ON()
|
|
ENDIF
|
|
ELSE // Just in case the anim doesn't play for some reason...
|
|
iDrivebyTimer = GET_GAME_TIMER()
|
|
driveByState = DRIVE_BY_RELEASE
|
|
TURN_ROADS_ON()
|
|
ENDIF
|
|
|
|
BREAK
|
|
CASE DRIVE_BY_RELEASE
|
|
IF (GET_GAME_TIMER() - iDrivebyTimer) > 3000
|
|
|
|
IF IS_PED_UNINJURED(DRIVEBY_FINGER_CAR.Driver)
|
|
IF IS_VEHICLE_OK(DRIVEBY_FINGER_CAR.thisCarIndex)
|
|
// IF IS_PED_UNINJURED(DRIVEBY_FINGER_CAR.Passenger)
|
|
// CLEAR_PED_TASKS(DRIVEBY_FINGER_CAR.Passenger)
|
|
// ENDIF
|
|
CLEAR_PED_TASKS(DRIVEBY_FINGER_CAR.Driver)
|
|
CLEAR_PED_SECONDARY_TASK(DRIVEBY_FINGER_CAR.Driver)
|
|
TASK_VEHICLE_DRIVE_WANDER(DRIVEBY_FINGER_CAR.Driver, DRIVEBY_FINGER_CAR.thisCarIndex, 15, DF_SteerAroundPeds | DRIVINGMODE_AVOIDCARS_OBEYLIGHTS)
|
|
SET_PED_KEEP_TASK(DRIVEBY_FINGER_CAR.Driver, TRUE)
|
|
SAFE_RELEASE_PED(DRIVEBY_FINGER_CAR.Driver)
|
|
SAFE_RELEASE_VEHICLE(DRIVEBY_FINGER_CAR.thisCarIndex)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
SAFE_RELEASE_PED(DRIVEBY_FINGER_CAR.Passenger)
|
|
SAFE_RELEASE_PED(FOLLOWING_CAR.Driver)
|
|
|
|
IF IS_PED_UNINJURED(FOLLOWING_CAR.Passenger)
|
|
DEBUG_PRINTSTRING("*** Clearing driveby task and releasing")
|
|
CLEAR_PED_TASKS(FOLLOWING_CAR.Passenger)
|
|
SAFE_RELEASE_PED(FOLLOWING_CAR.Passenger, TRUE)
|
|
ENDIF
|
|
SAFE_RELEASE_VEHICLE(FOLLOWING_CAR.thisCarIndex)
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Manages the playback of the dynamic heartbeat audio during the mission
|
|
PROC DEAL_WITH_HEARTBEAT_AUDIO()
|
|
|
|
IF NOT bHeartbeatStarted
|
|
IF iCURRENT_RACE_POS > 3
|
|
PLAY_SOUND_FRONTEND(iHeartbeatAudioID, "HEARTBEAT", "FANATIC_SOUNDSET")
|
|
bHeartbeatStarted = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
SEQUENCE_INDEX seq_michael
|
|
|
|
PROC DEAL_WITH_MICHAEL_OUT_OF_BREATH()
|
|
ANIM_DATA none
|
|
IF b_DoneOutOfBreath = FALSE
|
|
IF GET_SCRIPT_TASK_STATUS(PLAYER_PED_ID(), SCRIPT_TASK_PERFORM_SEQUENCE) != PERFORMING_TASK
|
|
AND GET_SCRIPT_TASK_STATUS(PLAYER_PED_ID(), SCRIPT_TASK_PERFORM_SEQUENCE) != WAITING_TO_START_TASK
|
|
OPEN_SEQUENCE_TASK(seq_michael)
|
|
TASK_SCRIPTED_ANIMATION(NULL, adBreathEnter, none, none)
|
|
TASK_SCRIPTED_ANIMATION(NULL, adBreathIdle1, none, none)
|
|
TASK_SCRIPTED_ANIMATION(NULL, adBreathIdle2, none, none)
|
|
TASK_SCRIPTED_ANIMATION(NULL, adBreathIdle3, none, none)
|
|
// TASK_PLAY_ANIM(NULL, "rcmfanatic1out_of_breath", "p_zero_tired_enter", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_SECONDARY|AF_UPPERBODY|AF_PRIORITY_MEDIUM)
|
|
// TASK_PLAY_ANIM(NULL, "rcmfanatic1out_of_breath", "p_zero_tired_01", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_SECONDARY|AF_UPPERBODY|AF_PRIORITY_MEDIUM)
|
|
// TASK_PLAY_ANIM(NULL, "rcmfanatic1out_of_breath", "p_zero_tired_02", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_SECONDARY|AF_UPPERBODY|AF_PRIORITY_MEDIUM)
|
|
// TASK_PLAY_ANIM(NULL, "rcmfanatic1out_of_breath", "p_zero_tired_01", NORMAL_BLEND_IN, SLOW_BLEND_OUT, -1, AF_SECONDARY|AF_UPPERBODY|AF_LOOPING|AF_PRIORITY_MEDIUM)
|
|
CLOSE_SEQUENCE_TASK(seq_michael)
|
|
TASK_PERFORM_SEQUENCE(PLAYER_PED_ID(), seq_michael)
|
|
//SET_ANIM_FILTER(PLAYER_PED_ID(), "UpperbodyFeathered_NoLeftArm_filter" , AF_PRIORITY_MEDIUM, TRUE)
|
|
DEBUG_PRINTSTRING("Starting out of breath anim loop")
|
|
b_DoneOutOfBreath = TRUE
|
|
CLEAR_SEQUENCE_TASK(seq_michael)
|
|
ENDIF
|
|
ELSE
|
|
//SET_ANIM_FILTER(PLAYER_PED_ID(), "UpperbodyFeathered_NoLeftArm_filter" , AF_PRIORITY_MEDIUM, TRUE)
|
|
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), MAS_BIKE, TRUE)
|
|
IF IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), "rcmfanatic1out_of_breath", "p_zero_tired_enter")
|
|
OR IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), "rcmfanatic1out_of_breath", "p_zero_tired_01")
|
|
OR IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), "rcmfanatic1out_of_breath", "p_zero_tired_02")
|
|
CLEAR_PED_TASKS(PLAYER_PED_ID())
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Make Mary Ann continually face the player if she's playing her "jogging_on_spot" animation
|
|
PROC DEAL_WITH_MARY_ANN_FACING_PLAYER()
|
|
|
|
IF IS_ENTITY_ALIVE(MARY_ANN)
|
|
IF IS_ENTITY_PLAYING_ANIM(MARY_ANN, "rcmfanatic1", "jogging_on_spot")
|
|
// MATHS
|
|
VECTOR n
|
|
VECTOR b = NORMALISE_VECTOR(GET_ENTITY_COORDS(PLAYER_PED_ID()) - GET_ENTITY_COORDS(MARY_ANN))
|
|
VECTOR a = GET_ENTITY_FORWARD_VECTOR(MARY_ANN)
|
|
FLOAT t = 0.25
|
|
// AARON IS A FUCKING MATHS WIZARD
|
|
n = a + ((b - a) * t)
|
|
SET_ENTITY_HEADING(MARY_ANN, GET_HEADING_FROM_COORDS(<<0, 0, 0>>, n))
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Handle things if the player decides to jack a vehicle during the race
|
|
PROC STAGE_PLAYER_IN_VEHICLE()
|
|
SWITCH stageStage
|
|
CASE SS_SETUP
|
|
DEBUG_PRINTSTRING("SETUP PLAYER IN VEHICLE STATE")
|
|
IF IS_SCRIPTED_CONVERSATION_ONGOING()
|
|
PAUSE_SCRIPTED_CONVERSATION(FALSE)
|
|
ENDIF
|
|
IF DOES_BLIP_EXIST(DESTINATION_BLIP)
|
|
SET_BLIP_ALPHA(DESTINATION_BLIP, 0)
|
|
ENDIF
|
|
CLEAR_PRINTS()
|
|
IF IS_WAYPOINT_PLAYBACK_GOING_ON_FOR_PED(MARY_ANN)
|
|
WAYPOINT_PLAYBACK_PAUSE(MARY_ANN, TRUE)
|
|
ENDIF
|
|
|
|
TASK_FOLLOW_TO_OFFSET_OF_ENTITY(MARY_ANN, PLAYER_PED_ID(), <<0,0,0>>, 3, -1, 3)
|
|
|
|
iVehicleFailTimer = GET_GAME_TIMER()
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
DEBUG_PRINTSTRING("stop scripted conversation at STAGE_PLAYER_IN_VEHICLE")
|
|
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
|
|
ENDIF
|
|
bMARY_ANN_CHASING_YOU_IN_CAR = TRUE
|
|
DEBUG_PRINTSTRING("STARTING PLAYER IN VEHICLE LOOP")
|
|
stageStage = SS_STAGE
|
|
BREAK
|
|
CASE SS_STAGE
|
|
|
|
IF bMARY_ANN_CHASING_YOU_IN_CAR
|
|
IF GET_DISTANCE_BETWEEN_PEDS(PLAYER_PED_ID(), MARY_ANN) < 4
|
|
CLEAR_PED_TASKS(MARY_ANN)
|
|
TASK_TURN_PED_TO_FACE_ENTITY(MARY_ANN, PLAYER_PED_ID(), -1)
|
|
bMARY_ANN_CHASING_YOU_IN_CAR = FALSE
|
|
ENDIF
|
|
ELSE
|
|
IF GET_DISTANCE_BETWEEN_PEDS(PLAYER_PED_ID(), MARY_ANN) > 5
|
|
CLEAR_PED_TASKS(MARY_ANN)
|
|
TASK_FOLLOW_TO_OFFSET_OF_ENTITY(MARY_ANN, PLAYER_PED_ID(), <<0,0,0>>, 3, -1, 3)
|
|
bMARY_ANN_CHASING_YOU_IN_CAR = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF (GET_GAME_TIMER() - iVehicleFailTimer) > 4000
|
|
TRIGGER_MUSIC_EVENT("RC6A_FAIL")
|
|
failReason = FAIL_IN_CAR
|
|
stageStage = SS_SETUP
|
|
missionstage = MS_FAIL_WAIT_FOR_FADE
|
|
ENDIF
|
|
|
|
IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
|
|
CLEAR_PRINTS()
|
|
|
|
IF NOT IS_STRING_NULL(sFANATIC_ROUTE)
|
|
IF GET_IS_WAYPOINT_RECORDING_LOADED(sFANATIC_ROUTE)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), -1, SLF_DEFAULT)
|
|
TASK_FOLLOW_NAV_MESH_TO_COORD(null, GET_COORD_FURTHER_ALONG_ROUTE(), 3)
|
|
TASK_FOLLOW_WAYPOINT_RECORDING(NULL, sFANATIC_ROUTE, GET_MARY_ANNS_NEXT_WAYPOINT(), EWAYPOINT_DEFAULT | EWAYPOINT_VEHICLES_USE_AI_SLOWDOWN | EWAYPOINT_ALLOW_STEERING_AROUND_PEDS, -1)
|
|
TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), -1)
|
|
TASK_PLAY_ANIM(null, "move_f@runner", "idle", SLOW_BLEND_IN, SLOW_BLEND_OUT, -1, AF_LOOPING)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(MARY_ANN, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
stageStage = SS_STAGE
|
|
missionStage = currentMissionStage
|
|
IF DOES_BLIP_EXIST(DESTINATION_BLIP)
|
|
SET_BLIP_ALPHA(DESTINATION_BLIP, 255)
|
|
ENDIF
|
|
|
|
RESTART_SCRIPTED_CONVERSATION()
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Check if the player has skipped a checkpoint, and return true if the distance between them is over the distance passed in
|
|
FUNC BOOL PLAYER_SKIPPED_CHECKPOINT(FLOAT distance)
|
|
IF iCURRENT_RACE_POS < iMaxRacePositions - 1
|
|
INT closestWaypointToBlip
|
|
WAYPOINT_RECORDING_GET_CLOSEST_WAYPOINT(sFANATIC_ROUTE, RACE_POSITIONS[iCURRENT_RACE_POS], closestWaypointToBlip)
|
|
if closestWaypointToBlip < iNum_PlayerClosestWaypoint
|
|
IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), RACE_POSITIONS[iCURRENT_RACE_POS]) > distance
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE: Check if the player has abandoned the race route by a significant margin, or if the distance between them and Mary Ann
|
|
/// has gotten too great
|
|
PROC CHECK_IF_PLAYER_LEFT_THE_COURSE_OR_MARY_ANN()
|
|
|
|
// THIS CHECKS IF YOU LEAVE THE ROUTE BY DISTANCE CHECKING THE CLOSEST POINT ON THE WAYPOINT REC
|
|
// OR IF THE PLAYER RUNS PAST A CHECKPOINT AND CONTINUES ON THE COURSE
|
|
IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), vPos_PlayerClosestWaypoint) > 60
|
|
OR PLAYER_SKIPPED_CHECKPOINT(60)
|
|
TRIGGER_MUSIC_EVENT("RC6A_FAIL")
|
|
failReason = FAIL_LEFT_RACE
|
|
stageStage = SS_SETUP
|
|
missionstage = MS_FAIL_WAIT_FOR_FADE
|
|
ELSE
|
|
IF leftRaceWarning.hasBeenShown = FALSE
|
|
IF NOT IS_THIS_PRINT_BEING_DISPLAYED(leftBehindWarning.textLabel)
|
|
IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), vPos_PlayerClosestWaypoint) > 40
|
|
OR PLAYER_SKIPPED_CHECKPOINT(40)
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
DEBUG_PRINTSTRING("stop scripted conversation at CHECK_IF_PLAYER_LEFT_THE_COURSE_OR_MARY_ANN")
|
|
KILL_ANY_CONVERSATION()
|
|
ENDIF
|
|
CLEAR_PRINTS()
|
|
PRINT(leftRaceWarning.textLabel, DEFAULT_GOD_TEXT_TIME, 1) //Return to the ~y~race.
|
|
leftRaceWarning.hasBeenShown = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// IF THE PLAYER IS BEHIND MARY ANN CHECK HOW FAR
|
|
IF iNum_PlayerClosestWaypoint < iNum_NPCClosestWaypoint
|
|
IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(MARY_ANN)) > 70
|
|
TRIGGER_MUSIC_EVENT("RC6A_FAIL")
|
|
failReason = FAIL_YOU_DIDNT_KEEP_UP
|
|
stageStage = SS_SETUP
|
|
missionstage = MS_FAIL_WAIT_FOR_FADE
|
|
ELIF leftBehindWarning.hasBeenShown = FALSE
|
|
AND NOT IS_THIS_PRINT_BEING_DISPLAYED(leftRaceWarning.textLabel)
|
|
IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(MARY_ANN)) > 50
|
|
PRINT_NOW(leftBehindWarning.textLabel, DEFAULT_GOD_TEXT_TIME, 1) //Catch up with ~b~Mary Ann.
|
|
leftBehindWarning.hasBeenShown = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Check if the player has got into a vehicle during the mission
|
|
PROC CHECK_IF_PLAYER_IS_IN_A_VEHICLE()
|
|
IF missionStage <> MS_PLAYER_IN_VEHICLE
|
|
AND missionStage <> MS_FAIL_WAIT_FOR_FADE
|
|
AND missionStage <> MS_END_CUTSCENE
|
|
AND missionStage <> MS_FAIL_WAIT_FOR_FADE
|
|
AND missionStage <> MS_LOST_RACE
|
|
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
|
|
IF vehicleWarning.hasBeenShown = FALSE
|
|
PRINT_HELP(vehicleWarning.textLabel)
|
|
vehicleWarning.hasBeenShown = TRUE
|
|
ENDIF
|
|
IF CAN_PED_SEE_PLAYER(MARY_ANN)
|
|
OR GET_DISTANCE_BETWEEN_PEDS(PLAYER_PED_ID(), MARY_ANN) < 7
|
|
currentMissionStage = missionstage
|
|
stageStage = SS_SETUP
|
|
missionStage = MS_PLAYER_IN_VEHICLE
|
|
ENDIF
|
|
ENDIF
|
|
ELIF missionStage = MS_END_CUTSCENE
|
|
// If we're in here, this is being called from END_CUTSCENE() and we need to check for the player dicking about during the unscripted scene
|
|
IF cutsceneStage <> CS_CUTSCENE_ENDS
|
|
IF IS_VEHICLE_OK(MAS_BIKE)
|
|
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), MAS_BIKE)
|
|
b_PlayerOnMAsBike = TRUE
|
|
// IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
// KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
|
|
// ENDIF
|
|
// IF PLAY_SINGLE_LINE_FROM_CONVERSATION(MyLocalPedStruct, "FAN1AU", "FAN1_AGGRO", "FAN1_AGGRO_1", CONV_PRIORITY_VERY_HIGH)
|
|
// CLEAR_PED_TASKS(MARY_ANN)
|
|
// TASK_SMART_FLEE_PED(MARY_ANN, PLAYER_PED_ID(), 150, -1)
|
|
// cutsceneStage = CS_CUTSCENE_ENDS
|
|
// ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Checks for Michael bumping into anyone and plays an appropriate line of dialogue if possible
|
|
PROC CHECK_PLAYER_COLLISIONS()
|
|
IF HAS_ENTITY_COLLIDED_WITH_ANYTHING(PLAYER_PED_ID())
|
|
PED_INDEX ped[32]
|
|
IF GET_PED_NEARBY_PEDS(PLAYER_PED_ID(), ped) > 0
|
|
// If the ped index exists, the player probably bumped into a ped rather than an object or whatever
|
|
IF DOES_ENTITY_EXIST(ped[0])
|
|
AND NOT IS_ENTITY_DEAD(ped[0])
|
|
IF IS_ENTITY_TOUCHING_ENTITY(PLAYER_PED_ID(), ped[0])
|
|
// Do different things depending on whether the ped is Mary Ann or an ambient civvie
|
|
IF ped[0] = MARY_ANN
|
|
DEBUG_PRINTSTRING("Player touched Mary Ann!")
|
|
if not IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
IF MikePushMALine.timesPlayed <= 3
|
|
IF CAN_MARY_ANN_SAY_RANDOM_LINE(MikePushMALine.dialogueLine)
|
|
DEBUG_PRINTSI("Saying MikePushMALine #", MikePushMALine.timesPlayed)
|
|
MikePushMALine.timesPlayed++
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
DEBUG_PRINTSTRING("Player touched a civ!")
|
|
IF NOT IS_PED_IN_ANY_VEHICLE(ped[0]) // Ignore if in a vehicle, otherwise it asserts...
|
|
// We can't do this to Mary Ann very easily, but we can for civvies without causing horribleness!
|
|
IF NOT IS_PED_RAGDOLL(ped[0])
|
|
CLEAR_PED_TASKS(ped[0])
|
|
SET_PED_TO_RAGDOLL(ped[0], 800, 1500, TASK_NM_BALANCE)
|
|
VECTOR pushDir = -GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(PLAYER_PED_ID(), GET_ENTITY_COORDS(ped[0]))
|
|
APPLY_FORCE_TO_ENTITY(ped[0], APPLY_TYPE_IMPULSE, pushDir, <<0,0,0>>, GET_PED_RAGDOLL_BONE_INDEX(ped[0], RAGDOLL_SPINE), FALSE, FALSE, TRUE)
|
|
ENDIF
|
|
if not IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
IF MikePushPedLine.timesPlayed <= 3
|
|
IF CAN_MARY_ANN_SAY_RANDOM_LINE(MikePushPedLine.dialogueLine)
|
|
DEBUG_PRINTSI("Said MikePushPedLine #", MikePushPedLine.timesPlayed)
|
|
MikePushPedLine.timesPlayed++
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// If the player's just overtaken Mary Ann, make her try and say an overtake line if possible
|
|
PROC TRY_OVERTAKE_LINE()
|
|
|
|
IF bOvertaken = TRUE
|
|
AND (GET_GAME_TIMER() - iOvertakeTimer) < 1500 // If it's been less than 1.5s since we overtook Mary Ann, do the line
|
|
if not IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
IF OvertakeLines.timesPlayed <= 3
|
|
IF bOvertakenSkip = FALSE
|
|
IF CAN_MARY_ANN_SAY_RANDOM_LINE(OvertakeLines.dialogueLine)
|
|
DEBUG_PRINTSI("Said OvertakeLines #", OvertakeLines.timesPlayed)
|
|
OvertakeLines.timesPlayed++
|
|
bOvertaken = FALSE
|
|
bOvertakenSkip = true // Skip the next time we overtake to reduce frequency of dialogue (B*1416011)
|
|
iOvertakeTimer = GET_GAME_TIMER() // Make sure we can't keep playing the overtake line over and over
|
|
ENDIF
|
|
ELSE
|
|
bOvertakenSkip = FALSE
|
|
bOvertaken = FALSE
|
|
iOvertakeTimer = GET_GAME_TIMER()
|
|
ENDIF
|
|
ELSE
|
|
bOvertaken = FALSE
|
|
iOvertakeTimer = GET_GAME_TIMER()
|
|
ENDIF
|
|
ELSE
|
|
bOvertaken = FALSE
|
|
iOvertakeTimer = GET_GAME_TIMER()
|
|
ENDIF
|
|
ELSE
|
|
IF bOvertaken = TRUE // Only do this reset if necessary! (or it keeps resetting the timer and we never get any overtake lines...)
|
|
bOvertaken = FALSE
|
|
iOvertakeTimer = GET_GAME_TIMER()
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Check if the player has threatened, injured or killed Mary Ann
|
|
PROC CHECK_IF_MARY_ANN_IS_INJURED_KILLED_OR_SCARED()
|
|
IF IS_ENTITY_DEAD(MARY_ANN)
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
DEBUG_PRINTSTRING("stop scripted conversation at CHECK_IF_MARY_ANN_IS_INJURED_KILLED_OR_SCARED 1")
|
|
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
|
|
ENDIF
|
|
DEBUG_PRINTSTRING("Mary Ann killed")
|
|
TRIGGER_MUSIC_EVENT("RC6A_FAIL")
|
|
failReason = FAIL_FANATIC_KILLED
|
|
stageStage = SS_SETUP
|
|
missionstage = MS_FAIL_WAIT_FOR_FADE
|
|
ELSE
|
|
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(MARY_ANN, PLAYER_PED_ID())
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
DEBUG_PRINTSTRING("stop scripted conversation at CHECK_IF_MARY_ANN_IS_INJURED_KILLED_OR_SCARED 2")
|
|
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
|
|
ENDIF
|
|
DEBUG_PRINTSTRING("Mary Ann injured by player")
|
|
TRIGGER_MUSIC_EVENT("RC6A_FAIL")
|
|
failReason = FAIL_FANATIC_INJURED
|
|
stageStage = SS_SETUP
|
|
missionstage = MS_FAIL_WAIT_FOR_FADE
|
|
ENDIF
|
|
IF HAS_PED_BEEN_DAMAGED_BY_WEAPON(MARY_ANN, WEAPONTYPE_INVALID, GENERALWEAPON_TYPE_ANYWEAPON)
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
DEBUG_PRINTSTRING("stop scripted conversation at CHECK_IF_MARY_ANN_IS_INJURED_KILLED_OR_SCARED 3")
|
|
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
|
|
ENDIF
|
|
DEBUG_PRINTSTRING("Mary Ann injured by some form of weapon")
|
|
TRIGGER_MUSIC_EVENT("RC6A_FAIL")
|
|
failReason = FAIL_FANATIC_INJURED
|
|
stageStage = SS_SETUP
|
|
missionstage = MS_FAIL_WAIT_FOR_FADE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF bMARY_ANN_IS_GOING_TO_RUN_SCARED = TRUE
|
|
DEBUG_PRINTSTRING("Mary Ann scared")
|
|
IF IS_ENTITY_ALIVE(MARY_ANN)
|
|
CLEAR_PED_TASKS(MARY_ANN)
|
|
ENDIF
|
|
TRIGGER_MUSIC_EVENT("RC6A_FAIL")
|
|
failReason = FAIL_FANATIC_SCARED
|
|
stageStage = SS_SETUP
|
|
missionstage = MS_FAIL_WAIT_FOR_FADE
|
|
ELSE
|
|
IF IS_ENTITY_ALIVE(MARY_ANN)
|
|
IF IS_PLAYER_SHOOTING_NEAR_PED(MARY_ANN)
|
|
OR HAS_PLAYER_THREATENED_PED(MARY_ANN)
|
|
OR IS_BULLET_IN_AREA(GET_ENTITY_COORDS(MARY_ANN), 10, FALSE)
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
DEBUG_PRINTSTRING("Killing any convo before scared convo")
|
|
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
|
|
ENDIF
|
|
bMARY_ANN_IS_GOING_TO_RUN_SCARED = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Check if Mary Ann has beaten the player to the finish line
|
|
PROC CHECK_IF_MARY_ANN_WINS_RACE()
|
|
IF missionStage <> MS_LOST_RACE // Don't want to keep resetting the Lost Race state once it's been triggered!
|
|
AND missionStage <> MS_FAIL_WAIT_FOR_FADE
|
|
IF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(MARY_ANN, vPos_FinishLine) < 3
|
|
DEBUG_PRINTSTRING("Detected Mary Ann won race")
|
|
failReason = FAIL_SHE_BEAT_YOU_TO_BIKE
|
|
stageStage = SS_SETUP
|
|
missionstage = MS_LOST_RACE
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Check for all fail possibilities during the mission
|
|
PROC CHECK_FAIL_POSSIBILITIES()
|
|
IF ENUM_TO_INT(missionStage) <> ENUM_TO_INT(MS_END_CUTSCENE)
|
|
AND ENUM_TO_INT(missionStage) <> ENUM_TO_INT(MS_FAIL_WAIT_FOR_FADE)
|
|
AND ENUM_TO_INT(missionStage) > ENUM_TO_INT(MS_CUTSCENE)
|
|
IF DOES_ENTITY_EXIST(MARY_ANN)
|
|
CHECK_IF_MARY_ANN_IS_INJURED_KILLED_OR_SCARED()
|
|
CHECK_IF_PLAYER_IS_IN_A_VEHICLE()
|
|
|
|
DETERMINE_CLOSEST_WAYPOINTS()
|
|
CHECK_IF_PLAYER_LEFT_THE_COURSE_OR_MARY_ANN()
|
|
CHECK_IF_MARY_ANN_WINS_RACE()
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
PROC CLEAR_RACE_ROUTE_OF_VEHICLES()
|
|
|
|
IF GET_IS_WAYPOINT_RECORDING_LOADED(sFANATIC_ROUTE)
|
|
INT iMaxPoints = 0
|
|
WAYPOINT_RECORDING_GET_NUM_POINTS(sFANATIC_ROUTE, iMaxPoints)
|
|
INT i = 0
|
|
FOR i = 0 to iMaxPoints
|
|
VECTOR vNewCoord = <<0,0,0>>
|
|
WAYPOINT_RECORDING_GET_COORD(sFANATIC_ROUTE, i, vNewCoord)
|
|
CLEAR_AREA_OF_VEHICLES(vNewCoord, 4)
|
|
DEBUG_PRINTSI("Clearing area around waypoint", i)
|
|
ENDFOR
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
//PURPOSE: general cutscene setup
|
|
PROC GO_TO_CUTSCENE()
|
|
camCutsceneStart = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", TRUE)
|
|
SET_CAM_PARAMS(camCutsceneStart,<<-2006.4041, -505.1258, 12.1679>>, <<-8.4110, 0.0000, -152.3152>>, 50)//<<-2004.4519, -496.6223, 12.3469>>, << -11.3454, -0.0000, -160.9836 >>, 50)
|
|
RENDER_SCRIPT_CAMS(TRUE, FALSE)
|
|
SET_CAM_ACTIVE(camCutsceneStart, TRUE)
|
|
ENDPROC
|
|
|
|
//PURPOSE: Once Mary Ann reaches this position the next stage of the race begins
|
|
FUNC BOOL RACE_LEG_FINISHED(VECTOR pos)
|
|
|
|
IF IS_ENTITY_AT_COORD(MARY_ANN, pos, <<3,3,2>>)
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
return FALSE
|
|
ENDFUNC
|
|
|
|
/// 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
|
|
|
|
/// PURPOSE: Initialise some basic elements of the mission such as the Z-skip list, the race checkpoints, and environment settings
|
|
PROC INIT()
|
|
|
|
CLEAR_PRINTS()
|
|
DEBUG_PRINTSTRING("IN INIT")
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
s_skip_menu[0].sTxtLabel = "INTRO CUTSCENE"
|
|
s_skip_menu[1].sTxtLabel = "START THE RUN"
|
|
s_skip_menu[2].sTxtLabel = "RUNNING ON ROAD"
|
|
s_skip_menu[3].sTxtLabel = "RUNNING DOWN STEPS"
|
|
s_skip_menu[4].sTxtLabel = "RACE TO THE FINISH"
|
|
s_skip_menu[5].sTxtLabel = "END OF RACE"
|
|
s_skip_menu[6].sTxtLabel = "***DEBUG: Next to finish line"
|
|
#ENDIF
|
|
|
|
sFANATIC_ROUTE = "Fanatic1MaryAnn"
|
|
|
|
// CLEARS THE ROUTE OF VEHICLES, IN CASE PLAYER HAS DROPPED ANY
|
|
CLEAR_ANGLED_AREA_OF_VEHICLES(<<-1877.022217,-439.566315,47.061394>>, <<-1809.614868,-493.493958,39.585079>>, 12.750000, TRUE)
|
|
CLEAR_ANGLED_AREA_OF_VEHICLES(<<-1816.865234,-492.408051,42.839161>>, <<-1792.158447,-470.209503,38.512688>>, 12.750000, TRUE)
|
|
CLEAR_ANGLED_AREA_OF_VEHICLES(<<-1792.193726,-470.231934,42.514709>>, <<-1726.926392,-552.837463,35.241489>>, 12.750000, TRUE)
|
|
CLEAR_ANGLED_AREA_OF_VEHICLES(<<-1728.023682,-561.872070,39.497372>>, <<-1835.284546,-514.933289,26.335573>>, 19.750000, TRUE)
|
|
CLEAR_ANGLED_AREA_OF_VEHICLES(<<-1822.225586,-535.309204,31.955553>>, <<-1890.278320,-616.276367,9.657555>>, 39.750000, TRUE)
|
|
CLEAR_ANGLED_AREA_OF_VEHICLES(<<-1867.242798,-622.763000,13.383512>>, <<-2013.266968,-497.979950,9.736394>>, 23.750000, TRUE)
|
|
|
|
REMOVE_RELATIONSHIP_GROUP(relGroupFriendly)
|
|
ADD_RELATIONSHIP_GROUP("FRIENDLIES", relGroupFriendly)
|
|
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_LIKE, relGroupFriendly, RELGROUPHASH_PLAYER)
|
|
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_LIKE, RELGROUPHASH_PLAYER, relGroupFriendly)
|
|
|
|
ADD_PED_FOR_DIALOGUE(MyLocalPedStruct, 0, PLAYER_PED_ID(), "MICHAEL")
|
|
|
|
LOAD_OTHER_ASSETS()
|
|
|
|
//SET_PLAYER_HAS_CHANGE_CLOTHES_ON_MISSION(CHAR_MICHAEL)
|
|
|
|
IF IS_ENTITY_ALIVE(MARY_ANN)
|
|
SET_PED_RELATIONSHIP_GROUP_HASH(MARY_ANN, relGroupFriendly)
|
|
SET_PED_SEEING_RANGE(MARY_ANN, 25.0)
|
|
SET_PED_MOVEMENT_CLIPSET(MARY_ANN, "FEMALE_FAST_RUNNER")
|
|
ENDIF
|
|
|
|
CLEAR_RACE_ROUTE_OF_VEHICLES()
|
|
|
|
CREATE_CARS()
|
|
|
|
//UNLOAD_ALL_MODELS()
|
|
|
|
TURN_ROADS_ON(FALSE)
|
|
|
|
sbiWallPeds = ADD_SCENARIO_BLOCKING_AREA(<<-1979.0620, -534.3250, 10.4558>>, <<-1973.3320, -528.2116, 13.7014>>)
|
|
sbiPathPeds = ADD_SCENARIO_BLOCKING_AREA(<<-1914.7804, -591.1177, 9.8302>>, <<-1910.3289, -586.7218, 12.0195>>)
|
|
sbiMobilePed = ADD_SCENARIO_BLOCKING_AREA(<<-1991.0669, -523.5920, 10.4269>>, <<-1989.1447, -521.6824, 11.3735>>)
|
|
|
|
adBreathEnter.type = APT_SINGLE_ANIM
|
|
adBreathEnter.dictionary0 = "rcmfanatic1out_of_breath"
|
|
adBreathEnter.anim0 = "p_zero_tired_enter"
|
|
adBreathEnter.blendInDelta = REALLY_SLOW_BLEND_IN
|
|
adBreathEnter.blendOutDelta = NORMAL_BLEND_OUT
|
|
adBreathEnter.flags = AF_SECONDARY|AF_UPPERBODY
|
|
adBreathEnter.filter = GET_HASH_KEY("UpperbodyFeathered_NoLefttArm_filter")
|
|
|
|
adBreathIdle1.type = APT_SINGLE_ANIM
|
|
adBreathIdle1.dictionary0 = "rcmfanatic1out_of_breath"
|
|
adBreathIdle1.anim0 = "p_zero_tired_01"
|
|
adBreathIdle1.blendInDelta = NORMAL_BLEND_IN
|
|
adBreathIdle1.blendOutDelta = NORMAL_BLEND_OUT
|
|
adBreathIdle1.flags = AF_SECONDARY|AF_UPPERBODY
|
|
adBreathIdle1.filter = GET_HASH_KEY("UpperbodyFeathered_NoLefttArm_filter")
|
|
|
|
adBreathIdle2.type = APT_SINGLE_ANIM
|
|
adBreathIdle2.dictionary0 = "rcmfanatic1out_of_breath"
|
|
adBreathIdle2.anim0 = "p_zero_tired_02"
|
|
adBreathIdle2.blendInDelta = NORMAL_BLEND_IN
|
|
adBreathIdle2.blendOutDelta = NORMAL_BLEND_OUT
|
|
adBreathIdle2.flags = AF_SECONDARY|AF_UPPERBODY
|
|
adBreathIdle2.filter = GET_HASH_KEY("UpperbodyFeathered_NoLefttArm_filter")
|
|
|
|
adBreathIdle3.type = APT_SINGLE_ANIM
|
|
adBreathIdle3.dictionary0 = "rcmfanatic1out_of_breath"
|
|
adBreathIdle3.anim0 = "p_zero_tired_01"
|
|
adBreathIdle3.blendInDelta = NORMAL_BLEND_IN
|
|
adBreathIdle3.blendOutDelta = INSTANT_BLEND_OUT
|
|
adBreathIdle3.flags = AF_SECONDARY|AF_UPPERBODY|AF_LOOPING
|
|
adBreathIdle3.filter = GET_HASH_KEY("UpperbodyFeathered_NoLefttArm_filter")
|
|
|
|
vPos_StartOfRoadRunning = <<-1730.2838, -551.7269, 36.3939>>
|
|
vPos_StartOfBeachRunning = <<-1870.6702, -616.2423, 10.8184>>
|
|
|
|
WAYPOINT_RECORDING_GET_NUM_POINTS(sFANATIC_ROUTE, iNum_WAYPOINTS)
|
|
|
|
RACE_POSITIONS[0] = <<-1868.36, -447.84, 45.20>>
|
|
RACE_POSITIONS[1] = <<-1835.81, -468.73, 43.45>>
|
|
RACE_POSITIONS[2] = <<-1753.45, -523.30, 37.35>>
|
|
RACE_POSITIONS[3] = vPos_StartOfRoadRunning
|
|
RACE_POSITIONS[4] = <<-1755.65, -558.99, 36.11>>
|
|
RACE_POSITIONS[5] = <<-1828.99, -516.33, 27.87>> // CLOSEST TO STEPS
|
|
RACE_POSITIONS[6] = <<-1819.20, -555.86, 15.77>>
|
|
RACE_POSITIONS[7] = vPos_StartOfBeachRunning
|
|
RACE_POSITIONS[8] = <<-1918.04, -583.45, 10.76>>
|
|
RACE_POSITIONS[9] = vPos_FinishLine
|
|
|
|
iMaxRacePositions = COUNT_OF(RACE_POSITIONS)
|
|
|
|
HURRY_UP_LINE[0] = "FAN1_FALLB_1"
|
|
HURRY_UP_LINE[1] = "FAN1_FALLB_2"
|
|
|
|
RACE_LINE[0] = "FAN1_FAST_1"
|
|
RACE_LINE[1] = "FAN1_FAST_2"
|
|
RACE_LINE[2] = "FAN1_FAST_3"
|
|
|
|
MikePushMALine.dialogueLine = "FAN1_RUNIN"
|
|
MikePushPedLine.dialogueLine = "FAN1_RUNIN2"
|
|
OvertakeLines.dialogueLine = "FAN1_OVERT"
|
|
|
|
pushLine[0].dialogueLine = "FAN1_PUSH_1"
|
|
pushLine[1].dialogueLine = "FAN1_PUSH_2"
|
|
pushLine[2].dialogueLine = "FAN1_PUSH_3"
|
|
|
|
cheatedLeaptFence.dialogueLine = "FAN1_CHEAT_1"
|
|
cheatedLeaptFence.rootLabel = "FAN1_CHEAT"
|
|
cheatedRanAcrossGrass.dialogueLine = "FAN1_CHEAT_2"
|
|
cheatedRanAcrossGrass.rootLabel = "FAN1_CHEAT"
|
|
returnAfterCheatedLine.dialogueLine = "FAN1_CATCHC_1"
|
|
returnAfterCheatedLine.rootLabel = "FAN1_CATCHC"
|
|
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
IF IS_OUTFIT_SUITABLE_FOR_FANATIC_MISSION(1)
|
|
startRunConversation.rootLabel = "FAN1_STRTB"
|
|
raceConversation.rootLabel = "FAN1_BCHB"
|
|
ELSE
|
|
startRunConversation.rootLabel = "FAN1_STRTA"
|
|
raceConversation.rootLabel = "FAN1_BCHA"
|
|
ENDIF
|
|
ENDIF
|
|
|
|
road1Conversation.rootLabel = "FAN1_RD1"
|
|
road2Conversation.rootLabel = "FAN1_RD2"
|
|
|
|
leftRaceWarning.textLabel = "FATIC1_7"
|
|
leftBehindWarning.textLabel = "FATIC1_6"
|
|
vehicleWarning.textLabel = "FATIC1_H"
|
|
|
|
DEBUG_PRINTSTRING("end of init")
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Main state for doing the lead-in
|
|
PROC LEADIN()
|
|
|
|
// Disable controls and exit current vehicle
|
|
RC_PLAYER_TRIGGER_SCENE_LOCK_IN()
|
|
|
|
SWITCH stageStage
|
|
CASE SS_SETUP
|
|
IF NOT Is_Replay_In_Progress()
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), MARY_ANN) <= 1.2
|
|
// 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")
|
|
stageStage = SS_SETUP
|
|
missionStage = MS_CUTSCENE
|
|
ENDIF
|
|
|
|
IF NOT IS_GAMEPLAY_HINT_ACTIVE()
|
|
SET_GAMEPLAY_ENTITY_HINT(MARY_ANN, <<0,0,0>>, TRUE, 30000)
|
|
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)
|
|
ELSE
|
|
STOP_GAMEPLAY_HINT_BEING_CANCELLED_THIS_UPDATE(TRUE)
|
|
ENDIF
|
|
|
|
REQUEST_ANIM_DICT("rcmfanatic1")
|
|
|
|
// Check for the anim dict being loaded, then if Mary Ann is in an early phase of her idle loop, then try to do the lead in convo and anims...
|
|
IF HAS_ANIM_DICT_LOADED("rcmfanatic1")
|
|
AND missionStage = MS_LEADIN // Ensure the stage is still lead-in in case the cutscene skip above occurred
|
|
IF IS_ENTITY_ALIVE(MARY_ANN)
|
|
IF IS_ENTITY_PLAYING_ANIM(MARY_ANN, "rcmfanatic1", "ef_1_rcm_mary_ann_streching_base")
|
|
IF GET_ENTITY_ANIM_CURRENT_TIME(MARY_ANN, "rcmfanatic1", "ef_1_rcm_mary_ann_streching_base") <0.1
|
|
FREEZE_ENTITY_POSITION(MARY_ANN, FALSE)
|
|
ADD_PED_FOR_DIALOGUE(MyLocalPedStruct, 3, MARY_ANN, "MARYANN")
|
|
ADD_PED_FOR_DIALOGUE(MyLocalPedStruct, 0, PLAYER_PED_ID(), "MICHAEL")
|
|
TASK_PLAY_ANIM_ADVANCED(MARY_ANN, "rcmfanatic1", "ef_1_rcm_mary_ann_leadin", <<-1878.223022,-440.518127,46.039829>>, <<0, 0, 159.97>>,
|
|
NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_HOLD_LAST_FRAME|AF_USE_KINEMATIC_PHYSICS|AF_NOT_INTERRUPTABLE)
|
|
DEBUG_PRINTSTRING("Done Mary Ann leadin anim")
|
|
|
|
stageStage = SS_STAGE
|
|
ELSE
|
|
DEBUG_PRINTSTRING("Waiting to blend the lead-in...")
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ELSE
|
|
DEBUG_PRINTSTRING("Replay in progress or in wrong area - skipping to intro")
|
|
missionStage = MS_CUTSCENE
|
|
ENDIF
|
|
BREAK
|
|
CASE SS_STAGE
|
|
IF IS_PED_UNINJURED(MARY_ANN)
|
|
IF NOT IS_GAMEPLAY_HINT_ACTIVE()
|
|
SET_GAMEPLAY_ENTITY_HINT(MARY_ANN, <<0,0,0>>, TRUE, 30000)
|
|
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)
|
|
ELSE
|
|
STOP_GAMEPLAY_HINT_BEING_CANCELLED_THIS_UPDATE(TRUE)
|
|
ENDIF
|
|
IF IS_ENTITY_PLAYING_ANIM(MARY_ANN, "rcmfanatic1", "ef_1_rcm_mary_ann_leadin")
|
|
IF b_LeadInConvo = FALSE
|
|
IF CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", "FAN1_LDI", CONV_PRIORITY_HIGH)
|
|
DEBUG_PRINTSTRING("Done Mary Ann leadin conv")
|
|
b_LeadInConvo = TRUE
|
|
ENDIF
|
|
ELSE
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
DEBUG_PRINTSTRING("Mary Ann leadin conv over")
|
|
WAIT(250) // Short wait just to add a more natural sounding pause after the final line before the CS starts
|
|
stageStage = SS_SETUP
|
|
missionStage = MS_CUTSCENE
|
|
ENDIF
|
|
ENDIF
|
|
// IF GET_ENTITY_ANIM_CURRENT_TIME(MARY_ANN, "rcmfanatic1", "ef_1_rcm_mary_ann_leadin") > 0.90
|
|
// DEBUG_PRINTSTRING("Mary Ann leadin anim over")
|
|
// stageStage = SS_SETUP
|
|
// missionStage = MS_CUTSCENE
|
|
// ENDIF
|
|
ELSE
|
|
DEBUG_PRINTSTRING("Mary Ann not playing leadin anim anymore - skip to cutscene for safety")
|
|
stageStage = SS_SETUP
|
|
missionStage = MS_CUTSCENE
|
|
ENDIF
|
|
// If player gets within 4m of Mary Ann, stop the player and make them face Mary Ann (B*231024)
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), MARY_ANN) <= 4.0
|
|
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE)
|
|
IF NOT IsPedPerformingTask(PLAYER_PED_ID(), SCRIPT_TASK_TURN_PED_TO_FACE_ENTITY)
|
|
TASK_TURN_PED_TO_FACE_ENTITY(PLAYER_PED_ID(), MARY_ANN)
|
|
TASK_LOOK_AT_ENTITY(PLAYER_PED_ID(), MARY_ANN, -1)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
FUNC BOOL DO_MICHAEL_BLEND()
|
|
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Michael")
|
|
DEBUG_PRINTSTRING("*** Forcing Michael's move state")
|
|
FORCE_PED_MOTION_STATE(PLAYER_PED_ID(), MS_ON_FOOT_RUN, FALSE, FAUS_CUTSCENE_EXIT)
|
|
SIMULATE_PLAYER_INPUT_GAIT(PLAYER_ID(), PEDMOVEBLENDRATIO_RUN, 5000)
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
PROC DO_MARY_ANN_BLEND()
|
|
|
|
IF IS_ENTITY_ALIVE(MARY_ANN)
|
|
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Mary_Ann", IG_MARYANN)
|
|
DEBUG_PRINTSTRING("*** Forcing Mary Ann's move state")
|
|
DEBUG_PRINTSTRING("SET MARY ANNS TASK")
|
|
IF b_CutsceneSkipped
|
|
SAFE_TELEPORT_ENTITY(MARY_ANN, <<-1867.64, -446.01, 45.16>>, 229.3557)
|
|
ENDIF
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(NULL, TRUE)
|
|
TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), -1, SLF_DEFAULT)
|
|
TASK_FOLLOW_WAYPOINT_RECORDING(NULL, sFANATIC_ROUTE, 1, EWAYPOINT_START_FROM_CLOSEST_POINT | EWAYPOINT_VEHICLES_USE_AI_SLOWDOWN | EWAYPOINT_ALLOW_STEERING_AROUND_PEDS | EWAYPOINT_NAVMESH_BACK_TO_WAYPOINT_IF_LEFT_ROUTE , -1)
|
|
TASK_PLAY_ANIM(null, "move_f@runner", "idle", SLOW_BLEND_IN, SLOW_BLEND_OUT, -1, AF_LOOPING)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(MARY_ANN, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
FORCE_PED_MOTION_STATE(MARY_ANN, MS_ON_FOOT_RUN, FALSE, FAUS_CUTSCENE_EXIT)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Main process to handle the intro cutscene
|
|
PROC INTRO_CUTSCENE()
|
|
SWITCH stageStage
|
|
CASE SS_SETUP
|
|
|
|
DEBUG_PRINTSTRING("Intro Cutscene")
|
|
|
|
RC_REQUEST_CUTSCENE("ef_1_rcm", TRUE)
|
|
|
|
IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY()
|
|
DEBUG_PRINTSTRING("Trying to set Mary Ann component variation")
|
|
SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Mary_Ann", MARY_ANN, CS_MARYANN)
|
|
ENDIF
|
|
|
|
iCutsceneStage = 0
|
|
b_MusicTriggered = FALSE
|
|
|
|
IF CutsceneNavBlockerID = -1
|
|
CutsceneNavBlockerID = ADD_NAVMESH_BLOCKING_OBJECT(<<-1877.30, -439.70, 45.05>>, <<4, 6, 2>>, 45.0)
|
|
ENDIF
|
|
|
|
IF RC_IS_CUTSCENE_OK_TO_START()
|
|
IF IS_ENTITY_ALIVE(MARY_ANN)
|
|
REGISTER_ENTITY_FOR_CUTSCENE(MARY_ANN, "Mary_Ann", CU_ANIMATE_EXISTING_SCRIPT_ENTITY, IG_MARYANN)
|
|
DEBUG_PRINTSTRING("Registered Mary Ann")
|
|
ENDIF
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
REGISTER_ENTITY_FOR_CUTSCENE(PLAYER_PED_ID(), "Michael", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
|
|
DEBUG_PRINTSTRING("Registered Michael")
|
|
ENDIF
|
|
|
|
sbiCutscene = ADD_SCENARIO_BLOCKING_AREA(<<-1926.6536, -387.8897, 46.7354>>, <<-1897.3219, -374.5802, 51.0241>>)
|
|
|
|
// 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)
|
|
|
|
//CLEAR_AREA_OF_VEHICLES(<<-1793.82, -472.73, 39.58>>, 40.0, DEFAULT, DEFAULT, TRUE, TRUE)
|
|
START_CUTSCENE()
|
|
WAIT(0)
|
|
SAFE_FADE_SCREEN_IN_FROM_BLACK(DEFAULT, FALSE)
|
|
RESOLVE_VEHICLES_INSIDE_ANGLED_AREA_WITH_SIZE_LIMIT(<<-1873.525513,-441.621063,44.693626>>, <<-1882.030029,-436.991730,47.483791>>, 7.0,
|
|
<<-1875.09, -431.08, 45.21>>, 236.42, GET_DEFAULT_ALLOWABLE_VEHICLE_SIZE_VECTOR())
|
|
RESOLVE_VEHICLES_INSIDE_ANGLED_AREA_WITH_SIZE_LIMIT(<<-1875.814819,-443.119110,49.135151>>, <<-1808.560669,-491.788696,36.580292>>, 11.0,
|
|
<<-1875.09, -431.08, 45.21>>, 236.42, GET_DEFAULT_ALLOWABLE_VEHICLE_SIZE_VECTOR())
|
|
RC_START_CUTSCENE_MODE(<<-1877.23, -440.46, 45.07>>, TRUE, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT)
|
|
INIT()
|
|
CLEAR_ANGLED_AREA_OF_VEHICLES(<<-1799.513428,-467.645935,43.138790>>, <<-1789.602783,-476.661560,36.837288>>, 7.50)
|
|
b_CutsceneSkipped = FALSE
|
|
DEBUG_PRINTSTRING("Going into cutscene main loop now")
|
|
|
|
stageStage = SS_STAGE
|
|
ELSE
|
|
DEBUG_PRINTSTRING("Waiting for cutscene to be OK to start...")
|
|
ENDIF
|
|
BREAK
|
|
CASE SS_STAGE
|
|
|
|
IF iCutsceneStage = 0
|
|
|
|
IF GET_CUTSCENE_TIME() >= 31000
|
|
IF NOT b_MusicTriggered
|
|
IF TRIGGER_MUSIC_EVENT("RC6A_START")
|
|
DEBUG_PRINTSTRING("Starting music")
|
|
b_MusicTriggered = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Keep spamming for the blend
|
|
SET_GAMEPLAY_CAM_RELATIVE_PITCH()
|
|
SET_GAMEPLAY_CAM_RELATIVE_HEADING()
|
|
|
|
IF WAS_CUTSCENE_SKIPPED()
|
|
DEBUG_PRINTSTRING("*** Cutscene skip detected")
|
|
DEBUG_PRINTSTRING("*** Cam exit state pitch/heading on skip")
|
|
SET_GAMEPLAY_CAM_RELATIVE_PITCH()
|
|
SET_GAMEPLAY_CAM_RELATIVE_HEADING()
|
|
IF IS_ENTITY_ALIVE(MARY_ANN)
|
|
SET_ENTITY_COORDS(MARY_ANN, <<-1869.24, -444.99, 45.17>>)
|
|
SET_ENTITY_HEADING(MARY_ANN, -143.87)
|
|
ENDIF
|
|
b_CutsceneSkipped = TRUE
|
|
iCutsceneStage = 1
|
|
ENDIF
|
|
|
|
// IF CAN_SET_EXIT_STATE_FOR_CAMERA()
|
|
// IF b_CutsceneSkipped
|
|
// DEBUG_PRINTSTRING("*** Cam exit state pitch/heading")
|
|
// SET_GAMEPLAY_CAM_RELATIVE_PITCH()
|
|
// SET_GAMEPLAY_CAM_RELATIVE_HEADING()
|
|
// ENDIF
|
|
// ENDIF
|
|
|
|
// Move on if blend happens
|
|
IF DO_MICHAEL_BLEND()
|
|
iCutsceneStage = 1
|
|
ENDIF
|
|
|
|
// Keep checking
|
|
DO_MARY_ANN_BLEND()
|
|
|
|
ELIF iCutsceneStage = 1
|
|
|
|
IF GET_CUTSCENE_TIME() >= 31000
|
|
IF NOT b_MusicTriggered
|
|
IF TRIGGER_MUSIC_EVENT("RC6A_START")
|
|
DEBUG_PRINTSTRING("Starting music")
|
|
b_MusicTriggered = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF WAS_CUTSCENE_SKIPPED()
|
|
DEBUG_PRINTSTRING("*** Cutscene skip detected")
|
|
DEBUG_PRINTSTRING("*** Cam exit state pitch/heading on skip")
|
|
SET_GAMEPLAY_CAM_RELATIVE_PITCH()
|
|
SET_GAMEPLAY_CAM_RELATIVE_HEADING()
|
|
IF IS_ENTITY_ALIVE(MARY_ANN)
|
|
SET_ENTITY_COORDS(MARY_ANN, <<-1869.24, -444.99, 45.17>>)
|
|
SET_ENTITY_HEADING(MARY_ANN, -143.87)
|
|
ENDIF
|
|
IF NOT b_MusicTriggered
|
|
IF TRIGGER_MUSIC_EVENT("RC6A_START")
|
|
DEBUG_PRINTSTRING("Starting music from skip")
|
|
b_MusicTriggered = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Keep checking in case we skipped
|
|
DO_MARY_ANN_BLEND()
|
|
|
|
// Keep checking in case missed in previous stage
|
|
DO_MICHAEL_BLEND()
|
|
|
|
IF NOT IS_CUTSCENE_ACTIVE()
|
|
REPLAY_STOP_EVENT()
|
|
|
|
REMOVE_NAVMESH_BLOCKING_OBJECT(CutsceneNavBlockerID)
|
|
CutsceneNavBlockerID = -1 // Reset so can be used again if we skip
|
|
REMOVE_SCENARIO_BLOCKING_AREA(sbiCutscene)
|
|
iOvertakeTimer = GET_GAME_TIMER()
|
|
stageStage = SS_SETUP
|
|
missionStage = MS_START_RUNNING
|
|
ENDIF
|
|
ENDIF
|
|
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Main process to handle the race immediately following the intro cutscene
|
|
PROC START_RUNNING()
|
|
SWITCH stageStage
|
|
CASE SS_SETUP
|
|
|
|
DEBUG_PRINTSTRING("Setup START_RUNNING")
|
|
|
|
REMOVE_VEHICLES_FROM_GENERATORS_IN_AREA(<<-1835.529785,-518.723816,25.116776>>, <<-1822.431030,-513.893311,30.386765>>)
|
|
SET_ALL_VEHICLE_GENERATORS_ACTIVE_IN_AREA(<<-1835.529785,-518.723816,25.116776>>, <<-1822.431030,-513.893311,30.386765>>, FALSE)
|
|
//CLEAR_AREA_OF_VEHICLES(<<-1793.82, -472.73, 39.58>>, 15.0)
|
|
// IF DOES_ENTITY_EXIST(MARY_ANN)
|
|
// SET_ENTITY_COORDS(MARY_ANN, <<-1865.90, -448.81, 45.2>>)
|
|
// SET_ENTITY_HEADING(MARY_ANN, -143.87)
|
|
// SET_PED_ON_THE_GROUND(MARY_ANN)
|
|
// ENDIF
|
|
|
|
IF NOT IS_AUDIO_SCENE_ACTIVE("FANATIC_MIX_SCENE")
|
|
START_AUDIO_SCENE("FANATIC_MIX_SCENE")
|
|
IF IS_ENTITY_ALIVE(MARY_ANN)
|
|
ADD_ENTITY_TO_AUDIO_MIX_GROUP(MARY_ANN,"FANATIC_MIX_MARY_ANNE")
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// In case the cutscene gets skipped or the trigger just somehow misses, do it here
|
|
IF NOT b_MusicTriggered
|
|
IF TRIGGER_MUSIC_EVENT("RC6A_START")
|
|
DEBUG_PRINTSTRING("Starting music - start_running() init")
|
|
b_MusicTriggered = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ADD_PED_FOR_DIALOGUE(MyLocalPedStruct, 3, MARY_ANN, "MARYANN")
|
|
|
|
RC_END_CUTSCENE_MODE(TRUE, FALSE)
|
|
RC_SET_ENTITY_PROOFS_FOR_CUTSCENE(sRCLauncherDataLocal, FALSE)
|
|
IF IS_ENTITY_ALIVE(MARY_ANN)
|
|
SET_ENTITY_PROOFS(MARY_ANN, FALSE, FALSE, FALSE, FALSE, FALSE)
|
|
ENDIF
|
|
|
|
start_time = GET_GAME_TIMER()
|
|
|
|
IF NOT DOES_BLIP_EXIST(FANATIC_BLIP)
|
|
FANATIC_BLIP = CREATE_PED_BLIP(MARY_ANN, TRUE, TRUE)
|
|
SET_BLIP_AS_FRIENDLY(FANATIC_BLIP, TRUE)
|
|
ENDIF
|
|
|
|
IF IS_PED_UNINJURED(MARY_ANN)
|
|
SET_PED_CAN_RAGDOLL_FROM_PLAYER_IMPACT(MARY_ANN, FALSE)
|
|
//FORCE_PED_MOTION_STATE(MARY_ANN, MS_ON_FOOT_RUN, true, FAUS_CUTSCENE_EXIT )
|
|
ENDIF
|
|
|
|
MASprintState = SPRINT_COOLDOWN
|
|
iSprintTimer = GET_GAME_TIMER()
|
|
|
|
IF GET_IS_WAYPOINT_RECORDING_LOADED("Fanatic1RollingStart")
|
|
DEBUG_PRINTSTRING("*** Using assisted movement...")
|
|
USE_WAYPOINT_RECORDING_AS_ASSISTED_MOVEMENT_ROUTE("Fanatic1RollingStart", TRUE, 2, 0.7)
|
|
ENDIF
|
|
|
|
b_ForcePlayerRunningAtStart = TRUE
|
|
|
|
iRollingStartTimer = GET_GAME_TIMER()
|
|
iConversationTimer = GET_GAME_TIMER()
|
|
|
|
DEBUG_PRINTSTRING("GOING INTO START_RUNNING LOOP")
|
|
|
|
REPLAY_RECORD_BACK_FOR_TIME(0.0, 10.0, REPLAY_IMPORTANCE_LOW)
|
|
|
|
stageStage = SS_STAGE
|
|
BREAK
|
|
|
|
CASE SS_STAGE
|
|
|
|
// 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
|
|
|
|
IF b_ForcePlayerRunningAtStart = TRUE
|
|
if (GET_GAME_TIMER() - iRollingStartTimer) < 5000
|
|
IF (GET_GAME_TIMER() - iRollingStartTimer) > 1000
|
|
IF IS_SCREEN_FADED_OUT()
|
|
DEBUG_PRINTSTRING("FADING IN NOW")
|
|
SAFE_FADE_SCREEN_IN_FROM_BLACK(500, FALSE)
|
|
RC_END_CUTSCENE_MODE(TRUE, FALSE)
|
|
ENDIF
|
|
ENDIF
|
|
//DEBUG_PRINTSTRING("USING ASSISTED ROUTE")
|
|
ELSE
|
|
b_ForcePlayerRunningAtStart = FALSE
|
|
DEBUG_PRINTSTRING("TURNING OFF ASSISTED ROUTE")
|
|
USE_WAYPOINT_RECORDING_AS_ASSISTED_MOVEMENT_ROUTE("Fanatic1RollingStart", FALSE)
|
|
REMOVE_WAYPOINT_RECORDING("Fanatic1RollingStart")
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF IS_ENTITY_ALIVE(MARY_ANN)
|
|
if GET_SCRIPT_TASK_STATUS(MARY_ANN, SCRIPT_TASK_PERFORM_SEQUENCE) != PERFORMING_TASK
|
|
DEBUG_PRINTSTRING("Re-set Mary Ann's task post-cutscene")
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(NULL, TRUE)
|
|
TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), -1, SLF_DEFAULT)
|
|
TASK_FOLLOW_WAYPOINT_RECORDING(NULL, sFANATIC_ROUTE, 1, EWAYPOINT_START_FROM_CLOSEST_POINT | EWAYPOINT_VEHICLES_USE_AI_SLOWDOWN | EWAYPOINT_ALLOW_STEERING_AROUND_PEDS | EWAYPOINT_NAVMESH_BACK_TO_WAYPOINT_IF_LEFT_ROUTE, -1)
|
|
TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), -1)
|
|
TASK_PLAY_ANIM(null, "move_f@runner", "idle", SLOW_BLEND_IN, SLOW_BLEND_OUT, -1, AF_LOOPING)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(MARY_ANN, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF cheatedLeaptFence.hasBeenPlayed = FALSE
|
|
IF iNum_NPCClosestWaypoint < 17
|
|
IF IS_PLAYER_CLIMBING(PLAYER_ID())
|
|
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-1799.070801,-468.659149,40.074013>>, <<-1820.118530,-492.413879,41.743690>>, 18.250000)
|
|
IF NOT IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-1798.075562,-468.229706,39.025360>>, <<-1816.664307,-484.317017,43.642105>>, 12.500000)
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
KILL_ANY_CONVERSATION()
|
|
ENDIF
|
|
IF CAN_MARY_ANN_SAY_SINGLE_LINE(cheatedLeaptFence.rootLabel, cheatedLeaptFence.dialogueLine, FALSE, startRunConversation.restartLine)
|
|
IF startRunConversation.restartLine != -1
|
|
startRunConversation.hasBeenInterrupted = TRUE
|
|
DEBUG_PRINTSTRING("*** startRunConversation interrupted!")
|
|
DEBUG_PRINTSI("*** startRunConversation will restart on line: ",startRunConversation.restartLine)
|
|
ENDIF
|
|
finishReason = FINISHED_BY_SHORTCUT
|
|
b_CheatedLine = TRUE // Do a returnAfterCheatedLine
|
|
cheatedLeaptFence.hasBeenPlayed = TRUE
|
|
g_savedGlobals.sRandomChars.g_bFanaticCheated = TRUE
|
|
ELSE
|
|
DEBUG_PRINTSTRING("*** Waiting for prior conversation to end before can play cheated line!")
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF cheatedRanAcrossGrass.hasBeenPlayed = FALSE
|
|
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-1772.761719,-532.997131,35.589294>>, <<-1797.245850,-492.129211,39.270397>>, 26.000000)
|
|
OR GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), <<-1812.910278,-468.525330,41.320290>>) < 10
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
KILL_ANY_CONVERSATION()
|
|
ENDIF
|
|
IF CAN_MARY_ANN_SAY_SINGLE_LINE(cheatedRanAcrossGrass.rootLabel, cheatedRanAcrossGrass.dialogueLine, FALSE, startRunConversation.restartLine)
|
|
IF startRunConversation.restartLine != -1
|
|
startRunConversation.hasBeenInterrupted = TRUE
|
|
DEBUG_PRINTSTRING("*** startRunConversation interrupted!")
|
|
DEBUG_PRINTSI("*** startRunConversation will restart on line: ",startRunConversation.restartLine)
|
|
ENDIF
|
|
finishReason = FINISHED_BY_SHORTCUT
|
|
b_CheatedLine = TRUE // Do a returnAfterCheatedLine
|
|
cheatedRanAcrossGrass.hasBeenPlayed = TRUE
|
|
g_savedGlobals.sRandomChars.g_bFanaticCheated = TRUE
|
|
ELSE
|
|
DEBUG_PRINTSTRING("*** Waiting for prior conversation to end before can play cheated line!")
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF b_CheatedLine = TRUE // Player has cheated, do a return line
|
|
IF returnAfterCheatedLine.hasBeenPlayed = FALSE
|
|
if GET_DISTANCE_BETWEEN_PEDS(PLAYER_PED_ID(), MARY_ANN) < 10
|
|
INT temp
|
|
IF CAN_MARY_ANN_SAY_SINGLE_LINE(returnAfterCheatedLine.rootLabel, returnAfterCheatedLine.dialogueLine, FALSE, temp)
|
|
returnAfterCheatedLine.hasBeenPlayed = TRUE
|
|
b_CheatedLine = FALSE
|
|
iOneLinerTimer = GET_GAME_TIMER()
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF CAN_CREATE_RUNNING_CONVERSATION()
|
|
IF startRunConversation.hasBeenPlayed = FALSE
|
|
AND (GET_GAME_TIMER() - iConversationTimer) > 3500
|
|
CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", startRunConversation.rootLabel, CONV_PRIORITY_MEDIUM)
|
|
DEBUG_PRINTSTRING("SETTING UP THE CONVERSATION")
|
|
startRunConversation.hasBeenPlayed = TRUE
|
|
iOneLinerTimer = GET_GAME_TIMER()
|
|
ELSE
|
|
IF startRunConversation.hasBeenInterrupted = TRUE
|
|
IF returnAfterCheatedLine.hasBeenPlayed = TRUE // We want to wait for the return after cheated line to be played first
|
|
tDialogueRoot = startRunConversation.rootLabel
|
|
tDialogueRoot += "_"
|
|
tDialogueRoot += startRunConversation.restartLine
|
|
IF CREATE_CONVERSATION_FROM_SPECIFIC_LINE(MyLocalPedStruct, "FAN1AU", startRunConversation.rootLabel, tDialogueRoot, CONV_PRIORITY_MEDIUM)
|
|
startRunConversation.hasBeenInterrupted = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// if the main conversation has been played, try doing the one-liners
|
|
IF startRunConversation.hasBeenPlayed
|
|
TRY_ONE_LINER()
|
|
ENDIF
|
|
|
|
IF RACE_LEG_FINISHED(vPos_StartOfRoadRunning)
|
|
fMBR_IncreaseRatio = 1.15
|
|
stageStage = SS_SETUP
|
|
missionStage = MS_ROAD_RUNNING_SECTION
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Main process to handle the road running section
|
|
PROC ROAD_RUNNING_SECTION()
|
|
|
|
SWITCH stageStage
|
|
CASE SS_SETUP
|
|
|
|
DEBUG_PRINTSTRING("SETUP ROAD_RUNNING_SECTION")
|
|
|
|
IF NOT DOES_BLIP_EXIST(FANATIC_BLIP)
|
|
FANATIC_BLIP = CREATE_PED_BLIP(MARY_ANN, TRUE, TRUE)
|
|
SET_BLIP_AS_FRIENDLY(FANATIC_BLIP, TRUE)
|
|
ENDIF
|
|
|
|
IF b_IsTheRoadSwitchedOn = TRUE
|
|
TURN_ROADS_ON(FALSE)
|
|
ENDIF
|
|
|
|
b_PlayerJumpedDownTheCliff = FALSE
|
|
|
|
iRoadTimer = GET_GAME_TIMER()
|
|
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
DEBUG_PRINTSTRING("stop scripted conversation at ROAD_RUNNING_SECTION")
|
|
KILL_ANY_CONVERSATION()
|
|
ENDIF
|
|
|
|
IF IS_VEHICLE_OK(FOLLOWING_CAR.thisCarIndex)
|
|
AND IS_PED_UNINJURED(FOLLOWING_CAR.Driver)
|
|
SET_ENTITY_COORDS(FOLLOWING_CAR.thisCarIndex, <<-1934.15, -438.19, 19.60>>)
|
|
SET_ENTITY_HEADING(FOLLOWING_CAR.thisCarIndex, 237.78)
|
|
SET_VEHICLE_ON_GROUND_PROPERLY(FOLLOWING_CAR.thisCarIndex)
|
|
TASK_VEHICLE_MISSION_COORS_TARGET(FOLLOWING_CAR.Driver, FOLLOWING_CAR.thisCarIndex, FOLLOWING_CAR.thisGoToPos, MISSION_GOTO, FOLLOWING_CAR.thisSpeed, DRIVINGMODE_AVOIDCARS_STOPFORPEDS_OBEYLIGHTS, 3, 3)
|
|
SET_ENTITY_LOAD_COLLISION_FLAG(FOLLOWING_CAR.Driver, TRUE)
|
|
ENDIF
|
|
|
|
|
|
DEBUG_PRINTSTRING("GOING INTO ROAD_RUNNING_SECTION LOOP")
|
|
|
|
driveByState = DRIVE_BY_PRE_TASK
|
|
stageStage = SS_STAGE
|
|
BREAK
|
|
CASE SS_STAGE
|
|
|
|
SET_PED_DENSITY_MULTIPLIER_THIS_FRAME(0.5)
|
|
|
|
IF CAN_CREATE_RUNNING_CONVERSATION()
|
|
IF road1Conversation.hasBeenPlayed = FALSE
|
|
INT i
|
|
IF IS_ENTITY_ALIVE(MARY_ANN)
|
|
WAYPOINT_RECORDING_GET_CLOSEST_WAYPOINT(sFANATIC_ROUTE, GET_ENTITY_COORDS(MARY_ANN), i)
|
|
ENDIF
|
|
IF i <= 52 // Only try and play the road conversation is Mary Ann is earlier or at the 54th waypoint, otherwise it's too late
|
|
IF cheatedLeaptFence.hasBeenPlayed = FALSE
|
|
AND cheatedRanAcrossGrass.hasBeenPlayed = FALSE
|
|
AND place = 2 // Only do the full one if the player is in second place
|
|
CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", road1Conversation.rootLabel, CONV_PRIORITY_MEDIUM)
|
|
ELSE
|
|
CREATE_CONVERSATION_FROM_SPECIFIC_LINE(MyLocalPedStruct, "FAN1AU", road1Conversation.rootLabel, "FAN1_RD1_3", CONV_PRIORITY_MEDIUM)
|
|
ENDIF
|
|
road1Conversation.hasBeenPlayed = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF driveByState = DRIVE_BY_PRE_TASK
|
|
IF iNum_NPCClosestWaypoint > 41
|
|
driveByState = DRIVE_BY_SET_DRIVE_TASK
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Only try this stuff if the main road conversations haven't been played
|
|
IF road1Conversation.hasBeenPlayed = TRUE
|
|
AND road2Conversation.hasBeenPlayed = TRUE
|
|
|
|
// Try and do a Mary Ann road rage conversation if a vehicle passes by
|
|
VECTOR vOffset
|
|
VEHICLE_INDEX vIdx
|
|
IF IS_ENTITY_ALIVE(MARY_ANN)
|
|
vOffset = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(MARY_ANN, <<0,6,0>>)
|
|
vIdx = GET_CLOSEST_VEHICLE(vOffset, 8, DUMMY_MODEL_FOR_SCRIPT, 2) // 2 = Return mission vehicles
|
|
if vIdx <> NULL
|
|
IF MADialogueState = MA_WITHIN_TALKING_RANGE
|
|
AND iRoadTimer > 2000
|
|
AND iRoadCounter < 5 // Max number of road rage lines
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
IF CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", "FAN1_RD3", CONV_PRIORITY_MEDIUM)
|
|
iRoadCounter++
|
|
iRoadTimer = GET_GAME_TIMER()
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
vIdx = GET_CLOSEST_VEHICLE(vOffset, 8, DUMMY_MODEL_FOR_SCRIPT, 4)
|
|
if vIdx <> NULL
|
|
IF MADialogueState = MA_WITHIN_TALKING_RANGE
|
|
AND iRoadTimer > 2000
|
|
AND iRoadCounter < 5 // Max number of road rage lines
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
IF CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", "FAN1_RD3", CONV_PRIORITY_MEDIUM)
|
|
iRoadCounter++
|
|
iRoadTimer = GET_GAME_TIMER()
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// If a road rage conversation above hasn't fired, try doing a one liner
|
|
TRY_ONE_LINER()
|
|
ENDIF
|
|
|
|
CHECK_IF_PLAYER_JUMPS_THE_CLIFF()
|
|
UPDATE_DRIVEBY_FINGERING()
|
|
|
|
IF iNum_NPCClosestWaypoint > 61
|
|
stageStage = SS_SETUP
|
|
missionStage = MS_STEPS_DOWN
|
|
ENDIF
|
|
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Main process to handle the steps down the cliff and over the freeway bridge
|
|
PROC STEPS_DOWN()
|
|
SWITCH stageStage
|
|
CASE SS_SETUP
|
|
|
|
DEBUG_PRINTSTRING("STEPS DOWN SETUP")
|
|
|
|
IF NOT DOES_BLIP_EXIST(FANATIC_BLIP)
|
|
FANATIC_BLIP = CREATE_PED_BLIP(MARY_ANN, TRUE, TRUE)
|
|
SET_BLIP_AS_FRIENDLY(FANATIC_BLIP, TRUE)
|
|
ENDIF
|
|
SET_PED_NON_CREATION_AREA(<<-1865.76, -617.48, 10.58>>, <<-1820.57, -552.41, 17.40>>)
|
|
//ADD_SCENARIO_BLOCKING_AREA(<<-1865.76, -617.48, 10.58>>, <<-1820.57, -552.41, 17.40>>)
|
|
SET_PED_PATHS_IN_AREA(<<-1865.76, -617.48, 10.58>>, <<-1820.57, -552.41, 17.40>>, FALSE)
|
|
|
|
IF IS_PED_UNINJURED(DRIVEBY_FINGER_CAR.Driver)
|
|
CLEAR_PED_TASKS(DRIVEBY_FINGER_CAR.Driver)
|
|
SAFE_RELEASE_PED(DRIVEBY_FINGER_CAR.Driver)
|
|
ENDIF
|
|
|
|
IF IS_VEHICLE_OK(DRIVEBY_FINGER_CAR.thisCarIndex)
|
|
SAFE_RELEASE_VEHICLE(DRIVEBY_FINGER_CAR.thisCarIndex)
|
|
ENDIF
|
|
|
|
DEBUG_PRINTSTRING("GOING INTO STEPS_DOWN MAIN LOOP")
|
|
|
|
stageStage = SS_STAGE
|
|
|
|
BREAK
|
|
CASE SS_STAGE
|
|
|
|
DEAL_WITH_THE_QUAD()
|
|
|
|
TRY_ONE_LINER()
|
|
|
|
SET_PED_DENSITY_MULTIPLIER_THIS_FRAME(0.5)
|
|
|
|
IF b_PlayerJumpedDownTheCliff = FALSE
|
|
CHECK_IF_PLAYER_JUMPS_THE_CLIFF()
|
|
ENDIF
|
|
|
|
IF RACE_LEG_FINISHED(vPos_StartOfBeachRunning)
|
|
fMBR_IncreaseRatio = 1.15
|
|
stageStage = SS_SETUP
|
|
missionStage = MS_SPRINT_TO_FINISH
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Main process to handle the final beach sprint
|
|
PROC SPRINT_TO_FINISH()
|
|
SWITCH stageStage
|
|
CASE SS_SETUP
|
|
|
|
DEBUG_PRINTSTRING("SETUP SPRINT_TO_FINISH")
|
|
|
|
IF NOT DOES_BLIP_EXIST(FANATIC_BLIP)
|
|
FANATIC_BLIP = CREATE_PED_BLIP(MARY_ANN, TRUE, TRUE)
|
|
SET_BLIP_AS_FRIENDLY(FANATIC_BLIP, TRUE)
|
|
ENDIF
|
|
|
|
beachDogState = DOG_LOADING
|
|
stageStage = SS_STAGE
|
|
|
|
DEBUG_PRINTSTRING("GOING INTO SPRINT_TO_FINISH MAIN LOOP")
|
|
|
|
BREAK
|
|
CASE SS_STAGE
|
|
|
|
SET_PED_DENSITY_MULTIPLIER_THIS_FRAME(0.5)
|
|
|
|
IF raceConversation.hasBeenPlayed = FALSE
|
|
AND iNum_NPCClosestWaypoint < 105
|
|
IF CAN_CREATE_RUNNING_CONVERSATION()
|
|
AND GET_DISTANCE_BETWEEN_PEDS(PLAYER_PED_ID(), MARY_ANN) < 25
|
|
IF CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", raceConversation.rootLabel, CONV_PRIORITY_MEDIUM)
|
|
raceConversation.hasBeenPlayed = TRUE
|
|
TASK_PLAY_ANIM(MARY_ANN, "rcmfanatic1yell", "yell_c", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_UPPERBODY|AF_SECONDARY)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF IS_THIS_CONVERSATION_ROOT_PLAYING(raceConversation.rootLabel)
|
|
IF GET_DISTANCE_BETWEEN_PEDS(PLAYER_PED_ID(), MARY_ANN) > 30
|
|
KILL_ANY_CONVERSATION()
|
|
ENDIF
|
|
ENDIF
|
|
|
|
CREATE_JOGGERS()
|
|
CREATE_MARY_ANNS_BIKE()
|
|
|
|
DEAL_WITH_THE_DOG()
|
|
DEAL_WITH_THE_QUAD()
|
|
DEAL_WITH_THE_TWO_FINAL_PEDS()
|
|
|
|
IF iRaceLineNumber < iMAXRaceLineNumber
|
|
AND iNum_NPCClosestWaypoint < 117
|
|
AND iNum_PlayerClosestWaypoint < 117
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
IF (GET_GAME_TIMER() - iConversationTimer) > 3000
|
|
int temp
|
|
if CAN_MARY_ANN_SAY_SINGLE_LINE("FAN1_FAST", RACE_LINE[iRaceLineNumber], FALSE, temp)
|
|
iRaceLineNumber++
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
iConversationTimer = GET_GAME_TIMER()
|
|
ENDIF
|
|
ENDIF
|
|
|
|
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Special process to debug move the player close to the finish line rather than directly on top of it
|
|
PROC DEBUG_NEAR_FINISH_LINE()
|
|
SWITCH stageStage
|
|
CASE SS_SETUP
|
|
|
|
IF NOT DOES_BLIP_EXIST(FANATIC_BLIP)
|
|
FANATIC_BLIP = CREATE_PED_BLIP(MARY_ANN, TRUE, TRUE)
|
|
SET_BLIP_AS_FRIENDLY(FANATIC_BLIP, TRUE)
|
|
ENDIF
|
|
|
|
stageStage = SS_STAGE
|
|
BREAK
|
|
CASE SS_STAGE
|
|
|
|
CREATE_MARY_ANNS_BIKE()
|
|
DEAL_WITH_THE_TWO_FINAL_PEDS()
|
|
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
|
|
|
|
/// PURPOSE: Main process to handle the end cutscene, either realtime or scripted
|
|
PROC END_CUTSCENE()
|
|
|
|
// handle the previous checkpoint in here to fade it out
|
|
IF PrevCheckpoint != NULL
|
|
INT PreviR, PreviG, PreviB, iA
|
|
DEBUG_PRINTSTRING("Fade previous CP")
|
|
iPrevAlpha -= 25
|
|
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 stageStage
|
|
CASE SS_SETUP
|
|
|
|
SAFE_REMOVE_BLIP(DESTINATION_BLIP)
|
|
DELETE_CHECKPOINT(checkPoint)
|
|
|
|
IF IS_PED_UNINJURED(BEACH_DOG)
|
|
CLEAR_PED_TASKS(BEACH_DOG)
|
|
TASK_SMART_FLEE_PED(BEACH_DOG, PLAYER_PED_ID(), 40, -1)
|
|
ENDIF
|
|
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
DEBUG_PRINTSTRING("stop scripted conversation at END_CUTSCENE")
|
|
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
|
|
ENDIF
|
|
|
|
IF IS_ENTITY_ALIVE(MARY_ANN)
|
|
SET_ENTITY_LOAD_COLLISION_FLAG(MARY_ANN, TRUE)
|
|
SET_PED_CAN_BE_KNOCKED_OFF_VEHICLE(MARY_ANN, KNOCKOFFVEHICLE_NEVER)
|
|
ENDIF
|
|
|
|
b_DoneOutOfBreath = FALSE
|
|
|
|
TRIGGER_MUSIC_EVENT("RC6A_FINISH")
|
|
|
|
WEAPON_TYPE currentWeapon
|
|
GET_CURRENT_PED_WEAPON(PLAYER_PED_ID(), currentWeapon, FALSE)
|
|
IF currentWeapon != WEAPONTYPE_UNARMED
|
|
SET_CURRENT_PED_WEAPON(PLAYER_PED_ID(), WEAPONTYPE_UNARMED, TRUE) // Force player to be unarmed so anim looks right
|
|
ENDIF
|
|
|
|
IF b_ScriptedEnding
|
|
|
|
CLEAR_AREA_OF_PEDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), 30)
|
|
RESOLVE_VEHICLES_INSIDE_ANGLED_AREA_WITH_SIZE_LIMIT(<<-2010.692993,-504.882050,9.529695>>, <<-1995.946777,-517.249390,13.764661>>, 10.0, <<-2008.54, -494.10, 11.04>>, 48.19,
|
|
GET_DEFAULT_ALLOWABLE_VEHICLE_SIZE_VECTOR())
|
|
RC_START_CUTSCENE_MODE(vPos_FinishLine, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, FALSE)
|
|
GO_TO_CUTSCENE()
|
|
|
|
IF GET_DISTANCE_BETWEEN_PEDS(PLAYER_PED_ID(), MARY_ANN) > 32
|
|
SET_ENTITY_COORDS(MARY_ANN, <<-1986.20, -526.22, 11>>)
|
|
SET_ENTITY_HEADING(MARY_ANN, 58.26)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_FOLLOW_WAYPOINT_RECORDING(NULL, sFANATIC_ROUTE, GET_MARY_ANNS_NEXT_WAYPOINT(), EWAYPOINT_DEFAULT | EWAYPOINT_VEHICLES_USE_AI_SLOWDOWN | EWAYPOINT_ALLOW_STEERING_AROUND_PEDS, -1)
|
|
TASK_PLAY_ANIM(null, "move_f@runner", "idle", SLOW_BLEND_IN, SLOW_BLEND_OUT, -1, AF_LOOPING)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(MARY_ANN, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
FORCE_PED_MOTION_STATE(MARY_ANN, MS_ON_FOOT_RUN, true, FAUS_CUTSCENE_EXIT )
|
|
ENDIF
|
|
|
|
TASK_LOOK_AT_ENTITY(MARY_ANN, PLAYER_PED_ID(), -1)
|
|
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, vPos_FinishLine, 1, DEFAULT_TIME_BEFORE_WARP, 0.5, ENAV_DEFAULT)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(PLAYER_PED_ID(), seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
FORCE_PED_MOTION_STATE(PLAYER_PED_ID(), MS_ON_FOOT_RUN, TRUE, FAUS_DEFAULT)
|
|
|
|
REQUEST_ANIM_DICT("rcmfanatic1out_of_breath")
|
|
WHILE NOT HAS_ANIM_DICT_LOADED("rcmfanatic1out_of_breath")
|
|
DEBUG_PRINTSTRING("Loading ANIMS")
|
|
WAIT(0)
|
|
ENDWHILE
|
|
|
|
b_TIRED_ANIM_PLAYING = FALSE
|
|
|
|
SET_EVERYONE_IGNORE_PLAYER(PLAYER_ID(), TRUE)
|
|
|
|
ELSE
|
|
REQUEST_ANIM_DICT("rcmfanatic1out_of_breath")
|
|
WHILE NOT HAS_ANIM_DICT_LOADED("rcmfanatic1out_of_breath")
|
|
DEBUG_PRINTSTRING("Loading ANIMS")
|
|
WAIT(0)
|
|
ENDWHILE
|
|
ENDIF
|
|
|
|
IF NOT DOES_ENTITY_EXIST(MAS_BIKE)
|
|
REQUEST_MODEL(MARYSBIKEMODEL)
|
|
WHILE NOT HAS_MODEL_LOADED(MARYSBIKEMODEL)
|
|
DEBUG_PRINTSTRING("Loading MARYSBIKE MODEL")
|
|
WAIT(0)
|
|
ENDWHILE
|
|
MAS_BIKE = CREATE_VEHICLE(MARYSBIKEMODEL, MAS_BIKE_POS, MAS_BIKE_DIR)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(MARYSBIKEMODEL)
|
|
ENDIF
|
|
|
|
INT p
|
|
FOR p = 0 TO 3
|
|
IF IS_PED_UNINJURED(OtherJoggers[p].thisIndex)
|
|
IF IS_PED_IN_MELEE_COMBAT(OtherJoggers[p].thisIndex)
|
|
OR IS_PED_RESPONDING_TO_EVENT(OtherJoggers[p].thisIndex, EVENT_PED_TO_CHASE)
|
|
OR IS_PED_RESPONDING_TO_EVENT(OtherJoggers[p].thisIndex, EVENT_MELEE_ACTION)
|
|
CLEAR_PED_TASKS(OtherJoggers[p].thisIndex)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_TURN_PED_TO_FACE_ENTITY(NULL, PLAYER_PED_ID())
|
|
TASK_PAUSE(NULL, 2000)
|
|
TASK_WANDER_STANDARD(NULL)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(OtherJoggers[p].thisIndex, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
SAFE_RELEASE_PED(OtherJoggers[p].thisIndex)
|
|
ENDIF
|
|
ENDIF
|
|
ENDFOR
|
|
|
|
myCam = CAM_TARGET_PLAYER
|
|
stageStage = SS_STAGE
|
|
|
|
BREAK
|
|
CASE SS_STAGE
|
|
|
|
DEAL_WITH_THE_TWO_FINAL_PEDS()
|
|
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
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_COVER) // Make the player unable to get into cover
|
|
|
|
SWITCH cutsceneStage
|
|
CASE CS_WAIT_FOR_ANN
|
|
|
|
IF b_ScriptedEnding
|
|
IF GET_SCRIPT_TASK_STATUS(PLAYER_PED_ID(), SCRIPT_TASK_PERFORM_SEQUENCE) = FINISHED_TASK
|
|
IF b_TIRED_ANIM_PLAYING = FALSE
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_PLAY_ANIM(NULL, "rcmfanatic1out_of_breath", "base", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_LOOPING)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(PLAYER_PED_ID(), seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
b_TIRED_ANIM_PLAYING = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF IS_ENTITY_AT_COORD(MARY_ANN, vPos_FinishLine, <<5,5,3>>)
|
|
AND b_TIRED_ANIM_PLAYING = TRUE
|
|
IF finishReason = FINISHED_BY_STEROIDS
|
|
dialogueOptionFinish = "FAN1_DONE_2"
|
|
ELIF finishReason = FINISHED_BY_SHORTCUT
|
|
dialogueOptionFinish = "FAN1_DONE_3"
|
|
ENDIF
|
|
|
|
IF CREATE_MULTIPART_CONVERSATION_WITH_4_LINES(MyLocalPedStruct, "FAN1AU",
|
|
"FAN1_DONE", "FAN1_DONE_1",
|
|
"FAN1_DONE", dialogueOptionFinish,
|
|
"FAN1_DONE", "FAN1_DONE_4",
|
|
"FAN1_DONE", "FAN1_DONE_5", CONV_PRIORITY_MEDIUM)
|
|
cutsceneStage = CS_MARY_ANN_LEAVES
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ELSE
|
|
|
|
// Keep looping this to make sure Michael's playing his out of breath anims
|
|
DEAL_WITH_MICHAEL_OUT_OF_BREATH()
|
|
|
|
INT i
|
|
IF IS_ENTITY_ALIVE(MARY_ANN)
|
|
WAYPOINT_RECORDING_GET_CLOSEST_WAYPOINT(sFANATIC_ROUTE, GET_ENTITY_COORDS(MARY_ANN), i)
|
|
IF i >=125
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_PLAY_ANIM(NULL, "rcmfanatic1", "jogging_up", NORMAL_BLEND_IN, FAST_BLEND_OUT, -1, AF_USE_KINEMATIC_PHYSICS)
|
|
TASK_PLAY_ANIM(NULL, "rcmfanatic1", "jogging_on_spot", FAST_BLEND_IN, SLOW_BLEND_OUT, -1, AF_LOOPING|AF_USE_KINEMATIC_PHYSICS)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(MARY_ANN, seq)
|
|
TASK_LOOK_AT_ENTITY(MARY_ANN, PLAYER_PED_ID(), -1)
|
|
IF finishReason = FINISHED_BY_STEROIDS
|
|
dialogueOptionFinish = "FAN1_DONE_2"
|
|
ELIF finishReason = FINISHED_BY_SHORTCUT
|
|
dialogueOptionFinish = "FAN1_DONE_3"
|
|
ENDIF
|
|
|
|
IF CREATE_MULTIPART_CONVERSATION_WITH_4_LINES(MyLocalPedStruct, "FAN1AU",
|
|
"FAN1_DONE", "FAN1_DONE_1",
|
|
"FAN1_DONE", dialogueOptionFinish,
|
|
"FAN1_DONE", "FAN1_DONE_4",
|
|
"FAN1_DONE", "FAN1_DONE_5", CONV_PRIORITY_MEDIUM)
|
|
|
|
REPLAY_RECORD_BACK_FOR_TIME(10.0, 10.0, REPLAY_IMPORTANCE_LOW)
|
|
|
|
cutsceneStage = CS_MARY_ANN_LEAVES
|
|
TASK_LOOK_AT_ENTITY(PLAYER_PED_ID(), MARY_ANN, 4000)
|
|
cutsceneStage = CS_MARY_ANN_LEAVES
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE CS_MARY_ANN_LEAVES
|
|
|
|
IF b_ScriptedEnding
|
|
switch myCam
|
|
CASE CAM_TARGET_PLAYER
|
|
IF GET_CURRENT_SCRIPTED_CONVERSATION_LINE() > 2
|
|
DETACH_CAM(camCutsceneStart)
|
|
STOP_CAM_POINTING(camCutsceneStart)
|
|
SET_CAM_PARAMS(camCutsceneStart,<<-2008.2262, -508.2978, 12.2798>>, <<-9.0657, -0.0000, -70.4730>>, 50.0)
|
|
myCam = CAM_MARY_ANN_LEAVES
|
|
ENDIF
|
|
BREAK
|
|
CASE CAM_MARY_ANN_LEAVES
|
|
IF IS_VEHICLE_OK(MAS_BIKE)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_LOOK_AT_ENTITY(NULL, MAS_BIKE, -1)
|
|
//TASK_PLAY_ANIM(NULL, "rcmfanatic1", "jogging_exit", FAST_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_TAG_SYNC_OUT|AF_USE_KINEMATIC_PHYSICS)
|
|
TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, <<-2003.36, -503.77, 10.48>>, PEDMOVEBLENDRATIO_RUN, DEFAULT, 1.0, ENAV_NO_STOPPING|ENAV_DONT_AVOID_PEDS|ENAV_SUPPRESS_EXACT_STOP)
|
|
TASK_ENTER_VEHICLE(NULL, MAS_BIKE, DEFAULT_TIME_BEFORE_WARP, VS_DRIVER, 1)
|
|
TASK_CLEAR_LOOK_AT(NULL)
|
|
TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), 2000)
|
|
TASK_VEHICLE_DRIVE_TO_COORD(NULL, MAS_BIKE, <<-2014.96, -455.47, 10.48>>, 10, DRIVINGSTYLE_NORMAL, MARYSBIKEMODEL, DF_SteerAroundStationaryCars, 3, 50)
|
|
TASK_VEHICLE_DRIVE_WANDER(NULL, MAS_BIKE, 10, DRIVINGMODE_AVOIDCARS_STOPFORPEDS_OBEYLIGHTS)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(MARY_ANN, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
SET_PED_KEEP_TASK(MARY_ANN, TRUE)
|
|
|
|
SET_ANIM_LOOPED(PLAYER_PED_ID(), FALSE)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_PLAY_ANIM(NULL, "rcmfanatic1out_of_breath", "base", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1)
|
|
TASK_LOOK_AT_ENTITY(NULL, MARY_ANN, -1)
|
|
TASK_TURN_PED_TO_FACE_COORD(NULL, <<-2000.81, -496.56, 10.56>>)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(PLAYER_PED_ID(), seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
ENDIF
|
|
cutsceneStage = CS_SAY_FINAL_LINE
|
|
BREAK
|
|
ENDSWITCH
|
|
ELSE
|
|
|
|
DEAL_WITH_MICHAEL_OUT_OF_BREATH()
|
|
DEAL_WITH_MARY_ANN_FACING_PLAYER() // Keep Mary Ann facing the player while this is playing out
|
|
|
|
IF GET_CURRENT_SCRIPTED_CONVERSATION_LINE() > 2
|
|
IF NOT b_PlayerOnMAsBike
|
|
IF IS_VEHICLE_OK(MAS_BIKE)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_CLEAR_LOOK_AT(NULL)
|
|
TASK_LOOK_AT_ENTITY(NULL, MAS_BIKE, -1)
|
|
//TASK_PLAY_ANIM(NULL, "rcmfanatic1", "jogging_exit", SLOW_BLEND_IN, FAST_BLEND_OUT, -1, AF_TAG_SYNC_OUT|AF_USE_KINEMATIC_PHYSICS)
|
|
TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, <<-2003.36, -503.77, 10.48>>, PEDMOVEBLENDRATIO_RUN, DEFAULT, 1.0, ENAV_NO_STOPPING|ENAV_DONT_AVOID_PEDS)
|
|
TASK_ENTER_VEHICLE(NULL, MAS_BIKE, DEFAULT_TIME_BEFORE_WARP, VS_DRIVER, PEDMOVEBLENDRATIO_RUN)
|
|
TASK_CLEAR_LOOK_AT(NULL)
|
|
TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), 2000)
|
|
TASK_VEHICLE_DRIVE_TO_COORD(NULL, MAS_BIKE, <<-2018.17, -461.00, 10.56>>, 10, DRIVINGSTYLE_NORMAL, MARYSBIKEMODEL, DF_SteerAroundStationaryCars, 3, 50)
|
|
TASK_VEHICLE_DRIVE_TO_COORD(NULL, MAS_BIKE, <<-2014.96, -455.47, 10.48>>, 10, DRIVINGSTYLE_NORMAL, MARYSBIKEMODEL, DF_SteerAroundStationaryCars, 3, 50)
|
|
TASK_VEHICLE_DRIVE_WANDER(NULL, MAS_BIKE, 10, DRIVINGMODE_AVOIDCARS_STOPFORPEDS_OBEYLIGHTS)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(MARY_ANN, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
SET_PED_KEEP_TASK(MARY_ANN, TRUE)
|
|
ENDIF
|
|
ELSE
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_CLEAR_LOOK_AT(NULL)
|
|
TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), 2000)
|
|
TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, <<-1954.10, -450.90, 16.77>>, PEDMOVEBLENDRATIO_RUN, DEFAULT_TIME_BEFORE_WARP)
|
|
TASK_WANDER_STANDARD(NULL)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(MARY_ANN, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
SET_PED_KEEP_TASK(MARY_ANN, TRUE)
|
|
ENDIF
|
|
TASK_LOOK_AT_ENTITY(PLAYER_PED_ID(), MARY_ANN, 6000)
|
|
cutsceneStage = CS_SAY_FINAL_LINE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
BREAK
|
|
CASE CS_SAY_FINAL_LINE
|
|
IF b_ScriptedEnding
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
IF NOT IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), MARY_ANN, <<5,5,3>>)
|
|
cutsceneStage = CS_CUTSCENE_ENDS
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
DEAL_WITH_MICHAEL_OUT_OF_BREATH()
|
|
IF b_PlayerOnMAsBike
|
|
IF NOT b_MaryAnnFinalOrdersGiven
|
|
IF IS_ENTITY_ALIVE(MARY_ANN)
|
|
CLEAR_PED_TASKS(MARY_ANN)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_CLEAR_LOOK_AT(NULL)
|
|
TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, <<-1954.10, -450.90, 16.77>>, PEDMOVEBLENDRATIO_RUN, DEFAULT_TIME_BEFORE_WARP)
|
|
TASK_WANDER_STANDARD(NULL)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(MARY_ANN, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
SET_PED_KEEP_TASK(MARY_ANN, TRUE)
|
|
b_MaryAnnFinalOrdersGiven = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
IF NOT IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), MARY_ANN, <<5,5,3>>)
|
|
cutsceneStage = CS_CUTSCENE_ENDS
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
BREAK
|
|
CASE CS_CUTSCENE_ENDS
|
|
IF b_ScriptedEnding
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
IF NOT IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), MARY_ANN, <<5,5,3>>)
|
|
CLEAR_PED_TASKS(PLAYER_PED_ID())
|
|
TASK_CLEAR_LOOK_AT(PLAYER_PED_ID())
|
|
SET_GAMEPLAY_CAM_RELATIVE_HEADING()
|
|
RENDER_SCRIPT_CAMS(FALSE, TRUE)
|
|
RC_END_CUTSCENE_MODE()
|
|
Script_Passed()
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
IF NOT IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), MARY_ANN, <<5,5,3>>)
|
|
TASK_CLEAR_LOOK_AT(PLAYER_PED_ID())
|
|
//CLEAR_PED_TASKS(PLAYER_PED_ID())
|
|
TASK_PLAY_ANIM(PLAYER_PED_ID(), "rcmfanatic1out_of_breath", "p_zero_tired_exit", INSTANT_BLEND_IN, REALLY_SLOW_BLEND_OUT, -1, AF_SECONDARY|AF_UPPERBODY)
|
|
FORCE_PED_AI_AND_ANIMATION_UPDATE(PLAYER_PED_ID())
|
|
Script_Passed()
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
IF b_ScriptedEnding
|
|
IF IS_CUTSCENE_SKIP_BUTTON_JUST_PRESSED_WITH_DELAY()
|
|
CLEAR_PED_TASKS(PLAYER_PED_ID())
|
|
TASK_CLEAR_LOOK_AT(PLAYER_PED_ID())
|
|
SET_GAMEPLAY_CAM_RELATIVE_HEADING()
|
|
RENDER_SCRIPT_CAMS(FALSE, FALSE)
|
|
RC_END_CUTSCENE_MODE()
|
|
INSTANTLY_FILL_VEHICLE_POPULATION()
|
|
Script_Passed()
|
|
ENDIF
|
|
ELSE
|
|
// Do Mary Ann checks here
|
|
IF IS_ENTITY_ALIVE(MARY_ANN)
|
|
CHECK_IF_MARY_ANN_IS_INJURED_KILLED_OR_SCARED()
|
|
CHECK_IF_PLAYER_IS_IN_A_VEHICLE()
|
|
|
|
// If the player gets too far away after the convo starts, kill the convo, make Mary Ann go away
|
|
IF cutsceneStage > CS_WAIT_FOR_ANN
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), MARY_ANN) > 15
|
|
// If the player's too far away and they're NOT on the bike...
|
|
IF NOT b_PlayerOnMAsBike
|
|
// ... and Mary Ann isn't in the bike herself...
|
|
IF NOT IS_PED_IN_ANY_VEHICLE(MARY_ANN, TRUE)
|
|
// ... make her go away!
|
|
IF cutsceneStage <= CS_MARY_ANN_LEAVES
|
|
IF IS_VEHICLE_OK(MAS_BIKE)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_LOOK_AT_ENTITY(NULL, MAS_BIKE, -1)
|
|
TASK_ENTER_VEHICLE(NULL, MAS_BIKE, DEFAULT_TIME_BEFORE_WARP, VS_DRIVER, 1)
|
|
TASK_CLEAR_LOOK_AT(NULL)
|
|
TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), 2000)
|
|
TASK_VEHICLE_DRIVE_TO_COORD(NULL, MAS_BIKE, <<-2018.17, -461.00, 10.56>>, 10, DRIVINGSTYLE_NORMAL, MARYSBIKEMODEL, DF_SteerAroundStationaryCars, 3, 50)
|
|
TASK_VEHICLE_DRIVE_TO_COORD(NULL, MAS_BIKE, <<-2024.98, -479.55, 10.57>>, 10, DRIVINGSTYLE_NORMAL, MARYSBIKEMODEL, DF_SteerAroundStationaryCars, 3, 50)
|
|
TASK_VEHICLE_DRIVE_WANDER(NULL, MAS_BIKE, 10, DRIVINGMODE_AVOIDCARS_STOPFORPEDS_OBEYLIGHTS)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(MARY_ANN, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
SET_PED_KEEP_TASK(MARY_ANN, TRUE)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
// The player's on her bike, so make Mary Ann run away instead
|
|
IF NOT b_MaryAnnFinalOrdersGiven
|
|
IF IS_ENTITY_ALIVE(MARY_ANN)
|
|
CLEAR_PED_TASKS(MARY_ANN)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_CLEAR_LOOK_AT(NULL)
|
|
TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, <<-1954.10, -450.90, 16.77>>, PEDMOVEBLENDRATIO_RUN, DEFAULT_TIME_BEFORE_WARP)
|
|
TASK_WANDER_STANDARD(NULL)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(MARY_ANN, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
SET_PED_KEEP_TASK(MARY_ANN, TRUE)
|
|
b_MaryAnnFinalOrdersGiven = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
// Kill the convo regardless of what Mary Ann is doing
|
|
KILL_ANY_CONVERSATION()
|
|
cutsceneStage = CS_CUTSCENE_ENDS
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
|
|
PROC LOST_RACE()
|
|
SWITCH stageStage
|
|
CASE SS_SETUP
|
|
DEBUG_PRINTSTRING("In setup for Lost Race")
|
|
// remove blips
|
|
SAFE_REMOVE_BLIP(FANATIC_BLIP)
|
|
SAFE_REMOVE_BLIP(DESTINATION_BLIP)
|
|
SAFE_REMOVE_BLIP(NEXT_DESTINATION_BLIP)
|
|
|
|
DELETE_CHECKPOINT(checkPoint)
|
|
|
|
BOOL bWhichConv // Use a random bool to determine which losing convo for Mary Ann to play
|
|
bWhichConv = GET_RANDOM_BOOL()
|
|
IF MADialogueState = MA_WITHIN_TALKING_RANGE
|
|
IF bWhichConv = TRUE
|
|
CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", "FAN1_LOSE", CONV_PRIORITY_HIGH)
|
|
DEBUG_PRINTSTRING("Doing 'FAN1_LOSE'")
|
|
ELSE
|
|
CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", "FAN1_LOSE2", CONV_PRIORITY_HIGH)
|
|
DEBUG_PRINTSTRING("Doing 'FAN1_LOSE2'")
|
|
ENDIF
|
|
ENDIF
|
|
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_LOOK_AT_ENTITY(null, PLAYER_PED_ID(), -1)
|
|
TASK_PLAY_ANIM(null, "rcmfanatic1celebrate", "celebrate", SLOW_BLEND_IN, FAST_BLEND_OUT, -1, AF_EXIT_AFTER_INTERRUPTED|AF_USE_KINEMATIC_PHYSICS|AF_TAG_SYNC_IN)
|
|
TASK_PLAY_ANIM(null, "move_f@runner", "idle", FAST_BLEND_IN, SLOW_BLEND_OUT, -1, AF_LOOPING|AF_EXIT_AFTER_INTERRUPTED|AF_USE_KINEMATIC_PHYSICS)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(MARY_ANN, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
|
|
DEBUG_PRINTSTRING("Going into loop for Lost Race")
|
|
stageStage = SS_STAGE
|
|
|
|
BREAK
|
|
CASE SS_STAGE
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
DEBUG_PRINTSTRING("No conversation going in Lost Race, failing properly now")
|
|
TRIGGER_MUSIC_EVENT("RC6A_FAIL")
|
|
failReason = FAIL_SHE_BEAT_YOU_TO_BIKE
|
|
stageStage = SS_SETUP
|
|
missionstage = MS_FAIL_WAIT_FOR_FADE
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Main process to handle mission failure and the fade out
|
|
PROC FAIL_WAIT_FOR_FADE()
|
|
SWITCH stageStage
|
|
CASE SS_SETUP
|
|
CLEAR_PRINTS()
|
|
CLEAR_HELP()
|
|
|
|
IF FailReason <> FAIL_FANATIC_SCARED
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
DEBUG_PRINTSTRING("Killing conversation in fail state")
|
|
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
|
|
ENDIF
|
|
ELSE
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
IF CREATE_CONVERSATION(MyLocalPedStruct, "FAN1AU", "FAN1_AGGRO", CONV_PRIORITY_VERY_HIGH)
|
|
DEBUG_PRINTSTRING("Playing aggro convo with subs")
|
|
ENDIF
|
|
ELSE
|
|
DEBUG_PRINTSTRING("Convo already active when failing for scaring Mary Ann - playing without subs asap?")
|
|
KILL_ANY_CONVERSATION()
|
|
ADD_NON_CRITICAL_STANDARD_CONVERSATION_TO_BUFFER(MyLocalPedStruct, "FAN1AU", "FAN1_AGGRO", CONV_PRIORITY_HIGH)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// remove blips
|
|
SAFE_REMOVE_BLIP(FANATIC_BLIP)
|
|
SAFE_REMOVE_BLIP(DESTINATION_BLIP)
|
|
SAFE_REMOVE_BLIP(NEXT_DESTINATION_BLIP)
|
|
|
|
DELETE_CHECKPOINT(checkPoint)
|
|
|
|
// handle Mary Ann
|
|
IF FailReason = FAIL_FANATIC_INJURED
|
|
OR FailReason = FAIL_FANATIC_KILLED
|
|
OR FailReason = FAIL_FANATIC_SCARED
|
|
IF IS_ENTITY_ALIVE(MARY_ANN)
|
|
TASK_SMART_FLEE_PED(MARY_ANN, PLAYER_PED_ID(), 80, -1)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
STRING fText
|
|
SWITCH FailReason
|
|
CASE FAIL_FANATIC_KILLED
|
|
fText = "FATIC1_F8"
|
|
BREAK
|
|
CASE FAIL_FANATIC_SCARED
|
|
fText = "FATIC1_F2"
|
|
BREAK
|
|
CASE FAIL_FANATIC_INJURED
|
|
fText = "FATIC1_F1"
|
|
BREAK
|
|
CASE FAIL_IN_CAR
|
|
fText = "FATIC1_F5"
|
|
BREAK
|
|
CASE FAIL_YOU_DIDNT_KEEP_UP
|
|
fText = "FATIC1_F3"
|
|
BREAK
|
|
CASE FAIL_SHE_BEAT_YOU_TO_BIKE
|
|
fText = "FATIC1_F7"
|
|
BREAK
|
|
CASE FAIL_LEFT_RACE
|
|
fText = "FATIC1_F6"
|
|
BREAK
|
|
DEFAULT
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
IF NOT IS_STRING_NULL_OR_EMPTY(fText)
|
|
Random_Character_Failed_With_Reason(fText)
|
|
ELSE
|
|
Random_Character_Failed()
|
|
ENDIF
|
|
|
|
stageStage = SS_STAGE
|
|
BREAK
|
|
CASE SS_STAGE
|
|
|
|
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(<< -1860.4117, -416.5467, 44.9804 >>, 143.1230)
|
|
//SET_REPLAY_DECLINED_VEHICLE_WARP_LOCATION(<< -1856.55, -413.59, 45.32 >>, -120.328)
|
|
|
|
|
|
// finished fading out
|
|
DELETE_EVERYTHING()
|
|
TURN_ROADS_ON()
|
|
RESET_PLAYER_HAS_CHANGE_CLOTHES_ON_MISSION(CHAR_MICHAEL, bHasChanged)
|
|
|
|
Script_Cleanup()
|
|
ELSE
|
|
// not finished fading out
|
|
// you may want to handle dialogue etc here.
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
// ===========================================================================================================
|
|
// Script Loop
|
|
// ===========================================================================================================
|
|
|
|
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]")
|
|
TRIGGER_MUSIC_EVENT("RC6A_FAIL")
|
|
Random_Character_Failed()
|
|
Script_Cleanup()
|
|
ENDIF
|
|
|
|
IF Is_Replay_In_Progress() // Set up the initial scene for replays
|
|
OR IS_REPEAT_PLAY_ACTIVE()
|
|
g_bSceneAutoTrigger = TRUE
|
|
eInitialSceneStage = IS_REQUEST_SCENE
|
|
WHILE NOT SetupScene_FANATIC_1(sRCLauncherDataLocal)
|
|
WAIT(0)
|
|
ENDWHILE
|
|
g_bSceneAutoTrigger = FALSE
|
|
ENDIF
|
|
|
|
DISABLE_CHEAT(CHEAT_TYPE_FAST_RUN, TRUE)
|
|
|
|
MARY_ANN = sRCLauncherDataLocal.pedID[0]
|
|
|
|
bHasChanged = GET_PLAYER_HAS_CHANGE_CLOTHES_ON_MISSION(CHAR_MICHAEL)
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF NOT DOES_WIDGET_GROUP_EXIST(widgetGroup)
|
|
widgetGroup= START_WIDGET_GROUP("Fanatic 1 widgets")
|
|
ADD_WIDGET_FLOAT_SLIDER("Maximum MBR rate increase", fMBRMax, 1.01, 1.15, 0.005)
|
|
ADD_WIDGET_FLOAT_SLIDER("Maximum MBR speed", fMBR_MaxRunSpeed, 2.5, 3.0, 0.01)
|
|
ADD_WIDGET_INT_SLIDER("Mary Ann sprint length (ms)", iSprintLength, 500, 5000, 100)
|
|
ADD_WIDGET_INT_SLIDER("Mary Ann sprint cooldown delay (ms)", iSprintDelay, 500, 10000, 100)
|
|
ADD_WIDGET_BOOL("TTY Toggle - Print Mission Debug Info", bDebug_PrintToTTY)
|
|
ADD_WIDGET_BOOL("TTY Toggle - Print Mary Ann Speed debug", bDebug_SpeedDebug)
|
|
ADD_WIDGET_FLOAT_READ_ONLY("Player sprint time remaining: ", fPlayerSprintRemaining)
|
|
|
|
STOP_WIDGET_GROUP()
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
REGISTER_SCRIPT_WITH_AUDIO()
|
|
|
|
IF IS_REPLAY_IN_PROGRESS()
|
|
OR IS_REPEAT_PLAY_ACTIVE()
|
|
|
|
CPRINTLN(DEBUG_MISSION, "Fanatic 1 *** Replay/repeat play IS in progress, doing INIT() now")
|
|
|
|
RC_SET_ENTITY_PROOFS_FOR_CUTSCENE(sRCLauncherDataLocal, FALSE)
|
|
IF IS_ENTITY_ALIVE(MARY_ANN)
|
|
SET_ENTITY_PROOFS(MARY_ANN, FALSE, FALSE, FALSE, FALSE, FALSE)
|
|
ENDIF
|
|
START_REPLAY_SETUP(<<-1878.2344, -439.6985, 45.0299>>, 241.0468)
|
|
INIT()
|
|
IF NOT IS_REPEAT_PLAY_ACTIVE() // Play the intro if we do a repeat play
|
|
SWITCH GET_REPLAY_MID_MISSION_STAGE()
|
|
CASE CP_AFTER_MOCAP
|
|
CPRINTLN(DEBUG_MISSION, "Fanatic 1 *** Replay/retry active, not a repeat play, skipping intro")
|
|
JUMP_TO_STAGE(DEBUG_TO_START)
|
|
BREAK
|
|
ENDSWITCH
|
|
ELSE
|
|
IF IS_REPLAY_IN_PROGRESS()
|
|
SWITCH GET_REPLAY_MID_MISSION_STAGE()
|
|
CASE CP_AFTER_MOCAP
|
|
CPRINTLN(DEBUG_MISSION, "Fanatic 1 *** Replay/retry active, is also a repeat play, skipping intro")
|
|
JUMP_TO_STAGE(DEBUG_TO_START)
|
|
BREAK
|
|
ENDSWITCH
|
|
ELSE
|
|
CPRINTLN(DEBUG_MISSION, "Fanatic 1 *** Replay/retry NOT active, but is repeat play, playing intro")
|
|
JUMP_TO_STAGE(DEBUG_TO_INTRO)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ELSE
|
|
CPRINTLN(DEBUG_MISSION, "Fanatic 1 *** Replay IS NOT in progress, proceeding normally")
|
|
ENDIF
|
|
|
|
// Loop within here until the mission passes or fails
|
|
WHILE(TRUE)
|
|
|
|
REPLAY_CHECK_FOR_EVENT_THIS_FRAME("SF_EDM")
|
|
|
|
WAIT(0)
|
|
|
|
UPDATE_MISSION_NAME_DISPLAYING(sRCLauncherDataLocal.sIntroCutscene, TRUE)
|
|
|
|
CHECK_FAIL_POSSIBILITIES()
|
|
DEAL_WITH_THE_RACE_TRACKING()
|
|
HANDLE_GLOBAL_STAMINA_HELP()
|
|
|
|
IF missionStage <> MS_LEADIN
|
|
AND missionStage <> MS_CUTSCENE
|
|
AND missionStage <> MS_FAIL_WAIT_FOR_FADE
|
|
AND missionStage <> MS_LOST_RACE
|
|
IF missionStage <> MS_END_CUTSCENE
|
|
CHECK_PLAYER_COLLISIONS()
|
|
ELSE
|
|
// Stop the heartbeat audio from playing during the end cutscene if you ride away
|
|
//STOP_SOUND(iHeartbeatAudioID)
|
|
ENDIF
|
|
DEAL_WITH_MARY_ANN()
|
|
TRY_OVERTAKE_LINE()
|
|
ELIF missionStage = MS_LEADIN
|
|
// Disable controls and exit current vehicle
|
|
RC_PLAYER_TRIGGER_SCENE_LOCK_IN()
|
|
ELIF missionStage = MS_CUTSCENE
|
|
IF IS_ENTITY_ALIVE(MARY_ANN)
|
|
SET_PED_MAX_MOVE_BLEND_RATIO(MARY_ANN, 2.3)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
SWITCH missionStage
|
|
CASE MS_LEADIN
|
|
LEADIN()
|
|
BREAK
|
|
CASE MS_CUTSCENE
|
|
INTRO_CUTSCENE()
|
|
BREAK
|
|
CASE MS_START_RUNNING
|
|
START_RUNNING()
|
|
BREAK
|
|
CASE MS_ROAD_RUNNING_SECTION
|
|
ROAD_RUNNING_SECTION()
|
|
BREAK
|
|
CASE MS_STEPS_DOWN
|
|
STEPS_DOWN()
|
|
BREAK
|
|
CASE MS_SPRINT_TO_FINISH
|
|
SPRINT_TO_FINISH()
|
|
BREAK
|
|
CASE MS_DEBUG_NEAR_FINISH_LINE
|
|
DEBUG_NEAR_FINISH_LINE()
|
|
BREAK
|
|
CASE MS_PLAYER_IN_VEHICLE
|
|
STAGE_PLAYER_IN_VEHICLE()
|
|
BREAK
|
|
CASE MS_END_CUTSCENE
|
|
END_CUTSCENE()
|
|
BREAK
|
|
CASE MS_LOST_RACE
|
|
LOST_RACE()
|
|
BREAK
|
|
CASE MS_FAIL_WAIT_FOR_FADE
|
|
FAIL_WAIT_FOR_FADE()
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
DEBUG_Check_Debug_Keys()
|
|
#ENDIF
|
|
|
|
ENDWHILE
|
|
|
|
// Script should never reach here. Always terminate with cleanup function.
|
|
ENDSCRIPT
|
|
|