/// Common helper functions to be used by all RC missions USING "rage_builtins.sch" USING "globals.sch" USING "commands_entity.sch" USING "script_player.sch" USING "script_ped.sch" USING "cutscene_public.sch" USING "dialogue_public.sch" USING "flow_help_public.sch" USING "commands_weapon.sch" using "clearMissionArea.sch" USING "cutscene_control_public.sch" USING "replay_public.sch" #if not USE_CLF_DLC #if not USE_NRM_DLC USING "randomChar_Public.sch" #endif #endif USING "locates_public.sch" // --------------------------------------------------------------------------------------------- // -----------------ALIVE CHECKS---------------------------------------------------------------- // --------------------------------------------------------------------------------------------- /// PURPOSE: /// Checks if the entity exists and is not dead. /// PARAMS: /// mEntity - the entity we are checking. /// RETURNS: /// True if the entity exists and is not dead. FUNC BOOL IS_ENTITY_ALIVE(ENTITY_INDEX mEntity) IF DOES_ENTITY_EXIST(mEntity) IF NOT IS_ENTITY_DEAD(mEntity) RETURN TRUE ENDIF ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// Checks that the ped exists, is alive and is not injured /// PARAMS: /// mPed - the ped we are checking /// RETURNS: /// True if the ped exists, is alive and is not injured. false otherwise. FUNC BOOL IS_PED_UNINJURED(PED_INDEX mPed) IF IS_ENTITY_ALIVE(mPed) IF NOT IS_PED_INJURED(mPed) RETURN TRUE ENDIF ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// Checks that the vehicle exists, is alive, driveable and not on fire /// PARAMS: /// mVehicle - the vehicle we are checking /// RETURNS: /// True if the vehicle exists, is alive, driveable and not on fire. false otherwise. FUNC BOOL IS_VEHICLE_OK(VEHICLE_INDEX mVehicle) IF IS_ENTITY_ALIVE(mVehicle) IF IS_VEHICLE_DRIVEABLE(mVehicle) IF NOT IS_ENTITY_ON_FIRE(mVehicle) RETURN TRUE ENDIF ENDIF ENDIF RETURN FALSE ENDFUNC // --------------------------------------------------------------------------------------------- // -----------------CUTSCENE FUNCTIONS---------------------------------------------------------- // --------------------------------------------------------------------------------------------- WEAPON_TYPE mPlayerWeapon /// PURPOSE: /// Call this just before requesting a mocap cutscene (or just before starting a scripted cutscene) /// Turns off player control, clears nearby explosions, disables phone and stops conversations PROC RC_PRE_REQUEST_CUTSCENE(BOOL bKeepControl) PLAYER_INDEX pId = GET_PLAYER_INDEX() IF NOT IS_PLAYER_DEAD(pId) IF bKeepControl CPRINTLN(DEBUG_MISSION, "RC_PRE_REQUEST_CUTSCENE: Keeping player control..") ELSE CPRINTLN(DEBUG_MISSION, "RC_PRE_REQUEST_CUTSCENE: Disabling player control..") ENDIF // Remove projectiles and explosions // Disable player control if this has been specified - now allowing player to // move prior to cutscenes for lead-ins, etc. SET_PLAYER_CONTROL(pId, bKeepControl, SPC_REMOVE_EXPLOSIONS) SET_PLAYER_CONTROL(pId, bKeepControl, SPC_REMOVE_PROJECTILES) ENDIF // Make the phone system safe SET_SCRIPTS_SAFE_FOR_CUTSCENE(TRUE, TRUE, FALSE) ENDPROC /// PURPOSE: /// Call this just before requesting a mocap cutscene which plays out during a mission (not an intro) /// This does all the same setup required as RC_PRE_REQUEST_CUTSCENE accept it doesn't call the player control commands /// since this interfers with stopping the player's vehicle smoothly with RC_IS_CUTSCENE_OK_TO_START(see bug 995297) /// PARAMS: /// sCutscene - the name of the cut-scene we are loading PROC RC_REQUEST_MID_MISSION_CUTSCENE(String sCutscene) SET_SCRIPTS_SAFE_FOR_CUTSCENE(TRUE, DEFAULT, FALSE) REQUEST_CUTSCENE(sCutscene) ENDPROC /// PURPOSE: /// Call this when requesting a mocap cutscene in an RC mission /// Disables player control and the phone, stops conversations, clears nearby explosions and loads the cutscene /// PARAMS: /// sCutscene - the name of the cut-scene we are loading /// bAllowControl - allows player control (if we are using this with RC_TRIGGER_PLAYER_LOCK_IN() - set this to be true) PROC RC_REQUEST_CUTSCENE(String sCutscene, BOOL bAllowControl = FALSE) RC_PRE_REQUEST_CUTSCENE(bAllowControl) REQUEST_CUTSCENE(sCutscene) ENDPROC /// PURPOSE: /// Fades the screen from the game camera to black. For use in cutscenes. /// PARAMS: /// iTime - Milliseconds length of the fade. /// bWaitForFade - Whether the mission script should wait until the fade is completed. PROC SAFE_FADE_SCREEN_OUT_TO_BLACK(INT iTime = 500, BOOL bWaitForFade = TRUE) IF IS_SCREEN_FADED_IN() IF NOT IS_SCREEN_FADING_OUT() DO_SCREEN_FADE_OUT(iTime) IF bWaitForFade WHILE NOT IS_SCREEN_FADED_OUT() WAIT(0) ENDWHILE ENDIF ENDIF ENDIF ENDPROC /// PURPOSE: /// Fades the screen from black, back to the game camera. For use in cutscenes. /// PARAMS: /// iTime - Milliseconds length of the fade. /// bWaitForFade - Whether the mission script should wait until the fade is completed. PROC SAFE_FADE_SCREEN_IN_FROM_BLACK(INT iTime = 500, BOOL bWaitForFade = TRUE) IF IS_SCREEN_FADED_OUT() OR IS_SCREEN_FADING_OUT() IF NOT IS_SCREEN_FADING_IN() DO_SCREEN_FADE_IN(iTime) ENDIF ENDIF IF bWaitForFade WHILE NOT IS_SCREEN_FADED_IN() WAIT(0) ENDWHILE ENDIF ENDPROC /// PURPOSE: /// Handles entering cutscenes. Turns player control off, disables phone /// Clears area of peds, clears wanted level, hides radar + HUD, Clears Prints + Help /// Puts widescreen borders on, handles hiding player's weapon /// repositions player's last vehicle, fades in /// PARAMS: /// vTriggerLocation - where is the cutscene taking place /// bUseWidescreenBorders - TRUE turn widescreen borders on /// bPutPlayerWeaponAway - TRUE handle hiding the player's weapon /// bFadeIn = should we fade the screen in? /// bClearPeds = do we want to clear the nearby area of peds /// bClearObjects = do we want to clear nearby area of objects (this also clears scenarios) /// bRemoveParachutes - do we want to removed the player's parachutte /// bRemovePlayerHelmet - do we want to removed the player's helmet PROC RC_START_CUTSCENE_MODE(VECTOR vTriggerLocation, BOOL bUseWidescreenBorders = TRUE, BOOL bPutPlayerWeaponAway = TRUE, BOOL bFadeIn = TRUE, BOOL bClearPeds = TRUE, BOOL bClearObjects = TRUE, BOOL bRemoveParachutes = TRUE, BOOL bRemovePlayerHelmet = TRUE, BOOL bExtinguishFires = TRUE, BOOL bClearHelp = TRUE, BOOL bHideHUDRadar = TRUE) PLAYER_INDEX pId = GET_PLAYER_INDEX() IF IS_PLAYER_PLAYING(pId) CPRINTLN(DEBUG_MISSION, "RC_START_CUTSCENE_MODE") // Disable player control, clear area of projectiles, disable phone... RC_PRE_REQUEST_CUTSCENE(FALSE) // Remove player's bike helmet if he has one IF bRemovePlayerHelmet REMOVE_PLAYER_HELMET(GET_PLAYER_INDEX(), TRUE) ENDIF // Remove the parachute jacket if present IF bRemoveParachutes SWITCH GET_CURRENT_PLAYER_PED_ENUM() CASE CHAR_MICHAEL IF IS_PED_COMP_ITEM_CURRENT_SP(PLAYER_PED_ID(), COMP_TYPE_SPECIAL, SPECIAL_P0_PARACHUTE) SET_PED_COMP_ITEM_CURRENT_SP(PLAYER_PED_ID(), COMP_TYPE_SPECIAL, SPECIAL_P0_NONE) ENDIF IF IS_PED_COMP_ITEM_CURRENT_SP(PLAYER_PED_ID(), COMP_TYPE_SPECIAL2, SPECIAL2_P0_PARACHUTE_2) SET_PED_COMP_ITEM_CURRENT_SP(PLAYER_PED_ID(), COMP_TYPE_SPECIAL2, SPECIAL2_P0_NONE) ENDIF BREAK CASE CHAR_FRANKLIN IF IS_PED_COMP_ITEM_CURRENT_SP(PLAYER_PED_ID(), COMP_TYPE_SPECIAL, SPECIAL_P1_PARACHUTE) OR IS_PED_COMP_ITEM_CURRENT_SP(PLAYER_PED_ID(), COMP_TYPE_SPECIAL, SPECIAL_P1_PARACHUTE_1) SET_PED_COMP_ITEM_CURRENT_SP(PLAYER_PED_ID(), COMP_TYPE_SPECIAL, SPECIAL_P1_DUMMY) ENDIF BREAK CASE CHAR_TREVOR IF IS_PED_COMP_ITEM_CURRENT_SP(PLAYER_PED_ID(), COMP_TYPE_SPECIAL, SPECIAL_P2_PARACHUTE) SET_PED_COMP_ITEM_CURRENT_SP(PLAYER_PED_ID(), COMP_TYPE_SPECIAL, SPECIAL_P2_DUMMY) ENDIF BREAK ENDSWITCH ENDIF // Clear area around player IF bClearPeds = TRUE CLEAR_AREA_OF_PEDS(GET_PLAYER_COORDS(GET_PLAYER_INDEX()), 50.0) ENDIF // Clear the cut-scene area of objects IF bClearObjects = TRUE CLEAR_AREA_OF_OBJECTS(vTriggerLocation, 30.0) ENDIF // Clear fires IF bExtinguishFires STOP_FIRE_IN_RANGE(vTriggerLocation, 30.0) ENDIF // Clear projectiles CLEAR_AREA_OF_PROJECTILES(vTriggerLocation, 30.0) // Clear the player's wanted level SET_PLAYER_WANTED_LEVEL(pId,0) SET_PLAYER_WANTED_LEVEL_NOW(pId) // Stop anyone from attacking the player SET_EVERYONE_IGNORE_PLAYER(pId, TRUE) // Remove radar and HUD IF bHideHUDRadar DISPLAY_RADAR(FALSE) DISPLAY_HUD(FALSE) ENDIF // Clear objective and help text CLEAR_PRINTS() IF bClearHelp = TRUE CLEAR_HELP() ENDIF // Widescreen borders option IF bUseWidescreenBorders = TRUE SET_WIDESCREEN_BORDERS(TRUE, 0) ENDIF // Automatically put the player's weapon away IF bPutPlayerWeaponAway = TRUE mPlayerWeapon = WEAPONTYPE_INVALID if IS_ENTITY_ALIVE(PLAYER_PED_ID()) // remove player's weapon mPlayerWeapon = GET_SELECTED_PED_WEAPON(PLAYER_PED_ID()) // store current weapon SET_CURRENT_PED_WEAPON(PLAYER_PED_ID(), WEAPONTYPE_UNARMED, TRUE) ENDIF ENDIF IF bFadeIn = TRUE SAFE_FADE_SCREEN_IN_FROM_BLACK(500, FALSE) ENDIF ENDIF ENDPROC /// PURPOSE: /// Handles exiting cutscenes. /// shows radar + HUD, Clears Help, turns player control back on, re-enables phone /// Puts widescreen borders off, handles re-eqipping player's weapon /// PARAMS: /// bUseWidescreenBorders - TRUE turn widescreen borders off /// bReEquipPlayerWeapon - TRUE = reequip the weapon the player had before the cut-scene PROC RC_END_CUTSCENE_MODE(BOOL bUseWidescreenBorders = TRUE, BOOL bReEquipPlayerWeapon= TRUE, BOOL bDisplayHudAndRadar= TRUE, BOOL bRestorePlayerControl = TRUE) PLAYER_INDEX pId = GET_PLAYER_INDEX() CPRINTLN(DEBUG_MISSION, "RC_END_CUTSCENE_MODE") SET_EVERYONE_IGNORE_PLAYER(pId, FALSE) SET_PLAYER_CONTROL(pId, bRestorePlayerControl) SET_SCRIPTS_SAFE_FOR_CUTSCENE(FALSE,DEFAULT,FALSE) IF bDisplayHudAndRadar= TRUE DISPLAY_RADAR(TRUE) DISPLAY_HUD(TRUE) ENDIF CLEAR_HELP() IF bUseWidescreenBorders = TRUE SET_WIDESCREEN_BORDERS(FALSE, 0) ENDIF IF bReEquipPlayerWeapon = TRUE IF mPlayerWeapon <> WEAPONTYPE_INVALID AND mPlayerWeapon <> WEAPONTYPE_OBJECT AND mPlayerWeapon <> GADGETTYPE_PARACHUTE if IS_ENTITY_ALIVE(PLAYER_PED_ID()) // put player's stored weapon back in his hand IF HAS_PED_GOT_WEAPON(PLAYER_PED_ID(), mPlayerWeapon) SET_CURRENT_PED_WEAPON(PLAYER_PED_ID(), mPlayerWeapon, FALSE) ENDIF ENDIF ENDIF ENDIF IF IS_PED_UNINJURED(PLAYER_PED_ID()) //B*1057583 wrapped in an alive check SET_PED_STEALTH_MOVEMENT(PLAYER_PED_ID(), FALSE) // B*1052570 Ensure stealth mode has been cancelled ENDIF ENDPROC /// PURPOSE: /// Sets proofs for RCM entities and the player PROC RC_SET_ENTITY_PROOFS_FOR_CUTSCENE(g_structRCScriptArgs& sData, BOOL bProof, BOOL bHolsterWeapon=TRUE) INT i CPRINTLN(DEBUG_RANDOM_CHAR, "RC_SET_ENTITY_PROOFS_FOR_CUTSCENE called with bProof = ", bProof) // Scene peds REPEAT RC_MAX_SCENE_PEDS i IF IS_ENTITY_ALIVE(sData.pedID[i]) SET_ENTITY_PROOFS(sData.pedID[i], bProof, bProof, bProof, bProof, bProof) ENDIF ENDREPEAT // Scene vehicles REPEAT RC_MAX_SCENE_VEHS i IF IS_ENTITY_ALIVE(sData.vehID[i]) SET_ENTITY_PROOFS(sData.vehID[i], bProof, bProof, bProof, bProof, bProof) ENDIF ENDREPEAT // Scene objects REPEAT RC_MAX_SCENE_OBJS i IF IS_ENTITY_ALIVE(sData.objID[i]) SET_ENTITY_PROOFS(sData.objID[i], bProof, bProof, bProof, bProof, bProof) ENDIF ENDREPEAT // Set player proofs. IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID()) SET_ENTITY_PROOFS(PLAYER_PED_ID(), bProof, bProof, bProof, bProof, bProof) SET_ENTITY_INVINCIBLE(PLAYER_PED_ID(), bProof) IF bHolsterWeapon SET_CURRENT_PED_WEAPON(PLAYER_PED_ID(), WEAPONTYPE_UNARMED, TRUE) ENDIF ENDIF ENDPROC /// PURPOSE: /// Disables attack, weapon select and certain movement controls when about to trigger a cutscene PROC RC_DISABLE_CONTROL_ACTIONS_FOR_LEAD_IN() DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_SPRINT) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_SELECT_WEAPON) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_AIM) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_MELEE_ATTACK_HEAVY) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_MELEE_ATTACK_LIGHT) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_ATTACK) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_ATTACK2) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_JUMP) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_ENTER) ENDPROC /// PURPOSE: /// Gets the player out of vehicle when triggering a lead-in animation PROC RC_EXIT_VEHICLE_FOR_LEAD_IN() IF IS_PLAYER_PLAYING(PLAYER_ID()) IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) IF BRING_VEHICLE_TO_HALT_AND_DISABLE_VEH_CONTROLS(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()), DEFAULT_VEH_STOPPING_DISTANCE, 1) //stopping dist increase for B*113835 IF (GET_SCRIPT_TASK_STATUS(PLAYER_PED_ID(), SCRIPT_TASK_LEAVE_ANY_VEHICLE) <> PERFORMING_TASK) TASK_LEAVE_ANY_VEHICLE(PLAYER_PED_ID()) ENDIF ENDIF ENDIF ENDIF ENDPROC /// PURPOSE: /// Disable certain player controls and force player to exit vehicle PROC RC_PLAYER_TRIGGER_SCENE_LOCK_IN() DISABLE_CELLPHONE_THIS_FRAME_ONLY() RC_DISABLE_CONTROL_ACTIONS_FOR_LEAD_IN() RC_EXIT_VEHICLE_FOR_LEAD_IN() ENDPROC /// PURPOSE: /// Tests if a ped is either performing a script task or is waiting to start it /// PARAMS: /// testPed - the ped to test /// testTask - the script task to check for /// RETURNS: /// TRUE if the ped is performing the task or waiting to start it, FALSE otherwise FUNC BOOL IsPedPerformingTask(PED_INDEX testPed, SCRIPT_TASK_NAME testTask) IF IS_PED_UNINJURED(testPed) IF (GET_SCRIPT_TASK_STATUS(testPed, testTask) = PERFORMING_TASK) OR (GET_SCRIPT_TASK_STATUS(testPed, testTask) = WAITING_TO_START_TASK) RETURN TRUE ENDIF ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// Handles delaying a cutscene until it's loaded, the last line of dialogue has finished, and the player's car has been halted. /// PARAMS: /// check_for_cutscene_loaded - if true waits on mocap being loaded /// stopping_distance - for vehicles, need to use DEFAULT_VEH_STOPPING_DISTANCE unless special case /// b_player_exit_vehicle - make the player leave the vehicle once it's stopped /// RETURNS: /// TRUE once all conditions are met FUNC BOOL RC_IS_CUTSCENE_OK_TO_START(BOOL check_for_cutscene_loaded = TRUE, FLOAT stopping_distance = DEFAULT_VEH_STOPPING_DISTANCE, BOOL b_player_exit_vehicle = FALSE) // See B*649704 - we need to do all this stuff rather than return false as soon as a condition returns false BOOL b_cutscene_ok_to_start = TRUE IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) IF NOT IS_PED_IN_ANY_HELI(PLAYER_PED_ID()) AND NOT IS_PED_IN_ANY_BOAT(PLAYER_PED_ID()) AND NOT IS_PED_IN_ANY_PLANE(PLAYER_PED_ID()) IF NOT BRING_VEHICLE_TO_HALT_AND_DISABLE_VEH_CONTROLS(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()), stopping_distance, 1) b_cutscene_ok_to_start = FALSE ELSE // Vehicle has stopped IF b_player_exit_vehicle = TRUE b_cutscene_ok_to_start = FALSE IF NOT IsPedPerformingTask(PLAYER_PED_ID(), SCRIPT_TASK_LEAVE_ANY_VEHICLE) TASK_LEAVE_ANY_VEHICLE(PLAYER_PED_ID()) ENDIF ENDIF ENDIF IF IS_ENTITY_IN_AIR(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID())) b_cutscene_ok_to_start = FALSE ENDIF ENDIF ENDIF // Disable attack controls RC_DISABLE_CONTROL_ACTIONS_FOR_LEAD_IN() IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() KILL_ANY_CONVERSATION() b_cutscene_ok_to_start = FALSE ENDIF IF b_cutscene_ok_to_start = FALSE RETURN FALSE ENDIF // B*1521696 - swap over from HAS_CUTSCENE_LOADED // HAS_CUTSCENE_LOADED_WITH_FAILSAFE()- Ensure you are only calling this check when your script is ready to play the cutscene IF check_for_cutscene_loaded = TRUE IF NOT HAS_CUTSCENE_LOADED_WITH_FAILSAFE() RETURN FALSE ENDIF ENDIF // Double check to make sure any conversations are killed when the function is returning TRUE IF IS_SCRIPTED_CONVERSATION_ONGOING() STOP_SCRIPTED_CONVERSATION(FALSE) ENDIF RETURN TRUE ENDFUNC // --------------------------------------------------------------------------------------------- // -----------------CLEAN UP FUNCTIONS---------------------------------------------------------------- // --------------------------------------------------------------------------------------------- /// PURPOSE: /// If a mocap cut-scene is active it will be stopped. Waits here until it has stopped. /// This procedure is useful when debug passing / failing a mission while a mocap is playing /// PARAMS: /// bCall_RC_END_CUTSCENE_MODE - if TRUE RC_END_CUTSCENE_MODE will be called. Parameter added so proc can be called by RC_START_Z_SKIP /// bUseWidescreenBorders - TRUE turn widescreen borders off. Note: requires bCall_RC_END_CUTSCENE_MODE = TRUE to take affect /// bReEquipPlayerWeapon - TRUE = reequip the weapon the player had before the cut-scene. Note: requires bCall_RC_END_CUTSCENE_MODE = TRUE to take affect PROC WAIT_FOR_CUTSCENE_TO_STOP(BOOL bCall_RC_END_CUTSCENE_MODE = TRUE, BOOL bUseWidescreenBorders = TRUE, BOOL bReEquipPlayerWeapon = TRUE) BOOL bLoop = TRUE IF IS_CUTSCENE_ACTIVE() WHILE (bLoop) bLoop = IS_CUTSCENE_ACTIVE() IF IS_CUTSCENE_PLAYING() STOP_CUTSCENE() ENDIF IF HAS_CUTSCENE_LOADED() REMOVE_CUTSCENE() ENDIF IF IS_CUTSCENE_ACTIVE() AND NOT IS_CUTSCENE_PLAYING() CPRINTLN(DEBUG_MISSION, "WAITING FOR CUTSCENE TO STOP - EMERGENCY BREAK OUT!") bLoop = FALSE ENDIF CPRINTLN(DEBUG_MISSION, "WAITING FOR CUTSCENE TO STOP") WAIT(0) ENDWHILE IF bCall_RC_END_CUTSCENE_MODE RC_END_CUTSCENE_MODE(bUseWidescreenBorders, bReEquipPlayerWeapon) ENDIF ENDIF ENDPROC /// PURPOSE: /// Deletes the vehicle if it exists, and player isn't in it /// PARAMS: /// mVehicle - the vehicle to delete PROC SAFE_DELETE_VEHICLE(VEHICLE_INDEX &mVehicle) IF DOES_ENTITY_EXIST(mVehicle) IF NOT IS_ENTITY_A_MISSION_ENTITY(mVehicle) SET_ENTITY_AS_MISSION_ENTITY(mVehicle) ENDIF IF IS_VEHICLE_OK(mVehicle) IF IS_ENTITY_A_MISSION_ENTITY(mVehicle) AND DOES_ENTITY_BELONG_TO_THIS_SCRIPT(mVehicle) IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), mVehicle) SET_VEHICLE_AS_NO_LONGER_NEEDED(mVehicle) // player is in the vehicle- don't delete it EXIT ENDIF ENDIF DELETE_VEHICLE(mVehicle) ENDIF ELSE IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), mVehicle) SET_VEHICLE_AS_NO_LONGER_NEEDED(mVehicle) // player is in the vehicle- don't delete it EXIT ENDIF ENDIF DELETE_VEHICLE(mVehicle) ENDIF ENDIF ENDPROC /// PURPOSE: /// If a vehicle exists it is set as no longer needed /// PARAMS: /// mVehicle - the vehicle we are releasing PROC SAFE_RELEASE_VEHICLE(VEHICLE_INDEX &mVehicle) IF DOES_ENTITY_EXIST(mVehicle) IS_ENTITY_DEAD(mVehicle) // we need call this or we get an assert... IF IS_ENTITY_A_MISSION_ENTITY(mVehicle) AND DOES_ENTITY_BELONG_TO_THIS_SCRIPT(mVehicle) SET_VEHICLE_AS_NO_LONGER_NEEDED(mVehicle) ENDIF ENDIF /* IF DOES_ENTITY_EXIST(mVehicle) IF IS_VEHICLE_OK(mVehicle) IF IS_ENTITY_A_MISSION_ENTITY(mVehicle) AND DOES_ENTITY_BELONG_TO_THIS_SCRIPT(mVehicle) SET_VEHICLE_AS_NO_LONGER_NEEDED(mVehicle) ENDIF ELSE SET_VEHICLE_AS_NO_LONGER_NEEDED(mVehicle) ENDIF ENDIF */ ENDPROC /// PURPOSE: /// If ped exists it is deleted /// PARAMS: /// mPed - ped to delete PROC SAFE_DELETE_PED(ped_index &mPed) IF DOES_ENTITY_EXIST(mPed) IF NOT IS_ENTITY_DEAD(mPed) SET_ENTITY_LOAD_COLLISION_FLAG(mPed, FALSE) ENDIF IF NOT IS_ENTITY_A_MISSION_ENTITY(mPed) SET_ENTITY_AS_MISSION_ENTITY(mPed) ENDIF DELETE_PED(mPed) ENDIF ENDPROC /// PURPOSE: /// If a ped exists it is set as no longer needed /// PARAMS: /// mPed - ped to release /// bKeepTask - whether or not the ped should keep its current task /// /// bKeepSecondaryTask - whether or not the ped should keep it's secondary task PROC SAFE_RELEASE_PED(PED_INDEX &mPed, BOOL bKeepTask = TRUE, BOOL bResetTempEvents = FALSE, BOOL bKeepSecondaryTask = TRUE) IF DOES_ENTITY_EXIST(mPed) IF NOT IS_PED_INJURED(mPed) SET_ENTITY_LOAD_COLLISION_FLAG(mPed, FALSE) IF bKeepSecondaryTask = FALSE CLEAR_PED_SECONDARY_TASK(mPed) // fix for B*951280 ENDIF SET_PED_KEEP_TASK(mPed, bKeepTask) IF bResetTempEvents = TRUE SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(mPed, FALSE) ENDIF ENDIF SET_PED_AS_NO_LONGER_NEEDED(mPed) ENDIF ENDPROC /// PURPOSE: /// If the object exists it is deleted /// PARAMS: /// mObject - the object to delete PROC SAFE_DELETE_OBJECT(OBJECT_INDEX &mObject) IF DOES_ENTITY_EXIST(mObject) IF IS_ENTITY_ATTACHED_TO_ANY_PED(mObject) DETACH_ENTITY(mObject) ENDIF DELETE_OBJECT(mObject) ENDIF ENDPROC /// PURPOSE: /// If the object exists it is released /// PARAMS: /// mObject - the object to release /// bwaitForRange - wait till player is out of range to clean up object PROC SAFE_RELEASE_OBJECT(OBJECT_INDEX &mObject,bool bwaitForRange = false) IF DOES_ENTITY_EXIST(mObject) IF IS_ENTITY_ATTACHED_TO_ANY_PED(mObject) DETACH_ENTITY(mObject) ENDIF if not bwaitForRange SET_OBJECT_AS_NO_LONGER_NEEDED(mObject) else ONLY_CLEAN_UP_OBJECT_WHEN_OUT_OF_RANGE(mObject) endif ENDIF ENDPROC /// PURPOSE: /// remove blip from the game, setting the route to false in the process /// PARAMS: /// blipIndex - blip to remove PROC SAFE_REMOVE_BLIP(BLIP_INDEX &blipIndex) IF DOES_BLIP_EXIST(blipIndex) SET_BLIP_ROUTE(blipIndex, FALSE) REMOVE_BLIP(blipIndex) ENDIF ENDPROC /// PURPOSE: /// If the pickup exists it is removed /// PARAMS: /// pickupIndex - pickup to remove PROC SAFE_REMOVE_PICKUP(PICKUP_INDEX &pickupIndex) IF DOES_PICKUP_EXIST(pickupIndex) REMOVE_PICKUP(pickupIndex) ENDIF ENDPROC // --------------------------------------------------------------------------------------------- // -----------------LAUNCHER CLEANUP FUNCTIONS-------------------------------------------------- // --------------------------------------------------------------------------------------------- /// PURPOSE: /// Cleans up an array of peds /// PARAMS: /// array - the array of peds /// bDeletePeds - if true we delete peds, if false we release them PROC RC_CleanupPedArray(PED_INDEX& array[],BOOL bDeletePeds) INT i = 0 FOR i=0 TO COUNT_OF(array) - 1 IF bDeletePeds = TRUE SAFE_DELETE_PED(array[i]) ELSE SAFE_RELEASE_PED(array[i], FALSE, TRUE, FALSE) ENDIF ENDFOR ENDPROC /// PURPOSE: /// Cleans up an array of vehicles /// PARAMS: /// array - the array of vehicles /// bDeleteVehicles - if true we delete vehicles, if false we release them PROC RC_CleanupVehicleArray(VEHICLE_INDEX& array[],BOOL bDeleteVehicles) INT i = 0 FOR i=0 TO COUNT_OF(array) - 1 IF bDeleteVehicles SAFE_DELETE_VEHICLE(array[i]) ELSE SAFE_RELEASE_VEHICLE(array[i]) ENDIF ENDFOR ENDPROC /// PURPOSE: /// Cleans up an array of props /// PARAMS: /// array - the array of props /// bDeleteObjects - if true we delete props, if false we release them PROC RC_CleanupPropArray(OBJECT_INDEX& array[],BOOL bDeleteObjects) INT i = 0 FOR i=0 TO COUNT_OF(array) - 1 IF bDeleteObjects SAFE_DELETE_OBJECT(array[i]) ELSE SAFE_RELEASE_OBJECT(array[i]) ENDIF ENDFOR ENDPROC /// PURPOSE: /// Cleans up the array of initial scene peds /// PARAMS: /// sData - mission data struct /// bDeletePeds - if true we delete the peds, if false we release them PROC RC_CleanupScene_PEDS(g_structRCScriptArgs& sData, BOOL bDeletePeds) RC_CleanupPedArray(sData.pedID, bDeletePeds) ENDPROC /// PURPOSE: /// Cleans up the array of initial scene vehicles /// PARAMS: /// sData - mission data struct /// bDeleteVehicles - if true we delete the vehicles, if false we release them PROC RC_CleanupScene_VEHICLES(g_structRCScriptArgs& sData, BOOL bDeleteVehicles) RC_CleanupVehicleArray(sData.vehID, bDeleteVehicles) ENDPROC /// PURPOSE: /// Cleans up the array of initial scene props /// PARAMS: /// sData - mission data struct /// bDeleteObjects - if true we delete the props, if false we release them PROC RC_CleanupScene_PROPS(g_structRCScriptArgs& sData, BOOL bDeleteObjects) RC_CleanupPropArray(sData.objID, bDeleteObjects) ENDPROC /// PURPOSE: /// Cleans up all entities within the scene data /// PARAMS: /// sData - mission data struct /// bDeletePeds - if true we delete the peds, if false we release them /// bDeleteVehicles - if true we delete the vehicles, if false we release them /// bDeleteObjects - if true we delete the props, if false we release them PROC RC_CleanupSceneEntities(g_structRCScriptArgs& sData, BOOL bDeletePeds=TRUE, BOOL bDeleteVehicles= FALSE, BOOL bDeleteObjects=FALSE) RC_CleanupScene_PEDS(sData, bDeletePeds) RC_CleanupScene_VEHICLES(sData, bDeleteVehicles) RC_CleanupScene_PROPS(sData, bDeleteObjects) ENDPROC /// PURPOSE: /// Sets array of entities to be mission entities /// PARAMS: /// array - the array of entities PROC RC_TakeOwnershipArray(ENTITY_INDEX& array[]) INT i = 0 // Pass over all entities FOR i=0 TO COUNT_OF(array) - 1 IF DOES_ENTITY_EXIST(array[i]) SET_ENTITY_AS_MISSION_ENTITY(array[i], FALSE, TRUE) ENDIF ENDFOR ENDPROC /// PURPOSE: /// Sets all of the initial scene entities as mission entities and then cleans up the launcher PROC RC_TakeEntityOwnership(g_structRCScriptArgs& sMissionData) // Pass over entities to mission RC_TakeOwnershipArray(sMissionData.pedID) RC_TakeOwnershipArray(sMissionData.vehID) RC_TakeOwnershipArray(sMissionData.objID) ENDPROC // --------------------------------------------------------------------------------------------- // -----------------BLIP FUNCTIONS-------------------------------------------------------------- // --------------------------------------------------------------------------------------------- /// PURPOSE: /// Adds a blip for a ped. /// Checks if the ped is alive and whether he needs to be blipped based on blip standards. /// Sets the correct size and colour of blip based on input variables. /// PARAMS: /// iPed - the ped we are adding a blip for /// bCritical - whether or not the ped is mission critical /// bFriendly - is the ped friendly or an enemy /// bBlipPriority - priority of the blip /// RETURNS: /// the blip index of the new blip (null if blip was not created) FUNC BLIP_INDEX CREATE_PED_BLIP(PED_INDEX iPed, BOOL bCritical=TRUE, BOOL bFriendly=FALSE, BLIP_PRIORITY bBlipPriority=BLIPPRIORITY_MED) BLIP_INDEX bRetBlip = NULL BOOL bShouldCreate = TRUE IF bShouldCreate IF IS_ENTITY_ALIVE(iPed) bRetBlip = ADD_BLIP_FOR_ENTITY(iPed) SET_BLIP_AS_FRIENDLY(bRetBlip,bFriendly) SET_BLIP_PRIORITY(bRetBlip,bBlipPriority) SET_BLIP_SCALE(bRetBlip, BLIP_SIZE_PED) IF NOT bCritical SET_BLIP_SCALE(bRetBlip, 0.5) ENDIF ENDIF ENDIF RETURN bRetBlip ENDFUNC /// PURPOSE: /// Add a blip for a vehicle. /// checks the vehicle is alive, then creates blip of correct size and colour /// PARAMS: /// iVeh - the vehicle we're adding a blip for /// bFriendly - whether the vehicle is friendly or an enemy /// bBlipPriority - priority of the blip /// RETURNS: /// the blip index of the new blip (null if blip was not created) FUNC BLIP_INDEX CREATE_VEHICLE_BLIP(VEHICLE_INDEX iVeh,BOOL bFriendly=TRUE, BLIP_PRIORITY bBlipPriority=BLIPPRIORITY_MED) BLIP_INDEX bRetBlip = NULL IF IS_ENTITY_ALIVE(iVeh) //Ensure the entity is alive bRetBlip = ADD_BLIP_FOR_ENTITY(iVeh) SET_BLIP_AS_FRIENDLY(bRetBlip,bFriendly) SET_BLIP_PRIORITY(bRetBlip,bBlipPriority) SET_BLIP_SCALE(bRetBlip, BLIP_SIZE_VEHICLE) ENDIF RETURN bRetBlip ENDFUNC /// PURPOSE: /// Creates a blip of the correct size and colour for a location /// PARAMS: /// vPos - where to create the blip /// bBlipPriority - priority of the blip /// bDisplayRoute - do we want to add a route for this blip? /// RETURNS: /// the blip index of the new blip (null if blip was not created) FUNC BLIP_INDEX CREATE_COORD_BLIP(VECTOR vPos, BLIP_PRIORITY bBlipPriority=BLIPPRIORITY_MED, BOOL bDisplayRoute = TRUE) BLIP_INDEX bRetBlip = NULL bRetBlip = ADD_BLIP_FOR_COORD(vPos) SET_BLIP_PRIORITY(bRetBlip,bBlipPriority) SET_BLIP_SCALE(bRetBlip, BLIP_SIZE_COORD) SET_BLIP_ROUTE(bRetBlip, bDisplayRoute) RETURN bRetBlip ENDFUNC /// PURPOSE: /// Sets up everything so that blips and text will change colour nicely /// This is used when the player has a choice between killing a ped and letting them go /// Call this function the frame before calling FLASH_BLIP_AND_TEXT /// PARAMS: /// thisBlip - the blip whose colour you want to flash /// sTextRed - the text string with the ped's name in red /// sTextBlue - the text string with the ped's name in blue /// fbtTimer - keeps track of when to change colour /// fbtTextTimer - keeps track of how long the text has been displayed /// redTextFirst - TRUE if you want the blip/text to be initialised to red, FALSE if you want them blue /// showText - TRUE if you want to link with an objective, FALSE if not PROC INIT_FLASH_BLIP_AND_TEXT(BLIP_INDEX &thisBlip, STRING sTextRed, STRING sTextBlue, INT &fbtTimer, INT &fbtTextTimer, BOOL redTextFirst = TRUE, BOOL showText = TRUE) IF DOES_BLIP_EXIST(thisBlip) IF redTextFirst SET_BLIP_COLOUR(thisBlip, BLIP_COLOUR_RED) SET_BLIP_NAME_FROM_TEXT_FILE(thisBlip, "BLIP_ENEMY") IF showText AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF NOT IS_MESSAGE_BEING_DISPLAYED() OR IS_THIS_PRINT_BEING_DISPLAYED(sTextBlue) PRINT_NOW(sTextRed, DEFAULT_GOD_TEXT_TIME, 0) ENDIF ENDIF ELSE SET_BLIP_COLOUR(thisBlip, BLIP_COLOUR_BLUE) SET_BLIP_NAME_FROM_TEXT_FILE(thisBlip, "BLIP_FRIEND") IF showText AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF NOT IS_MESSAGE_BEING_DISPLAYED() OR IS_THIS_PRINT_BEING_DISPLAYED(sTextRed) PRINT_NOW(sTextBlue, DEFAULT_GOD_TEXT_TIME, 0) ENDIF ENDIF ENDIF fbtTimer = GET_GAME_TIMER() fbtTextTimer = GET_GAME_TIMER() ENDIF ENDPROC /// PURPOSE: /// Switches a blip and accompanying god text between red and blue /// This is used when the player has a choice between killing a ped and letting them go /// Call this function every frame for as long as you want the colour to flash /// Before going into the loop that calls this function, call INIT_FLASH_BLIP_AND_TEXT for best results /// If you don't want to use INIT_FLASH_BLIP_AND_TEXT, make sure the text and blip are the same colour and that fbtTimer has been set equal to GET_GAME_TIMER /// PARAMS: /// thisBlip - the blip whose colour you want to flash /// sTextRed - the text string with the ped's name in red /// sTextBlue - the text string with the ped's name in blue /// fbtTimer - keeps track of when to change colour /// fbtTextTimer - keeps track of how long the text has been displayed /// showText - TRUE if you want to link with an objective, FALSE if not PROC FLASH_BLIP_AND_TEXT(BLIP_INDEX &thisBlip, STRING sTextRed, STRING sTextBlue, INT &fbtTimer, INT fbtTextTimer, BOOL showText = TRUE) IF DOES_BLIP_EXIST(thisBlip) IF (GET_GAME_TIMER() - fbtTimer) > 500 IF GET_BLIP_COLOUR(thisBlip) = BLIP_COLOUR_RED SET_BLIP_COLOUR(thisBlip, BLIP_COLOUR_BLUE) SET_BLIP_NAME_FROM_TEXT_FILE(thisBlip, "BLIP_FRIEND") IF (GET_GAME_TIMER() - fbtTextTimer) < DEFAULT_GOD_TEXT_TIME AND showText IF NOT IS_MESSAGE_BEING_DISPLAYED() OR IS_THIS_PRINT_BEING_DISPLAYED(sTextRed) PRINT_NOW(sTextBlue, DEFAULT_GOD_TEXT_TIME, 0) ENDIF ENDIF fbtTimer = GET_GAME_TIMER() ELSE SET_BLIP_COLOUR(thisBlip, BLIP_COLOUR_RED) SET_BLIP_NAME_FROM_TEXT_FILE(thisBlip, "BLIP_ENEMY") IF (GET_GAME_TIMER() - fbtTextTimer) < DEFAULT_GOD_TEXT_TIME AND showText IF NOT IS_MESSAGE_BEING_DISPLAYED() OR IS_THIS_PRINT_BEING_DISPLAYED(sTextBlue) PRINT_NOW(sTextRed, DEFAULT_GOD_TEXT_TIME, 0) ENDIF ENDIF fbtTimer = GET_GAME_TIMER() ENDIF ENDIF ENDIF IF (GET_GAME_TIMER() - fbtTextTimer) > DEFAULT_GOD_TEXT_TIME // Text has been displayed for long enough, get rid of it if necessary IF IS_THIS_PRINT_BEING_DISPLAYED(sTextRed) CLEAR_THIS_PRINT(sTextRed) ENDIF IF IS_THIS_PRINT_BEING_DISPLAYED(sTextBlue) CLEAR_THIS_PRINT(sTextBlue) ENDIF ENDIF ENDPROC /// PURPOSE: /// Creates a coordinate blip at an entity's position then updates it each frame relative to the entity's new position /// Use for entities that might need to be warped, the blip's position will move smoothly from the old position to the new /// PARAMS: /// iEntity - The entity that needs blipping /// iBlip - The blip index, this should be empty when first calling the function /// bFriendly - Is the entity being blipped friendly or not /// fSlidyFactor - How quickly the blip will slide to catch up with the entity PROC MANAGE_SLIDY_BLIP_FOR_ENTITY(BLIP_INDEX & biBlip, ENTITY_INDEX eiEntity, BOOL bFriendly = FALSE, FLOAT fSlidyFactor = 10.0, BOOL bAllowCreateBlip = TRUE) IF bAllowCreateBlip = TRUE AND NOT DOES_BLIP_EXIST(biBlip) biBlip = CREATE_BLIP_FOR_COORD(GET_ENTITY_COORDS(eiEntity)) IF bFriendly SET_BLIP_COLOUR(biBlip, BLIP_COLOUR_BLUE) SET_BLIP_NAME_FROM_TEXT_FILE(biBlip, "BLIP_FRIEND") ELSE SET_BLIP_COLOUR(biBlip, BLIP_COLOUR_RED) SET_BLIP_NAME_FROM_TEXT_FILE(biBlip, "BLIP_ENEMY") ENDIF IF IS_ENTITY_A_PED(eiEntity) SET_BLIP_SCALE(biBlip, BLIP_SIZE_PED) ENDIF ENDIF IF DOES_BLIP_EXIST(biBlip) VECTOR vBlipPosition = GET_BLIP_COORDS(biBlip) VECTOR vEntityPosition = GET_ENTITY_COORDS(eiEntity) vBlipPosition.X = vBlipPosition.X + ((vEntityPosition.X - vBlipPosition.X) / fSlidyFactor) vBlipPosition.Y = vBlipPosition.Y + ((vEntityPosition.Y - vBlipPosition.Y) / fSlidyFactor) vBlipPosition.Z = vBlipPosition.Z + ((vEntityPosition.Z - vBlipPosition.Z) / fSlidyFactor) SET_BLIP_COORDS(biBlip, vBlipPosition) ENDIF ENDPROC // --------------------------------------------------------------------------------------------- // ----------------- INITIAL SCENE SETUP---------------------------------------------------------------- // --------------------------------------------------------------------------------------------- /// PURPOSE: /// Creates the NPC ped needed for this mission, sets their debug name and blocks temp events /// Doesn't allow player to target the NPC /// PARAMS: /// mPed - ped index you want to use /// ePed - the contact character /// vPos - where to create the NPC /// fHeading - NPC's start heading /// sDebugName - NPC's debug name /// bFriendly - is the NPC friendly to the player [if so, he cannot be targetted]- defaults to true. /// RETURNS: /// true if the ped was created, false otherwise. should be called repeatedly until returns true. FUNC BOOL RC_CREATE_NPC_PED(PED_INDEX& mPed, enumCharacterList ePed, VECTOR vPos, FLOAT fHeading, STRING sDebugName, BOOL bFriendly=TRUE) IF CREATE_NPC_PED_ON_FOOT(mPed, ePed, vPos, fHeading, TRUE) IF DOES_ENTITY_EXIST(mPed) IF NOT IS_ENTITY_DEAD(mPed) SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(mPed, TRUE) SET_PED_MONEY(mPed, 0) IF bFriendly = TRUE SET_PED_CAN_BE_TARGETTED(mPed, FALSE) ENDIF ENDIF SET_PED_NAME_DEBUG(mPed, sDebugName) ENDIF RETURN TRUE // succesfully created NPC ped ENDIF RETURN FALSE // Failed to create NPC ped ENDFUNC /// PURPOSE: /// Creates a vehicle and sets it on the ground properly /// PARAMS: /// mVehicle - Vehicle index of the vehicle we are creating /// model - model of the vehicle /// vPos - where to create it /// fHeading - heading to create it with PROC CREATE_SCENE_VEHICLE(VEHICLE_INDEX &mVehicle, MODEL_NAMES model, VECTOR vPos, FLOAT fHeading) SAFE_DELETE_VEHICLE(mVehicle) mVehicle = CREATE_VEHICLE(model, vPos, fHeading) IF DOES_ENTITY_EXIST(mVehicle) SET_VEHICLE_ON_GROUND_PROPERLY(mVehicle) SET_ENTITY_HEALTH(mVehicle, 1000) // Required because CHECK_VEHICLES_OK in rc_launcher_public checks for the health being less than 990, if so player has tampered with scene ENDIF ENDPROC /// PURPOSE: /// Creates a ped for initial scene /// PARAMS: /// mPed - ped index of ped we are creating /// model - model to use /// vPos - where to create ped /// fHeading - heading to use /// mPedType - the pedtype to use for this ped. defaults to PEDTYPE_MISSION PROC CREATE_SCENE_PED(PED_INDEX &mPed, MODEL_NAMES model, VECTOR vPos, FLOAT fHeading, PED_TYPE mPedType = PEDTYPE_MISSION) SAFE_DELETE_PED(mPed) mPed = CREATE_PED(mPedType, model, vPos, fHeading, FALSE, FALSE) ENDPROC /// PURPOSE: /// Creates an object for initial scene /// PARAMS: /// mObject - object index of the object we are creating /// model - model to use /// vPos - where to create object /// fHeading - heading to use PROC CREATE_SCENE_PROP(OBJECT_INDEX &mObject, MODEL_NAMES model, VECTOR vPos, FLOAT fHeading) SAFE_DELETE_OBJECT(mObject) mObject = CREATE_OBJECT(model,vPos) SET_ENTITY_HEADING(mObject, fHeading) ENDPROC /// PURPOSE: /// Helper function for creating props in initial scene setups. /// PARAMS: /// mObject - object index of the object we are creatingt /// model - desired prop model /// vPos - location to spawn the prop /// vAngles - euler angles for spawning prop PROC CREATE_SCENE_PROP_WITH_ANGLES(OBJECT_INDEX &mObject, MODEL_NAMES model, VECTOR vPos, VECTOR vAngles) CREATE_SCENE_PROP(mObject, model, vPos, vAngles.z) SET_ENTITY_ROTATION(mObject, vAngles) ENDPROC // Used when making one ped index equal to another. This saves two variables pointing at the same entity. // Helps with cleanup PROC ASSIGN_PED_INDEX(PED_INDEX& target, PED_INDEX& source) target = source source = NULL ENDPROC // Used when making one vehicle index equal to another. This saves two variables pointing at the same entity. // Helps with cleanup PROC ASSIGN_VEHICLE_INDEX(VEHICLE_INDEX& target, VEHICLE_INDEX& source) target = source source = NULL ENDPROC // Used when making one object index equal to another. This saves two variables pointing at the same entity. // Helps with cleanup PROC ASSIGN_OBJECT_INDEX(OBJECT_INDEX& target, OBJECT_INDEX& source) target = source source = NULL ENDPROC // --------------------------------------------------------------------------------------------- // -----------------DEBUG SKIPPING / REPLAYS---------------------------------------------------------- // --------------------------------------------------------------------------------------------- /// PURPOSE: /// Fades screen out, turns player control off, clears prints + wanted level etc /// PURPOSE: /// Setup used when starting a Z skip /// Fades screen out, turns player control off, clears prints + wanted level etc /// PARAMS: /// bForceActiveMocapToStop - parameter added to fix bug 100674. /// bRemovePlayerHelmet - parameter added to override the player's helmet being removed PROC RC_START_Z_SKIP(BOOl bForceActiveMocapToStop = TRUE, BOOL bRemovePlayerHelmet = TRUE) IF bForceActiveMocapToStop WAIT_FOR_CUTSCENE_TO_STOP(FALSE) ENDIF IF NOT IS_SCREEN_FADED_OUT() DO_SCREEN_FADE_OUT(0) ENDIF RC_START_CUTSCENE_MODE(<<0.0,0.0,0.0>>, FALSE, FALSE, FALSE, DEFAULT, DEFAULT, DEFAULT, bRemovePlayerHelmet) CPRINTLN(DEBUG_MISSION,"Z skip started") ENDPROC /// PURPOSE: /// Turns player control back on etc, fades in /// PARAMS: /// bResetCamera - do you want the camera to be reset behind the player /// bFadeBackIn - do you want to fade back in (usually you do) PROC RC_END_Z_SKIP(BOOL bResetCamera = TRUE, BOOL bFadeBackIn = TRUE, BOOL bDisplayHudAndRadar= TRUE) RC_END_CUTSCENE_MODE(FALSE, FALSE, bDisplayHudAndRadar) IF bResetCamera = TRUE SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0) // reset camera behind player SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0) ENDIF IF bFadeBackIn = TRUE SAFE_FADE_SCREEN_IN_FROM_BLACK(500, FALSE) ENDIF CPRINTLN(DEBUG_MISSION,"Z skip finished") ENDPROC // --------------------------------------------------------------------------------------------- // -----------------MISC---------------------------------------------------------------- // --------------------------------------------------------------------------------------------- /// PURPOSE: /// Prints some debug output /// PARAMS: /// sOutput - the string to print PROC PRINT_LAUNCHER_DEBUG(STRING sOutput) IF NOT Is_String_Null_Or_Empty(sOutput) CPRINTLN(DEBUG_RANDOM_CHAR, GET_THIS_SCRIPT_NAME(), ": ", sOutput) ENDIF ENDPROC /// PURPOSE: /// Sets an entities heading to be facing the given coord /// PARAMS: /// entity - the entity to be rotated /// vLookAt - the point the entity should be turned to face PROC SET_ENTITY_FACING(ENTITY_INDEX entity, vector vLookAt) VECTOR vEntity = GET_ENTITY_COORDS(entity) float fAngle float dX = vLookAt.x - vEntity.x float dY = vLookAt.y - vEntity.y if dY != 0 fAngle = ATAN2(dX,dY) ELSE if dX < 0 fAngle = -90 ELSE fAngle = 90 ENDIF ENDIF //flip because for some odd reason the coders think west is a heading of 90 degrees, so this'll match the output of commands such as GET_ENTITY_HEADING() fAngle *= -1.0 SET_ENTITY_HEADING(entity, fAngle) ENDPROC /// PURPOSE: /// Very efficient test for if two entities are with fRange metres of each other /// Will be more efficient than doing IS_ENTITY_AT_ENTITY() /// NOTE: This function doesn't do dead checks to keep it fast, make sure you do them yourself! /// PARAMS: /// e1 - First entity /// e2 - Second entity /// fRange - Test if the entities are this close to each other FUNC BOOL IS_ENTITY_IN_RANGE_ENTITY(ENTITY_INDEX e1, ENTITY_INDEX e2, FLOAT fRange, BOOL bHealthCheck = TRUE) RETURN ( VDIST2(GET_ENTITY_COORDS(e1, bHealthCheck), GET_ENTITY_COORDS(e2, bHealthCheck)) <= fRange*fRange ) ENDFUNC /// PURPOSE: /// Very efficient test for if two entities are with fRange metres of each other /// Will be more efficient than doing IS_ENTITY_AT_ENTITY() /// NOTE: This function doesn't do dead checks to keep it fast, make sure you do them yourself! /// PARAMS: /// e1 - First entity /// e2 - Second entity /// fRange - Test if the entities are this close to each other FUNC BOOL IS_ENTITY_IN_RANGE_COORDS(ENTITY_INDEX e1, VECTOR vCoord, FLOAT fRange, BOOL bDoDeadCheck = TRUE) RETURN ( VDIST2(GET_ENTITY_COORDS(e1, bDoDeadCheck), vCoord) <= fRange*fRange ) ENDFUNC /// PURPOSE: /// Tests the angle of an entity from another entity's forward vector /// Imagine a cone coming out of the front of entity-1, centred on it's forward vector /// If entity-2 is in this cone, the function returns true /// The width of the cone is set by fArc, this is the maximum angle entity-2 can be from entity-1's forward vector /// NOTE: This function doesn't do dead checks to keep it fast, make sure you do them yourself! /// PARAMS: /// e1 - First entity /// e2 - Second entity /// fArc - The maximum angle from e1's forward vector FUNC BOOL IS_ENTITY_IN_ARC_2D(ENTITY_INDEX e1, ENTITY_INDEX e2, FLOAT fArc) VECTOR vForward = GET_ENTITY_FORWARD_VECTOR(e1) VECTOR vTo2 = GET_ENTITY_COORDS(e2) - GET_ENTITY_COORDS(e1) RETURN (((vForward.x*vTo2.x)+(vForward.y*vTo2.y)) / VDIST(vTo2, <<0,0,0>>)) > COS(fArc) ENDFUNC /// PURPOSE: /// Teleports the entity to the desired vector and heading /// PARAMS: /// entity - Entity handle /// vCoord - Vector to teleport the entity to /// fHeading - Heading to set the entity at after the teleport /// bGetGroundZ - Get the ground z for the vCoord prior to performing SET_ENTITY_COORDS /// RETURNS: /// Returns false if entity is dead or if GET_GROUND_Z_FOR_3D_COORD() fails FUNC BOOL SAFE_TELEPORT_ENTITY(ENTITY_INDEX entity, VECTOR vCoord, FLOAT fHeading = 0.0, BOOL bGetGroundZ = FALSE, BOOL bDoWarp = TRUE) BOOL groundCheckOk = FALSE IF IS_ENTITY_ALIVE(entity) IF bGetGroundZ = TRUE FLOAT fNewZ = 0.0 groundCheckOk = GET_GROUND_Z_FOR_3D_COORD(vCoord, fNewZ) IF (groundCheckOk) vCoord.z = fNewZ ENDIF ENDIF SET_ENTITY_COORDS(entity, vCoord, DEFAULT, DEFAULT, DEFAULT, bDoWarp) SET_ENTITY_HEADING(entity, fHeading) IF (bGetGroundZ) RETURN groundCheckOk ENDIF RETURN TRUE ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// Tests if a ped is either performing a script task or is waiting to start it /// PARAMS: /// testPed - the ped to test /// testTask - the script task to check for /// RETURNS: /// TRUE if the ped is performing the task or waiting to start it, FALSE otherwise FUNC BOOL HasPedCompletedTask(PED_INDEX testPed, SCRIPT_TASK_NAME testTask) IF IS_PED_UNINJURED(testPed) IF GET_SCRIPT_TASK_STATUS(testPed, testTask) = FINISHED_TASK RETURN TRUE ENDIF ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// Tests if the player is towing a specific vehicle using a tow truck /// PARAMS: /// viTestVehicle - The vehicle that might be getting towed /// RETURNS: /// TRUE if the vehicle is being towed by the player, FALSE otherwise FUNC BOOL IS_PLAYER_TOWING_VEHICLE(VEHICLE_INDEX viTestVehicle) IF IS_PED_UNINJURED(PLAYER_PED_ID()) AND IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) AND IS_VEHICLE_OK(viTestVehicle) VEHICLE_INDEX viPlayer = GET_PLAYERS_LAST_VEHICLE() IF IS_VEHICLE_OK(viPlayer) MODEL_NAMES Mod = GET_ENTITY_MODEL(viPlayer) IF Mod = TOWTRUCK OR Mod = TOWTRUCK2 IF IS_VEHICLE_ATTACHED_TO_TOW_TRUCK(viPlayer, viTestVehicle) RETURN TRUE ENDIF ENDIF ENDIF ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// Tests if the player is using the cargobob as a tow truck /// PARAMS: /// viTestVehicle - The vehicle that might be getting cargobobbed /// RETURNS: /// TRUE if the vehicle is being cargobobbed by the player, FALSE otherwise FUNC BOOL IS_PLAYER_FLYING_WITH_ATTACHED_VEHICLE(VEHICLE_INDEX viTestVehicle) IF IS_PED_UNINJURED(PLAYER_PED_ID()) AND IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) AND IS_VEHICLE_OK(viTestVehicle) VEHICLE_INDEX viPlayer = GET_PLAYERS_LAST_VEHICLE() IF IS_VEHICLE_OK(viPlayer) MODEL_NAMES Mod = GET_ENTITY_MODEL(viPlayer) IF Mod = CARGOBOB OR Mod = CARGOBOB2 OR Mod = CARGOBOB3 IF DOES_CARGOBOB_HAVE_PICK_UP_ROPE(viPlayer) IF IS_VEHICLE_ATTACHED_TO_CARGOBOB(viPlayer, viTestVehicle) RETURN TRUE ENDIF ENDIF ENDIF ENDIF ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// Tests if the player is using the cargobob as a tow truck /// PARAMS: /// viTestVehicle - The vehicle to write to if there is a vehicle attached to the bob /// RETURNS: /// TRUE if any vehicle is being cargobobbed by the player, FALSE otherwise FUNC BOOL IS_PLAYER_FLYING_WITH_ANY_ATTACHED_VEHICLE(VEHICLE_INDEX &viTestVehicle) IF IS_PED_UNINJURED(PLAYER_PED_ID()) AND IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) VEHICLE_INDEX viPlayer = GET_PLAYERS_LAST_VEHICLE() IF IS_VEHICLE_OK(viPlayer) MODEL_NAMES Mod = GET_ENTITY_MODEL(viPlayer) IF Mod = CARGOBOB OR Mod = CARGOBOB2 OR Mod = CARGOBOB3 IF DOES_CARGOBOB_HAVE_PICK_UP_ROPE(viPlayer) ENTITY_INDEX ent = GET_VEHICLE_ATTACHED_TO_CARGOBOB(viPlayer) IF DOES_ENTITY_EXIST(ent) viTestVehicle = GET_VEHICLE_INDEX_FROM_ENTITY_INDEX(ent) IF IS_VEHICLE_OK(viTestVehicle) RETURN TRUE ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// Get Special Ability Bar Amount /// PARAMS: /// None FUNC INT GET_PLAYER_SPECIAL_ABILITY_VALUE() INT iStatValue SWITCH GET_CURRENT_PLAYER_PED_ENUM() CASE CHAR_MICHAEL STAT_GET_INT(SP0_SPECIAL_ABILITY, iStatValue) // Michael BREAK CASE CHAR_FRANKLIN STAT_GET_INT(SP1_SPECIAL_ABILITY, iStatValue) // Franklin BREAK CASE CHAR_TREVOR STAT_GET_INT(SP2_SPECIAL_ABILITY, iStatValue) // Trevor BREAK ENDSWITCH RETURN iStatValue ENDFUNC /// PURPOSE: /// Waits for the world to load in around a given coordinate. /// Call this before fading back in if you teleport the player for a checkpoint restart /// PARAMS: /// vLocation - the location, will usually be the player's location /// fRadius - the radius around the location you need to be loaded, increase this if the world still doesn't properly load /// satDataToLoad - the type of data that needs to be loaded: FLAG_COLLISIONS_MOVER, FLAG_COLLISIONS_WEAPON or FLAG_MAPDATA, can be OR'd together /// iTimeout - how long the function should wait before timing out /// bDisableSwitching - Turns of switching while this is loading /// bDisablePhone - Turns off phone while this is loading PROC WAIT_FOR_WORLD_TO_LOAD(VECTOR vLocation, FLOAT fRadius = 50.0, STREAMVOL_ASSET_TYPES satDataToLoad = FLAG_MAPDATA, INT iTimeout = 5000, BOOL bDisableSwitching = FALSE, BOOL bDisablePhone = FALSE) STREAMVOL_ID streamVolID // ID for camera's stream vol ID streamVolID = STREAMVOL_CREATE_SPHERE(vLocation, fRadius, satDataToLoad) IF STREAMVOL_IS_VALID(streamVolID) INT iWaitTime = GET_GAME_TIMER() + iTimeout WHILE NOT STREAMVOL_HAS_LOADED(streamVolID) AND GET_GAME_TIMER() < iWaitTime CPRINTLN(DEBUG_MISSION, "Loading world") IF (bDisablePhone) DISABLE_CELLPHONE_THIS_FRAME_ONLY() ENDIF IF (bDisableSwitching) DISABLE_SELECTOR_THIS_FRAME() ENDIF WAIT(0) ENDWHILE IF GET_GAME_TIMER() < iWaitTime CPRINTLN(DEBUG_MISSION, "World loaded") ELSE CPRINTLN(DEBUG_MISSION, "World loading timed out") ENDIF STREAMVOL_DELETE(streamVolID) ELSE CPRINTLN(DEBUG_MISSION, "Unable to create the streaming volume, cannot test for the world loading") ENDIF ENDPROC /// PURPOSE: /// Checks the ped and vehicle are alive. /// Unfreezes the ped and puts him in the vehicle. /// PARAMS: /// mPed - ped to put in the vehicle. /// mVehicle - vehicle to put him in. /// seat - the seat the ped will sit in - Az added since we'd don't always want to set the ped as the driver PROC SAFE_SET_PED_INTO_VEHICLE(PED_INDEX mPed, VEHICLE_INDEX mVehicle, VEHICLE_SEAT seat = VS_DRIVER, BOOL bNetworked = FALSE) IF IS_PED_UNINJURED(mPed) IF IS_ENTITY_ALIVE(mVehicle) // unfreeze the ped IF IS_ENTITY_ATTACHED(mPed) IF (bNetworked) IF NETWORK_HAS_CONTROL_OF_ENTITY(GET_ENTITY_ATTACHED_TO(mPed)) FREEZE_ENTITY_POSITION(GET_ENTITY_ATTACHED_TO(mPed), FALSE) ENDIF ELSE FREEZE_ENTITY_POSITION(GET_ENTITY_ATTACHED_TO(mPed), FALSE) ENDIF ELSE FREEZE_ENTITY_POSITION(mPed, FALSE) ENDIF SET_PED_INTO_VEHICLE(mPed, mVehicle, seat) ENDIF ENDIF ENDPROC /// PURPOSE: /// Starts a timer to check if a conversation has failed to trigger /// PARAMS: /// iConvFailedTimer - The timer variable the function uses, initialise this to -1 before calling the function for the first time /// TIME_TO_WAIT - The amount of time the function will wait before returning TRUE, defaults to 5000 milliseconds /// RETURNS: /// TRUE when TIME_TO_WAIT has passed FUNC BOOL CONVERSATION_TIMED_OUT(INT & iConvFailedTimer, INT TIME_TO_WAIT = 5000) IF iConvFailedTimer < 0 iConvFailedTimer = GET_GAME_TIMER() + TIME_TO_WAIT ELIF GET_GAME_TIMER() > iConvFailedTimer RETURN TRUE ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// Makes a ped play a random scream /// using "WAVELOAD_PAIN_MALE" , "SCREAM_TERROR" /// handles male or female variation /// PARAMS: /// mPed - The ped we want to scream /// bUseHighFallScream - if TRUE includes "SUPER_HIGH_FALL" in possible selection PROC MAKE_PED_SCREAM(PED_INDEX mPed, BOOL bUseHighFallScream = TRUE) IF IS_PED_UNINJURED(mPed) STRING sScream INT iRange = 2 IF bUseHighFallScream // only include iRange = 3 ENDIF INT iScream = GET_RANDOM_INT_IN_RANGE(0, iRange) IF iScream = 0 sScream = "SCREAM_PANIC" ELIF iScream = 1 sScream = "SCREAM_TERROR" ELSE sScream = "SUPER_HIGH_FALL" ENDIF IF IS_PED_MALE(mPed) PLAY_PED_AMBIENT_SPEECH_WITH_VOICE(mPed, sScream, "WAVELOAD_PAIN_MALE") ELSE PLAY_PED_AMBIENT_SPEECH_WITH_VOICE(mPed, sScream, "WAVELOAD_PAIN_FEMALE") ENDIF ENDIF ENDPROC /// PURPOSE: /// Generates a scenario blocking area based on a position and a radius /// PARAMS: /// pos - center point /// rad - radius /// RETURNS: /// Scenario Block Index FUNC SCENARIO_BLOCKING_INDEX ADD_SCENARIO_BLOCKING_AREA_FROM_POSITION_AND_RADIUS(VECTOR pos, FLOAT rad) VECTOR rhalf = <> RETURN ADD_SCENARIO_BLOCKING_AREA(pos - rhalf, pos + rhalf) ENDFUNC /// PURPOSE: /// If a scripted conversation is in progress and god text is printed, this will begin the check to avoid the dialogue subtitles overwriting the god text PROC CHECK_CONVERSATION_AND_OBJECTIVE_TEXT_CONFLICT_NOW(RC_CONV_RESTORE_STATE & stateRestoreConversation) IF GET_PROFILE_SETTING(PROFILE_DISPLAY_SUBTITLES) <> 0 // Don't do any checking if the user isn't displaying conversation subtitles anyway AND stateRestoreConversation != RC_CONV_STOP_CURRENT_CONV AND IS_SCRIPTED_CONVERSATION_ONGOING() #IF IS_DEBUG_BUILD CPRINTLN(DEBUG_MISSION, "RC CONV CONFLICTS: Starting check for conversation and objective text conflicts") #ENDIF stateRestoreConversation = RC_CONV_STOP_CURRENT_CONV ENDIF ENDPROC /// PURPOSE: /// If a scripted conversation is in progress and god text is printed, this will stop the check to avoid the dialogue subtitles overwriting the god text PROC STOP_CHECKING_CONVERSATION_AND_OBJECTIVE_TEXT_CONFLICT(RC_CONV_RESTORE_STATE & stateRestoreConversation) IF stateRestoreConversation != RC_CONV_IDLE #IF IS_DEBUG_BUILD CPRINTLN(DEBUG_MISSION, "RC CONV CONFLICTS: Stopping check for conversation and objective text conflicts") #ENDIF stateRestoreConversation = RC_CONV_IDLE ENDIF ENDPROC /// PURPOSE: /// If a scripted conversation is in progress and god text is printed, this will handle stopping & restarting the conversation without subtitles to prevent overwriting the god text, then stopping & restarting with subtitles after the text has cleared. PROC HANDLE_CONVERSATION_AND_OBJECTIVE_TEXT_CONFLICT(RC_CONV_RESTORE_STATE & stateRestoreConversation, structPedsForConversation & sConversationToUse, STRING sTextBlockToUse, TEXT_LABEL_23 & tSavedConversationRoot, TEXT_LABEL_23 & tSavedConversationLabel) SWITCH stateRestoreConversation CASE RC_CONV_IDLE BREAK CASE RC_CONV_STOP_CURRENT_CONV IF IS_SCRIPTED_CONVERSATION_ONGOING() tSavedConversationRoot = GET_CURRENTLY_PLAYING_STANDARD_CONVERSATION_ROOT() tSavedConversationLabel = GET_STANDARD_CONVERSATION_LABEL_FOR_FUTURE_RESUMPTION() IF ARE_STRINGS_EQUAL(tSavedConversationLabel, "") OR ARE_STRINGS_EQUAL(tSavedConversationLabel, "NULL") #IF IS_DEBUG_BUILD CPRINTLN(DEBUG_MISSION, "RC CONV CONFLICTS: Already last line of the conversation so not stopping it") #ENDIF stateRestoreConversation = RC_CONV_IDLE ELSE #IF IS_DEBUG_BUILD CPRINTLN(DEBUG_MISSION, "RC CONV CONFLICTS: Stopping and storing conversation ", tSavedConversationRoot) #ENDIF KILL_ANY_CONVERSATION() stateRestoreConversation = RC_CONV_RESTART_WITHOUT_SUBS ENDIF ENDIF BREAK CASE RC_CONV_RESTART_WITHOUT_SUBS IF NOT IS_SCRIPTED_CONVERSATION_ONGOING() IF IS_MESSAGE_BEING_DISPLAYED() // Re-check to see if the god text has since gone offscreen IF CREATE_CONVERSATION_FROM_SPECIFIC_LINE(sConversationToUse, sTextBlockToUse, tSavedConversationRoot, tSavedConversationLabel, CONV_PRIORITY_HIGH, DO_NOT_DISPLAY_SUBTITLES) #IF IS_DEBUG_BUILD CPRINTLN(DEBUG_MISSION, "RC CONV CONFLICTS: Restoring conversation ", tSavedConversationRoot, " from label ", tSavedConversationLabel, " without subtitles") #ENDIF stateRestoreConversation = RC_CONV_RESTORE_WAIT_FOR_NO_TEXT ENDIF ELSE #IF IS_DEBUG_BUILD CPRINTLN(DEBUG_MISSION, "RC CONV CONFLICTS: God text removed before last line of dialogue was finished, so just restart with subtitles") #ENDIF stateRestoreConversation = RC_CONV_RESTART_WITH_SUBS ENDIF ENDIF BREAK CASE RC_CONV_RESTORE_WAIT_FOR_NO_TEXT IF NOT IS_MESSAGE_BEING_DISPLAYED() AND IS_SCRIPTED_CONVERSATION_ONGOING() tSavedConversationRoot = GET_CURRENTLY_PLAYING_STANDARD_CONVERSATION_ROOT() tSavedConversationLabel = GET_STANDARD_CONVERSATION_LABEL_FOR_FUTURE_RESUMPTION() IF ARE_STRINGS_EQUAL(tSavedConversationLabel, "") OR ARE_STRINGS_EQUAL(tSavedConversationLabel, "NULL") #IF IS_DEBUG_BUILD CPRINTLN(DEBUG_MISSION, "RC CONV CONFLICTS: Already last line of the conversation so not stopping it") #ENDIF ELSE #IF IS_DEBUG_BUILD CPRINTLN(DEBUG_MISSION, "RC CONV CONFLICTS: Stopping and storing conversation ", tSavedConversationRoot) #ENDIF KILL_ANY_CONVERSATION() stateRestoreConversation = RC_CONV_RESTART_WITH_SUBS ENDIF ENDIF BREAK CASE RC_CONV_RESTART_WITH_SUBS IF NOT IS_SCRIPTED_CONVERSATION_ONGOING() AND CREATE_CONVERSATION_FROM_SPECIFIC_LINE(sConversationToUse, sTextBlockToUse, tSavedConversationRoot, tSavedConversationLabel, CONV_PRIORITY_HIGH, DISPLAY_SUBTITLES) #IF IS_DEBUG_BUILD CPRINTLN(DEBUG_MISSION, "RC CONV CONFLICTS: Restoring conversation ", tSavedConversationRoot, " from label ", tSavedConversationLabel, " with subtitles") #ENDIF stateRestoreConversation = RC_CONV_IDLE ENDIF BREAK ENDSWITCH ENDPROC /// PURPOSE: /// Does this RCM have a lead-in sequence? FUNC BOOL DOES_RC_MISSION_HAVE_LEAD_IN(g_eRC_MissionIDs eMission) SWITCH eMission CASE RC_ABIGAIL_1 CASE RC_ABIGAIL_2 CASE RC_BARRY_1 CASE RC_BARRY_2 CASE RC_BARRY_3 CASE RC_EPSILON_1 CASE RC_EPSILON_3 CASE RC_EPSILON_4 CASE RC_EPSILON_5 CASE RC_EXTREME_2 CASE RC_EXTREME_3 CASE RC_FANATIC_1 CASE RC_FANATIC_3 CASE RC_JOSH_1 CASE RC_JOSH_4 CASE RC_MINUTE_3 CASE RC_NIGEL_3 CASE RC_PAPARAZZO_1 CASE RC_PAPARAZZO_2 CASE RC_PAPARAZZO_3 RETURN TRUE BREAK ENDSWITCH RETURN FALSE ENDFUNC /// PURPOSE: /// Creates a replacement mission blip for a RCM that is displayed /// for the duration of a lead-in sequence PROC CREATE_BLIP_FOR_LEAD_IN(g_eRC_MissionIDs eMission, BLIP_INDEX &biBlip) SWITCH eMission // Abigail CASE RC_ABIGAIL_1 biBlip = CREATE_BLIP_FOR_COORD(<< -1604.668, 5239.10, 3.01 >>) SET_BLIP_SPRITE(biBlip, RADAR_TRACE_RANDOM_CHARACTER) SET_BLIP_COLOUR(biBlip, BLIP_COLOUR_MICHAEL) BREAK CASE RC_ABIGAIL_2 biBlip = CREATE_BLIP_FOR_COORD(<< -1592.84, 5214.04, 3.01 >>) SET_BLIP_SPRITE(biBlip, RADAR_TRACE_ABIGAIL) SET_BLIP_COLOUR(biBlip, BLIP_COLOUR_MICHAEL) BREAK // Barry CASE RC_BARRY_1 CASE RC_BARRY_2 biBlip = CREATE_BLIP_FOR_COORD(<< 190.26, -956.35, 29.63 >>) IF IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[RC_BARRY_1].rcFlags, ENUM_TO_INT(RC_FLAG_COMPLETED)) OR IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[RC_BARRY_3].rcFlags, ENUM_TO_INT(RC_FLAG_COMPLETED)) OR IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[RC_BARRY_3].rcFlags, ENUM_TO_INT(RC_FLAG_COMPLETED)) SET_BLIP_SPRITE(biBlip, RADAR_TRACE_BARRY) ELSE SET_BLIP_SPRITE(biBlip, RADAR_TRACE_RANDOM_CHARACTER) ENDIF IF eMission = RC_BARRY_1 SET_BLIP_COLOUR(biBlip, BLIP_COLOUR_MICHAEL) ELSE SET_BLIP_COLOUR(biBlip, BLIP_COLOUR_TREVOR) ENDIF BREAK CASE RC_BARRY_3 biBlip = CREATE_BLIP_FOR_COORD(<< 414.00, -761.00, 29.00 >>) IF IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[RC_BARRY_1].rcFlags, ENUM_TO_INT(RC_FLAG_COMPLETED)) OR IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[RC_BARRY_2].rcFlags, ENUM_TO_INT(RC_FLAG_COMPLETED)) SET_BLIP_SPRITE(biBlip, RADAR_TRACE_BARRY) ELSE SET_BLIP_SPRITE(biBlip, RADAR_TRACE_RANDOM_CHARACTER) ENDIF SET_BLIP_COLOUR(biBlip, BLIP_COLOUR_FRANKLIN) BREAK // Epsilon CASE RC_EPSILON_1 biBlip = CREATE_BLIP_FOR_COORD(<< -1622.89, 4204.87, 83.30 >>) SET_BLIP_SPRITE(biBlip, RADAR_TRACE_RANDOM_CHARACTER) SET_BLIP_COLOUR(biBlip, BLIP_COLOUR_MICHAEL) BREAK CASE RC_EPSILON_3 CASE RC_EPSILON_4 CASE RC_EPSILON_5 IF eMission = RC_EPSILON_3 biBlip = CREATE_BLIP_FOR_COORD(<< 1835.53, 4705.86, 38.1 >>) ELIF eMission = RC_EPSILON_4 biBlip = CREATE_BLIP_FOR_COORD(<< 1826.13, 4698.88, 38.92 >>) ELSE biBlip = CREATE_BLIP_FOR_COORD(<< 637.02, 119.7093, 89.50 >>) ENDIF SET_BLIP_SPRITE(biBlip, RADAR_TRACE_EPSILON) SET_BLIP_COLOUR(biBlip, BLIP_COLOUR_MICHAEL) BREAK // Extreme CASE RC_EXTREME_2 CASE RC_EXTREME_3 IF eMission = RC_EXTREME_2 biBlip = CREATE_BLIP_FOR_COORD(<< -954.19, -2760.05, 14.64 >>) ELSE biBlip = CREATE_BLIP_FOR_COORD(<< -63.8, -809.5, 321.8 >>) ENDIF SET_BLIP_SPRITE(biBlip, RADAR_TRACE_DOM) SET_BLIP_COLOUR(biBlip, BLIP_COLOUR_FRANKLIN) BREAK // Fanatic CASE RC_FANATIC_1 CASE RC_FANATIC_3 IF eMission = RC_FANATIC_1 biBlip = CREATE_BLIP_FOR_COORD(<< -1877.82, -440.649, 45.05>>) ELSE biBlip = CREATE_BLIP_FOR_COORD(<< -915.6, 6139.2, 5.5 >>) ENDIF IF IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[RC_FANATIC_1].rcFlags, ENUM_TO_INT(RC_FLAG_COMPLETED)) OR IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[RC_FANATIC_2].rcFlags, ENUM_TO_INT(RC_FLAG_COMPLETED)) OR IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[RC_FANATIC_3].rcFlags, ENUM_TO_INT(RC_FLAG_COMPLETED)) SET_BLIP_SPRITE(biBlip, RADAR_TRACE_FANATIC) ELSE SET_BLIP_SPRITE(biBlip, RADAR_TRACE_RANDOM_CHARACTER) ENDIF IF eMission = RC_FANATIC_1 SET_BLIP_COLOUR(biBlip, BLIP_COLOUR_MICHAEL) ELSE SET_BLIP_COLOUR(biBlip, BLIP_COLOUR_FRANKLIN) ENDIF BREAK // Josh CASE RC_JOSH_1 biBlip = CREATE_BLIP_FOR_COORD(<< -1104.93, 291.25, 64.30 >>) SET_BLIP_SPRITE(biBlip, RADAR_TRACE_RANDOM_CHARACTER) SET_BLIP_COLOUR(biBlip, BLIP_COLOUR_TREVOR) BREAK CASE RC_JOSH_4 biBlip = CREATE_BLIP_FOR_COORD(<< -1104.93, 291.25, 64.30 >>) SET_BLIP_SPRITE(biBlip, RADAR_TRACE_JOSH) SET_BLIP_COLOUR(biBlip, BLIP_COLOUR_TREVOR) BREAK // Minute CASE RC_MINUTE_3 biBlip = CREATE_BLIP_FOR_COORD(<< -303.82, 6211.29, 31.05>>) SET_BLIP_SPRITE(biBlip, RADAR_TRACE_MINUTE) SET_BLIP_COLOUR(biBlip, BLIP_COLOUR_TREVOR) BREAK // Nigel CASE RC_NIGEL_3 biBlip = CREATE_BLIP_FOR_COORD(<< -44.75, -1288.67, 28.21 >>) SET_BLIP_SPRITE(biBlip, RADAR_TRACE_CELEBRITY_THEFT) SET_BLIP_COLOUR(biBlip, BLIP_COLOUR_TREVOR) BREAK // Paparazzo CASE RC_PAPARAZZO_1 biBlip = CREATE_BLIP_FOR_COORD(<< -149.75, 285.81, 93.67 >>) SET_BLIP_SPRITE(biBlip, RADAR_TRACE_RANDOM_CHARACTER) SET_BLIP_COLOUR(biBlip, BLIP_COLOUR_FRANKLIN) BREAK CASE RC_PAPARAZZO_2 CASE RC_PAPARAZZO_3 IF eMission = RC_PAPARAZZO_2 biBlip = CREATE_BLIP_FOR_COORD(<< -70.71, 301.43, 106.79 >>) ELSE biBlip = CREATE_BLIP_FOR_COORD(<< -257.22, 292.85, 90.63 >>) ENDIF SET_BLIP_SPRITE(biBlip, RADAR_TRACE_PAPARAZZO) SET_BLIP_COLOUR(biBlip, BLIP_COLOUR_FRANKLIN) BREAK ENDSWITCH ENDPROC