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