1789 lines
64 KiB
Scheme
Executable File
1789 lines
64 KiB
Scheme
Executable File
/// 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 = <<rad / 2.0, rad / 2.0, rad / 2.0>>
|
|
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
|