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

1709 lines
59 KiB
Python
Executable File

// Includes
//USING "chase_hint_cam.sch" CHASE_HINT_CAM_STRUCT localChaseHintCamStruct
USING "Race_Control.sch"
USING "minigame_big_message.sch"
USING "rich_presence_public.sch"
USING "taxi_functions.sch"
#IF IS_DEBUG_BUILD
USING "debug_Races.sch"
#ENDIF
// *****************************************************************************************
// *****************************************************************************************
// *****************************************************************************************
//
// SCRIPT NAME : mission_Race.sc
// AUTHOR : David Roberts
// DESCRIPTION : Handles the Street and Sea Races
//
// *****************************************************************************************
// *****************************************************************************************
// *****************************************************************************************
INT iRaceFailTimeout = -1
TEXT_LABEL_23 emptyTextLabel = ""
INT iRaceID = -1
INT iMissionEndTimeout = -1
INT iMissionStartTime = 0
INT iBS = 0
//VECTOR vRewardDest
//SIMPLE_USE_CONTEXT sComplexUseContext
//SIMPLE_USE_CONTEXT sLeaderboardContext
INT iLoadLeaderboardTimer
// Fail screen variables
MG_FAIL_SPLASH sFailSplash
SCRIPT_SCALEFORM_BIG_MESSAGE sBigMessage
STRING sFailMessage
BOOL bShouldRetry
VEHICLE_INDEX viCityRaceCar
BOOL bCreateCar = TRUE
BOOL bSetupLeaderboard = TRUE
BOOL bDrawLeaderboard = FALSE
BOOL bWaitToShowProfile
BOOL bOnlineButtons
BOOL bPlayMedalSound = TRUE
BOOL bIntroSkipped = FALSE
BOOL bReadyToWalk = TRUE
BOOL bBlowKiss = TRUE
//SC_LEADERBOARD_CONTROL_STRUCT sclbControl
END_SCREEN_DATASET esdEndScreen
//STREAMVOL_ID streamVolume
OBJECT_INDEX oiDumpsterOne
VECTOR vDumpsterOnePos = <<-1107.184082,-1170.246582,1.159090>>
VECTOR vDumpsterOneRot = <<0.01, -0.01, -44.69>>
OBJECT_INDEX oiDumpsterTwo
VECTOR vDumpsterTwoPos = <<-1105.14, -1171.53, 1.16>>
VECTOR vDumpsterTwoRot = <<-0.13, -0.21, -65.97>>
OBJECT_INDEX oiDumpsterThree
VECTOR vDumpsterThreePos = <<-928.308228,-1070.007935,1.155174>>
VECTOR vDumpsterThreeRot = <<-0.06, 0.07, -42.91>>
OBJECT_INDEX oiDumpsterFour
VECTOR vDumpsterFourPos = <<-1104.51, -1173.58, 1.15>>
VECTOR vDumpsterFourRot = <<0.00, 0.00, -46.41>>
// ===========================================================================================================
// Cleanup
// ===========================================================================================================
/// PURPOSE:
/// Cleans up the script
/// PARAMS:
/// b_delete_racers - should the AI racers be deleted?
PROC SCRIPT_CLEANUP(BOOL b_delete_racers)//, BOOL b_delete_second_place = TRUE)
IF sRaceHUD.iPlayerPosition = 1 OR sRaceHUD.iPlayerPosition = 2 OR sRaceHUD.iPlayerPosition = 3
SWITCH sRaceData.eRaceTrack
// Sea Races
CASE SEA_RACE_01
REGISTER_SCRIPT_IN_COMPLETION_PERCENTAGE_TOTAL (CP_MG_SNCA)
BREAK
CASE SEA_RACE_02
REGISTER_SCRIPT_IN_COMPLETION_PERCENTAGE_TOTAL (CP_MG_SSC)
BREAK
CASE SEA_RACE_03
REGISTER_SCRIPT_IN_COMPLETION_PERCENTAGE_TOTAL (CP_MG_SCAN)
BREAK
CASE SEA_RACE_04
REGISTER_SCRIPT_IN_COMPLETION_PERCENTAGE_TOTAL (CP_MG_SLOS)
BREAK
// Street Races
CASE STREET_RACE_01
REGISTER_SCRIPT_IN_COMPLETION_PERCENTAGE_TOTAL (CP_MG_SRLS)
BREAK
CASE STREET_RACE_02
REGISTER_SCRIPT_IN_COMPLETION_PERCENTAGE_TOTAL (CP_MG_SRCC)
BREAK
CASE STREET_RACE_04
REGISTER_SCRIPT_IN_COMPLETION_PERCENTAGE_TOTAL (CP_MG_SRAP)
BREAK
CASE STREET_RACE_05
REGISTER_SCRIPT_IN_COMPLETION_PERCENTAGE_TOTAL (CP_MG_SRFW)
BREAK
CASE STREET_RACE_06
REGISTER_SCRIPT_IN_COMPLETION_PERCENTAGE_TOTAL (CP_MG_SRVC)
BREAK
ENDSWITCH
IF sRaceHUD.iPlayerPosition = 1 AND NOT g_savedGlobals.sStreetRaceData.bPhonecallDone
IF (IS_BIT_SET(g_savedGlobals.sStreetRaceData.iRaceWon, ENUM_TO_INT(STREET_RACE_LOS_SANTOS)) OR sRaceData.eRaceTrack = STREET_RACE_01)
AND (IS_BIT_SET(g_savedGlobals.sStreetRaceData.iRaceWon, ENUM_TO_INT(STREET_RACE_CITY_CIRCUIT)) OR sRaceData.eRaceTrack = STREET_RACE_02)
AND (IS_BIT_SET(g_savedGlobals.sStreetRaceData.iRaceWon, ENUM_TO_INT(STREET_RACE_AIRPORT)) OR sRaceData.eRaceTrack = STREET_RACE_04)
AND (IS_BIT_SET(g_savedGlobals.sStreetRaceData.iRaceWon, ENUM_TO_INT(STREET_RACE_FREEWAY)) OR sRaceData.eRaceTrack = STREET_RACE_05)
AND (IS_BIT_SET(g_savedGlobals.sStreetRaceData.iRaceWon, ENUM_TO_INT(STREET_RACE_VESPUCCI_CANALS)) OR sRaceData.eRaceTrack = STREET_RACE_06)
IF REGISTER_CALL_FROM_CHARACTER_TO_PLAYER(CALL_RACES_DONE, CT_AMBIENT, BIT_FRANKLIN, CHAR_HAO, 3, 10000, 10000)
g_savedGlobals.sStreetRaceData.bPhonecallDone = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
SET_STATIC_BLIP_CATEGORY_VISIBILITY(STATIC_BLIP_CATEGORY_SAVEHOUSE, TRUE)
SET_STATIC_BLIP_CATEGORY_VISIBILITY(STATIC_BLIP_CATEGORY_SHOP, TRUE)
// Release candidate ID
MISSION_OVER(sRaceData.iCandidateID)
MISSION_FLOW_CLEAR_DISPLAY_MISSION_TITLE()
SAFE_RELEASE_OBJECT(oiDumpsterOne)
SAFE_RELEASE_OBJECT(oiDumpsterTwo)
SAFE_RELEASE_OBJECT(oiDumpsterThree)
SAFE_RELEASE_OBJECT(oiDumpsterFour)
// Do common cleanup
RACE_CLEANUP(b_delete_racers)
SUPPRESS_LARGE_VEHICLES(FALSE)
SAFE_RELEASE_VEHICLE(viCityRaceCar)
CLEAR_RANK_REDICTION_DETAILS()
CLEANUP_SOCIAL_CLUB_LEADERBOARD(sclbControl)
IF sRaceData.eRaceType = RACETYPE_SEA
CLEAR_CUSTOM_RADIO_TRACK_LIST("RADIO_16_SILVERLAKE")
ENDIF
SET_AMBIENT_ZONE_STATE("AZ_DISTANT_VEHICLES_CITY_CENTRE", TRUE)
SET_AMBIENT_ZONE_STATE("AZ_COUNTRYSIDE_DISTANT_CARS_ZONE_01", TRUE)
SET_AMBIENT_ZONE_STATE("AZ_COUNTRYSIDE_DISTANT_CARS_ZONE_02", TRUE)
SET_AMBIENT_ZONE_STATE("AZ_COUNTRYSIDE_DISTANT_CARS_ZONE_03", TRUE)
// Cleanup race blip
SWITCH sRaceData.eRaceTrack
// Sea Races
CASE SEA_RACE_01
SET_STATIC_BLIP_ACTIVE_STATE(STATIC_BLIP_MINIGAME_SEA_RACE1, FALSE)
SET_BIT(g_savedGlobals.sSeaRaceData.iRaceLeaveArea, ENUM_TO_INT(SEA_RACE_EAST))
BREAK
CASE SEA_RACE_02
SET_STATIC_BLIP_ACTIVE_STATE(STATIC_BLIP_MINIGAME_SEA_RACE2, FALSE)
SET_BIT(g_savedGlobals.sSeaRaceData.iRaceLeaveArea, ENUM_TO_INT(SEA_RACE_NORTH))
BREAK
CASE SEA_RACE_03
SET_STATIC_BLIP_ACTIVE_STATE(STATIC_BLIP_MINIGAME_SEA_RACE3, FALSE)
SET_BIT(g_savedGlobals.sSeaRaceData.iRaceLeaveArea, ENUM_TO_INT(SEA_RACE_CANYON))
BREAK
CASE SEA_RACE_04
SET_STATIC_BLIP_ACTIVE_STATE(STATIC_BLIP_MINIGAME_SEA_RACE4, FALSE)
SET_BIT(g_savedGlobals.sSeaRaceData.iRaceLeaveArea, ENUM_TO_INT(SEA_RACE_CITY))
BREAK
// Street Races
CASE STREET_RACE_01
SET_STATIC_BLIP_ACTIVE_STATE(STATIC_BLIP_MINIGAME_STREET_RACE1, FALSE)
SET_BIT(g_savedGlobals.sStreetRaceData.iRaceLeaveArea, ENUM_TO_INT(STREET_RACE_LOS_SANTOS))
BREAK
CASE STREET_RACE_02
SET_STATIC_BLIP_ACTIVE_STATE(STATIC_BLIP_MINIGAME_STREET_RACE2, FALSE)
SET_BIT(g_savedGlobals.sStreetRaceData.iRaceLeaveArea, ENUM_TO_INT(STREET_RACE_CITY_CIRCUIT))
BREAK
CASE STREET_RACE_04
SET_STATIC_BLIP_ACTIVE_STATE(STATIC_BLIP_MINIGAME_STREET_RACE4, FALSE)
SET_BIT(g_savedGlobals.sStreetRaceData.iRaceLeaveArea, ENUM_TO_INT(STREET_RACE_AIRPORT))
BREAK
CASE STREET_RACE_05
SET_STATIC_BLIP_ACTIVE_STATE(STATIC_BLIP_MINIGAME_STREET_RACE5, FALSE)
SET_BIT(g_savedGlobals.sStreetRaceData.iRaceLeaveArea, ENUM_TO_INT(STREET_RACE_FREEWAY))
BREAK
CASE STREET_RACE_06
SET_STATIC_BLIP_ACTIVE_STATE(STATIC_BLIP_MINIGAME_STREET_RACE6, FALSE)
SET_BIT(g_savedGlobals.sStreetRaceData.iRaceLeaveArea, ENUM_TO_INT(STREET_RACE_VESPUCCI_CANALS))
BREAK
ENDSWITCH
CLEAR_ADDITIONAL_TEXT(MISSION_TEXT_SLOT, TRUE)
WAIT(1000)
ENABLE_CONTROL_ACTION(CAMERA_CONTROL, INPUT_VEH_CIN_CAM)
ENABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_CIN_CAM)
// Reseting this here, in case MG_UPDATE_FAIL_SPLASH_SCREEN failed to cleanup. (Very important this gets reset)
SET_NO_LOADING_SCREEN(FALSE)
SET_DEFAULT_RICH_PRESENCE_FOR_SP()
// End race script
TERMINATE_THIS_THREAD()
ENDPROC
// ===========================================================================================================
// Debug
// ===========================================================================================================
#IF IS_DEBUG_BUILD
/// PURPOSE: Check for Forced Pass or Fail
PROC DEBUG_Check_Debug_Keys()
IF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_S))
CLEAR_PRINTS()
SAFE_RACE_FADE_IN()
END_RACE_CUTSCENE()
CHECK_FOR_TRACK_UNLOCK()
SCRIPT_CLEANUP(FALSE)
ELIF(IS_KEYBOARD_KEY_JUST_PRESSED(KEY_F))
CLEAR_PRINTS()
SAFE_RACE_FADE_IN()
END_RACE_CUTSCENE()
SCRIPT_CLEANUP(FALSE)
ENDIF
ENDPROC
#ENDIF
/// PURPOSE:
/// Creates a car in a City Race (Street Race 2) driveway
/// This is needed to stop AI racers crashing into a driveway...
PROC CREATE_CITY_RACE_CAR()
IF bCreateCar AND sRaceData.eRaceTrack = STREET_RACE_02
INT iCurrentWaypoint
WAYPOINT_RECORDING_GET_CLOSEST_WAYPOINT(sRaceWaypointRecording, GET_ENTITY_COORDS(PLAYER_PED_ID()), iCurrentWaypoint)
IF iCurrentWaypoint > 50 AND iCurrentWaypoint < 70
IF NOT DOES_ENTITY_EXIST(viCityRaceCar)
REQUEST_MODEL(BALLER)
IF HAS_MODEL_LOADED(BALLER)
viCityRaceCar = CREATE_VEHICLE(Baller, <<-1080.727661,454.448883,76.541245>>, -32.274254)
ENDIF
ENDIF
ELIF iCurrentWaypoint > 90
IF DOES_ENTITY_EXIST(viCityRaceCar)
SET_MODEL_AS_NO_LONGER_NEEDED(baller)
SAFE_RELEASE_VEHICLE(viCityRaceCar)
bCreateCar = FALSE
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Creates some dumpsters near the canals in city race six
/// This is needed to stop AI racers driving into the canal...
PROC CREATE_CANAL_DUMPSTERS()
IF sRaceData.eRaceTrack = STREET_RACE_06
IF HAS_MODEL_LOADED(prop_dumpster_02a)
IF NOT DOES_ENTITY_EXIST(oiDumpsterOne)
oiDumpsterOne = CREATE_OBJECT( prop_dumpster_02a ,vDumpsterOnePos)
SET_ENTITY_ROTATION (oiDumpsterOne, vDumpsterOneRot)
FREEZE_ENTITY_POSITION(oiDumpsterOne, TRUE)
ENDIF
IF NOT DOES_ENTITY_EXIST(oiDumpsterTwo)
oiDumpsterTwo = CREATE_OBJECT( prop_dumpster_02a ,vDumpsterTwoPos)
SET_ENTITY_ROTATION (oiDumpsterTwo, vDumpsterTwoRot)
FREEZE_ENTITY_POSITION(oiDumpsterTwo, TRUE)
ENDIF
IF NOT DOES_ENTITY_EXIST(oiDumpsterThree)
oiDumpsterThree = CREATE_OBJECT( prop_dumpster_02a ,vDumpsterThreePos)
SET_ENTITY_ROTATION (oiDumpsterThree, vDumpsterThreeRot)
FREEZE_ENTITY_POSITION(oiDumpsterThree, TRUE)
ENDIF
IF NOT DOES_ENTITY_EXIST(oiDumpsterFour)
oiDumpsterFour = CREATE_OBJECT( prop_dumpster_02a ,vDumpsterFourPos)
SET_ENTITY_ROTATION (oiDumpsterFour, vDumpsterFourRot)
FREEZE_ENTITY_POSITION(oiDumpsterFour, TRUE)
ENDIF
ENDIF
ENDIF
ENDPROC
// ===========================================================================================================
// Race States
// ===========================================================================================================
/// PURPOSE: Faded start
/*PROC RACE_SETUP()
UPDATE_MISSION_NAME_DISPLAYING(emptyTextLabel, FALSE, FALSE, FALSE, FALSE, iRaceID)
SWITCH eRaceSubState
CASE RACE_SUBSTATE_SETUP
// Fade out screen and setup systems for cutscene
CPRINTLN(DEBUG_MISSION, "Mission Race: RACE_SETUP")
SAFE_RACE_FADE_OUT()
START_RACE_CUTSCENE()
eRaceSubState = RACE_SUBSTATE_RUNNING
BREAK
CASE RACE_SUBSTATE_RUNNING
// Setup vehicles
SETUP_PLAYER_COUNTDOWN()
SETUP_AI_RACERS()
IF sRaceData.eRaceType = RACETYPE_CAR OR sRaceData.eRaceType = RACETYPE_BIKE
VECTOR behind_pos
behind_pos = GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(sTrackData.vStartGrid[sTrackData.iNumAIRacers], sTrackData.fStartGrid[sTrackData.iNumAIRacers], <<0.0, -15.0, 0.0>>)
SET_ENTITY_COORDS(sPlayerVehicle.vehPlayerVehicle, behind_pos)
SET_ENTITY_HEADING(sPlayerVehicle.vehPlayerVehicle, sTrackData.fStartGrid[sTrackData.iNumAIRacers])
SET_VEHICLE_ON_GROUND_PROPERLY(sPlayerVehicle.vehPlayerVehicle)
BRING_VEHICLE_TO_HALT(sPlayerVehicle.vehPlayerVehicle, 0, 2)
ENDIF
// Race information has been collected from the cloud
eRaceSubState = RACE_SUBSTATE_CLEANUP
BREAK
CASE RACE_SUBSTATE_CLEANUP
// Head over to the grid lineup
eRaceState = RACE_STATE_LINEUP
eRaceSubState = RACE_SUBSTATE_SETUP
BREAK
ENDSWITCH
ENDPROC*/
/// PURPOSE:
/// Restarts the race
PROC RESTART_RACE(BOOL bFromPass = TRUE)
IF bFromPass
HIDE_HUD_AND_RADAR_THIS_FRAME()
SAFE_FADE_SCREEN_OUT_TO_BLACK(500, FALSE)
ELSE
SAFE_FADE_SCREEN_OUT_TO_BLACK()
ENDIF
// B*2259879 - Clear Vehicles
IF sRaceData.eRaceType = RACETYPE_BIKE
CPRINTLN(DEBUG_MISSION, "Street Race: CLEANING UP VEHICLES FOR B*2259879")
CLEAR_AREA_OF_VEHICLES(GET_ENTITY_COORDS(PLAYER_PED_ID()), 50.0)
SAFE_DELETE_VEHICLE(sPlayerVehicle.vehPlayerVehicle)
SAFE_REMOVE_BLIP(sPlayerVehicle.biPlayerVehicle)
ENDIF
VEHICLE_INDEX viTemp
IF sRaceData.eRaceType = RACETYPE_CAR
IF NOT IS_PLAYER_IN_SUITABLE_RACE_CAR()
CREATE_VEHICLE_FOR_REPLAY(viTemp, GET_ENTITY_COORDS(PLAYER_PED_ID()), 0, TRUE, TRUE, FALSE, FALSE, TRUE, BUFFALO)
sPlayerVehicle.vehPlayerVehicle = viTemp
ENDIF
ELIF sRaceData.eRaceType = RACETYPE_BIKE
IF NOT IS_PLAYER_ON_SUITABLE_BIKE()
CREATE_VEHICLE_FOR_REPLAY(viTemp, GET_ENTITY_COORDS(PLAYER_PED_ID()), 0, TRUE, TRUE, FALSE, FALSE, TRUE, BATI)
sPlayerVehicle.vehPlayerVehicle = viTemp
ENDIF
ELIF sRaceData.eRaceType = RACETYPE_SEA
IF NOT IS_PLAYER_IN_SUITABLE_SEA_VEHICLE()
CREATE_VEHICLE_FOR_REPLAY(viTemp, GET_ENTITY_COORDS(PLAYER_PED_ID()), 0, TRUE, TRUE, FALSE, FALSE, TRUE, SEASHARK)
sPlayerVehicle.vehPlayerVehicle = viTemp
ENDIF
ENDIF
CLEAR_AREA_OF_PROJECTILES(GET_ENTITY_COORDS(PLAYER_PED_ID()), 100.0)
STOP_FIRE_IN_RANGE(GET_ENTITY_COORDS(PLAYER_PED_ID()), 100.0)
SET_PLAYER_WANTED_LEVEL(PLAYER_ID(), 0)
SET_PLAYER_WANTED_LEVEL_NOW(PLAYER_ID())
sRaceHUD.iCurrentCheckPoint = 0
CLEANUP_CHECKPOINTS()
CLEANUP_RACERS(TRUE)
SAFE_DELETE_PED(piRewardPed)
RACE_INIT()
SET_ENTITY_COORDS(PLAYER_PED_ID(), sTrackData.vStartGrid[sTrackData.iNumAIRacers])
NEW_LOAD_SCENE_START_SPHERE(sTrackData.vStartGrid[sTrackData.iNumAIRacers], 500)
BOOL bWaiting = TRUE
INT iLoadFailTime = GET_GAME_TIMER() + 30000
WHILE bWaiting
IF IS_NEW_LOAD_SCENE_LOADED()
bWaiting = FALSE
ENDIF
IF GET_GAME_TIMER() > iLoadFailTime
bWaiting = FALSE
ENDIF
WAIT(0)
ENDWHILE
SETUP_PLAYER_PRECUTSCENE()
SETUP_AI_RACERS()
WAIT(1000) // Waiting for a while after creating the racers so their wheels have time to load in and seasharks are positioned correctly on the water
SETUP_PLAYER_COUNTDOWN()
START_RACE_CUTSCENE()
RENDER_SCRIPT_CAMS(FALSE, FALSE)
WAIT(0)
CLEAR_AREA_OF_VEHICLES(GET_ENTITY_COORDS(PLAYER_PED_ID()), 500.0)
SET_GAMEPLAY_CAM_RELATIVE_PITCH()
SET_GAMEPLAY_CAM_RELATIVE_HEADING()
sRaceHUD.uiCountdown.iBitFlags = 0
INT i_index
FOR i_index = 0 TO sTrackData.iNumAIRacers-1
IF IS_PED_UNINJURED(sRacer[i_index].piDriver)
CLEAR_PED_TASKS(sRacer[i_index].piDriver)
ENDIF
IF IS_VEHICLE_OK(sRacer[i_index].viCar)
BRING_VEHICLE_TO_HALT(sRacer[i_index].viCar, 0.1, 1)
SET_ENTITY_COORDS_GROUNDED(sRacer[i_index].viCar, sTrackData.vStartGrid[i_index])
SET_ENTITY_HEADING(sRacer[i_index].viCar, sTrackData.fStartGrid[i_index])
ENDIF
ENDFOR
WAIT(500) // Waiting a while after this so vehicles are positioned properly
IF sRaceData.eRaceTrack = STREET_RACE_02
WAIT(1000) // Wait an extra second for street race 2 as the player can be a long distance away
ENDIF
SAFE_FADE_SCREEN_IN_FROM_BLACK()
START_AUDIO_SCENE("RACE_INTRO_GENERIC")
RESTART_TIMER_NOW(sRaceHUD.uiCountdown.CountdownTimer)
ENABLE_CONTROL_ACTION(CAMERA_CONTROL, INPUT_VEH_CIN_CAM)
ENABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_CIN_CAM)
eRaceState = RACE_STATE_COUNTDOWN
eRaceSubState = RACE_SUBSTATE_SETUP
ENDPROC
#IF IS_DEBUG_BUILD
/// PURPOSE:
/// Debug skip back to the lineup state
PROC P_SKIP_TO_LINEUP()
IF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_P))
CLEANUP_RACERS(TRUE)
SAFE_DELETE_PED(piGridGirlOne)
SAFE_DELETE_PED(piGridGirlTwo)
SAFE_DELETE_PED(piGridGirlThree)
RENDER_SCRIPT_CAMS(FALSE, FALSE)
INT i_index = 0
REPEAT COUNT_OF(gridCamera) i_index
IF DOES_CAM_EXIST(gridCamera[i_index])
DESTROY_CAM(gridCamera[i_index])
ENDIF
ENDREPEAT
WAIT(0)
SET_GAMEPLAY_CAM_RELATIVE_PITCH()
SET_GAMEPLAY_CAM_RELATIVE_HEADING()
eRaceState = RACE_STATE_LINEUP
eRaceSubState = RACE_SUBSTATE_SETUP
ENDIF
ENDPROC
#ENDIF
/// PURPOSE: Shows racers on the starting grid
PROC RACE_LINEUP()
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.0)
UPDATE_MISSION_NAME_DISPLAYING(emptyTextLabel, FALSE, FALSE, FALSE, FALSE, iRaceID)
CREATE_CANAL_DUMPSTERS()
GET_RACE_BEST_TIMES(sRaceData.eRaceTrack)
INT i_index = 0
SWITCH eRaceSubState
CASE RACE_SUBSTATE_SETUP
SET_STATIC_BLIP_CATEGORY_VISIBILITY(STATIC_BLIP_CATEGORY_SAVEHOUSE, FALSE)
SET_STATIC_BLIP_CATEGORY_VISIBILITY(STATIC_BLIP_CATEGORY_SHOP, FALSE)
IF IS_PLAYER_ONLINE()
SC_LEADERBOARD_CACHE_CLEAR_ALL()
ENDIF
PLAY_INTRO_SOUND(FALSE)
//IF sRaceData.eRaceType = RACETYPE_CAR OR sRaceData.eRaceType = RACETYPE_BIKE
// SETUP_PLAYER_COUNTDOWN()
/*VECTOR behind_pos
behind_pos = GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(sTrackData.vStartGrid[sTrackData.iNumAIRacers], sTrackData.fStartGrid[sTrackData.iNumAIRacers], <<0.0, -15.0, 0.0>>)
SET_ENTITY_COORDS_GROUNDED(sPlayerVehicle.vehPlayerVehicle, behind_pos)
SET_ENTITY_HEADING(sPlayerVehicle.vehPlayerVehicle, sTrackData.fStartGrid[sTrackData.iNumAIRacers])
//SET_VEHICLE_ON_GROUND_PROPERLY(sPlayerVehicle.vehPlayerVehicle)
BRING_VEHICLE_TO_HALT(sPlayerVehicle.vehPlayerVehicle, 0, 2)*/
//ENDIF
/*IF sRaceData.eRaceType = RACETYPE_BIKE
IF IS_PED_UNINJURED(PLAYER_PED_ID())
GIVE_PED_HELMET(PLAYER_PED_ID())
ENDIF
ENDIF*/
SETUP_PLAYER_PRECUTSCENE()
//WAIT(0)
START_AUDIO_SCENE("RACE_INTRO_GENERIC")
SET_AMBIENT_ZONE_STATE("AZ_DISTANT_VEHICLES_CITY_CENTRE", FALSE)
SET_AMBIENT_ZONE_STATE("AZ_COUNTRYSIDE_DISTANT_CARS_ZONE_01", FALSE)
SET_AMBIENT_ZONE_STATE("AZ_COUNTRYSIDE_DISTANT_CARS_ZONE_02", FALSE)
SET_AMBIENT_ZONE_STATE("AZ_COUNTRYSIDE_DISTANT_CARS_ZONE_03", FALSE)
REQUEST_ADDITIONAL_TEXT("HAO1", MISSION_TEXT_SLOT)
// Start cutscene
START_RACE_CUTSCENE()
SET_CELLPHONE_PROFILE_TO_NORMAL()
// Fade out screen and setup systems for cutscene
CPRINTLN(DEBUG_MISSION, "Street Race: RACE_SETUP")
// Removed for B* 1453786 at advice of systems code
//streamVolume = STREAMVOL_CREATE_FRUSTUM(vStartPos, vStartRot, 100, FLAG_MAPDATA)
CREATE_RACE_CAMERAS()
//ANIMPOSTFX_STOP("SwitchSceneNeutral")
ANIMPOSTFX_PLAY("SwitchSceneFranklin", 0, FALSE)
// Setup vehicles
SETUP_AI_RACERS()
// Setup the grid girls
SETUP_GRID_GIRLS()
bPlayedIntroSound = FALSE
bIntroSkipped = FALSE
IF IS_VEHICLE_OK(sPlayerVehicle.vehPlayerVehicle)
IF sRaceData.eRaceType = RACETYPE_SEA
//PREPARE_MUSIC_EVENT("MGSR_START")
//SET_VEH_RADIO_STATION(sPlayerVehicle.vehPlayerVehicle, "RADIO_16_SILVERLAKE")
SET_RADIO_TO_STATION_NAME("RADIO_16_SILVERLAKE")
FREEZE_RADIO_STATION("RADIO_16_SILVERLAKE")
CPRINTLN(DEBUG_MISSION, "About to set custom radio track list")
SET_CUSTOM_RADIO_TRACK_LIST("RADIO_16_SILVERLAKE", "SEA_RACE_RADIO_PLAYLIST", TRUE)
CPRINTLN(DEBUG_MISSION, "About to unfreeze radio station")
UNFREEZE_RADIO_STATION("RADIO_16_SILVERLAKE")
CPRINTLN(DEBUG_MISSION, "About to enable vehicle radio")
SET_VEHICLE_RADIO_ENABLED(sPlayerVehicle.vehPlayerVehicle, TRUE)
ELSE
//SET_VEH_RADIO_STATION(sPlayerVehicle.vehPlayerVehicle, "RADIO_07_DANCE_01")
SET_RADIO_TO_STATION_NAME("RADIO_07_DANCE_01")
ENDIF
SET_FRONTEND_RADIO_ACTIVE(true)
ENDIF
/*WAIT(0)
IF IS_PED_UNINJURED(PLAYER_PED_ID()) AND IS_VEHICLE_OK(sPlayerVehicle.vehPlayerVehicle)
VECTOR targetPos
FLOAT fSpeed
targetPos = GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(sTrackData.vStartGrid[sTrackData.iNumAIRacers], sTrackData.fStartGrid[sTrackData.iNumAIRacers], <<0.0, 2.3, 0.0>>)
fSpeed = 3.0
SET_VEHICLE_FORWARD_SPEED(sPlayerVehicle.vehPlayerVehicle, fSpeed)
TASK_VEHICLE_DRIVE_TO_COORD(PLAYER_PED_ID(), sPlayerVehicle.vehPlayerVehicle, targetPos, fSpeed, DRIVINGSTYLE_NORMAL, GET_ENTITY_MODEL(sPlayerVehicle.vehPlayerVehicle), DF_ForceStraightLine|DRIVINGMODE_PLOUGHTHROUGH, 0.5, 15.0)
ENDIF*/
eRaceSubState = RACE_SUBSTATE_RUNNING
BREAK
CASE RACE_SUBSTATE_RUNNING
// Camera running?
IF CONTROL_RACE_CAMERAS()
SET_GRID_GIRLS_FOR_COUNTDOWN(0.32)
IF IS_PED_UNINJURED(PLAYER_PED_ID())
CLEAR_PED_TASKS(PLAYER_PED_ID())
ENDIF
// Got to race countdown
eRaceState = RACE_STATE_COUNTDOWN
eRaceSubState = RACE_SUBSTATE_SETUP
ENDIF
IF IS_CUTSCENE_SKIP_BUTTON_JUST_PRESSED_WITH_DELAY()
SAFE_FADE_SCREEN_OUT_TO_BLACK()
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
bIntroSkipped = TRUE
SAFE_DELETE_PED(piGridGirlTwo)
SAFE_DELETE_PED(piGridGirlThree)
//WAIT(1000)
eRaceSubState = RACE_SUBSTATE_CLEANUP
ENDIF
IF sRaceData.eRaceTrack = STREET_RACE_06
IF IS_PED_UNINJURED(PLAYER_PED_ID())
SET_PED_RESET_FLAG(PLAYER_PED_ID(), PRF_PreventGoingIntoStillInVehicleState, TRUE)
ENDIF
FOR i_index = 0 TO sTrackData.iNumAIRacers-1
IF IS_PED_UNINJURED(sRacer[i_index].piDriver)
SET_PED_RESET_FLAG(sRacer[i_index].piDriver, PRF_PreventGoingIntoStillInVehicleState, TRUE)
ENDIF
ENDFOR
ENDIF
BREAK
CASE RACE_SUBSTATE_CLEANUP
IF sRaceData.eRaceType = RACETYPE_SEA
SETUP_PLAYER_COUNTDOWN()
ENDIF
SET_GRID_GIRLS_FOR_COUNTDOWN(0.27)
// Removed for B* 1453786 at advice of systems code
//STREAMVOL_DELETE(streamVolume)
UPDATE_RACE_CHECKPOINTS(FALSE)
// Set camera behind player
IF sRaceData.eRaceType = RACETYPE_SEA
RENDER_SCRIPT_CAMS(FALSE, FALSE)
WAIT(0)
SET_GAMEPLAY_CAM_RELATIVE_PITCH()
SET_GAMEPLAY_CAM_RELATIVE_HEADING()
ELSE
IF bIntroSkipped
SETUP_PLAYER_COUNTDOWN()
FOR i_index = 0 TO sTrackData.iNumAIRacers-1
IF IS_PED_UNINJURED(sRacer[i_index].piDriver)
CLEAR_PED_TASKS(sRacer[i_index].piDriver)
ENDIF
IF IS_VEHICLE_OK(sRacer[i_index].viCar)
BRING_VEHICLE_TO_HALT(sRacer[i_index].viCar, 0.1, 1)
SET_ENTITY_COORDS_GROUNDED(sRacer[i_index].viCar, sTrackData.vStartGrid[i_index])
SET_ENTITY_HEADING(sRacer[i_index].viCar, sTrackData.fStartGrid[i_index])
ENDIF
ENDFOR
RENDER_SCRIPT_CAMS(FALSE, FALSE)
WAIT(500)
SET_GAMEPLAY_CAM_RELATIVE_PITCH()
SET_GAMEPLAY_CAM_RELATIVE_HEADING()
ELSE
//RENDER_SCRIPT_CAMS(FALSE, FALSE)
STOP_RENDERING_SCRIPT_CAMS_USING_CATCH_UP()
ENDIF
ENDIF
SAFE_FADE_SCREEN_IN_FROM_BLACK()
UPDATE_RACE_CHECKPOINTS(FALSE)
// Cleanup cameras
i_index = 0
REPEAT COUNT_OF(gridCamera) i_index
IF DOES_CAM_EXIST(gridCamera[i_index])
DESTROY_CAM(gridCamera[i_index])
ENDIF
ENDREPEAT
//SET_GAMEPLAY_CAM_RELATIVE_PITCH()
//SET_GAMEPLAY_CAM_RELATIVE_HEADING()
// Got to race countdown
eRaceState = RACE_STATE_COUNTDOWN
eRaceSubState = RACE_SUBSTATE_SETUP
BREAK
ENDSWITCH
#IF IS_DEBUG_BUILD
P_SKIP_TO_LINEUP()
#ENDIF
ENDPROC
/// PURPOSE: Countdown UI
PROC RACE_COUNTDOWN()
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.0)
CREATE_CANAL_DUMPSTERS()
DISABLE_SELECTOR_THIS_FRAME()
CONTROL_RACE_CAMERAS()
GET_RACE_BEST_TIMES(sRaceData.eRaceTrack)
SWITCH eRaceSubState
CASE RACE_SUBSTATE_SETUP
SAFE_FADE_SCREEN_IN_FROM_BLACK()
REQUEST_MINIGAME_COUNTDOWN_UI(sRaceHUD.uiCountdown)
REQUEST_SCRIPT_AUDIO_BANK("HUD_321_GO", TRUE)
bRacersReleased = FALSE
iBoostTimer = -1
eBoostState = BS_READY
CLEAR_BITMASK_AS_ENUM(sRaceHUD.uiCountdown.iBitFlags, CNTDWN_UI_Played_Go)
CLEAR_BITMASK_AS_ENUM(sRaceHUD.uiCountdown.iBitFlags, CNTDWN_UI_Played_1)
CLEAR_BITMASK_AS_ENUM(sRaceHUD.uiCountdown.iBitFlags, CNTDWN_UI_Played_2)
CLEAR_BITMASK_AS_ENUM(sRaceHUD.uiCountdown.iBitFlags, CNTDWN_UI_Played_3)
CANCEL_TIMER(sRaceHUD.uiCountdown.CountdownTimer)
// Request textures for the end of the race here
REQUEST_STREAMED_TEXTURE_DICT("MPHUD")
REQUEST_STREAMED_TEXTURE_DICT("SPROffroad")
REQUEST_STREAMED_TEXTURE_DICT("SHARED")
REQUEST_ADDITIONAL_TEXT("SP_SPR", MINIGAME_TEXT_SLOT)
uiLeaderboard[0] = REQUEST_SC_LEADERBOARD_UI()
sBigMessage.siMovie = REQUEST_MG_BIG_MESSAGE()
MG_INIT_FAIL_SPLASH_SCREEN(sFailSplash)
IF IS_VEHICLE_OK(sPlayerVehicle.vehPlayerVehicle) AND sRaceData.eRaceType <> RACETYPE_SEA
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
SET_VEHICLE_HANDBRAKE(sPlayerVehicle.vehPlayerVehicle, TRUE)
ENDIF
eRaceSubState = RACE_SUBSTATE_RUNNING
BREAK
CASE RACE_SUBSTATE_RUNNING
REQUEST_SCRIPT_AUDIO_BANK("HUD_321_GO", TRUE)
IF HAS_MINIGAME_COUNTDOWN_UI_LOADED(sRaceHUD.uiCountdown)
IF UPDATE_MINIGAME_COUNTDOWN_UI(sRaceHUD.uiCountdown, TRUE, FALSE, FALSE, 3, TRUE)
eRaceSubState = RACE_SUBSTATE_CLEANUP
ENDIF
// See B*929855 - allow racers to move as soon as "GO" appears
IF IS_BITMASK_AS_ENUM_SET(sRaceHUD.uiCountdown.iBitFlags, CNTDWN_UI_Played_Go)
IF iBoostTimer < 0
iBoostTimer = GET_GAME_TIMER() + BOOST_START_WINDOW
ENDIF
IF bRacersReleased = FALSE
bRacersReleased = TRUE
INIT_RACE_HUD()
STOP_AUDIO_SCENE("RACE_INTRO_GENERIC")
START_RACE_MIXER()
IF IS_PLAYER_PLAYING(PLAYER_ID())
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
ENDIF
IF IS_VEHICLE_OK(sPlayerVehicle.vehPlayerVehicle)
IF sRaceData.eRaceType = RACETYPE_SEA
INT i_index
FOR i_index = 0 TO sTrackData.iNumAIRacers - 1
IF IS_VEHICLE_OK(sRacer[i_index].viCar)
SET_BOAT_ANCHOR(sRacer[i_index].viCar, FALSE)
ENDIF
ENDFOR
SET_BOAT_ANCHOR(sPlayerVehicle.vehPlayerVehicle, FALSE)
ELSE
SET_VEHICLE_HANDBRAKE(sPlayerVehicle.vehPlayerVehicle, FALSE)
ENDIF
ENDIF
//SET_FRONTEND_RADIO_ACTIVE(true)
CPRINTLN(DEBUG_MISSION, "Street Race: Starting race at game time ", GET_GAME_TIMER())
ENDIF
UPDATE_RACE_AI()
ENDIF
ENDIF
BREAK
CASE RACE_SUBSTATE_CLEANUP
CLEANUP_GRID_GIRLS()
// Release countdown timer
RELEASE_MINIGAME_COUNTDOWN_UI(sRaceHUD.uiCountdown)
// Enable controls and go to race!
END_RACE_CUTSCENE()
INT i_index
i_index = 0
REPEAT COUNT_OF(gridCamera) i_index
IF DOES_CAM_EXIST(gridCamera[i_index])
DESTROY_CAM(gridCamera[i_index])
ENDIF
ENDREPEAT
// Update states
eRaceState = RACE_STATE_ACTIVE
eRaceSubState = RACE_SUBSTATE_SETUP
BREAK
ENDSWITCH
UPDATE_RACE_CHECKPOINTS(FALSE)
HANDLE_START_BOOST()
CHECK_PLAYER_SHOOTING_IN_COUNTDOWN()
#IF IS_DEBUG_BUILD
P_SKIP_TO_LINEUP()
#ENDIF
ENDPROC
FUNC BOOL RIVALS_FINISHED()
IF iRaceFailTimeout < 0
INT i_index
FOR i_index = 0 TO sTrackData.iNumAIRacers-1
IF sRacer[i_index].iCurrentLap > sTrackData.iNumLaps
iRaceFailTimeout = GET_GAME_TIMER() + 120000
ENDIF
ENDFOR
ENDIF
IF iRaceFailTimeout > 0
IF GET_GAME_TIMER() > iRaceFailTimeout
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE: Handles the main race
PROC RACE_ACTIVE()
HIDE_STREET_AND_CAR_NAMES_THIS_FRAME()
DISABLE_SELECTOR_THIS_FRAME()
GET_RACE_BEST_TIMES(sRaceData.eRaceTrack)
IF sRaceData.eRaceTrack = STREET_RACE_02
IF (sRaceHUD.iCurrentCheckPoint > 7 AND sRaceHUD.iCurrentCheckPoint < 17) OR (sRaceHUD.iCurrentLap = 1 AND sRaceHUD.iCurrentCheckPoint < 2)
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.0)
ELIF sRaceHUD.iCurrentCheckPoint < 8
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.4)
ELSE
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.1)
ENDIF
ELSE
IF sRaceHUD.iCurrentLap = 1 AND sRaceHUD.iCurrentCheckPoint < 3
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.0)
ELSE
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.1)
ENDIF
ENDIF
SWITCH eRaceSubState
CASE RACE_SUBSTATE_SETUP
CPRINTLN(DEBUG_MISSION, "Mission Race: RACE_UPDATE")
IF sRaceData.eRaceType = RACETYPE_SEA
STOP_SOUND(iIntroSound)
RELEASE_SCRIPT_AUDIO_BANK()
/*ELSE
STOP_STREAM()*/
ENDIF
// Used for respawning the player's car if it become stuck
racesRespawnState = RACES_RESPAWN_SET
iPlayerWantsToRecoverVehicleTimer = -1
// Set the start time for the oddjob
iMissionStartTime = GET_GAME_TIMER()
iRaceFailTimeout = -1
INIT_STOPPED_SOUND()
bCreateCar = TRUE
UPDATE_RACE_CHECKPOINTS()
iPreviousPosition = sRaceHUD.iPlayerPosition
iPositionConvTimer = GET_GAME_TIMER() + POSITION_CONV_TIME
IF sRaceData.eRaceType <> RACETYPE_SEA AND g_savedGlobals.sStreetRaceData.iSlipstreamHelpCount < 3
//ADD_HELP_TO_FLOW_QUEUE("FM_IHELP_SLP", FHP_HIGH) // You can slipstream by driving close behind another racer. This will give you a speed boost.
PRINT_HELP("FM_IHELP_SLP") // You can slipstream by driving close behind another racer. This will give you a speed boost.
g_savedGlobals.sStreetRaceData.iSlipstreamHelpCount++
ENDIF
eRaceSubState = RACE_SUBSTATE_RUNNING
BREAK
CASE RACE_SUBSTATE_RUNNING
UPDATE_RACE_AI()
UPDATE_PLAYER_POS()
//CAM_HINT_FOR_NEXT_CAR()
UPDATE_RACE_HUD()
CHECK_RACE_CONVS()
CREATE_CITY_RACE_CAR()
IF iReplayRecordWarpTimer > GET_GAME_TIMER()
REPLAY_DISABLE_CAMERA_MOVEMENT_THIS_FRAME() //Fix for bug 2226208
ENDIF
IF RIVALS_FINISHED()
CPRINTLN(DEBUG_MISSION, "Mission Race: Rivals finished a while back so abandoning race")
failReason = FAIL_ABANDONED_RACE
eRaceState = RACE_STATE_FAIL
eRaceSubState = RACE_SUBSTATE_SETUP
ENDIF
IF IS_PLAYER_IN_VEHICLE()
AND UPDATE_RACE_CHECKPOINTS()
IF sRaceData.eRaceType = RACETYPE_SEA
//TRIGGER_MUSIC_EVENT("MGSR_STOP")
CLEAR_CUSTOM_RADIO_TRACK_LIST("RADIO_16_SILVERLAKE")
STOP_AUDIO_SCENE("SEA_RACE_DURING_RACE")
START_AUDIO_SCENE("SEA_RACES_OUTRO")
ELSE
STOP_AUDIO_SCENE("STREET_RACE_DURING_RACE")
START_AUDIO_SCENE("STREET_RACE_OUTRO")
ENDIF
// create the white version of the finish blip for race over
INT iR, iG, iB, iA
VECTOR currentCheckpoint
currentCheckpoint = sTrackData.vCheckPoint[sTrackData.iNumCheckpoints - 1]
GET_HUD_COLOUR(HUD_COLOUR_WHITE, iR, iG, iB, iA)
IF ciPreviousCheckPoint != NULL
DELETE_CHECKPOINT(ciPreviousCheckPoint)
ENDIF
ciPreviousCheckPoint = CREATE_CHECKPOINT(CHECKPOINT_RACE_GROUND_FLAG,(currentCheckpoint+<<0,0,fCheckpointDrawSize>>), sTrackData.vCheckPoint[0], (CHECKPOINT_VISUAL_SIZE * CHECKPOINT_VISUAL_SIZE_MODIFIER), iR, iG, iB, 180)
eRaceSubState = RACE_SUBSTATE_CLEANUP
ENDIF
BREAK
CASE RACE_SUBSTATE_CLEANUP
PLAYER_INDEX piPlayer
piPlayer = GET_PLAYER_INDEX()
IF IS_PLAYER_PLAYING(piPlayer)
IF IS_SPECIAL_ABILITY_ACTIVE(piPlayer)
SPECIAL_ABILITY_DEACTIVATE(piPlayer)
ENDIF
ENDIF
IF IS_PHONE_ONSCREEN()
HANG_UP_AND_PUT_AWAY_PHONE()
ENDIF
CLEANUP_RACER_BLIPS()
eRaceState = RACE_STATE_END
eRaceSubState = RACE_SUBSTATE_SETUP
BREAK
ENDSWITCH
HANDLE_START_BOOST()
#IF IS_DEBUG_BUILD
P_SKIP_TO_LINEUP()
#ENDIF
ENDPROC
PROC GIVE_PLAYER_WINNINGS()
// Give the player their winnings, sea races don't have fees or prizes
IF sRaceData.eRaceType <> RACETYPE_SEA
FLOAT fRaceFee
fRaceFee = TO_FLOAT(sRaceData.iRaceFee)
IF sRaceHUD.iPlayerPosition = 1
fRaceFee*=4.5
CREDIT_BANK_ACCOUNT(CHAR_FRANKLIN, BAAC_UNLOGGED_SMALL_ACTION, ROUND(fRaceFee))
ELIF sRaceHUD.iPlayerPosition = 2
CREDIT_BANK_ACCOUNT(CHAR_FRANKLIN, BAAC_UNLOGGED_SMALL_ACTION, ROUND(fRaceFee))
ELIF sRaceHUD.iPlayerPosition = 3
fRaceFee*=0.5
CREDIT_BANK_ACCOUNT(CHAR_FRANKLIN, BAAC_UNLOGGED_SMALL_ACTION, ROUND(fRaceFee))
ENDIF
ENDIF
ENDPROC
FUNC BOOL RANK_PREDICT_DONE()
IF IS_PLAYER_ONLINE() AND NETWORK_HAVE_ONLINE_PRIVILEGES() AND sclbControl.ReadDataStruct.m_LeaderboardId > 0
IF scLB_rank_predict.bFinishedRead
AND NOT scLB_rank_predict.bFinishedWrite
INIT_RACE_LEADERBOARD(sRaceData.eRaceTrack, sRaceHUD.iPlayerPosition, iFinalRaceTime, sRaceHUD.iBestTime, sPlayerVehicle.vehPlayerVehicle)
scLB_rank_predict.bFinishedWrite = TRUE
ENDIF
IF GET_RANK_PREDICTION_DETAILS(sclbControl)
sclb_useRankPrediction = TRUE
RETURN TRUE
ENDIF
ELSE
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE: Race has been completed
PROC RACE_END()
//VEHICLE_INDEX viPlayer
DISABLE_CONTROL_ACTION(FRONTEND_CONTROL, INPUT_FRONTEND_PAUSE_ALTERNATE) // B*2239651 - Disabling pause_alternate during end screens (to avoid clash when exiting leaderboards)
HIDE_STREET_AND_CAR_NAMES_THIS_FRAME()
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.0)
SWITCH eRaceSubState
CASE RACE_SUBSTATE_SETUP
CPRINTLN(DEBUG_MISSION, "Mission Race: RACE_END")
REQUEST_LOAD_MODEL(A_F_Y_Genhot_01)
REQUEST_ANIM_DICT(sAnimDict)
//eRaceSubState = RACE_SUBSTATE_RUNNING
//INIT_RACE_RESULTS(mptRaceResultPlacement)
//SETUP_SOCIAL_CLUB_LEADERBOARD_READ_DATA(sclbControl, FMMC_TYPE_RACE, "", "", ciRACE_SUB_TYPE_STANDARD, sTrackData.iNumLaps)
iFinalRaceTime = GET_GAME_TIMER() - sRaceHUD.iStartTime
//iEndScreenTimer = GET_GAME_TIMER() + END_SCREEN_TIME
iQuitDelayTimer = -1
iLoadLeaderboardTimer = GET_GAME_TIMER() + 1000
bSetupLeaderboard = TRUE
bDrawLeaderboard = FALSE
bWaitToShowProfile = FALSE
bPlayMedalSound = TRUE
IF sTrackData.iNumLaps < 2
// If this was a single lap or point to point race, make the best time equal to the full race time
sRaceHUD.iBestTime = iFinalRaceTime
ENDIF
CLEAR_HELP()
bAllowLeaderboard = TRUE
SETUP_RACE_LEADERBOARD(sRaceData.eRaceTrack)
//INIT_RACE_LEADERBOARD(sRaceData.eRaceTrack, sRaceHUD.iPlayerPosition, iFinalRaceTime, sRaceHUD.iBestTime, sPlayerVehicle.vehPlayerVehicle)
INIT_RESULT_SCREEN_BUTTONS(sRaceResults)
bOnlineButtons = IS_PLAYER_ONLINE()
//INIT_SIMPLE_USE_CONTEXT(sLeaderboardContext, FALSE)
//ADD_SIMPLE_USE_CONTEXT_INPUT(sLeaderboardContext, "HUD_INPUT43", FRONTEND_CONTROL, INPUT_FRONTEND_LEADERBOARD)
INIT_RACE_RESULTS(esdEndScreen, sRaceData.eRaceTrack, sRaceHUD.iPlayerPosition, sTrackData.iNumAIRacers+1, iFinalRaceTime)//, sRaceHUD.iBestTime)
/*IF sRaceData.eRaceType = RACETYPE_SEA AND IS_PED_SITTING_IN_ANY_VEHICLE(PLAYER_PED_ID())
viPlayer = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID())
IF IS_VEHICLE_OK(viPlayer)
IF BRING_VEHICLE_TO_HALT_AND_DISABLE_VEH_CONTROLS(viPlayer, 20.0)
SET_BOAT_ANCHOR(viPlayer, TRUE)
ENDIF
ENDIF
ENDIF*/
// url:bugstar:7104254 - Double check the vehicle engine/petrol tank isn't on fire so we can proceed, if damaged repair it.
IF GET_VEHICLE_ENGINE_HEALTH(sPlayerVehicle.vehPlayerVehicle) <= 0.0
OR GET_VEHICLE_PETROL_TANK_HEALTH(sPlayerVehicle.vehPlayerVehicle) <= 0.0
SET_VEHICLE_ENGINE_HEALTH(sPlayerVehicle.vehPlayerVehicle, 800.0)
SET_VEHICLE_PETROL_TANK_HEALTH(sPlayerVehicle.vehPlayerVehicle, 800.0)
STOP_ENTITY_FIRE(sPlayerVehicle.vehPlayerVehicle)
ENDIF
IF IS_VEHICLE_OK(sPlayerVehicle.vehPlayerVehicle)
SET_VEHICLE_STOP_INSTANTLY_WHEN_PLAYER_INACTIVE(sPlayerVehicle.vehPlayerVehicle, FALSE)
ENDIF
PLAYER_INDEX piPlayer
piPlayer = GET_PLAYER_INDEX()
IF IS_PLAYER_PLAYING(piPlayer)
SET_PLAYER_CONTROL(piPlayer, FALSE)
ENDIF
IF sRaceData.eRaceType = RACETYPE_SEA
PLAYSTATS_ODDJOB_DONE(GET_GAME_TIMER() - iMissionStartTime, ENUM_TO_INT(MINIGAME_SEA_RACES), ENUM_TO_INT(sRaceData.eRaceTrack))
ELSE
PLAYSTATS_ODDJOB_DONE(GET_GAME_TIMER() - iMissionStartTime, ENUM_TO_INT(MINIGAME_STREET_RACES), ENUM_TO_INT(sRaceData.eRaceTrack))
FLOAT fPlayerHeading, fCheckpointHeading, fDiff
fPlayerHeading = GET_ENTITY_HEADING(PLAYER_PED_ID())
fCheckpointHeading = GET_HEADING_BETWEEN_VECTORS(GET_ENTITY_COORDS(PLAYER_PED_ID()), sTrackData.vCheckPoint[0])
fDiff = fPlayerHeading - fCheckpointHeading
IF fDiff < 20 AND fDiff > -20
TASK_VEHICLE_DRIVE_TO_COORD(PLAYER_PED_ID(), sPlayerVehicle.vehPlayerVehicle, sTrackData.vCheckPoint[0], 25, DRIVINGSTYLE_RACING, GET_ENTITY_MODEL(sPlayerVehicle.vehPlayerVehicle), DRIVINGMODE_AVOIDCARS_RECKLESS | DF_ForceStraightLine, 3.0, 5.0)
ENDIF
ENDIF
//streamVolume = STREAMVOL_CREATE_SPHERE(GET_ENTITY_COORDS(PLAYER_PED_ID()), 20.0, FLAG_MAPDATA)
eRaceSubState = RACE_SUBSTATE_RUNNING
BREAK
CASE RACE_SUBSTATE_RUNNING
//viPlayer = GET_PLAYERS_LAST_VEHICLE()
HIDE_HUD_AND_RADAR_THIS_FRAME()
SETUP_RACE_LEADERBOARD(sRaceData.eRaceTrack)
IF IS_USING_KEYBOARD_AND_MOUSE(FRONTEND_CONTROL)
SET_MOUSE_CURSOR_THIS_FRAME()
ENDIF
IF ciPreviousCheckPoint != NULL
IF DOES_CAM_EXIST(sRaceResults.ciCityRaceFinishCam[0])
DELETE_CHECKPOINT(ciPreviousCheckPoint)
ciPreviousCheckPoint = NULL
ENDIF
ENDIF
IF IS_VEHICLE_OK(sPlayerVehicle.vehPlayerVehicle)
IF City_Race_Manage_Finish_Camera(sPlayerVehicle.vehPlayerVehicle, sRaceResults, sRaceData.eRaceTrack)
IF RANK_PREDICT_DONE()
IF sRaceData.eRaceType = RACETYPE_SEA AND IS_PED_SITTING_IN_ANY_VEHICLE(PLAYER_PED_ID())
//viPlayer = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID())
IF IS_VEHICLE_OK(sPlayerVehicle.vehPlayerVehicle)
IF BRING_VEHICLE_TO_HALT_AND_DISABLE_VEH_CONTROLS(sPlayerVehicle.vehPlayerVehicle, 20.0)
AND CAN_ANCHOR_BOAT_HERE(sPlayerVehicle.vehPlayerVehicle)
SET_BOAT_ANCHOR(sPlayerVehicle.vehPlayerVehicle, TRUE)
ENDIF
ENDIF
ENDIF
IF iQuitDelayTimer < 0
iQuitDelayTimer = GET_GAME_TIMER() + QUIT_BUTTON_DELAY
IF sRaceData.eRaceTrack = STREET_RACE_06 AND sRaceHUD.iPlayerPosition <> 1
// Special case repositioning for street race 6 if the player doesn't win the race
SET_ENTITY_COORDS(sPlayerVehicle.vehPlayerVehicle, <<-1051.5194, -1147.2173, 1.0868>>)
SET_ENTITY_HEADING(sPlayerVehicle.vehPlayerVehicle, 303.3337)
CLEAR_PED_TASKS(PLAYER_PED_ID())
SET_VEHICLE_FORWARD_SPEED(sPlayerVehicle.vehPlayerVehicle, 0.0)
ENDIF
ENDIF
IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), sPlayerVehicle.vehPlayerVehicle) AND IS_VEHICLE_SEAT_FREE(sPlayerVehicle.vehPlayerVehicle)
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), sPlayerVehicle.vehPlayerVehicle)
ENDIF
IF sRaceData.eRaceType = RACETYPE_SEA
SETUP_SEA_RACERS_AT_END()
ELSE
CLEANUP_RACERS(TRUE)
ENDIF
IF sRaceResults.eCRCutFinish = CR_FINISH_IDLE
SETUP_END_SCENE(sPlayerVehicle.vehPlayerVehicle)
ENDIF
//DRAW_RACE_RESULTS(mptRaceResultPlacement, sRaceData.eRaceTrack, sRaceHUD.iPlayerPosition, sTrackData.iNumAIRacers+1, iFinalRaceTime)
IF IS_PLAYER_ONLINE() AND NETWORK_HAVE_ONLINE_PRIVILEGES() AND iQuitDelayTimer > 0 AND GET_GAME_TIMER() > iQuitDelayTimer
IF bDrawLeaderboard
IF IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_CANCEL)
PLAY_SOUND_FRONTEND(-1,"LEADER_BOARD","HUD_FRONTEND_DEFAULT_SOUNDSET")
CLEANUP_SIMPLE_USE_CONTEXT(sRaceResults.ucInstructions)
INIT_RESULT_SCREEN_BUTTONS(sRaceResults)
bDrawLeaderboard = FALSE
ELSE
// Check for if it's OK to add the Profile button to the leaderboard buttons
IF bWaitToShowProfile
IF SHOULD_PROFILE_BUTTON_BE_AVAILABLE_FOR_LEADERBOARD(sclbControl)
CLEANUP_SIMPLE_USE_CONTEXT(sRaceResults.ucInstructions)
INIT_SIMPLE_USE_CONTEXT(sRaceResults.ucInstructions, FALSE, FALSE, TRUE, TRUE)
ADD_SIMPLE_USE_CONTEXT_INPUT(sRaceResults.ucInstructions, "HUD_INPUT43", FRONTEND_CONTROL, INPUT_FRONTEND_CANCEL)
ADD_SIMPLE_USE_CONTEXT_INPUT(sRaceResults.ucInstructions, "SCLB_PROFILE", FRONTEND_CONTROL, INPUT_FRONTEND_SELECT)
bWaitToShowProfile = FALSE
ENDIF
ENDIF
ENDIF
ELSE
IF IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_LEADERBOARD)
PLAY_SOUND_FRONTEND(-1,"LEADER_BOARD","HUD_FRONTEND_DEFAULT_SOUNDSET")
CLEANUP_SIMPLE_USE_CONTEXT(sRaceResults.ucInstructions)
INIT_SIMPLE_USE_CONTEXT(sRaceResults.ucInstructions, FALSE, FALSE, TRUE, TRUE)
ADD_SIMPLE_USE_CONTEXT_INPUT(sRaceResults.ucInstructions, "HUD_INPUT43", FRONTEND_CONTROL, INPUT_FRONTEND_CANCEL)
IF SHOULD_PROFILE_BUTTON_BE_AVAILABLE_FOR_LEADERBOARD(sclbControl)
ADD_SIMPLE_USE_CONTEXT_INPUT(sRaceResults.ucInstructions, "SCLB_PROFILE", FRONTEND_CONTROL, INPUT_FRONTEND_SELECT)
bWaitToShowProfile = FALSE
ELSE
bWaitToShowProfile = TRUE
ENDIF
bDrawLeaderboard = TRUE
ENDIF
ENDIF
ENDIF
IF bPlayMedalSound
IF sRaceHUD.iPlayerPosition <= 1
PLAY_SOUND_FRONTEND(-1, "MEDAL_UP", "HUD_MINI_GAME_SOUNDSET")
ELSE
PLAY_SOUND_FRONTEND(-1, "RACE_PLACED", "HUD_AWARDS")
ENDIF
bPlayMedalSound = FALSE
ENDIF
IF bDrawLeaderboard
IF IS_PLAYER_ONLINE()
DRAW_RACE_LEADERBOARD(uiLeaderboard)
UPDATE_SIMPLE_USE_CONTEXT(sRaceResults.ucInstructions)
ELSE
IF DO_SIGNED_OUT_WARNING(iBS)
iBS = 0
CLEANUP_SIMPLE_USE_CONTEXT(sRaceResults.ucInstructions)
INIT_RESULT_SCREEN_BUTTONS(sRaceResults)
bDrawLeaderboard = FALSE
bOnlineButtons = FALSE
ENDIF
ENDIF
ELSE
DRAW_RACE_RESULTS(esdEndScreen)
IF (IS_PLAYER_ONLINE() <> bOnlineButtons)
CLEANUP_SIMPLE_USE_CONTEXT(sRaceResults.ucInstructions)
INIT_RESULT_SCREEN_BUTTONS(sRaceResults)
bOnlineButtons = IS_PLAYER_ONLINE()
ENDIF
IF GET_GAME_TIMER() > iQuitDelayTimer
//DRAW_RESULT_SCREEN_INSTRUCTIONS(sRaceResults)
UPDATE_SIMPLE_USE_CONTEXT(sRaceResults.ucInstructions)
IF IS_CONTROL_JUST_PRESSED( FRONTEND_CONTROL, INPUT_FRONTEND_ENDSCREEN_ACCEPT)
FORCE_ENDSCREEN_ANIM_OUT(esdEndScreen)
SET_ENTITY_CAN_BE_DAMAGED(sPlayerVehicle.vehPlayerVehicle, true)
eRaceSubState = RACE_SUBSTATE_CLEANUP
ELIF IS_CONTROL_JUST_PRESSED( FRONTEND_CONTROL, INPUT_FRONTEND_ENDSCREEN_EXPAND)
PLAY_SOUND_FRONTEND(-1,"LEADER_BOARD","HUD_FRONTEND_DEFAULT_SOUNDSET")
WAIT(0)
HIDE_HUD_AND_RADAR_THIS_FRAME()
CLEANUP_RACE_LEADERBOARD(esdEndScreen, uiLeaderboard[0])
GIVE_PLAYER_WINNINGS()
//STREAMVOL_DELETE(streamVolume)
CLEANUP_SIMPLE_USE_CONTEXT(sRaceResults.ucInstructions)
CLEAR_RANK_REDICTION_DETAILS()
IF IS_VEHICLE_OK(sPlayerVehicle.vehPlayerVehicle)
SET_ENTITY_CAN_BE_DAMAGED(sPlayerVehicle.vehPlayerVehicle, true)
ENDIF
IF sRaceData.eRaceType = RACETYPE_SEA
IF IS_VEHICLE_OK(sPlayerVehicle.vehPlayerVehicle)
SET_BOAT_ANCHOR(sPlayerVehicle.vehPlayerVehicle, FALSE)
ENDIF
ENDIF
RESTART_RACE()
Stop_Finish_Cam(sRaceResults, FALSE)
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
RANK_PREDICT_DONE() // Added for B* 2057456 - preloading all social club data
ENDSCREEN_PREPARE(esdEndScreen, FALSE)
ENDIF
ENDIF
IF bSetupLeaderboard
IF GET_GAME_TIMER() > iLoadLeaderboardTimer
SETUP_RACE_LEADERBOARD(sRaceData.eRaceTrack)
bSetupLeaderboard = FALSE
ENDIF
ENDIF
/*IF GET_GAME_TIMER() > iEndScreenTimer
eRaceSubState = RACE_SUBSTATE_CLEANUP
ENDIF*/
BREAK
CASE RACE_SUBSTATE_CLEANUP
HIDE_HUD_AND_RADAR_THIS_FRAME()
IF RENDER_ENDSCREEN(esdEndScreen)
IF sRaceData.eRaceType = RACETYPE_SEA
//viPlayer = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID())
IF IS_VEHICLE_OK(sPlayerVehicle.vehPlayerVehicle)
SET_BOAT_ANCHOR(sPlayerVehicle.vehPlayerVehicle, FALSE)
ENDIF
ENDIF
//STREAMVOL_DELETE(streamVolume)
// Reward stage
IF END_SCENE_IS_VALID()
IF IS_PED_UNINJURED(piRewardPed)
TASK_PLAY_ANIM(piRewardPed, sAnimDict, "_grid_girl_end", INSTANT_BLEND_IN, NORMAL_BLEND_OUT, 5500)
ENDIF
eRaceState = RACE_STATE_REWARD
eRaceSubState = RACE_SUBSTATE_SETUP
ELSE
// sea race, no end scene for this race
CLEANUP_RACE_LEADERBOARD(esdEndScreen, uiLeaderboard[0])
CLEANUP_SIMPLE_USE_CONTEXT(sRaceResults.ucInstructions)
Stop_Finish_Cam(sRaceResults, FALSE, TRUE)
IF DOES_CAM_EXIST(sRaceResults.ciCityRaceFinishCam[4])
IF NOT IS_CAM_INTERPOLATING(sRaceResults.ciCityRaceFinishCam[4])
IF DOES_CAM_EXIST(sRaceResults.ciCityRaceFinishCam[3])
SET_CAM_MOTION_BLUR_STRENGTH(sRaceResults.ciCityRaceFinishCam[3],0.0)
ENDIF
SET_CAM_MOTION_BLUR_STRENGTH(sRaceResults.ciCityRaceFinishCam[4],0.0)
WAIT(0)
HIDE_HUD_AND_RADAR_THIS_FRAME()
STOP_RENDERING_SCRIPT_CAMS_USING_CATCH_UP()
INT i_index
i_index = 0
REPEAT 8 i_index
IF DOES_CAM_EXIST(sRaceResults.ciCityRaceFinishCam[i_index])
DESTROY_CAM(sRaceResults.ciCityRaceFinishCam[i_index])
ENDIF
ENDREPEAT
eRaceState = RACE_STATE_REWARD
eRaceSubState = RACE_SUBSTATE_CLEANUP
ENDIF
ELSE
eRaceState = RACE_STATE_REWARD
eRaceSubState = RACE_SUBSTATE_CLEANUP
ENDIF
ENDIF
ENDIF
BREAK
ENDSWITCH
ENDPROC
PROC MAKE_REWARD_PED_WALK()
IF bReadyToWalk
IF IS_PED_UNINJURED(piRewardPed)
//IF GET_GAME_TIMER() > iMissionEndTimeout
VECTOR targetPos
IF sRaceData.eRaceTrack = STREET_RACE_01
targetPos = <<-193.889465,-1608.291748,32.996201>>
ELIF sRaceData.eRaceTrack = STREET_RACE_02
targetPos = <<315.518982,334.954834,104.468964>>//<<271.950775,345.988983,104.469872>>
ELIF sRaceData.eRaceTrack = STREET_RACE_04
targetPos = <<-679.861633,-2360.600098,12.865215>>
ELIF sRaceData.eRaceTrack = STREET_RACE_05
targetPos = <<816.6395, -1170.4956, 27.6677>>
ELIF sRaceData.eRaceTrack = STREET_RACE_06
targetPos = <<-997.567810,-1153.996948,1.157350>>
ELSE
targetPos = GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(GET_ENTITY_COORDS(piRewardPed), GET_ENTITY_HEADING(piRewardPed), <<0.0, 5.0, 0.0>>)
ENDIF
SEQUENCE_INDEX siLeave
OPEN_SEQUENCE_TASK(siLeave)
TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, targetPos, PEDMOVE_WALK, -1)
IF sRaceData.eRaceTrack = STREET_RACE_04
TASK_START_SCENARIO_IN_PLACE(NULL, "WORLD_HUMAN_SMOKING", 0, TRUE)
ELSE
TASK_WANDER_STANDARD(NULL, fRewardPedHeading)
ENDIF
CLOSE_SEQUENCE_TASK(siLeave)
IF IS_ENTITY_PLAYING_ANIM(piRewardPed, sAnimDict, "_grid_girl_end")
STOP_ANIM_TASK(piRewardPed, sAnimDict, "_grid_girl_end")
ENDIF
CLEAR_PED_TASKS(piRewardPed)
TASK_PERFORM_SEQUENCE(piRewardPed, siLeave)
FORCE_PED_MOTION_STATE(piRewardPed,MS_ON_FOOT_WALK,FALSE,FAUS_DEFAULT, TRUE)
//FORCE_PED_AI_AND_ANIMATION_UPDATE(piRewardPed, TRUE)
CLEAR_SEQUENCE_TASK(siLeave)
//iMissionEndTimeout = GET_GAME_TIMER() + 1000
//eRaceSubState = RACE_SUBSTATE_CLEANUP
CPRINTLN(DEBUG_MISSION, "Making grid girl walk")
bReadyToWalk = FALSE
//ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Scripted scene showing a ped giving the prize money to the winner
PROC RACE_REWARD()
HIDE_STREET_AND_CAR_NAMES_THIS_FRAME()
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.0)
SWITCH eRaceSubState
CASE RACE_SUBSTATE_SETUP
HIDE_HUD_AND_RADAR_THIS_FRAME()
/*IF IS_PED_UNINJURED(piRewardPed)
SEQUENCE_INDEX siReward
IF IS_PED_UNINJURED(PLAYER_PED_ID())
//vRewardDest = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(PLAYER_PED_ID(), <<1,5,0>>)
OPEN_SEQUENCE_TASK(siReward)
//TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, vRewardDest, PEDMOVE_WALK)
//TASK_TURN_PED_TO_FACE_ENTITY(NULL, PLAYER_PED_ID())
TASK_PLAY_ANIM(NULL, sAnimDict, "_grid_girl_end", INSTANT_BLEND_IN)//, INSTANT_BLEND_OUT)
//TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, vRewardDest, PEDMOVE_WALK)
TASK_WANDER_STANDARD(NULL, fRewardPedHeading)
CLOSE_SEQUENCE_TASK(siReward)
TASK_PERFORM_SEQUENCE(piRewardPed, siReward)
CLEAR_SEQUENCE_TASK(siReward)
ENDIF
ENDIF*/
IF IS_PED_UNINJURED(piRewardPed) AND IS_PED_UNINJURED(PLAYER_PED_ID())
TASK_LOOK_AT_ENTITY(PLAYER_PED_ID(), piRewardPed, -1, SLF_FAST_TURN_RATE | SLF_WHILE_NOT_IN_FOV, SLF_LOOKAT_VERY_HIGH)
ENDIF
WAIT(0)
HIDE_HUD_AND_RADAR_THIS_FRAME()
Stop_Finish_Cam(sRaceResults)
CLEANUP_RACE_LEADERBOARD(esdEndScreen, uiLeaderboard[0])
CLEANUP_SIMPLE_USE_CONTEXT(sRaceResults.ucInstructions)
//SET_GAMEPLAY_CAM_RELATIVE_PITCH(-12.0135)
//SET_GAMEPLAY_CAM_RELATIVE_HEADING(-124.8084)
//iConvFailTimer = -1
//iMissionEndTimeout = -1
iMissionEndTimeout = GET_GAME_TIMER() + 2500
//bConversationStarted = FALSE
bReadyToWalk = TRUE
bBlowKiss = TRUE
eRaceSubState = RACE_SUBSTATE_RUNNING
BREAK
CASE RACE_SUBSTATE_RUNNING
HIDE_HUD_AND_RADAR_THIS_FRAME()
IF City_Race_Manage_Reward_Camera(sRaceResults) //AND GET_GAME_TIMER() > iMissionEndTimeout
//iMissionEndTimeout = GET_GAME_TIMER() + 1000
//MAKE_REWARD_PED_WALK()
eRaceSubState = RACE_SUBSTATE_CLEANUP
ENDIF
IF IS_PED_UNINJURED(piRewardPed)
IF GET_GAME_TIMER() > iMissionEndTimeout
MAKE_REWARD_PED_WALK()
ENDIF
IF bBlowKiss AND IS_ENTITY_PLAYING_ANIM(piRewardPed, sAnimDict, "_grid_girl_end") AND GET_ENTITY_ANIM_CURRENT_TIME(piRewardPed, sAnimDict, "_grid_girl_end") > 0.165
PLAY_SOUND_FROM_ENTITY(-1, "KISS", piRewardPed, "ROAD_RACE_SOUNDSET")
bBlowKiss = FALSE
ENDIF
ENDIF
BREAK
CASE RACE_SUBSTATE_CLEANUP
//IF GET_GAME_TIMER() > iMissionEndTimeout
GIVE_PLAYER_WINNINGS()
//SET_GAMEPLAY_CAM_RELATIVE_PITCH()
//SET_GAMEPLAY_CAM_RELATIVE_HEADING()
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
IF IS_PED_UNINJURED(PLAYER_PED_ID())
TASK_CLEAR_LOOK_AT(PLAYER_PED_ID())
ENDIF
Stop_Reward_Cam(sRaceResults)
INT i_index
i_index = 0
REPEAT 8 i_index
IF DOES_CAM_EXIST(sRaceResults.ciCityRaceFinishCam[i_index])
DESTROY_CAM(sRaceResults.ciCityRaceFinishCam[i_index])
ENDIF
ENDREPEAT
// Terminate script
IF sRaceData.eRaceType = RACETYPE_SEA
SCRIPT_CLEANUP(FALSE)
ELSE
SCRIPT_CLEANUP(TRUE)
ENDIF
//ENDIF
BREAK
ENDSWITCH
ENDPROC
/// PURPOSE: Race has been failed
PROC RACE_FAIL()
HIDE_STREET_AND_CAR_NAMES_THIS_FRAME()
SWITCH eRaceSubState
CASE RACE_SUBSTATE_SETUP
CPRINTLN(DEBUG_MISSION, "Mission Race: RACE_FAIL")
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
ENDIF
CLEANUP_CHECKPOINTS()
//CLEANUP_RACERS(FALSE)
IF sRaceData.eRaceType = RACETYPE_SEA
STOP_AUDIO_SCENE("SEA_RACE_DURING_RACE")
ELSE
STOP_AUDIO_SCENE("STREET_RACE_DURING_RACE")
ENDIF
IF IS_VEHICLE_OK(sPlayerVehicle.vehPlayerVehicle)
SET_VEHICLE_STOP_INSTANTLY_WHEN_PLAYER_INACTIVE(sPlayerVehicle.vehPlayerVehicle, FALSE)
ENDIF
SET_PLAYER_CONTROL(GET_PLAYER_INDEX(), FALSE)
DISABLE_CONTROL_ACTION(CAMERA_CONTROL, INPUT_VEH_CIN_CAM)
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_CIN_CAM)
HANG_UP_AND_PUT_AWAY_PHONE()
sFailMessage = ""
SWITCH failReason
CASE FAIL_DEFAULT
CPRINTLN(DEBUG_MISSION, "MISSION_FAILED reason=FAILED_DEFAULT")
BREAK
CASE FAIL_RIVAL_ATTACKED
CPRINTLN(DEBUG_MISSION, "MISSION_FAILED reason=FAIL_RIVAL_ATTACKED")
//PRINT_NOW("RACES_R_INJ", DEFAULT_GOD_TEXT_TIME, 1) // Franklin attacked a rival racer.
IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_FRANKLIN
sFailMessage = "RACES_R_INJ"
ELIF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_MICHAEL
sFailMessage = "RACES_R_INJ_M"
ELSE
sFailMessage = "RACES_R_INJ_T"
ENDIF
BREAK
CASE FAIL_RIVAL_DEAD
CPRINTLN(DEBUG_MISSION, "MISSION_FAILED reason=FAIL_RIVAL_DEAD")
//PRINT_NOW("RACES_R_DEAD", DEFAULT_GOD_TEXT_TIME, 1) // A rival racer died.
sFailMessage = "RACES_R_DEAD"
BREAK
CASE FAIL_WRECKED
CPRINTLN(DEBUG_MISSION, "MISSION_FAILED reason=FAIL_WRECKED")
//PRINT_NOW("RACES_WRECK", DEFAULT_GOD_TEXT_TIME, 1) // Franklin's vehicle was wrecked.
IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_FRANKLIN
sFailMessage = "RACES_WRECK"
ELIF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_MICHAEL
sFailMessage = "RACES_WRECK_M"
ELSE
sFailMessage = "RACES_WRECK_T"
ENDIF
BREAK
CASE FAIL_ABANDONED_RACE
CPRINTLN(DEBUG_MISSION, "MISSION_FAILED reason=FAIL_ABANDONED_RACE")
//PRINT_NOW("RACES_ABAND", DEFAULT_GOD_TEXT_TIME, 1) // Franklin abandoned the race.
IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_FRANKLIN
sFailMessage = "RACES_ABAND"
ELIF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_MICHAEL
sFailMessage = "RACES_ABAND_M"
ELSE
sFailMessage = "RACES_ABAND_T"
ENDIF
BREAK
CASE FAIL_MISSED_CHECKPOINT
CPRINTLN(DEBUG_MISSION, "MISSION_FAILED reason=FAIL_MISSED_CHECKPOINT")
IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_FRANKLIN
sFailMessage = "RACES_MISS"
ELIF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_MICHAEL
sFailMessage = "RACES_MISS_M"
ELSE
sFailMessage = "RACES_MISS_T"
ENDIF
BREAK
CASE FAIL_ALERTED_COPS
CPRINTLN(DEBUG_MISSION, "MISSION_FAILED reason=FAIL_ALERTED_COPS")
//PRINT_NOW("RACES_COPS", DEFAULT_GOD_TEXT_TIME, 1) // Franklin alerted the cops.
IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_FRANKLIN
sFailMessage = "RACES_COPS"
ELIF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_MICHAEL
sFailMessage = "RACES_COPS_M"
ELSE
sFailMessage = "RACES_COPS_T"
ENDIF
BREAK
ENDSWITCH
/*INIT_SIMPLE_USE_CONTEXT(sComplexUseContext, FALSE)
ADD_SIMPLE_USE_CONTEXT_INPUT(sComplexUseContext, "IB_YES", FRONTEND_CONTROL, INPUT_FRONTEND_ACCEPT)
ADD_SIMPLE_USE_CONTEXT_INPUT(sComplexUseContext, "IB_NO", FRONTEND_CONTROL, INPUT_FRONTEND_CANCEL)*/
IF IS_STRING_NULL_OR_EMPTY(sFailMessage)
// Terminate script
SCRIPT_CLEANUP(FALSE)
ELSE
//SET_SCALEFORM_BIG_MESSAGE(sBigMessage, "SPR_UI_FAILD", sFailMessage, 4000, HUD_COLOUR_RED)//, MG_BIG_MESSAGE_MISSION_FAILED)
iRaceFailTimeout = GET_GAME_TIMER() + 4000
eRaceSubState = RACE_SUBSTATE_RUNNING
ENDIF
BREAK
CASE RACE_SUBSTATE_RUNNING
/*UPDATE_SCALEFORM_BIG_MESSAGE(sBigMessage)
IF GET_GAME_TIMER() > iRaceFailTimeout
// Switch to the retry menu
SET_SCALEFORM_BIG_MESSAGE(sBigMessage, "SPR_UI_FAILD", "SPR_UI_FRETRY", 4000, HUD_COLOUR_RED)//, MG_BIG_MESSAGE_MISSION_FAILED)
eRaceSubState = RACE_SUBSTATE_CLEANUP
ENDIF*/
IF MG_UPDATE_FAIL_SPLASH_SCREEN(sBigMessage, sFailSplash, "SPR_UI_FAILD", sFailMessage, bShouldRetry)
IF bShouldRetry
PLAY_SOUND_FRONTEND(-1,"YES","HUD_FRONTEND_DEFAULT_SOUNDSET")
WAIT(0)
RESTART_RACE(FALSE)
ELSE
// Terminate script
//ENABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_CIN_CAM)
PLAY_SOUND_FRONTEND(-1,"NO","HUD_FRONTEND_DEFAULT_SOUNDSET")
WAIT(0)
sRaceHUD.iPlayerPosition = 99
SET_PLAYER_CONTROL(GET_PLAYER_INDEX(), TRUE)
SCRIPT_CLEANUP(FALSE)
ENDIF
ENDIF
BREAK
/*CASE RACE_SUBSTATE_CLEANUP
UPDATE_SCALEFORM_BIG_MESSAGE(sBigMessage)
SET_INPUT_EXCLUSIVE(FRONTEND_CONTROL, INPUT_FRONTEND_ACCEPT)
SET_INPUT_EXCLUSIVE(FRONTEND_CONTROL, INPUT_FRONTEND_CANCEL)
UPDATE_SIMPLE_USE_CONTEXT(sComplexUseContext)
IF IS_CONTROL_JUST_RELEASED(FRONTEND_CONTROL, INPUT_FRONTEND_ACCEPT)
//ENABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_CIN_CAM)
PLAY_SOUND_FRONTEND(-1,"YES","HUD_FRONTEND_DEFAULT_SOUNDSET")
WAIT(0)
RESTART_RACE(FALSE)
ELIF IS_CONTROL_JUST_RELEASED(FRONTEND_CONTROL, INPUT_FRONTEND_CANCEL)
// Terminate script
//ENABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_CIN_CAM)
PLAY_SOUND_FRONTEND(-1,"NO","HUD_FRONTEND_DEFAULT_SOUNDSET")
WAIT(0)
sRaceHUD.iPlayerPosition = 99
SET_PLAYER_CONTROL(GET_PLAYER_INDEX(), TRUE)
SCRIPT_CLEANUP(FALSE)
ENDIF
BREAK*/
ENDSWITCH
ENDPROC
// Main script thread
SCRIPT (RACE_DATA launcherRaceData)
CPRINTLN(DEBUG_MISSION, "Mission Race: Launched!")
//Grab race data
sRaceData = launcherRaceData
// 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|FORCE_CLEANUP_FLAG_REPEAT_PLAY))
CPRINTLN(DEBUG_MISSION, "Mission Race: FORCE CLEANUP")
sRaceHUD.iPlayerPosition = 99
SCRIPT_CLEANUP(FALSE)
ENDIF
// Now on mission
SET_MISSION_FLAG(TRUE)
IF sRaceData.eRaceType = RACETYPE_SEA
MINIGAME_DISPLAY_MISSION_TITLE(ENUM_TO_INT(MINIGAME_SEA_RACES))
SET_RICH_PRESENCE_FOR_SP_MINIGAME(MINIGAME_SEA_RACES)
ELSE
MINIGAME_DISPLAY_MISSION_TITLE(ENUM_TO_INT(MINIGAME_STREET_RACES))
SET_RICH_PRESENCE_FOR_SP_MINIGAME(MINIGAME_STREET_RACES)
ENDIF
SWITCH sRaceData.eRaceTrack
CASE STREET_RACE_01 iRaceID=1 BREAK
CASE STREET_RACE_02 iRaceID=2 BREAK
CASE STREET_RACE_04 iRaceID=4 BREAK
CASE STREET_RACE_05 iRaceID=5 BREAK
CASE STREET_RACE_06 iRaceID=6 BREAK
CASE SEA_RACE_01 iRaceID=1 BREAK
CASE SEA_RACE_02 iRaceID=2 BREAK
CASE SEA_RACE_03 iRaceID=3 BREAK
CASE SEA_RACE_04 iRaceID=4 BREAK
ENDSWITCH
// Initial setup
CPRINTLN(DEBUG_MISSION, "Mission Race: Initialising...")
RACE_INIT()
DISABLE_TAXI_HAILING(TRUE)
SUPPRESS_LARGE_VEHICLES(TRUE)
// Create the canal blocking dumpsters for street race 6
IF sRaceData.eRaceTrack = STREET_RACE_06
REQUEST_MODEL(prop_dumpster_02a)
ENDIF
// Street race main loop.
WHILE TRUE
// Check current race state
SWITCH eRaceState
CASE RACE_STATE_LINEUP
RACE_LINEUP()
BREAK
CASE RACE_STATE_COUNTDOWN
RACE_COUNTDOWN()
BREAK
CASE RACE_STATE_ACTIVE
RACE_ACTIVE()
BREAK
CASE RACE_STATE_END
RACE_END()
BREAK
CASE RACE_STATE_REWARD
RACE_REWARD()
BREAK
CASE RACE_STATE_FAIL
RACE_FAIL()
BREAK
ENDSWITCH
#IF IS_DEBUG_BUILD
DEBUG_Check_Debug_Keys()
#ENDIF
// Wait until next frame.
WAIT(0)
ENDWHILE
// Should never reach here.
CPRINTLN(DEBUG_MISSION, "Mission Race: Reached ENDSCRIPT!!!")
ENDSCRIPT