// ***************************************************************************************** // ***************************************************************************************** // // 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(), <>, 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, (<>)) 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