5968 lines
195 KiB
Python
Executable File
5968 lines
195 KiB
Python
Executable File
// *****************************************************************************************
|
|
// *****************************************************************************************
|
|
//
|
|
// MISSION NAME : Barry2.sc
|
|
// AUTHOR : Aaron Gandaa / Stefan Arnold
|
|
// DESCRIPTION : Second Barry Mission (clowns)
|
|
//
|
|
// *****************************************************************************************
|
|
// *****************************************************************************************
|
|
|
|
//Compile out Title Update changes to header functions.
|
|
//Must be before includes.
|
|
//CONST_INT USE_TU_CHANGES 0 // Removed by Kenneth R.
|
|
|
|
//----------------------
|
|
// INCLUDES
|
|
//----------------------
|
|
USING "rage_builtins.sch"
|
|
USING "globals.sch"
|
|
USING "cutscene_public.sch"
|
|
USING "commands_cutscene.sch"
|
|
USING "commands_entity.sch"
|
|
USING "commands_script.sch"
|
|
USING "commands_shapetest.sch"
|
|
USING "script_player.sch"
|
|
USING "randomChar_public.sch"
|
|
USING "rgeneral_include.sch"
|
|
USING "dialogue_public.sch"
|
|
USING "RC_Helper_Functions.sch"
|
|
USING "RC_Area_public.sch"
|
|
USING "RC_Asset_public.sch"
|
|
USING "cheat_controller_public.sch"
|
|
|
|
USING "CompletionPercentage_public.sch"
|
|
USING "replay_public.sch"
|
|
USING "shop_public.sch"
|
|
USING "initial_scenes_barry.sch"
|
|
USING "commands_recording.sch"
|
|
USING "taxi_functions.sch"
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
USING "select_mission_stage.sch"
|
|
USING "shared_debug.sch"
|
|
#ENDIF
|
|
|
|
//----------------------
|
|
// ENUMS
|
|
//----------------------
|
|
ENUM CLOWN_STATE
|
|
CS_NULL,
|
|
CS_DELAY,
|
|
CS_TELEPORT,
|
|
CS_TELEPORT_OUT_START,
|
|
CS_TELEPORT_OUT,
|
|
CS_TELEPORT_SEEK_PLACE,
|
|
CS_DANCE_START,
|
|
CS_DANCE,
|
|
CS_PERFORM_START,
|
|
CS_PERFORM_SPAWN_GUN,
|
|
CS_ONROUTE_START,
|
|
CS_ONROUTE,
|
|
CS_ACTIVE,
|
|
CS_ATTACK_SPECTATORS,
|
|
CS_VEHICLE_DEPLOY,
|
|
CS_DYING,
|
|
CS_DEATH_FX,
|
|
CS_DEAD
|
|
ENDENUM
|
|
|
|
ENUM STAGE_ENUM
|
|
SE_LEAD_IN = -1,
|
|
SE_INTRO = 0,
|
|
SE_TEST,
|
|
SE_PERFORMANCE, // 1 clown performs, then shoots audience
|
|
SE_FIRSTCONTACT, // 3 guys
|
|
SE_WAVE1, // clown generator
|
|
SE_WAVE2, // clown generator
|
|
SE_WAVE3, // 5 guys
|
|
SE_WAVE4, // 2 generators
|
|
SE_WAVE5, // 2 generators
|
|
SE_WAVE6, // "boss" wave
|
|
SE_PASSOUT,
|
|
SE_OUTRO,
|
|
SE_FAILED
|
|
ENDENUM
|
|
|
|
// @SBA - different possible starting types for clowns
|
|
ENUM STARTING_CLOWN_TYPES
|
|
SCT_NORMAL, // Your typical killer clown
|
|
SCT_SPECIAL, // Used if clown needs to do something custom (currently for first performance clown lead-out)
|
|
SCT_PERFORM, // Used for clowns that are entertaining spectators (except first performance lead-out)
|
|
SCT_CHASE, // Used for clowns engaged in hunting down spectators
|
|
SCT_VAN_EXIT // Used for clowns exitng the back of a clown van
|
|
ENDENUM
|
|
|
|
ENUM PASS_OUT_STAGE
|
|
POS_SETUP,
|
|
POS_WAIT_FOR_TIRED,
|
|
POS_START_DIALOG,
|
|
POS_TRANSITION_FX,
|
|
POS_WAIT_DIALOGUE,
|
|
POS_WAIT_PASS_OUT
|
|
ENDENUM
|
|
|
|
//----------------------
|
|
// STRUCTURES
|
|
//----------------------
|
|
|
|
STRUCT CLOWN_PED
|
|
BOOL bIsActive
|
|
BOOL bIsDead = FALSE
|
|
CLOWN_STATE aState
|
|
|
|
PED_INDEX pedID
|
|
BLIP_INDEX blipID
|
|
INT laughSoundID = -1
|
|
FLOAT fClownAlpha = 255.0
|
|
|
|
TEXT_LABEL danceAnim
|
|
INT iDanceTimer = 0
|
|
INT iTimer
|
|
INT iLongevityTimer
|
|
|
|
STARTING_CLOWN_TYPES ClownType = SCT_NORMAL
|
|
PED_INDEX piClosestSpec = NULL
|
|
|
|
VECTOR vDeathPosition
|
|
ENDSTRUCT
|
|
|
|
STRUCT CLOWN_GENERATOR
|
|
BOOL bIsActive
|
|
BOOL bIsDead = FALSE
|
|
CLOWN_STATE aState
|
|
|
|
VEHICLE_INDEX generatorID
|
|
BLIP_INDEX blipID
|
|
FLOAT fClownAlpha = 255.0
|
|
|
|
INT iTimer
|
|
BOOL bIsInDynamicMix = FALSE
|
|
BOOL bHasStartedDeploying = FALSE
|
|
BOOL bHasPlayerApproached = FALSE
|
|
|
|
INT iClownPedsSpawned = 0
|
|
INT iForwardTime = 5000
|
|
INT iHBrakeTime = 500
|
|
|
|
INT iSwerveIn = 0
|
|
INT iDriverID = -1
|
|
ENDSTRUCT
|
|
|
|
//----------------------
|
|
// CONSTANTS
|
|
//----------------------
|
|
CONST_INT MISSION_VERSION 016 // this so i can be sure that my changes have been accepted
|
|
CONST_INT FAIL_WARNING_TIME 10000
|
|
CONST_INT CUTSCENE_TRANSITION_TIME 54000 // 1m 07 seconds 44000
|
|
CONST_INT CUTSCENE_CLOWN_TIME 59000 // 58000 // 46000
|
|
|
|
|
|
CONST_INT MAX_CLOWN_PEDS 8
|
|
CONST_INT CLOWN_FADE_TIME 500
|
|
CONST_INT TELEPORT_TIME 250
|
|
|
|
CONST_FLOAT TELEPORT_Z_DIFF 0.1
|
|
CONST_FLOAT CLOWN_APPEAR_SIZE 1.5
|
|
CONST_FLOAT GENERATOR_APPEAR_SIZE 3.0
|
|
CONST_FLOAT STAGE_BREAK_TIME 0.5
|
|
|
|
//----------------------
|
|
// CHECKPOINTS
|
|
//----------------------
|
|
CONST_INT CP_MISSION_START 0
|
|
CONST_INT CP_MID_STAGE 1 // stage 4
|
|
CONST_INT CP_OUTRO 2
|
|
|
|
CONST_INT Z_SKIP_TO_INTRO 0
|
|
CONST_INT Z_SKIP_TO_PERFORMANCE 1 //@SBA - inserted this stage
|
|
CONST_INT Z_SKIP_TO_FIRST_CONTACT 2
|
|
CONST_INT Z_SKIP_TO_FIRST_WAVE 3
|
|
CONST_INT Z_SKIP_TO_SECOND_WAVE 4
|
|
CONST_INT Z_SKIP_TO_THIRD_WAVE 5
|
|
CONST_INT Z_SKIP_TO_FOURTH_WAVE 6
|
|
CONST_INT Z_SKIP_TO_FIFTH_WAVE 7
|
|
CONST_INT Z_SKIP_TO_SIXTH_WAVE 8 //@SBA - inserted this stage
|
|
CONST_INT Z_SKIP_TO_PASSOUT 9
|
|
CONST_INT Z_SKIP_TO_OUTRO 10
|
|
CONST_INT Z_SKIP_TO_TEST 11
|
|
|
|
CONST_INT MAX_SKIP_MENU_LENGTH 12
|
|
|
|
// match up with object array in g_structRCScriptArgs (see initial_scenes_barry.sch)
|
|
CONST_INT OBJ_TABLE 0
|
|
CONST_INT OBJ_CHAIR 1
|
|
CONST_INT OBJ_PAPERS 2
|
|
CONST_INT OBJ_SIGN 3
|
|
|
|
//----------------------
|
|
// RC VARIABLES
|
|
//----------------------
|
|
g_structRCScriptArgs sRCLauncherDataLocal
|
|
|
|
//----------------------
|
|
// VARIABLES
|
|
//----------------------
|
|
INT iFailTimer
|
|
STRING sFailString = ""
|
|
STAGE_ENUM stageEnum = SE_LEAD_IN
|
|
PASS_OUT_STAGE ePassOutStage
|
|
STAGE_PROGRESS stageProgress
|
|
OBJECT_INDEX gunObject
|
|
|
|
INT iDbgStageJump // now also used in checkpoint / replay stuff
|
|
SCENARIO_BLOCKING_INDEX scenarioBlock
|
|
VECTOR vPlayerCarRespot = <<174.1703, -1012.2490, 28.3180>>
|
|
FLOAT fPlayerCarRespot = 27.4862
|
|
|
|
VECTOR vBattleCenter = <<180.5319, -970.6324, 29.0923>>
|
|
FLOAT fBattleRadius = 80.0
|
|
VECTOR vMissionStart = << 188.86, -955.83, 29.09 >>
|
|
FLOAT fMissionStart = 62.08
|
|
|
|
FLOAT fTimeScale = 0.8
|
|
|
|
ANGLED_AREA battleAreaOuter
|
|
ANGLED_AREA battleArea
|
|
ANGLED_AREA battleAreaInner
|
|
ANGLED_AREA respotVehicleArea
|
|
|
|
BOOL bIsPlayerInBattleArea = TRUE
|
|
INT iMissionAbandonedTimer = 0
|
|
BLIP_INDEX locationBlip
|
|
BOOL bDebugTTYSpew = FALSE
|
|
INT iAlphaCounter = 0
|
|
|
|
BOOL bTransitionStarted = FALSE
|
|
BOOL bInitialClowns = FALSE
|
|
ASSET_REQUESTER assetRequester
|
|
|
|
//----------------------
|
|
// ANIM / CS VARIABLES
|
|
//----------------------
|
|
STRING sSceneHandleBarry = "Barry"
|
|
STRING sSceneHandleChair = "Barrys_chair"
|
|
STRING sSceneHandleTable = "Barrys_protest_table"
|
|
STRING sSceneHandlePapers = "Barry_Pamphlet_1"
|
|
|
|
STRING FX_DrugsIn = "DrugsTrevorClownsFightIn"
|
|
STRING FX_DrugsSkip = "DrugsTrevorClownsFight"
|
|
STRING FX_DrugsOut = "DrugsTrevorClownsFightOut"
|
|
STRING sMissionAnimDictionary = "rcmbarry"
|
|
STRING sMissionAnimDanceDictionary = "rcm_barry2"
|
|
STRING sndAlienAmbientScene = "BARRY_02_DRUGS"
|
|
|
|
BOOL bHasPlayerCameraExitState = FALSE
|
|
|
|
//----------------------
|
|
// CLOWN VARIABLES
|
|
//----------------------
|
|
CLOWN_PED clownPed[MAX_CLOWN_PEDS]
|
|
CLOWN_GENERATOR clownGenerator[3]
|
|
|
|
MODEL_NAMES clownModel = S_M_Y_CLOWN_01
|
|
MODEL_NAMES clownCarModel = SPEEDO2
|
|
MODEL_NAMES mnProtestSign = Prop_Protest_Sign_01
|
|
WEAPON_TYPE playerWeapon = WEAPONTYPE_ASSAULTSHOTGUN
|
|
COMBAT_PARAMETERS combatParams
|
|
|
|
INT iNextSpawnTimer = 0
|
|
INT iMinPedSpawnTime = 500
|
|
INT iMaxPedSpawnTime = 2000
|
|
INT iMinGeneratorPedSpawnTime = 1500
|
|
INT iMaxGeneratorPedSpawnTime = 3000
|
|
FLOAT fNoSpawnPlayerDist = 12.0
|
|
|
|
INT iMaxActivePeds = 5
|
|
INT iClownPedsSpawned = 0
|
|
INT iClownPedsKilled = 0
|
|
INT iDancingClownPedsKilled = 0
|
|
INT iClownGeneratorsDestroyed = 0
|
|
FLOAT fClownGeneratorTriggerDist = 20.0
|
|
|
|
INT iAliveClownCount = 0
|
|
INT iAliveClownGeneratorCount = 0
|
|
|
|
FLOAT fClownSpawnRadius = 40.0
|
|
BOOL bGenerateAutoClowns = FALSE
|
|
BOOL bUseClownSpawnPoint = FALSE
|
|
VECTOR vClownSpawnPoint
|
|
VECTOR vClownCarSmokeOffset = <<0, -3.2, 0.6>>
|
|
FLOAT fClownCarPedSmokeSize = 1.5
|
|
|
|
FLOAT iStageTimer = 0
|
|
INT iStateTimeOut = 0
|
|
|
|
BOOL bUseIsAreaOccupied = FALSE
|
|
BOOL bHasClownGeneratorHelpDisplayed = FALSE
|
|
BOOL bHasTrevorClownGeneratorRanted = FALSE
|
|
INT iTrevorClownGeneratorRantTime = 0
|
|
|
|
INT iMinClownDanceDelay = 5000
|
|
INT iMaxClownDanceDelay = 20000
|
|
|
|
FLOAT fClownCarFwdSpeed = 8.5 //12.5
|
|
|
|
//----------------------
|
|
// AUDIO VARIABLES
|
|
//----------------------
|
|
BOOL bHasInitialOutburst = FALSE
|
|
INT iFirstDialogTime
|
|
INT iNextFightDialogTime
|
|
INT iNextFreakDialogTime
|
|
LOCATES_HEADER_DATA sLocateData
|
|
structPedsForConversation convoPlayer
|
|
STRING sAmbientZone = "AZ_BARRY_02_AMBIENCE"
|
|
|
|
//----------------------
|
|
// DEBUG VARIABLES
|
|
//----------------------
|
|
#IF IS_DEBUG_BUILD
|
|
MissionStageMenuTextStruct sSkipMenu[MAX_SKIP_MENU_LENGTH]
|
|
WIDGET_GROUP_ID m_WidgetGroup
|
|
|
|
BOOL bGenerateTestClown = FALSE
|
|
BOOL bUpdateWidgets = TRUE
|
|
|
|
BOOL bGenerateTestGenerator = FALSE
|
|
VECTOR vTestGenPoint = << 171.9, -978.4, 30.1 >>
|
|
FLOAT fTestHeading = 0
|
|
INT iTestSwerve = 0
|
|
INT iTestFwdTime = 5000
|
|
INT iTestBrakeTime = 500
|
|
#ENDIF
|
|
|
|
|
|
//----------------------
|
|
// @SBA - ADDITIONAL VARIABLES
|
|
//----------------------
|
|
|
|
// Anim phases we care about
|
|
// Phase at which to start the mime anim
|
|
CONST_FLOAT kfMimeStartPhase 0.625
|
|
// Phase in the mime anim in which gun should spawn
|
|
CONST_FLOAT kfMimeGunSpawnPhase 0.802
|
|
// End phase of the mime anim
|
|
CONST_FLOAT kfMimeEndPhase 0.815
|
|
// Ditto for the regular dance anims
|
|
CONST_FLOAT kfDanceGunSpawnPhase 0.95
|
|
CONST_FLOAT kfDanceEndPhase 0.99
|
|
|
|
// If a clown has been alive this long, he becomes aggresive
|
|
// Should help stragglers seek out the player
|
|
CONST_INT kiAggressiveTime 30000
|
|
|
|
// Min gap between fight/freak lines
|
|
CONST_INT kiDialogTimeCheck 2500
|
|
|
|
|
|
// cutscene skip
|
|
BOOL bSkipAllowed = FALSE
|
|
|
|
// Keep track of the armor the player stared with
|
|
INT iPlayerStartingArmor
|
|
|
|
// Flag to set last clown in wave aggressive
|
|
BOOL bLastClownAggressive = FALSE
|
|
|
|
// performance vars
|
|
BOOL bPerformancePedsCreated = FALSE
|
|
BOOL bPlayedGunSmokeFX = FALSE
|
|
INT i1stPerformanceClownID
|
|
INT i2ndPerformanceClownID
|
|
INT i3rdPerformanceClownID
|
|
|
|
BOOL bTrevFirstLine = FALSE
|
|
|
|
// cameras used in the opening performance
|
|
CAMERA_INDEX ciPerformCamera1
|
|
|
|
// @SBA - spectators
|
|
CONST_INT kiNumberOfSpectators 5
|
|
// The distance within which clowns engaged with the player will notice a spectator
|
|
CONST_FLOAT kiShortIgnoreSpectatorsDist 12.0
|
|
// All Clowns ignore spectators past this distance
|
|
CONST_FLOAT kiLongIgnoreSpectatorsDist 22.0
|
|
// Clowns run after spectators if farther than this distance
|
|
CONST_FLOAT kiCHaseSpectatorsDist 5.0
|
|
// Distance at which a spectator will notice another spectator dying
|
|
CONST_FLOAT kfMinSpectatorWitnessDist 20.0
|
|
|
|
MODEL_NAMES mnSpectatorMale = A_M_M_Business_01
|
|
MODEL_NAMES mnSpectatorFemale = A_F_M_BevHills_02
|
|
INT iSpecAlphaCounter = 0
|
|
INT iApplauseSound = -1
|
|
STRING sSpectatorFemAnimDict = "amb@world_human_cheering@female_d"
|
|
STRING sSpectatorFemAnimClip = "base"
|
|
STRING sSpectatorMaleAnimDict = "amb@world_human_cheering@male_d"
|
|
STRING sSpectatorMaleAnimClip = "base"
|
|
STRING sMimeAnimDict = "special_ped@mime"
|
|
STRING sMimeAnimClip = "idle_c"
|
|
|
|
VECTOR vSpectatorPerformOffsets[kiNumberOfSpectators]
|
|
|
|
ENUM SPECTATOR_STATE
|
|
SS_FADE_IN,
|
|
SS_WATCH_CLOWN,
|
|
SS_REACT_TO_DANGER,
|
|
SS_FLEEING,
|
|
SS_KILL,
|
|
SS_GOING,
|
|
SS_GONE,
|
|
SS_DONE
|
|
ENDENUM
|
|
|
|
STRUCT SPECTATOR_STRUCT
|
|
PED_INDEX piPed
|
|
MODEL_NAMES mnModel
|
|
VECTOR vSpawnPos
|
|
FLOAT fSpawnHead
|
|
SPECTATOR_STATE ssState
|
|
BOOL bIsActive = FALSE
|
|
INT iTimer
|
|
FLOAT fSpectAlpha = 255.0
|
|
BOOL bJustFlee = FALSE
|
|
ENDSTRUCT
|
|
SPECTATOR_STRUCT ssSpectator[kiNumberOfSpectators]
|
|
|
|
// states for the intro performance
|
|
ENUM PERFORMANCE_STATE
|
|
PS_MIME_CLOWN_MIME,
|
|
PS_MOVE_PLAYER,
|
|
PS_SPAWN_WEAPON,
|
|
PS_SPAWN_LAST_CLOWNS,
|
|
PS_CLOWNS_ATTACK_SPECTATORS,
|
|
PS_CLOWNS_ATTACK_SPECTATORS_2,
|
|
PS_KILLING_SPECTATORS,
|
|
PS_RETURN_PLAYER_CONTROL,
|
|
PS_CLOWNS_ATTACK_PLAYER,
|
|
PS_KILL_CLOWNS,
|
|
PS_DONE
|
|
ENDENUM
|
|
PERFORMANCE_STATE psPerformanceState = PS_MIME_CLOWN_MIME
|
|
|
|
// for timing out some of the performance states
|
|
structTIMER tmrPerformance
|
|
|
|
// ~~~ @SBA General Clown Performance Vars ~~~
|
|
|
|
// size of the performance data array
|
|
CONST_INT kiPerformDataSize 15
|
|
// Minimum distance the player should be from a performance spawn
|
|
CONST_FLOAT kfPerformMinSpawnDIst 7.0
|
|
|
|
// General spawn areas,
|
|
ENUM SPAWN_ZONES
|
|
SZ_ZONE_1, // Intro through Wave 2
|
|
SZ_ZONE_2,
|
|
SZ_ZONE_3,
|
|
SZ_NO_ZONE // for clearing data
|
|
ENDENUM
|
|
|
|
// data for performance clowns and spectators
|
|
STRUCT CLOWN_PERFORMANCE_DATA
|
|
SPAWN_ZONES SpawnZone
|
|
VECTOR vClownPos
|
|
FLOAT fClownHead
|
|
INT iNumSpectators = -1
|
|
BOOL bThisIsAFleeSpawn = FALSE
|
|
ENDSTRUCT
|
|
// Permanent struct to hold performance location data
|
|
CLOWN_PERFORMANCE_DATA CPD_PerformData[kiPerformDataSize]
|
|
// Used to hold valid data for specific performance spawns
|
|
// (@TODO - This array could be smaller, as it just needs a zone's worth of data)
|
|
CLOWN_PERFORMANCE_DATA CPD_SpecificData[kiPerformDataSize]
|
|
|
|
//
|
|
BOOL bClownGeneratorRantTimerSet = FALSE
|
|
BOOL bHasTrevorDupClownRanted = FALSE
|
|
|
|
|
|
// for timing out some general stuff (reusable)
|
|
structTIMER tmrGeneral
|
|
FLOAT fGeneralTime
|
|
|
|
// Boss wave
|
|
CONST_INT kiNumDuplicates 2
|
|
INT iDuplicatesCount = 0
|
|
|
|
//----------------------
|
|
// @SBA - END ADDITIONAL VARIABLES
|
|
//----------------------
|
|
|
|
|
|
|
|
//----------------------
|
|
// MISC FUNCTIONS
|
|
//----------------------
|
|
|
|
FUNC VECTOR GET_MODEL_SIZE(MODEL_NAMES mdlName)
|
|
VECTOR vMin, vMax, vSize
|
|
GET_MODEL_DIMENSIONS(mdlName, vMin, vMax)
|
|
|
|
vSize.x = ABSF(vMax.x - vMin.x)
|
|
vSize.y = ABSF(vMax.y - vMin.y)
|
|
vSize.z = ABSF(vMax.z - vMin.z)
|
|
RETURN vSize
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Resolve cars for mission
|
|
PROC RESOLVE_MISSION_VEHICLES_FOR_CUTSCENE()
|
|
MODEL_NAMES mdlName
|
|
CPRINTLN(DEBUG_MISSION, "Vehicles Resolved For Intro")
|
|
|
|
IF NOT IS_ENTITY_ALIVE(GET_PLAYERS_LAST_VEHICLE())
|
|
EXIT
|
|
ENDIF
|
|
|
|
mdlName = GET_ENTITY_MODEL(GET_PLAYERS_LAST_VEHICLE())
|
|
IF IS_THIS_MODEL_A_HELI(mdlName) OR IS_THIS_MODEL_A_PLANE(mdlName)
|
|
|
|
vPlayerCarRespot = <<180.47, -1017.79, 30.01>>
|
|
fPlayerCarRespot = 206.45
|
|
|
|
CPRINTLN(DEBUG_MISSION, "RESOLVE_MISSION_VEHICLES_FOR_CUTSCENE() - THIS IS A PLANE OR HELI")
|
|
RESOLVE_VEHICLES_INSIDE_ANGLED_AREA_WITH_SIZE_LIMIT(respotVehicleArea.vPosition[0], respotVehicleArea.vPosition[1], respotVehicleArea.fWidth,
|
|
vPlayerCarRespot, fPlayerCarRespot, <<0, 0, 0>>, TRUE, FALSE) // setVehicleAsVehGen parameter should no longer be used - SET_MISSION_START_VEHICLE_AS_VEHICLE_GEN to handle it
|
|
|
|
//IF IS_REPLAY_START_VEHICLE_UNDER_SIZE_LIMIT(<<0, 0, 0>>, TRUE)
|
|
SET_MISSION_START_VEHICLE_AS_VEHICLE_GEN(vPlayerCarRespot, fPlayerCarRespot, FALSE)
|
|
//ENDIF
|
|
|
|
ELSE
|
|
|
|
RESOLVE_VEHICLES_INSIDE_ANGLED_AREA_WITH_SIZE_LIMIT(respotVehicleArea.vPosition[0], respotVehicleArea.vPosition[1], respotVehicleArea.fWidth,
|
|
vPlayerCarRespot, fPlayerCarRespot, GET_DEFAULT_ALLOWABLE_VEHICLE_SIZE_VECTOR(), TRUE, FALSE) // setVehicleAsVehGen parameter should no longer be used - SET_MISSION_START_VEHICLE_AS_VEHICLE_GEN to handle it
|
|
|
|
IF IS_REPLAY_START_VEHICLE_UNDER_SIZE_LIMIT(<<0, 0, 0>>, TRUE)
|
|
SET_MISSION_START_VEHICLE_AS_VEHICLE_GEN(vPlayerCarRespot, fPlayerCarRespot, FALSE)
|
|
ENDIF
|
|
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Initializes the data for the general clown performances
|
|
PROC INITIAILIZE_PERFORMANCE_DATA()
|
|
|
|
// Most won't be flee spawns, so init these false
|
|
INT idx
|
|
REPEAT kiPerformDataSize idx
|
|
CPD_PerformData[idx].bThisIsAFleeSpawn = FALSE
|
|
ENDREPEAT
|
|
|
|
// Zone 1 - near start
|
|
CPD_PerformData[0].SpawnZone = SZ_ZONE_1
|
|
CPD_PerformData[0].vClownPos = <<174.1163, -979.6599, 30.0923>>
|
|
CPD_PerformData[0].fClownHead = 341.3244
|
|
CPD_PerformData[1].SpawnZone = SZ_ZONE_1
|
|
CPD_PerformData[1].vClownPos = <<184.8053, -980.3381, 30.0923>>
|
|
CPD_PerformData[1].fClownHead = 50.2065
|
|
CPD_PerformData[2].SpawnZone = SZ_ZONE_1
|
|
CPD_PerformData[2].vClownPos = <<192.9764, -972.7697, 30.0923>>
|
|
CPD_PerformData[2].fClownHead = 32.8447
|
|
CPD_PerformData[3].SpawnZone = SZ_ZONE_1
|
|
CPD_PerformData[3].vClownPos = <<195.3397, -989.3920, 30.0923>>
|
|
CPD_PerformData[3].fClownHead = 2.9484
|
|
// Zone 2 - near where first pair of vans drive up
|
|
CPD_PerformData[4].SpawnZone = SZ_ZONE_2
|
|
CPD_PerformData[4].vClownPos = <<185.1147, -917.4800, 29.6923>>
|
|
CPD_PerformData[4].fClownHead = 146.3272
|
|
CPD_PerformData[5].SpawnZone = SZ_ZONE_2
|
|
CPD_PerformData[5].vClownPos = <<212.4505, -945.4181, 30.6921>>
|
|
CPD_PerformData[5].fClownHead = 64.4890
|
|
CPD_PerformData[6].SpawnZone = SZ_ZONE_2
|
|
CPD_PerformData[6].vClownPos = <<209.6497, -926.5642, 30.6921>>
|
|
CPD_PerformData[6].fClownHead = 119.3868
|
|
CPD_PerformData[7].SpawnZone = SZ_ZONE_2
|
|
CPD_PerformData[7].vClownPos = <<197.8188, -916.9774, 30.6929>>
|
|
CPD_PerformData[7].fClownHead = 248.1600
|
|
CPD_PerformData[8].SpawnZone = SZ_ZONE_2
|
|
CPD_PerformData[8].vClownPos = <<168.9134, -916.1412, 30.6921>>
|
|
CPD_PerformData[8].fClownHead = 245.1600
|
|
CPD_PerformData[8].bThisIsAFleeSpawn = TRUE
|
|
CPD_PerformData[9].SpawnZone = SZ_ZONE_2
|
|
CPD_PerformData[9].vClownPos = <<220.6332, -952.7892, 30.0924>>
|
|
CPD_PerformData[9].fClownHead = 63.2940
|
|
CPD_PerformData[9].bThisIsAFleeSpawn = TRUE
|
|
CPD_PerformData[10].SpawnZone = SZ_ZONE_2
|
|
CPD_PerformData[10].vClownPos = <<226.5618, -909.9656, 30.6922>>
|
|
CPD_PerformData[10].fClownHead = 119.7046
|
|
CPD_PerformData[10].bThisIsAFleeSpawn = TRUE
|
|
// Zone 3 - last wave of vans
|
|
CPD_PerformData[11].SpawnZone = SZ_ZONE_3
|
|
CPD_PerformData[11].vClownPos = <<229.2508, -904.2552, 30.6922>>
|
|
CPD_PerformData[11].fClownHead = 56.9046
|
|
CPD_PerformData[12].SpawnZone = SZ_ZONE_3
|
|
CPD_PerformData[12].vClownPos = <<205.4078, -898.1343, 30.1166>>
|
|
CPD_PerformData[12].fClownHead = 144.7924
|
|
CPD_PerformData[13].SpawnZone = SZ_ZONE_3
|
|
CPD_PerformData[13].vClownPos = <<222.5962, -855.8390, 30.1816>>
|
|
CPD_PerformData[13].fClownHead = 204.4446
|
|
CPD_PerformData[13].bThisIsAFleeSpawn = TRUE
|
|
CPD_PerformData[14].SpawnZone = SZ_ZONE_3
|
|
CPD_PerformData[14].vClownPos = <<182.0917, -886.9590, 30.1164>>
|
|
CPD_PerformData[14].fClownHead = 236.4387
|
|
CPD_PerformData[14].bThisIsAFleeSpawn = TRUE
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Initializes the offsets for the spectators of a general clown performance
|
|
PROC INITIALIZE_SPECTATOR_OFFSET_DATA()
|
|
vSpectatorPerformOffsets[0] = <<0,2.0,0>>
|
|
vSpectatorPerformOffsets[1] = <<-1.0,1.75,0>>
|
|
vSpectatorPerformOffsets[2] = <<1.25,1.75,0>>
|
|
vSpectatorPerformOffsets[3] = <<2.0,2.25,0>>
|
|
vSpectatorPerformOffsets[4] = <<-2.25,2.5,0>>
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// @SBA - Resets the CPD_SpecificData array to default values
|
|
PROC RESET_SPECIFIC_PERFORMANCE_DATA()
|
|
INT idx
|
|
REPEAT COUNT_OF(CPD_SpecificData) idx
|
|
CPD_SpecificData[idx].SpawnZone = SZ_NO_ZONE
|
|
CPD_SpecificData[idx].vClownPos = (<<0,0,0>>)
|
|
CPD_SpecificData[idx].fClownHead = -1.0
|
|
CPD_SpecificData[idx].iNumSpectators = -1
|
|
CPD_SpecificData[idx].bThisIsAFleeSpawn = FALSE
|
|
ENDREPEAT
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// @SBA - Populates the given specifc datum from the given entry in the permanent data
|
|
/// PARAMS:
|
|
/// iPerformDataIndex - the index into the permanent CPD_PerformData array
|
|
/// iSpecificDataIndex - the index into the specific CPD_SpecificData array
|
|
PROC POPULATE_SPECIFIC_SPAWN_DATA(INT iPerformDataIndex, INT iSpecificDataIndex)
|
|
CPD_SpecificData[iSpecificDataIndex].SpawnZone = CPD_PerformData[iPerformDataIndex].SpawnZone
|
|
CPD_SpecificData[iSpecificDataIndex].vClownPos = CPD_PerformData[iPerformDataIndex].vClownPos
|
|
CPD_SpecificData[iSpecificDataIndex].fClownHead = CPD_PerformData[iPerformDataIndex].fClownHead
|
|
CPD_SpecificData[iSpecificDataIndex].bThisIsAFleeSpawn = CPD_PerformData[iPerformDataIndex].bThisIsAFleeSpawn
|
|
CPRINTLN(DEBUG_MISSION, "POPULATE_SPECIFIC_SPAWN_DATA: Populating specific array datum. Spawn location = ", CPD_SpecificData[iSpecificDataIndex].vClownPos)
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// @SBA - Fills the CPD_SpecificData array with valid data, returns a randomized index into it
|
|
/// PARAMS:
|
|
/// SpawnZone - The zone to search for useable spawn data
|
|
/// iReturnSpecificIndex - Returns by ref the index into the re-build CPD_SpecificData array
|
|
/// bFleeOnly - if TRUE, will return only spawn data flagged to be flee only (no clown)
|
|
/// RETURNS:
|
|
/// TRUE if able to find useable data; FALSE otherwise
|
|
FUNC BOOL GET_SPECIFIC_PERFORMANCE_SPAWN_DATA(SPAWN_ZONES SpawnZone, INT &iReturnSpecificIndex, BOOL bFleeOnly)
|
|
INT idx, iCount = 0
|
|
|
|
RESET_SPECIFIC_PERFORMANCE_DATA()
|
|
|
|
// comb the permanent data of the appropriate zone for data
|
|
REPEAT kiPerformDataSize idx
|
|
IF CPD_PerformData[idx].SpawnZone = SpawnZone
|
|
// Make sure we're getting only the data we want re: fleeing
|
|
IF CPD_PerformData[idx].bThisIsAFleeSpawn = bFleeOnly
|
|
// Make sure there's room in the array
|
|
IF iCount < COUNT_OF(CPD_SpecificData)
|
|
// Make sure peds aren't too close to the prospective spawn location
|
|
// Any more condtions? Do we want a max distance too?
|
|
//IF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), CPD_PerformData[idx].vClownPos) > kfPerformMinSpawnDist
|
|
IF NOT IS_ANY_PED_NEAR_POINT(CPD_PerformData[idx].vClownPos, kfPerformMinSpawnDist)
|
|
POPULATE_SPECIFIC_SPAWN_DATA(idx, iCount)
|
|
iCount ++
|
|
ELSE
|
|
CPRINTLN(DEBUG_MISSION, "GET_SPECIFIC_PERFORMANCE_SPAWN_DATA: *** Spawn point ", CPD_PerformData[idx].vClownPos, " is too close to an existing ped ***")
|
|
ENDIF
|
|
ELSE
|
|
CPRINTLN(DEBUG_MISSION, "GET_SPECIFIC_PERFORMANCE_SPAWN_DATA: *** Wha' hoppend? CPD_SpecificData Array Is Full! ***")
|
|
idx = kiPerformDataSize
|
|
ENDIF
|
|
ELSE
|
|
CPRINTLN(DEBUG_MISSION, "GET_SPECIFIC_PERFORMANCE_SPAWN_DATA: Expecting bFleeOnly = ", bFleeOnly, ". But got: ", NOT bFleeOnly)
|
|
ENDIF
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
IF iCount = 0
|
|
CPRINTLN(DEBUG_MISSION, "GET_SPECIFIC_PERFORMANCE_SPAWN_DATA: *** No good spawn locations for clown performance! ***")
|
|
ELSE
|
|
// Pick a random index for the specific data array
|
|
iReturnSpecificIndex = GET_RANDOM_INT_IN_RANGE(0, iCount)
|
|
CPRINTLN(DEBUG_MISSION, "GET_SPECIFIC_PERFORMANCE_SPAWN_DATA: Returning TRUE. Random index = ", iReturnSpecificIndex,". Spawn location = ", CPD_SpecificData[iReturnSpecificIndex].vClownPos, ".")
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Converts a rotation vector into a normalised direction vector (basically the direction an entity would move if it moved forward at the current rotation).
|
|
/// For example: a rotation of <<0.0, 0.0, 45.0>> gives a direction vector of <<-0.707107, 0.707107, 0.0>>
|
|
/// PARAMS:
|
|
/// v_rot - The rotation vector
|
|
/// RETURNS:
|
|
/// The direction vector
|
|
FUNC VECTOR B2_CONVERT_ROT_TO_DIR_VECTOR(VECTOR v_rot)
|
|
RETURN <<-SIN(v_rot.z) * COS(v_rot.x), COS(v_rot.z) * COS(v_rot.x), SIN(v_rot.x)>>
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Set a random variation for a ped body part
|
|
/// PARAMS
|
|
/// ind - ped index
|
|
/// pc - ped component enum
|
|
PROC RESET_MISSION_VALUES()
|
|
fClownSpawnRadius = 40.0
|
|
|
|
iNextSpawnTimer = 0
|
|
iMinPedSpawnTime = 500
|
|
iMaxPedSpawnTime = 2000
|
|
iMinGeneratorPedSpawnTime = 1500
|
|
iMaxGeneratorPedSpawnTime = 3000
|
|
fNoSpawnPlayerDist = 12.0
|
|
|
|
iMaxActivePeds = 5
|
|
iClownPedsSpawned = 0
|
|
iClownPedsKilled = 0
|
|
iClownGeneratorsDestroyed = 0
|
|
bGenerateAutoClowns = FALSE
|
|
|
|
bInitialClowns = FALSE
|
|
iStageTimer = 0
|
|
iAliveClownCount = 0
|
|
iAliveClownGeneratorCount = 0
|
|
|
|
ePassOutStage = POS_SETUP
|
|
|
|
//@SBA - additional reinitializations
|
|
bSkipAllowed = FALSE
|
|
bLastClownAggressive = FALSE
|
|
psPerformanceState = PS_MIME_CLOWN_MIME
|
|
bPerformancePedsCreated = FALSE
|
|
bPlayedGunSmokeFX = FALSE
|
|
bTrevFirstLine = FALSE
|
|
bClownGeneratorRantTimerSet = FALSE
|
|
bHasTrevorDupClownRanted = FALSE
|
|
iDuplicatesCount = 0
|
|
|
|
INITIAILIZE_PERFORMANCE_DATA()
|
|
INITIALIZE_SPECTATOR_OFFSET_DATA()
|
|
ENDPROC
|
|
|
|
PROC CLEANUP_SCREEN_FX()
|
|
CPRINTLN(DEBUG_MISSION, "[BARRY 2] - CLEANING UP SCREEN FX")
|
|
|
|
IF ANIMPOSTFX_IS_RUNNING(FX_DrugsIn)
|
|
ANIMPOSTFX_STOP(FX_DrugsIn)
|
|
ENDIF
|
|
IF ANIMPOSTFX_IS_RUNNING(FX_DrugsSkip)
|
|
ANIMPOSTFX_STOP(FX_DrugsSkip)
|
|
ENDIF
|
|
IF ANIMPOSTFX_IS_RUNNING(FX_DrugsOut)
|
|
ANIMPOSTFX_STOP(FX_DrugsOut)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Tells us if the mission is in combat state
|
|
FUNC BOOL IS_MISSION_IN_COMBAT_STAGE()
|
|
INT i1 = ENUM_TO_INT(SE_INTRO)
|
|
INT i2 = ENUM_TO_INT(SE_PASSOUT)
|
|
INT i = ENUM_TO_INT(stageEnum)
|
|
|
|
RETURN (i > i1) AND (i < i2)
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Forces the players weapon
|
|
PROC FORCE_PLAYER_WEAPON()
|
|
WEAPON_TYPE wpn
|
|
|
|
//REMOVE_ALL_PED_WEAPONS(PLAYER_PED_ID())
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
IF NOT HAS_PED_GOT_WEAPON(PLAYER_PED_ID(), playerWeapon)
|
|
GIVE_WEAPON_TO_PED(PLAYER_PED_ID(), playerWeapon, INFINITE_AMMO, TRUE, TRUE)
|
|
CPRINTLN(DEBUG_MISSION, "Player doesn't have a gun lets give him one.")
|
|
ELSE
|
|
IF NOT GET_CURRENT_PED_WEAPON(PLAYER_PED_ID(), wpn) OR (wpn <> playerWeapon)
|
|
CPRINTLN(DEBUG_MISSION, "Player has a gun but doesn't want to equip it for some reason.")
|
|
SET_CURRENT_PED_WEAPON(PLAYER_PED_ID(), playerWeapon, TRUE)
|
|
ELSE
|
|
CPRINTLN(DEBUG_MISSION, "Player - Should have the gun and it should in his hand")
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ADD_AMMO_TO_PED(PLAYER_PED_ID(), playerWeapon, 10000)
|
|
SET_PED_INFINITE_AMMO(PLAYER_PED_ID(), TRUE, playerWeapon)
|
|
SET_PED_CURRENT_WEAPON_VISIBLE(PLAYER_PED_ID(), TRUE)
|
|
SET_PED_CAN_SWITCH_WEAPON(PLAYER_PED_ID(), FALSE)
|
|
IF DOES_WEAPON_TAKE_WEAPON_COMPONENT(playerWeapon, WEAPONCOMPONENT_ASSAULTSHOTGUN_CLIP_02)
|
|
GIVE_WEAPON_COMPONENT_TO_PED(PLAYER_PED_ID(), playerWeapon, WEAPONCOMPONENT_ASSAULTSHOTGUN_CLIP_02)
|
|
CPRINTLN(DEBUG_MISSION, "Player - Should have the gun clip component")
|
|
ENDIF
|
|
|
|
SET_PED_USING_ACTION_MODE(PLAYER_PED_ID(), TRUE, -1)
|
|
//FORCE_PED_MOTION_STATE(PLAYER_PED_ID(), MS_ACTIONMODE_IDLE, TRUE)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
|
|
PROC HANDLE_LOCK_PLAYER_IN_FRONT_OF_TABLE()
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
IF IS_PLAYER_CONTROL_ON(PLAYER_ID())
|
|
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), (<<189.13988, -955.80487, 29.09192>>), (<<187.52740, -955.01056,31.091919>>), 2.5000000)
|
|
CPRINTLN(DEBUG_MISSION, "HANDLE_LOCK_PLAYER_IN_FRONT_OF_TABLE: Locking player")
|
|
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE, SPC_LEAVE_CAMERA_CONTROL_ON)
|
|
IF IS_ENTITY_ALIVE(sRCLauncherDataLocal.pedID[0])
|
|
TASK_TURN_PED_TO_FACE_ENTITY(PLAYER_PED_ID(), sRCLauncherDataLocal.pedID[0])
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Set a random variation for a ped body part
|
|
/// PARAMS
|
|
/// ind - ped index
|
|
/// pc - ped component enum
|
|
PROC SET_RANDOM_PED_COMPONENT_VARIATION(PED_INDEX ind, PED_COMPONENT pc)
|
|
INT iDrawable = GET_RANDOM_INT_IN_RANGE(0, GET_NUMBER_OF_PED_DRAWABLE_VARIATIONS(ind, pc))
|
|
INT iTexture = GET_RANDOM_INT_IN_RANGE(0, GET_NUMBER_OF_PED_TEXTURE_VARIATIONS(ind, pc, iDrawable))
|
|
SET_PED_COMPONENT_VARIATION(ind, pc, iDrawable, iTexture)
|
|
ENDPROC
|
|
|
|
|
|
/// PURPOSE:
|
|
/// Reset combat parameters
|
|
/// PARAMS:
|
|
/// cpm - combat param reference
|
|
PROC RESET_MISSION_COMBAT_PARAMETERS(COMBAT_PARAMETERS &cpm)
|
|
cpm.hFiringPattern = FIRING_PATTERN_DELAY_FIRE_BY_ONE_SEC
|
|
|
|
cpm.fWeaponAccuracy1 = 0.12
|
|
cpm.fWeaponAccuracy2 = 0.12
|
|
|
|
cpm.fNearBlankChance = 0.1
|
|
cpm.fFarBlankChance = 0.3
|
|
|
|
cpm.fMinTimeBetweenPeeks = 10.0
|
|
cpm.fMaxTimeBetweenPeeks = 11.0
|
|
|
|
cpm.fMinTimeBetweenCoverBurst = 1.25
|
|
cpm.fMaxTimeBetweenCoverBurst = 2.25
|
|
|
|
cpm.fMinBurstDurationTime = 2.0
|
|
cpm.fMaxBurstDurationTime = 2.5
|
|
|
|
cpm.iMinShootRate = 25
|
|
cpm.iMaxShootRate = 60
|
|
|
|
cpm.fPlayerWeaponDefenseModifier = 0.2
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Sets the mission fail reason and goes into the fail state
|
|
/// PARAMS:
|
|
/// sFailReason - text label of fail reason
|
|
PROC SET_MISSION_FAILED(STRING sFailReason)
|
|
IF stageEnum <> SE_FAILED
|
|
CPRINTLN(DEBUG_MISSION, "Setting mission as failed. ", sFailReason)
|
|
sFailString = sFailReason
|
|
stageProgress = SP_LOADING
|
|
stageEnum = SE_FAILED
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
// Check if any clown in the array is within a given radius of a given point (True if so)
|
|
FUNC BOOL IS_ANY_CLOWN_NEAR_POINT(VECTOR vPoint, FLOAT fRadius)
|
|
INT i
|
|
REPEAT (COUNT_OF(clownPed)) i
|
|
IF DOES_ENTITY_EXIST(clownPed[i].pedID)
|
|
IF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(clownPed[i].pedID, vPoint) < fRadius
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDREPEAT
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Given a point does a ground z check, checks it not in a no spawn zone and there are no peds too close
|
|
/// PARAMS:
|
|
/// pos -
|
|
/// RETURNS:
|
|
/// True / False
|
|
FUNC BOOL CHECK_SPAWN_POINT_IS_OK(VECTOR &pos)
|
|
VECTOR spawnPos
|
|
FLOAT z
|
|
FLOAT fPedCheckRadius = 2.0
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
VECTOR vPlayerPos = GET_ENTITY_COORDS(PLAYER_PED_ID())
|
|
#ENDIF
|
|
|
|
CPRINTLN(DEBUG_MISSION, "CHECK_SPAWN_POINT_IS_OK: START")
|
|
|
|
// do a safety check here (special case wave 6)
|
|
IF stageEnum != SE_WAVE6
|
|
IF NOT GET_SAFE_COORD_FOR_PED(pos, FALSE, spawnPos, GSC_FLAG_NOT_ISOLATED | GSC_FLAG_NOT_INTERIOR | GSC_FLAG_NOT_WATER)
|
|
CPRINTLN(DEBUG_MISSION, "CHECK_SPAWN_POINT_IS_OK: - FAILED - PLAYER POSITION:", vPlayerPos)
|
|
CPRINTLN(DEBUG_MISSION, "CHECK_SPAWN_POINT_IS_OK: - FAILED - COULDN'T GET SAFE POINT FOR:", pos)
|
|
RETURN FALSE
|
|
ENDIF
|
|
// @SBA - for wave 6 we don't want to bother with the safe coords as it spawns clowns to far afield.
|
|
// Also tighten up the radius for checking if other peds are in the way
|
|
ELSE
|
|
spawnPos = pos
|
|
fPedCheckRadius = 0.5
|
|
// For last wave, keep above ground
|
|
IF spawnPos.z < 29.1
|
|
CPRINTLN(DEBUG_MISSION, "CHECK_SPAWN_POINT_IS_OK: spawnPos.z = ", spawnPos.z, ". Setting to 30.0")
|
|
spawnPos.z = 30
|
|
ENDIF
|
|
ENDIF
|
|
CPRINTLN(DEBUG_MISSION, "CHECK_SPAWN_POINT_IS_OK: spawnPos = ", spawnPos)
|
|
|
|
IF NOT GET_GROUND_Z_FOR_3D_COORD(spawnPos, z)
|
|
CPRINTLN(DEBUG_MISSION, "CHECK_SPAWN_POINT_IS_OK: - FAILED - PLAYER POSITION:", vPlayerPos)
|
|
CPRINTLN(DEBUG_MISSION, "CHECK_SPAWN_POINT_IS_OK: - FAILED - COULDN'T GET GROUND Z FOR:", spawnPos)
|
|
RETURN FALSE
|
|
ENDIF
|
|
//CPRINTLN(DEBUG_MISSION, "CHECK_SPAWN_POINT_IS_OK: 2nd!")
|
|
|
|
spawnPos.z = z
|
|
|
|
// Ok to spawn anywhere if it's the last wave
|
|
IF stageEnum != SE_WAVE6
|
|
IF (GET_DISTANCE_BETWEEN_COORDS(spawnPos, vBattleCenter) > fBattleRadius)
|
|
CPRINTLN(DEBUG_MISSION, "CHECK_SPAWN_POINT_IS_OK: - FAILED - PLAYER POSITION:", vPlayerPos)
|
|
CPRINTLN(DEBUG_MISSION, "CHECK_SPAWN_POINT_IS_OK: - FAILED - POINT IS OUT OF BATTLE RADIUS:", spawnPos)
|
|
RETURN FALSE
|
|
ENDIF
|
|
ENDIF
|
|
//CPRINTLN(DEBUG_MISSION, "CHECK_SPAWN_POINT_IS_OK: 3rd!")
|
|
|
|
IF (GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), spawnPos) < fNoSpawnPlayerDist)
|
|
CPRINTLN(DEBUG_MISSION, "CHECK_SPAWN_POINT_IS_OK: - FAILED - PLAYER POSITION:", vPlayerPos)
|
|
CPRINTLN(DEBUG_MISSION, "CHECK_SPAWN_POINT_IS_OK: - FAILED - POINT IS WITHIN NOSPAWNPLAYERDIST:", spawnPos)
|
|
RETURN FALSE
|
|
ENDIF
|
|
//CPRINTLN(DEBUG_MISSION, "CHECK_SPAWN_POINT_IS_OK: 4th!")
|
|
|
|
// check there isn't a ped in the same area
|
|
//IF IS_ANY_PED_IN_SPHERE(spawnPos, fPedCheckRadius, PLAYER_PED_ID())
|
|
|
|
IF (bUseIsAreaOccupied)
|
|
IF IS_ANY_PED_IN_SPHERE(spawnPos, fPedCheckRadius, PLAYER_PED_ID())
|
|
CPRINTLN(DEBUG_MISSION, "CHECK_SPAWN_POINT_IS_OK: - FAILED - PLAYER POSITION:", vPlayerPos)
|
|
CPRINTLN(DEBUG_MISSION, "CHECK SPAWN POINT IS OK - FAILED - IS_ANY_PED_IN_SPHERE - SPAWN POS:[", spawnPos.x, ",", spawnPos.y, ",", spawnPos.z, "] THERE IS ANOTHER ALIEN WITHIN ", fPedCheckRadius, " METERS")
|
|
RETURN FALSE
|
|
ENDIF
|
|
ELSE
|
|
IF IS_ANY_PED_NEAR_POINT(spawnPos, fPedCheckRadius)
|
|
CPRINTLN(DEBUG_MISSION, "CHECK_SPAWN_POINT_IS_OK: - FAILED - PLAYER POSITION:", vPlayerPos)
|
|
CPRINTLN(DEBUG_MISSION, "CHECK SPAWN POINT IS OK - FAILED - IS_ANY_PED_NEAR_POINT - SPAWN POS:[", spawnPos.x, ",", spawnPos.y, ",", spawnPos.z, "] THERE IS ANOTHER ALIEN WITHIN ", fPedCheckRadius, " METERS")
|
|
RETURN FALSE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// last stage
|
|
IF stageEnum = SE_WAVE6
|
|
VECTOR temppos = spawnPos
|
|
IF NOT GET_SAFE_COORD_FOR_PED(spawnPos, FALSE, temppos, GSC_FLAG_NOT_ISOLATED | GSC_FLAG_NOT_INTERIOR | GSC_FLAG_NOT_WATER)
|
|
CPRINTLN(DEBUG_MISSION, "CHECK_SPAWN_POINT_IS_OK: - FAILED - PLAYER POSITION:", vPlayerPos)
|
|
CPRINTLN(DEBUG_MISSION, "CHECK_SPAWN_POINT_IS_OK: FINAL WAVE - FAILED - COULDN'T GET SAFE POINT FOR: spawnPos = ", spawnPos)
|
|
RETURN FALSE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// to fix B*174705
|
|
IF IS_POINT_IN_ANGLED_AREA(spawnPos, <<211.885208,-931.168457,29.691504>>, <<220.750351,-918.622864,32.441525>>, 2.000000)
|
|
CPRINTLN(DEBUG_MISSION, "CHECK_SPAWN_POINT_IS_OK: - FAILED - PLAYER POSITION:", vPlayerPos)
|
|
CPRINTLN(DEBUG_MISSION, "CHECK_SPAWN_POINT_IS_OK: - FAILED - POINT IS BURIED IN WALL DESCRIBED IN B*174705 - POINT:", spawnPos)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
IF (spawnPos.z < 28.58)
|
|
CPRINTLN(DEBUG_MISSION, "CHECK_SPAWN_POINT_IS_OK: - FAILED - PLAYER POSITION:", vPlayerPos)
|
|
CPRINTLN(DEBUG_MISSION, "CHECK_SPAWN_POINT_IS_OK: - FAILED - POINT IS TOO FAR BELOW GROUND THIS WILL CAUSE - B*174705 - POINT:", spawnPos)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
pos = spawnPos
|
|
RETURN TRUE
|
|
ENDFUNC
|
|
|
|
//----------------------
|
|
// DIALOG FUNCTIONS
|
|
//----------------------
|
|
|
|
/// PURPOSE:
|
|
/// Returns True if God Text is on
|
|
FUNC BOOL ARE_OBJECTIVES_BEING_DISPLAYED()
|
|
IF IS_THIS_PRINT_BEING_DISPLAYED("B2_PRIME") // Kill the ~r~clowns.~s~
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
IF IS_THIS_PRINT_BEING_DISPLAYED("B2_WARN") // Return to the ~r~battle.~s~
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Returns True if God Text is on
|
|
FUNC BOOL ARE_OBJECTIVES_OR_TEXT_BEING_DISPLAYED()
|
|
IF IS_THIS_PRINT_BEING_DISPLAYED("B2_PRIME") // Kill the ~r~clowns.~s~
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
IF IS_THIS_PRINT_BEING_DISPLAYED("B2_WARN") // Return to the ~r~battle.~s~
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
IF IS_ANY_TEXT_BEING_DISPLAYED(sLocateData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF)
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Initial sets up Trevors Ranting during the battle
|
|
PROC SETUP_TREVOR_DIALOG()
|
|
ADD_PED_FOR_DIALOGUE(convoPlayer, ENUM_TO_INT(CHAR_TREVOR), PLAYER_PED_ID(), "TREVOR")
|
|
|
|
iNextFreakDialogTime = GET_RANDOM_INT_IN_RANGE(20000, 30000)
|
|
iNextFightDialogTime = GET_RANDOM_INT_IN_RANGE(10000, 20000)
|
|
bHasInitialOutburst = FALSE
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Runs the fight rants Trevor can shout out during the battle
|
|
PROC PLAY_TREVOR_FREAK_DIALOG_LINES()
|
|
IF IS_SCRIPTED_CONVERSATION_ONGOING()
|
|
EXIT
|
|
ENDIF
|
|
|
|
// stop if we're outside the battle area
|
|
IF NOT bIsPlayerInBattleArea
|
|
EXIT
|
|
ENDIF
|
|
|
|
IF (GET_GAME_TIMER() < iNextFreakDialogTime)
|
|
EXIT
|
|
ENDIF
|
|
|
|
IF (NOT bHasInitialOutburst)
|
|
EXIT
|
|
ENDIF
|
|
|
|
IF ARE_OBJECTIVES_OR_TEXT_BEING_DISPLAYED()
|
|
EXIT
|
|
ENDIF
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF bDebugTTYSpew = TRUE
|
|
CPRINTLN(DEBUG_MISSION, "Trying to play Freak Rant - Time:", (GET_GAME_TIMER() - iMissionDebugTime) / 1000)
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
ADD_PED_FOR_DIALOGUE(convoPlayer, ENUM_TO_INT(CHAR_TREVOR), PLAYER_PED_ID(), "TREVOR")
|
|
IF CREATE_CONVERSATION(convoPlayer, "BARY2AU", "BARY2_FREAK", CONV_PRIORITY_LOW)
|
|
CPRINTLN(DEBUG_MISSION, "Freak Rant - Time:", (GET_GAME_TIMER() - iMissionDebugTime) / 1000)
|
|
iNextFreakDialogTime = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(20000, 40000)
|
|
// don't let fight line play too quickly after
|
|
IF iNextFightDialogTime - GET_GAME_TIMER() < kiDialogTimeCheck
|
|
CPRINTLN(DEBUG_MISSION, "Fight Rant Time too soon: resetting.")
|
|
iNextFightDialogTime = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(3000, 5000)
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Runs the fight rants Trevor can shout out during the battle
|
|
PROC PLAY_TREVOR_FIGHT_DIALOG_LINES()
|
|
IF IS_SCRIPTED_CONVERSATION_ONGOING()
|
|
EXIT
|
|
ENDIF
|
|
|
|
IF (GET_GAME_TIMER() < iNextFightDialogTime)
|
|
EXIT
|
|
ENDIF
|
|
|
|
IF (NOT bHasInitialOutburst)
|
|
EXIT
|
|
ENDIF
|
|
|
|
IF ARE_OBJECTIVES_OR_TEXT_BEING_DISPLAYED()
|
|
EXIT
|
|
ENDIF
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF bDebugTTYSpew = TRUE
|
|
CPRINTLN(DEBUG_MISSION, "Trying to play Trevor Fight Rant - Time:", (GET_GAME_TIMER() - iMissionDebugTime) / 1000)
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
ADD_PED_FOR_DIALOGUE(convoPlayer, ENUM_TO_INT(CHAR_TREVOR), PLAYER_PED_ID(), "TREVOR")
|
|
IF CREATE_CONVERSATION(convoPlayer, "BARY2AU", "BARY2_FIGHT", CONV_PRIORITY_LOW)
|
|
CPRINTLN(DEBUG_MISSION, "Fight Rant - Time:", (GET_GAME_TIMER() - iMissionDebugTime) / 1000)
|
|
iNextFightDialogTime = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(10000, 20000)
|
|
// don't let freak line play too quickly after
|
|
IF iNextFreakDialogTime - GET_GAME_TIMER() < kiDialogTimeCheck
|
|
CPRINTLN(DEBUG_MISSION, "Freak Rant Time too soon: resetting.")
|
|
iNextFreakDialogTime = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(3000, 5000)
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// This handles playing Trevor's shouts during battle
|
|
PROC PLAY_TREVOR_CLOWN_GENERATOR_RANT()
|
|
|
|
IF ARE_OBJECTIVES_BEING_DISPLAYED()
|
|
IF IS_ANY_TEXT_BEING_DISPLAYED(sLocateData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF)
|
|
EXIT
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF IS_SCRIPTED_CONVERSATION_ONGOING()
|
|
EXIT
|
|
ENDIF
|
|
|
|
ADD_PED_FOR_DIALOGUE(convoPlayer, ENUM_TO_INT(CHAR_TREVOR), PLAYER_PED_ID(), "TREVOR")
|
|
IF CREATE_CONVERSATION(convoPlayer, "BARY2AU", "BARY2_ONEOFF", CONV_PRIORITY_MEDIUM)
|
|
CPRINTLN(DEBUG_MISSION, "Trevor Destroy Clown Car Ranting")
|
|
bHasTrevorClownGeneratorRanted = TRUE
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
|
|
/// PURPOSE:
|
|
/// This handles playing a specific Trevor shouts during battle
|
|
PROC HANDLE_PLAY_TREVOR_CLOWN_DUPLICATION_RANT()
|
|
|
|
IF bHasTrevorDupClownRanted
|
|
EXIT
|
|
ENDIF
|
|
|
|
IF iClownPedsSpawned < kiNumDuplicates
|
|
EXIT
|
|
ENDIF
|
|
|
|
START_TIMER_NOW(tmrGeneral)
|
|
|
|
IF NOT TIMER_DO_WHEN_READY(tmrGeneral, 1.500)
|
|
EXIT
|
|
ENDIF
|
|
|
|
IF ARE_OBJECTIVES_BEING_DISPLAYED()
|
|
IF IS_ANY_TEXT_BEING_DISPLAYED(sLocateData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF)
|
|
EXIT
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF IS_SCRIPTED_CONVERSATION_ONGOING()
|
|
EXIT
|
|
ENDIF
|
|
|
|
ADD_PED_FOR_DIALOGUE(convoPlayer, ENUM_TO_INT(CHAR_TREVOR), PLAYER_PED_ID(), "TREVOR")
|
|
IF CREATE_CONVERSATION(convoPlayer, "BARY2AU", "BARY2_DUPE", CONV_PRIORITY_HIGH)
|
|
CPRINTLN(DEBUG_MISSION, "Trevor Duplicate Clown Ranting")
|
|
bHasTrevorDupClownRanted = TRUE
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
|
|
//----------------------
|
|
// @SBA - SPECTATOR FUNCTIONS
|
|
//----------------------
|
|
|
|
/// PURPOSE:
|
|
/// Initializes data for a spectator
|
|
/// PARAMS:
|
|
/// iIndex - index in the struct array
|
|
/// mnModel - ped model to use
|
|
/// vSpawnPos - where to spawn
|
|
/// fSpawnHead - what heading to use when spawned
|
|
PROC INITIALIZE_SPECTATOR_DATA(INT iIndex, VECTOR vSpawnPos, FLOAT fSpawnHead)
|
|
CPRINTLN(DEBUG_MISSION, "INITIALIZE_SPECTATOR_DATA: Initializing Spectator ", iIndex)
|
|
IF GET_RANDOM_BOOL()
|
|
ssSpectator[iIndex].mnModel = mnSpectatorFemale
|
|
ELSE
|
|
ssSpectator[iIndex].mnModel = mnSpectatorMale
|
|
ENDIF
|
|
ssSpectator[iIndex].vSpawnPos = vSpawnPos
|
|
ssSpectator[iIndex].fSpawnHead = fSpawnHead
|
|
ssSpectator[iIndex].bIsActive = FALSE
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Initializes the data for all the spectators
|
|
PROC INITIALIZE_PERFORMANCE_SPECTATOR_DATA()
|
|
INITIALIZE_SPECTATOR_DATA(0, (<<177.0773, -961.4605, 30.0923>>), 27.2)
|
|
INITIALIZE_SPECTATOR_DATA(1, (<<177.190, -959.988, 30.0923>>), 22.8)
|
|
INITIALIZE_SPECTATOR_DATA(2, (<<178.863, -960.405, 30.0923>>), 62.8)
|
|
INITIALIZE_SPECTATOR_DATA(3, (<<178.8338, -959.1136, 30.0923>>), 67.8)
|
|
INITIALIZE_SPECTATOR_DATA(4, (<<178.2160, -956.9438, 30.0923>>), 115.1)
|
|
ENDPROC
|
|
|
|
|
|
/// PURPOSE:
|
|
/// Returns True if a spectator ped is ready to be re-used
|
|
/// PARAMS:
|
|
/// out - index in array to next free clown (this gets overwritten)
|
|
FUNC BOOL GET_FREE_SPECTATOR_INDEX(INT &out)
|
|
INT i = 0
|
|
|
|
out = -1
|
|
REPEAT (COUNT_OF(ssSpectator)) i
|
|
IF (ssSpectator[i].bIsActive = FALSE)
|
|
out = i
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Creates a spectator for the given array index
|
|
/// RETURNS:
|
|
/// TRUE when they are created
|
|
FUNC BOOL CREATE_SPECTATOR_PED(INT iIndex)
|
|
FLOAT z
|
|
|
|
IF GET_GROUND_Z_FOR_3D_COORD(ssSpectator[iIndex].vSpawnPos, z)
|
|
ssSpectator[iIndex].vSpawnPos.z = z
|
|
ENDIF
|
|
|
|
IF (ssSpectator[iIndex].vSpawnPos.z < 28.0)
|
|
CPRINTLN(DEBUG_MISSION, "FAILED - TRYING TO CREATE SPECTATOR ", iIndex," AT POS ", ssSpectator[iIndex].vSpawnPos ," Z IS TOO LOW.")
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
ssSpectator[iIndex].piPed = CREATE_PED(PEDTYPE_MISSION, ssSpectator[iIndex].mnModel, ssSpectator[iIndex].vSpawnPos, ssSpectator[iIndex].fSPawnHead)
|
|
IF NOT DOES_ENTITY_EXIST(ssSpectator[iIndex].piPed)
|
|
CPRINTLN(DEBUG_MISSION, "FAILED - TRYING TO CREATE SPECTATOR ", iIndex," AT POS ", ssSpectator[iIndex].vSpawnPos ," - PED ISN'T VALID")
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
DISABLE_PED_INJURED_ON_GROUND_BEHAVIOUR(ssSpectator[iIndex].piPed)
|
|
STOP_PED_SPEAKING(ssSpectator[iIndex].piPed, TRUE)
|
|
SET_PED_DIES_WHEN_INJURED(ssSpectator[iIndex].piPed, TRUE)
|
|
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(ssSpectator[iIndex].piPed, TRUE)
|
|
|
|
SET_PED_MONEY(ssSpectator[iIndex].piPed, 0)
|
|
SET_ENTITY_HEALTH(ssSpectator[iIndex].piPed, 100)
|
|
|
|
ssSpectator[iIndex].ssState = SS_FADE_IN
|
|
ssSpectator[iIndex].bIsActive = TRUE
|
|
ssSpectator[iIndex].bJustFlee = FALSE
|
|
CPRINTLN(DEBUG_MISSION, "CREATED SPECTATOR ", iIndex," AT POS ", ssSpectator[iIndex].vSpawnPos)
|
|
|
|
RETURN TRUE
|
|
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Cleans up a single spectator ped
|
|
/// PARAMS:
|
|
/// ent - reference to spectator ped
|
|
/// keepTask - set this to keep tasks after cleanup
|
|
PROC CLEANUP_SPECTATOR_PED(SPECTATOR_STRUCT &ent, BOOL keepTask = TRUE)
|
|
// IF (ent.bIsActive = FALSE)
|
|
// EXIT
|
|
// ENDIF
|
|
|
|
SAFE_RELEASE_PED(ent.piPed, keepTask, TRUE)
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Deletes a single spectator ped
|
|
/// PARAMS:
|
|
/// ent - reference to spectator ped
|
|
PROC DELETE_SPECTATOR_PED(SPECTATOR_STRUCT &ent)
|
|
// clear active flag
|
|
IF (ent.bIsActive = TRUE)
|
|
ent.bIsActive = FALSE
|
|
ENDIF
|
|
|
|
SAFE_DELETE_PED(ent.piPed)
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Cleans all spectator peds
|
|
/// PARAMS:
|
|
/// keepTask - set this to keep tasks after cleanup
|
|
PROC CLEANUP_ALL_SPECTATOR_PEDS(BOOL keepTask = TRUE)
|
|
INT i = 0
|
|
REPEAT COUNT_OF(ssSpectator) i
|
|
CLEANUP_SPECTATOR_PED(ssSpectator[i], keepTask)
|
|
ENDREPEAT
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Deletes all spectator peds
|
|
PROC DELETE_ALL_SPECTATOR_PEDS()
|
|
INT i = 0
|
|
REPEAT COUNT_OF(ssSpectator) i
|
|
DELETE_SPECTATOR_PED(ssSpectator[i])
|
|
ENDREPEAT
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Returns active number of spectator peds
|
|
FUNC INT GET_ALIVE_SPECTATOR_PED_COUNT()
|
|
INT i = 0
|
|
INT cnt = 0
|
|
|
|
REPEAT (COUNT_OF(ssSpectator)) i
|
|
IF DOES_ENTITY_EXIST(ssSpectator[i].piPed)
|
|
IF NOT IS_PED_INJURED(ssSpectator[i].piPed)
|
|
cnt ++
|
|
ENDIF
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
//CPRINTLN(DEBUG_MISSION, "GET_ALIVE_SPECTATOR_PED_COUNT: Number of alive spectators = ", cnt)
|
|
RETURN cnt
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Spawn the spectators for a clown performance
|
|
/// PARAMS:
|
|
/// SpawnData - preset Spawn data
|
|
/// iNumberOfSpectators - How many spectators to make
|
|
/// bJustFlee - If set TRUE, spectators will instantly go into flee state once faded in
|
|
PROC SPAWN_SPECTATORS_FOR_GENERAL_PERFORMANCE(CLOWN_PERFORMANCE_DATA &SpawnData, INT iNumberOfSpectators, BOOL bJustFlee = FALSE)
|
|
INT idx // The counter
|
|
INT iIndex // Valid index of spectator
|
|
|
|
IF iNumberOfSpectators > kiNumberOfSpectators
|
|
CPRINTLN(DEBUG_MISSION, "*** SPAWN_SPECTATORS_FOR_GENERAL_PERFORMANCE: Too many spectators requested! iNumberOfSpectators = ", iNumberOfSpectators)
|
|
EXIT
|
|
ENDIF
|
|
|
|
FLOAT fHead
|
|
|
|
REPEAT iNumberOfSpectators idx
|
|
CPRINTLN(DEBUG_MISSION, "SPAWN_SPECTATORS_FOR_GENERAL_PERFORMANCE: idx = ", idx)
|
|
IF GET_FREE_SPECTATOR_INDEX(iIndex)
|
|
CPRINTLN(DEBUG_MISSION, "SPAWN_SPECTATORS_FOR_GENERAL_PERFORMANCE: Found free spectator index: ", iIndex)
|
|
VECTOR vPos = GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(SpawnData.vClownPos, SpawnData.fClownHead, vSpectatorPerformOffsets[idx])
|
|
// We want the spectators to face the opposite direction if there is no clown
|
|
IF bJustFlee
|
|
fHead = GET_HEADING_BETWEEN_VECTORS_2D(SpawnData.vClownPos, vPos)
|
|
ELSE
|
|
fHead = GET_HEADING_BETWEEN_VECTORS_2D(vPos, SpawnData.vClownPos)
|
|
ENDIF
|
|
INITIALIZE_SPECTATOR_DATA(iIndex, vPos, fHead)
|
|
CREATE_SPECTATOR_PED(iIndex)
|
|
|
|
IF iApplauseSound = -1
|
|
AND NOT bJustFlee
|
|
PLAY_SOUND_FROM_ENTITY(iApplauseSound, "CROWD_WATCHING", ssSpectator[iIndex].piPed)
|
|
ENDIF
|
|
|
|
ssSpectator[iIndex].bJustFlee = bJustFlee
|
|
ELSE
|
|
CPRINTLN(DEBUG_MISSION, "SPAWN_SPECTATORS_FOR_GENERAL_PERFORMANCE: Spectator index NOT free: ", iIndex)
|
|
ENDIF
|
|
ENDREPEAT
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// @SBA - determines if the spectator with the given index should run away
|
|
/// PARAMS:
|
|
/// iSpecIndex - index of current spectator we're checking
|
|
/// RETURNS:
|
|
/// TRUE if spectator should start running
|
|
FUNC BOOL SHOULD_SPECTATOR_FLEE(INT iSpecIndex)
|
|
|
|
// bail if this is the intro lead-out, as we want them to stay to get killed
|
|
IF stageEnum = SE_PERFORMANCE
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
VECTOR vPedLoc = GET_ENTITY_COORDS(ssSpectator[iSpecIndex].piPed, FALSE)
|
|
|
|
IF ssSpectator[iSpecIndex].bJustFlee
|
|
CPRINTLN(DEBUG_MISSION, "SHOULD_SPECTATOR_FLEE: This spectator was set to flee: ", iSpecIndex)
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
IF HAS_BULLET_IMPACTED_IN_AREA(vPedLoc, kiCHaseSpectatorsDist - 1)
|
|
CPRINTLN(DEBUG_MISSION, "SHOULD_SPECTATOR_FLEE: Bullet impact! This spectator should flee: ", iSpecIndex)
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
INT idx
|
|
REPEAT COUNT_OF(ssSpectator) idx
|
|
IF idx != iSpecIndex
|
|
IF DOES_ENTITY_EXIST(ssSpectator[idx].piPed)
|
|
IF IS_PED_DEAD_OR_DYING(ssSpectator[idx].piPed)
|
|
OR IS_PED_INJURED(ssSpectator[idx].piPed)
|
|
IF GET_DISTANCE_BETWEEN_COORDS(vPedLoc, GET_ENTITY_COORDS(ssSpectator[idx].piPed, FALSE), FALSE) < kfMinSpectatorWitnessDist
|
|
|
|
CPRINTLN(DEBUG_MISSION, "SHOULD_SPECTATOR_FLEE: Nearby spectator death! This spectator should flee: ", iSpecIndex)
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDREPEAT
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// @SBA - start and maintain spectator clown-watching anim
|
|
/// PARAMS:
|
|
/// iIndex - index into the spectator array
|
|
PROC HANDLE_SPECTATOR_CLOWN_WATCHING_ANIM(INT iIndex)
|
|
IF ssSpectator[iIndex].mnModel = mnSpectatorMale
|
|
IF NOT IS_ENTITY_PLAYING_ANIM(ssSpectator[iIndex].piPed, sSpectatorMaleAnimDict, sSpectatorMaleAnimClip)
|
|
TASK_PLAY_ANIM(ssSpectator[iIndex].piPed, sSpectatorMaleAnimDict, sSpectatorMaleAnimClip, NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1,
|
|
AF_LOOPING, GET_RANDOM_FLOAT_IN_RANGE(0,0.5))
|
|
ENDIF
|
|
ELSE
|
|
IF NOT IS_ENTITY_PLAYING_ANIM(ssSpectator[iIndex].piPed, sSpectatorFemAnimDict, sSpectatorFemAnimClip)
|
|
TASK_PLAY_ANIM(ssSpectator[iIndex].piPed, sSpectatorFemAnimDict, sSpectatorFemAnimClip, NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1,
|
|
AF_LOOPING, GET_RANDOM_FLOAT_IN_RANGE(0,0.5))
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// @SBA - handles thew state machine for spectators
|
|
/// PARAMS:
|
|
/// iIndex -
|
|
PROC UPDATE_SPECTATOR(INT iIndex)
|
|
|
|
IF NOT DOES_ENTITY_EXIST(ssSpectator[iIndex].piPed)
|
|
EXIT
|
|
ENDIF
|
|
|
|
IF NOT ssSpectator[iIndex].bIsActive
|
|
EXIT
|
|
ENDIF
|
|
|
|
IF IS_ENTITY_DEAD(ssSpectator[iIndex].piPed)
|
|
OR IS_PED_DEAD_OR_DYING(ssSpectator[iIndex].piPed)
|
|
// Checking here for safety, since one shot from player may kill spectator
|
|
IF ssSpectator[iIndex].ssState < SS_GOING
|
|
CPRINTLN(DEBUG_MISSION, "UPDATE_SPECTATOR: Spectator ", iIndex," has been killed!")
|
|
IF HAS_PED_BEEN_DAMAGED_BY_WEAPON(ssSpectator[iIndex].piPed, playerWeapon)
|
|
CPRINTLN(DEBUG_MISSION, "UPDATE_SPECTATOR: Spectator ", iIndex," has been killed by player!")
|
|
ENDIF
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(iApplauseSound)
|
|
ssSpectator[iIndex].iTimer = GET_GAME_TIMER() + CLOWN_FADE_TIME
|
|
ssSpectator[iIndex].ssState = SS_GOING
|
|
ENDIF
|
|
ENDIF
|
|
|
|
SWITCH ssSpectator[iIndex].ssState
|
|
CASE SS_FADE_IN
|
|
ssSpectator[iIndex].fSpectAlpha += GET_FRAME_TIME() * 512.0 // HALF SECOND FADE OUT
|
|
IF (ssSpectator[iIndex].fSpectAlpha < 2.0)
|
|
SET_ENTITY_VISIBLE(ssSpectator[iIndex].piPed, FALSE)
|
|
ELSE
|
|
SET_ENTITY_VISIBLE(ssSpectator[iIndex].piPed, TRUE)
|
|
IF (ssSpectator[iIndex].fSpectAlpha > 255.0)
|
|
ssSpectator[iIndex].fSpectAlpha = 255.0
|
|
RESET_ENTITY_ALPHA(ssSpectator[iIndex].piPed)
|
|
CPRINTLN(DEBUG_MISSION, "UPDATE_SPECTATOR: Spectator ", iIndex, " has faded in.")
|
|
|
|
ssSpectator[iIndex].ssState = SS_WATCH_CLOWN
|
|
ELSE
|
|
IF IS_ENTITY_ON_SCREEN(ssSpectator[iIndex].piPed)
|
|
SET_PED_ALPHA(ssSpectator[iIndex].piPed, FLOOR(ssSpectator[iIndex].fSpectAlpha), iSpecAlphaCounter)
|
|
ELSE
|
|
RESET_ENTITY_ALPHA(ssSpectator[iIndex].piPed)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE SS_WATCH_CLOWN
|
|
// @SBA - if a spectator is shot, advance to killing them
|
|
IF HAS_ENTITY_BEEN_DAMAGED_BY_ANY_PED(ssSpectator[iIndex].piPed)
|
|
CPRINTLN(DEBUG_MISSION, "UPDATE_SPECTATOR: SS_WATCH_CLOWN: Spectator ", iIndex," has been damaged!")
|
|
ssSpectator[iIndex].ssState = SS_KILL
|
|
// @SBA - if the player's weapon type was used, set flag so remaining spec's flee
|
|
IF HAS_PED_BEEN_DAMAGED_BY_WEAPON(ssSpectator[iIndex].piPed, playerWeapon)
|
|
CPRINTLN(DEBUG_MISSION, "UPDATE_SPECTATOR: Spectator ", iIndex," was damaged by player!")
|
|
ENDIF
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(iApplauseSound)
|
|
|
|
ELIF SHOULD_SPECTATOR_FLEE(iIndex)
|
|
CPRINTLN(DEBUG_MISSION, "UPDATE_SPECTATOR: SS_WATCH_CLOWN: Spectator ", iIndex," is going to flee!")
|
|
ssSpectator[iIndex].ssState = SS_REACT_TO_DANGER
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(iApplauseSound)
|
|
ELSE
|
|
HANDLE_SPECTATOR_CLOWN_WATCHING_ANIM(iIndex)
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE SS_REACT_TO_DANGER
|
|
// Have remaining living spectators flee
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
IF IS_ENTITY_ALIVE(ssSpectator[iIndex].piPed)
|
|
// If spectator was told to just flee, change flee origin to behind them
|
|
VECTOR vFleeOrigin
|
|
IF ssSpectator[iIndex].bJustFlee
|
|
vFleeOrigin = <<0,-2.5,0>>
|
|
ELSE
|
|
vFleeOrigin = <<0,1.75,0>>
|
|
ENDIF
|
|
SEQUENCE_INDEX seq
|
|
CPRINTLN(DEBUG_MISSION, "UPDATE_SPECTATOR: SS_REACT_TO_DANGER for Spectator ", iIndex)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
// @SBA - the pause looks bad and cower isn't quick enough. Something else?
|
|
//TASK_PAUSE(NULL, GET_RANDOM_INT_IN_RANGE(200, 600))
|
|
TASK_SMART_FLEE_COORD(NULL, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(ssSpectator[iIndex].piPed, vFleeOrigin), 200.0, -1)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
CLEAR_PED_TASKS(ssSpectator[iIndex].piPed)
|
|
TASK_PERFORM_SEQUENCE(ssSpectator[iIndex].piPed, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
// @SBA - commenting out per audio feedback
|
|
//IF GET_RANDOM_BOOL()
|
|
// MAKE_PED_SCREAM(ssSpectator[iIndex].piPed)
|
|
//ENDIF
|
|
// send this to a fleeing handler
|
|
ssSpectator[iIndex].ssState = SS_FLEEING
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE SS_FLEEING
|
|
// See if fleeing spectator has gotten far enough
|
|
IF NOT IS_ENTITY_IN_ANGLED_AREA(ssSpectator[iIndex].piPed, battleAreaOuter.vPosition[0], battleAreaOuter.vPosition[1], battleAreaOuter.fWidth)
|
|
CPRINTLN(DEBUG_MISSION, "UPDATE_SPECTATOR: Spectator ", iIndex, " is done fleeing. Going to SS_GOING.")
|
|
ssSpectator[iIndex].iTimer = GET_GAME_TIMER() + 500
|
|
ssSpectator[iIndex].ssState = SS_KILL
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE SS_KILL
|
|
CPRINTLN(DEBUG_MISSION, "UPDATE_SPECTATOR: SS_KILL for Spectator ", iIndex)
|
|
EXPLODE_PED_HEAD(ssSpectator[iIndex].piPed)
|
|
APPLY_DAMAGE_TO_PED(ssSpectator[iIndex].piPed, 1000, TRUE)
|
|
ssSpectator[iIndex].iTimer = GET_GAME_TIMER() + 500
|
|
ssSpectator[iIndex].ssState = SS_GOING
|
|
BREAK
|
|
|
|
CASE SS_GOING
|
|
IF (GET_GAME_TIMER() > ssSpectator[iIndex].iTimer)
|
|
IF IS_ENTITY_DEAD(ssSpectator[iIndex].piPed) OR IS_PED_INJURED(ssSpectator[iIndex].piPed)
|
|
// @SBA - keeping this in case we want to get fancier
|
|
// IF NOT IS_ENTITY_IN_AIR(ssSpectator[iIndex].piPed)
|
|
// vec = GET_ENTITY_COORDS(ssSpectator[iIndex].piPed)
|
|
// IF GET_GROUND_Z_FOR_3D_COORD(vec, z)
|
|
// vec.z = z
|
|
// vec.z += 1.0
|
|
// ENDIF
|
|
//
|
|
// START_PARTICLE_FX_NON_LOOPED_AT_COORD("scr_clown_death", vec, GET_ENTITY_ROTATION(ssSpectator[iIndex].piPed), 2.0)
|
|
// PLAY_SOUND_FROM_COORD(-1, "clown_die_wrapper", vec, "BARRY_02_SOUNDSET")
|
|
|
|
CPRINTLN(DEBUG_MISSION, "UPDATE_SPECTATOR: SS_GOING for Spectator ", iIndex)
|
|
ssSpectator[iIndex].iTimer = GET_GAME_TIMER() + CLOWN_FADE_TIME
|
|
ssSpectator[iIndex].fSpectAlpha = 255.0
|
|
ssSpectator[iIndex].ssState = SS_GONE
|
|
|
|
// ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE SS_GONE
|
|
IF (GET_GAME_TIMER() > ssSpectator[iIndex].iTimer)
|
|
|
|
ssSpectator[iIndex].fSpectAlpha -= GET_FRAME_TIME() * 1024.0 // HALF SECOND FADE OUT
|
|
IF (ssSpectator[iIndex].fSpectAlpha < 0.0)
|
|
ssSpectator[iIndex].fSpectAlpha = 0.0
|
|
ENDIF
|
|
|
|
SET_PED_ALPHA(ssSpectator[iIndex].piPed, FLOOR(ssSpectator[iIndex].fSpectAlpha), iSpecAlphaCounter) // @SBA - do we want a separate counter?
|
|
|
|
IF (ssSpectator[iIndex].fSpectAlpha <= 0.0) OR NOT IS_ENTITY_ON_SCREEN(ssSpectator[iIndex].piPed)
|
|
CPRINTLN(DEBUG_MISSION, "UPDATE_SPECTATOR: SS_GONE for Spectator ", iIndex)
|
|
ssSpectator[iIndex].bIsActive = FALSE
|
|
DELETE_SPECTATOR_PED(ssSpectator[iIndex])
|
|
ssSpectator[iIndex].ssState = SS_DONE
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE SS_DONE
|
|
// nothing
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// @SBA - iterates over whole spectator array and updates state machine
|
|
PROC UPDATE_SPECTATOR_PEDS()
|
|
INT i = 0
|
|
|
|
REPEAT (COUNT_OF(ssSpectator)) i
|
|
UPDATE_SPECTATOR(i)
|
|
ENDREPEAT
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// @SBA - Finds the closest spectator to the passed in ped
|
|
/// PARAMS:
|
|
/// piPedToCheck - the ped from which you are measuring the distance
|
|
/// piClosestSpectator - returns index of closest spectator
|
|
/// RETURNS:
|
|
/// TRUE if there is a valid ped that is close enough
|
|
FUNC BOOL GET_CLOSEST_SPECTATOR_TO_PED(PED_INDEX piPedToCheck, PED_INDEX &piClosestSpectator, FLOAT fIgnoreDist = kiLongIgnoreSpectatorsDist)
|
|
|
|
IF IS_PED_INJURED(piPedToCheck)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
INT i
|
|
FLOAT fNewDistance, fClosestDistance = 1000
|
|
// reset this
|
|
piClosestSpectator = NULL
|
|
|
|
// iterate over spectators to find the closest who's still alive
|
|
FOR i = 0 TO COUNT_OF(ssSpectator) - 1
|
|
IF DOES_ENTITY_EXIST(ssSpectator[i].piPed)
|
|
IF NOT IS_ENTITY_DEAD(ssSpectator[i].piPed)
|
|
IF NOT IS_PED_INJURED(ssSpectator[i].piPed)
|
|
AND NOT IS_PED_DEAD_OR_DYING(ssSpectator[i].piPed)
|
|
fNewDistance = GET_DISTANCE_BETWEEN_PEDS(piPedToCheck, ssSpectator[i].piPed)
|
|
IF fNewDistance < fClosestDistance
|
|
fClosestDistance = fNewDistance
|
|
piClosestSpectator = ssSpectator[i].piPed
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDFOR
|
|
|
|
// If there is a valid target that is not too far away, return TRUE
|
|
IF piClosestSpectator != NULL
|
|
AND fClosestDistance < fIgnoreDist
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
// reset this to NULL since we're not returning TRUE
|
|
piClosestSpectator = NULL
|
|
RETURN FALSE
|
|
|
|
ENDFUNC
|
|
|
|
//----------------------
|
|
// CLOWN FUNCTIONS
|
|
//----------------------
|
|
|
|
|
|
/// PURPOSE:
|
|
/// This is stuff which is common to both cleaning up and deleting a clown ped
|
|
/// PARAMS:
|
|
/// ent - reference to clown ped
|
|
PROC SHARED_CLEANUP_AND_DELETE_CLOWN_PED(CLOWN_PED &ent)
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(ent.laughSoundID)
|
|
SAFE_REMOVE_BLIP(ent.blipID)
|
|
ent.bIsActive = FALSE
|
|
ent.pedID = NULL
|
|
ent.blipID = NULL
|
|
ent.bIsDead = FALSE
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Cleans up a single clown ped
|
|
/// PARAMS:
|
|
/// ent - reference to clown ped
|
|
/// keepTask - set this to keep tasks after cleanup
|
|
PROC CLEANUP_CLOWN_PED(CLOWN_PED &ent, BOOL keepTask = TRUE)
|
|
IF (ent.bIsActive = FALSE)
|
|
EXIT
|
|
ENDIF
|
|
|
|
SAFE_RELEASE_PED(ent.pedID, keepTask, TRUE)
|
|
SHARED_CLEANUP_AND_DELETE_CLOWN_PED(ent)
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Deletes a single clown ped
|
|
/// PARAMS:
|
|
/// ent - reference to clown ped
|
|
PROC DELETE_CLOWN_PED(CLOWN_PED &ent)
|
|
IF (ent.bIsActive = FALSE)
|
|
EXIT
|
|
ENDIF
|
|
|
|
SAFE_DELETE_PED(ent.pedID)
|
|
SHARED_CLEANUP_AND_DELETE_CLOWN_PED(ent)
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Cleans all clown peds
|
|
/// PARAMS:
|
|
/// keepTask - set this to keep tasks after cleanup
|
|
PROC CLEANUP_ALL_CLOWN_PEDS(BOOL keepTask = TRUE)
|
|
INT i = 0
|
|
REPEAT COUNT_OF(clownPed) i
|
|
CLEANUP_CLOWN_PED(clownPed[i], keepTask)
|
|
ENDREPEAT
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Deletes all clown peds
|
|
PROC DELETE_ALL_CLOWN_PEDS()
|
|
INT i = 0
|
|
REPEAT COUNT_OF(clownPed) i
|
|
DELETE_CLOWN_PED(clownPed[i])
|
|
ENDREPEAT
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Returns True if clown ped is living
|
|
/// PARAMS:
|
|
/// rp - reference to clown ped
|
|
FUNC BOOL IS_CLOWN_PED_ALIVE(CLOWN_PED &rp)
|
|
IF NOT rp.bIsActive
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
IF NOT DOES_ENTITY_EXIST(rp.pedID)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
RETURN NOT rp.bIsDead AND NOT (rp.aState = CS_DEAD) AND NOT IS_PED_INJURED(rp.pedID)
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Go through clown array and find the first living clown
|
|
/// RETURNS:
|
|
/// the index of that clown
|
|
FUNC INT GET_INDEX_OF_FIRST_LIVING_CLOWN_IN_ARRAY()
|
|
INT i = 0
|
|
|
|
REPEAT (COUNT_OF(clownPed)) i
|
|
IF IS_CLOWN_PED_ALIVE(clownPed[i])
|
|
CPRINTLN(DEBUG_MISSION, "GET_INDEX_OF_FIRST_LIVING_CLOWN_IN_ARRAY: Returning an index for clown: ", i)
|
|
RETURN i
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
RETURN -1
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Returns True if clown ped is in dying state (or dead)
|
|
/// PARAMS:
|
|
/// rp - reference to clown ped
|
|
FUNC BOOL IS_CLOWN_DYING(CLOWN_PED &rp)
|
|
RETURN (rp.aState = CS_DYING) OR (rp.aState = CS_DEAD)
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Returns True if clown ped is ready to be re-used
|
|
/// PARAMS:
|
|
/// rp - reference to clown ped
|
|
FUNC BOOL IS_CLOWN_PED_FREE(CLOWN_PED &rp)
|
|
IF NOT rp.bIsActive
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
IF NOT DOES_ENTITY_EXIST(rp.pedID)
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN NOT rp.bIsDead AND NOT (rp.aState = CS_DEAD)
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Sets the type of the clown.
|
|
/// PARAMS:
|
|
/// clown - the struct of the clown
|
|
/// TypeOfClown - The clown's starting type enum that you want to switch the clown to
|
|
PROC SET_CLOWN_TYPE(CLOWN_PED &clown, STARTING_CLOWN_TYPES TypeOfClown)
|
|
clown.ClownType = TypeOfClown
|
|
CPRINTLN(DEBUG_MISSION, "SET_CLOWN_TYPE: Clown type has been set to: ", ENUM_TO_INT(clown.ClownType))
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Gets the clown's starting type
|
|
/// PARAMS:
|
|
/// clown - struct
|
|
/// RETURNS:
|
|
/// The clown's starting type enum
|
|
FUNC STARTING_CLOWN_TYPES GET_CLOWN_TYPE(CLOWN_PED &clown)
|
|
RETURN clown.ClownType
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Returns active number of clown peds
|
|
FUNC INT GET_ALIVE_CLOWN_PED_COUNT()
|
|
INT i = 0
|
|
INT cnt = 0
|
|
|
|
REPEAT (COUNT_OF(clownPed)) i
|
|
IF IS_CLOWN_PED_ALIVE(clownPed[i])
|
|
cnt ++
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
RETURN cnt
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Returns True if a clown ped is ready to be re-used
|
|
/// PARAMS:
|
|
/// out - index in array to next free clown (this gets overwritten)
|
|
FUNC BOOL GET_FREE_CLOWN_PED_INDEX(INT &out)
|
|
INT i = 0
|
|
|
|
out = -1
|
|
REPEAT (COUNT_OF(clownPed)) i
|
|
IF (clownPed[i].bIsActive = FALSE)
|
|
out = i
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Determines if the clown should do a performance for spectators
|
|
/// PARAMS:
|
|
/// clown - struct
|
|
/// RETURNS:
|
|
/// TRUE if the clown is set to perform and there are avaialble spectators to spawn; False otherwise.
|
|
FUNC BOOL SHOULD_CLOWN_PERFORM(CLOWN_PED &clown)
|
|
|
|
// If he's not set to perform, then he shouldn't perform
|
|
IF GET_CLOWN_TYPE(clown) != SCT_PERFORM
|
|
RETURN FALSE
|
|
ENDIF
|
|
// Are there any available spectator slots? If so, ok to perform
|
|
IF GET_ALIVE_SPECTATOR_PED_COUNT() < kiNumberOfSpectators
|
|
CPRINTLN(DEBUG_MISSION, "SHOULD_CLOWN_PERFORM: Returning TRUE!")
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
|
|
ENDFUNC
|
|
|
|
|
|
/// PURPOSE:
|
|
/// @SBA - checks if the clown has a valid spectator target
|
|
/// PARAMS:
|
|
/// clown - the clown struct
|
|
/// RETURNS:
|
|
/// TRUE if the clown has a valid, living target, FALSE if not
|
|
FUNC BOOL DOES_CLOWN_HAVE_SPECTATOR_TARGET(CLOWN_PED &clown)
|
|
IF IS_CLOWN_PED_ALIVE(clown)
|
|
IF clown.piClosestSpec != NULL
|
|
IF NOT IS_ENTITY_DEAD(clown.piClosestSpec)
|
|
IF NOT IS_PED_INJURED(clown.piClosestSpec)
|
|
AND NOT IS_PED_DEAD_OR_DYING(clown.piClosestSpec)
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// @SBA - checks if any clown currently has a valid spectator target
|
|
/// RETURNS:
|
|
/// TRUE if any clown has a valid target, FALSE if not
|
|
FUNC BOOL DOES_ANY_CLOWN_HAVE_SPECTATOR_TARGET()
|
|
INT i = 0
|
|
REPEAT COUNT_OF(clownPed) i
|
|
IF DOES_CLOWN_HAVE_SPECTATOR_TARGET(clownPed[i])
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDREPEAT
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Toggle clown's aggressiveness (used for combatting spectators)
|
|
/// PARAMS:
|
|
/// clown -
|
|
/// bMakeAggressive - TRUE = make agressive; FALSE = remove agressiveness
|
|
/// bForPlayer - If TRUE, soften the deadliness for combat with the player
|
|
PROC MAKE_CLOWN_MORE_AGGRESSIVE(CLOWN_PED &clown, BOOL bMakeAggressive, BOOL bForPlayer = FALSE)
|
|
|
|
// Hijack the reset if this is the last clown to keep him aggressive to the player
|
|
IF bLastClownAggressive
|
|
IF NOT bMakeAggressive
|
|
bMakeAggressive = TRUE
|
|
bForPlayer = TRUE
|
|
CPRINTLN(DEBUG_MISSION, "MAKE_CLOWN_MORE_AGGRESSIVE: LAST CLOWN!")
|
|
ENDIF
|
|
ENDIF
|
|
|
|
CPRINTLN(DEBUG_MISSION, "MAKE_CLOWN_MORE_AGGRESSIVE: Clown Aggressiveness = ", bMakeAggressive, ". For Player = ", bForPlayer)
|
|
|
|
IF NOT bForPlayer
|
|
SET_PED_COMBAT_ATTRIBUTES(clown.pedID, CA_USE_PROXIMITY_FIRING_RATE, bMakeAggressive)
|
|
ELSE
|
|
SET_PED_COMBAT_ATTRIBUTES(clown.pedID, CA_CAN_CHARGE, TRUE)
|
|
ENDIF
|
|
SET_PED_COMBAT_ATTRIBUTES(clown.pedID, CA_AGGRESSIVE, bMakeAggressive)
|
|
SET_PED_COMBAT_ATTRIBUTES(clown.pedID, CA_USE_COVER, NOT bMakeAggressive)
|
|
// Turning on
|
|
IF bMakeAggressive
|
|
IF NOT bForPlayer
|
|
SET_PED_COMBAT_ABILITY(clown.pedID, CAL_PROFESSIONAL)
|
|
SET_PED_ACCURACY(clown.pedID, 70)
|
|
ELSE
|
|
SET_PED_ACCURACY(clown.pedID, 12)
|
|
SET_PED_COMBAT_ABILITY(clown.pedID, CAL_AVERAGE)
|
|
REMOVE_PED_DEFENSIVE_AREA(clown.pedID, TRUE)
|
|
SET_PED_DEFENSIVE_SPHERE_ATTACHED_TO_PED(clown.pedID, PLAYER_PED_ID(), <<0, 0, 0>>, GET_RANDOM_FLOAT_IN_RANGE(20.0, 40.0), FALSE)
|
|
ENDIF
|
|
SET_PED_COMBAT_MOVEMENT(clown.pedID, CM_WILLADVANCE)
|
|
SET_PED_COMBAT_RANGE(clown.pedID, CR_NEAR)
|
|
// Turning off
|
|
ELSE
|
|
SET_PED_ACCURACY(clown.pedID, 12)
|
|
SET_PED_COMBAT_MOVEMENT(clown.pedID, CM_DEFENSIVE)
|
|
SET_PED_COMBAT_RANGE(clown.pedID, CR_MEDIUM)
|
|
SET_PED_COMBAT_ABILITY(clown.pedID, CAL_AVERAGE)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Get the last living clown and make him go after the player so the player won't have to hunt
|
|
/// PARAMS:
|
|
/// bGateVar - Passes in by ref the gating bool. Be sure to rest after the last clown is dead.
|
|
PROC MAKE_LAST_CLOWN_AGGRESSIVE(BOOL &bGateVar)
|
|
|
|
IF NOT bGateVar
|
|
IF iAliveClownCount = 1
|
|
INT iLastClownIdx = GET_INDEX_OF_FIRST_LIVING_CLOWN_IN_ARRAY()
|
|
IF iLastClownIdx != -1
|
|
MAKE_CLOWN_MORE_AGGRESSIVE(ClownPed[iLastClownIdx], TRUE, TRUE)
|
|
// Don't dance soon
|
|
ClownPed[iLastClownIdx].iDanceTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(iMaxClownDanceDelay, iMaxClownDanceDelay + iMinClownDanceDelay)
|
|
REMOVE_PED_DEFENSIVE_AREA(ClownPed[iLastClownIdx].pedID)
|
|
ELSE
|
|
CPRINTLN(DEBUG_MISSION, "MAKE_LAST_CLOWN_AGGRESSIVE: last clown not found!")
|
|
ENDIF
|
|
bGateVar = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// @SBA - Have the Clown shoot the spectators.
|
|
/// PARAMS:
|
|
/// piClown -
|
|
PROC CLOWN_ATTACKS_SPECTATORS(CLOWN_PED &clown)
|
|
|
|
IF IS_PED_INJURED(clown.pedID)
|
|
OR IS_PED_INJURED(clown.piClosestSpec)
|
|
EXIT
|
|
ENDIF
|
|
|
|
SEQUENCE_INDEX seqAttack
|
|
|
|
IF (GET_SCRIPT_TASK_STATUS(clown.pedID, SCRIPT_TASK_PERFORM_SEQUENCE) <> PERFORMING_TASK)
|
|
CPRINTLN(DEBUG_MISSION, "CLOWN_ATTACKS_SPECTATORS: Clown shooting at spectator!")
|
|
OPEN_SEQUENCE_TASK(seqAttack)
|
|
// if target is close by, shoot first
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(clown.pedID, clown.piClosestSpec, FALSE) <= kiCHaseSpectatorsDist
|
|
TASK_AIM_GUN_AT_ENTITY(NULL, clown.piClosestSpec, GET_RANDOM_INT_IN_RANGE(250, 500))
|
|
TASK_SHOOT_AT_ENTITY(NULL, clown.piClosestSpec, GET_RANDOM_INT_IN_RANGE(250, 500), FIRING_TYPE_CONTINUOUS)
|
|
ENDIF
|
|
TASK_GO_TO_ENTITY_WHILE_AIMING_AT_ENTITY(NULL, clown.piClosestSpec, clown.piClosestSpec, PEDMOVE_RUN, TRUE, 3.0, 4.5)
|
|
TASK_COMBAT_PED(NULL, clown.piClosestSpec, COMBAT_PED_PREVENT_CHANGING_TARGET)
|
|
CLOSE_SEQUENCE_TASK(seqAttack)
|
|
//CLEAR_PED_TASKS(clown.pedID)
|
|
TASK_PERFORM_SEQUENCE(clown.pedID, seqAttack)
|
|
CLEAR_SEQUENCE_TASK(seqAttack)
|
|
IF GET_RANDOM_BOOL()
|
|
CPRINTLN(DEBUG_MISSION, "CLOWN_ATTACKS_SPECTATORS: Clown laughs!")
|
|
PLAY_PED_AMBIENT_SPEECH_WITH_VOICE(clown.pedID, "CLOWN_LAUGH", "CLOWNS", SPEECH_PARAMS_FORCE_SHOUTED_CLEAR)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
// ~~~~~~~~~~
|
|
|
|
/// PURPOSE:
|
|
/// Creates one clown ped
|
|
/// PARAMS
|
|
/// clown - clown ped reference
|
|
/// task - clown task
|
|
/// pos - clown spawn point
|
|
/// head - clown spawn heading
|
|
/// bForceHeavyWeapon - @SBA - some weapon variety
|
|
/// safecheck - do ground and safe check on pos before spawning
|
|
/// forcecombat - doesn't do delay after telportining in
|
|
/// areacheck - if this is true we check to see if no spawn areas are being used
|
|
FUNC BOOL CREATE_CLOWN_PED(CLOWN_PED &clown, VECTOR pos, FLOAT head = 0.0, BOOL bForceHeavyWeapon = FALSE, BOOL bNoWeapon = FALSE)
|
|
INT rnd
|
|
FLOAT z
|
|
|
|
// don't care about height for final wave - clowns need to spawn anywhere
|
|
IF stageEnum != SE_WAVE6
|
|
IF GET_GROUND_Z_FOR_3D_COORD(pos, z)
|
|
pos.z = z
|
|
ENDIF
|
|
|
|
IF (pos.z < 28.0)
|
|
RETURN FALSE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
clown.pedID = CREATE_PED(PEDTYPE_MISSION, clownModel, pos, head)
|
|
IF NOT DOES_ENTITY_EXIST(clown.pedID)
|
|
CPRINTLN(DEBUG_MISSION, "FAILED - TRYING TO CREATE CLOWN PED AT POS ", pos ," - PED ISN'T VALID")
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
clown.laughSoundID = -1
|
|
|
|
SET_ENTITY_HEADING_FACE_PLAYER(clown.pedID)
|
|
SET_PED_COMBAT_ATTRIBUTES(clown.pedID, CA_USE_PROXIMITY_FIRING_RATE, FALSE)
|
|
SET_PED_RANDOM_COMPONENT_VARIATION(clown.pedID)
|
|
|
|
SET_PED_RELATIONSHIP_GROUP_HASH(clown.pedID, RELGROUPHASH_HATES_PLAYER)
|
|
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(clown.pedID, TRUE)
|
|
|
|
rnd = GET_ENTITY_MAX_HEALTH(clown.pedID) / 2
|
|
SET_ENTITY_HEALTH(clown.pedID, rnd)
|
|
SET_ENTITY_MAX_HEALTH(clown.pedID, rnd)
|
|
SET_ENTITY_IS_TARGET_PRIORITY(clown.pedID, TRUE)
|
|
SET_PED_MONEY(clown.pedID, 0)
|
|
//SET_ENTITY_HEALTH(clown.pedID, GET_ENTITY_MAX_HEALTH(clown.pedID))
|
|
|
|
SET_PED_ALERTNESS(clown.pedID, AS_MUST_GO_TO_COMBAT)
|
|
SET_PED_TARGET_LOSS_RESPONSE(clown.pedID, TLR_NEVER_LOSE_TARGET)
|
|
SET_PED_COMBAT_ATTRIBUTES(clown.pedID, CA_AGGRESSIVE, FALSE)
|
|
SET_PED_COMBAT_ATTRIBUTES(clown.pedID, CA_USE_COVER, TRUE)
|
|
|
|
SET_PED_COMBAT_MOVEMENT(clown.pedID, CM_DEFENSIVE)
|
|
STOP_PED_SPEAKING(clown.pedID, TRUE)
|
|
SET_AMBIENT_VOICE_NAME(clown.pedID, "CLOWNS")
|
|
|
|
// @SBA - first performance clown starts with no weapon
|
|
IF NOT bNoWeapon
|
|
// @SBA - setup weapon randomly, weighted toward pistol
|
|
IF NOT bForceHeavyWeapon
|
|
rnd = GET_RANDOM_INT_IN_RANGE(0, 3)
|
|
IF rnd = 0
|
|
GIVE_WEAPON_TO_PED(clown.pedID, WEAPONTYPE_SMG, INFINITE_AMMO, TRUE)
|
|
ELSE
|
|
GIVE_WEAPON_TO_PED(clown.pedID, WEAPONTYPE_PISTOL, INFINITE_AMMO, TRUE)
|
|
ENDIF
|
|
// @SBA - otherwsie, give the heavier weapon
|
|
ELSE
|
|
GIVE_WEAPON_TO_PED(clown.pedID, WEAPONTYPE_SMG, INFINITE_AMMO, TRUE)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// setup combat movement
|
|
rnd = GET_RANDOM_INT_IN_RANGE(0, 3)
|
|
SWITCH (rnd)
|
|
CASE 0
|
|
SET_PED_COMBAT_MOVEMENT(clown.pedID, CM_DEFENSIVE) // Seeks a defensive position.
|
|
BREAK
|
|
CASE 1
|
|
SET_PED_COMBAT_MOVEMENT(clown.pedID, CM_WILLADVANCE) // Will advance forward in combat
|
|
BREAK
|
|
CASE 2
|
|
SET_PED_COMBAT_MOVEMENT(clown.pedID, CM_WILLRETREAT) // Will retreat if the enemy gets too close
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
clown.bIsActive = TRUE
|
|
clown.bIsDead = FALSE
|
|
clown.aState = CS_DELAY
|
|
clown.iDanceTimer = GET_GAME_TIMER()
|
|
// @SBA - setting normal type by default. Change it separately.
|
|
SET_CLOWN_TYPE(clown, SCT_NORMAL)
|
|
clown.vDeathPosition = <<0,0,0>>
|
|
|
|
SET_PED_CAN_PEEK_IN_COVER(clown.pedID, TRUE)
|
|
SAFE_REMOVE_BLIP(clown.blipID)
|
|
|
|
IF GET_RANDOM_BOOL()
|
|
SET_PED_PROP_INDEX(clown.pedID, ANCHOR_HEAD, 0)
|
|
ENDIF
|
|
|
|
SET_PED_CAN_COWER_IN_COVER(clown.pedID, FALSE)
|
|
SET_PED_CAN_PEEK_IN_COVER(clown.pedID, TRUE)
|
|
SET_PED_COMBAT_ATTRIBUTES(clown.pedID, CA_USE_VEHICLE, FALSE)
|
|
SET_PED_AS_ENEMY(clown.pedID, TRUE)
|
|
SET_PED_DIES_WHEN_INJURED(clown.pedID, TRUE)
|
|
SET_PED_SUFFERS_CRITICAL_HITS(clown.pedID, TRUE)
|
|
SET_PED_DEFENSIVE_SPHERE_ATTACHED_TO_PED(clown.pedID, PLAYER_PED_ID(), <<0, 0, 0>>, GET_RANDOM_FLOAT_IN_RANGE(12.0, 50.0))
|
|
|
|
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(clown.pedID, TRUE)
|
|
SET_ENTITY_INVINCIBLE(clown.pedID, TRUE)
|
|
SET_ENTITY_VISIBLE(clown.pedID, FALSE)
|
|
FREEZE_ENTITY_POSITION(clown.pedID, TRUE)
|
|
clown.iTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(125, 1000)
|
|
|
|
APPLY_COMBAT_PARAMETERS_TO_PED(clown.pedID, combatParams)
|
|
|
|
clown.danceAnim = "clown_idle_"
|
|
clown.danceAnim += GET_RANDOM_INT_IN_RANGE(0, 6)
|
|
TASK_PLAY_ANIM(clown.pedID, sMissionAnimDanceDictionary, clown.danceAnim, NORMAL_BLEND_IN, REALLY_SLOW_BLEND_OUT, -1)
|
|
|
|
// for checking how long the clown has been around
|
|
clown.iLongevityTimer = GET_GAME_TIMER() + kiAggressiveTime
|
|
|
|
//TASK_AIM_GUN_AT_ENTITY(clown.pedID, PLAYER_PED_ID(), 6000, TRUE)
|
|
CPRINTLN(DEBUG_MISSION, "CREATED CLOWN PED AT POS ", pos)
|
|
|
|
iClownPedsSpawned ++
|
|
RETURN TRUE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Sets a ped to optionally hold a defense perimeter around a vehicle
|
|
/// PARAMS:
|
|
/// pass - ped index
|
|
/// veh - car to defend
|
|
PROC SET_PED_CAR_DEFENDER(PED_INDEX pass, VEHICLE_INDEX veh)
|
|
FLOAT x, y
|
|
|
|
SET_PED_COMBAT_ATTRIBUTES(pass, CA_LEAVE_VEHICLES, TRUE)
|
|
SET_PED_COMBAT_ATTRIBUTES(pass, CA_USE_VEHICLE, FALSE)
|
|
SET_PED_COMBAT_ATTRIBUTES(pass, CA_USE_COVER, TRUE)
|
|
|
|
TASK_COMBAT_PED(pass, PLAYER_PED_ID())
|
|
|
|
x = GET_RANDOM_FLOAT_IN_RANGE(-15.0, 15.0)
|
|
y = GET_RANDOM_FLOAT_IN_RANGE(-15.0, 15.0)
|
|
SET_PED_DEFENSIVE_SPHERE_ATTACHED_TO_PED(pass, PLAYER_PED_ID(), <<x, y, 0>>, GET_RANDOM_FLOAT_IN_RANGE(20.0, 60.0), TRUE)
|
|
|
|
IF (GET_RANDOM_FLOAT_IN_RANGE() < 0.5)
|
|
SET_PED_SPHERE_DEFENSIVE_AREA(pass, GET_ENTITY_COORDS(veh), GET_RANDOM_FLOAT_IN_RANGE(10.0, 25.0), TRUE)
|
|
ELSE
|
|
SET_PED_DEFENSIVE_SPHERE_ATTACHED_TO_PED(pass, PLAYER_PED_ID(), <<0, 0, 0>>, GET_RANDOM_FLOAT_IN_RANGE(20.0, 60.0), FALSE)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Creates one clown ped
|
|
/// PARAMS
|
|
/// clown - clown ped reference
|
|
/// task - clown task
|
|
/// pos - clown spawn point
|
|
/// head - clown spawn heading
|
|
/// safecheck - do ground and safe check on pos before spawning
|
|
/// forcecombat - doesn't do delay after telportining in
|
|
/// areacheck - if this is true we check to see if no spawn areas are being used
|
|
FUNC BOOL CREATE_CLOWN_PED_IN_VEHICLE(CLOWN_PED &clown, VEHICLE_INDEX veh, BOOL bForceDriver = FALSE)
|
|
INT rnd
|
|
VEHICLE_SEAT seat = VS_DRIVER
|
|
|
|
IF (bForceDriver = FALSE)
|
|
IF NOT DOES_VEHICLE_HAVE_FREE_SEAT(veh)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
IF IS_VEHICLE_SEAT_FREE(veh, VS_BACK_LEFT)
|
|
seat = VS_BACK_LEFT
|
|
ELIF IS_VEHICLE_SEAT_FREE(veh, VS_BACK_RIGHT)
|
|
seat = VS_BACK_RIGHT
|
|
ELSE
|
|
RETURN FALSE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
clown.pedID = CREATE_PED_INSIDE_VEHICLE(veh, PEDTYPE_MISSION, clownModel, seat)
|
|
SAFE_REMOVE_BLIP(clown.blipID)
|
|
clown.blipID = CREATE_PED_BLIP(clown.pedID)
|
|
|
|
clown.laughSoundID = -1
|
|
|
|
SET_PED_COMBAT_ATTRIBUTES(clown.pedID, CA_USE_PROXIMITY_FIRING_RATE, FALSE)
|
|
SET_PED_RANDOM_COMPONENT_VARIATION(clown.pedID)
|
|
|
|
SET_PED_RELATIONSHIP_GROUP_HASH(clown.pedID, RELGROUPHASH_HATES_PLAYER)
|
|
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(clown.pedID, TRUE)
|
|
|
|
rnd = GET_ENTITY_MAX_HEALTH(clown.pedID) / 2
|
|
SET_ENTITY_HEALTH(clown.pedID, rnd)
|
|
SET_ENTITY_MAX_HEALTH(clown.pedID, rnd)
|
|
SET_ENTITY_IS_TARGET_PRIORITY(clown.pedID, TRUE)
|
|
SET_PED_MONEY(clown.pedID, 0)
|
|
|
|
SET_PED_ALERTNESS(clown.pedID, AS_MUST_GO_TO_COMBAT)
|
|
SET_PED_TARGET_LOSS_RESPONSE(clown.pedID, TLR_NEVER_LOSE_TARGET)
|
|
SET_PED_COMBAT_ATTRIBUTES(clown.pedID, CA_AGGRESSIVE, FALSE)
|
|
SET_PED_COMBAT_ATTRIBUTES(clown.pedID, CA_USE_COVER, TRUE)
|
|
SET_PED_COMBAT_MOVEMENT(clown.pedID, CM_DEFENSIVE)
|
|
STOP_PED_SPEAKING(clown.pedID, TRUE)
|
|
SET_AMBIENT_VOICE_NAME(clown.pedID, "CLOWNS")
|
|
|
|
GIVE_WEAPON_TO_PED(clown.pedID, WEAPONTYPE_PISTOL, INFINITE_AMMO, TRUE)
|
|
|
|
// setup combat movement
|
|
rnd = GET_RANDOM_INT_IN_RANGE(0, 3)
|
|
SWITCH (rnd)
|
|
CASE 0
|
|
SET_PED_COMBAT_MOVEMENT(clown.pedID, CM_DEFENSIVE) // Seeks a defensive position.
|
|
BREAK
|
|
CASE 1
|
|
SET_PED_COMBAT_MOVEMENT(clown.pedID, CM_WILLADVANCE) // Will advance forward in combat
|
|
BREAK
|
|
CASE 2
|
|
SET_PED_COMBAT_MOVEMENT(clown.pedID, CM_WILLRETREAT) // Will retreat if the enemy gets too close
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
clown.bIsActive = TRUE
|
|
clown.bIsDead = FALSE
|
|
clown.aState = CS_NULL
|
|
// @SBA - setting normal type by default. Change it separately.
|
|
SET_CLOWN_TYPE(clown, SCT_NORMAL)
|
|
|
|
// @SBA - don't let them dance too soon so they get out of van first
|
|
clown.iDanceTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(ROUND(iMinClownDanceDelay * 1.5), iMaxClownDanceDelay)
|
|
|
|
SET_PED_CAN_COWER_IN_COVER(clown.pedID, FALSE)
|
|
SET_PED_CAN_PEEK_IN_COVER(clown.pedID, TRUE)
|
|
SET_PED_COMBAT_ATTRIBUTES(clown.pedID, CA_USE_VEHICLE, FALSE)
|
|
SET_PED_AS_ENEMY(clown.pedID, TRUE)
|
|
SET_PED_DIES_WHEN_INJURED(clown.pedID, TRUE)
|
|
SET_PED_SUFFERS_CRITICAL_HITS(clown.pedID, TRUE)
|
|
SET_PED_DEFENSIVE_SPHERE_ATTACHED_TO_PED(clown.pedID, PLAYER_PED_ID(), <<0, 0, 0>>, GET_RANDOM_FLOAT_IN_RANGE(12.0, 50.0))
|
|
|
|
CLEAR_PED_TASKS(clown.pedID)
|
|
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(clown.pedID, TRUE)
|
|
APPLY_COMBAT_PARAMETERS_TO_PED(clown.pedID, combatParams)
|
|
// IF GET_RANDOM_BOOL()
|
|
// SET_PED_CAR_DEFENDER(clown.pedID, veh)
|
|
// ELSE
|
|
// TASK_COMBAT_PED(clown.pedID, PLAYER_PED_ID())
|
|
// ENDIF
|
|
|
|
IF GET_RANDOM_BOOL()
|
|
SET_PED_PROP_INDEX(clown.pedID, ANCHOR_HEAD, 0)
|
|
ENDIF
|
|
|
|
// for checking how long the clown has been around (additional time for car spawns so car defenders will stick around longer)
|
|
clown.iLongevityTimer = GET_GAME_TIMER() + (kiAggressiveTime + ROUND(kiAggressiveTime * 0.5))
|
|
|
|
iClownPedsSpawned ++
|
|
RETURN TRUE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// @SBA - picks and plays the appropriate clown dance/perform anim
|
|
/// PARAMS:
|
|
/// clown - struct
|
|
/// bJustDanceClown - TRUE = just choose dance anims; FALSE = % chance of playing mime anim instead
|
|
PROC SELECT_AND_START_CLOWN_DANCE_ANIM(CLOWN_PED &clown, BOOL bJustDanceClown)
|
|
INT iValue = -1
|
|
|
|
// If we want a chance for mime, get a random number
|
|
IF NOT bJustDanceClown
|
|
iValue = GET_RANDOM_INT_IN_RANGE(0,5)
|
|
ENDIF
|
|
CPRINTLN(DEBUG_MISSION, "SELECT_AND_START_CLOWN_DANCE_ANIM: bJustDanceClown = ", bJustDanceClown, ". Value = ", iValue)
|
|
// Do mime anim
|
|
IF iValue = 0
|
|
clown.danceAnim = sMimeAnimClip
|
|
TASK_PLAY_ANIM(clown.pedID, sMimeAnimDict, clown.danceAnim, NORMAL_BLEND_IN, SLOW_BLEND_OUT, -1, AF_DEFAULT, kfMimeStartPhase)
|
|
// do normal dance anim
|
|
ELSE
|
|
clown.danceAnim = "clown_idle_"
|
|
clown.danceAnim += GET_RANDOM_INT_IN_RANGE(0, 6)
|
|
TASK_PLAY_ANIM(clown.pedID, sMissionAnimDanceDictionary, clown.danceAnim, NORMAL_BLEND_IN, -1)
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Puts an SMG in a clown's hand in a puff of purple smoke
|
|
/// PARAMS:
|
|
/// clown - the individual clown struct
|
|
/// sAnimDict - which anim dict is being used for the performance
|
|
/// fSpawnGunPhase - the phase of the performance (dance) anim at which to play the smoke FX (should be close to end phase)
|
|
/// fEndAnimPhase - the phanse of the anim at which the performance ends and the gun spans in
|
|
/// bSmokeFX - passes ref to a bool to gate the playing of the smoke FX
|
|
/// RETURNS:
|
|
/// TRUE once the performance has ended and the clown has a gun
|
|
FUNC BOOL SPAWN_GUN_IN_CLOWNS_HAND(CLOWN_PED &clown, STRING sAnimDict, FLOAT fSpawnGunPhase, FLOAT fEndAnimPhase, BOOL &bSmokeFX)
|
|
IF IS_ENTITY_PLAYING_ANIM(clown.pedID, sAnimDict, clown.danceAnim)
|
|
// play FX for equiping gun
|
|
// @TODO - May need to change this global bool to something else if we have multiple performances at once!
|
|
IF NOT bSmokeFX
|
|
IF GET_ENTITY_ANIM_CURRENT_TIME(clown.pedID, sAnimDict, clown.danceAnim) >= fSpawnGunPhase
|
|
AND NOT HAS_PED_GOT_WEAPON(clown.pedID, WEAPONTYPE_SMG)
|
|
CPRINTLN(DEBUG_MISSION, "SPAWN_GUN_IN_CLOWNS_HAND: POOF...")
|
|
START_PARTICLE_FX_NON_LOOPED_AT_COORD("scr_clown_appears", GET_PED_BONE_COORDS(clown.pedID, BONETAG_R_HAND, (<<0,0,0>>)), (<<0,0,0>>), 0.3)
|
|
bSmokeFX = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
// Kill anim early, supply weapon if needed
|
|
IF GET_ENTITY_ANIM_CURRENT_TIME(clown.pedID, sAnimDict, clown.danceAnim) >= fEndAnimPhase
|
|
CPRINTLN(DEBUG_MISSION, "SPAWN_GUN_IN_CLOWNS_HAND: ...A GUN!")
|
|
//CLEAR_PED_TASKS(clown.pedID)
|
|
IF NOT HAS_PED_GOT_WEAPON(clown.pedID, WEAPONTYPE_SMG)
|
|
GIVE_WEAPON_TO_PED(clown.pedID, WEAPONTYPE_SMG, INFINITE_AMMO, TRUE)
|
|
ENDIF
|
|
// reset flag
|
|
bSmokeFX = FALSE
|
|
RETURN TRUE
|
|
ENDIF
|
|
ELSE
|
|
CPRINTLN(DEBUG_MISSION, "*** SPAWN_GUN_IN_CLOWNS_HAND: Clown isn't playing his anim! Anim Dict = ", sAnimDict, ". Anim Clip = ", clown.danceAnim,". Resetting...")
|
|
SELECT_AND_START_CLOWN_DANCE_ANIM(clown, TRUE)
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// This handles the clowns day to day stuff
|
|
/// PARAMS
|
|
/// clown - clown ped reference
|
|
PROC UPDATE_CLOWN_PED(CLOWN_PED &clown)
|
|
VECTOR vec
|
|
FLOAT z
|
|
|
|
IF (clown.bIsActive = FALSE)
|
|
EXIT
|
|
ENDIF
|
|
|
|
IF NOT DOES_ENTITY_EXIST(clown.pedID)
|
|
CLEANUP_CLOWN_PED(clown)
|
|
EXIT
|
|
ENDIF
|
|
|
|
// to stop assert from crying at me constantly
|
|
// as we can some time call this after a wait (in the case of updating bosses)
|
|
IS_ENTITY_OK(clown.pedID)
|
|
IS_ENTITY_OK(PLAYER_PED_ID())
|
|
|
|
IF NOT IS_CLOWN_DYING(clown)
|
|
IF IS_ENTITY_DEAD(clown.pedID) OR IS_PED_INJURED(clown.pedID) OR IS_PED_DEAD_OR_DYING(clown.pedID, FALSE)
|
|
INT iDyingTime = 500
|
|
|
|
IF (clown.aState = CS_DANCE) OR (clown.aState = CS_DANCE_START)
|
|
OR (clown.aState = CS_PERFORM_START) OR (clown.aState = CS_PERFORM_SPAWN_GUN)// @SBA - adding conditions
|
|
IF (iDancingClownPedsKilled < 6)
|
|
CPRINTLN(DEBUG_MISSION, "INCREASE BA2_DANCING_CLOWNS_KILLED")
|
|
INFORM_MISSION_STATS_OF_INCREMENT(BA2_DANCING_CLOWNS_KILLED)
|
|
ENDIF
|
|
|
|
iDancingClownPedsKilled ++
|
|
CPRINTLN(DEBUG_MISSION, "UPDATE_CLOWN_PED: DANCING CLOWNS DEAD:", iDancingClownPedsKilled)
|
|
ENDIF
|
|
|
|
// @SBA - shorten the timer if we're in wave 6
|
|
IF stageEnum = SE_WAVE6
|
|
iDyingTime = 100
|
|
ENDIF
|
|
|
|
PLAY_AMBIENT_SPEECH_FROM_POSITION("CLOWN_DEATH", "CLOWNS", GET_ENTITY_COORDS(clown.pedID), SPEECH_PARAMS_FORCE_SHOUTED_CLEAR)
|
|
|
|
clown.aState = CS_DYING
|
|
clown.iTimer = GET_GAME_TIMER() + iDyingTime
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(clown.laughSoundID)
|
|
|
|
// @SBA - clear any non-normal type
|
|
IF GET_CLOWN_TYPE(clown) != SCT_NORMAL
|
|
SET_CLOWN_TYPE(clown, SCT_NORMAL)
|
|
ENDIF
|
|
|
|
IF NOT IS_ENTITY_DEAD(clown.pedID)
|
|
EXPLODE_PED_HEAD(clown.pedID)
|
|
ENDIF
|
|
|
|
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(clown.pedID, PLAYER_PED_ID())
|
|
PLAY_TREVOR_FIGHT_DIALOG_LINES()
|
|
ENDIF
|
|
|
|
// @SBA - Remember where the clown died if we're in the right stage
|
|
IF stageEnum = SE_WAVE6
|
|
clown.vDeathPosition = GET_ENTITY_COORDS(clown.pedID)
|
|
CPRINTLN(DEBUG_MISSION, "UPDATE_CLOWN_PED: DEAD CLOWN LOCATION = ", clown.vDeathPosition)
|
|
ENDIF
|
|
|
|
SAFE_REMOVE_BLIP(clown.blipID)
|
|
iClownPedsKilled ++
|
|
ENDIF
|
|
ENDIF
|
|
|
|
SWITCH (clown.aState)
|
|
CASE CS_DELAY
|
|
IF (GET_GAME_TIMER() >= clown.iTimer)
|
|
OR stageEnum = SE_WAVE6 // @SBA - if we're in this stage just spawn, don't wait
|
|
|
|
FREEZE_ENTITY_POSITION(clown.pedID, TRUE)
|
|
START_PARTICLE_FX_NON_LOOPED_ON_ENTITY("scr_clown_appears", clown.pedID, <<0, 0, -TELEPORT_Z_DIFF>>, <<0, 0, 0>>, CLOWN_APPEAR_SIZE)
|
|
clown.iTimer = GET_GAME_TIMER() + TELEPORT_TIME
|
|
vec = GET_ENTITY_COORDS(clown.pedID)
|
|
CPRINTLN(DEBUG_MISSION, "UPDATE_CLOWN_PED: CLOWN PED SPAWNED IN AT ", vec)
|
|
clown.aState = CS_TELEPORT
|
|
ENDIF
|
|
BREAK
|
|
CASE CS_TELEPORT
|
|
IF (GET_GAME_TIMER() > clown.iTimer)
|
|
SET_ENTITY_VISIBLE(clown.pedID, TRUE)
|
|
FREEZE_ENTITY_POSITION(clown.pedID, FALSE)
|
|
SET_ENTITY_INVINCIBLE(clown.pedID, FALSE)
|
|
SAFE_REMOVE_BLIP(clown.blipID)
|
|
clown.blipID = CREATE_PED_BLIP(clown.pedID)
|
|
|
|
// @SBA - Send clown ped to correct state
|
|
SWITCH clown.ClownType
|
|
// @SBA - is clown set "special"?
|
|
CASE SCT_SPECIAL
|
|
CPRINTLN(DEBUG_MISSION, "UPDATE_CLOWN_PED: CLOWN is set SPECIAL, setting state to CS_NULL.")
|
|
clown.aState = CS_NULL
|
|
BREAK
|
|
// @SBA - is clown set to perform?
|
|
CASE SCT_PERFORM
|
|
CPRINTLN(DEBUG_MISSION, "UPDATE_CLOWN_PED: CLOWN is OK to perform, setting state to CS_PERFORM_START.")
|
|
clown.aState = CS_PERFORM_START
|
|
BREAK
|
|
CASE SCT_NORMAL
|
|
clown.aState = CS_ACTIVE
|
|
IF (clown.iDanceTimer <> 0)
|
|
CPRINTLN(DEBUG_MISSION, "UPDATE_CLOWN_PED: Setting clown state to CS_ACTIVE!")
|
|
clown.iDanceTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(iMinClownDanceDelay, iMaxClownDanceDelay)
|
|
ELSE
|
|
CPRINTLN(DEBUG_MISSION, "UPDATE_CLOWN_PED: DANCE CLOWN DANCE!!")
|
|
clown.aState = CS_DANCE_START
|
|
ENDIF
|
|
BREAK
|
|
DEFAULT
|
|
CPRINTLN(DEBUG_MISSION, "UPDATE_CLOWN_PED: Ruh Roh!! No clown type!")
|
|
clown.aState = CS_ACTIVE
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
IF GET_RANDOM_BOOL()
|
|
CPRINTLN(DEBUG_MISSION, "UPDATE_CLOWN_PED: Clown laughs!")
|
|
PLAY_PED_AMBIENT_SPEECH_WITH_VOICE(clown.pedID, "CLOWN_LAUGH", "CLOWNS", SPEECH_PARAMS_FORCE_SHOUTED_CLEAR)
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE CS_TELEPORT_OUT_START
|
|
SAFE_REMOVE_BLIP(clown.blipID)
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(clown.laughSoundID)
|
|
|
|
FREEZE_ENTITY_POSITION(clown.pedID, TRUE)
|
|
SET_ENTITY_INVINCIBLE(clown.pedID, TRUE)
|
|
START_PARTICLE_FX_NON_LOOPED_AT_COORD("scr_clown_appears", GET_ENTITY_COORDS(clown.pedID), GET_ENTITY_ROTATION(clown.pedID), CLOWN_APPEAR_SIZE)
|
|
clown.iTimer = GET_GAME_TIMER() + (TELEPORT_TIME / 2)
|
|
clown.aState = CS_TELEPORT_OUT
|
|
BREAK
|
|
CASE CS_TELEPORT_OUT
|
|
IF (GET_GAME_TIMER() > clown.iTimer)
|
|
DELETE_PED(clown.pedID)
|
|
CLEANUP_CLOWN_PED(clown)
|
|
clown.bIsActive = FALSE
|
|
ENDIF
|
|
BREAK
|
|
CASE CS_ACTIVE
|
|
// @SBA - check if the clown is set to be chasing spectators, so we can use longer dist check
|
|
IF GET_CLOWN_TYPE(clown) = SCT_CHASE
|
|
IF GET_CLOSEST_SPECTATOR_TO_PED(clown.pedID, clown.piClosestSpec, kiLongIgnoreSpectatorsDist)
|
|
// Make them more aggressive with the spectators
|
|
MAKE_CLOWN_MORE_AGGRESSIVE(clown, TRUE)
|
|
clown.aState = CS_ATTACK_SPECTATORS
|
|
EXIT
|
|
ENDIF
|
|
// @SBA - Check all clowns for short-distance targets
|
|
ELIF GET_CLOSEST_SPECTATOR_TO_PED(clown.pedID, clown.piClosestSpec, kiShortIgnoreSpectatorsDist)
|
|
// Make them more aggressive with the spectators
|
|
MAKE_CLOWN_MORE_AGGRESSIVE(clown, TRUE)
|
|
clown.aState = CS_ATTACK_SPECTATORS
|
|
EXIT
|
|
ENDIF
|
|
|
|
// wait for van exiters to finish exiting
|
|
IF (GET_CLOWN_TYPE(clown) = SCT_VAN_EXIT)
|
|
AND (GET_SCRIPT_TASK_STATUS(clown.pedID, SCRIPT_TASK_PERFORM_SEQUENCE) <= PERFORMING_TASK)
|
|
EXIT
|
|
// Clowns should be set normal when attacking the player
|
|
ELIF GET_CLOWN_TYPE(clown) != SCT_NORMAL
|
|
CPRINTLN(DEBUG_MISSION, "UPDATE_CLOWN_PED: Active Clown being set to SCT_NORMAL!")
|
|
SET_CLOWN_TYPE(clown, SCT_NORMAL)
|
|
ENDIF
|
|
|
|
// ~~~ @SBA - normal activity ~~~
|
|
// Attack player if not already doing so
|
|
IF (GET_SCRIPT_TASK_STATUS(clown.pedID, SCRIPT_TASK_COMBAT) > PERFORMING_TASK)
|
|
// If the clown has been alive a long time, make him aggressive in combat
|
|
IF GET_GAME_TIMER() > clown.iLongevityTimer
|
|
CPRINTLN(DEBUG_MISSION, "UPDATE_CLOWN_PED: Long-lived clown - make him aggressive!!")
|
|
MAKE_CLOWN_MORE_AGGRESSIVE(clown, TRUE, TRUE)
|
|
ELSE
|
|
MAKE_CLOWN_MORE_AGGRESSIVE(clown, FALSE)
|
|
ENDIF
|
|
|
|
TASK_COMBAT_PED(clown.pedID, PLAYER_PED_ID(), COMBAT_PED_DISABLE_AIM_INTRO)
|
|
|
|
IF GET_RANDOM_BOOL()
|
|
CPRINTLN(DEBUG_MISSION, "Attack player: Clown laughs!")
|
|
PLAY_PED_AMBIENT_SPEECH_WITH_VOICE(clown.pedID, "CLOWN_LAUGH", "CLOWNS", SPEECH_PARAMS_FORCE_SHOUTED_CLEAR)
|
|
ENDIF
|
|
ENDIF
|
|
// Time to dance
|
|
IF (GET_GAME_TIMER() > clown.iDanceTimer)
|
|
IF NOT IS_PED_IN_COVER(clown.pedID)
|
|
MAKE_CLOWN_MORE_AGGRESSIVE(clown, FALSE)
|
|
clown.aState = CS_DANCE_START
|
|
ELSE
|
|
clown.iDanceTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(iMinClownDanceDelay, iMaxClownDanceDelay/2)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
vec = GET_ENTITY_COORDS(clown.pedID)
|
|
IF (vec.z < 27.7)
|
|
CPRINTLN(DEBUG_MISSION, "UPDATE_CLOWN_PED: CLOWN PED IS TOO FAR BELOW GROUND THIS WILL CAUSE - B*174705 - POINT - EMERGENCY TELEPORT:", vec)
|
|
clown.aState = CS_TELEPORT_OUT
|
|
EXIT
|
|
ENDIF
|
|
|
|
IF IS_ENTITY_IN_ANGLED_AREA( clown.pedID, <<220.531845,-918.456665,27.533890>>, <<211.758118,-931.421509,39.691795>>, 2.500000)
|
|
CPRINTLN(DEBUG_MISSION, "UPDATE_CLOWN_PED: IN BOXED AREA - B*174705 - POINT - EMERGENCY TELEPORT:", vec)
|
|
clown.aState = CS_TELEPORT_OUT
|
|
EXIT
|
|
ENDIF
|
|
|
|
BREAK
|
|
// @SBA - adding new state for attacking spectators
|
|
CASE CS_ATTACK_SPECTATORS
|
|
// If we lost the target...
|
|
IF NOT DOES_CLOWN_HAVE_SPECTATOR_TARGET(clown)
|
|
OR GET_DISTANCE_BETWEEN_PEDS(clown.pedID, clown.piClosestSpec) > kiLongIgnoreSpectatorsDist
|
|
// @TODO - add timer to break off attack after awhile?
|
|
CPRINTLN(DEBUG_MISSION, "UPDATE_CLOWN_PED: Clown no longer has a spectator target!")
|
|
// reset target and go back to active state
|
|
clown.iDanceTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(iMinClownDanceDelay, iMaxClownDanceDelay)
|
|
clown.piClosestSpec = NULL
|
|
clown.aState = CS_ACTIVE
|
|
// @TODO - Reset an eventual timer to check for spectators again
|
|
// otherwise attack the spectator target
|
|
ELSE
|
|
// Clowns should be set to chase when attacking spectators
|
|
IF GET_CLOWN_TYPE(clown) != SCT_CHASE
|
|
CPRINTLN(DEBUG_MISSION, "UPDATE_CLOWN_PED: Clown being set to SCT_CHASE!")
|
|
SET_CLOWN_TYPE(clown, SCT_CHASE)
|
|
ENDIF
|
|
CLOWN_ATTACKS_SPECTATORS(clown)
|
|
ENDIF
|
|
BREAK
|
|
CASE CS_DANCE_START
|
|
SELECT_AND_START_CLOWN_DANCE_ANIM(clown, TRUE)
|
|
clown.aState = CS_DANCE
|
|
BREAK
|
|
CASE CS_DANCE
|
|
IF NOT IS_ENTITY_PLAYING_ANIM(clown.pedID, sMissionAnimDanceDictionary, clown.danceAnim)
|
|
clown.aState = CS_ACTIVE
|
|
clown.iDanceTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(iMinClownDanceDelay, iMaxClownDanceDelay)
|
|
ENDIF
|
|
BREAK
|
|
// @SBA - adding case for general performance start
|
|
CASE CS_PERFORM_START
|
|
SELECT_AND_START_CLOWN_DANCE_ANIM(clown, FALSE)
|
|
CPRINTLN(DEBUG_MISSION, "UPDATE_CLOWN_PED: Setting clown state to CS_PERFORM_SPAWN_GUN!")
|
|
clown.aState = CS_PERFORM_SPAWN_GUN
|
|
BREAK
|
|
// @SBA - adding case for general performance gun spawn
|
|
CASE CS_PERFORM_SPAWN_GUN
|
|
STRING sAnimDict
|
|
FLOAT fSpawnGunPhase
|
|
FLOAT fEndAnimPhase
|
|
// @SBA - set appropriate data
|
|
IF ARE_STRINGS_EQUAL(clown.danceAnim, sMimeAnimClip)
|
|
sAnimDict = sMimeAnimDict
|
|
fSpawnGunPhase = kfMimeGunSpawnPhase
|
|
fEndAnimPhase = kfMimeEndPhase
|
|
ELSE
|
|
sAnimDict = sMissionAnimDanceDictionary
|
|
fSpawnGunPhase = kfDanceGunSpawnPhase
|
|
fEndAnimPhase = kfDanceEndPhase
|
|
ENDIF
|
|
// If clown has a gun now, move on
|
|
IF SPAWN_GUN_IN_CLOWNS_HAND(clown, sAnimDict, fSpawnGunPhase, fEndAnimPhase, bPlayedGunSmokeFX)
|
|
CPRINTLN(DEBUG_MISSION, "UPDATE_CLOWN_PED: Setting clown state to CS_ACTIVE!")
|
|
// set to chase
|
|
SET_CLOWN_TYPE(clownPed[i1stPerformanceClownID], SCT_CHASE)
|
|
clown.iDanceTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(iMinClownDanceDelay, iMaxClownDanceDelay)
|
|
clown.aState = CS_ACTIVE
|
|
ENDIF
|
|
BREAK
|
|
CASE CS_VEHICLE_DEPLOY
|
|
|
|
clown.fClownAlpha += GET_FRAME_TIME() * 512.0 // HALF SECOND FADE OUT
|
|
IF (clown.fClownAlpha < 2.0)
|
|
SET_ENTITY_VISIBLE(clown.pedID, FALSE)
|
|
ELSE
|
|
SET_ENTITY_VISIBLE(clown.pedID, TRUE)
|
|
IF (clown.fClownAlpha > 255.0)
|
|
clown.fClownAlpha = 255.0
|
|
RESET_ENTITY_ALPHA(clown.pedID)
|
|
clown.aState = CS_ACTIVE
|
|
ELSE
|
|
IF IS_ENTITY_ON_SCREEN(clown.pedID)
|
|
SET_PED_ALPHA(clown.pedID, FLOOR(clown.fClownAlpha), iAlphaCounter)
|
|
ELSE
|
|
RESET_ENTITY_ALPHA(clown.pedID)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE CS_TELEPORT_SEEK_PLACE
|
|
/*
|
|
IF GENERATE_CLOWN_SPAWN_POINT_AROUND_PLAYER(vec)
|
|
clown.aState = CS_DELAY
|
|
clown.iTimer = GET_GAME_TIMER() + (TELEPORT_TIME / 2)
|
|
|
|
SET_ENTITY_COORDS(clown.pedID, vec)
|
|
SET_ENTITY_INVINCIBLE(clown.pedID, TRUE)
|
|
SET_ENTITY_VISIBLE(clown.pedID, FALSE)
|
|
FREEZE_ENTITY_POSITION(clown.pedID, TRUE)
|
|
SAFE_REMOVE_BLIP(clown.blipID)
|
|
|
|
CPRINTLN(DEBUG_MISSION, "CLOWN FOUND BETTER PLACE")
|
|
ENDIF
|
|
*/
|
|
BREAK
|
|
CASE CS_DYING
|
|
SAFE_REMOVE_BLIP(clown.blipID)
|
|
IF (GET_GAME_TIMER() > clown.iTimer)
|
|
IF IS_ENTITY_DEAD(clown.pedID) OR IS_PED_INJURED(clown.pedID)
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(clown.laughSoundID)
|
|
IF NOT IS_ENTITY_IN_AIR(clown.pedID)
|
|
vec = GET_ENTITY_COORDS(clown.pedID)
|
|
IF GET_GROUND_Z_FOR_3D_COORD(vec, z)
|
|
vec.z = z
|
|
vec.z += 1.0
|
|
ENDIF
|
|
|
|
START_PARTICLE_FX_NON_LOOPED_AT_COORD("scr_clown_death", vec, GET_ENTITY_ROTATION(clown.pedID), 2.0)
|
|
PLAY_SOUND_FROM_COORD(-1, "clown_die_wrapper", vec, "BARRY_02_SOUNDSET")
|
|
|
|
clown.aState = CS_DEAD
|
|
// @SBA - shorten timer for wave 6
|
|
IF stageEnum = SE_WAVE6
|
|
clown.iTimer = GET_GAME_TIMER() + (CLOWN_FADE_TIME - (CLOWN_FADE_TIME - 100))
|
|
ELSE
|
|
clown.iTimer = GET_GAME_TIMER() + CLOWN_FADE_TIME
|
|
ENDIF
|
|
clown.fClownAlpha = 255.0
|
|
SAFE_REMOVE_BLIP(clown.blipID)
|
|
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE CS_DEAD
|
|
IF (GET_GAME_TIMER() > clown.iTimer)
|
|
|
|
clown.fClownAlpha -= GET_FRAME_TIME() * 512.0 // HALF SECOND FADE OUT
|
|
IF (clown.fClownAlpha < 0.0)
|
|
clown.fClownAlpha = 0.0
|
|
ENDIF
|
|
|
|
SET_PED_ALPHA(clown.pedID, FLOOR(clown.fClownAlpha), iAlphaCounter)
|
|
|
|
IF (clown.fClownAlpha <= 0.0) OR NOT IS_ENTITY_ON_SCREEN(clown.pedID)
|
|
clown.bIsDead = TRUE
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(clown.laughSoundID)
|
|
DELETE_CLOWN_PED(clown)
|
|
clown.bIsActive = FALSE
|
|
ENDIF
|
|
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// This handles all clowns day to day stuff
|
|
PROC UPDATE_CLOWN_PEDS()
|
|
INT i = 0
|
|
|
|
REPEAT (COUNT_OF(clownPed)) i
|
|
UPDATE_CLOWN_PED(clownPed[i])
|
|
ENDREPEAT
|
|
|
|
iAliveClownCount = GET_ALIVE_CLOWN_PED_COUNT()
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// This handles on foot auto spawner
|
|
PROC UPDATE_CLOWN_SPAWNER()
|
|
INT ind
|
|
VECTOR v
|
|
|
|
IF (iAliveClownCount >= iMaxActivePeds) OR (bGenerateAutoClowns = FALSE)
|
|
EXIT
|
|
ENDIF
|
|
//CPRINTLN(DEBUG_MISSION, "UPDATE_CLOWN_SPAWNER: 1st!")
|
|
|
|
IF (GET_GAME_TIMER() < iNextSpawnTimer)
|
|
EXIT
|
|
ENDIF
|
|
//CPRINTLN(DEBUG_MISSION, "UPDATE_CLOWN_SPAWNER: 2nd!")
|
|
|
|
IF NOT GET_FREE_CLOWN_PED_INDEX(ind)
|
|
EXIT
|
|
ENDIF
|
|
//CPRINTLN(DEBUG_MISSION, "UPDATE_CLOWN_SPAWNER: 3rd!")
|
|
|
|
// @SBA - special case for wave 6. if we've created enough duplicate replacements, we're good.
|
|
IF stageEnum = SE_WAVE6
|
|
IF iDuplicatesCount >= kiNumDuplicates
|
|
CPRINTLN(DEBUG_MISSION, "UPDATE_CLOWN_SPAWNER: Duplicates Complete.")
|
|
bGenerateAutoClowns = FALSE
|
|
iDuplicatesCount = 0
|
|
EXIT
|
|
ENDIF
|
|
ENDIF
|
|
//CPRINTLN(DEBUG_MISSION, "UPDATE_CLOWN_SPAWNER: 4th! vClownSpawnPoint = ", vClownSpawnPoint)
|
|
|
|
IF ( bUseClownSpawnPoint )
|
|
v = GET_RANDOM_POINT_IN_DISC(vClownSpawnPoint, fClownSpawnRadius, 2.0)
|
|
ELSE
|
|
v = GET_RANDOM_POINT_IN_DISC(vBattleCenter, fClownSpawnRadius, 2.0)
|
|
ENDIF
|
|
CPRINTLN(DEBUG_MISSION, "UPDATE_CLOWN_SPAWNER: Randomized Vector = ", v) //, " fClownSpawnRadius = ", fClownSpawnRadius)
|
|
|
|
IF NOT CHECK_SPAWN_POINT_IS_OK(v)
|
|
EXIT
|
|
ENDIF
|
|
//CPRINTLN(DEBUG_MISSION, "UPDATE_CLOWN_SPAWNER: 5th!")
|
|
|
|
IF CREATE_CLOWN_PED(clownPed[ind], v)
|
|
// @SBA - special case for wave 6
|
|
IF stageEnum = SE_WAVE6
|
|
iNextSpawnTimer = GET_GAME_TIMER() + 25
|
|
iDuplicatesCount ++
|
|
CPRINTLN(DEBUG_MISSION, "UPDATE_CLOWN_SPAWNER: iDuplicatesCount = ", iDuplicatesCount)
|
|
CPRINTLN(DEBUG_MISSION, "UPDATE_CLOWN_SPAWNER: Clowns spawned this wave (including first) = ", iClownPedsSpawned)
|
|
ELSE
|
|
iNextSpawnTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(iMinPedSpawnTime, iMaxPedSpawnTime)
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// @SBA - for wave 6, check if more clowns need to spawn
|
|
PROC CHECK_FOR_SPAWNING_DUPLICATES()
|
|
INT i = 0
|
|
|
|
REPEAT (COUNT_OF(clownPed)) i
|
|
IF NOT ARE_VECTORS_EQUAL(clownPed[i].vDeathPosition, <<0,0,0>>)
|
|
CPRINTLN(DEBUG_MISSION, "We need to spawn duplicates! Index = ", i)
|
|
// ok to generate duplicates
|
|
bGenerateAutoClowns = TRUE
|
|
vClownSpawnPoint = clownPed[i].vDeathPosition
|
|
CPRINTLN(DEBUG_MISSION, "CHECK_FOR_SPAWNING_DUPLICATES: vClownSpawnPoint = ", vClownSpawnPoint)
|
|
// reset death vector
|
|
clownPed[i].vDeathPosition = <<0,0,0>>
|
|
// stop the repeat
|
|
i = COUNT_OF(clownPed) - 1
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// @SBA - set values to origin
|
|
PROC RESET_ALL_CLOWN_DEATH_VECTORS()
|
|
CPRINTLN(DEBUG_MISSION, "RESET_ALL_CLOWN_DEATH_VECTORS")
|
|
INT i = 0
|
|
|
|
REPEAT (COUNT_OF(clownPed)) i
|
|
clownPed[i].vDeathPosition = <<0,0,0>>
|
|
ENDREPEAT
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Tells all clown peds to flee
|
|
PROC FLEE_ALL_CLOWN_PEDS()
|
|
INT i = 0
|
|
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
REPEAT (COUNT_OF(clownPed)) i
|
|
IF IS_CLOWN_PED_ALIVE(clownPed[i])
|
|
clownPed[i].aState = CS_NULL
|
|
TASK_SMART_FLEE_COORD(clownPed[i].pedID, GET_ENTITY_COORDS(PLAYER_PED_ID()), 400.0, -1)
|
|
ENDIF
|
|
ENDREPEAT
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
//----------------------
|
|
// CAR FUNCTIONS
|
|
//----------------------
|
|
|
|
/// PURPOSE:
|
|
/// Tells us if a clown car is dead
|
|
/// PARAMS:
|
|
/// car - reference to clown car struct
|
|
FUNC BOOL IS_CLOWN_GENERATOR_DEAD(CLOWN_GENERATOR &car)
|
|
IF (car.bIsActive = FALSE)
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
IF NOT DOES_ENTITY_EXIST(car.generatorID)
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN IS_ENTITY_DEAD(car.generatorID)
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Tells us if all clown cars is dead
|
|
FUNC BOOL ARE_ALL_CLOWN_GENERATORS_DEAD()
|
|
INT i
|
|
|
|
i = 0
|
|
REPEAT (COUNT_OF(clownGenerator)) i
|
|
IF NOT IS_CLOWN_GENERATOR_DEAD(clownGenerator[i])
|
|
RETURN FALSE
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
RETURN TRUE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Returns active number of clown peds
|
|
FUNC INT GET_ALIVE_CLOWN_GENERATOR_COUNT()
|
|
INT i = 0
|
|
INT cnt = 0
|
|
|
|
REPEAT (COUNT_OF(clownGenerator)) i
|
|
IF NOT IS_CLOWN_GENERATOR_DEAD(clownGenerator[i])
|
|
cnt ++
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
RETURN cnt
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Gets a free slot in clown car array
|
|
/// PARAMS:
|
|
/// out - index into array which is free
|
|
/// RETURNS:
|
|
/// true if there is a free slot
|
|
FUNC BOOL GET_FREE_CLOWN_GENERATOR_INDEX(INT &out)
|
|
INT i = 0
|
|
|
|
out = -1
|
|
REPEAT (COUNT_OF(clownGenerator)) i
|
|
IF (clownGenerator[i].bIsActive = FALSE)
|
|
out = i
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// This is stuff which is common to both cleaning up and deleting a clown ped
|
|
/// PARAMS:
|
|
/// ent - reference to clown ped
|
|
PROC SHARED_CLEANUP_AND_DELETE_CLOWN_GENERATOR(CLOWN_GENERATOR &car)
|
|
SAFE_REMOVE_BLIP(car.blipID)
|
|
|
|
car.generatorID = NULL
|
|
car.bIsActive = FALSE
|
|
car.blipID = NULL
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Cleans up single clown car
|
|
/// PARAMS:
|
|
/// car - clown car reference
|
|
PROC CLEANUP_CLOWN_GENERATOR(CLOWN_GENERATOR &car)
|
|
IF (car.bIsActive = FALSE)
|
|
EXIT
|
|
ENDIF
|
|
IF NOT DOES_ENTITY_EXIST(car.generatorID)
|
|
EXIT
|
|
ENDIF
|
|
|
|
IF IS_ENTITY_DEAD(car.generatorID)
|
|
ENDIF
|
|
|
|
SET_VEHICLE_CAN_BE_TARGETTED(car.generatorID, FALSE)
|
|
SET_ENTITY_IS_TARGET_PRIORITY(car.generatorID, FALSE)
|
|
SAFE_RELEASE_VEHICLE(car.generatorID)
|
|
SHARED_CLEANUP_AND_DELETE_CLOWN_GENERATOR(car)
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Deletes single clown car
|
|
/// PARAMS:
|
|
/// car - clown car reference
|
|
PROC DELETE_CLOWN_GENERATOR(CLOWN_GENERATOR &car)
|
|
IF (car.bIsActive = FALSE)
|
|
EXIT
|
|
ENDIF
|
|
|
|
IF NOT DOES_ENTITY_EXIST(car.generatorID)
|
|
EXIT
|
|
ENDIF
|
|
|
|
SAFE_REMOVE_BLIP(car.blipID)
|
|
IF IS_ENTITY_OK(car.generatorID)
|
|
SET_VEHICLE_CAN_BE_TARGETTED(car.generatorID, FALSE)
|
|
SET_ENTITY_IS_TARGET_PRIORITY(car.generatorID, FALSE)
|
|
ENDIF
|
|
|
|
IF IS_ENTITY_OK(PLAYER_PED_ID())
|
|
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), car.generatorID)
|
|
SAFE_RELEASE_VEHICLE(car.generatorID)
|
|
ELSE
|
|
SAFE_DELETE_VEHICLE(car.generatorID)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
SHARED_CLEANUP_AND_DELETE_CLOWN_GENERATOR(car)
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Cleanups all clown cars
|
|
PROC CLEANUP_ALL_CLOWN_GENERATORS()
|
|
INT i = 0
|
|
REPEAT COUNT_OF(clownGenerator) i
|
|
CLEANUP_CLOWN_GENERATOR(clownGenerator[i])
|
|
ENDREPEAT
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Deletes all clown cars
|
|
PROC DELETE_ALL_CLOWN_GENERATORS()
|
|
INT i = 0
|
|
REPEAT COUNT_OF(clownGenerator) i
|
|
DELETE_CLOWN_GENERATOR(clownGenerator[i])
|
|
ENDREPEAT
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Update a single clown car
|
|
/// PARAMS:
|
|
/// car - reference to the vehicle
|
|
FUNC BOOL UPDATE_CLOWN_GENERATOR(CLOWN_GENERATOR &car)
|
|
INT ind
|
|
BOOL bBust
|
|
SEQUENCE_INDEX seqTask
|
|
VECTOR vec
|
|
|
|
// existence checks
|
|
IF (car.bIsActive = FALSE)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
IF NOT DOES_ENTITY_EXIST(car.generatorID)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
INT i1stGeneratorSpawnTime = iMinGeneratorPedSpawnTime *2
|
|
|
|
// @SBA Puting this here to avoid asserts beyond CS_DYING
|
|
bBust = IS_VEHICLE_BRUCK_UP(car.generatorID)
|
|
|
|
// dead check - we do this so we can jump into the delayed detonation state
|
|
IF (ENUM_TO_INT(car.aState) < ENUM_TO_INT(CS_DYING))
|
|
vec = GET_ENTITY_COORDS(car.generatorID)
|
|
|
|
//CPRINTLN(DEBUG_MISSION, "CLOWN GENERATOR HEALTH = ", GET_ENTITY_HEALTH(car.generatorID))
|
|
IF (vec.z < 21.0)
|
|
CPRINTLN(DEBUG_MISSION, "CLOWN GENERATOR FALLEN THROUGH WORLD?")
|
|
ENDIF
|
|
|
|
IF bBust OR (vec.z < 21.0)
|
|
car.aState = CS_DYING
|
|
|
|
// increase the stat in here
|
|
IF (car.bHasStartedDeploying = FALSE)
|
|
CPRINTLN(DEBUG_MISSION, "INCREASE BA2_VANS_DESTROYED")
|
|
|
|
IF (iClownGeneratorsDestroyed < 4)
|
|
INFORM_MISSION_STATS_OF_INCREMENT(BA2_VANS_DESTROYED)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
iClownGeneratorsDestroyed ++
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF (car.bHasPlayerApproached = FALSE)
|
|
IF (GET_DISTANCE_BETWEEN_ENTITIES(car.generatorID, PLAYER_PED_ID()) < fClownGeneratorTriggerDist) OR HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(car.generatorID, PLAYER_PED_ID())
|
|
CPRINTLN(DEBUG_MISSION, "ACTIVE GENERATOR")
|
|
// @SBA - give some extra time here
|
|
car.iTimer = GET_GAME_TIMER() + i1stGeneratorSpawnTime
|
|
car.bHasPlayerApproached = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF (bDebugTTYSpew)
|
|
IF (car.bHasPlayerApproached = FALSE)
|
|
DRAW_DEBUG_CIRCLE(GET_ENTITY_COORDS(car.generatorID), fClownGeneratorTriggerDist, 255, 0, 0)
|
|
ELSE
|
|
DRAW_DEBUG_CIRCLE(GET_ENTITY_COORDS(car.generatorID), fClownGeneratorTriggerDist, 0, 0, 255)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// handle states
|
|
SWITCH (car.aState)
|
|
CASE CS_DELAY
|
|
IF (GET_GAME_TIMER() >= car.iTimer)
|
|
#IF IS_DEBUG_BUILD
|
|
vec = GET_ENTITY_COORDS(car.generatorID)
|
|
CPRINTLN(DEBUG_MISSION, "CLOWN GENERATOR SPAWNED IN AT ", vec)
|
|
#ENDIF
|
|
|
|
START_PARTICLE_FX_NON_LOOPED_ON_ENTITY("scr_clown_appears", car.generatorID, <<0, 0, 0>>, <<0, 0, 0>>, GENERATOR_APPEAR_SIZE)
|
|
|
|
car.iTimer = GET_GAME_TIMER() + TELEPORT_TIME
|
|
car.aState = CS_TELEPORT
|
|
car.fClownAlpha = 0
|
|
SET_VEHICLE_ALPHA(car.generatorID, FLOOR(car.fClownAlpha), iAlphaCounter)
|
|
SET_ENTITY_VISIBLE(car.generatorID, TRUE)
|
|
// add to dynamic mix
|
|
IF (car.bIsInDynamicMix = FALSE)
|
|
ADD_ENTITY_TO_AUDIO_MIX_GROUP(car.generatorID, "BARRY_02_VEHICLE_SETTING")
|
|
car.bIsInDynamicMix = TRUE
|
|
ENDIF
|
|
|
|
IF NOT IS_ENTITY_ON_SCREEN(car.generatorID)
|
|
car.fClownAlpha = 255.0
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE CS_TELEPORT
|
|
car.fClownAlpha += GET_FRAME_TIME() * 1024.0 // HALF SECOND FADE OUT
|
|
IF (car.fClownAlpha > 255.0)
|
|
car.fClownAlpha = 255.0
|
|
ENDIF
|
|
|
|
IF IS_ENTITY_ON_SCREEN(car.generatorID)
|
|
SET_VEHICLE_ALPHA(car.generatorID, FLOOR(car.fClownAlpha), iAlphaCounter)
|
|
ELSE
|
|
RESET_ENTITY_ALPHA(car.generatorID)
|
|
ENDIF
|
|
|
|
IF (GET_GAME_TIMER() >= car.iTimer) OR (car.fClownAlpha >= 255.0)
|
|
SET_ENTITY_VISIBLE(car.generatorID, TRUE)
|
|
SET_ENTITY_COLLISION(car.generatorID, TRUE)
|
|
SET_ENTITY_INVINCIBLE(car.generatorID, FALSE)
|
|
FREEZE_ENTITY_POSITION(car.generatorID, FALSE)
|
|
RESET_ENTITY_ALPHA(car.generatorID)
|
|
SAFE_REMOVE_BLIP(car.blipID)
|
|
car.blipID = CREATE_VEHICLE_BLIP(car.generatorID, FALSE)
|
|
car.aState = CS_ACTIVE
|
|
START_VEHICLE_HORN(car.generatorID, 4000)
|
|
SET_VEHICLE_ENGINE_ON(car.generatorID, TRUE, TRUE)
|
|
SET_VEHICLE_FORWARD_SPEED(car.generatorID, fClownCarFwdSpeed)
|
|
car.iTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(iMinGeneratorPedSpawnTime, iMaxGeneratorPedSpawnTime)
|
|
|
|
IF (car.iSwerveIn <> 0)
|
|
car.aState = CS_ONROUTE_START
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE CS_ONROUTE_START
|
|
|
|
IF (iAliveClownCount >= iMaxActivePeds)
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
IF GET_FREE_CLOWN_PED_INDEX(ind)
|
|
car.iDriverID = ind
|
|
IF CREATE_CLOWN_PED_IN_VEHICLE(clownPed[car.iDriverID], car.generatorID, TRUE)
|
|
clownPed[car.iDriverID].aState = cs_null
|
|
SAFE_REMOVE_BLIP(clownPed[car.iDriverID].blipID)
|
|
CLEAR_PED_TASKS(clownPed[car.iDriverID].pedID)
|
|
OPEN_SEQUENCE_TASK(seqTask)
|
|
TASK_VEHICLE_TEMP_ACTION(null, car.generatorID, TEMPACT_GOFORWARD_HARD, car.iForwardTime)
|
|
|
|
IF (car.iSwerveIn = 1)
|
|
TASK_VEHICLE_TEMP_ACTION(null, car.generatorID, TEMPACT_HANDBRAKETURNRIGHT, car.iHBrakeTime)
|
|
ELIF (car.iSwerveIn = -1)
|
|
TASK_VEHICLE_TEMP_ACTION(null, car.generatorID, TEMPACT_HANDBRAKETURNLEFT, car.iHBrakeTime)
|
|
ENDIF
|
|
|
|
CLOSE_SEQUENCE_TASK(seqTask)
|
|
TASK_PERFORM_SEQUENCE(clownPed[car.iDriverID].pedID, seqTask)
|
|
CLEAR_SEQUENCE_TASK(seqTask)
|
|
CPRINTLN(DEBUG_MISSION, "Car has started on route - Time:", GET_GAME_TIMER())
|
|
car.aState = CS_ONROUTE
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE CS_ONROUTE
|
|
IF IS_ENTITY_ALIVE( clownPed[car.iDriverID].pedID )
|
|
IF GET_SCRIPT_TASK_STATUS(clownPed[car.iDriverID].pedID, SCRIPT_TASK_PERFORM_SEQUENCE) = FINISHED_TASK
|
|
CPRINTLN(DEBUG_MISSION, "Car has finished route - Time:", GET_GAME_TIMER())
|
|
SEQUENCE_INDEX seq
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_LEAVE_VEHICLE(NULL, car.generatorID)
|
|
TASK_COMBAT_PED(NULL, PLAYER_PED_ID())
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(clownPed[car.iDriverID].pedID, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
clownPed[car.iDriverID].blipID = CREATE_PED_BLIP(clownPed[car.iDriverID].pedID)
|
|
clownPed[car.iDriverID].aState = CS_VEHICLE_DEPLOY
|
|
car.aState = CS_ACTIVE
|
|
ENDIF
|
|
ELSE
|
|
CPRINTLN(DEBUG_MISSION, "Car has aborted route as people are dead - Time:", GET_GAME_TIMER())
|
|
TASK_EVERYONE_LEAVE_VEHICLE(car.generatorID)
|
|
// @SBA - make sure to give a little time before we start spawning clowns
|
|
car.iTimer = GET_GAME_TIMER() + i1stGeneratorSpawnTime
|
|
car.aState = CS_ACTIVE
|
|
ENDIF
|
|
BREAK
|
|
CASE CS_ACTIVE
|
|
IF (bHasTrevorClownGeneratorRanted = FALSE) AND (bClownGeneratorRantTimerSet)
|
|
IF (GET_GAME_TIMER() > iTrevorClownGeneratorRantTime) AND IS_ENTITY_ON_SCREEN(car.generatorID)
|
|
// Don't comment if van is too far away
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), car.generatorID) < 50.0
|
|
PLAY_TREVOR_CLOWN_GENERATOR_RANT()
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF (GET_GAME_TIMER() < car.iTimer)
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
IF (iAliveClownCount >= iMaxActivePeds)
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
VECTOR vPoint
|
|
vPoint = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(car.generatorID, (<<0.0, -3.3, -0.7>>))
|
|
// check if clown to close to rear of van
|
|
CPRINTLN(DEBUG_MISSION, "Exit sphere: ", vPoint)
|
|
IF (bDebugTTYSpew)
|
|
DRAW_DEBUG_CIRCLE(vPoint, 1.5, 255, 0, 0)
|
|
ENDIF
|
|
IF IS_ANY_CLOWN_NEAR_POINT(vPoint, 1.5)
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
IF GET_FREE_CLOWN_PED_INDEX(ind)
|
|
IF CREATE_CLOWN_PED_IN_VEHICLE(clownPed[ind], car.generatorID)
|
|
START_PARTICLE_FX_NON_LOOPED_ON_ENTITY("scr_clown_appears", car.generatorID, vClownCarSmokeOffset, <<0, 0, 0>>, fClownCarPedSmokeSize)
|
|
clownPed[ind].aState = CS_VEHICLE_DEPLOY
|
|
SET_CLOWN_TYPE(clownPed[ind], SCT_VAN_EXIT)
|
|
car.bHasStartedDeploying = TRUE
|
|
car.iClownPedsSpawned ++
|
|
car.fClownAlpha = 0.0
|
|
SET_ENTITY_VISIBLE(clownPed[ind].pedID, FALSE)
|
|
|
|
vPoint = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(car.generatorID, (<<GET_RANDOM_FLOAT_IN_RANGE(-2.5, 2.5), GET_RANDOM_FLOAT_IN_RANGE(-6.5, -10.0), -0.7>>))
|
|
CPRINTLN(DEBUG_MISSION, "Clown exiting vehicle - position: ", vPoint)
|
|
|
|
SEQUENCE_INDEX seq
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_SWAP_WEAPON(NULL, TRUE)
|
|
TASK_LEAVE_VEHICLE(NULL, car.generatorID, ECF_DONT_CLOSE_DOOR)
|
|
TASK_GO_TO_COORD_WHILE_AIMING_AT_ENTITY(NULL, vPoint, PLAYER_PED_ID(), PEDMOVE_WALK, TRUE, 1.5, 2.0)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(clownPed[ind].pedID, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
|
|
IF (car.bHasPlayerApproached = FALSE)
|
|
car.iTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(iMinGeneratorPedSpawnTime * 4, iMaxGeneratorPedSpawnTime * 4)
|
|
ELSE
|
|
// increase times slightly, but don't change globally
|
|
car.iTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(iMinGeneratorPedSpawnTime + 500, iMaxGeneratorPedSpawnTime)
|
|
ENDIF
|
|
|
|
// delay spawning after 5 have come out
|
|
IF (car.iClownPedsSpawned > 5)
|
|
car.iTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(iMinGeneratorPedSpawnTime * 4, iMaxGeneratorPedSpawnTime * 4)
|
|
car.iClownPedsSpawned = 0
|
|
ENDIF
|
|
|
|
IF (bHasClownGeneratorHelpDisplayed = FALSE)
|
|
PRINT_HELP("B2_CAR_HLP") // Destroy clown vans to stop clowns regenerating.
|
|
bHasClownGeneratorHelpDisplayed = TRUE
|
|
ENDIF
|
|
|
|
// @SBA - set this timer separately from the help text in case Trevor
|
|
// doesn't have a chance to say his rant, so we can reset and try again on the next van
|
|
IF NOT bClownGeneratorRantTimerSet
|
|
iTrevorClownGeneratorRantTime = GET_GAME_TIMER() + (iMaxGeneratorPedSpawnTime + 500)
|
|
bClownGeneratorRantTimerSet = TRUE
|
|
ENDIF
|
|
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE CS_DYING
|
|
SAFE_REMOVE_BLIP(car.blipID)
|
|
IF car.bIsInDynamicMix
|
|
REMOVE_ENTITY_FROM_AUDIO_MIX_GROUP(car.generatorID)
|
|
car.bIsInDynamicMix = FALSE
|
|
ENDIF
|
|
FREEZE_ENTITY_POSITION(car.generatorID, FALSE)
|
|
//START_PARTICLE_FX_NON_LOOPED_AT_COORD("scr_clown_death", GET_ENTITY_COORDS(car.generatorID), GET_ENTITY_ROTATION(car.generatorID), 2.0)
|
|
EXPLODE_VEHICLE(car.generatorID)
|
|
|
|
CPRINTLN(DEBUG_MISSION, "CLOWN GENERATOR IS DEAD")
|
|
PLAY_SOUND_FRONTEND(-1, "HOORAY", "BARRY_02_SOUNDSET")
|
|
|
|
|
|
car.aState = CS_DEATH_FX
|
|
car.iTimer = GET_GAME_TIMER() + (CLOWN_FADE_TIME * 3)
|
|
car.fClownAlpha = 255.0
|
|
|
|
// @SBA - If the van died before Trevor ranted, reset flag so timer will reset next time around
|
|
IF NOT bHasTrevorClownGeneratorRanted
|
|
IF bClownGeneratorRantTimerSet
|
|
CPRINTLN(DEBUG_MISSION, "Didn't hear Trevor's clown generator rant - reseting timer flag")
|
|
bClownGeneratorRantTimerSet = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
BREAK
|
|
// @SBA - want the fade and effect to coincide
|
|
CASE CS_DEATH_FX
|
|
IF (GET_GAME_TIMER() > car.iTimer)
|
|
CPRINTLN(DEBUG_MISSION, "CLOWN GENERATOR ABOUT TO DISAPPEAR - PLAY EFFECT")
|
|
START_PARTICLE_FX_NON_LOOPED_AT_COORD("scr_clown_death", GET_ENTITY_COORDS(car.generatorID, FALSE), GET_ENTITY_ROTATION(car.generatorID), 3.0)
|
|
car.iTimer = GET_GAME_TIMER() + (CLOWN_FADE_TIME - 100)
|
|
car.aState = CS_DEAD
|
|
ENDIF
|
|
BREAK
|
|
CASE CS_DEAD
|
|
IF (GET_GAME_TIMER() > car.iTimer)
|
|
|
|
car.fClownAlpha -= GET_FRAME_TIME() * 512.0 // HALF SECOND FADE OUT
|
|
IF (car.fClownAlpha < 0.0)
|
|
car.fClownAlpha = 0.0
|
|
ENDIF
|
|
|
|
IS_ENTITY_OK(car.generatorID)
|
|
IF IS_ENTITY_ON_SCREEN(car.generatorID)
|
|
SET_VEHICLE_ALPHA(car.generatorID, FLOOR(car.fClownAlpha), iAlphaCounter)
|
|
ENDIF
|
|
|
|
IF (car.fClownAlpha <= 0.0)
|
|
CPRINTLN(DEBUG_MISSION, "CLOWN GENERATOR IS GONE")
|
|
STOP_FIRE_IN_RANGE(GET_ENTITY_COORDS(car.generatorID), 2.0)
|
|
|
|
CPRINTLN(DEBUG_MISSION, "START RECORDING THE LAST 4 SECONDS AS A CLOWN CAR HAS BLOWN UP")
|
|
REPLAY_RECORD_BACK_FOR_TIME(4.0) // Clown car has blown up and faded out
|
|
DELETE_CLOWN_GENERATOR(car)
|
|
RETURN FALSE
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
RETURN TRUE
|
|
ENDFUNC
|
|
|
|
FUNC BOOL CREATE_CLOWN_GENERATOR(CLOWN_GENERATOR &car, VECTOR pos, FLOAT head = 0.0, INT swerve = 0, INT iDelay = 0, INT iFwdTime = 4625, INT iBrakeTime = 2000)
|
|
FLOAT hp
|
|
|
|
// get start point and work out direction
|
|
CPRINTLN(DEBUG_MISSION, "CLOUD GENERATOR INIT POSITION:", pos)
|
|
|
|
CLEAR_AREA_OF_VEHICLES(pos, 5.0)
|
|
IF GET_GROUND_Z_FOR_3D_COORD(pos + <<0, 0, 0.23>>, hp)
|
|
pos.z = hp
|
|
ENDIF
|
|
|
|
car.generatorID = CREATE_VEHICLE(clownCarModel, pos, head)
|
|
IF NOT DOES_ENTITY_EXIST(car.generatorID)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
// setup hp and degradation
|
|
CPRINTLN(DEBUG_MISSION, "CLOUD GENERATOR ACTUAL SPAWN POSITION:", pos)
|
|
// @SBA - decrease van health a bit
|
|
hp = TO_FLOAT(GET_ENTITY_HEALTH(car.generatorID)) / 1.5
|
|
SET_ENTITY_HEALTH(car.generatorID, FLOOR(hp))
|
|
car.bHasStartedDeploying = FALSE
|
|
car.bHasPlayerApproached = FALSE
|
|
|
|
// setup damage and targetting
|
|
SET_ENTITY_ONLY_DAMAGED_BY_RELATIONSHIP_GROUP(car.generatorID, TRUE, RELGROUPHASH_PLAYER)
|
|
SET_VEHICLE_CAN_BE_TARGETTED(car.generatorID, TRUE)
|
|
SET_ENTITY_IS_TARGET_PRIORITY(car.generatorID, TRUE)
|
|
|
|
// freeze and hide object
|
|
SET_ENTITY_VISIBLE(car.generatorID, FALSE)
|
|
SET_ENTITY_INVINCIBLE(car.generatorID, TRUE)
|
|
SET_ENTITY_COLLISION(car.generatorID, FALSE)
|
|
FREEZE_ENTITY_POSITION(car.generatorID, TRUE)
|
|
|
|
// make car fire proof or it will take damages as it drives through flames
|
|
SET_ENTITY_PROOFS(car.generatorID, FALSE, TRUE, FALSE, FALSE, FALSE)
|
|
|
|
// turn off vehicle cover so clowns won't block other clowns trying to exit the van
|
|
SET_VEHICLE_PROVIDES_COVER(car.generatorID, FALSE)
|
|
|
|
// finalize
|
|
car.bIsActive = TRUE
|
|
car.iTimer = GET_GAME_TIMER() + iDelay
|
|
car.bIsInDynamicMix = FALSE
|
|
car.aState = CS_DELAY
|
|
car.iClownPedsSpawned = 0
|
|
car.iSwerveIn = swerve
|
|
car.iForwardTime = iFwdTime
|
|
car.iHBrakeTime = iBrakeTime
|
|
RETURN TRUE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Update all clown cars
|
|
PROC UPDATE_CLOWN_GENERATORS()
|
|
INT i = 0
|
|
|
|
iAliveClownGeneratorCount = 0
|
|
REPEAT (COUNT_OF(clownGenerator)) i
|
|
IF UPDATE_CLOWN_GENERATOR(clownGenerator[i])
|
|
iAliveClownGeneratorCount ++
|
|
ENDIF
|
|
ENDREPEAT
|
|
ENDPROC
|
|
|
|
|
|
//----------------------
|
|
// DEBUG FUNCTIONS
|
|
//----------------------
|
|
#IF IS_DEBUG_BUILD
|
|
|
|
/// PURPOSE:
|
|
/// Initializes Debug Widgets
|
|
PROC SETUP_DEBUG_WIDGETS()
|
|
SET_PROFILING_OF_THIS_SCRIPT(TRUE)
|
|
|
|
m_WidgetGroup = START_WIDGET_GROUP("Barry 2 Config")
|
|
|
|
START_WIDGET_GROUP("Test Options")
|
|
ADD_WIDGET_BOOL("Show Debug Stuff", bDebugTTYSpew)
|
|
ADD_WIDGET_BOOL("Show Mission Timer", bShowDebugMissionTime)
|
|
ADD_WIDGET_BOOL("Update Widgets", bUpdateWidgets)
|
|
ADD_WIDGET_BOOL("bUseIsAreaOccupied", bUseIsAreaOccupied)
|
|
STOP_WIDGET_GROUP()
|
|
|
|
SETUP_COMBAT_PARAMETERS_WIDGET(combatParams, "Clown Combat Parameters")
|
|
START_WIDGET_GROUP("Clown Ped Options")
|
|
ADD_WIDGET_BOOL("Spawn Test Clown", bGenerateTestClown)
|
|
ADD_WIDGET_INT_SLIDER("Max Active", iMaxActivePeds, 0, COUNT_OF(clownPed), 1)
|
|
ADD_WIDGET_INT_SLIDER("Min Spawn Time", iMinPedSpawnTime, 0, 5000, 250)
|
|
ADD_WIDGET_INT_SLIDER("Max Spawn Time", iMaxPedSpawnTime, 50, 5500, 250)
|
|
ADD_WIDGET_FLOAT_SLIDER("No Player Spawn Dist", fNoSpawnPlayerDist, 5.0, 200.0, 0.5)
|
|
ADD_WIDGET_FLOAT_SLIDER("Spawn Range", fClownSpawnRadius, 5.0, 200.0, 0.5)
|
|
ADD_WIDGET_INT_READ_ONLY("Alive Clowns", iAliveClownCount)
|
|
ADD_WIDGET_INT_READ_ONLY("Clown Peds Spawned", iClownPedsSpawned)
|
|
ADD_WIDGET_INT_READ_ONLY("Clown Peds Killed", iClownPedsKilled)
|
|
STOP_WIDGET_GROUP()
|
|
|
|
START_WIDGET_GROUP("Clown Generator Options")
|
|
START_WIDGET_GROUP("Test Generator")
|
|
ADD_WIDGET_BOOL("Spawn Generator", bGenerateTestGenerator)
|
|
ADD_WIDGET_VECTOR_SLIDER("Spawn Point", vTestGenPoint, -7000.0, 7000.0, 1.0)
|
|
ADD_WIDGET_FLOAT_SLIDER("Heading", fTestHeading, 0.0, 360.0, 0.5)
|
|
ADD_WIDGET_FLOAT_SLIDER("Forward Speed", fClownCarFwdSpeed, 0.0, 360.0, 0.25)
|
|
ADD_WIDGET_INT_SLIDER("Forward Time", iTestFwdTime, 0, 10000, 250)
|
|
ADD_WIDGET_INT_SLIDER("Brake Time", iTestBrakeTime, 50, 10500, 250)
|
|
ADD_WIDGET_INT_SLIDER("Swerve", iTestSwerve, -1, 1, 1)
|
|
ADD_WIDGET_VECTOR_SLIDER("Ped Spawn Smoke Offset", vClownCarSmokeOffset, -10.0, 10.0, 0.1)
|
|
ADD_WIDGET_FLOAT_SLIDER("Ped Spawn Smoke Size", fClownCarPedSmokeSize, 0.0, 10.0, 0.1)
|
|
STOP_WIDGET_GROUP()
|
|
ADD_WIDGET_INT_SLIDER("Min Ped Spawn Time", iMinGeneratorPedSpawnTime, 0, 5000, 250)
|
|
ADD_WIDGET_INT_SLIDER("Max Ped Spawn Time", iMaxGeneratorPedSpawnTime, 50, 5500, 250)
|
|
ADD_WIDGET_FLOAT_SLIDER("Trigger Distance", fClownGeneratorTriggerDist, 0.0, 100.0, 0.25)
|
|
ADD_WIDGET_INT_READ_ONLY("Alive Generators", iAliveClownGeneratorCount)
|
|
ADD_WIDGET_INT_READ_ONLY("Generators Destroyed", iClownGeneratorsDestroyed)
|
|
STOP_WIDGET_GROUP()
|
|
|
|
START_WIDGET_GROUP("Area Options")
|
|
ADD_WIDGET_BOOL("Player In Battle Area", bIsPlayerInBattleArea)
|
|
ADD_WIDGET_VECTOR_SLIDER("Battle Center", vBattleCenter, -6000.0, 6000.0, 0.5)
|
|
ADD_WIDGET_FLOAT_SLIDER("Battle Range", fBattleRadius, 5.0, 1000.0, 0.5)
|
|
STOP_WIDGET_GROUP()
|
|
|
|
START_WIDGET_GROUP("Read Only Values")
|
|
ADD_WIDGET_INT_READ_ONLY("Next Spawn Time", iNextSpawnTimer)
|
|
ADD_WIDGET_INT_READ_ONLY("Current Game Time", iCurrentGameTime)
|
|
|
|
START_WIDGET_GROUP("Dialog Stats")
|
|
ADD_WIDGET_BOOL("Has First Outburst", bHasInitialOutburst)
|
|
ADD_WIDGET_INT_READ_ONLY("Initial Speech Time", iFirstDialogTime)
|
|
ADD_WIDGET_INT_READ_ONLY("Next Fight Dialog Time", iNextFightDialogTime)
|
|
ADD_WIDGET_INT_READ_ONLY("Next Freak Dialog Time", iNextFreakDialogTime)
|
|
STOP_WIDGET_GROUP()
|
|
STOP_WIDGET_GROUP()
|
|
|
|
STOP_WIDGET_GROUP()
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Removes Debug Widgets
|
|
PROC CLEANUP_DEBUG_WIDGETS()
|
|
IF DOES_WIDGET_GROUP_EXIST(m_WidgetGroup)
|
|
DELETE_WIDGET_GROUP(m_WidgetGroup)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
#ENDIF
|
|
|
|
//----------------------
|
|
// SCRIPT FLOW
|
|
//----------------------
|
|
|
|
/// PURPOSE:
|
|
/// Handles the Pass Out Sequence, it's animations and dialog
|
|
/// PARAMS:
|
|
/// pWait - Do we wait 2.5 seconds
|
|
FUNC BOOL PASS_OUT_SEQUENCE(BOOL bPass = FALSE)
|
|
VECTOR v
|
|
BOOL bOK = FALSE
|
|
CAMERA_INDEX cCamera
|
|
|
|
// do global stuff here
|
|
UPDATE_CLOWN_PEDS()
|
|
|
|
IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY()
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Trevor", PLAYER_PED_ID(), GET_ENTITY_MODEL(PLAYER_PED_ID()))
|
|
ENDIF
|
|
SET_CUTSCENE_PED_PROP_VARIATION(sSceneHandleBarry, ANCHOR_EYES, 0)
|
|
CPRINTLN(DEBUG_MISSION, "PED CUTSCENE VARIATIONS SET")
|
|
ENDIF
|
|
|
|
// flow of the pass out sequence
|
|
SWITCH ePassOutStage
|
|
|
|
CASE POS_SETUP
|
|
// -----setup--------------------------------
|
|
IF (bPass = TRUE)
|
|
RC_REQUEST_CUTSCENE("bar_4_rcm")
|
|
REQUEST_SCRIPT("postRC_Barry1and2")
|
|
ENDIF
|
|
|
|
PREPARE_MUSIC_EVENT("RC18B_END")
|
|
CPRINTLN(DEBUG_MISSION, "Interactive Music Event: RC18A_COLLAPSE Prepared")
|
|
CPRINTLN(DEBUG_MISSION, "Pass Out - 2.5 Second Warm Up")
|
|
|
|
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
|
|
ePassOutStage = POS_WAIT_FOR_TIRED
|
|
STOP_FIRE_IN_RANGE(GET_ENTITY_COORDS(PLAYER_PED_ID()), 2.0)
|
|
BREAK
|
|
CASE POS_WAIT_FOR_TIRED
|
|
// -----wait for tired--------------------------------
|
|
IF (bPass = FALSE)
|
|
IF IS_ENTITY_OK(gunObject)
|
|
DETACH_ENTITY(gunObject, DEFAULT, FALSE)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
cCamera = CREATE_CAM_WITH_PARAMS("DEFAULT_SCRIPTED_CAMERA", GET_GAMEPLAY_CAM_COORD(), GET_GAMEPLAY_CAM_ROT(), GET_GAMEPLAY_CAM_FOV(), TRUE)
|
|
v = GET_ENTITY_COORDS(PLAYER_PED_ID()) - GET_GAMEPLAY_CAM_COORD()
|
|
ATTACH_CAM_TO_ENTITY(cCamera, PLAYER_PED_ID(), -v)
|
|
|
|
IF DOES_CAM_EXIST(cCamera)
|
|
SET_CAM_ACTIVE(cCamera, TRUE)
|
|
ENDIF
|
|
|
|
// fail safe
|
|
iFailTimer = GET_GAME_TIMER() + 6000
|
|
|
|
ADD_PED_FOR_DIALOGUE(convoPlayer, ENUM_TO_INT(CHAR_TREVOR), PLAYER_PED_ID(), "TREVOR")
|
|
|
|
CPRINTLN(DEBUG_MISSION, "Pass Out - Start Dialog - Going to Start Dialog State")
|
|
ePassOutStage = POS_START_DIALOG
|
|
BREAK
|
|
CASE POS_START_DIALOG
|
|
|
|
// -----start dialog--------------------------------
|
|
bOK = FALSE
|
|
|
|
IF (bPass = TRUE)
|
|
IF CREATE_CONVERSATION(convoPlayer, "BARY2AU", "BARY2_PREOUT", CONV_PRIORITY_HIGH) OR (GET_GAME_TIMER() > iFailTimer)
|
|
IF (GET_GAME_TIMER() < iFailTimer)
|
|
CPRINTLN(DEBUG_MISSION, "Pass Out - Start Dialog - Conversation Created")
|
|
ELSE
|
|
CPRINTLN(DEBUG_MISSION, "Pass Out - Start Dialog - Conversation Not Created - Emergency Abort")
|
|
ENDIF
|
|
|
|
iFailTimer = GET_GAME_TIMER() + 5000
|
|
bOK = TRUE
|
|
ENDIF
|
|
ELSE
|
|
// @SBA - don't want a line played for the fail state - line was getting cut off anyway
|
|
//IF PLAY_SINGLE_LINE_FROM_CONVERSATION(convoPlayer, "BARY2AU", "BARY2_PREOUT", "BARY2_PREOUT_2", CONV_PRIORITY_HIGH) OR (GET_GAME_TIMER() > iFailTimer)
|
|
iFailTimer = GET_GAME_TIMER() + 2000
|
|
|
|
|
|
bOK = TRUE
|
|
//ENDIF
|
|
ENDIF
|
|
|
|
IF (bOK = TRUE)
|
|
CPRINTLN(DEBUG_MISSION, "Pass Out - Start Dialog - We should be ready to play line now")
|
|
ePassOutStage = POS_TRANSITION_FX
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE POS_TRANSITION_FX
|
|
bOK = FALSE
|
|
IF (bPass = TRUE)
|
|
IF (GET_GAME_TIMER() > iFailTimer)
|
|
// @SBA - filter for passing out
|
|
CLEANUP_SCREEN_FX()
|
|
ANIMPOSTFX_PLAY(FX_DrugsOut, 0, FALSE)
|
|
// wait for FX white out
|
|
iFailTimer = GET_GAME_TIMER() + 3500
|
|
bOK = TRUE
|
|
ENDIF
|
|
ELSE
|
|
bOK = TRUE
|
|
ENDIF
|
|
|
|
IF (bOK = TRUE)
|
|
CPRINTLN(DEBUG_MISSION, "Pass Out - FX should be transitioning")
|
|
ePassOutStage = POS_WAIT_DIALOGUE
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE POS_WAIT_DIALOGUE
|
|
|
|
IF (bPass = TRUE)
|
|
bOK = (GET_GAME_TIMER() > iFailTimer)
|
|
ELSE
|
|
|
|
IF (GET_GAME_TIMER() < iFailTimer)
|
|
CPRINTLN(DEBUG_MISSION, "Pass Out - Start Dialog - Conversation Finished")
|
|
ENDIF
|
|
|
|
// make the player pass out and drop weapon (add component)
|
|
//gunObject = CREATE_FAKE_WEAPON_FOR_PLAYER(playerWeapon)
|
|
gunObject = CREATE_WEAPON_OBJECT_FROM_CURRENT_PED_WEAPON_WITH_COMPONENTS(PLAYER_PED_ID())
|
|
IF DOES_ENTITY_EXIST(gunObject)
|
|
IF IS_ENTITY_OK(PLAYER_PED_ID())
|
|
ATTACH_ENTITY_TO_ENTITY(gunObject, PLAYER_PED_ID(), GET_PED_BONE_INDEX(PLAYER_PED_ID(), BONETAG_PH_R_HAND), <<0, 0, 0>>, <<0, 0, 0>>)
|
|
|
|
REMOVE_ALL_PED_WEAPONS(PLAYER_PED_ID())
|
|
|
|
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE)
|
|
SET_PED_TO_RAGDOLL(PLAYER_PED_ID(), 7000, 7500, TASK_RELAX, FALSE, FALSE)
|
|
|
|
// if for any reason the gun hasn't detached...
|
|
IF IS_ENTITY_OK(gunObject) AND IS_ENTITY_ATTACHED(gunObject)
|
|
DETACH_ENTITY(gunObject, DEFAULT, FALSE)
|
|
ENDIF
|
|
|
|
bOK = TRUE
|
|
ENDIF
|
|
// z-skip fix
|
|
ELSE
|
|
CPRINTLN(DEBUG_MISSION, "No weapon - just ending")
|
|
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE)
|
|
SET_PED_TO_RAGDOLL(PLAYER_PED_ID(), 7000, 7500, TASK_RELAX, FALSE, FALSE)
|
|
bOK = TRUE
|
|
ENDIF
|
|
|
|
ENDIF
|
|
IF (bOK = TRUE)
|
|
CPRINTLN(DEBUG_MISSION, "IM Trigger - RC18B_END")
|
|
TRIGGER_MUSIC_EVENT("RC18B_END")
|
|
|
|
iFailTimer = GET_GAME_TIMER() + 1000 //3500
|
|
ePassOutStage = POS_WAIT_PASS_OUT
|
|
ENDIF
|
|
|
|
BREAK
|
|
CASE POS_WAIT_PASS_OUT
|
|
// ----wait for player to pass out--------------------------------
|
|
IF GET_GAME_TIMER() > iFailTimer
|
|
IF (bPass = TRUE)
|
|
|
|
// put this in a proc and call in fail too???
|
|
//CLEANUP_ALL_ALIEN_PEDS(FALSE)
|
|
SAFE_DELETE_OBJECT(gunObject)
|
|
|
|
IF DOES_CAM_EXIST(cCamera)
|
|
SET_CAM_ACTIVE(cCamera, FALSE)
|
|
DESTROY_CAM(cCamera)
|
|
ENDIF
|
|
|
|
SHAKE_GAMEPLAY_CAM("DRUNK_SHAKE", 0)
|
|
SET_TIME_SCALE(1.0)
|
|
DEACTIVATE_AUDIO_SLOWMO_MODE("BARRY_02_SLOWMO")
|
|
SET_AUDIO_FLAG("AllowScriptedSpeechInSlowMo", FALSE)
|
|
SET_AUDIO_FLAG("AllowAmbientSpeechInSlowMo", FALSE)
|
|
|
|
CLEAR_AREA_OF_VEHICLES(vMissionStart, 200.0)
|
|
REMOVE_DECALS_IN_RANGE(vMissionStart, 500.0)
|
|
|
|
IF IS_ENTITY_OK(PLAYER_PED_ID())
|
|
RESET_PED_VISIBLE_DAMAGE(PLAYER_PED_ID())
|
|
CLEAR_PED_BLOOD_DAMAGE(PLAYER_PED_ID())
|
|
ENDIF
|
|
ENDIF
|
|
|
|
CPRINTLN(DEBUG_MISSION, "Pass Out - Complete")
|
|
RETURN TRUE // completed the pass out sequence
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
RETURN FALSE // not completed the pass out sequence
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Loads Mission Assets
|
|
/// PARAMS:
|
|
/// loadWait - if this is true pause script until all assets are loaded
|
|
PROC REQUEST_MISSION_ASSETS()
|
|
|
|
//CLEAR_ASSET_REQUESTER(assetRequester)
|
|
|
|
ADD_ASSET_REQUEST_FROM_STRING(assetRequester, 0, ASSET_AUDIOBANK, "SCRIPT\\BARRY_02_CLOWN_A")
|
|
ADD_ASSET_REQUEST_FROM_STRING(assetRequester, 1, ASSET_AUDIOBANK, "SCRIPT\\BARRY_02_CLOWN_B")
|
|
ADD_ASSET_REQUEST_FROM_STRING(assetRequester, 2, ASSET_AUDIOBANK, "SCRIPT\\BARRY_02_CLOWN_C")
|
|
|
|
ADD_ASSET_REQUEST_FOR_MODEL(assetRequester, 3, clownModel)
|
|
ADD_ASSET_REQUEST_FOR_MODEL(assetRequester, 4, clownCarModel)
|
|
|
|
ADD_ASSET_REQUEST_FOR_TEXT(assetRequester, 5, "BARY2", MISSION_TEXT_SLOT)
|
|
ADD_ASSET_REQUEST_FROM_STRING(assetRequester, 6, ASSET_ANIMDICT, sMissionAnimDictionary)
|
|
ADD_ASSET_REQUEST_FOR_PTFX(assetRequester, 7)
|
|
ADD_ASSET_REQUEST_FROM_STRING(assetRequester, 8, ASSET_ANIMDICT, sMissionAnimDanceDictionary)
|
|
|
|
// @SBA Adding new requests here for simplicity and separation
|
|
ADD_ASSET_REQUEST_FOR_MODEL(assetRequester, 9, mnSpectatorMale)
|
|
ADD_ASSET_REQUEST_FOR_MODEL(assetRequester, 10, mnSpectatorFemale)
|
|
ADD_ASSET_REQUEST_FROM_STRING(assetRequester, 11, ASSET_ANIMDICT, sSpectatorFemAnimDict)
|
|
ADD_ASSET_REQUEST_FROM_STRING(assetRequester, 12, ASSET_ANIMDICT, sSpectatorMaleAnimDict)
|
|
ADD_ASSET_REQUEST_FROM_STRING(assetRequester, 13, ASSET_ANIMDICT, sMimeAnimDict)
|
|
ADD_ASSET_REQUEST_FOR_MODEL(assetRequester, 14, mnProtestSign)
|
|
|
|
ENDPROC
|
|
|
|
//----------------------
|
|
// CHECKPNT FUNCTIONS
|
|
//----------------------
|
|
|
|
/// PURPOSE:
|
|
/// Performs Z Skip
|
|
/// PARAMS:
|
|
/// iTargetStage - which stage to jump to
|
|
PROC DO_Z_SKIP(INT iTargetStage)
|
|
RC_START_Z_SKIP()
|
|
RESET_MISSION_VALUES()
|
|
// @SBA - adding spectators
|
|
DELETE_ALL_SPECTATOR_PEDS()
|
|
DELETE_ALL_CLOWN_PEDS()
|
|
DELETE_ALL_CLOWN_GENERATORS()
|
|
|
|
// @SBA - make sure to reset to game cam if needed
|
|
IF NOT IS_GAMEPLAY_CAM_RENDERING()
|
|
RENDER_SCRIPT_CAMS(FALSE, FALSE)
|
|
ENDIF
|
|
|
|
// Barry and Table Should Not Be Here
|
|
RC_SET_ENTITY_PROOFS_FOR_CUTSCENE(sRCLauncherDataLocal, FALSE)
|
|
RC_CleanupSceneEntities(sRCLauncherDataLocal, TRUE, TRUE, FALSE)
|
|
|
|
SWITCH iTargetStage
|
|
CASE Z_SKIP_TO_INTRO
|
|
CPRINTLN(DEBUG_MISSION, "IM Trigger - RC18B_END")
|
|
TRIGGER_MUSIC_EVENT("RC18B_END")
|
|
SET_ENTITY_COORDS_GROUNDED(PLAYER_PED_ID(), vMissionStart)
|
|
SET_ENTITY_HEADING(PLAYER_PED_ID(), fMissionStart)
|
|
iDbgStageJump = ENUM_TO_INT(SE_INTRO)
|
|
BREAK
|
|
// @SBA - adding new stage
|
|
// This is CP_MISSION_START
|
|
CASE Z_SKIP_TO_PERFORMANCE
|
|
#IF IS_DEBUG_BUILD
|
|
CPRINTLN(DEBUG_MISSION, "Z-Skip or Replay: Performance")
|
|
#ENDIF
|
|
|
|
IF NOT IS_REPLAY_BEING_SET_UP()
|
|
SET_ENTITY_COORDS_GROUNDED(PLAYER_PED_ID(), vMissionStart)
|
|
SET_ENTITY_HEADING(PLAYER_PED_ID(), fMissionStart)
|
|
ENDIF
|
|
|
|
// start performance cam on replay
|
|
ciPerformCamera1 = CREATE_CAM_WITH_PARAMS("DEFAULT_SCRIPTED_CAMERA", <<188.1366, -957.7827, 30.6514>>, <<-5.5067, -8.0000, 92.8053>>, 40.0)
|
|
IF DOES_CAM_EXIST(ciPerformCamera1)
|
|
CPRINTLN(DEBUG_MISSION, "EXIT STATE FOR CAMERA SET: start cam")
|
|
SET_CAM_ACTIVE(ciPerformCamera1, TRUE)
|
|
RENDER_SCRIPT_CAMS(TRUE, FALSE)
|
|
SHAKE_CAM(ciPerformCamera1, "DRUNK_SHAKE")
|
|
ENDIF
|
|
iDbgStageJump = ENUM_TO_INT(SE_PERFORMANCE)
|
|
BREAK
|
|
CASE Z_SKIP_TO_FIRST_CONTACT
|
|
#IF IS_DEBUG_BUILD
|
|
CPRINTLN(DEBUG_MISSION, "Z-Skip or Replay: 1st Contact")
|
|
#ENDIF
|
|
|
|
SET_ENTITY_COORDS_GROUNDED(PLAYER_PED_ID(), vMissionStart)
|
|
SET_ENTITY_HEADING(PLAYER_PED_ID(), fMissionStart)
|
|
iDbgStageJump = ENUM_TO_INT(SE_FIRSTCONTACT)
|
|
BREAK
|
|
CASE Z_SKIP_TO_FIRST_WAVE
|
|
#IF IS_DEBUG_BUILD
|
|
CPRINTLN(DEBUG_MISSION, "Z-Skip or Replay: 1st Wave")
|
|
#ENDIF
|
|
|
|
SET_ENTITY_COORDS_GROUNDED(PLAYER_PED_ID(), <<179.1285, -961.5800, 29.0923>>)
|
|
SET_ENTITY_HEADING(PLAYER_PED_ID(), 143.3596)
|
|
iDbgStageJump = ENUM_TO_INT(SE_WAVE1)
|
|
BREAK
|
|
CASE Z_SKIP_TO_SECOND_WAVE
|
|
#IF IS_DEBUG_BUILD
|
|
CPRINTLN(DEBUG_MISSION, "Z-Skip or Replay: 2nd Wave")
|
|
#ENDIF
|
|
|
|
SET_ENTITY_COORDS_GROUNDED(PLAYER_PED_ID(), <<176.0677, -976.4255, 29.0923>>)
|
|
SET_ENTITY_HEADING(PLAYER_PED_ID(), 324.8268)
|
|
iDbgStageJump = ENUM_TO_INT(SE_WAVE2)
|
|
BREAK
|
|
CASE Z_SKIP_TO_THIRD_WAVE
|
|
#IF IS_DEBUG_BUILD
|
|
CPRINTLN(DEBUG_MISSION, "Z-Skip or Replay: 3nd Wave")
|
|
#ENDIF
|
|
|
|
SET_ENTITY_COORDS_GROUNDED(PLAYER_PED_ID(), <<188.0644, -948.7751, 29.0923>>)
|
|
SET_ENTITY_HEADING(PLAYER_PED_ID(), 329.9782)
|
|
iDbgStageJump = ENUM_TO_INT(SE_WAVE3)
|
|
BREAK
|
|
// @SBA this is CP_MID_STAGE
|
|
CASE Z_SKIP_TO_FOURTH_WAVE
|
|
#IF IS_DEBUG_BUILD
|
|
CPRINTLN(DEBUG_MISSION, "Z-Skip or Replay: 4th Wave")
|
|
#ENDIF
|
|
|
|
IF NOT IS_REPLAY_BEING_SET_UP()
|
|
SET_ENTITY_COORDS_GROUNDED(PLAYER_PED_ID(), <<188.9320, -952.0983, 29.0923>>)
|
|
SET_ENTITY_HEADING(PLAYER_PED_ID(), 325.7944)
|
|
ENDIF
|
|
iDbgStageJump = ENUM_TO_INT(SE_WAVE4)
|
|
BREAK
|
|
CASE Z_SKIP_TO_FIFTH_WAVE
|
|
#IF IS_DEBUG_BUILD
|
|
CPRINTLN(DEBUG_MISSION, "Z-Skip or Replay: 5th Wave")
|
|
#ENDIF
|
|
|
|
SET_ENTITY_COORDS_GROUNDED(PLAYER_PED_ID(), <<213.3817, -919.8522, 29.6929>>)
|
|
SET_ENTITY_HEADING(PLAYER_PED_ID(), 323.9430)
|
|
iDbgStageJump = ENUM_TO_INT(SE_WAVE5)
|
|
BREAK
|
|
// @SNA - new
|
|
CASE Z_SKIP_TO_SIXTH_WAVE
|
|
#IF IS_DEBUG_BUILD
|
|
CPRINTLN(DEBUG_MISSION, "Z-Skip or Replay: 6th Wave")
|
|
#ENDIF
|
|
|
|
SET_ENTITY_COORDS_GROUNDED(PLAYER_PED_ID(), <<209.8298, -912.4507, 29.6921>>)
|
|
SET_ENTITY_HEADING(PLAYER_PED_ID(), 138.4911)
|
|
iDbgStageJump = ENUM_TO_INT(SE_WAVE6)
|
|
BREAK
|
|
CASE Z_SKIP_TO_PASSOUT
|
|
#IF IS_DEBUG_BUILD
|
|
CPRINTLN(DEBUG_MISSION, "Z-Skip or Replay: Pass out")
|
|
#ENDIF
|
|
iDbgStageJump = ENUM_TO_INT(SE_PASSOUT)
|
|
BREAK
|
|
// @SBA - this is CP_OUTRO
|
|
CASE Z_SKIP_TO_OUTRO
|
|
#IF IS_DEBUG_BUILD
|
|
CPRINTLN(DEBUG_MISSION, "Z-Skip or Replay: Outro")
|
|
#ENDIF
|
|
iDbgStageJump = ENUM_TO_INT(SE_OUTRO)
|
|
BREAK
|
|
CASE Z_SKIP_TO_TEST
|
|
#IF IS_DEBUG_BUILD
|
|
CPRINTLN(DEBUG_MISSION, "Z-Skip or Replay: TEST")
|
|
#ENDIF
|
|
iDbgStageJump = ENUM_TO_INT(SE_TEST)
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
// delete and unload everything
|
|
stageEnum = INT_TO_ENUM(STAGE_ENUM, iDbgStageJump)
|
|
stageProgress = SP_LOADING
|
|
IF (iDbgStageJump > ENUM_TO_INT(SE_TEST)) AND (iDbgStageJump < ENUM_TO_INT(SE_PASSOUT))
|
|
TRIGGER_MUSIC_EVENT("RC18B_START")
|
|
IF NOT IS_AUDIO_SCENE_ACTIVE(sndAlienAmbientScene)
|
|
START_AUDIO_SCENE(sndAlienAmbientScene)
|
|
ENDIF
|
|
|
|
CPRINTLN(DEBUG_MISSION, "[BARRY 2] - PLAY SCREEN FX - FX_DrugsSkip")
|
|
ANIMPOSTFX_PLAY(FX_DrugsSkip, 0, TRUE)
|
|
SET_TIME_SCALE(fTimeScale)
|
|
DEACTIVATE_AUDIO_SLOWMO_MODE("BARRY_02_SLOWMO")
|
|
ACTIVATE_AUDIO_SLOWMO_MODE("BARRY_02_SLOWMO")
|
|
SET_AUDIO_FLAG("AllowScriptedSpeechInSlowMo", TRUE)
|
|
SET_AUDIO_FLAG("AllowAmbientSpeechInSlowMo", TRUE)
|
|
|
|
FORCE_PLAYER_WEAPON()
|
|
ENDIF
|
|
|
|
ENABLE_AMBIENT_PEDS_AND_VEHICLES(FALSE, FALSE, TRUE, TRUE)
|
|
|
|
END_REPLAY_SETUP(NULL, VS_DRIVER, FALSE)
|
|
|
|
IF iDbgStageJump = ENUM_TO_INT(SE_OUTRO)
|
|
OR iDbgStageJump = ENUM_TO_INT(SE_PERFORMANCE)
|
|
RC_END_Z_SKIP(TRUE, FALSE, FALSE)
|
|
ELSE
|
|
RC_END_Z_SKIP()
|
|
ENDIF
|
|
|
|
SET_GAMEPLAY_CAM_RELATIVE_HEADING()
|
|
SET_GAMEPLAY_CAM_RELATIVE_PITCH()
|
|
|
|
ANIMPOSTFX_PLAY(FX_DrugsIn, 0, TRUE)
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Cleans mission
|
|
PROC MISSION_SETUP()
|
|
// my mission setup - these things are only done once
|
|
CPRINTLN(DEBUG_MISSION, " ")
|
|
CPRINTLN(DEBUG_MISSION, "BARRY 2 - VERSION:", MISSION_VERSION)
|
|
|
|
REQUEST_MISSION_ASSETS()
|
|
|
|
// areas
|
|
SET_ANGLED_AREA(battleArea, <<226.221329,-848.208069,25.421360>>, <<163.914642,-1012.380005,54.881466>>, 131.750000)
|
|
battleAreaInner = EXPAND_ANGLED_AREA(battleArea, -10.0)
|
|
battleAreaOuter = EXPAND_ANGLED_AREA(battleArea, 20.0)
|
|
|
|
//SET_ANGLED_AREA(battleAreaOuter, <<231.158264,-839.291626,25.425917>>, <<161.858002,-1023.933411,56.252029>>, 138.5)
|
|
|
|
// @SBA - set a lager area to cover most of the battle zone
|
|
// SET_ANGLED_AREA(respotVehicleArea, <<176.729996,-969.593384,37.092262>>, <<195.129456,-941.357605,27.191963>>, 21.500000)
|
|
SET_ANGLED_AREA(respotVehicleArea, <<168.850021,-1001.023804,23.091291>>, <<225.904175,-862.596924,34.092327>>, 55.000000)
|
|
|
|
// turn off debug lines just in case i forget and shops
|
|
SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(FALSE)
|
|
SET_ALL_SHOPS_TEMPORARILY_UNAVAILABLE(TRUE)
|
|
SUPPRESS_PICKUP_REWARD_TYPE(PICKUP_REWARD_TYPE_ALL, TRUE)
|
|
|
|
// setup z skip menu
|
|
#IF IS_DEBUG_BUILD
|
|
sSkipMenu[Z_SKIP_TO_INTRO].sTxtLabel = "INTRO"
|
|
sSkipMenu[Z_SKIP_TO_PERFORMANCE].sTxtLabel = "PERFORMANCE"
|
|
sSkipMenu[Z_SKIP_TO_FIRST_CONTACT].sTxtLabel = "FIRST CONTACT"
|
|
sSkipMenu[Z_SKIP_TO_FIRST_WAVE].sTxtLabel = "1ST WAVE"
|
|
sSkipMenu[Z_SKIP_TO_SECOND_WAVE].sTxtLabel = "2ND WAVE"
|
|
sSkipMenu[Z_SKIP_TO_THIRD_WAVE].sTxtLabel = "3RD WAVE"
|
|
sSkipMenu[Z_SKIP_TO_FOURTH_WAVE].sTxtLabel = "4TH WAVE"
|
|
sSkipMenu[Z_SKIP_TO_FIFTH_WAVE].sTxtLabel = "5TH WAVE"
|
|
sSkipMenu[Z_SKIP_TO_SIXTH_WAVE].sTxtLabel = "6TH WAVE"
|
|
sSkipMenu[Z_SKIP_TO_PASSOUT].sTxtLabel = "COLLAPSE"
|
|
sSkipMenu[Z_SKIP_TO_OUTRO].sTxtLabel = "OUTRO"
|
|
sSkipMenu[Z_SKIP_TO_TEST].sTxtLabel = "TEST"
|
|
SETUP_DEBUG_WIDGETS()
|
|
#ENDIF
|
|
|
|
// stop police bothering me
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
SET_MAX_WANTED_LEVEL(0)
|
|
SET_PLAYER_WANTED_LEVEL(GET_PLAYER_INDEX(), 0)
|
|
SET_PLAYER_WANTED_LEVEL_NOW(GET_PLAYER_INDEX())
|
|
// @SBA - remember armor level (since this isn't "real" he shouldn't lose armor once it's done)
|
|
iPlayerStartingArmor = GET_PED_ARMOUR(PLAYER_PED_ID())
|
|
CPRINTLN(DEBUG_MISSION, "MISSION_SETUP: Player's starting armor level = ", iPlayerStartingArmor)
|
|
ENDIF
|
|
|
|
ENABLE_ALL_DISPATCH_SERVICES(FALSE)
|
|
DISABLE_CELLPHONE(TRUE)
|
|
|
|
// set weather transition
|
|
SET_WEATHER_TYPE_OVERTIME_PERSIST("extrasunny", 10.000)
|
|
|
|
SPECIAL_ABILITY_LOCK(GET_PLAYER_PED_MODEL(CHAR_TREVOR))
|
|
SPECIAL_ABILITY_RESET(PLAYER_ID())
|
|
RESET_MISSION_VALUES()
|
|
|
|
DISABLE_CHEAT(CHEAT_TYPE_SPAWN_VEHICLE, TRUE)
|
|
DISABLE_CHEAT(CHEAT_TYPE_GIVE_WEAPONS, TRUE)
|
|
|
|
DISABLE_TAXI_HAILING(TRUE)
|
|
|
|
// replay malarky
|
|
IF IS_REPLAY_IN_PROGRESS()= TRUE // Set up the initial scene for replays
|
|
CPRINTLN(DEBUG_MISSION, "REPLAY IN PROGRESS", MISSION_VERSION)
|
|
g_bSceneAutoTrigger = TRUE
|
|
eInitialSceneStage = IS_REQUEST_SCENE
|
|
WHILE NOT SetupScene_BARRY_2(sRCLauncherDataLocal)
|
|
WAIT(0)
|
|
ENDWHILE
|
|
g_bSceneAutoTrigger = FALSE
|
|
ENABLE_AMBIENT_PEDS_AND_VEHICLES(FALSE, FALSE, TRUE, TRUE)
|
|
BLOCK_SCENARIOS_AND_AMBIENT(scenarioBlock)
|
|
// WAIT_FOR_WORLD_TO_LOAD(vMissionStart)
|
|
// SAFE_TELEPORT_ENTITY(PLAYER_PED_ID(), vMissionStart, fMissionStart, TRUE)
|
|
|
|
SET_AMBIENT_ZONE_STATE(sAmbientZone, TRUE)
|
|
|
|
WHILE NOT HAVE_ASSET_REQUESTS_LOADED(assetRequester)
|
|
WAIT(0)
|
|
ENDWHILE
|
|
|
|
stageEnum = SE_FIRSTCONTACT
|
|
stageProgress = SP_LOADING
|
|
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
CPRINTLN(DEBUG_MISSION, "Please Stop T-Posing...")
|
|
SET_ENTITY_VISIBLE(PLAYER_PED_ID(), TRUE)
|
|
ENDIF
|
|
|
|
INT iReplayStage = GET_REPLAY_MID_MISSION_STAGE()
|
|
|
|
IF g_bShitskipAccepted = TRUE
|
|
iReplayStage++ // player is skipping this stage
|
|
ENDIF
|
|
|
|
|
|
|
|
SWITCH iReplayStage
|
|
CASE CP_MISSION_START
|
|
// @SBA - inital wave is now performance
|
|
START_REPLAY_SETUP(vMissionStart, fMissionStart, FALSE)
|
|
Do_Z_Skip(Z_SKIP_TO_PERFORMANCE) // skip to the inital clowns
|
|
|
|
IF NOT ANIMPOSTFX_IS_RUNNING(FX_DrugsSkip)
|
|
CPRINTLN(DEBUG_MISSION, "[BARRY2] - REPLAY START - CP_MISSION_START - PLAY FX:FX_DrugsSkip")
|
|
ANIMPOSTFX_PLAY(FX_DrugsSkip, 0, TRUE)
|
|
ENDIF
|
|
BREAK
|
|
CASE CP_MID_STAGE
|
|
START_REPLAY_SETUP((<<188.9320, -952.0983, 29.0923>>), 325.7944, FALSE)
|
|
SETUP_TREVOR_DIALOG()
|
|
Do_Z_Skip(Z_SKIP_TO_FOURTH_WAVE) // skip to the 2 wave of clowns
|
|
PRINT_NOW("B2_PRIME", DEFAULT_GOD_TEXT_TIME, 1) // Kill the Clowns
|
|
IF NOT ANIMPOSTFX_IS_RUNNING(FX_DrugsSkip)
|
|
CPRINTLN(DEBUG_MISSION, "[BARRY2] - REPLAY START - PLAY FX:FX_DrugsSkip")
|
|
ANIMPOSTFX_PLAY(FX_DrugsSkip, 0, TRUE)
|
|
ENDIF
|
|
BREAK
|
|
CASE CP_OUTRO
|
|
SAFE_FADE_SCREEN_OUT_TO_BLACK()
|
|
Do_Z_Skip(Z_SKIP_TO_OUTRO) // skip to the end
|
|
BREAK
|
|
|
|
DEFAULT
|
|
SCRIPT_ASSERT("Replay in progress: Unknown checkpoint selected")
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
ENDIF
|
|
|
|
ENABLE_CLOWN_BLOOD_VFX(TRUE)
|
|
RESET_MISSION_COMBAT_PARAMETERS(combatParams)
|
|
CPRINTLN(DEBUG_MISSION, "SETUP DONE")
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Cleans up the scripted cameras
|
|
PROC CLEANUP_CAMERAS()
|
|
IF DOES_CAM_EXIST(ciPerformCamera1)
|
|
SET_CAM_ACTIVE(ciPerformCamera1, FALSE)
|
|
DESTROY_CAM(ciPerformCamera1)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
// PURPOSE:
|
|
/// Cleans mission
|
|
PROC MISSION_CLEANUP()
|
|
IF IS_AUDIO_SCENE_ACTIVE(sndAlienAmbientScene)
|
|
STOP_AUDIO_SCENE(sndAlienAmbientScene)
|
|
ENDIF
|
|
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(iApplauseSound)
|
|
|
|
// @SBA - adding spectators to this
|
|
CLEANUP_ALL_SPECTATOR_PEDS()
|
|
|
|
FLEE_ALL_CLOWN_PEDS()
|
|
CLEANUP_ALL_CLOWN_PEDS()
|
|
CLEANUP_ALL_CLOWN_GENERATORS()
|
|
|
|
IF DOES_ENTITY_EXIST(sRCLauncherDataLocal.pedID[0])
|
|
DELETE_PED(sRCLauncherDataLocal.pedID[0])
|
|
ENDIF
|
|
|
|
SET_PLAYER_HEALTH_RECHARGE_MULTIPLIER(PLAYER_ID(), 1.0)
|
|
SET_PLAYER_WEAPON_DAMAGE_MODIFIER(GET_PLAYER_INDEX(), 1.0)
|
|
|
|
SET_PED_CAN_SWITCH_WEAPON(PLAYER_PED_ID(), TRUE)
|
|
SPECIAL_ABILITY_UNLOCK(GET_PLAYER_PED_MODEL(CHAR_TREVOR))
|
|
SET_PED_USING_ACTION_MODE(PLAYER_PED_ID(), FALSE)
|
|
|
|
SAFE_REMOVE_BLIP(locationBlip)
|
|
// @SBA - make sure cams are gone
|
|
CLEANUP_CAMERAS()
|
|
|
|
ENABLE_CLOWN_BLOOD_VFX(FALSE)
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Cleanups Script and terminates thread - this should be the last function called
|
|
PROC SCRIPT_CLEANUP()
|
|
|
|
// Ensure launcher is cleaned up
|
|
RC_CLEANUP_LAUNCHER()
|
|
|
|
// If the mission was triggered then additional mission cleanup will be required.
|
|
IF (Random_Character_Cleanup_If_Triggered())
|
|
#IF IS_DEBUG_BUILD
|
|
CPRINTLN(DEBUG_MISSION, "Random Character Script was triggered so additional cleanup required")
|
|
#ENDIF
|
|
ENDIF
|
|
|
|
SET_PLAYER_HEALTH_RECHARGE_MULTIPLIER(GET_PLAYER_INDEX(), 1.0)
|
|
SET_PLAYER_WEAPON_DAMAGE_MODIFIER(GET_PLAYER_INDEX(), 1.0)
|
|
|
|
IF HAS_PED_GOT_WEAPON(PLAYER_PED_ID(), playerWeapon)
|
|
SET_PED_INFINITE_AMMO(PLAYER_PED_ID(), FALSE, playerWeapon)
|
|
ENDIF
|
|
|
|
CLEANUP_SCREEN_FX()
|
|
MISSION_CLEANUP()
|
|
UNLOAD_REQUESTED_ASSETS(assetRequester)
|
|
//UNLOAD_MISSION_ASSETS()
|
|
SET_ALL_SHOPS_TEMPORARILY_UNAVAILABLE(FALSE)
|
|
SET_CONTROL_SHAKE(PLAYER_CONTROL, 0, 0)
|
|
DISABLE_TAXI_HAILING(FALSE)
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
CLEANUP_DEBUG_WIDGETS()
|
|
#ENDIF
|
|
|
|
// restore world based things
|
|
SHAKE_GAMEPLAY_CAM("DRUNK_SHAKE", 0)
|
|
|
|
// @SBA - adding spectators to this
|
|
DELETE_ALL_SPECTATOR_PEDS()
|
|
|
|
// @SBA - restore armor
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
CPRINTLN(DEBUG_MISSION, "MISSION_SETUP: Restoring player's previous armor level of: ", iPlayerStartingArmor)
|
|
SET_PED_ARMOUR(PLAYER_PED_ID(), iPlayerStartingArmor)
|
|
ENDIF
|
|
|
|
SAFE_REMOVE_BLIP(locationBlip)
|
|
CLEANUP_ALL_CLOWN_PEDS(TRUE)
|
|
|
|
CLEAR_PED_BLOOD_DAMAGE(PLAYER_PED_ID())
|
|
//CLEAR_AREA_OF_VEHICLES(vMainLocation, 30.0)
|
|
REMOVE_DECALS_IN_RANGE(vMissionStart, 500.0)
|
|
SET_TIME_SCALE(1.0)
|
|
DEACTIVATE_AUDIO_SLOWMO_MODE("BARRY_02_SLOWMO")
|
|
SET_AUDIO_FLAG("AllowScriptedSpeechInSlowMo", FALSE)
|
|
SET_AUDIO_FLAG("AllowAmbientSpeechInSlowMo", FALSE)
|
|
|
|
DISABLE_CHEAT(CHEAT_TYPE_SPAWN_VEHICLE, FALSE)
|
|
DISABLE_CHEAT(CHEAT_TYPE_GIVE_WEAPONS, FALSE)
|
|
|
|
ENABLE_ALL_DISPATCH_SERVICES(TRUE)
|
|
CLEAR_ALL_PICKUP_REWARD_TYPE_SUPPRESSION()
|
|
DISABLE_CELLPHONE(FALSE)
|
|
|
|
ENABLE_AMBIENT_PEDS_AND_VEHICLES(TRUE, TRUE)
|
|
UNBLOCK_SCENARIOS_AND_AMBIENT(scenarioBlock)
|
|
|
|
CLEAR_WEATHER_TYPE_PERSIST()
|
|
|
|
FREEZE_ENTITY_POSITION(PLAYER_PED_ID(), FALSE)
|
|
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
|
|
CLEAR_AMBIENT_ZONE_STATE(sAmbientZone, TRUE)
|
|
RC_CleanupSceneEntities(sRCLauncherDataLocal, FALSE)
|
|
TERMINATE_THIS_THREAD()
|
|
ENDPROC
|
|
|
|
|
|
/// PURPOSE:
|
|
/// Handles Mission Passed
|
|
PROC SCRIPT_PASSED()
|
|
#IF IS_DEBUG_BUILD
|
|
CPRINTLN(DEBUG_MISSION, "Mission Passed")
|
|
#ENDIF
|
|
|
|
//FLEE_ALL_ALIEN_PEDS()
|
|
IF HAS_PED_GOT_WEAPON(PLAYER_PED_ID(), playerWeapon)
|
|
SET_PED_INFINITE_AMMO(PLAYER_PED_ID(), FALSE, playerWeapon)
|
|
ENDIF
|
|
REMOVE_ALL_PED_WEAPONS(PLAYER_PED_ID())
|
|
//SIMULATE_PLAYER_INPUT_GAIT(PLAYER_ID(), PEDMOVE_WALK, 1000)
|
|
// ADD_CONTACT_TO_PHONEBOOK(CHAR_BARRY, TREVOR_BOOK)
|
|
|
|
// This needs to be done before random character passed as the replay values are reset
|
|
Restore_Game_State_Snapshot_Weapons(g_startSnapshot)
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
RESTORE_PLAYER_PED_WEAPONS(PLAYER_PED_ID())
|
|
ENDIF
|
|
|
|
CPRINTLN(DEBUG_MISSION, "Starting postRC_Barry1and2")
|
|
START_NEW_SCRIPT("postRC_Barry1and2", DEFAULT_STACK_SIZE)
|
|
SET_SCRIPT_AS_NO_LONGER_NEEDED("postRC_Barry1and2")
|
|
|
|
Random_Character_Passed(CP_RAND_C_BAR2)
|
|
SCRIPT_CLEANUP()
|
|
ENDPROC
|
|
|
|
//----------------------
|
|
// STATE FUNCTIONS
|
|
//----------------------
|
|
|
|
/// PURPOSE:
|
|
/// @SBA - creates the peds for the opening performance
|
|
PROC CREATE_INITIAL_PERFORMANCE_PEDS()
|
|
INT idx
|
|
|
|
// @SBA - keeping in case we get new lead out
|
|
// Init and make spectators, ensure they start clapping immediately
|
|
// INITIALIZE_PERFORMANCE_SPECTATOR_DATA()
|
|
// REPEAT COUNT_OF(ssSpectator) idx
|
|
// IF CREATE_SPECTATOR_PED(idx)
|
|
// SET_ENTITY_VISIBLE(ssSpectator[idx].piPed, TRUE)
|
|
// ssSpectator[idx].ssState = SS_WATCH_CLOWN
|
|
// ENDIF
|
|
// ENDREPEAT
|
|
|
|
// Create first clown (center), set "special" for custom treatment
|
|
IF GET_FREE_CLOWN_PED_INDEX(idx)
|
|
//IF CREATE_CLOWN_PED(clownPed[idx], (<<175.2541, -958.2550, 30.1>>), 262.4564, TRUE, TRUE)
|
|
IF CREATE_CLOWN_PED(clownPed[idx], (<<163.92494, -956.99603, 29.09192>>), 262.4564, TRUE)
|
|
i1stPerformanceClownID = idx
|
|
SET_CLOWN_TYPE(clownPed[i1stPerformanceClownID], SCT_SPECIAL)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Clown on right
|
|
IF GET_FREE_CLOWN_PED_INDEX(idx)
|
|
CREATE_CLOWN_PED(clownPed[idx], (<<166.44772, -955.05847, 29.09192>>), 263.4564)
|
|
i2ndPerformanceClownID = idx
|
|
SET_CLOWN_TYPE(clownPed[i2ndPerformanceClownID], SCT_SPECIAL)
|
|
ENDIF
|
|
|
|
// clown on left
|
|
IF GET_FREE_CLOWN_PED_INDEX(idx)
|
|
CREATE_CLOWN_PED(clownPed[idx], (<<168.95203, -960.75641, 29.07847>>), 265.4564)
|
|
i3rdPerformanceClownID = idx
|
|
SET_CLOWN_TYPE(clownPed[i3rdPerformanceClownID], SCT_SPECIAL)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// @SBA - these are the last two clowns who pop in for the performance, straight to active state
|
|
PROC CREATE_FINAL_PERFORMANCE_CLOWNS()
|
|
INT idx
|
|
|
|
// Clown on right
|
|
IF GET_FREE_CLOWN_PED_INDEX(idx)
|
|
CREATE_CLOWN_PED(clownPed[idx], (<<174.05942, -960.29022, 30.09226>>), 262.4564, TRUE)
|
|
i2ndPerformanceClownID = idx
|
|
SET_CLOWN_TYPE(clownPed[i2ndPerformanceClownID], SCT_SPECIAL)
|
|
ENDIF
|
|
|
|
// clown on left
|
|
IF GET_FREE_CLOWN_PED_INDEX(idx)
|
|
CREATE_CLOWN_PED(clownPed[idx], (<<175.53503, -956.09955, 30.09226>>), 265.4564, TRUE)
|
|
i3rdPerformanceClownID = idx
|
|
SET_CLOWN_TYPE(clownPed[i3rdPerformanceClownID], SCT_SPECIAL)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// @SBA - creates a clown performer (if desired) and an random audience of spectators
|
|
/// PARAMS:
|
|
/// SpawnZone - the general area in which the spawn points are grouped (SZ_ZONE_1 = start, 2 = middle, 3 = end)
|
|
/// iMinNumSpectators - Minimum number of spectators to create.
|
|
/// iMaxNumSpectators - Max number to create. A random number bewteen min and max will be spawned, depedning on available slots.
|
|
/// bMakeClown - Set FALSE if you just want to make some spectators that will flee (and no clown)
|
|
PROC CREATE_GENERAL_CLOWN_PERFORMANCE(SPAWN_ZONES SpawnZone, INT iMinNumSpectators = 2, INT iMaxNumSpectators = kiNumberOfSpectators, BOOL bMakeClown = TRUE)
|
|
|
|
// Exit if too many or too few spectators specified
|
|
IF iMinNumSpectators < 1
|
|
OR iMaxNumSpectators > kiNumberOfSpectators
|
|
OR iMinNumSpectators > iMaxNumSpectators
|
|
CPRINTLN(DEBUG_MISSION, "CREATE_GENERAL_CLOWN_PERFORMANCE: *** Spectators out of range! iMinNumSpectators = ", iMinNumSpectators, "; iMaxNumSpectators = ", iMaxNumSpectators)
|
|
EXIT
|
|
ENDIF
|
|
|
|
// How many spectators could we create at maximum?
|
|
INT iAvailableSlots = kiNumberOfSpectators - GET_ALIVE_SPECTATOR_PED_COUNT()
|
|
|
|
// Are there enough slots at minimum?
|
|
IF iAvailableSlots < iMinNumSpectators
|
|
// Do we want to force this? Yes.
|
|
IF iAvailableSlots > 0
|
|
CPRINTLN(DEBUG_MISSION, "CREATE_GENERAL_CLOWN_PERFORMANCE: Need to increase min spectators: iMinNumSpectators = ", iMinNumSpectators, "; iAvailableSlots = ", iAvailableSlots)
|
|
iMinNumSpectators = iAvailableSlots
|
|
ELSE
|
|
CPRINTLN(DEBUG_MISSION, "CREATE_GENERAL_CLOWN_PERFORMANCE: NO AVAILABLE SLOTS! iMinNumSpectators = ", iMinNumSpectators, "; iAvailableSlots = ", iAvailableSlots)
|
|
EXIT
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Can we create the max number requested? If not, set max to what is available.
|
|
IF iAvailableSlots < iMaxNumSpectators
|
|
IF iAvailableSlots > 0
|
|
CPRINTLN(DEBUG_MISSION, "CREATE_GENERAL_CLOWN_PERFORMANCE: Need to reduce max spectators: iMaxNumSpectators = ", iMaxNumSpectators, "; iAvailableSlots = ", iAvailableSlots)
|
|
iMaxNumSpectators = iAvailableSlots
|
|
ELSE
|
|
CPRINTLN(DEBUG_MISSION, "CREATE_GENERAL_CLOWN_PERFORMANCE: NO AVAILABLE SLOTS! iMaxNumSpectators = ", iMaxNumSpectators, "; iAvailableSlots = ", iAvailableSlots)
|
|
EXIT
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Pick a random number of spectators based on what's avaialble
|
|
INT iRandomNum = GET_RANDOM_INT_IN_RANGE(iMinNumSpectators, iMaxNumSpectators)
|
|
CPRINTLN(DEBUG_MISSION, "CREATE_GENERAL_CLOWN_PERFORMANCE: Randomized number of spectators = ", iRandomNum)
|
|
|
|
INT ind, idx
|
|
|
|
IF GET_SPECIFIC_PERFORMANCE_SPAWN_DATA(SpawnZone, idx, NOT bMakeClown)
|
|
IF bMakeClown
|
|
IF GET_FREE_CLOWN_PED_INDEX(ind)
|
|
IF CREATE_CLOWN_PED(clownPed[ind], CPD_SpecificData[idx].vClownPos, CPD_SpecificData[idx].fClownHead, TRUE, TRUE)
|
|
CPRINTLN(DEBUG_MISSION, "CREATE_GENERAL_CLOWN_PERFORMANCE: Created performance clown")
|
|
SET_CLOWN_TYPE(clownPed[ind], SCT_PERFORM)
|
|
SPAWN_SPECTATORS_FOR_GENERAL_PERFORMANCE(CPD_SpecificData[idx], iRandomNum)
|
|
ELSE
|
|
CPRINTLN(DEBUG_MISSION, "CREATE_GENERAL_CLOWN_PERFORMANCE: *** Could not create performance clown! ***")
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
CPRINTLN(DEBUG_MISSION, "CREATE_GENERAL_CLOWN_PERFORMANCE: No Clown Requested. Making just spectators.")
|
|
SPAWN_SPECTATORS_FOR_GENERAL_PERFORMANCE(CPD_SpecificData[idx], iRandomNum, NOT bMakeClown)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
|
|
/// PURPOSE:
|
|
/// Puts all living/active clowns into the active state
|
|
PROC RETURN_CLOWNS_TO_STATE_MACHINE()
|
|
INT i
|
|
REPEAT (COUNT_OF(clownPed)) i
|
|
IF IS_CLOWN_PED_ALIVE(clownPed[i])
|
|
clownPed[i].aState = CS_ACTIVE
|
|
ENDIF
|
|
ENDREPEAT
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Creates initial clowns
|
|
PROC CREATE_INITIAL_CLOWNS()
|
|
INT ind
|
|
|
|
IF bInitialClowns = TRUE
|
|
EXIT
|
|
ENDIF
|
|
|
|
IF GET_FREE_CLOWN_PED_INDEX(ind)
|
|
IF CREATE_CLOWN_PED(clownPed[ind], <<181.1, -951.9, 30.1>>)
|
|
// @SBA this clown goes to attack first
|
|
//clownPed[ind].iDanceTimer = 0
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF GET_FREE_CLOWN_PED_INDEX(ind)
|
|
IF CREATE_CLOWN_PED(clownPed[ind], <<173.0, -956.9, 30.1>>)
|
|
clownPed[ind].iDanceTimer = 0
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF GET_FREE_CLOWN_PED_INDEX(ind)
|
|
IF CREATE_CLOWN_PED(clownPed[ind], <<174.7, -948.1, 30.1>>)
|
|
clownPed[ind].iDanceTimer = 0
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// @SBA - Create a performance with 5 spectators
|
|
CREATE_GENERAL_CLOWN_PERFORMANCE(SZ_ZONE_1, 5)
|
|
|
|
CPRINTLN(DEBUG_MISSION, "INITIAL CLOWNS CREATED")
|
|
bInitialClowns = TRUE
|
|
ENDPROC
|
|
|
|
// Get clown dancing for initial performance
|
|
FUNC BOOL MAKE_CLOWN_DANCE_FOR_PERFORMANCE(CLOWN_PED &clown, STRING sDanceAnim, FLOAT fStartPhase = 0.0)
|
|
IF clown.aState = CS_NULL
|
|
IF NOT IS_ENTITY_PLAYING_ANIM(clown.pedID, sMissionAnimDanceDictionary, sDanceAnim)
|
|
CPRINTLN(DEBUG_MISSION, "MAKE_CLOWN_DANCE_FOR_PERFORMANCE: PERFORM, CLOWN!!")
|
|
clown.danceAnim = sDanceAnim
|
|
TASK_PLAY_ANIM(clown.pedID, sMissionAnimDanceDictionary, clown.danceAnim, NORMAL_BLEND_IN, -1, -1, AF_DEFAULT, fStartPhase) //, kfMimeStartPhase)
|
|
ELSE
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
// when clown is done dancing, get him to aim at player (for initial performance)
|
|
FUNC BOOL HAVE_CLOWN_AIM_AT_PLAYER(CLOWN_PED &clown)
|
|
|
|
// If clown died, just assume true
|
|
IF NOT IS_ENTITY_OK(clown.pedID)
|
|
RETURN TRUE
|
|
ENDIF
|
|
IF (GET_SCRIPT_TASK_STATUS(clown.pedID, SCRIPT_TASK_AIM_GUN_AT_ENTITY) > PERFORMING_TASK)
|
|
IF NOT IS_ENTITY_PLAYING_ANIM(clown.pedID, sMissionAnimDanceDictionary, clown.danceAnim)
|
|
CPRINTLN(DEBUG_MISSION, "HAVE_CLOWN_AIM_AT_PLAYER: AIM, CLOWN!!")
|
|
// Reset the timer here to avoid premature dancing
|
|
clown.iDanceTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(iMinClownDanceDelay, iMaxClownDanceDelay)
|
|
TASK_AIM_GUN_AT_ENTITY(clown.pedID, PLAYER_PED_ID(), -1, TRUE)
|
|
RETURN TRUE
|
|
ENDIF
|
|
ELSE
|
|
RETURN TRUE
|
|
ENDIF
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
// when clown is done dancing, get him to attack player (for initial performance)
|
|
FUNC BOOL HAVE_CLOWN_ATTACK_PLAYER(CLOWN_PED &clown)
|
|
// If clown died, just assume true
|
|
IF NOT IS_ENTITY_OK(clown.pedID)
|
|
RETURN TRUE
|
|
ENDIF
|
|
IF (GET_SCRIPT_TASK_STATUS(clown.pedID, SCRIPT_TASK_COMBAT) > PERFORMING_TASK)
|
|
IF NOT IS_ENTITY_PLAYING_ANIM(clown.pedID, sMissionAnimDanceDictionary, clown.danceAnim)
|
|
CPRINTLN(DEBUG_MISSION, "HAVE_CLOWN_ATTACK_PLAYER: ATTACK, CLOWN!!")
|
|
clown.iDanceTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(iMinClownDanceDelay, iMaxClownDanceDelay)
|
|
clown.aState = CS_ACTIVE
|
|
TASK_COMBAT_PED(clown.pedID, PLAYER_PED_ID(), COMBAT_PED_DISABLE_AIM_INTRO)
|
|
RETURN TRUE
|
|
ENDIF
|
|
ELSE
|
|
RETURN TRUE
|
|
ENDIF
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
// @SBA - special case stuff for the lead out performance
|
|
FUNC BOOL INTRO_PERFORMANCE_ATTACK_SPECTATORS(CLOWN_PED &clown, PED_INDEX pi1stTarget, PED_INDEX pi2ndTarget = NULL)
|
|
|
|
IF clownPed[i1stPerformanceClownID].aState != CS_NULL
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
IF NOT IS_PED_INJURED(clown.pedID)
|
|
AND NOT IS_PED_INJURED(pi1stTarget)
|
|
|
|
IF GET_SCRIPT_TASK_STATUS(clown.pedID, SCRIPT_TASK_PERFORM_SEQUENCE) > PERFORMING_TASK
|
|
|
|
SEQUENCE_INDEX seq
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_AIM_GUN_AT_ENTITY(NULL, pi1stTarget, GET_RANDOM_INT_IN_RANGE(750, 1000))
|
|
TASK_SHOOT_AT_ENTITY(NULL, pi1stTarget, GET_RANDOM_INT_IN_RANGE(500, 750), FIRING_TYPE_CONTINUOUS)
|
|
IF pi2ndTarget != NULL
|
|
TASK_AIM_GUN_AT_ENTITY(NULL, pi2ndTarget, GET_RANDOM_INT_IN_RANGE(500, 750))
|
|
TASK_SHOOT_AT_ENTITY(NULL, pi2ndTarget, GET_RANDOM_INT_IN_RANGE(500, 750), FIRING_TYPE_CONTINUOUS)
|
|
TASK_AIM_GUN_AT_ENTITY(NULL, PLAYER_PED_ID(), INFINITE_TASK_TIME)
|
|
// ELSE
|
|
// TASK_SHOOT_AT_ENTITY(NULL, pi1stTarget, 500, FIRING_TYPE_CONTINUOUS)
|
|
ENDIF
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(clown.pedID, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
|
|
RETURN TRUE
|
|
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
|
|
ENDFUNC
|
|
|
|
|
|
/// PURPOSE:
|
|
/// Handles the timing of the intro lead-out performance in which the clowns shoot the spectators
|
|
/// RETURNS:
|
|
/// TRUE when the performance is complete
|
|
FUNC BOOL HANDLE_INTRO_PERFORMANCE()
|
|
|
|
// for asserts
|
|
IS_ENTITY_OK(clownPed[i1stPerformanceClownID].pedID)
|
|
IS_ENTITY_OK(clownPed[i2ndPerformanceClownID].pedID)
|
|
IS_ENTITY_OK(clownPed[i3rdPerformanceClownID].pedID)
|
|
IS_ENTITY_OK(PLAYER_PED_ID())
|
|
|
|
// Trevor's first line
|
|
IF NOT bTrevFirstLine
|
|
IF psPerformanceState = PS_KILL_CLOWNS
|
|
AND (GET_GAME_TIMER() > iFirstDialogTime)
|
|
ADD_PED_FOR_DIALOGUE(convoPlayer, ENUM_TO_INT(CHAR_TREVOR), PLAYER_PED_ID(), "TREVOR")
|
|
IF CREATE_CONVERSATION(convoPlayer, "BARY2AU", "BARY2_FREAK", CONV_PRIORITY_HIGH, DO_NOT_DISPLAY_SUBTITLES)
|
|
CPRINTLN(DEBUG_MISSION, "Trevor's first rant")
|
|
bTrevFirstLine = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
SWITCH psPerformanceState
|
|
|
|
CASE PS_MIME_CLOWN_MIME
|
|
// Ensure player control is off
|
|
IF IS_PLAYER_CONTROL_ON(PLAYER_ID())
|
|
CPRINTLN(DEBUG_MISSION, "HANDLE_INTRO_PERFORMANCE: PLAYER CONTROL was on, turning off.")
|
|
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE)
|
|
ENDIF
|
|
|
|
// trigger music if not triggered
|
|
IF (bTransitionStarted = FALSE)
|
|
bTransitionStarted = TRUE
|
|
TRIGGER_MUSIC_EVENT("RC18B_START")
|
|
ENDIF
|
|
|
|
// Put first clowns into dance anim once done teleporting
|
|
IF MAKE_CLOWN_DANCE_FOR_PERFORMANCE(clownPed[i1stPerformanceClownID], "clown_idle_0")
|
|
AND MAKE_CLOWN_DANCE_FOR_PERFORMANCE(clownPed[i2ndPerformanceClownID], "clown_idle_6", 0.1)
|
|
AND MAKE_CLOWN_DANCE_FOR_PERFORMANCE(clownPed[i3rdPerformanceClownID], "clown_idle_3", 0.1)
|
|
CPRINTLN(DEBUG_MISSION, "HANDLE_INTRO_PERFORMANCE: ALL CLOWNS SHOULD BE DANCING")
|
|
psPerformanceState = PS_MOVE_PLAYER
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE PS_MOVE_PLAYER
|
|
|
|
// have clown on left laugh (if not already speaking)
|
|
IF NOT IS_AMBIENT_SPEECH_PLAYING(clownPed[i3rdPerformanceClownID].pedID)
|
|
CPRINTLN(DEBUG_MISSION, "HANDLE_INTRO_PERFORMANCE: Laugh, Clown, Laugh!")
|
|
PLAY_PED_AMBIENT_SPEECH_WITH_VOICE(clownPed[i3rdPerformanceClownID].pedID, "CLOWN_LAUGH", "CLOWNS", SPEECH_PARAMS_FORCE_SHOUTED_CLEAR)
|
|
ENDIF
|
|
|
|
// Hold on second cam after interp, and move the player
|
|
IF DOES_CAM_EXIST(ciPerformCamera1)
|
|
IF IS_CAM_ACTIVE(ciPerformCamera1)
|
|
CPRINTLN(DEBUG_MISSION, "HANDLE_INTRO_PERFORMANCE: CAM PLAYING - MOVING PLAYER")
|
|
// @SBA - teleporting player
|
|
SAFE_TELEPORT_ENTITY(PLAYER_PED_ID(), (<<187.78902, -959.62036, 29.00801>>), 85.0)
|
|
// dummy ref
|
|
CANCEL_TIMER(tmrPerformance)
|
|
//psPerformanceState = PS_SPAWN_WEAPON
|
|
psPerformanceState = PS_KILLING_SPECTATORS
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
|
|
// @SBA - saving this in case we get a new lead out
|
|
// CASE PS_SPAWN_WEAPON
|
|
// IF SPAWN_GUN_IN_CLOWNS_HAND(clownPed[i1stPerformanceClownID], sMimeAnimDict, kfMimeGunSpawnPhase, kfMimeEndPhase, bPlayedGunSmokeFX)
|
|
// // Get a target and aim at it while we wait for reinforcements
|
|
// IF NOT IS_PED_INJURED(ssSpectator[1].piPed)
|
|
// TASK_AIM_GUN_AT_ENTITY(clownPed[i1stPerformanceClownID].pedID, ssSpectator[1].piPed, -1)
|
|
// ENDIF
|
|
// // Start timer for attack and last clown spawns
|
|
// START_TIMER_NOW(tmrPerformance)
|
|
// psPerformanceState = PS_SPAWN_LAST_CLOWNS
|
|
// ENDIF
|
|
// BREAK
|
|
|
|
// CASE PS_SPAWN_LAST_CLOWNS
|
|
// // Check the timer to spawn in the rest of the killer clowns
|
|
// IF TIMER_DO_ONCE_WHEN_READY(tmrPerformance, 0.200)
|
|
// CPRINTLN(DEBUG_MISSION, "HANDLE_INTRO_PERFORMANCE: Spawning last clowns")
|
|
// CREATE_FINAL_PERFORMANCE_CLOWNS()
|
|
// // Start timer for attack and last clown spawns
|
|
// START_TIMER_NOW(tmrPerformance)
|
|
// psPerformanceState = PS_CLOWNS_ATTACK_SPECTATORS
|
|
// ENDIF
|
|
// BREAK
|
|
|
|
// CASE PS_CLOWNS_ATTACK_SPECTATORS
|
|
// // Check timer, then set intial clown into attack state
|
|
// IF TIMER_DO_ONCE_WHEN_READY(tmrPerformance, 0.100)
|
|
// CPRINTLN(DEBUG_MISSION, "HANDLE_INTRO_PERFORMANCE: 1st Clown should be attacking spectators.")
|
|
// MAKE_CLOWN_MORE_AGGRESSIVE(clownPed[i1stPerformanceClownID], TRUE)
|
|
// INTRO_PERFORMANCE_ATTACK_SPECTATORS(clownPed[i1stPerformanceClownID], ssSpectator[1].piPed)
|
|
// SET_CLOWN_TYPE(clownPed[i1stPerformanceClownID], SCT_NORMAL)
|
|
// psPerformanceState = PS_CLOWNS_ATTACK_SPECTATORS_2
|
|
// ENDIF
|
|
// BREAK
|
|
|
|
// CASE PS_CLOWNS_ATTACK_SPECTATORS_2
|
|
// IF INTRO_PERFORMANCE_ATTACK_SPECTATORS(clownPed[i2ndPerformanceClownID], ssSpectator[0].piPed, ssSpectator[2].piPed)
|
|
// AND INTRO_PERFORMANCE_ATTACK_SPECTATORS(clownPed[i3rdPerformanceClownID], ssSpectator[4].piPed, ssSpectator[3].piPed)
|
|
// CPRINTLN(DEBUG_MISSION, "HANDLE_INTRO_PERFORMANCE: Last two clowns should be attacking spectators.")
|
|
// psPerformanceState = PS_KILLING_SPECTATORS
|
|
// ENDIF
|
|
// BREAK
|
|
|
|
CASE PS_KILLING_SPECTATORS
|
|
// Put first clown into his dance anim once he's done a'killin'
|
|
// IF clownPed[i1stPerformanceClownID].aState = CS_NULL
|
|
// IF GET_SCRIPT_TASK_STATUS(clownPed[i1stPerformanceClownID].pedID, SCRIPT_TASK_PERFORM_SEQUENCE) > PERFORMING_TASK
|
|
// CPRINTLN(DEBUG_MISSION, "HANDLE_INTRO_PERFORMANCE: 1st clown is ready to do happy dance.")
|
|
// clownPed[i1stPerformanceClownID].aState = CS_DANCE_START
|
|
// ENDIF
|
|
// ENDIF
|
|
// Have spectators died
|
|
// IF GET_ALIVE_SPECTATOR_PED_COUNT() = 0
|
|
|
|
// 1st clown should be done dancing first, but monitor others
|
|
HAVE_CLOWN_AIM_AT_PLAYER(clownPed[i2ndPerformanceClownID])
|
|
HAVE_CLOWN_AIM_AT_PLAYER(clownPed[i3rdPerformanceClownID])
|
|
IF HAVE_CLOWN_AIM_AT_PLAYER(clownPed[i1stPerformanceClownID])
|
|
CPRINTLN(DEBUG_MISSION, "HANDLE_INTRO_PERFORMANCE: 1st clown should be aiming")
|
|
|
|
// give the player his weapon
|
|
FORCE_PLAYER_WEAPON()
|
|
|
|
// Reset to the game cam
|
|
SET_GAMEPLAY_CAM_RELATIVE_PITCH()
|
|
SET_GAMEPLAY_CAM_RELATIVE_HEADING()
|
|
|
|
IF GET_CAM_VIEW_MODE_FOR_CONTEXT(CAM_VIEW_MODE_CONTEXT_ON_FOOT) = CAM_VIEW_MODE_FIRST_PERSON
|
|
RENDER_SCRIPT_CAMS(FALSE, FALSE, DEFAULT_INTERP_IN_TIME)
|
|
ELSE
|
|
RENDER_SCRIPT_CAMS(FALSE, TRUE, DEFAULT_INTERP_IN_TIME)
|
|
ENDIF
|
|
|
|
SET_CAM_ACTIVE(ciPerformCamera1, FALSE)
|
|
psPerformanceState = PS_RETURN_PLAYER_CONTROL
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE PS_RETURN_PLAYER_CONTROL
|
|
// update aims
|
|
HAVE_CLOWN_AIM_AT_PLAYER(clownPed[i2ndPerformanceClownID])
|
|
HAVE_CLOWN_AIM_AT_PLAYER(clownPed[i3rdPerformanceClownID])
|
|
|
|
// Return player control once the camera is done interpolating
|
|
IF IS_GAMEPLAY_CAM_RENDERING()
|
|
CPRINTLN(DEBUG_MISSION, "HANDLE_INTRO_PERFORMANCE: NOW BACK TO GAME CAMERA")
|
|
IF NOT IS_PLAYER_CONTROL_ON(PLAYER_ID())
|
|
CPRINTLN(DEBUG_MISSION, "HANDLE_INTRO_PERFORMANCE: RESTORING PLAYER CONTROL")
|
|
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
|
|
ENDIF
|
|
// Print objective
|
|
PRINT_NOW("B2_PRIME", DEFAULT_GOD_TEXT_TIME, 1) // Kill the Clowns
|
|
RC_END_CUTSCENE_MODE(TRUE, FALSE)
|
|
psPerformanceState = PS_CLOWNS_ATTACK_PLAYER
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE PS_CLOWNS_ATTACK_PLAYER
|
|
// 1st clown should finish first, others can keep aiming
|
|
HAVE_CLOWN_AIM_AT_PLAYER(clownPed[i2ndPerformanceClownID])
|
|
HAVE_CLOWN_AIM_AT_PLAYER(clownPed[i3rdPerformanceClownID])
|
|
IF HAVE_CLOWN_ATTACK_PLAYER(clownPed[i1stPerformanceClownID])
|
|
CPRINTLN(DEBUG_MISSION, "HANDLE_INTRO_PERFORMANCE: 1st Clown is attacking!")
|
|
iFirstDialogTime = GET_GAME_TIMER() + 1500
|
|
psPerformanceState = PS_KILL_CLOWNS
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE PS_KILL_CLOWNS
|
|
HAVE_CLOWN_ATTACK_PLAYER(clownPed[i1stPerformanceClownID])
|
|
HAVE_CLOWN_ATTACK_PLAYER(clownPed[i2ndPerformanceClownID])
|
|
HAVE_CLOWN_ATTACK_PLAYER(clownPed[i3rdPerformanceClownID])
|
|
// check if clowns are dead
|
|
IF (iAliveClownCount = 0)
|
|
CPRINTLN(DEBUG_MISSION, "HANDLE_INTRO_PERFORMANCE: ALL CLOWNS ARE DEAD - DONE!")
|
|
psPerformanceState = PS_DONE
|
|
RETURN TRUE
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE PS_DONE
|
|
// Nothing
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Updates Leading Sequence
|
|
/// PARAMS:
|
|
/// prog - stage progress enum, tells us what state we are in
|
|
PROC UPDATE_STAGE_LEADIN(STAGE_PROGRESS &prog)
|
|
RC_PLAYER_TRIGGER_SCENE_LOCK_IN()
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_DETONATE)
|
|
SET_ALL_RANDOM_PEDS_FLEE_THIS_FRAME(PLAYER_ID())
|
|
HANDLE_LOCK_PLAYER_IN_FRONT_OF_TABLE()
|
|
|
|
SWITCH (prog)
|
|
CASE SP_LOADING
|
|
REQUEST_MISSION_ASSETS()
|
|
SECURE_REQUEST_AND_LOAD_ANIM_DICT(sMissionAnimDanceDictionary, FALSE)
|
|
prog = SP_SETUP
|
|
|
|
IF IS_ENTITY_ALIVE(sRCLauncherDataLocal.pedID[0])
|
|
|
|
IF GET_CAM_VIEW_MODE_FOR_CONTEXT(CAM_VIEW_MODE_CONTEXT_ON_FOOT) = CAM_VIEW_MODE_FIRST_PERSON
|
|
SET_GAMEPLAY_ENTITY_HINT(sRCLauncherDataLocal.pedID[0], (<<0.0, 0, 0.3>>), TRUE, -1, 3000)
|
|
SET_GAMEPLAY_HINT_CAMERA_RELATIVE_SIDE_OFFSET(0.0)
|
|
ELSE
|
|
SET_GAMEPLAY_ENTITY_HINT(sRCLauncherDataLocal.pedID[0], (<<0.6, 0, 0.3>>), TRUE, -1, 3000)
|
|
SET_GAMEPLAY_HINT_CAMERA_RELATIVE_SIDE_OFFSET(-0.04)
|
|
ENDIF
|
|
|
|
SET_GAMEPLAY_HINT_FOLLOW_DISTANCE_SCALAR(0.43)
|
|
|
|
//SET_GAMEPLAY_HINT_BASE_ORBIT_PITCH_OFFSET(1.0)
|
|
SET_GAMEPLAY_HINT_CAMERA_RELATIVE_VERTICAL_OFFSET(-0.02)
|
|
SET_GAMEPLAY_HINT_FOV(30.00)
|
|
SET_GAMEPLAY_HINT_CAMERA_BLEND_TO_FOLLOW_PED_MEDIUM_VIEW_MODE(TRUE)
|
|
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
TASK_LOOK_AT_ENTITY(PLAYER_PED_ID(), sRCLauncherDataLocal.pedID[0], -1)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
BREAK
|
|
CASE SP_SETUP
|
|
IF HAS_ANIM_DICT_LOADED(sMissionAnimDanceDictionary)
|
|
AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
CPRINTLN(DEBUG_MISSION, "LEAD-IN ANIMS LOADED")
|
|
structPedsForConversation sConversation
|
|
ADD_PED_FOR_DIALOGUE(sConversation, 1, PLAYER_PED_ID(), "TREVOR")
|
|
ADD_PED_FOR_DIALOGUE(sConversation, 0, sRCLauncherDataLocal.pedID[0], "BARRY")
|
|
|
|
IF CREATE_CONVERSATION(sConversation ,"BARY2AU", "BAR_3_RCM_LI", CONV_PRIORITY_MEDIUM, DISPLAY_SUBTITLES)
|
|
TASK_PLAY_ANIM(sRCLauncherDataLocal.pedID[0], sMissionAnimDanceDictionary, "lead_in", NORMAL_BLEND_IN, SLOW_BLEND_OUT, -1, AF_HOLD_LAST_FRAME)
|
|
TASK_LOOK_AT_ENTITY(sRCLauncherDataLocal.pedID[0], PLAYER_PED_ID(), INFINITE_TASK_TIME, SLF_WHILE_NOT_IN_FOV, SLF_LOOKAT_VERY_HIGH)
|
|
CPRINTLN(DEBUG_MISSION, "STARTED PLAYING LEAD-IN CONVERSATION")
|
|
prog = SP_RUNNING
|
|
iStateTimeOut = GET_GAME_TIMER() + 30000
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE SP_RUNNING
|
|
IF IS_ENTITY_ALIVE(sRCLauncherDataLocal.pedID[0])
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() OR (GET_GAME_TIMER() > iStateTimeOut )
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
TASK_CLEAR_LOOK_AT(PLAYER_PED_ID())
|
|
ENDIF
|
|
prog = SP_CLEANUP
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE SP_CSKIPPED
|
|
BREAK
|
|
CASE SP_CLEANUP
|
|
|
|
IF IS_GAMEPLAY_HINT_ACTIVE()
|
|
STOP_GAMEPLAY_HINT()
|
|
ENDIF
|
|
|
|
CPRINTLN(DEBUG_MISSION, "LEAD IN FINISHED")
|
|
stageEnum = SE_INTRO
|
|
prog = SP_LOADING
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Updates Intro Sequence
|
|
/// PARAMS:
|
|
/// prog - stage progress enum, tells us what state we are in
|
|
PROC UPDATE_STAGE_INTRO(STAGE_PROGRESS &prog)
|
|
|
|
SWITCH (prog)
|
|
CASE SP_LOADING
|
|
//DELETE_ALL_ALIEN_PEDS()
|
|
CPRINTLN(DEBUG_MISSION, "REQUESTED CUTSCENE")
|
|
RC_REQUEST_CUTSCENE("BAR_3_RCM")
|
|
stageProgress = SP_SETUP
|
|
START_MISSION_DEBUG_TIMER()
|
|
//CLEAR_PED_BLOOD_DAMAGE(PLAYER_PED_ID())
|
|
BREAK
|
|
CASE SP_SETUP
|
|
bHasPlayerCameraExitState = FALSE
|
|
|
|
IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY()
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Trevor", PLAYER_PED_ID(), GET_ENTITY_MODEL(PLAYER_PED_ID()))
|
|
ENDIF
|
|
SET_CUTSCENE_PED_PROP_VARIATION(sSceneHandleBarry, ANCHOR_EYES, 0)
|
|
CPRINTLN(DEBUG_MISSION, "PED CUTSCENE VARIATIONS SET")
|
|
ENDIF
|
|
|
|
CPRINTLN(DEBUG_MISSION, "CHECKING TO SEE IF CUTSCENE IS OK TO START")
|
|
IF RC_IS_CUTSCENE_OK_TO_START()
|
|
CPRINTLN(DEBUG_MISSION, "CUTSCENE IS OK TO START")
|
|
|
|
IF IS_ENTITY_ALIVE(sRCLauncherDataLocal.pedID[0])
|
|
REGISTER_ENTITY_FOR_CUTSCENE(sRCLauncherDataLocal.pedID[0], sSceneHandleBarry, CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
|
|
CPRINTLN(DEBUG_MISSION, "REGISTERED BARRY")
|
|
ELSE
|
|
REGISTER_ENTITY_FOR_CUTSCENE(sRCLauncherDataLocal.pedID[0], sSceneHandleBarry, CU_CREATE_AND_ANIMATE_NEW_SCRIPT_ENTITY, GET_NPC_PED_MODEL(CHAR_BARRY))
|
|
CPRINTLN(DEBUG_MISSION, "REGISTERED NEW BARRY")
|
|
ENDIF
|
|
|
|
IF IS_ENTITY_ALIVE(sRCLauncherDataLocal.objID[OBJ_TABLE])
|
|
REGISTER_ENTITY_FOR_CUTSCENE(sRCLauncherDataLocal.objID[OBJ_TABLE], sSceneHandleTable, CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
|
|
CPRINTLN(DEBUG_MISSION, "REGISTERED TABLE")
|
|
ELSE
|
|
REGISTER_ENTITY_FOR_CUTSCENE(sRCLauncherDataLocal.objID[OBJ_TABLE], sSceneHandleTable, CU_CREATE_AND_ANIMATE_NEW_SCRIPT_ENTITY, PROP_PROTEST_TABLE_01)
|
|
CPRINTLN(DEBUG_MISSION, "REGISTERED NEW TABLE")
|
|
ENDIF
|
|
|
|
IF IS_ENTITY_ALIVE(sRCLauncherDataLocal.objID[OBJ_CHAIR])
|
|
REGISTER_ENTITY_FOR_CUTSCENE(sRCLauncherDataLocal.objID[OBJ_CHAIR], sSceneHandleChair, CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
|
|
CPRINTLN(DEBUG_MISSION, "REGISTERED CHAIR")
|
|
ELSE
|
|
REGISTER_ENTITY_FOR_CUTSCENE(sRCLauncherDataLocal.objID[OBJ_CHAIR], sSceneHandleChair, CU_CREATE_AND_ANIMATE_NEW_SCRIPT_ENTITY, PROP_CHAIR_08)
|
|
CPRINTLN(DEBUG_MISSION, "REGISTERED NEW CHAIR")
|
|
ENDIF
|
|
|
|
// @SBA - adding this prop. Uncomment the registrations once the cutscene handle is fixed (otherwise causes and assert)
|
|
IF IS_ENTITY_ALIVE(sRCLauncherDataLocal.objID[OBJ_PAPERS])
|
|
//REGISTER_ENTITY_FOR_CUTSCENE(sRCLauncherDataLocal.objID[OBJ_PAPERS], sSceneHandlePapers, CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
|
|
SET_OBJECT_AS_NO_LONGER_NEEDED(sRCLauncherDataLocal.objID[OBJ_PAPERS]) // REMOVE THIS!
|
|
DUMMY_REFERENCE_STRING(sSceneHandlePapers) // AND THIS!
|
|
CPRINTLN(DEBUG_MISSION, "REGISTERED PAPERS")
|
|
ELSE
|
|
//REGISTER_ENTITY_FOR_CUTSCENE(sRCLauncherDataLocal.objID[OBJ_PAPERS], sSceneHandlePapers, CU_CREATE_AND_ANIMATE_NEW_SCRIPT_ENTITY, P_A4_Sheets_S)
|
|
CPRINTLN(DEBUG_MISSION, "REGISTERED NEW PAPERS")
|
|
ENDIF
|
|
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
REGISTER_ENTITY_FOR_CUTSCENE(PLAYER_PED_ID(), "Trevor", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
|
|
CPRINTLN(DEBUG_MISSION, "REGISTERED TREVOR")
|
|
ENDIF
|
|
|
|
// set up cut cam for post cutscene
|
|
ciPerformCamera1 = CREATE_CAM_WITH_PARAMS("DEFAULT_SCRIPTED_CAMERA", <<188.1366, -957.7827, 30.6514>>, <<-5.5067, -8.0000, 92.8053>>, 40.0)
|
|
|
|
// Cleanup launcher which will remove lead-in blip
|
|
RC_CLEANUP_LAUNCHER()
|
|
|
|
START_CUTSCENE()
|
|
REPLAY_START_EVENT(REPLAY_IMPORTANCE_LOW)
|
|
SET_CUTSCENE_CAN_BE_SKIPPED(FALSE)
|
|
WAIT(0)
|
|
|
|
ENABLE_AMBIENT_PEDS_AND_VEHICLES(FALSE, FALSE, TRUE, FALSE)
|
|
RESOLVE_MISSION_VEHICLES_FOR_CUTSCENE()
|
|
RC_START_CUTSCENE_MODE(vMissionStart, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE)
|
|
BLOCK_SCENARIOS_AND_AMBIENT(scenarioBlock)
|
|
|
|
CLEANUP_SCREEN_FX()
|
|
CREATE_STANDING_SIGN(sRCLauncherDataLocal.objID[OBJ_SIGN], mnProtestSign)
|
|
SAFE_FADE_SCREEN_IN_FROM_BLACK(500, FALSE)
|
|
REQUEST_MISSION_ASSETS()
|
|
|
|
stageProgress = SP_RUNNING
|
|
ENDIF
|
|
BREAK
|
|
CASE SP_RUNNING
|
|
|
|
IF NOT IS_CUTSCENE_PLAYING()
|
|
|
|
SET_TIME_SCALE(fTimeScale)
|
|
ACTIVATE_AUDIO_SLOWMO_MODE("BARRY_02_SLOWMO")
|
|
SET_AUDIO_FLAG("AllowScriptedSpeechInSlowMo", TRUE)
|
|
SET_AUDIO_FLAG("AllowAmbientSpeechInSlowMo", TRUE)
|
|
|
|
// @SBA - don't want player to have control yet or give weapon(?)
|
|
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE)
|
|
//FORCE_PLAYER_WEAPON()
|
|
|
|
stageProgress = SP_LOADING
|
|
stageEnum = SE_PERFORMANCE// @SBA - adding performance stage OLD = SE_FIRSTCONTACT
|
|
ELSE
|
|
INT iCutTime
|
|
iCutTime = GET_CUTSCENE_TIME()
|
|
CDEBUG3LN(DEBUG_MISSION, "Cutscene Time = ", iCutTime)
|
|
|
|
IF (bShowDebugMissionTime)
|
|
SET_TEXT_SCALE(0.5, 0.5)
|
|
DISPLAY_TEXT_WITH_NUMBER(0.1, 0.1, "NUMBER", iCutTime)
|
|
ENDIF
|
|
|
|
IF HAVE_ASSET_REQUESTS_LOADED(assetRequester)
|
|
IF NOT bSkipAllowed
|
|
SET_CUTSCENE_CAN_BE_SKIPPED(TRUE)
|
|
bSkipAllowed = TRUE
|
|
ENDIF
|
|
// not sure this is really used - skipping seems built in
|
|
IF (iCutTime < 59000)
|
|
IF IS_CUTSCENE_SKIP_BUTTON_JUST_PRESSED_WITH_DELAY()
|
|
stageProgress = SP_CSKIPPED
|
|
CPRINTLN(DEBUG_MISSION, "Cutscene Skipped - Assets Loaded")
|
|
EXIT
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF (bTransitionStarted = FALSE)
|
|
IF (iCutTime >= CUTSCENE_TRANSITION_TIME)
|
|
CPRINTLN(DEBUG_MISSION, "Transition started!")
|
|
bTransitionStarted = TRUE
|
|
STRING FXname
|
|
FXname = FX_DrugsIn
|
|
IF WAS_CUTSCENE_SKIPPED()
|
|
CPRINTLN(DEBUG_MISSION, "Starting screen effect (cs skipped)")
|
|
FXname = FX_DrugsSkip
|
|
ENDIF
|
|
ANIMPOSTFX_PLAY(FXname, 0, TRUE)
|
|
TRIGGER_MUSIC_EVENT("RC18B_START")
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// @SBA - adding first performace clown
|
|
IF (bPerformancePedsCreated = FALSE) AND (iCutTime >= CUTSCENE_CLOWN_TIME)
|
|
CREATE_INITIAL_PERFORMANCE_PEDS()
|
|
bPerformancePedsCreated = TRUE
|
|
ELIF bPerformancePedsCreated
|
|
HANDLE_INTRO_PERFORMANCE()
|
|
ENDIF
|
|
|
|
// is this happening too late in the cutscene?
|
|
IF CAN_SET_EXIT_STATE_FOR_CAMERA()
|
|
REPLAY_STOP_EVENT()
|
|
// @SBA - cut to performance cam
|
|
IF DOES_CAM_EXIST(ciPerformCamera1)
|
|
CPRINTLN(DEBUG_MISSION, "EXIT STATE FOR CAMERA SET: start cam")
|
|
SET_CAM_ACTIVE(ciPerformCamera1, TRUE)
|
|
RENDER_SCRIPT_CAMS(TRUE, FALSE)
|
|
SHAKE_CAM(ciPerformCamera1, "DRUNK_SHAKE")
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Trevor")
|
|
CPRINTLN(DEBUG_MISSION, "EXIT STATE FOR PLAYER SET")
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE SP_CSKIPPED
|
|
|
|
SET_CUTSCENE_FADE_VALUES(false, false, FALSE, false)
|
|
SAFE_FADE_SCREEN_OUT_TO_BLACK(250, TRUE)
|
|
IF IS_CUTSCENE_PLAYING()
|
|
WAIT_FOR_CUTSCENE_TO_STOP()
|
|
ENDIF
|
|
//RC_END_CUTSCENE_MODE(TRUE, FALSE)
|
|
|
|
// trigger music if not triggered
|
|
IF (bTransitionStarted = FALSE)
|
|
bTransitionStarted = TRUE
|
|
TRIGGER_MUSIC_EVENT("RC18B_START")
|
|
IF NOT ANIMPOSTFX_IS_RUNNING(FX_DrugsSkip)
|
|
ANIMPOSTFX_PLAY(FX_DrugsSkip, 0, TRUE)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// @SBA - don't want player to have control yet or give weapon(?)
|
|
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE)
|
|
//FORCE_PLAYER_WEAPON()
|
|
|
|
// @SBA - cut to performance cam
|
|
IF DOES_CAM_EXIST(ciPerformCamera1)
|
|
CPRINTLN(DEBUG_MISSION, "Cutscene skipped: start cam")
|
|
SET_CAM_ACTIVE(ciPerformCamera1, TRUE)
|
|
RENDER_SCRIPT_CAMS(TRUE, FALSE)
|
|
SHAKE_CAM(ciPerformCamera1, "DRUNK_SHAKE")
|
|
ENDIF
|
|
|
|
WAIT(500)
|
|
|
|
// update handler
|
|
IF bPerformancePedsCreated
|
|
HANDLE_INTRO_PERFORMANCE()
|
|
ENDIF
|
|
|
|
stageProgress = SP_LOADING
|
|
stageEnum = SE_PERFORMANCE// @SBA - adding performance stage OLD = SE_FIRSTCONTACT
|
|
BREAK
|
|
CASE SP_CLEANUP
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Updates The Pass Out Sequence
|
|
/// PARAMS:
|
|
/// prog - stage progress enum, tells us what state we are in
|
|
PROC UPDATE_STAGE_TEST(STAGE_PROGRESS &prog)
|
|
SWITCH (prog)
|
|
CASE SP_LOADING
|
|
CASE SP_SETUP
|
|
SAFE_FADE_SCREEN_IN_FROM_BLACK(500, FALSE)
|
|
CPRINTLN(DEBUG_MISSION, "ENTERING UPDATE STAGE TEST")
|
|
CLEAR_PRINTS()
|
|
CLEAR_HELP()
|
|
// @SBA - adding spectators
|
|
DELETE_ALL_SPECTATOR_PEDS()
|
|
DELETE_ALL_CLOWN_PEDS()
|
|
DELETE_ALL_CLOWN_GENERATORS()
|
|
prog = SP_RUNNING
|
|
BREAK
|
|
CASE SP_RUNNING
|
|
BREAK
|
|
CASE SP_CLEANUP
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
|
|
/// PURPOSE:
|
|
/// @SBA - adding this stage - Updates the opening Performance stage
|
|
/// PARAMS:
|
|
/// prog - stage progress enum, tells us what state we are in
|
|
PROC UPDATE_STAGE_PERFORMANCE(STAGE_PROGRESS &prog)
|
|
|
|
SWITCH (prog)
|
|
CASE SP_LOADING
|
|
|
|
WHILE NOT HAVE_ASSET_REQUESTS_LOADED(assetRequester)
|
|
WAIT(0)
|
|
ENDWHILE
|
|
|
|
// @SBA - make performance peds if not made already
|
|
IF NOT bPerformancePedsCreated
|
|
CREATE_INITIAL_PERFORMANCE_PEDS()
|
|
bPerformancePedsCreated = TRUE
|
|
ENDIF
|
|
// update handler
|
|
HANDLE_INTRO_PERFORMANCE()
|
|
|
|
prog = SP_SETUP
|
|
iMaxActivePeds = 5
|
|
|
|
RC_SET_ENTITY_PROOFS_FOR_CUTSCENE(sRCLauncherDataLocal, FALSE)
|
|
RC_CleanupSceneEntities(sRCLauncherDataLocal, TRUE, TRUE, FALSE)
|
|
START_MISSION_DEBUG_TIMER()
|
|
|
|
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_MISSION_START, "Mission Start", FALSE)
|
|
BREAK
|
|
|
|
CASE SP_SETUP
|
|
CLEAR_PRINTS()
|
|
CPRINTLN(DEBUG_MISSION, "PERFORMANCE (you'll laugh 'til you die).")
|
|
INFORM_MISSION_STATS_OF_DAMAGE_WATCH_ENTITY(PLAYER_PED_ID())
|
|
IF NOT IS_AUDIO_SCENE_ACTIVE(sndAlienAmbientScene)
|
|
START_AUDIO_SCENE(sndAlienAmbientScene)
|
|
ENDIF
|
|
CLEAR_PED_BLOOD_DAMAGE(PLAYER_PED_ID())
|
|
SET_AMBIENT_ZONE_STATE(sAmbientZone, TRUE)
|
|
|
|
SETUP_TREVOR_DIALOG()
|
|
|
|
// update handler
|
|
HANDLE_INTRO_PERFORMANCE()
|
|
|
|
SAFE_FADE_SCREEN_IN_FROM_BLACK(500, FALSE)
|
|
//TRIGGER_MUSIC_EVENT("RC18B_START")
|
|
|
|
prog = SP_RUNNING
|
|
BREAK
|
|
|
|
CASE SP_RUNNING
|
|
// Is performance done and are clowns dead?
|
|
IF HANDLE_INTRO_PERFORMANCE()
|
|
CPRINTLN(DEBUG_MISSION, "GOING TO PERFORMANCE CLEANUP")
|
|
prog = SP_CLEANUP
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE SP_CLEANUP
|
|
prog = SP_LOADING
|
|
stageEnum = SE_FIRSTCONTACT
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
|
|
/// PURPOSE:
|
|
/// Updates First Contact (wave of 3 clowns)
|
|
/// PARAMS:
|
|
/// prog - stage progress enum, tells us what state we are in
|
|
PROC UPDATE_STAGE_FIRSTCONTACT(STAGE_PROGRESS &prog)
|
|
SWITCH (prog)
|
|
CASE SP_LOADING
|
|
//
|
|
prog = SP_SETUP
|
|
iMaxActivePeds = 5
|
|
|
|
BREAK
|
|
CASE SP_SETUP
|
|
|
|
CPRINTLN(DEBUG_MISSION, "FIRST CONTACT")
|
|
|
|
bHasInitialOutburst = TRUE
|
|
|
|
CREATE_INITIAL_CLOWNS()
|
|
|
|
prog = SP_RUNNING
|
|
BREAK
|
|
CASE SP_RUNNING
|
|
IF (iAliveClownCount = 0)
|
|
CPRINTLN(DEBUG_MISSION, "GOING TO FIRST CONTACT CLEANUP")
|
|
bLastClownAggressive = FALSE
|
|
prog = SP_CLEANUP
|
|
ENDIF
|
|
BREAK
|
|
CASE SP_CLEANUP
|
|
prog = SP_LOADING
|
|
stageEnum = SE_WAVE1
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Updates First Wave - 1 clown generator
|
|
/// PARAMS:
|
|
/// prog - stage progress enum, tells us what state we are in
|
|
PROC UPDATE_STAGE_WAVE_1(STAGE_PROGRESS &prog)
|
|
INT ind
|
|
|
|
SWITCH (prog)
|
|
CASE SP_LOADING
|
|
CASE SP_SETUP
|
|
CPRINTLN(DEBUG_MISSION, "FIRST WAVE")
|
|
iMaxActivePeds = 5
|
|
IF GET_FREE_CLOWN_GENERATOR_INDEX(ind)
|
|
IF CREATE_CLOWN_GENERATOR(clownGenerator[ind], <<151.200, -962.300, 30.100>>, 213.200, 1, 0, 1250, 2500) //CREATE_CLOWN_GENERATOR(clownGenerator[ind], <<163.5672, -983.8129, 29.0923>>, 114.28)
|
|
prog = SP_RUNNING
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE SP_RUNNING
|
|
IF ARE_ALL_CLOWN_GENERATORS_DEAD()
|
|
// @SBA - have last clown come after player
|
|
MAKE_LAST_CLOWN_AGGRESSIVE(bLastClownAggressive)
|
|
IF (iAliveClownCount = 0)
|
|
bLastClownAggressive = FALSE
|
|
CPRINTLN(DEBUG_MISSION, "GOING TO FIRST WAVE CLEANUP")
|
|
prog = SP_CLEANUP
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE SP_CLEANUP
|
|
prog = SP_LOADING
|
|
stageEnum = SE_WAVE2
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Updates Wave 2 - three clowns
|
|
/// PARAMS:
|
|
/// prog - stage progress enum, tells us what state we are in
|
|
PROC UPDATE_STAGE_WAVE_2(STAGE_PROGRESS &prog)
|
|
INT ind
|
|
|
|
SWITCH (prog)
|
|
CASE SP_LOADING
|
|
CASE SP_SETUP
|
|
CPRINTLN(DEBUG_MISSION, "2 WAVE")
|
|
iMaxActivePeds = 5
|
|
IF GET_FREE_CLOWN_PED_INDEX(ind)
|
|
CREATE_CLOWN_PED(clownPed[ind], <<202.1, -999.3, 30.6>>)
|
|
ENDIF
|
|
|
|
IF GET_FREE_CLOWN_PED_INDEX(ind)
|
|
CREATE_CLOWN_PED(clownPed[ind], <<200.6, -989.3, 30.6>>)
|
|
ENDIF
|
|
|
|
IF GET_FREE_CLOWN_PED_INDEX(ind)
|
|
CREATE_CLOWN_PED(clownPed[ind], <<192.3, -994.7, 30.6>>)
|
|
ENDIF
|
|
|
|
// @SBA - PERFORMANCE CLOWN SPAWN
|
|
CREATE_GENERAL_CLOWN_PERFORMANCE(SZ_ZONE_1)
|
|
|
|
prog = SP_RUNNING
|
|
BREAK
|
|
CASE SP_RUNNING
|
|
IF ARE_ALL_CLOWN_GENERATORS_DEAD()
|
|
// @SBA - have last clown come after player
|
|
MAKE_LAST_CLOWN_AGGRESSIVE(bLastClownAggressive)
|
|
IF (iAliveClownCount = 0)
|
|
bLastClownAggressive = FALSE
|
|
CPRINTLN(DEBUG_MISSION, "GOING TO 2 WAVE CLEANUP")
|
|
prog = SP_CLEANUP
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE SP_CLEANUP
|
|
prog = SP_LOADING
|
|
stageEnum = SE_WAVE3
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Updates third wave
|
|
/// PARAMS:
|
|
/// prog - stage progress enum, tells us what state we are in
|
|
PROC UPDATE_STAGE_WAVE_3(STAGE_PROGRESS &prog)
|
|
SWITCH (prog)
|
|
CASE SP_LOADING
|
|
iStageTimer = 0
|
|
iMaxActivePeds = 5
|
|
prog = SP_SETUP
|
|
BREAK
|
|
CASE SP_SETUP
|
|
IF (iStageTimer < STAGE_BREAK_TIME)
|
|
EXIT
|
|
ENDIF
|
|
CPRINTLN(DEBUG_MISSION, "3 WAVE")
|
|
bGenerateAutoClowns = TRUE
|
|
bUseClownSpawnPoint = TRUE
|
|
vClownSpawnPoint = <<188.085785,-952.725281,33.092264>>
|
|
fClownSpawnRadius = 16
|
|
|
|
iClownPedsSpawned = 0
|
|
|
|
prog = SP_RUNNING
|
|
BREAK
|
|
CASE SP_RUNNING
|
|
IF (iClownPedsSpawned >= 3)
|
|
bGenerateAutoClowns = FALSE
|
|
ENDIF
|
|
|
|
IF ARE_ALL_CLOWN_GENERATORS_DEAD() AND (bGenerateAutoClowns = FALSE)
|
|
// @SBA - have last clown come after player
|
|
MAKE_LAST_CLOWN_AGGRESSIVE(bLastClownAggressive)
|
|
IF (iAliveClownCount = 0)
|
|
bLastClownAggressive = FALSE
|
|
CPRINTLN(DEBUG_MISSION, "GOING TO 3 WAVE CLEANUP")
|
|
prog = SP_CLEANUP
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE SP_CLEANUP
|
|
prog = SP_LOADING
|
|
stageEnum = SE_WAVE4
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Updates fourth wave
|
|
/// PARAMS:
|
|
/// prog - stage progress enum, tells us what state we are in
|
|
PROC UPDATE_STAGE_WAVE_4(STAGE_PROGRESS &prog)
|
|
INT ind
|
|
|
|
SWITCH (prog)
|
|
CASE SP_LOADING
|
|
iStageTimer = 0
|
|
bUseClownSpawnPoint = FALSE
|
|
bGenerateAutoClowns = FALSE
|
|
iMaxActivePeds = MAX_CLOWN_PEDS - 2
|
|
prog = SP_SETUP
|
|
BREAK
|
|
CASE SP_SETUP
|
|
IF (iStageTimer < STAGE_BREAK_TIME)
|
|
EXIT
|
|
ENDIF
|
|
|
|
CPRINTLN(DEBUG_MISSION, "4 WAVE")
|
|
|
|
bGenerateAutoClowns = FALSE
|
|
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_MID_STAGE, "Half Way", FALSE)
|
|
IF GET_FREE_CLOWN_GENERATOR_INDEX(ind)
|
|
CREATE_CLOWN_GENERATOR(clownGenerator[ind], <<173.700, -918.900, 32.200>>, 235.720, -1, 1250, 1150, 1750)
|
|
// @SBA - experimental - having van drive down the stairs
|
|
//CREATE_CLOWN_GENERATOR(clownGenerator[ind], <<196.6811, -929.6295, 32.200>>, 150.6685, -1, 1250, 1150, 1750)
|
|
ENDIF
|
|
|
|
IF GET_FREE_CLOWN_GENERATOR_INDEX(ind)
|
|
CREATE_CLOWN_GENERATOR(clownGenerator[ind], <<214.200, -947.300, 32.200>>, 53.640, -1, 8250, 850, 2000)
|
|
ENDIF
|
|
|
|
// @SBA - timer for fleeing peds
|
|
START_TIMER_NOW(tmrGeneral)
|
|
|
|
prog = SP_RUNNING
|
|
|
|
BREAK
|
|
CASE SP_RUNNING
|
|
|
|
// @SBA - set up some runners after timer goes off and there are enough clowns
|
|
IF iAliveClownCount > 1
|
|
IF TIMER_DO_ONCE_WHEN_READY(tmrGeneral, GET_RANDOM_FLOAT_IN_RANGE(9.000, 12.000))
|
|
CREATE_GENERAL_CLOWN_PERFORMANCE(SZ_ZONE_2, 5, 5, FALSE)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF ARE_ALL_CLOWN_GENERATORS_DEAD()
|
|
// @SBA - have last clown come after player
|
|
MAKE_LAST_CLOWN_AGGRESSIVE(bLastClownAggressive)
|
|
IF (iAliveClownCount = 0)
|
|
bLastClownAggressive = FALSE
|
|
CPRINTLN(DEBUG_MISSION, "GOING TO 4 WAVE CLEANUP")
|
|
prog = SP_CLEANUP
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE SP_CLEANUP
|
|
prog = SP_LOADING
|
|
stageEnum = SE_WAVE5
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Updates fifth wave
|
|
/// PARAMS:
|
|
/// prog - stage progress enum, tells us what state we are in
|
|
PROC UPDATE_STAGE_WAVE_5(STAGE_PROGRESS &prog)
|
|
INT ind
|
|
|
|
SWITCH (prog)
|
|
CASE SP_LOADING
|
|
iStageTimer = 0
|
|
iMaxActivePeds = MAX_CLOWN_PEDS
|
|
prog = SP_SETUP
|
|
BREAK
|
|
CASE SP_SETUP
|
|
IF (iStageTimer < STAGE_BREAK_TIME)
|
|
EXIT
|
|
ENDIF
|
|
|
|
CPRINTLN(DEBUG_MISSION, "5 WAVE")
|
|
bGenerateAutoClowns = TRUE
|
|
bUseClownSpawnPoint = TRUE
|
|
iClownPedsSpawned = 0
|
|
|
|
vClownSpawnPoint = <<210.035477,-902.093811,29.692423>>
|
|
fClownSpawnRadius = 20
|
|
|
|
IF GET_FREE_CLOWN_GENERATOR_INDEX(ind)
|
|
CREATE_CLOWN_GENERATOR(clownGenerator[ind], <<247.800, -880.300, 33.000>>, 129.460, 1, 6000, 600, 2000)
|
|
ENDIF
|
|
|
|
IF GET_FREE_CLOWN_GENERATOR_INDEX(ind)
|
|
CREATE_CLOWN_GENERATOR(clownGenerator[ind], <<218.400, -868.500, 33.000>>, 228.600, -1, 14000, 1100, 2000)
|
|
ENDIF
|
|
|
|
// @SBA - timer for fleeing peds
|
|
START_TIMER_NOW(tmrGeneral)
|
|
fGeneralTime = GET_RANDOM_FLOAT_IN_RANGE(5.000, 8.000)
|
|
|
|
prog = SP_RUNNING
|
|
BREAK
|
|
CASE SP_RUNNING
|
|
|
|
// @SBA - set up some runners after timer goes off, if not on last clown
|
|
IF NOT bLastClownAggressive
|
|
IF TIMER_DO_ONCE_WHEN_READY(tmrGeneral, fGeneralTime)
|
|
CREATE_GENERAL_CLOWN_PERFORMANCE(SZ_ZONE_3, 5, 5, FALSE)
|
|
fGeneralTime = GET_RANDOM_FLOAT_IN_RANGE(20.000, 30.000)
|
|
START_TIMER_NOW(tmrGeneral)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF (iClownPedsSpawned >= 5)
|
|
bGenerateAutoClowns = FALSE
|
|
ENDIF
|
|
|
|
IF ARE_ALL_CLOWN_GENERATORS_DEAD() AND (bGenerateAutoClowns = FALSE)
|
|
// @SBA - have last clown come after player
|
|
MAKE_LAST_CLOWN_AGGRESSIVE(bLastClownAggressive)
|
|
IF (iAliveClownCount = 0)
|
|
bLastClownAggressive = FALSE
|
|
CPRINTLN(DEBUG_MISSION, "GOING TO 5 WAVE CLEANUP")
|
|
prog = SP_CLEANUP
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE SP_CLEANUP
|
|
prog = SP_LOADING
|
|
stageEnum = SE_WAVE6
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
PROC UPDATE_STAGE_WAVE_6(STAGE_PROGRESS &prog)
|
|
SWITCH (prog)
|
|
CASE SP_LOADING
|
|
iStageTimer = 0
|
|
iMaxActivePeds = MAX_CLOWN_PEDS
|
|
RESET_ALL_CLOWN_DEATH_VECTORS()
|
|
prog = SP_SETUP
|
|
BREAK
|
|
CASE SP_SETUP
|
|
IF (iStageTimer < STAGE_BREAK_TIME)
|
|
EXIT
|
|
ENDIF
|
|
|
|
CPRINTLN(DEBUG_MISSION, "6 WAVE")
|
|
INT ind
|
|
iDuplicatesCount = 0
|
|
iClownPedsSpawned = 0
|
|
fClownSpawnRadius = 2.0
|
|
iNextSpawnTimer = 0
|
|
bUseClownSpawnPoint = TRUE
|
|
bGenerateAutoClowns = FALSE
|
|
// lower value for this stage
|
|
fNoSpawnPlayerDist = 2.0
|
|
CANCEL_TIMER(tmrGeneral)
|
|
|
|
// create 1st clown
|
|
IF GET_FREE_CLOWN_PED_INDEX(ind)
|
|
IF CREATE_CLOWN_PED(clownPed[ind], <<195.1091, -933.9568, 29.6918>>, 325.0, TRUE)
|
|
CPRINTLN(DEBUG_MISSION, "Created 1st Clown of 6th WAVE")
|
|
ENDIF
|
|
ENDIF
|
|
|
|
prog = SP_RUNNING
|
|
BREAK
|
|
CASE SP_RUNNING
|
|
|
|
IF (iClownPedsSpawned >= 15)
|
|
bGenerateAutoClowns = FALSE
|
|
ELIF NOT bGenerateAutoClowns
|
|
CHECK_FOR_SPAWNING_DUPLICATES()
|
|
ENDIF
|
|
|
|
HANDLE_PLAY_TREVOR_CLOWN_DUPLICATION_RANT()
|
|
|
|
IF ARE_ALL_CLOWN_GENERATORS_DEAD() AND (bGenerateAutoClowns = FALSE) AND (iClownPedsSpawned >= 10) // @SBA - just need a largish number for this last condition
|
|
// @SBA - have last clown come after player
|
|
MAKE_LAST_CLOWN_AGGRESSIVE(bLastClownAggressive)
|
|
IF (iAliveClownCount = 0)
|
|
bLastClownAggressive = FALSE
|
|
CPRINTLN(DEBUG_MISSION, "GOING TO 6 WAVE CLEANUP")
|
|
prog = SP_CLEANUP
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE SP_CLEANUP
|
|
prog = SP_LOADING
|
|
stageEnum = SE_PASSOUT
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
/// PURPOSE:
|
|
/// Updates The Pass Out Sequence
|
|
/// PARAMS:
|
|
/// prog - stage progress enum, tells us what state we are in
|
|
PROC UPDATE_STAGE_PASSOUT(STAGE_PROGRESS &prog)
|
|
SWITCH (prog)
|
|
CASE SP_LOADING
|
|
CASE SP_SETUP
|
|
SAFE_FADE_SCREEN_IN_FROM_BLACK(500, FALSE)
|
|
CPRINTLN(DEBUG_MISSION, "ENTERING UPDATE STAGE PASSOUT")
|
|
CLEAR_PRINTS()
|
|
CLEAR_HELP()
|
|
prog = SP_RUNNING
|
|
BREAK
|
|
CASE SP_RUNNING
|
|
IF PASS_OUT_SEQUENCE(TRUE)
|
|
prog = SP_CLEANUP
|
|
ENDIF
|
|
BREAK
|
|
CASE SP_CLEANUP
|
|
prog = SP_LOADING
|
|
stageEnum = SE_OUTRO
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
//request the necessary dictionaries
|
|
FUNC BOOL REQUEST_DRUNK_ANIMS()
|
|
STRING m_movementClip = Get_Drunk_Level_Moveclip(DL_verydrunk)
|
|
REQUEST_CLIP_SET(m_movementClip)
|
|
IF NOT HAS_CLIP_SET_LOADED(m_movementClip)
|
|
RETURN FALSE
|
|
ELSE
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDFUNC
|
|
|
|
|
|
/// PURPOSE:
|
|
/// Updates Outro
|
|
/// PARAMS:
|
|
/// prog - stage progress enum, tells us what state we are in
|
|
PROC UPDATE_STAGE_OUTRO(STAGE_PROGRESS &prog)
|
|
|
|
IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY()
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Trevor", PLAYER_PED_ID(), GET_ENTITY_MODEL(PLAYER_PED_ID()))
|
|
ENDIF
|
|
SET_CUTSCENE_PED_PROP_VARIATION(sSceneHandleBarry, ANCHOR_EYES, 0)
|
|
CPRINTLN(DEBUG_MISSION, "PED CUTSCENE VARIATIONS SET")
|
|
ENDIF
|
|
|
|
SWITCH (prog)
|
|
CASE SP_LOADING
|
|
CPRINTLN(DEBUG_MISSION, "REQUESTING CUTSCENE - bar_4_rcm")
|
|
|
|
RC_REQUEST_CUTSCENE("bar_4_rcm")
|
|
WAIT_FOR_WORLD_TO_LOAD(vMissionStart)
|
|
IF NOT HAS_SCRIPT_LOADED("postRC_Barry1and2")
|
|
REQUEST_SCRIPT("postRC_Barry1and2")
|
|
ENDIF
|
|
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_OUTRO, "Outro", TRUE)
|
|
prog = SP_SETUP
|
|
BREAK
|
|
CASE SP_SETUP
|
|
|
|
IF NOT REQUEST_DRUNK_ANIMS()
|
|
CPRINTLN(DEBUG_MISSION, "Waiting on drunk anims...")
|
|
EXIT
|
|
ENDIF
|
|
|
|
CLEAR_AMBIENT_ZONE_STATE(sAmbientZone, TRUE)
|
|
|
|
IF RC_IS_CUTSCENE_OK_TO_START()
|
|
AND HAS_SCRIPT_LOADED("postRC_Barry1and2")
|
|
|
|
IF IS_ENTITY_OK(PLAYER_PED_ID())
|
|
RESET_PED_VISIBLE_DAMAGE(PLAYER_PED_ID())
|
|
CLEAR_PED_BLOOD_DAMAGE(PLAYER_PED_ID())
|
|
ENDIF
|
|
|
|
MISSION_CLEANUP()
|
|
|
|
bHasPlayerCameraExitState = FALSE
|
|
CLEAR_AREA_OF_VEHICLES(vMissionStart, 250.0)
|
|
CLEAR_AREA_OF_PEDS(vMissionStart, 50.0)
|
|
CLEAR_AREA_OF_OBJECTS(vMissionStart, 30.0)
|
|
REMOVE_DECALS_IN_RANGE(vMissionStart, 500.0)
|
|
|
|
REGISTER_ENTITY_FOR_CUTSCENE(NULL, sSceneHandleBarry, CU_CREATE_AND_ANIMATE_NEW_SCRIPT_ENTITY, GET_NPC_PED_MODEL(CHAR_BARRY))
|
|
REGISTER_ENTITY_FOR_CUTSCENE(NULL, sSceneHandleTable, CU_CREATE_AND_ANIMATE_NEW_SCRIPT_ENTITY, PROP_PROTEST_TABLE_01)
|
|
REGISTER_ENTITY_FOR_CUTSCENE(NULL, sSceneHandleChair, CU_CREATE_AND_ANIMATE_NEW_SCRIPT_ENTITY, PROP_CHAIR_08) //PROP_TABLE_03_CHR
|
|
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
REGISTER_ENTITY_FOR_CUTSCENE(PLAYER_PED_ID(), "Trevor", CU_ANIMATE_EXISTING_SCRIPT_ENTITY, PLAYER_TWO)
|
|
CPRINTLN(DEBUG_MISSION, "REGISTERED TREVOR")
|
|
ENDIF
|
|
|
|
REPLAY_START_EVENT(REPLAY_IMPORTANCE_LOW)
|
|
|
|
START_CUTSCENE()
|
|
WAIT(0)
|
|
|
|
//CLEANUP_SCREEN_FX()
|
|
//ANIMPOSTFX_PLAY(FX_DrugsIn, 0, FALSE)
|
|
|
|
SAFE_FADE_SCREEN_IN_FROM_BLACK(1000, FALSE)
|
|
//RESOLVE_MISSION_VEHICLES_FOR_CUTSCENE()
|
|
RC_START_CUTSCENE_MODE(<<0, 0, 0>>, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE)
|
|
|
|
SET_SRL_POST_CUTSCENE_CAMERA(<<183.4340, -949.1876, 30.8535>>, B2_CONVERT_ROT_TO_DIR_VECTOR(<<-3.0000, 0.0000, 72.9999>>))
|
|
|
|
//SET_CUTSCENE_CAN_BE_SKIPPED(FALSE)
|
|
prog = SP_RUNNING
|
|
ENDIF
|
|
BREAK
|
|
CASE SP_RUNNING
|
|
INT iCutTime
|
|
|
|
// Don't look back
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE)
|
|
ENDIF
|
|
|
|
IF NOT IS_CUTSCENE_PLAYING()
|
|
RC_END_CUTSCENE_MODE()
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE)
|
|
ENDIF
|
|
REPLAY_STOP_EVENT()
|
|
prog = SP_CLEANUP
|
|
ELSE
|
|
iCutTime = GET_CUTSCENE_TIME()
|
|
CDEBUG3LN(DEBUG_MISSION, "Cutscene Time = ", iCutTime)
|
|
|
|
IF iCutTime > 15000
|
|
IF MAKE_PED_DRUNK(PLAYER_PED_ID(), 10000)
|
|
CPRINTLN(DEBUG_MISSION, "TREVOR set to be drunk")
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF NOT bHasPlayerCameraExitState
|
|
SET_GAMEPLAY_CAM_RELATIVE_PITCH()
|
|
SET_GAMEPLAY_CAM_RELATIVE_HEADING()
|
|
ENDIF
|
|
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Trevor")
|
|
CPRINTLN(DEBUG_MISSION, "SET EXIT STATE FOR TREVOR")
|
|
SET_ENTITY_COORDS_GROUNDED(PLAYER_PED_ID(), <<180.1684, -948.6075, 29.0919>>)
|
|
SET_ENTITY_HEADING(PLAYER_PED_ID(), 73.0)
|
|
FORCE_PED_MOTION_STATE(PLAYER_PED_ID(), MS_ON_FOOT_RUN, FALSE, FAUS_CUTSCENE_EXIT)
|
|
SIMULATE_PLAYER_INPUT_GAIT(player_id(), PEDMOVE_RUN, 750)
|
|
bHasPlayerCameraExitState = TRUE
|
|
ENDIF
|
|
|
|
IF NOT IS_ENTITY_ALIVE(sRCLauncherDataLocal.objID[OBJ_SIGN])
|
|
CREATE_STANDING_SIGN(sRCLauncherDataLocal.objID[OBJ_SIGN], mnProtestSign)
|
|
ENDIF
|
|
|
|
// register things as we exit
|
|
IF NOT IS_ENTITY_ALIVE(sRCLauncherDataLocal.pedID[0])
|
|
IF DOES_ENTITY_EXIST(GET_ENTITY_INDEX_OF_REGISTERED_ENTITY(sSceneHandleBarry))
|
|
sRCLauncherDataLocal.pedID[0] = GET_PED_INDEX_FROM_ENTITY_INDEX(GET_ENTITY_INDEX_OF_REGISTERED_ENTITY(sSceneHandleBarry))
|
|
SET_PED_PROP_INDEX(sRCLauncherDataLocal.pedID[0], ANCHOR_EYES, 0) //Glasses prop.
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF NOT IS_ENTITY_ALIVE(sRCLauncherDataLocal.objID[OBJ_TABLE])
|
|
IF DOES_ENTITY_EXIST(GET_ENTITY_INDEX_OF_REGISTERED_ENTITY(sSceneHandleTable))
|
|
sRCLauncherDataLocal.objID[OBJ_TABLE] = GET_OBJECT_INDEX_FROM_ENTITY_INDEX(GET_ENTITY_INDEX_OF_REGISTERED_ENTITY(sSceneHandleTable))
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF NOT IS_ENTITY_ALIVE(sRCLauncherDataLocal.objID[OBJ_CHAIR])
|
|
IF DOES_ENTITY_EXIST(GET_ENTITY_INDEX_OF_REGISTERED_ENTITY(sSceneHandleChair))
|
|
sRCLauncherDataLocal.objID[OBJ_CHAIR] = GET_OBJECT_INDEX_FROM_ENTITY_INDEX(GET_ENTITY_INDEX_OF_REGISTERED_ENTITY(sSceneHandleChair))
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF CAN_SET_ENTER_STATE_FOR_REGISTERED_ENTITY(sSceneHandleTable)
|
|
IF IS_ENTITY_ALIVE(sRCLauncherDataLocal.objID[OBJ_TABLE]) AND IS_ENTITY_ALIVE(sRCLauncherDataLocal.objID[OBJ_PAPERS])
|
|
ATTACH_ENTITY_TO_ENTITY(sRCLauncherDataLocal.objID[OBJ_PAPERS], sRCLauncherDataLocal.objID[OBJ_TABLE], 0, <<0, -0.25, 0>>, <<0, 0, 0>>)
|
|
CPRINTLN(DEBUG_MISSION, "PAPERS REATTACHED TO TABLE")
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDIF
|
|
BREAK
|
|
CASE SP_CSKIPPED
|
|
SET_CUTSCENE_FADE_VALUES(false, false, FALSE, false)
|
|
SAFE_FADE_SCREEN_OUT_TO_BLACK(250, FALSE)
|
|
IF IS_CUTSCENE_PLAYING()
|
|
WAIT_FOR_CUTSCENE_TO_STOP()
|
|
ENDIF
|
|
RC_END_CUTSCENE_MODE()
|
|
SET_ENTITY_COORDS_GROUNDED(PLAYER_PED_ID(), vMissionStart)
|
|
SET_ENTITY_HEADING(PLAYER_PED_ID(), fMissionStart)
|
|
SET_GAMEPLAY_CAM_RELATIVE_PITCH()
|
|
SET_GAMEPLAY_CAM_RELATIVE_HEADING()
|
|
WAIT(250)
|
|
SAFE_FADE_SCREEN_IN_FROM_BLACK(250, FALSE)
|
|
SCRIPT_PASSED()
|
|
BREAK
|
|
CASE SP_CLEANUP
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
|
|
ENDIF
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_LOOK_BEHIND)
|
|
SCRIPT_PASSED()
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Updates failed stage
|
|
/// PARAMS:
|
|
/// prog - stage progress enum, tells us what state we are in
|
|
PROC UPDATE_STAGE_FAILED(STAGE_PROGRESS &prog)
|
|
SWITCH (prog)
|
|
CASE SP_LOADING
|
|
CASE SP_SETUP
|
|
CPRINTLN(DEBUG_MISSION, "Mission Failed")
|
|
CLEAR_PRINTS()
|
|
CLEAR_HELP()
|
|
|
|
// @SBA - adding spectators
|
|
CLEANUP_ALL_SPECTATOR_PEDS()
|
|
|
|
// Remove all blips here
|
|
|
|
// Make all clowns flee
|
|
FLEE_ALL_CLOWN_PEDS()
|
|
CLEANUP_ALL_CLOWN_PEDS(TRUE)
|
|
|
|
// stop mission music
|
|
CPRINTLN(DEBUG_MISSION, "FAIL STRING = ", sFailString)
|
|
PREPARE_MUSIC_EVENT("RC18B_END")
|
|
|
|
// B*938802 - No more delay fades
|
|
IF IS_STRING_NULL_OR_EMPTY(sFailString)
|
|
Random_Character_Failed()
|
|
ELSE
|
|
Random_Character_Failed_With_Reason(sFailString, TRUE) ///, bDelayFade)
|
|
ENDIF
|
|
prog = SP_RUNNING
|
|
BREAK
|
|
|
|
CASE SP_RUNNING
|
|
|
|
IF GET_MISSION_FLOW_SAFE_TO_CLEANUP()
|
|
// @SBA - this is preventing the music from ending if you debug fail - is the death check needed?
|
|
//IF IS_ENTITY_DEAD(PLAYER_PED_ID())
|
|
TRIGGER_MUSIC_EVENT("RC18B_END")
|
|
//ENDIF
|
|
// Set warp locations
|
|
MISSION_FLOW_SET_FAIL_WARP_LOCATION(<<165.4821, -990.5140, 29.0923>>, 166.7554)
|
|
SET_REPLAY_DECLINED_VEHICLE_WARP_LOCATION(vPlayerCarRespot, fPlayerCarRespot)
|
|
|
|
// @SBA - adding spectators
|
|
CLEANUP_ALL_SPECTATOR_PEDS()
|
|
|
|
// delete everything here!
|
|
//DeleteEverything()?
|
|
CLEANUP_ALL_CLOWN_PEDS(TRUE)
|
|
|
|
// script_cleanup should terminate the thread
|
|
RC_END_CUTSCENE_MODE(TRUE, FALSE)
|
|
Script_Cleanup()
|
|
|
|
ELSE
|
|
// not finished fading out
|
|
// you may want to handle dialogue etc here.
|
|
IF ARE_STRINGS_EQUAL(sFailString, "B2_FAIL2") // Fled the battle
|
|
IF PASS_OUT_SEQUENCE() AND IS_REPEAT_PLAY_ACTIVE()
|
|
CPRINTLN(DEBUG_MISSION, "Repeat Play - Emergency Exit")
|
|
Script_Cleanup()
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
//----------------------
|
|
// DEBUG FUNCTIONS
|
|
//----------------------
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
|
|
/// PURPOSE:
|
|
/// Operates S, F, J and Z keys
|
|
PROC UPDATE_DEBUG_KEYS()
|
|
|
|
UPDATE_MISSION_DEBUG_TIMER()
|
|
|
|
IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_S)
|
|
IF IS_CUTSCENE_PLAYING()
|
|
WAIT_FOR_CUTSCENE_TO_STOP(TRUE, FALSE)
|
|
ENDIF
|
|
WHILE NOT HAS_SCRIPT_LOADED("postRC_Barry1and2")
|
|
REQUEST_SCRIPT("postRC_Barry1and2")
|
|
WAIT(0)
|
|
ENDWHILE
|
|
IF IS_GAMEPLAY_HINT_ACTIVE()
|
|
STOP_GAMEPLAY_HINT()
|
|
ENDIF
|
|
|
|
CLEANUP_SCREEN_FX()
|
|
|
|
TRIGGER_MUSIC_EVENT("RC18B_END")
|
|
// @SBA - adding spectators
|
|
DELETE_ALL_SPECTATOR_PEDS()
|
|
CLEANUP_ALL_SPECTATOR_PEDS()
|
|
DELETE_ALL_CLOWN_PEDS()
|
|
DELETE_ALL_CLOWN_GENERATORS()
|
|
FLEE_ALL_CLOWN_PEDS()
|
|
CLEANUP_ALL_CLOWN_PEDS()
|
|
SCRIPT_PASSED()
|
|
ENDIF
|
|
|
|
IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_F)
|
|
IF IS_CUTSCENE_PLAYING()
|
|
WAIT_FOR_CUTSCENE_TO_STOP(TRUE, FALSE)
|
|
ENDIF
|
|
SET_MISSION_FAILED("")
|
|
ENDIF
|
|
|
|
IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_P)
|
|
IF IS_CUTSCENE_PLAYING()
|
|
WAIT_FOR_CUTSCENE_TO_STOP(TRUE, FALSE)
|
|
ENDIF
|
|
|
|
IF (stageEnum = SE_INTRO) OR (stageEnum = SE_PERFORMANCE) OR (stageEnum = SE_FIRSTCONTACT)
|
|
DO_Z_SKIP(Z_SKIP_TO_INTRO)
|
|
ELSE
|
|
DO_Z_SKIP(ENUM_TO_INT(stageEnum) - 1)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_J)
|
|
IF IS_CUTSCENE_PLAYING()
|
|
WAIT_FOR_CUTSCENE_TO_STOP(TRUE, FALSE)
|
|
ENDIF
|
|
|
|
IF (stageEnum = SE_INTRO)
|
|
// @SBA - Performance is now first
|
|
//DO_Z_SKIP(Z_SKIP_TO_FIRST_CONTACT)
|
|
DO_Z_SKIP(Z_SKIP_TO_PERFORMANCE)
|
|
ELIF (stageEnum = SE_OUTRO)
|
|
CLEANUP_SCREEN_FX()
|
|
TRIGGER_MUSIC_EVENT("RC18B_END")
|
|
SCRIPT_PASSED()
|
|
ELSE
|
|
DO_Z_SKIP(ENUM_TO_INT(stageEnum) + 1)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF LAUNCH_MISSION_STAGE_MENU(sSkipMenu, iDbgStageJump)
|
|
DO_Z_SKIP(iDbgStageJump)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Updates Debug Widgets and draw debug stuff
|
|
PROC UPDATE_DEBUG_WIDGETS()
|
|
INT ind
|
|
VECTOR v
|
|
|
|
IF (bDebugTTYSpew)
|
|
DRAW_DEBUG_CIRCLE(vBattleCenter, fBattleRadius)
|
|
DRAW_DEBUG_CIRCLE(vBattleCenter, fClownSpawnRadius)
|
|
|
|
DEBUG_DRAW_ANGLED_AREA_EX(battleAreaInner, 0, 255, 0)
|
|
DEBUG_DRAW_ANGLED_AREA_EX(battleArea, 255, 255, 255)
|
|
DEBUG_DRAW_ANGLED_AREA_EX(battleAreaOuter, 255, 0, 0)
|
|
|
|
DRAW_DEBUG_CIRCLE(vTestGenPoint, 1.0)
|
|
DRAW_DEBUG_SPHERE(vTestGenPoint, 0.125)
|
|
v = GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(vTestGenPoint, fTestHeading, <<0, 5, 0>>)
|
|
DRAW_DEBUG_LINE(vTestGenPoint, v)
|
|
ENDIF
|
|
|
|
IF (bGenerateTestGenerator)
|
|
DELETE_ALL_CLOWN_PEDS()
|
|
DELETE_ALL_CLOWN_GENERATORS()
|
|
IF CREATE_CLOWN_GENERATOR(clownGenerator[0], vTestGenPoint, fTestHeading, iTestSwerve, 0, iTestFwdTime, iTestBrakeTime)
|
|
bGenerateTestGenerator = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF (bGenerateTestClown)
|
|
IF (iAliveClownCount >= iMaxActivePeds)
|
|
EXIT
|
|
ENDIF
|
|
|
|
IF (GET_GAME_TIMER() < iNextSpawnTimer)
|
|
EXIT
|
|
ENDIF
|
|
|
|
IF NOT GET_FREE_CLOWN_PED_INDEX(ind)
|
|
EXIT
|
|
ENDIF
|
|
|
|
v = GET_RANDOM_POINT_IN_DISC(vBattleCenter, fClownSpawnRadius, 6.0)
|
|
IF NOT CHECK_SPAWN_POINT_IS_OK(v)
|
|
EXIT
|
|
ENDIF
|
|
|
|
IF CREATE_CLOWN_PED(clownPed[ind], v)
|
|
iNextSpawnTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(iMinPedSpawnTime, iMaxPedSpawnTime)
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
#ENDIF
|
|
|
|
/// PURPOSE:
|
|
/// Check to see if player has left battle area if so handle failure
|
|
PROC UPDATE_PLAYER_AREA_CHECK()
|
|
|
|
/*
|
|
IF (bIsPlayerInBattleArea)
|
|
IF NOT IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), battleAreaOuter.vPosition[0], battleAreaOuter.vPosition[1], battleAreaOuter.fWidth)
|
|
PRINT_NOW("B2_WARN", DEFAULT_GOD_TEXT_TIME, 1) // Return to the ~y~battleground.~s~
|
|
SAFE_REMOVE_BLIP(locationBlip)
|
|
locationBlip = CREATE_COORD_BLIP(vBattleCenter)
|
|
iMissionAbandonedTimer = GET_GAME_TIMER() + FAIL_WARNING_TIME
|
|
bIsPlayerInBattleArea = FALSE
|
|
ENDIF
|
|
ELSE
|
|
IF NOT IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), battleAreaInner.vPosition[0], battleAreaInner.vPosition[1], battleAreaInner.fWidth)
|
|
IF (GET_GAME_TIMER() > iMissionAbandonedTimer)
|
|
SET_MISSION_FAILED("B2_FAIL2") // You fled the battle.
|
|
ENDIF
|
|
ELSE
|
|
PRINT_NOW("B2_PRIME", DEFAULT_GOD_TEXT_TIME, 1) // Kill the ~r~clowns.~s~
|
|
SAFE_REMOVE_BLIP(locationBlip)
|
|
bIsPlayerInBattleArea = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
*/
|
|
|
|
IF (bIsPlayerInBattleArea)
|
|
IF NOT IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), battleArea.vPosition[0], battleArea.vPosition[1], battleArea.fWidth)
|
|
PRINT_NOW("B2_WARN", DEFAULT_GOD_TEXT_TIME, 1) // Return to the ~y~battleground.~s~
|
|
SAFE_REMOVE_BLIP(locationBlip)
|
|
locationBlip = CREATE_COORD_BLIP(vBattleCenter)
|
|
iMissionAbandonedTimer = GET_GAME_TIMER() + FAIL_WARNING_TIME
|
|
bIsPlayerInBattleArea = FALSE
|
|
ENDIF
|
|
ELSE
|
|
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), battleAreaInner.vPosition[0], battleAreaInner.vPosition[1], battleAreaInner.fWidth)
|
|
PRINT_NOW("B2_PRIME", DEFAULT_GOD_TEXT_TIME, 1) // Kill the ~r~clowns.~s~
|
|
SAFE_REMOVE_BLIP(locationBlip)
|
|
bIsPlayerInBattleArea = TRUE
|
|
ELIF NOT IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), battleAreaOuter.vPosition[0], battleAreaOuter.vPosition[1], battleAreaOuter.fWidth)
|
|
IF (GET_GAME_TIMER() > iMissionAbandonedTimer)
|
|
ENDIF
|
|
SET_MISSION_FAILED("B2_FAIL2") // You fled the battle.
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
//----------------------
|
|
// MAIN SCRIPT
|
|
//----------------------
|
|
SCRIPT(g_structRCScriptArgs sRCLauncherDataIn)
|
|
|
|
VECTOR amin, amax
|
|
sRCLauncherDataLocal = sRCLauncherDataIn
|
|
RC_TakeEntityOwnership(sRCLauncherDataLocal)
|
|
|
|
SET_MISSION_FLAG(TRUE)
|
|
sFailString = ""
|
|
|
|
// clean up any live projectiles near Barry
|
|
CLEAR_AREA_OF_PROJECTILES((<<190.2424, -956.3790, 28.63>>), 6.0)
|
|
|
|
// Setup callback when player is killed, arrested or goes to multiplayer
|
|
IF (HAS_FORCE_CLEANUP_OCCURRED(DEFAULT_FORCE_CLEANUP_FLAGS|FORCE_CLEANUP_FLAG_DEBUG_MENU))
|
|
PRINT_LAUNCHER_DEBUG("Force cleanup [TERMINATING]")
|
|
TRIGGER_MUSIC_EVENT("RC18B_END")
|
|
Random_Character_Failed()
|
|
SCRIPT_CLEANUP()
|
|
ENDIF
|
|
|
|
// setup areas
|
|
MISSION_SETUP()
|
|
|
|
SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(TRUE)
|
|
CALCULATE_MIN_MAX_FROM_POSITION_AND_RADIUS(vBattleCenter, 200.0, amin, amax)
|
|
DUMMY_REFERENCE_INT(iClownGeneratorsDestroyed)
|
|
DUMMY_REFERENCE_INT(iAliveClownGeneratorCount)
|
|
DUMMY_REFERENCE_INT(iClownPedsKilled)
|
|
|
|
IF IS_REPEAT_PLAY_ACTIVE()
|
|
if not is_screen_faded_in()
|
|
if not is_screen_fading_in()
|
|
do_screen_fade_in(default_fade_time)
|
|
endif
|
|
endif
|
|
ENDIF
|
|
|
|
// main loop
|
|
WHILE (TRUE)
|
|
REPLAY_CHECK_FOR_EVENT_THIS_FRAME("SF_GRT")
|
|
UPDATE_MISSION_NAME_DISPLAYING(sRCLauncherDataLocal.sIntroCutscene)
|
|
|
|
// globals
|
|
iAlphaCounter = 0 // this regulates alpha
|
|
iSpecAlphaCounter = 0
|
|
iStageTimer += GET_FRAME_TIME()
|
|
|
|
// stop nonsense
|
|
NO_AMBIENT_MALARKY_THIS_FRAME()
|
|
SET_PED_NON_CREATION_AREA(amin, amax)
|
|
SET_PLAYER_MAY_NOT_ENTER_ANY_VEHICLE(GET_PLAYER_INDEX())
|
|
|
|
// update spectators
|
|
DISABLE_CELLPHONE_THIS_FRAME_ONLY()
|
|
UPDATE_SPECTATOR_PEDS()
|
|
|
|
// update enemies
|
|
UPDATE_CLOWN_PEDS()
|
|
UPDATE_CLOWN_GENERATORS()
|
|
UPDATE_CLOWN_SPAWNER()
|
|
|
|
// main switch
|
|
SWITCH (stageEnum)
|
|
CASE SE_LEAD_IN
|
|
UPDATE_STAGE_LEADIN(stageProgress)
|
|
BREAK
|
|
CASE SE_INTRO
|
|
UPDATE_STAGE_INTRO(stageProgress)
|
|
BREAK
|
|
CASE SE_TEST
|
|
UPDATE_STAGE_TEST(stageProgress)
|
|
BREAK
|
|
CASE SE_PERFORMANCE
|
|
UPDATE_STAGE_PERFORMANCE(stageProgress)
|
|
BREAK
|
|
CASE SE_FIRSTCONTACT
|
|
UPDATE_STAGE_FIRSTCONTACT(stageProgress)
|
|
BREAK
|
|
CASE SE_WAVE1
|
|
UPDATE_STAGE_WAVE_1(stageProgress)
|
|
BREAK
|
|
CASE SE_WAVE2
|
|
UPDATE_STAGE_WAVE_2(stageProgress)
|
|
BREAK
|
|
CASE SE_WAVE3
|
|
UPDATE_STAGE_WAVE_3(stageProgress)
|
|
BREAK
|
|
CASE SE_WAVE4
|
|
UPDATE_STAGE_WAVE_4(stageProgress)
|
|
BREAK
|
|
CASE SE_WAVE5
|
|
UPDATE_STAGE_WAVE_5(stageProgress)
|
|
BREAK
|
|
CASE SE_WAVE6
|
|
UPDATE_STAGE_WAVE_6(stageProgress)
|
|
BREAK
|
|
CASE SE_PASSOUT
|
|
UPDATE_STAGE_PASSOUT(stageProgress)
|
|
BREAK
|
|
CASE SE_OUTRO
|
|
UPDATE_STAGE_OUTRO(stageProgress)
|
|
BREAK
|
|
CASE SE_FAILED
|
|
UPDATE_STAGE_FAILED(stageProgress)
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
// handle things which are updated in combat
|
|
IF IS_MISSION_IN_COMBAT_STAGE()
|
|
// drugs effect and other thing
|
|
IF IS_AUDIO_SCENE_ACTIVE(sndAlienAmbientScene)
|
|
SET_AUDIO_SCENE_VARIABLE(sndAlienAmbientScene, "DrugsEffect", (SIN(((TO_FLOAT(GET_GAME_TIMER())/1000)*45)%360))*0.25+0.25)
|
|
ENDIF
|
|
|
|
UPDATE_PLAYER_AREA_CHECK()
|
|
PLAY_TREVOR_FREAK_DIALOG_LINES()
|
|
ENDIF
|
|
|
|
WAIT(0)
|
|
|
|
// debug
|
|
#IF IS_DEBUG_BUILD
|
|
IF (stageEnum <> SE_FAILED)
|
|
UPDATE_DEBUG_KEYS()
|
|
ENDIF
|
|
|
|
IF (bUpdateWidgets)
|
|
UPDATE_DEBUG_WIDGETS()
|
|
ENDIF
|
|
#ENDIF
|
|
ENDWHILE
|
|
|
|
// Script should never reach here. Always terminate with cleanup function.
|
|
ENDSCRIPT
|
|
|
|
|