Files
gtav-src/script/dev_ng/singleplayer/scripts/RandomChar/Hunting/Hunting1.sc
T
2025-09-29 00:52:08 +02:00

6134 lines
188 KiB
Python
Executable File

//Compile out Title Update changes to header functions.
//Must be before includes.
//CONST_INT USE_TU_CHANGES 0 // Removed by Kenneth R.
USING "rage_builtins.sch"
USING "globals.sch"
USING "cellphone_public.sch"
USING "commands_camera.sch"
USING "commands_clock.sch"
USING "commands_entity.sch"
USING "commands_misc.sch"
USING "commands_object.sch"
USING "commands_pad.sch"
USING "commands_path.sch"
USING "commands_player.sch"
USING "commands_script.sch"
USING "commands_streaming.sch"
USING "commands_task.sch"
USING "commands_vehicle.sch"
USING "CompletionPercentage_public.sch"
USING "cutscene_public.sch"
USING "dialogue_public.sch"
USING "event_public.sch"
USING "script_blips.sch"
USING "script_player.sch"
USING "script_MISC.sch"
USING "script_debug.sch"
USING "RC_Helper_Functions.sch"
USING "initial_scenes_Hunting.sch"
USING "rgeneral_include.sch"
USING "commands_recording.sch"
#IF IS_DEBUG_BUILD
USING "select_mission_stage.sch"
USING "shared_debug.sch"
#ENDIF
// *****************************************************************************************
// MISSION NAME : Hunting1
// AUTHOR : Rob Taylor
// DESCRIPTION : Hunting tutorial near trailer park
// *****************************************************************************************
g_structRCScriptArgs sRCLauncherDataLocal
structPedsForConversation mHunterConv
// ENUMS
ENUM MISSION_STATE
MS_INIT_MISSION = 0, // Init mission
MS_DO_LEAD_IN,
MS_RUN_INTRO, // Mocap cutscene
MS_JUMP_SET_UP_AFTER_INTRO, // --* JUMP STATE *--
MS_GET_TO_DISH_SPOT, // Walking with the hunter to the the dishes
MS_JUMP_SET_UP_SHOOT_DISHES, // --* JUMP STATE* --
MS_SHOOT_DISHES, // Shooting the dishes
MS_GET_BACK_TO_DISH_SPOT, // Return to the dish spot
MS_DO_AFTER_DISH_CONVO, // Hunter says well done, go to motel
MS_GET_TO_TYRE_AREA, // Driving to the tyre area
MS_BACK_TO_HUNTER_FOR_TYRES, // Get back to the hunter if you lose him
MS_FOLLOW_TO_TYRE_BALCONY, // Walking up to the balcony
MS_JUMP_SET_UP_SHOOT_TYRES, // --* JUMP STATE* --
MS_SHOOT_TYRES, // Shooting the tyres
MS_FOLLOW_TO_COLLAPSED_ROOF, // Walk up to the balcony before the collapsed roof
MS_GET_TO_COYOTE_SPOT, // Follow the hunter to the roof where the coyote are
MS_JUMP_SET_UP_SHOOT_COYOTE, // --* JUMP STATE *--
MS_SHOOT_COYOTE, // Kill three coyote
MS_JUMP_SET_UP_OUTRO, // --* JUMP STATE *--
MS_RUN_OUTRO, // Scripted outro cutscene
MS_MISSION_PASSED,
MS_FAILED_WAIT_FOR_FADE
ENDENUM
MISSION_STATE eMissionState = MS_INIT_MISSION
ENUM HUNTER_STATE
HS_NULL = 0,
HS_PUT_BINOS_AWAY_AND_WANDER_OFF,
HS_START_WALKING_TO_DISHES,
HS_JUMP_AFTER_INTRO,
HS_WALK_TO_DISHES,
HS_JUMP_TO_SHOOT_DISHES,
HS_GET_BINOS_OUT_FOR_DISHES,
HS_WATCH_PLAYER_SHOOT_DISHES,
HS_PUT_BINOS_AWAY_AFTER_DISHES,
HS_BECOME_PLAYERS_BUDDY_FOR_MOTEL,
HS_FOLLOW_PLAYER_TO_MOTEL,
HS_WAIT_PLAYER_COME_BACK,
HS_WALK_TO_TYRE_BALCONY,
HS_JUMP_TO_SHOOT_TYRES,
HS_GET_BINOS_OUT_FOR_TYRES,
HS_WATCH_PLAYER_SHOOT_TYRES,
HS_PUT_BINOS_AWAY_AFTER_TYRES,
HS_WALK_TO_COLLAPSED_ROOF,
HS_WAIT_AT_COLLAPSED_ROOF,
HS_WALK_TO_COYOTES,
HS_JUMP_TO_COLLAPSED_ROOF,
HS_GET_BINOS_OUT_FOR_COYOTES,
HS_WATCH_PLAYER_SHOOT_COYOTES,
HS_BINOS_AWAY_AFTER_COYOTE,
HS_JUMP_SET_UP_OUTRO,
HS_DO_OUTRO_CONV,
HS_DO_ANGRY_FAIL
ENDENUM
HUNTER_STATE eHunterState = HS_NULL
HUNTER_STATE ePreState = HS_NULL
ENUM SUB_STATE
SS_INIT,
SS_ACTIVE,
SS_CLEANUP,
SS_SKIPPED
ENDENUM
SUB_STATE eSubState
ENUM SHOOT_LOCATION
DISH_LOC = 0,
TYRE_LOC,
COYOTE_LOC
ENDENUM
ENUM TYRE_CAR_STATE
TCS_NULL = 0,
TCS_CHECK_CAN_CREATE,
TCS_CREATE,
TCS_WANDER,
TCS_CHECK_FOR_DAMGAGE,
TCS_STOP_CAR,
TCS_WAIT_FOR_CAR_TO_STOP,
TCS_LEAVE_CAR,
TCS_GET_TO_INSPECTION_POINT,
TCS_GETTING_TO_INSPECTION_POINT,
TCS_TURN_TO_FACE_TYRE,
TCS_LOAD_INSPECT_DAMAGE_ANIMS,
TCS_INSPECT_DAMAGE,
TCS_FLEE_ON_FOOT,
TCS_FLEE_IN_CAR,
TCS_CLEAN_UP
ENDENUM
ENUM COYOTE_STATE
CS_NULL = 0,
CS_SPAWN_IN,
CS_TRY_SPAWNING_AGAIN,
CS_CALC_RANDOM_WAIT_TIME,
CS_WAIT_RANDOM_TIME,
CS_CHOOSE_NEXT_DESTINATION,
CS_GO_NEXT_DESTINATION,
CS_ARRIVED_NEXT_DESTINATION,
CS_FOLLOW_LEADER,
CS_FOLLOWING_LEADER,
CS_INVESTIGATING_DEATH,
CS_RUN_OFF,
CS_RUNNING_OFF,
CS_CLEAN_UP
ENDENUM
ENUM FAIL_REASON
FAIL_NONE = 0,
FAIL_HUNTER_DEAD,
FAIL_HUNTER_INJURED,
FAIL_CAR_DEAD,
FAIL_KILLED_PEDS,
FAIL_LEFT_HUNT,
FAIL_BAD_SHOT,
FAIL_WRONG_GUN,
FAIL_LEFT_HUNT_AREA
ENDENUM
ENUM COYOTE_PACK_ID
CP_LEADER,
CP_FOLLOWER,
CP_LONE
ENDENUM
ENUM PACK_STATES
PS_SPAWN_IN,
PS_ACTIVE,
PS_INVESTIGATE,
PS_INVESTIGATING_DEATH,
PS_FLEE,
PS_AFTER_FLEE,
PS_NULL
ENDENUM
ENUM HUNTER_CONVO
HC_PRE_DISH_BANTER = 0,
HC_DISH_INSTRUCT,
HC_LEAVE_BEFORE_COMPLETE,
HC_DISH_COMPLETE,
HC_AFTER_DISH_BANTER,
HC_LEAVE_DISHES,
HC_COMPLAIN,
HC_CAR_COMMENT,
HC_IN_CAR,
HC_FOLLOW_ME,
HC_WALK_TO_TYRES,
HC_TYRE_INSTRUCT,
HC_COY_KILL_IN_TYRE,
HC_MURDER,
HC_TYRE_COMPLETE,
HC_WALK_TO_WAIT,
HC_WAIT,
HC_COY_INSTRUCT,
HC_SHOT_ONE_COYOTE,
HC_SHOT_TWO_COYOTE,
HC_COY_COMPLETE,
HC_OUTRO_CONVO,
HC_NO_AIM
ENDENUM
ENUM OBJECTIVE_TEXT
OT_FOLLOW_CLETUS = 0,
OT_GO_MOTEL,
OT_RETURN_TO_CLETUS
ENDENUM
// DEBUG CONSTS
#IF IS_DEBUG_BUILD
CONST_INT MAX_SKIP_MENU_LENGTH 5
#ENDIF
// CONSTS
CONST_INT CAR_CONVO_DELAY_TIME 3000
CONST_INT NO_CAR_CONVO_DELAY_TIME 20000
CONST_INT MAX_DISHES 3
CONST_INT DISH_START_HEALTH 100
CONST_INT MAX_TYRE_CARS 5
CONST_INT MAX_TYRE_CARS_AT_ONCE 3
CONST_INT MAX_COYOTES 6
CONST_INT MAX_PACK_MEMBERS 3 // Number of coyote in a pack
CONST_INT MAX_PACKS 2 // Number of packs
CONST_INT MAX_GRAZE_AREAS 8 // Vecs for the graze areas
CONST_INT MAX_AMBIENT_CARS 4 // The ambient vehicles in the world
CONST_INT MAX_NAV_POINTS 4
CONST_INT TARGET_HITS_REQUIRED 3 // How many things we need to shoot at each location.
CONST_INT MAX_HUNTER_CONVO 23 // How many conversations the Hunter has. Each one to be flagged on completion.
CONST_INT MAX_OBJECTIVE_TEXT 3
CONST_INT PLAYER_EXIT_DELAY 1250
CONST_INT HUNTER_EXIT_DELAY 1750
CONST_INT CP_AFTER_MOCAP 0
CONST_INT CP_BEFORE_DISHES 1
CONST_INT CP_AFTER_DISHES 2
CONST_INT CP_AFTER_TYRES 3
CONST_INT CP_AFTER_COYOTES 4
CONST_INT CP_BEFORE_PASS 5
CONST_INT NICE_LITTLE_PAUSE 2400
// ACTION AREA WIDTHS
CONST_FLOAT CLETUS_HOUSE_WIDTH 16.0
CONST_FLOAT TYRE_MOTEL_WIDTH 19.0
CONST_FLOAT COYOTE_MOTEL_WIDTH 19.0
CONST_FLOAT COLLAPSED_WIDTH 3.5
CONST_FLOAT MIN_CONVO_DIST 10.0
CONST_FLOAT DISH_AREA_WIDTH 7.0
CONST_FLOAT TYRE_AREA_WIDTH 10.0
CONST_FLOAT COYOTE_AREA_WIDTH 20.0
CONST_FLOAT TYRE_CAR_ROAD_WIDTH 325.0
CONST_FLOAT RESOLVE_AREA_WIDTH 5.0
CONST_FLOAT DEST_RADIUS_SMALL 5.0
CONST_FLOAT DEST_RADIUS_BIG 10.0
CONST_FLOAT HINT_CAM_OVERRIDE 3.0
// STRUCTS
STRUCT DISH_TARGETS
OBJECT_INDEX mObj
VECTOR vSpawn
FLOAT fHead
INT iHealth
FLOAT fHunterAngleToFace
BOOL bDamaged
BOOL bDamageChecked
BLIP_INDEX mDishBlip
ENDSTRUCT
DISH_TARGETS mDish[MAX_DISHES]
STRUCT TYRE_CARS
BLIP_INDEX mCarBlip
BOOL bTyreHit
BOOL bIsFleeing
BOOL bReducedCarsInWorld
FLOAT fHead
FLOAT fTyreHeadModifier
FLOAT fTyreInspectHead
INT iRand
INT iCallDuration
MODEL_NAMES mModel
MODEL_NAMES mPedModel
OBJECT_INDEX mMobileObj
PED_INDEX mCarPed
TYRE_CAR_STATE eCarState
SEQUENCE_INDEX mSeq
SCRIPTTASKSTATUS mTaskStatus
VECTOR vSpawn
VECTOR vGoto
VECTOR vTyrePosOffset
VECTOR vTyreInspectPos
VEHICLE_INDEX mCar
ENDSTRUCT
TYRE_CARS mTyreCar[MAX_TYRE_CARS]
/// PURPOSE: Holds common data for the coyote targets
STRUCT COYOTE_TARGETS
BLIP_INDEX mCoyBlip
BOOL bDead = FALSE
BOOL bShot = FALSE
COYOTE_STATE eCoyState
COYOTE_PACK_ID ePackID
FLOAT fRandHead
PED_INDEX mCoyPed
INT iWaitTime
INT iCurTime
INT iCurSpawn
INT iRandSpawn
VECTOR vFollowOffset
VECTOR vBulletLoc
ENDSTRUCT
/// PURPOSE: Holds common data for a coyote pack
STRUCT COYOTE_PACK
COYOTE_TARGETS mCoyote[MAX_PACK_MEMBERS]
PACK_STATES ePackState = PS_NULL
INT iAlive
ENDSTRUCT
COYOTE_PACK mPack[MAX_PACKS]
// VARIABLES
REL_GROUP_HASH relGroupFriendly
BLIP_INDEX mBlip
BLIP_INDEX mHunterBlip
BOOL bBalconySceneBlocked = FALSE
BOOL bBinoAssetsInMem = FALSE
BOOL bBinosOut = FALSE
BOOL bBonusComment = FALSE
BOOL bCanBlipTyreCars = FALSE
BOOL bChosenDish = FALSE
BOOL bLetPlayerRun = FALSE
BOOL bDishAssetsInMem = FALSE
BOOL bDoneThreatSpeech = FALSE
BOOL bDoneWrongCarComment = FALSE
BOOL bHadSniperRifle = FALSE
//BOOL bHadSuppressor = FALSE
BOOL bHasAimed = FALSE
//BOOL bHadLargeScope = FALSE
//BOOL bHadMaxScope = FALSE
//BOOL bHadClip = FALSE
BOOL bHunterStartedWalking = FALSE
BOOL bInactiveTimerStarted = FALSE
BOOL bGotCarDamageTime = FALSE
BOOL bGotDelayTimer = FALSE
BOOL bGotFailDelay = FALSE
BOOL bMissedCoyote = FALSE
BOOL bMissedTyreCar = FALSE
BOOL bPlayerLeftHunter = FALSE
BOOL bRelGroupCreated = FALSE
BOOL bReturnedPlayersGun = FALSE
BOOL bCanAddCoyoteBlips = FALSE
BOOL bSaidNoGunComment = FALSE
BOOL bSaidWrongGunComment = FALSE
BOOL bShotFromWrongPlace = FALSE
BOOL bShownDishObjective = FALSE
BOOL bStartedCarConvoTimer = FALSE
BOOL bTyreCarAssetsInMem = FALSE
BOOL bTyreStairsSceneBlocked= FALSE
BOOL bWrongGunFail = FALSE
BOOL bSetIntroExitState = FALSE
BOOL bGotBalconyIdleTimer = FALSE
BOOL bStartedNoCarConvoTimer = FALSE
BOOL bFalling = FALSE
BOOL bSaidGoodShotLine[TARGET_HITS_REQUIRED]
BOOL bIsBooked[MAX_GRAZE_AREAS]
BOOL bTriggeredConvo[MAX_HUNTER_CONVO]
BOOL bTriggeredObjectiveText[MAX_OBJECTIVE_TEXT]
BOOL bDeathInPack[MAX_PACKS]
FLOAT fPedDishHeading = 196.3286
FLOAT fPedTyreHeading = 123.1702
FLOAT fHintFov = 40.0
FLOAT fHintFollow = 0.35
FLOAT fHintPitchOrbit = -0.00
FLOAT fHintSide = -0.81
FLOAT fHintVert = -0.05
FLOAT fHunterWaitHeading = 210.0785
FLOAT fHunterIntroSkipHead = 177.7762
FLOAT fPedCoyoteHeading = 215.1814
FLOAT fCarResolveHeading = 131.6226
FLOAT fTankerRadius = 5.0
INT iBalconyIdleTimer
INT iCarConvoTime = 0
INT iCarDamageTime = 0
INT iCarsInWorld = 0
INT iCutsceneState = 0
INT iDeadPeds = 0
INT iDelayTime
INT iDishLine = 0 // Cletus' bespoke inactivity lines for the dish section
INT iFailDelay
INT iHintTimer
INT iInactiveTime
INT iInactiveDuration
INT iKnockState = 0
INT iLeaderID = 0
INT iLoop = 0
INT iNavPoint = 0
INT iNoCarConvoTime
INT iPoleBlock = -1
INT iPreDishConvoTime
INT iRandomDish = -1
INT iShotsFired = 0
INT iSniperAmmoBefore
INT iTargetsShot = 0
//INT iTint
INT iTyreLine = 0 // Cletus' bespoke inactivity lines for the tyre section
MODEL_NAMES mDishModel = PROP_SATDISH_L_02B
MODEL_NAMES mCoyModel = A_C_COYOTE
MODEL_NAMES mBinoModel = PROP_BINOC_01
MODEL_NAMES mAmbCarModelOne = EMPEROR2
MODEL_NAMES mAmbCarModelTwo = SURFER2
MODEL_NAMES mMobileModel = PROP_NPC_PHONE
OBJECT_INDEX mBinos
OBJECT_INDEX mCletusGun
PED_INDEX mHunter
SCENARIO_BLOCKING_INDEX mBalconyBlockArea
SCENARIO_BLOCKING_INDEX mTyreStairsBlockArea
SEQUENCE_INDEX mWanderSeq
STRING sFailReason
STRING sTextBlock = "HUNT1AU"
STRING sTrevor = "Trevor"
STRING sCletusCS = "Cletus" // "CSB_Cletus"
// Positions
VECTOR vDishShootPos = << 1815.7172, 3906.1472, 36.2175 >>
VECTOR vMotelPos = << 1517.0549, 3556.8809, 34.3632 >>
VECTOR vTyreShootPos = << 1511.2650, 3564.7551, 37.7316 >>
// Tanker objects
VECTOR vTankerAPos = <<1776.1980, 3838.0986, 33.2593>>
VECTOR vTankerBPos = <<1780.5133, 3831.4253, 33.1172>>
// Shoot Areas
VECTOR vDishShootAreaA = << 1812.6630, 3906.6938, 35.0000 >>
VECTOR vDishShootAreaB = << 1820.2716, 3908.1089, 38.0000 >>
VECTOR vTyreShootAreaA = << 1512.3389, 3563.7341, 36.0000 >>
VECTOR vTyreShootAreaB = << 1504.8284, 3574.7021, 39.5000 >>
VECTOR vCoyoteShootAreaA = << 1603.2378, 3558.5503, 38.0000 >>
VECTOR vCoyoteShootAreaB = << 1618.2628, 3567.5781, 45.0000 >>
VECTOR vFailDist = << 250.0, 250.0, 250.0 >>
// Hunters Locations
VECTOR vHunterDishPos = << 1816.7703, 3908.3315, 36.2176 >>
VECTOR vHunterTyrePos = << 1510.6383, 3567.1609, 37.7315 >>
VECTOR vHunterBalconyWaitPos = << 1586.0638, 3589.7173, 37.7952>>
FLOAT fHunterBalconyWaitHead = 248.7637
VECTOR vHunterCoyotePos = << 1611.7203, 3567.2546, 41.1167 >>
VECTOR vHunterIntroSkipPos = <<1801.2651, 3921.9150, 33.0721>>
// Road positions
VECTOR vTyreCarDestLeft = << 1590.7385, 3474.2935, 30.0000 >>
VECTOR vTyreCarDestRight = << 1160.5759, 3537.1135, 36.0000 >>
VECTOR vRoadPos = << 1369.7688, 3518.3479, 34.6511 >>
// Player start/skip positions
VECTOR vPlayerBalconyWaitPos = <<1584.5571, 3591.8162, 37.7349>>
FLOAT fPlayerBalconyWaitHead = 248.7637
VECTOR vMocapIntroPos = << 1803.3263, 3933.7354, 32.7459 >>
VECTOR vPlayerIntroSkipPos = <<1805.7805, 3926.2749, 32.6940>>
FLOAT fPlayerIntroSkipHead = 144.2076
VECTOR vLeftFollower = << -2.5, -1.5, 0.0 >>
VECTOR vRightFollower = << 2.5, -2.0, 0.0 >>
VECTOR vGroupRange = << 40.0, 40.0, 40.0 >>
VECTOR vGroupReturnRange = << 15.0, 15.0, 5.0 >>
VECTOR vResolveAreaA = << 1809.0676, 3927.2029, 31.7835>>
VECTOR vResolveAreaB = << 1799.5347, 3934.3552, 35.8289>>
VECTOR vResolveAreaC = << 1802.5814, 3928.4397, 32.9820>>
VECTOR vResolveAreaD = << 1792.1840, 3926.4375, 34.1531>>
VECTOR vResolveAreaE = << 1810.5790, 3933.2617, 31.6445>>
VECTOR vResolveAreaF = << 1802.9730, 3935.1440, 35.7574>>
VECTOR vResolveAreaG = << 1809.1598, 3934.6692, 34.6121>>
VECTOR vResolveAreaH = << 1817.4181, 3936.8616, 31.3923>>
VECTOR vCarResolvePos = << 1792.6660, 3935.5110, 33.0160 >>
VECTOR vTyrePolePos = << 1513.5538, 3563.9299, 34.3215 >>
VECTOR vTyrePoleSize = << 0.5, 0.5, 2.0 >>
// Action mode areas
VECTOR vCletusHouseA = <<1801.3896, 3912.1118, 32.7075>>
VECTOR vCletusHouseB = <<1817.6522, 3915.5693, 40.5196>>
VECTOR vTyreMotelA = <<1568.2800, 3603.7947, 34.0000>>
VECTOR vTyreMotelB = <<1505.4122, 3570.8496, 40.7358>>
VECTOR vCoyoteMotelA = <<1576.7498, 3622.0029, 34.0000>>
VECTOR vCoyoteMotelB = <<1612.0980, 3560.5864, 40.4248>>
// Scenario Ped Blocking positions
// Satellite stairs
VECTOR vDishStairsPos = << 1801.1593, 3919.6062, 33.0662 >>
VECTOR vDishStairsAreaA = << 1803.6034, 3920.1909, 32.9855 >>
VECTOR vDishStairsAreaB = << 1798.4159, 3918.2910, 35.0579 >>
// Satellite dish balcony
VECTOR vDishBlockPos = << 1815.8374, 3905.2798, 36.2176 >>
VECTOR vDishBlockAreaA = << 1818.0779, 3906.8181, 36.2176 >>
VECTOR vDishBlockAreaB = << 1813.2834, 3904.5962, 38.2176 >>
VECTOR vFenceBlockPos = << 1797.2856, 3927.3591, 33.0176 >>
VECTOR vFenceBlockAreaA = << 1793.7654, 3926.7485, 35.1276 >>
VECTOR vFenceBlockAreaB = << 1799.7296, 3927.8149, 32.9875 >>
VECTOR vTyreBlockPos = << 1509.6061, 3568.5481, 34.4349 >>
//VECTOR vTyreBlockAreaA = << 1506.5310, 3569.1045, 34.5601 >>
//VECTOR vTyreBlockAreaB = << 1513.0338, 3567.4006, 36.4170 >>
VECTOR vCollapsedPosA = << 1583.4836, 3594.0876, 37.7349 >>
VECTOR vCollapsedPosB = << 1590.5530, 3582.1738, 40.8244 >>
// Outro positions
VECTOR vPlayerOutroPos = << 1609.7288, 3564.4075, 41.1167 >>
FLOAT fPlayerOutroHead = 294.7606
//VECTOR vPlayerOutroSkipPos = << 1799.0994, 3935.8647, 32.9143 >>
//FLOAT fPlayerOutroSkipHead = 247.4269
VECTOR vHunterOutroPos = << 1611.4178, 3565.4700, 41.1167 >>
FLOAT fHunterOutroHead = 118.7707
VECTOR vGrazePos[MAX_GRAZE_AREAS]
VECTOR vNavPoint[MAX_NAV_POINTS]
VECTOR vDeath[MAX_PACKS]
VECTOR vWanderPoint1 = << 1591.3438, 3581.7783, 40.9600 >>
VECTOR vWanderPoint2 = << 1585.1088, 3591.6975, 37.7349 >>
VECTOR vWanderPoint3 = << 1591.2906, 3596.7617, 34.6910 >>
VEHICLE_INDEX mAmbCar[MAX_AMBIENT_CARS]
VEHICLE_INDEX mHunterCar
// DEBUG VARS
//DEBUG DECLARATIONS
#IF IS_DEBUG_BUILD
MissionStageMenuTextStruct s_skip_menu[MAX_SKIP_MENU_LENGTH]
INT i_debug_jump_stage
#ENDIF
// FUNCTIONS
PROC SAFE_FADE_OUT()
IF NOT IS_SCREEN_FADED_OUT()
AND NOT IS_SCREEN_FADING_OUT()
DO_SCREEN_FADE_OUT(500)
ENDIF
ENDPROC
PROC SAFE_FADE_IN()
IF NOT IS_SCREEN_FADED_IN()
AND NOT IS_SCREEN_FADING_IN()
DO_SCREEN_FADE_IN(500)
ENDIF
ENDPROC
// CLEANUP
/// PURPOSE:
/// Removes all blips on all targets
PROC REMOVE_ALL_TARGET_BLIPS()
INT i, j
i = 0
REPEAT MAX_DISHES i
SAFE_REMOVE_BLIP(mDish[i].mDishBlip)
ENDREPEAT
i = 0
REPEAT MAX_TYRE_CARS i
SAFE_REMOVE_BLIP(mTyreCar[i].mCarBlip)
ENDREPEAT
i = 0
j = 0
REPEAT MAX_PACKS i
REPEAT MAX_PACK_MEMBERS j
SAFE_REMOVE_BLIP(mPack[i].mCoyote[j].mCoyBlip)
ENDREPEAT
ENDREPEAT
ENDPROC
PROC RELEASE_DISH_ASSETS
CPRINTLN(DEBUG_MISSION, "RELEASE_DISH_ASSETS")
INT i = 0
REPEAT MAX_DISHES i
IF DOES_BLIP_EXIST(mDish[i].mDishBlip)
CPRINTLN(DEBUG_MISSION, "Blip exists")
REMOVE_BLIP(mDish[i].mDishBlip)
ENDIF
SAFE_DELETE_OBJECT(mDish[i].mObj)
ENDREPEAT
IF bDishAssetsInMem
SET_MODEL_AS_NO_LONGER_NEEDED(mDishModel)
ENDIF
ENDPROC
PROC RELEASE_TYRE_CAR_ASSETS()
IF bTyreCarAssetsInMem
CPRINTLN(DEBUG_MISSION, "RELEASE_TYRE_CAR_ASSETS")
SET_MODEL_AS_NO_LONGER_NEEDED(mTyreCar[0].mModel)
SET_MODEL_AS_NO_LONGER_NEEDED(mTyreCar[1].mModel)
SET_MODEL_AS_NO_LONGER_NEEDED(mTyreCar[2].mModel)
SET_MODEL_AS_NO_LONGER_NEEDED(mTyreCar[3].mModel)
SET_MODEL_AS_NO_LONGER_NEEDED(mTyreCar[4].mModel)
SET_MODEL_AS_NO_LONGER_NEEDED(mTyreCar[0].mPedModel)
SET_MODEL_AS_NO_LONGER_NEEDED(mTyreCar[1].mPedModel)
SET_MODEL_AS_NO_LONGER_NEEDED(mTyreCar[2].mPedModel)
SET_MODEL_AS_NO_LONGER_NEEDED(mTyreCar[3].mPedModel)
SET_MODEL_AS_NO_LONGER_NEEDED(mTyreCar[4].mPedModel)
SET_MODEL_AS_NO_LONGER_NEEDED(mMobileModel)
bTyreCarAssetsInMem = FALSE
ENDIF
ENDPROC
PROC RELEASE_COYOTE_ASSETS()
CPRINTLN(DEBUG_MISSION, "RELEASE_COYOTE_ASSETS")
SET_MODEL_AS_NO_LONGER_NEEDED(mCoyModel)
ENDPROC
PROC RELEASE_AMBIENT_CAR_ASSETS()
CPRINTLN(DEBUG_MISSION, "RELEASE_AMBIENT_CAR_ASSETS")
SET_MODEL_AS_NO_LONGER_NEEDED(mAmbCarModelOne)
SET_MODEL_AS_NO_LONGER_NEEDED(mAmbCarModelTwo)
ENDPROC
/// PURPOSE:
/// Turn off emergency services
PROC TOGGLE_EMS(BOOL bEnable)
CPRINTLN(DEBUG_MISSION, "TOGGLE EMS")
ENABLE_DISPATCH_SERVICE(DT_POLICE_AUTOMOBILE, bEnable)
ENABLE_DISPATCH_SERVICE(DT_POLICE_HELICOPTER, bEnable)
ENABLE_DISPATCH_SERVICE(DT_FIRE_DEPARTMENT, bEnable)
ENABLE_DISPATCH_SERVICE(DT_SWAT_AUTOMOBILE, bEnable)
ENABLE_DISPATCH_SERVICE(DT_AMBULANCE_DEPARTMENT, bEnable)
//Wanted
IF NOT bEnable
SET_MAX_WANTED_LEVEL(0)
SET_WANTED_LEVEL_MULTIPLIER(0.0)
ELSE
SET_WANTED_LEVEL_MULTIPLIER(1.0)
ENDIF
ENDPROC
PROC RETURN_PLAYERS_GUN()
CPRINTLN(DEBUG_MISSION, "RETURNING PLAYERS GUN")
IF bHadSniperRifle
CPRINTLN(DEBUG_MISSION, "Player had a sniper rifle")
// GIVE_WEAPON_TO_PED(PLAYER_PED_ID(), WEAPONTYPE_SNIPERRIFLE, iSniperAmmoBefore, FALSE, FALSE)
//
// WAIT(0)
// Remove infinite ammo.
SET_PED_INFINITE_AMMO(PLAYER_PED_ID(), FALSE, WEAPONTYPE_SNIPERRIFLE)
CPRINTLN(DEBUG_MISSION, "Removing infinite ammo")
SET_PED_AMMO_BY_TYPE(PLAYER_PED_ID(), AMMOTYPE_SNIPER, iSniperAmmoBefore)
CPRINTLN(DEBUG_MISSION, "Giving player ammo amount = ", iSniperAmmoBefore)
// No need to do this... Trevor's previous Sniper Rifle should be saved in the snapshot.
// IF bHadSuppressor
// CPRINTLN(DEBUG_MISSION, "with a supressor")
// GIVE_WEAPON_COMPONENT_TO_PED(PLAYER_PED_ID(), WEAPONTYPE_SNIPERRIFLE, WEAPONCOMPONENT_AT_AR_SUPP_02)
// ENDIF
// IF iTint != -1
// CPRINTLN(DEBUG_MISSION, "setting tint")
// SET_PED_WEAPON_TINT_INDEX(PLAYER_PED_ID(), WEAPONTYPE_SNIPERRIFLE, iTint)
// ENDIF
// IF bHadClip
// CPRINTLN(DEBUG_MISSION, "giving clip")
// GIVE_WEAPON_COMPONENT_TO_PED(PLAYER_PED_ID(), WEAPONTYPE_SNIPERRIFLE, WEAPONCOMPONENT_SNIPERRIFLE_CLIP_01)
// ENDIF
// IF bHadLargeScope
// CPRINTLN(DEBUG_MISSION, "giving large scope")
// GIVE_WEAPON_COMPONENT_TO_PED(PLAYER_PED_ID(), WEAPONTYPE_SNIPERRIFLE, WEAPONCOMPONENT_AT_SCOPE_LARGE)
// ENDIF
// IF bHadMaxScope
// CPRINTLN(DEBUG_MISSION, "giving max scope")
// GIVE_WEAPON_COMPONENT_TO_PED(PLAYER_PED_ID(), WEAPONTYPE_SNIPERRIFLE, WEAPONCOMPONENT_AT_SCOPE_MAX)
// ENDIF
ELSE
CPRINTLN(DEBUG_MISSION, "Removing sniper rifle - player didn't start with it.")
SET_CURRENT_PED_WEAPON(PLAYER_PED_ID(), WEAPONTYPE_UNARMED, TRUE)
REMOVE_WEAPON_FROM_PED(PLAYER_PED_ID(), WEAPONTYPE_SNIPERRIFLE)
ENDIF
bReturnedPlayersGun = TRUE
ENDPROC
/// PURPOSE:
/// Cleans up widgets, vehicles and resores players weapon
PROC Script_Cleanup()
// Clear the mission title
MISSION_FLOW_CLEAR_DISPLAY_MISSION_TITLE()
// Ensure launcher is cleaned up
RC_CLEANUP_LAUNCHER()
END_REPLAY_SETUP()
REMOVE_ALL_TARGET_BLIPS()
RELEASE_DISH_ASSETS()
RELEASE_TYRE_CAR_ASSETS()
RELEASE_COYOTE_ASSETS()
RELEASE_AMBIENT_CAR_ASSETS()
TOGGLE_EMS(TRUE)
IF NOT bReturnedPlayersGun
RETURN_PLAYERS_GUN()
ENDIF
// If the mission was triggered then additional mission cleanup will be required.
IF (Random_Character_Cleanup_If_Triggered())
PRINTSTRING("...Random Character Script was triggered so additional cleanup required") PRINTNL()
ENDIF
IF iPoleBlock != -1
CPRINTLN(DEBUG_MISSION, "REMOVING NAVMESH BLOCKING OBJECT")
REMOVE_NAVMESH_BLOCKING_OBJECT(iPoleBlock)
ENDIF
IF NOT IS_SCENARIO_TYPE_ENABLED("WORLD_HUMAN_HANG_OUT_STREET")
SET_SCENARIO_TYPE_ENABLED("WORLD_HUMAN_HANG_OUT_STREET", TRUE)
ENDIF
IF NOT IS_SCENARIO_TYPE_ENABLED("WORLD_HUMAN_DRINKING")
SET_SCENARIO_TYPE_ENABLED("WORLD_HUMAN_DRINKING", TRUE)
ENDIF
IF NOT IS_SCENARIO_TYPE_ENABLED("WORLD_HUMAN_SMOKING")
SET_SCENARIO_TYPE_ENABLED("WORLD_HUMAN_SMOKING", TRUE)
ENDIF
IF IS_PED_UNINJURED(mHunter)
IF IS_PED_GROUP_MEMBER(mHunter, PLAYER_GROUP_ID())
REMOVE_PED_FROM_GROUP(mHunter)
ENDIF
SET_PED_GET_OUT_UPSIDE_DOWN_VEHICLE(mHunter, TRUE)
SAFE_RELEASE_PED(mHunter, TRUE)
ENDIF
IF bBinoAssetsInMem
SET_MODEL_AS_NO_LONGER_NEEDED(mBinoModel)
ENDIF
IF bBalconySceneBlocked
REMOVE_SCENARIO_BLOCKING_AREA(mBalconyBlockArea)
ENDIF
IF bTyreStairsSceneBlocked
REMOVE_SCENARIO_BLOCKING_AREA(mTyreStairsBlockArea)
ENDIF
CLEAR_PED_NON_CREATION_AREA()
RC_CleanupSceneEntities(sRCLauncherDataLocal,FALSE)
CLEAR_ADDITIONAL_TEXT(MISSION_DIALOGUE_TEXT_SLOT, TRUE)
ENDPROC
/// PURPOSE:
/// Terminates the thread
PROC Script_Passed()
// B*1948239 - Stop the New Contact Added message from drawing in over a faded out screen.
IF NOT IS_REPLAY_IN_PROGRESS()
ADD_CONTACT_TO_PHONEBOOK(CHAR_HUNTER, TREVOR_BOOK)
ENDIF
END_REPLAY_SETUP()
SAFE_FADE_IN()
KILL_ANY_CONVERSATION()
Random_Character_Passed(CP_OJ_HUN1)
Script_Cleanup()
TERMINATE_THIS_THREAD()
ENDPROC
/// PURPOSE:
/// Waits for the screen to fade out then updates failed reason
PROC FAILED_WAIT_FOR_FADE()
SWITCH eSubState
CASE SS_INIT
CLEAR_PRINTS()
CLEAR_HELP()
REMOVE_ALL_TARGET_BLIPS()
IF IS_STRING_NULL_OR_EMPTY(sFailReason)
Random_Character_Failed()
ELSE
Random_Character_Failed_With_Reason(sFailReason)
ENDIF
eSubState = SS_ACTIVE
BREAK
CASE SS_ACTIVE
IF GET_MISSION_FLOW_SAFE_TO_CLEANUP()
KILL_ANY_CONVERSATION()
Script_Cleanup()
TERMINATE_THIS_THREAD()
ELSE
// not finished fading out
// you may want to handle dialogue etc here.
ENDIF
BREAK
ENDSWITCH
ENDPROC
/// PURPOSE:
/// Called when the player has failed and deletes blips and clears the screen of text and conversations are ended
PROC SET_MISSION_FAILED_REASON(FAIL_REASON eFailReason)
CPRINTLN(DEBUG_MISSION, "SET_MISSION_FAIL_REASON")
CLEAR_PRINTS()
KILL_ANY_CONVERSATION()
REMOVE_ALL_TARGET_BLIPS()
SAFE_REMOVE_BLIP(mHunterBlip)
SAFE_REMOVE_BLIP(mBlip)
SWITCH eFailReason
CASE FAIL_CAR_DEAD sFailReason = "HH_FAIL1" BREAK // The car was destroyed.
CASE FAIL_HUNTER_DEAD sFailReason = "HH_FAIL2" BREAK // Cletus died.
CASE FAIL_HUNTER_INJURED sFailReason = "HH_FAIL3" BREAK // Cletus was injured.
CASE FAIL_KILLED_PEDS sFailReason = "HH_FAIL4" BREAK // Trevor killed innocent people
CASE FAIL_LEFT_HUNT sFailReason = "HH_FAIL5" BREAK // Trevor left the hunter behind.
CASE FAIL_BAD_SHOT sFailReason = "HT_FAIL6" BREAK // Trevor disobeyed Cletus.
CASE FAIL_LEFT_HUNT_AREA sFailReason = "HT_FAIL7" BREAK // Trevor left the hunt area.
CASE FAIL_WRONG_GUN sFailReason = "HT_FAIL8" BREAK // Trevor used the wrong weapon
CASE FAIL_NONE BREAK
ENDSWITCH
CPRINTLN(DEBUG_MISSION, "Mission Fail Reason has been set")
eSubState = SS_INIT
eMissionState = MS_FAILED_WAIT_FOR_FADE
ENDPROC
// GENERAL FUNCTIONS
PROC MONITOR_ACTION_ZONES()
IF GET_FOLLOW_PED_CAM_VIEW_MODE() != CAM_VIEW_MODE_FIRST_PERSON
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), vCletusHouseA, vCletusHouseB, CLETUS_HOUSE_WIDTH)
OR IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), vTyreMotelA, vTyreMotelB, TYRE_MOTEL_WIDTH)
OR IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), vCoyoteMotelA, vCoyoteMotelB, COYOTE_MOTEL_WIDTH)
IF NOT IS_PED_USING_ACTION_MODE(PLAYER_PED_ID())
SET_PED_USING_ACTION_MODE(PLAYER_PED_ID(), TRUE)
ENDIF
ELSE
IF IS_PED_USING_ACTION_MODE(PLAYER_PED_ID())
SET_PED_USING_ACTION_MODE(PLAYER_PED_ID(), FALSE)
ENDIF
ENDIF
ENDIF
ENDPROC
PROC CHECK_PLAYER_AIMING()
IF NOT bHasAimed
IF IS_AIMING_THROUGH_SNIPER_SCOPE(PLAYER_PED_ID())
CPRINTLN(DEBUG_MISSION, "Player has aimed")
bHasAimed = TRUE
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Checks if peds are in different vehicles. Used for checking if its ok to trigger a cutscene.
FUNC BOOL ARE_PEDS_IN_DIFFERENT_VEHICLES()
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
AND NOT IS_PED_IN_ANY_VEHICLE(mHunter)
RETURN TRUE
ENDIF
IF IS_PED_IN_ANY_VEHICLE(mHunter)
AND NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Resets all the hunters conversation flags to false.
PROC RESET_HUNTER_CONVOS
INT i = 0
REPEAT MAX_HUNTER_CONVO i
bTriggeredConvo[i] = FALSE
ENDREPEAT
ENDPROC
/// PURPOSE:
/// Resets all the godtext displayed flags to false.
PROC RESET_OBJECTIVE_TEXT
INT i = 0
REPEAT MAX_OBJECTIVE_TEXT i
bTriggeredObjectiveText[i] = FALSE
ENDREPEAT
ENDPROC
PROC RESET_CAM()
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0)
ENDPROC
/// PURPOSE:
/// Prints objective to the screen
PROC PRINT_OBJ(String objstr)
PRINT_NOW(objstr, DEFAULT_GOD_TEXT_TIME, 0)
ENDPROC
PROC RESET_GUN_COMMENTS()
// Reset this if the player is using the right gun
IF bSaidWrongGunComment
bSaidWrongGunComment = FALSE
ENDIF
IF bSaidNoGunComment
bSaidNoGunComment = FALSE
ENDIF
ENDPROC
/// PURPOSE:
/// Checks that the player is using the correct gun for the mission.
FUNC BOOL IS_PLAYER_USING_SNIPER_RIFLE()
IF IS_PED_UNINJURED(PLAYER_PED_ID())
IF GET_WEAPONTYPE_GROUP(GET_PEDS_CURRENT_WEAPON(PLAYER_PED_ID())) = WEAPONGROUP_SNIPER
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Check that the targets are being hit when the player is still inside the hunt area.
PROC CHECK_FOR_PLAYER_DAMAGE_WHEN_OUTSIDE_SHOOT(ENTITY_INDEX index)
IF DOES_ENTITY_EXIST(index)
IF NOT IS_ENTITY_ALIVE(index) OR IS_ENTITY_ALIVE(index)
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(index, PLAYER_PED_ID())
//CLEAR_ENTITY_LAST_DAMAGE_ENTITY(index)
bShotFromWrongPlace = TRUE
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
///
PROC CHECK_COYOTE_KILL_IN_TYRE_SECTION()
PED_INDEX mPed
INT i = 0
IF Has_Ped_Been_Injured()
REPEAT Get_Number_Of_Ped_Injured_Events() i
IF DOES_ENTITY_EXIST(Get_Index_Of_Injured_Ped(i))
mPed = GET_PED_INDEX_FROM_ENTITY_INDEX(Get_Index_Of_Injured_Ped(i))
IF IS_ENTITY_ALIVE(mPed) OR NOT IS_ENTITY_ALIVE(mPed)
IF IS_PED_MODEL(mPed, mCoyModel)
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mPed, PLAYER_PED_ID())
CLEAR_ENTITY_LAST_DAMAGE_ENTITY(mPed)
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_COYTYR", CONV_PRIORITY_MEDIUM)
bTriggeredConvo[HC_COY_KILL_IN_TYRE] = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDREPEAT
ENDIF
ENDPROC
/// PURPOSE:
/// Checks to see if the player has killed too many innocents.
/// PARAMS:
/// bIsAfterOtherFail - Flag to see if the player has already failed the mission when this
/// returns true and changes the mission fail reason accordingly.
PROC CHECK_FOR_MURDER(BOOL bIsAfterOtherFail = FALSE)
PED_INDEX mPed
INT i = 0
IF IS_PED_UNINJURED(mHunter) AND IS_PED_UNINJURED(PLAYER_PED_ID())
IF Has_Ped_Been_Injured()
REPEAT Get_Number_Of_Ped_Injured_Events() i
IF DOES_ENTITY_EXIST(Get_Index_Of_Injured_Ped(i))
mPed = GET_PED_INDEX_FROM_ENTITY_INDEX(Get_Index_Of_Injured_Ped(i))
IF mPed <> PLAYER_PED_ID() AND mPed <> mHunter
IF NOT IS_ENTITY_A_MISSION_ENTITY(mPed) AND IS_ENTITY_A_PED(mPed) AND IS_PED_HUMAN(mPed)
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mPed, PLAYER_PED_ID())
CLEAR_ENTITY_LAST_DAMAGE_ENTITY(mPed)
iDeadPeds++
CPRINTLN(DEBUG_MISSION, "* * * * * PED KILLED * * * * * ")
ENDIF
ENDIF
ENDIF
ENDIF
ENDREPEAT
i = 0
REPEAT MAX_TYRE_CARS i
// Check the car drivers for getting shot too.
IF DOES_ENTITY_EXIST(mTyreCar[i].mCarPed)
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mTyreCar[i].mCarPed, PLAYER_PED_ID())
CLEAR_ENTITY_LAST_DAMAGE_ENTITY(mTyreCar[i].mCarPed)
iDeadPeds++
ENDIF
ENDIF
ENDREPEAT
IF iDeadPeds = 1
IF NOT bTriggeredConvo[HC_MURDER]
// Get the hunter to warn the player about killing innocents
IF PLAY_SINGLE_LINE_FROM_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_INOC", "HUNT1_INOC_1", CONV_PRIORITY_HIGH)
bTriggeredConvo[HC_MURDER] = TRUE
ENDIF
ENDIF
ELIF iDeadPeds > 1
// If the hunter is close, get the hunter to do his angry fail speech Hunter walks off
IF NOT bIsAfterOtherFail
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
SET_MISSION_FAILED_REASON(FAIL_KILLED_PEDS)
ENDIF
ELSE
SET_MISSION_FAILED_REASON(FAIL_KILLED_PEDS)
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Makes the hunter friendly to the player and vice versa.
PROC CREATE_REL_GROUP()
IF NOT bRelGroupCreated
ADD_RELATIONSHIP_GROUP("FRIENDLIES", relGroupFriendly)
SET_PED_RELATIONSHIP_GROUP_HASH(mHunter, relGroupFriendly)
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_LIKE, relGroupFriendly, RELGROUPHASH_PLAYER)
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_LIKE, RELGROUPHASH_PLAYER, relGroupFriendly)
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_IGNORE, relGroupFriendly, RELGROUPHASH_HATES_PLAYER)
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_IGNORE, RELGROUPHASH_PLAYER, RELGROUPHASH_HATES_PLAYER)
bRelGroupCreated = TRUE
ENDIF
ENDPROC
/// PURPOSE:
/// Resets the inactivity timer, the amount of shots
/// fired by player and how many targets he's hit.
PROC RESET_SHOOTING_AREA
CPRINTLN(DEBUG_MISSION, "RESET SHOOTING AREA")
bInactiveTimerStarted = FALSE
iShotsFired = 0
iTargetsShot = 0
iDishLine = 0
iTyreLine = 0
ENDPROC
PROC RECORD_PLAYERS_GUN()
CPRINTLN(DEBUG_MISSION, "RECORD_PLAYERS_GUN")
IF HAS_PED_GOT_WEAPON(PLAYER_PED_ID(), WEAPONTYPE_SNIPERRIFLE, GENERALWEAPON_TYPE_INVALID)
CPRINTLN(DEBUG_MISSION, "Player had a sniper rifle pre-mission")
bHadSniperRifle = TRUE
iSniperAmmoBefore = GET_PED_AMMO_BY_TYPE(PLAYER_PED_ID(), AMMOTYPE_SNIPER)
CPRINTLN(DEBUG_MISSION, "iSniperAmmoBefore = ", iSniperAmmoBefore)
// iTint = GET_PED_WEAPON_TINT_INDEX(PLAYER_PED_ID(), WEAPONTYPE_SNIPERRIFLE)
// CPRINTLN(DEBUG_MISSION, "iTint = ", iTint)
// IF HAS_PED_GOT_WEAPON_COMPONENT(PLAYER_PED_ID(), WEAPONTYPE_SNIPERRIFLE, WEAPONCOMPONENT_AT_AR_SUPP_02)
// CPRINTLN(DEBUG_MISSION, "bHadSuppressor = TRUE")
// bHadSuppressor = TRUE
// ENDIF
//
// IF HAS_PED_GOT_WEAPON_COMPONENT(PLAYER_PED_ID(), WEAPONTYPE_SNIPERRIFLE, WEAPONCOMPONENT_AT_SCOPE_LARGE)
// CPRINTLN(DEBUG_MISSION, "bHadLargeScope = TRUE")
// bHadLargeScope = TRUE
// ENDIF
//
// IF HAS_PED_GOT_WEAPON_COMPONENT(PLAYER_PED_ID(), WEAPONTYPE_SNIPERRIFLE, WEAPONCOMPONENT_AT_SCOPE_MAX)
// CPRINTLN(DEBUG_MISSION, "bHadMaxScope = TRUE")
// bHadMaxScope = TRUE
// ENDIF
//
// IF HAS_PED_GOT_WEAPON_COMPONENT(PLAYER_PED_ID(), WEAPONTYPE_SNIPERRIFLE, WEAPONCOMPONENT_SNIPERRIFLE_CLIP_01)
// CPRINTLN(DEBUG_MISSION, "bHadClip = TRUE")
// bHadClip = TRUE
// ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// GIVES THE PLAYER A SNIPER RIFLE, IF HE DOESN'T ALREADY HAVE ONE
PROC SAFE_GIVE_SNIPER_TO_PLAYER(BOOL bForceToHand = TRUE)
CPRINTLN(DEBUG_MISSION, "SAFE_GIVE_SNIPER_TO_PLAYER")
PED_INDEX pedPlayer = PLAYER_PED_ID()
IF IS_PED_UNINJURED(pedPlayer)
IF NOT HAS_PED_GOT_WEAPON(pedPlayer, WEAPONTYPE_SNIPERRIFLE, GENERALWEAPON_TYPE_INVALID)
GIVE_WEAPON_TO_PED(pedPlayer, WEAPONTYPE_SNIPERRIFLE, INFINITE_AMMO, bForceToHand)
ENDIF
IF NOT HAS_PED_GOT_WEAPON_COMPONENT(pedPlayer, WEAPONTYPE_SNIPERRIFLE, WEAPONCOMPONENT_AT_AR_SUPP_02)
GIVE_WEAPON_COMPONENT_TO_PED(pedPlayer, WEAPONTYPE_SNIPERRIFLE, WEAPONCOMPONENT_AT_AR_SUPP_02)
ENDIF
SET_PED_INFINITE_AMMO(pedPlayer, TRUE, WEAPONTYPE_SNIPERRIFLE)
SET_CURRENT_PED_WEAPON(pedPlayer, WEAPONTYPE_SNIPERRIFLE, bForceToHand)
ENDIF
ENDPROC
// ASSET REQUESTS AND CREATE FUNCTIONS
PROC REQUEST_SNIPER_RIFLE_ASSET()
REQUEST_WEAPON_ASSET(WEAPONTYPE_SNIPERRIFLE, ENUM_TO_INT(WRF_REQUEST_ALL_ANIMS), WEAPON_COMPONENT_SCOPE)
WHILE NOT HAS_WEAPON_ASSET_LOADED(WEAPONTYPE_SNIPERRIFLE)
WAIT(0)
ENDWHILE
ENDPROC
PROC REQUEST_ANIMS()
REQUEST_ANIM_DICT("ODDJOBS@HUNTER")
WHILE NOT HAS_ANIM_DICT_LOADED ("ODDJOBS@HUNTER")
WAIT(0)
ENDWHILE
ENDPROC
PROC REQUEST_DIALOGUE()
REQUEST_ADDITIONAL_TEXT("HUNT1", MISSION_TEXT_SLOT )
REQUEST_ADDITIONAL_TEXT("HUNT1AU", MISSION_DIALOGUE_TEXT_SLOT)
WHILE NOT HAS_ADDITIONAL_TEXT_LOADED(MISSION_TEXT_SLOT)
OR NOT HAS_ADDITIONAL_TEXT_LOADED(MISSION_DIALOGUE_TEXT_SLOT)
WAIT(0)
ENDWHILE
ENDPROC
PROC REQUEST_BINO_ASSETS()
REQUEST_MODEL(mBinoModel)
WHILE NOT HAS_MODEL_LOADED(mBinoModel)
WAIT(0)
ENDWHILE
bBinoAssetsInMem = TRUE
ENDPROC
/// PURPOSE:
/// Loads the bino model and creates the object at the hunter's location.
FUNC BOOL HAVE_BINOS_BEEN_CREATED()
IF DOES_ENTITY_EXIST(mBinos)
AND IS_ENTITY_ATTACHED_TO_ENTITY(mBinos,mHunter)
CPRINTLN(DEBUG_MISSION, "Binos ALREADY created")
RETURN TRUE
ENDIF
IF NOT bBinoAssetsInMem
REQUEST_BINO_ASSETS()
ELSE
RETURN TRUE
ENDIF
// IF NOT IS_PED_INJURED(mHunter)
// IF NOT DOES_ENTITY_EXIST(mBinos)
// mBinos = CREATE_OBJECT(mBinoModel, GET_ENTITY_COORDS(mHunter), FALSE, FALSE)
// ELSE
// IF NOT IS_ENTITY_ATTACHED_TO_ENTITY(mBinos,mHunter)
// ATTACH_ENTITY_TO_ENTITY(mBinos, mHunter, GET_PED_BONE_INDEX(mHunter, BONETAG_PH_R_HAND), <<0.0, 0.0, 0.0>>, <<0.0, 0.0, 0.0>>)
// SET_ENTITY_VISIBLE(mBinos, FALSE)
// SET_ENTITY_CAN_BE_DAMAGED(mBinos, FALSE)
// SET_MODEL_AS_NO_LONGER_NEEDED(mBinoModel)
// bBinoAssetsInMem = FALSE
// CPRINTLN(DEBUG_MISSION, "Binos created")
// RETURN TRUE
// ENDIF
// ENDIF
// ENDIF
RETURN FALSE
ENDFUNC
PROC REQUEST_DISH_ASSETS()
REQUEST_MODEL(mDishModel)
WHILE NOT HAS_MODEL_LOADED(mDishModel)
WAIT(0)
ENDWHILE
bDishAssetsInMem = TRUE
ENDPROC
FUNC BOOL IS_RANDOM_DISH_ALIVE()
iRandomDish = GET_RANDOM_INT_IN_RANGE(0, MAX_DISHES)
IF DOES_ENTITY_EXIST(mDish[iRandomDish].mObj)
IF NOT mDish[iRandomDish].bDamaged
CPRINTLN(DEBUG_MISSION, "Random Dish chosen is ", iRandomDish)
bChosenDish = TRUE
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL HAVE_DISHES_BEEN_CREATED()
IF NOT bDishAssetsInMem
REQUEST_DISH_ASSETS()
ELSE
//FAR LEFT
mDish[0].vSpawn = << 1880.9296, 3882.2424, 32.0116 >> // Far left, now covered by trees
mDish[0].fHead = 278.1801
mDish[0].fHunterAngleToFace = 250.0
// CENTER
mDish[1].vSpawn = << 1859.0547, 3858.95, 38.9254>>
mDish[1].fHead = 277.6478
mDish[1].fHunterAngleToFace = 219.6870
//FAR RIGHT
mDish[2].vSpawn = << 1818.4, 3856.1, 37.3883 >> // The awkward one near the other dishes
mDish[2].fHead = 34.0150
mDish[2].fHunterAngleToFace = 179.0284
INT i = 0
REPEAT MAX_DISHES i
CLEAR_AREA_OF_OBJECTS(mDish[i].vSpawn, 2.0)
mDish[i].mObj = CREATE_OBJECT(mDishModel, mDish[i].vSpawn)
IF DOES_ENTITY_EXIST(mDish[i].mObj)
SET_ENTITY_HEADING(mDish[i].mObj, mDish[i].fHead)
//ACTIVATE_PHYSICS(mDish[i].mObj)
SET_OBJECT_TARGETTABLE(mDish[i].mObj, FALSE)
SET_ENTITY_HEALTH(mDish[i].mObj, DISH_START_HEALTH)
//SET_ENTITY_CAN_BE_DAMAGED(mDish[i].mObj, FALSE)
//FREEZE_ENTITY_POSITION(mDish[i].mObj, TRUE)
SET_ENTITY_DYNAMIC(mDish[i].mObj, TRUE)
mDish[i].bDamaged = FALSE
mDish[i].bDamageChecked = FALSE
ENDIF
ENDREPEAT
IF DOES_ENTITY_EXIST(mDish[0].mObj)
AND DOES_ENTITY_EXIST(mDish[1].mObj)
AND DOES_ENTITY_EXIST(mDish[2].mObj)
AND IS_RANDOM_DISH_ALIVE()
SET_MODEL_AS_NO_LONGER_NEEDED(mDishModel)
CPRINTLN(DEBUG_MISSION, " * * DISHES_CREATED! * * ")
bDishAssetsInMem = FALSE
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
FUNC TYRE_CARS FILL_TYRE_CARS(MODEL_NAMES carModel, VECTOR spawnPos, FLOAT spawnHead, MODEL_NAMES pedModel, VECTOR goToPos )
TYRE_CARS newTyreCar
newTyreCar.mModel = carModel
newTyreCar.vSpawn = spawnPos
newTyreCar.fHead = spawnHead
newTyreCar.mPedModel = pedModel
newTyreCar.vGoto = goToPos
RETURN newTyreCar
ENDFUNC
/// PURPOSE:
/// Sets up the tyre cars, the car models, the spawn locations, driver ped model and the destination vector
PROC POPULATE_TYRE_CARS()
mTyreCar[0] = FILL_TYRE_CARS(HABANERO, << 1155.0581, 3533.1348, 33.9186 >>, 34.9236, A_M_Y_HIPPY_01, vTyreCarDestLeft)
mTyreCar[1] = FILL_TYRE_CARS(DUBSTA, << 1655.8027, 3492.4509, 35.5714 >>, 105.5303, A_M_M_SALTON_01, vTyreCarDestRight)
mTyreCar[2] = FILL_TYRE_CARS(PATRIOT, << 1516.0764, 3376.6038, 36.6333 >>, 359.8644, A_M_M_HILLBILLY_01, vTyreCarDestRight)
mTyreCar[3] = FILL_TYRE_CARS(REBEL, << 1140.0581, 3533.1348, 33.9186 >>, 269.0000, A_M_M_SALTON_01, vTyreCarDestLeft )
mTyreCar[4] = FILL_TYRE_CARS(SADLER, << 1508.0764, 3372.6038, 36.6333 >>, 359.8644, A_M_Y_HIPPY_01, vTyreCarDestRight)
ENDPROC
PROC REQUEST_TYRE_CAR_ASSETS()
POPULATE_TYRE_CARS()
REQUEST_MODEL(mTyreCar[0].mModel)
REQUEST_MODEL(mTyreCar[1].mModel)
REQUEST_MODEL(mTyreCar[2].mModel)
REQUEST_MODEL(mTyreCar[3].mModel)
REQUEST_MODEL(mTyreCar[4].mModel)
REQUEST_MODEL(mTyreCar[0].mPedModel)
REQUEST_MODEL(mTyreCar[1].mPedModel)
REQUEST_MODEL(mTyreCar[2].mPedModel)
REQUEST_MODEL(mTyreCar[3].mPedModel)
REQUEST_MODEL(mTyreCar[4].mPedModel)
REQUEST_MODEL(mMobileModel)
WHILE NOT HAS_MODEL_LOADED(mTyreCar[0].mModel)
OR NOT HAS_MODEL_LOADED(mTyreCar[1].mModel)
OR NOT HAS_MODEL_LOADED(mTyreCar[2].mModel)
OR NOT HAS_MODEL_LOADED(mTyreCar[3].mModel)
OR NOT HAS_MODEL_LOADED(mTyreCar[4].mModel)
OR NOT HAS_MODEL_LOADED(mTyreCar[0].mPedModel)
OR NOT HAS_MODEL_LOADED(mTyreCar[1].mPedModel)
OR NOT HAS_MODEL_LOADED(mTyreCar[2].mPedModel)
OR NOT HAS_MODEL_LOADED(mTyreCar[3].mPedModel)
OR NOT HAS_MODEL_LOADED(mTyreCar[4].mPedModel)
OR NOT HAS_MODEL_LOADED(mMobileModel)
WAIT(0)
ENDWHILE
bTyreCarAssetsInMem = TRUE
ENDPROC
PROC REQUEST_COYOTE_ASSETS()
CPRINTLN(DEBUG_MISSION, "Requesting Coyote Assets")
REQUEST_MODEL(mCoyModel)
REQUEST_MISSION_AUDIO_BANK("SCRIPT\\HUNTING_1_COYOTE_VOCALS")
WHILE NOT HAS_MODEL_LOADED(mCoyModel)
WAIT(0)
ENDWHILE
ENDPROC
PROC REQUEST_AMBIENT_CAR_ASSETS()
REQUEST_MODEL(mAmbCarModelOne)
REQUEST_MODEL(mAmbCarModelTwo)
WHILE NOT HAS_MODEL_LOADED(mAmbCarModelOne)
OR NOT HAS_MODEL_LOADED(mAmbCarModelTwo)
WAIT(0)
ENDWHILE
ENDPROC
/// PURPOSE:
/// Creates convenient cars for the player to drive back home
PROC CREATE_AMBIENT_CARS()
CPRINTLN(DEBUG_MISSION, "Creating ambient cars")
VECTOR vPos[MAX_AMBIENT_CARS]
vPos[0] = <<1815.1830, 3887.5366, 32.7844>>
vPos[1] = <<1627.5449, 3578.1245, 34.1480>>
vPos[2] = <<1574.2471, 3667.2583, 33.3797>>
vPos[3] = <<1600.8467, 3605.4497, 34.1463>>
FLOAT fHead[MAX_AMBIENT_CARS]
fHead[0] = 114.6666
fHead[1] = 57.4417
fHead[2] = 287.0027
fHead[3] = 23.9956
MODEL_NAMES mModel[MAX_AMBIENT_CARS]
mModel[0] = mAmbCarModelOne
mModel[1] = mAmbCarModelTwo
mModel[2] = mAmbCarModelOne
mModel[3] = mAmbCarModelTwo
INT i = 0
REPEAT MAX_AMBIENT_CARS i
IF WOULD_ENTITY_BE_OCCLUDED(mModel[i], vPos[i])
mAmbCar[i] = CREATE_VEHICLE(mModel[i], vPos[i], fHead[i])
ENDIF
ENDREPEAT
IF IS_ENTITY_ALIVE(mAmbCar[0])
AND IS_ENTITY_ALIVE(mAmbCar[1])
AND IS_ENTITY_ALIVE(mAmbCar[2])
AND IS_ENTITY_ALIVE(mAmbCar[3])
RELEASE_AMBIENT_CAR_ASSETS()
ENDIF
ENDPROC
FUNC INT GET_CLOSEST_AMBIENT_CAR()
INT i = 0
INT iClosestCar = -1
FLOAT fDist
FLOAT fShortestDist = 999.0
IF IS_PED_UNINJURED(mHunter)
REPEAT MAX_AMBIENT_CARS i
IF IS_ENTITY_ALIVE(mAmbCar[i])
fDist = GET_DISTANCE_BETWEEN_ENTITIES(mHunter, mAmbCar[i])
IF fDist < fShortestDist
fShortestDist = fDist
iClosestCar = i
ENDIF
ENDIF
ENDREPEAT
ENDIF
RETURN iClosestCar
ENDFUNC
/// PURPOSE:
// Count all the shots here to record accuracy.
PROC COUNT_SHOTS_FIRED()
IF IS_PED_SHOOTING(PLAYER_PED_ID())
iShotsFired++
ENDIF
ENDPROC
/// PURPOSE:
/// Checks to see if the Target (entity) was damaged by the sniper rifle
FUNC BOOL WAS_TARGET_DAMAGED_BY_SNIPER_RIFLE(ENTITY_INDEX index)
CPRINTLN(DEBUG_MISSION, "entity was damaged by sniper rifle")
IF DOES_ENTITY_EXIST(index)
VECTOR vPos
IF IS_ENTITY_ALIVE(index) OR NOT IS_ENTITY_ALIVE(index)
vPos = GET_ENTITY_COORDS(index)
ENDIF
IF IS_EXPLOSION_IN_SPHERE(EXP_TAG_DONTCARE, vPos, 20)
RETURN FALSE
ENDIF
IF IS_PED_UNINJURED(PLAYER_PED_ID())
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(index, PLAYER_PED_ID())
IF HAS_ENTITY_BEEN_DAMAGED_BY_WEAPON(index, WEAPONTYPE_SNIPERRIFLE)
OR HAS_ENTITY_BEEN_DAMAGED_BY_WEAPON(index, WEAPONTYPE_HEAVYSNIPER)
OR HAS_ENTITY_BEEN_DAMAGED_BY_WEAPON(index, WEAPONTYPE_DLC_MARKSMANRIFLE)
CPRINTLN(DEBUG_MISSION, "entity was damaged by sniper rifle")
//CLEAR_ENTITY_LAST_DAMAGE_ENTITY(index)
RETURN TRUE
ELSE
CPRINTLN(DEBUG_MISSION, "entity was damaged by non-sniper")
//CLEAR_ENTITY_LAST_DAMAGE_ENTITY(index)
RETURN FALSE
ENDIF
ELSE
CPRINTLN(DEBUG_MISSION, "Target wasn't damaged by player")
ENDIF
ENDIF
ENDIF
CPRINTLN(DEBUG_MISSION, "Target wasn't damaged by a sniper rifle...")
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Checks that the player is with in range of the hunter used when playing dialogue
FUNC BOOL ARE_PEDS_IN_CONVO_RANGE()
IF IS_PED_UNINJURED(PLAYER_PED_ID())
VECTOR vE1 = GET_ENTITY_COORDS(PLAYER_PED_ID())
IF IS_PED_UNINJURED(mHunter)
VECTOR vE2 = GET_ENTITY_COORDS(mHunter)
IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), mHunter, FALSE) <= MIN_CONVO_DIST
AND ABSF(vE1.z - vE2.z) < 1.5
RETURN TRUE
ENDIF
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
INT iCoyoteLine = 0
/// PURPOSE:
/// Checks the player is doing something and if not, prompts the hunter to speak.
PROC CHECK_INACTIVITY(SHOOT_LOCATION eLocation)
STRING sString = "NONE"
SWITCH eLocation
CASE DISH_LOC sString = "HUNT1_DIIN" BREAK
CASE TYRE_LOC sString = "HUNT_TYIN" BREAK
CASE COYOTE_LOC sString = "HUNT1_COIN" BREAK
ENDSWITCH
IF iTargetsShot < TARGET_HITS_REQUIRED
AND NOT IS_THIS_PRINT_BEING_DISPLAYED("HT_SHDISH")
AND NOT IS_THIS_PRINT_BEING_DISPLAYED("HT_SHTYRE")
AND NOT IS_THIS_PRINT_BEING_DISPLAYED("HT_SHCOY")
IF bInactiveTimerStarted
IF GET_GAME_TIMER() > iInactiveTime
// If we are at the satellite dishes
IF ARE_STRINGS_EQUAL(sString, "HUNT1_DIIN")
IF GET_RANDOM_BOOL()
OR iDishLine > 2
OR iTargetsShot = 0
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, sString, CONV_PRIORITY_MEDIUM)
bInactiveTimerStarted = FALSE
ENDIF
ELSE
SWITCH iDishLine
CASE 0
// Makes you feel alive dont it...
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_SAT", CONV_PRIORITY_MEDIUM)
bInactiveTimerStarted = FALSE
iDishLine++
ENDIF
BREAK
CASE 1
// Keeps us out of trouble eh Cletus
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_SAT2", CONV_PRIORITY_MEDIUM)
bInactiveTimerStarted = FALSE
iDishLine++
ENDIF
BREAK
CASE 2
// We're doing 'em a favour
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_SAT3", CONV_PRIORITY_MEDIUM)
bInactiveTimerStarted = FALSE
iDishLine++
ENDIF
BREAK
ENDSWITCH
ENDIF
// Inactivty lines for tyre shooting section
ELIF ARE_STRINGS_EQUAL(sString, "HUNT_TYIN")
IF GET_RANDOM_BOOL()
OR iTyreLine > 2
OR iTargetsShot = 0
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, sString, CONV_PRIORITY_MEDIUM) // Normal inactivity lines...
bInactiveTimerStarted = FALSE
ENDIF
ELSE
SWITCH iTyreLine
CASE 0
// I never knew you were such an agitator
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_BANT1", CONV_PRIORITY_MEDIUM)
bInactiveTimerStarted = FALSE
iTyreLine++
ENDIF
BREAK
CASE 1
// Sometimes I come up here with my girl
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_BANT2", CONV_PRIORITY_MEDIUM)
bInactiveTimerStarted = FALSE
iTyreLine++
ENDIF
BREAK
CASE 2
// You're right, this is surprisingly cathartic
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_BANT3", CONV_PRIORITY_MEDIUM)
bInactiveTimerStarted = FALSE
iTyreLine++
ENDIF
BREAK
ENDSWITCH
ENDIF
ELSE
IF GET_RANDOM_BOOL()
OR iCoyoteLine > 2
// OR iTargetsShot = 0
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, sString, CONV_PRIORITY_MEDIUM) // Normal inactivity lines...
bInactiveTimerStarted = FALSE
ENDIF
ELSE
SWITCH iCoyoteLine
CASE 0
// Damn varmints always gettin' at the trash and chickens...
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_COYB1", CONV_PRIORITY_MEDIUM)
bInactiveTimerStarted = FALSE
iCoyoteLine++
ENDIF
BREAK
CASE 1
// Nobody can accuse us bein' hell-raisers now, can they?
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_COYB2", CONV_PRIORITY_MEDIUM)
bInactiveTimerStarted = FALSE
iCoyoteLine++
ENDIF
BREAK
CASE 2
// Coyote tried to take off with one of my ferrets last week...
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_COYB3", CONV_PRIORITY_MEDIUM)
bInactiveTimerStarted = FALSE
iCoyoteLine++
ENDIF
BREAK
ENDSWITCH
ENDIF
ENDIF
ENDIF
ELSE
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
iInactiveDuration = GET_RANDOM_INT_IN_RANGE(10000, 15000)
iInactiveTime = GET_GAME_TIMER() + iInactiveDuration
bInactiveTimerStarted = TRUE
ENDIF
ENDIF
ENDIF
ENDPROC
// SATELLITE DISH FUNCTIONS
/// PURPOSE:
/// Adds blips to all of the satellite dish targets
PROC BLIP_DISHES()
INT i = 0
REPEAT MAX_DISHES i
IF NOT DOES_BLIP_EXIST(mDish[i].mDishBlip)
IF IS_ENTITY_ALIVE(mDish[i].mObj)
IF NOT mDish[i].bDamaged
mDish[i].mDishBlip = CREATE_BLIP_FOR_OBJECT(mDish[i].mObj)
SET_BLIP_COLOUR(mDish[i].mDishBlip, BLIP_COLOUR_RED)
//SET_ENTITY_CAN_BE_DAMAGED(mDish[i].mObj, TRUE)
ENDIF
ENDIF
ENDIF
ENDREPEAT
ENDPROC
/// PURPOSE:
/// Adds blips to all of the satellite dish targets
FUNC BOOL ARE_DISHES_BLIPPED()
INT i = 0
REPEAT MAX_DISHES i
IF DOES_BLIP_EXIST(mDish[i].mDishBlip)
RETURN TRUE
ENDIF
ENDREPEAT
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Monitors if the player has shot and missed.
PROC MONITOR_NEAR_MISSES()
INT i = 0
REPEAT MAX_DISHES i
IF IS_BULLET_IN_AREA(mDish[i].vSpawn, 10.0)
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
IF NOT IS_THIS_PRINT_BEING_DISPLAYED("HT_SHDISH") OR GET_PROFILE_SETTING(PROFILE_DISPLAY_SUBTITLES) = 0
IF NOT mDish[i].bDamaged
CPRINTLN(DEBUG_MISSION, "Sniper bullet close to undamaged dish ")
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT_MISS", CONV_PRIORITY_MEDIUM)
bInactiveTimerStarted = FALSE
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDREPEAT
IF IS_BULLET_IN_AREA(<<1793.3051, 3804.4263, 32.6374>>, 10.0) // Dishes to the right - the wrong ones.
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
IF NOT IS_THIS_PRINT_BEING_DISPLAYED("HT_SHDISH") OR GET_PROFILE_SETTING(PROFILE_DISPLAY_SUBTITLES) = 0
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT_MISS2", CONV_PRIORITY_LOW)
bInactiveTimerStarted = FALSE
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Monitors if the dish has been shot
PROC CHECK_DISH_DAMAGED(INT i)
IF DOES_ENTITY_EXIST(mDish[i].mObj) AND NOT mDish[i].bDamaged
mDish[i].iHealth = GET_ENTITY_HEALTH(mDish[i].mObj)
IF mDish[i].iHealth < DISH_START_HEALTH
KILL_ANY_CONVERSATION()
mDish[i].bDamaged = TRUE
bInactiveTimerStarted = FALSE
SAFE_REMOVE_BLIP(mDish[i].mDishBlip)
BREAK_OBJECT_FRAGMENT_CHILD(mDish[i].mObj, 1, FALSE) // 0 = Assert 1 = Dish tips over a bit 2. in game 3 = Dish falls off support
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Counts up the dishes that have been shot.
PROC COUNT_DEAD_DISHES()
INT i = 0
REPEAT MAX_DISHES i
//DRAW_MARKER(MARKER_CYLINDER, mDish[i].vSpawn, <<0.0, 0.0, 0.0>>, <<0.0, 0.0, 0.0>>, <<20, 20, 20>>, 255, 0, 128, 178)
CHECK_DISH_DAMAGED(i)
IF mDish[i].bDamaged = TRUE
IF NOT mDish[i].bDamageChecked
IF WAS_TARGET_DAMAGED_BY_SNIPER_RIFLE(mDish[i].mObj)
CLEAR_ENTITY_LAST_DAMAGE_ENTITY(mDish[i].mObj)
CPRINTLN(DEBUG_MISSION, "Dish was damaged by sniper rifle")
iTargetsShot++
ELSE
CPRINTLN(DEBUG_MISSION, "Dish was damaged by wrong weapon")
bWrongGunFail = TRUE
ENDIF
mDish[i].bDamageChecked = TRUE
ENDIF
ENDIF
ENDREPEAT
ENDPROC
/// PURPOSE:
/// Tracks if the player has damaged any of the satellite dishes before he should be.
FUNC BOOL HAS_PLAYER_DAMAGED_DISH_EARLY()
INT i = 0
REPEAT MAX_DISHES i
IF DOES_ENTITY_EXIST(mDish[i].mObj)
IF IS_BULLET_IN_AREA(mDish[i].vSpawn, 5.0)
RETURN TRUE
ENDIF
ENDIF
ENDREPEAT
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Triggers Hunter comments if the player has damaged any satellite dishes before he should.
FUNC BOOL DO_EARLY_DISH_DAMAGE_CONVO()
//Plays a random line
IF ARE_PEDS_IN_CONVO_RANGE()
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_SHB4", CONV_PRIORITY_HIGH)
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
// TYRE CAR FUNCTIONS
/// PURPOSE:
/// Prompts the hunter to tell player he hit the car, but not the tyre
PROC DO_HIT_CAR_NOT_TYRE_CONV()
IF NOT bGotCarDamageTime
IF GET_RANDOM_BOOL()
iCarDamageTime = GET_GAME_TIMER() + 1000
bGotCarDamageTime = TRUE
ENDIF
ELSE
IF GET_GAME_TIMER() > iCarDamageTime
IF ARE_PEDS_IN_CONVO_RANGE()
AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_CARH", CONV_PRIORITY_MEDIUM)
bGotCarDamageTime = FALSE
ENDIF
ENDIF
bGotCarDamageTime = FALSE
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Makes a tyre car ped flee.
PROC MAKE_PED_FLEE(INT i)
IF IS_PED_UNINJURED(mTyreCar[i].mCarPed)
CLEAR_PED_TASKS(mTyreCar[i].mCarPed)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(mTyreCar[i].mCarPed, TRUE)
IF IS_VEHICLE_OK(mTyreCar[i].mCar)
IF IS_PED_IN_VEHICLE(mTyreCar[i].mCarPed, mTyreCar[i].mCar)
TASK_VEHICLE_DRIVE_TO_COORD(mTyreCar[i].mCarPed, mTyreCar[i].mCar, mTyreCar[i].vGoto, 80.0, DRIVINGSTYLE_RACING, DUMMY_MODEL_FOR_SCRIPT, DRIVINGMODE_AVOIDCARS, DEST_RADIUS_SMALL, 2.0)
CPRINTLN(DEBUG_MISSION, " Car is fleeing")
mTyreCar[i].eCarState = TCS_FLEE_IN_CAR
ELSE
TASK_SMART_FLEE_COORD(mTyreCar[i].mCarPed, vTyreShootPos, 10000, -1)
mTyreCar[i].eCarState = TCS_FLEE_ON_FOOT
ENDIF
ENDIF
mTyreCar[i].bIsFleeing = TRUE
SET_PED_KEEP_TASK(mTyreCar[i].mCarPed, TRUE)
ELSE
mTyreCar[i].eCarState = TCS_CLEAN_UP
ENDIF
ENDPROC
/// PURPOSE:
/// Finds a road node 50m in front and 5m to the right of a vehicle
FUNC VECTOR FIND_PARKING_SPOT(VEHICLE_INDEX vh)
IF IS_VEHICLE_OK(vh)
VECTOR vTestPos = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(vh, <<5.0, 25.0, 0.0>>)
VECTOR vTestParkPos
IF GET_CLOSEST_VEHICLE_NODE(vTestPos, vTestParkPos)
IF GET_POSITION_BY_SIDE_OF_ROAD(vTestParkPos, 0, vTestParkPos)
IF NOT IS_ANY_VEHICLE_NEAR_POINT(vTestParkPos, 2)
AND NOT IS_ANY_OBJECT_NEAR_POINT(vTestParkPos, 2)
RETURN vTestParkPos
ENDIF
ENDIF
ENDIF
ENDIF
RETURN <<0.0, 0.0, 0.0>>
ENDFUNC
/// PURPOSE:
/// Puts the Tyre Cars into the state where they can be created
PROC CREATE_TYRE_CARS()
INT i = 0
REPEAT MAX_TYRE_CARS i
mTyreCar[i].eCarState = TCS_CHECK_CAN_CREATE
ENDREPEAT
ENDPROC
/// PURPOSE:
/// Puts all the current alive tyre cars into the cleanup state.
PROC CLEANUP_ACTIVE_TYRE_CARS()
CPRINTLN(DEBUG_MISSION, "CLEANUP_ACTIVE_TYRE_CARS")
INT i = 0
REPEAT MAX_TYRE_CARS i
SAFE_REMOVE_BLIP(mTyreCar[i].mCarBlip)
mTyreCar[i].eCarState = TCS_CLEAN_UP
ENDREPEAT
ENDPROC
/// PURPOSE:
/// Checks to see if the car ped has been damaged
PROC HAS_PED_BEEN_DAMAGED(INT i)
IF DOES_ENTITY_EXIST(mTyreCar[i].mCarPed)
IF IS_ENTITY_DEAD(mTyreCar[i].mCarPed) OR NOT IS_ENTITY_DEAD(mTyreCar[i].mCarPed)
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mTyreCar[i].mCarPed, PLAYER_PED_ID())
MAKE_PED_FLEE(i)
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Checks to see if the player has burst a tyre on the car
FUNC BOOL HAS_PLAYER_SHOT_TYRE(INT i)
IF DOES_ENTITY_EXIST(mTyreCar[i].mCar) AND NOT IS_ENTITY_DEAD(mTyreCar[i].mCar)
IF IS_VEHICLE_TYRE_BURST(mTyreCar[i].mCar, SC_WHEEL_CAR_FRONT_RIGHT)
mTyreCar[i].vTyrePosOffset = << 2.5, 3.0, 0.0 >>
mTyreCar[i].fTyreHeadModifier = 90.0
RETURN TRUE
ELIF IS_VEHICLE_TYRE_BURST(mTyreCar[i].mCar, SC_WHEEL_CAR_REAR_RIGHT)
mTyreCar[i].vTyrePosOffset = << 2.5, -3.0, 0.0 >>
mTyreCar[i].fTyreHeadModifier = 90.0
RETURN TRUE
ELIF IS_VEHICLE_TYRE_BURST(mTyreCar[i].mCar, SC_WHEEL_CAR_REAR_LEFT)
mTyreCar[i].vTyrePosOffset = <<-2.5, -3.0, 0.0 >>
mTyreCar[i].fTyreHeadModifier = -90.0
RETURN TRUE
ELIF IS_VEHICLE_TYRE_BURST(mTyreCar[i].mCar, SC_WHEEL_CAR_FRONT_LEFT)
mTyreCar[i].vTyrePosOffset = <<-2.5, 3.0, 0.0 >>
mTyreCar[i].fTyreHeadModifier = -90.0
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Adds a long range blip to the specified car.
PROC BLIP_TYRE_CAR(INT i)
mTyreCar[i].mCarBlip = CREATE_VEHICLE_BLIP(mTyreCar[i].mCar, FALSE)
IF IS_VEHICLE_OK(mTyreCar[i].mCar) AND NOT mTyreCar[i].bTyreHit
SET_ENTITY_CAN_BE_DAMAGED(mTyreCar[i].mCar, TRUE)
SET_BLIP_MARKER_LONG_DISTANCE(mTyreCar[i].mCarBlip, TRUE)
ENDIF
ENDPROC
/// PURPOSE:
/// Removes a car blip for a specific car and makes it invunerable
PROC REMOVE_TYRE_CAR_BLIP(INT i)
//CPRINTLN(DEBUG_MISSION, "REMOVING CAR BLIP")
SAFE_REMOVE_BLIP(mTyreCar[i].mCarBlip)
IF NOT IS_ENTITY_DEAD(mTyreCar[i].mCar)
SET_ENTITY_CAN_BE_DAMAGED(mTyreCar[i].mCar, FALSE)
ENDIF
IF NOT mTyreCar[i].bReducedCarsInWorld
iCarsInWorld--
mTyreCar[i].bReducedCarsInWorld = TRUE
ENDIF
ENDPROC
/// PURPOSE:
/// Add or removes car blips based on the players actions.
PROC CHECK_TYRE_CAR_BLIP(INT i)
//CPRINTLN(DEBUG_MISSION, "CHECK_TYRE_CAR_BLIP")
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), vTyreShootAreaA, vTyreShootAreaB, TYRE_AREA_WIDTH, FALSE)
AND bCanBlipTyreCars
IF DOES_ENTITY_EXIST(mTyreCar[i].mCarPed)
AND IS_PLAYER_USING_SNIPER_RIFLE()
AND IS_ENTITY_IN_ANGLED_AREA(mTyreCar[i].mCarPed, vTyreCarDestLeft, vTyreCarDestRight, TYRE_CAR_ROAD_WIDTH, FALSE, FALSE, TM_ANY)
AND NOT DOES_BLIP_EXIST(mTyreCar[i].mCarBlip)
AND NOT mTyreCar[i].bTyreHit // So we don't re-blip an already hit car
BLIP_TYRE_CAR(i)
ENDIF
ELSE
IF DOES_BLIP_EXIST(mTyreCar[i].mCarBlip)
//CPRINTLN(DEBUG_MISSION, "Remove Tyre Car Blip called from check tyre car blip")
REMOVE_TYRE_CAR_BLIP(i)
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Tells the a tyre car ped to get in the tyre car and flee [TODO] Might not be needed
PROC RETURN_TO_CAR_AND_FLEE(INT i)
PED_INDEX mPed = mTyreCar[i].mCarPed
IF IS_PED_UNINJURED(mPed)
IF IS_VEHICLE_OK(mTyreCar[i].mCar)
CLEAR_PED_TASKS(mPed)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(mPed, TRUE)
OPEN_SEQUENCE_TASK(mTyreCar[i].mSeq)
TASK_ENTER_VEHICLE(NULL, mTyreCar[i].mCar, 60000, VS_DRIVER, PEDMOVEBLENDRATIO_WALK)
TASK_VEHICLE_DRIVE_WANDER(NULL, mTyreCar[i].mCar, 60.0, DRIVINGMODE_AVOIDCARS_RECKLESS)
CLOSE_SEQUENCE_TASK(mTyreCar[i].mSeq)
TASK_PERFORM_SEQUENCE(mPed, mTyreCar[i].mSeq)
SET_PED_KEEP_TASK(mPed, TRUE)
CLEAR_SEQUENCE_TASK(mTyreCar[i].mSeq)
ENDIF
mTyreCar[i].bIsFleeing = TRUE
ENDIF
ENDPROC
// TYRE CAR STATES
/// PURPOSE:
/// The tyre car states
PROC CHECK_CAR_STATES()
INT i = 0
VECTOR vTempParkingPos = <<0.0, 0.0, 0.0>>
VECTOR vPos
REPEAT MAX_TYRE_CARS i
IF mTyreCar[i].eCarState <> TCS_NULL
HAS_PED_BEEN_DAMAGED(i)
//CHECK_TYRE_CAR_BLIP(i) // Don't blip the cars anymore B*1170631
IF DOES_ENTITY_EXIST(mTyreCar[i].mCar)
IF NOT IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), vTyreShootAreaA, vTyreShootAreaB, TYRE_AREA_WIDTH, FALSE)
IF NOT bShotFromWrongPlace
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mTyreCar[i].mCar, PLAYER_PED_ID())
//CPRINTLN(DEBUG_MISSION, "bShotFromWrongPlace = TRUE")
bShotFromWrongPlace = TRUE
SET_MISSION_FAILED_REASON(FAIL_BAD_SHOT)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
SWITCH mTyreCar[i].eCarState
CASE TCS_NULL
BREAK
CASE TCS_CHECK_CAN_CREATE
IF iCarsInWorld < MAX_TYRE_CARS_AT_ONCE
AND iTargetsShot < TARGET_HITS_REQUIRED
//CPRINTLN(DEBUG_MISSION, "Ok to create more Tyre Cars")
mTyreCar[i].eCarState = TCS_CREATE
ENDIF
BREAK
CASE TCS_CREATE
mTyreCar[i].iRand = GET_RANDOM_INT_IN_RANGE(0, MAX_TYRE_CARS)
//CPRINTLN(DEBUG_MISSION, " mTyreCar[i].iRand = ", mTyreCar[i].iRand)
IF NOT IS_ANY_VEHICLE_NEAR_POINT(mTyreCar[mTyreCar[i].iRand].vSpawn, 4.5) AND iCarsInWorld < MAX_TYRE_CARS_AT_ONCE AND WOULD_ENTITY_BE_OCCLUDED(mTyreCar[i].mModel, mTyreCar[i].vSpawn)
mTyreCar[i].mCar = CREATE_VEHICLE(mTyreCar[i].mModel, mTyreCar[i].vSpawn, mTyreCar[i].fHead)
IF DOES_ENTITY_EXIST(mTyreCar[i].mCar)
AND NOT IS_ENTITY_DEAD(mTyreCar[i].mCar)
SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(mTyreCar[i].mCar, TRUE)
SET_VEHICLE_TYRES_CAN_BURST(mTyreCar[i].mCar, TRUE)
mTyreCar[i].iRand = GET_RANDOM_INT_IN_RANGE(0, MAX_TYRE_CARS)
mTyreCar[i].mCarPed = CREATE_PED_INSIDE_VEHICLE(mTyreCar[i].mCar, PEDTYPE_MISSION, mTyreCar[mTyreCar[i].iRand].mPedModel)
IF DOES_ENTITY_EXIST(mTyreCar[i].mCarPed)
mTyreCar[i].mMobileObj = CREATE_OBJECT(mMobileModel, mTyreCar[i].vSpawn)
IF DOES_ENTITY_EXIST(mTyreCar[i].mMobileObj)
ATTACH_ENTITY_TO_ENTITY(mTyreCar[i].mMobileObj, mTyreCar[i].mCarPed, GET_PED_BONE_INDEX(mTyreCar[i].mCarPed, BONETAG_PH_R_HAND), <<0.0, 0.0, 0.0>>, <<0.0, 0.0, 0.0>>)
SET_ENTITY_VISIBLE(mTyreCar[i].mMobileObj, FALSE)
SET_ENTITY_LOAD_COLLISION_FLAG(mTyreCar[i].mCarPed, TRUE)
SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(mTyreCar[i].mCarPed, TRUE)
mTyreCar[i].bIsFleeing = FALSE
mTyreCar[i].bTyreHit = FALSE
mTyreCar[i].bReducedCarsInWorld = FALSE
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(mTyreCar[i].mCarPed, TRUE)
TASK_VEHICLE_DRIVE_TO_COORD(mTyreCar[i].mCarPed, mTyreCar[i].mCar, mTyreCar[i].vGoto, 8.0, DRIVINGSTYLE_ACCURATE, DUMMY_MODEL_FOR_SCRIPT, DRIVINGMODE_AVOIDCARS_STOPFORPEDS_OBEYLIGHTS, DEST_RADIUS_SMALL, 2.0)
iCarsInWorld++
//CPRINTLN(DEBUG_MISSION, "Car Created!")
mTyreCar[i].eCarState = TCS_CHECK_FOR_DAMGAGE
ENDIF
ENDIF
ENDIF
ENDIF
BREAK
CASE TCS_CHECK_FOR_DAMGAGE
IF IS_PED_UNINJURED(mTyreCar[i].mCarPed) AND IS_VEHICLE_OK(mTyreCar[i].mCar)
// Have we made it out?
IF NOT IS_ENTITY_AT_COORD(mTyreCar[i].mCar, mTyreCar[i].vGoto, <<DEST_RADIUS_BIG, DEST_RADIUS_BIG, DEST_RADIUS_BIG>>, FALSE, FALSE)
IF NOT IsPedPerformingTask(mTyreCar[i].mCarPed, SCRIPT_TASK_VEHICLE_DRIVE_TO_COORD)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(mTyreCar[i].mCarPed, TRUE)
TASK_VEHICLE_DRIVE_TO_COORD(mTyreCar[i].mCarPed, mTyreCar[i].mCar, mTyreCar[i].vGoto, 8.0, DRIVINGSTYLE_ACCURATE, DUMMY_MODEL_FOR_SCRIPT, DRIVINGMODE_AVOIDCARS_STOPFORPEDS_OBEYLIGHTS, DEST_RADIUS_SMALL, 2.0)
ENDIF
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mTyreCar[i].mCar, PLAYER_PED_ID())
IF WAS_TARGET_DAMAGED_BY_SNIPER_RIFLE(mTyreCar[i].mCar)
IF HAS_PLAYER_SHOT_TYRE(i)
IF NOT mTyreCar[i].bTyreHit
//CPRINTLN(DEBUG_MISSION, "Tyre Hit in TCS_CHECK_FOR_DAMGAGE")
iTargetsShot++
bInactiveTimerStarted = FALSE
// iTargetsShot = 3 // HACK
mTyreCar[i].bTyreHit = TRUE
REMOVE_TYRE_CAR_BLIP(i)
CLEAR_ENTITY_LAST_DAMAGE_ENTITY(mTyreCar[i].mCar)
mTyreCar[i].eCarState = TCS_STOP_CAR
ENDIF
ELSE
bInactiveTimerStarted = FALSE
//CPRINTLN(DEBUG_MISSION, "player missed tyre")
DO_HIT_CAR_NOT_TYRE_CONV()
CLEAR_ENTITY_LAST_DAMAGE_ENTITY(mTyreCar[i].mCar)
MAKE_PED_FLEE(i)
ENDIF
ELSE
bWrongGunFail = TRUE
mTyreCar[i].eCarState = TCS_CLEAN_UP
ENDIF
ELSE
IF NOT bMissedTyreCar
IF IS_BULLET_IN_AREA(GET_ENTITY_COORDS(mTyreCar[i].mCar), 5)
bMissedTyreCar = TRUE
ENDIF
ENDIF
ENDIF
ELSE
CLEAR_PED_TASKS(mTyreCar[i].mCarPed)
SET_VEHICLE_TYRES_CAN_BURST(mTyreCar[i].mCar, FALSE)
TASK_VEHICLE_DRIVE_WANDER(mTyreCar[i].mCarPed, mTyreCar[i].mCar, 8.0, DRIVINGMODE_AVOIDCARS_STOPFORPEDS_OBEYLIGHTS)
SET_PED_KEEP_TASK(mTyreCar[i].mCarPed, TRUE)
mTyreCar[i].eCarState = TCS_CLEAN_UP
ENDIF
ELSE
mTyreCar[i].eCarState = TCS_CLEAN_UP
ENDIF
BREAK
// CAN ONLY GET HERE IF TYRE HAS BEEN SHOT
CASE TCS_STOP_CAR
IF IS_PED_UNINJURED(mTyreCar[i].mCarPed) AND IS_VEHICLE_OK(mTyreCar[i].mCar)
CLEAR_PED_TASKS(mTyreCar[i].mCarPed)
vTempParkingPos = FIND_PARKING_SPOT(mTyreCar[i].mCar )
IF NOT ARE_VECTORS_EQUAL(vTempParkingPos, <<0.0, 0.0, 0.0>>)
TASK_VEHICLE_PARK(mTyreCar[i].mCarPed, mTyreCar[i].mCar, vTempParkingPos, GET_ENTITY_HEADING(mTyreCar[i].mCar), PARK_TYPE_PULL_OVER, 270.0, TRUE)
ELSE
IF GET_RANDOM_BOOL()
TASK_VEHICLE_TEMP_ACTION(mTyreCar[i].mCarPed, mTyreCar[i].mCar, TEMPACT_HANDBRAKETURNRIGHT, 2000)
ELSE
TASK_VEHICLE_TEMP_ACTION(mTyreCar[i].mCarPed, mTyreCar[i].mCar, TEMPACT_HANDBRAKETURNLEFT, 2000)
ENDIF
ENDIF
KILL_ANY_CONVERSATION()
mTyreCar[i].eCarState = TCS_WAIT_FOR_CAR_TO_STOP
ELSE
mTyreCar[i].eCarState = TCS_CLEAN_UP
ENDIF
BREAK
CASE TCS_WAIT_FOR_CAR_TO_STOP
IF IS_ENTITY_ALIVE(mTyreCar[i].mCar) AND IS_PED_UNINJURED(mTyreCar[i].mCarPed) AND NOT HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mTyreCar[i].mCar, PLAYER_PED_ID())
IF IS_VEHICLE_STOPPED(mTyreCar[i].mCar)
CLEAR_PED_TASKS(mTyreCar[i].mCarPed)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(mTyreCar[i].mCarPed, TRUE)
IF NOT HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mTyreCar[i].mCar, PLAYER_PED_ID()) OR NOT mTyreCar[i].bIsFleeing
TASK_LEAVE_VEHICLE(mTyreCar[i].mCarPed, mTyreCar[i].mCar, ECF_RESUME_IF_INTERRUPTED)
ELSE
MAKE_PED_FLEE(i)
ENDIF
mTyreCar[i].eCarState = TCS_LEAVE_CAR
ENDIF
ELSE
mTyreCar[i].eCarState = TCS_CLEAN_UP
ENDIF
BREAK
CASE TCS_LEAVE_CAR
IF IS_PED_UNINJURED(mTyreCar[i].mCarPed) AND NOT HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mTyreCar[i].mCar, PLAYER_PED_ID())
IF NOT IS_PED_IN_ANY_VEHICLE(mTyreCar[i].mCarPed)
IF NOT HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mTyreCar[i].mCar, PLAYER_PED_ID()) OR NOT mTyreCar[i].bIsFleeing
mTyreCar[i].eCarState = TCS_GET_TO_INSPECTION_POINT
ELSE
MAKE_PED_FLEE(i)
ENDIF
ELSE
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mTyreCar[i].mCar, PLAYER_PED_ID())
MAKE_PED_FLEE(i)
ENDIF
ENDIF
ELSE
mTyreCar[i].eCarState = TCS_CLEAN_UP
ENDIF
BREAK
CASE TCS_GET_TO_INSPECTION_POINT
IF IS_PED_UNINJURED(mTyreCar[i].mCarPed) AND NOT HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mTyreCar[i].mCar, PLAYER_PED_ID()) AND IS_VEHICLE_OK(mTyreCar[i].mCar)
vPos = GET_ENTITY_COORDS(mTyreCar[i].mCarPed)
IF NOT IS_PED_IN_ANY_VEHICLE(mTyreCar[i].mCarPed)
IF NOT HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mTyreCar[i].mCar, PLAYER_PED_ID())
AND NOT IS_BULLET_IN_AREA(vPos, 3)
mTyreCar[i].vTyreInspectPos = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(mTyreCar[i].mCar, mTyreCar[i].vTyrePosOffset)
mTyreCar[i].fTyreInspectHead = GET_ENTITY_HEADING(mTyreCar[i].mCar) + mTyreCar[i].fTyreHeadModifier
CLEAR_PED_TASKS(mTyreCar[i].mCarPed)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(mTyreCar[i].mCarPed, TRUE)
TASK_FOLLOW_NAV_MESH_TO_COORD(mTyreCar[i].mCarPed, mTyreCar[i].vTyreInspectPos, PEDMOVEBLENDRATIO_WALK, DEFAULT_TIME_NEVER_WARP, DEFAULT_NAVMESH_RADIUS,ENAV_DEFAULT, mTyreCar[i].fTyreInspectHead)
mTyreCar[i].eCarState = TCS_GETTING_TO_INSPECTION_POINT
ELSE
MAKE_PED_FLEE(i)
ENDIF
ELSE
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mTyreCar[i].mCar, PLAYER_PED_ID())
MAKE_PED_FLEE(i)
ENDIF
ENDIF
ELSE
mTyreCar[i].eCarState = TCS_CLEAN_UP
ENDIF
BREAK
CASE TCS_GETTING_TO_INSPECTION_POINT
IF IS_PED_UNINJURED(mTyreCar[i].mCarPed) AND NOT HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mTyreCar[i].mCar, PLAYER_PED_ID())
vPos = GET_ENTITY_COORDS(mTyreCar[i].mCarPed)
IF NOT HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mTyreCar[i].mCar, PLAYER_PED_ID())
AND NOT IS_BULLET_IN_AREA(vPos, 3)
IF IS_ENTITY_AT_COORD(mTyreCar[i].mCarPed, mTyreCar[i].vTyreInspectPos, <<1.0, 1.0, 1.0>>, FALSE, FALSE, TM_ON_FOOT)
CLEAR_PED_TASKS(mTyreCar[i].mCarPed)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(mTyreCar[i].mCarPed, TRUE)
TASK_TURN_PED_TO_FACE_ENTITY(mTyreCar[i].mCarPed, mTyreCar[i].mCar)
mTyreCar[i].eCarState = TCS_TURN_TO_FACE_TYRE
ENDIF
ELSE
MAKE_PED_FLEE(i)
ENDIF
ELSE
mTyreCar[i].eCarState = TCS_CLEAN_UP
ENDIF
BREAK
CASE TCS_TURN_TO_FACE_TYRE
IF IS_PED_UNINJURED(mTyreCar[i].mCarPed) AND NOT HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mTyreCar[i].mCar, PLAYER_PED_ID())
vPos = GET_ENTITY_COORDS(mTyreCar[i].mCarPed)
IF NOT HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mTyreCar[i].mCar, PLAYER_PED_ID())
AND NOT IS_BULLET_IN_AREA(vPos, 3)
mTyreCar[i].mTaskStatus = GET_SCRIPT_TASK_STATUS(mTyreCar[i].mCarPed, SCRIPT_TASK_TURN_PED_TO_FACE_ENTITY)
IF mTyreCar[i].mTaskStatus = FINISHED_TASK
mTyreCar[i].eCarState = TCS_LOAD_INSPECT_DAMAGE_ANIMS
ENDIF
ELSE
MAKE_PED_FLEE(i)
mTyreCar[i].eCarState = TCS_FLEE_ON_FOOT
ENDIF
ELSE
mTyreCar[i].eCarState = TCS_CLEAN_UP
ENDIF
BREAK
CASE TCS_LOAD_INSPECT_DAMAGE_ANIMS
IF IS_PED_UNINJURED(mTyreCar[i].mCarPed) AND NOT HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mTyreCar[i].mCar, PLAYER_PED_ID())
vPos = GET_ENTITY_COORDS(mTyreCar[i].mCarPed)
IF NOT HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mTyreCar[i].mCar, PLAYER_PED_ID())
AND NOT IS_BULLET_IN_AREA(vPos, 3)
OPEN_SEQUENCE_TASK(mTyreCar[i].mSeq)
TASK_PLAY_ANIM(NULL, "ODDJOBS@HUNTER", "enter")
TASK_PLAY_ANIM(NULL, "ODDJOBS@HUNTER", "idle_a", NORMAL_BLEND_IN, NORMAL_BLEND_OUT)
TASK_PLAY_ANIM(NULL, "ODDJOBS@HUNTER", "exit")
TASK_PLAY_ANIM(NULL, "ODDJOBS@HUNTER", "enter_call")
TASK_PLAY_ANIM(NULL, "ODDJOBS@HUNTER", "idle_a_call", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_LOOPING)
CLOSE_SEQUENCE_TASK(mTyreCar[i].mSeq)
TASK_PERFORM_SEQUENCE(mTyreCar[i].mCarPed, mTyreCar[i].mSeq)
CLEAR_SEQUENCE_TASK(mTyreCar[i].mSeq)
mTyreCar[i].iCallDuration = GET_GAME_TIMER() + 20000
mTyreCar[i].eCarState = TCS_INSPECT_DAMAGE
ELSE
MAKE_PED_FLEE(i)
mTyreCar[i].eCarState = TCS_FLEE_ON_FOOT
ENDIF
ELSE
mTyreCar[i].eCarState = TCS_CLEAN_UP
ENDIF
BREAK
CASE TCS_INSPECT_DAMAGE
IF IS_PED_UNINJURED(mTyreCar[i].mCarPed) AND NOT HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mTyreCar[i].mCar, PLAYER_PED_ID())
vPos = GET_ENTITY_COORDS(mTyreCar[i].mCarPed)
IF NOT HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mTyreCar[i].mCar, PLAYER_PED_ID())
AND NOT IS_BULLET_IN_AREA(vPos, 3)
IF GET_GAME_TIMER() > mTyreCar[i].iCallDuration
IF IS_ENTITY_VISIBLE(mTyreCar[i].mMobileObj)
SET_ENTITY_VISIBLE(mTyreCar[i].mMobileObj, FALSE)
ELSE
CLEAR_PED_TASKS(mTyreCar[i].mCarPed)
RETURN_TO_CAR_AND_FLEE(i)
mTyreCar[i].eCarState = TCS_CLEAN_UP
ENDIF
ELSE
IF IS_ENTITY_PLAYING_ANIM(mTyreCar[i].mCarPed, "ODDJOBS@HUNTER", "enter_call")
AND NOT IS_ENTITY_VISIBLE(mTyreCar[i].mMobileObj)
SET_ENTITY_VISIBLE(mTyreCar[i].mMobileObj, TRUE)
ENDIF
ENDIF
ELSE
CLEAR_PED_TASKS(mTyreCar[i].mCarPed)
MAKE_PED_FLEE(i)
ENDIF
ELSE
CLEAR_PED_TASKS(mTyreCar[i].mCarPed)
MAKE_PED_FLEE(i)
//SK_PRINT ("TCS - PED OR CAR EITHER DEAD OR NON-EXISTENT")
mTyreCar[i].eCarState = TCS_CLEAN_UP
ENDIF
BREAK
CASE TCS_FLEE_IN_CAR
IF IS_PED_UNINJURED(mTyreCar[i].mCarPed) AND IS_VEHICLE_OK(mTyreCar[i].mCar)
IF NOT IS_ENTITY_AT_COORD(mTyreCar[i].mCar, mTyreCar[i].vGoto, <<DEST_RADIUS_BIG, DEST_RADIUS_BIG, DEST_RADIUS_BIG>>, FALSE, FALSE)
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mTyreCar[i].mCar, PLAYER_PED_ID())
IF WAS_TARGET_DAMAGED_BY_SNIPER_RIFLE(mTyreCar[i].mCar)
IF HAS_PLAYER_SHOT_TYRE(i)
//CPRINTLN(DEBUG_MISSION, "Tyre shot")
iTargetsShot++
bInactiveTimerStarted = FALSE
mTyreCar[i].bTyreHit = TRUE
REMOVE_TYRE_CAR_BLIP(i)
CLEAR_ENTITY_LAST_DAMAGE_ENTITY(mTyreCar[i].mCar)
mTyreCar[i].eCarState = TCS_STOP_CAR
ELSE
DO_HIT_CAR_NOT_TYRE_CONV()
CLEAR_ENTITY_LAST_DAMAGE_ENTITY(mTyreCar[i].mCar)
ENDIF
ELSE
bWrongGunFail = TRUE
ENDIF
ENDIF
ELSE
CLEAR_PED_TASKS(mTyreCar[i].mCarPed)
SET_VEHICLE_TYRES_CAN_BURST(mTyreCar[i].mCar, FALSE)
TASK_VEHICLE_DRIVE_WANDER(mTyreCar[i].mCarPed, mTyreCar[i].mCar, 8.0, DRIVINGMODE_AVOIDCARS_STOPFORPEDS_OBEYLIGHTS)
SET_PED_KEEP_TASK(mTyreCar[i].mCarPed, TRUE)
mTyreCar[i].eCarState = TCS_CLEAN_UP
ENDIF
ELSE
mTyreCar[i].eCarState = TCS_CLEAN_UP
ENDIF
BREAK
CASE TCS_FLEE_ON_FOOT
IF NOT HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mTyreCar[i].mCar, PLAYER_PED_ID())
IF GET_DISTANCE_BETWEEN_COORDS (GET_ENTITY_COORDS(mTyreCar[i].mCar, FALSE), GET_ENTITY_COORDS(mTyreCar[i].mCarPed), FALSE) > 100.0
mTyreCar[i].eCarState = TCS_CLEAN_UP
ENDIF
ELSE
mTyreCar[i].eCarState = TCS_CLEAN_UP
ENDIF
BREAK
CASE TCS_CLEAN_UP
//CPRINTLN(DEBUG_MISSION, "Remove Tyre Blip callled from clean up")
REMOVE_TYRE_CAR_BLIP(i)
IF DOES_ENTITY_EXIST(mTyreCar[i].mCarPed)
IF NOT IS_ENTITY_DEAD(mTyreCar[i].mCarPed)
SET_PED_KEEP_TASK(mTyreCar[i].mCarPed, TRUE)
ENDIF
SAFE_RELEASE_PED(mTyreCar[i].mCarPed)
ENDIF
IF DOES_ENTITY_EXIST(mTyreCar[i].mCar)
SAFE_RELEASE_VEHICLE(mTyreCar[i].mCar)
ENDIF
mTyreCar[i].eCarState = TCS_CHECK_CAN_CREATE
BREAK
ENDSWITCH
IF IS_VEHICLE_OK(mTyreCar[i].mCar) AND IS_PED_UNINJURED(mTyreCar[i].mCarPed)
IF GET_DISTANCE_BETWEEN_COORDS(vRoadPos, GET_ENTITY_COORDS(mTyreCar[i].mCar)) > 450
mTyreCar[i].eCarState = TCS_CLEAN_UP
ENDIF
ENDIF
ENDREPEAT
ENDPROC
// COYOTE FUNCTIONS
/// PURPOSE:
/// Kicks off the "Pack" state machine for each of the coyote packs.
PROC CREATE_COYOTES()
CPRINTLN(DEBUG_MISSION, "Creating Coyotes")
// COYOTES PACK
mPack[0].mCoyote[0].ePackID = CP_LEADER
mPack[0].mCoyote[1].ePackID = CP_FOLLOWER
mPack[0].mCoyote[2].ePackID = CP_FOLLOWER
mPack[1].mCoyote[0].ePackID = CP_LEADER
mPack[1].mCoyote[1].ePackID = CP_FOLLOWER
mPack[1].mCoyote[2].ePackID = CP_FOLLOWER
// GRAZING AREAS FOR COYOTES
vGrazePos[0] = << 1649.8706, 3537.3772, 35.1815 >>
vGrazePos[1] = << 1665.3329, 3530.1526, 35.4407 >>
vGrazePos[2] = << 1656.2551, 3529.3284, 35.4361 >>
vGrazePos[3] = << 1666.9313, 3520.0317, 35.4593 >>
vGrazePos[4] = << 1663.5317, 3499.7029, 35.3817 >>
vGrazePos[5] = << 1654.5912, 3509.7827, 35.1706 >>
vGrazePos[6] = << 1642.8019, 3516.5681, 35.5786 >>
vGrazePos[7] = << 1653.0293, 3510.4785, 35.3398 >>
INT i = 0
REPEAT MAX_PACKS i
mPack[i].ePackState = PS_SPAWN_IN
ENDREPEAT
ENDPROC
/// PURPOSE:
/// Makes sure the coyote blips are added, scaled correctly and removed on death
PROC CHECK_COYOTE_BLIPS(INT i, INT j)
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), vCoyoteShootAreaA, vCoyoteShootAreaB, COYOTE_AREA_WIDTH, FALSE)
AND DOES_ENTITY_EXIST(mPack[i].mCoyote[j].mCoyPed)
AND NOT IS_ENTITY_DEAD(mPack[i].mCoyote[j].mCoyPed)
AND bCanAddCoyoteBlips
AND iTargetsShot < TARGET_HITS_REQUIRED
IF NOT DOES_BLIP_EXIST(mPack[i].mCoyote[j].mCoyBlip)
mPack[i].mCoyote[j].mCoyBlip = CREATE_PED_BLIP(mPack[i].mCoyote[j].mCoyPed)
IF DOES_BLIP_EXIST(mPack[i].mCoyote[j].mCoyBlip)
SET_BLIP_SCALE(mPack[i].mCoyote[j].mCoyBlip, BLIP_SIZE_PED)
ENDIF
IF NOT IS_ENTITY_DEAD(mPack[i].mCoyote[j].mCoyPed)
SET_ENTITY_CAN_BE_DAMAGED(mPack[i].mCoyote[j].mCoyPed, TRUE)
ENDIF
ENDIF
ELSE
SAFE_REMOVE_BLIP(mPack[i].mCoyote[j].mCoyBlip)
ENDIF
ENDPROC
/// PURPOSE:
/// Gets the coyotes to flee from their spawn point.
PROC GIVE_COYOTE_FLEE_ORDER(INT i, INT j)
IF DOES_ENTITY_EXIST(mPack[i].mCoyote[j].mCoyPed)
CLEAR_PED_TASKS(mPack[i].mCoyote[j].mCoyPed)
IF bDeathInPack[i]
CPRINTLN(DEBUG_MISSION, "GIVE_COYOTE_FLEE_ORDER bDeathInPack = TRUE")
TASK_SMART_FLEE_COORD(mPack[i].mCoyote[j].mCoyPed, vDeath[i], 50.0, -1, FALSE)
ELSE
CPRINTLN(DEBUG_MISSION, "GIVE_COYOTE_FLEE_ORDER bDeathInPack = FALSE")
TASK_SMART_FLEE_COORD(mPack[i].mCoyote[j].mCoyPed, mPack[i].mCoyote[j].vBulletLoc, 50.0, -1, FALSE)
ENDIF
SET_PED_KEEP_TASK(mPack[i].mCoyote[j].mCoyPed, TRUE)
ENDIF
ENDPROC
/// PURPOSE:
/// Checks if the player has killed more than one coyote with one bullet
PROC CHECK_MULTI_COYOTE_KILL(INT i)
PED_INDEX mPed
INT j, c, iDeadCoyoteInFrame = 0
//IF IS_PED_UNINJURED(mHunter) AND IS_PED_UNINJURED(PLAYER_PED_ID())
IF Has_Ped_Been_Killed()
CPRINTLN(DEBUG_MISSION, "A coyote has died!")
REPEAT Get_Number_Of_Ped_Killed_Events() j
mPed = GET_PED_INDEX_FROM_ENTITY_INDEX(Get_Index_Of_Killed_Ped(j))
REPEAT MAX_PACK_MEMBERS c
IF mPed = mPack[i].mCoyote[c].mCoyPed
IF WAS_TARGET_DAMAGED_BY_SNIPER_RIFLE(mPed)
iDeadCoyoteInFrame++
CPRINTLN(DEBUG_MISSION, "iDeadCoyoteInFrame is ", iDeadCoyoteInFrame)
ENDIF
ENDIF
ENDREPEAT
ENDREPEAT
IF iDeadCoyoteInFrame > 1 AND NOT bBonusComment
CPRINTLN(DEBUG_MISSION, "MORE THAN ONE IN A SINGLE FRAME")
INFORM_STAT_SYSTEM_OF_BOOL_STAT_HAPPENED(HU1_TWO_COYOTES_KILLED_IN_ONE)
IF PLAY_SINGLE_LINE_FROM_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_KILL", "HUNT1_KILL_1", CONV_PRIORITY_MEDIUM)
bBonusComment = TRUE
ENDIF
ENDIF
ENDIF
//ENDIF
ENDPROC
/// PURPOSE:
/// Makes the coyote howl occasionally.
PROC HANDLE_COYOTE_SOUNDS(INT i, INT j)
IF GET_RANDOM_BOOL()
PLAY_SOUND_FROM_ENTITY(-1, "COYOTE_BARK_MASTER", mPack[i].mCoyote[j].mCoyPed)
ELSE
PLAY_SOUND_FROM_ENTITY(-1, "COYOTE_CRY_MASTER", mPack[i].mCoyote[j].mCoyPed)
ENDIF
ENDPROC
/// PURPOSE:
/// Spawns in a coyote pack leader.
PROC SPAWN_LEADER_COYOTE(INT i, INT j)
IF NOT IS_PED_UNINJURED(mPack[i].mCoyote[j].mCoyPed)
mPack[i].mCoyote[j].iRandSpawn = GET_RANDOM_INT_IN_RANGE(0, MAX_GRAZE_AREAS)
IF NOT bIsBooked[mPack[i].mCoyote[j].iRandSpawn]
mPack[i].mCoyote[j].fRandHead = GET_RANDOM_FLOAT_IN_RANGE(0.0, 359.9)
mPack[i].mCoyote[j].mCoyPed = CREATE_PED(PEDTYPE_MISSION, mCoyModel, vGrazePos[mPack[i].mCoyote[j].iRandSpawn], mPack[i].mCoyote[j].fRandHead)
IF DOES_ENTITY_EXIST(mPack[i].mCoyote[j].mCoyPed)
SET_ENTITY_HEALTH(mPack[i].mCoyote[j].mCoyPed, 100)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(mPack[i].mCoyote[j].mCoyPed, TRUE)
mPack[i].mCoyote[j].iCurSpawn = mPack[i].mCoyote[j].iRandSpawn
bIsBooked[mPack[i].mCoyote[j].iCurSpawn] = TRUE
mPack[i].mCoyote[j].eCoyState = CS_CALC_RANDOM_WAIT_TIME
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Spawns in a coyote pack follower.
PROC SPAWN_FOLLOWER_COYOTE(INT i, INT j)
IF NOT IS_PED_UNINJURED(mPack[i].mCoyote[j].mCoyPed)
VECTOR vSpawn
IF j = 1
vSpawn = vGrazePos[mPack[i].mCoyote[0].iCurSpawn] + vLeftFollower
mPack[i].mCoyote[j].vFollowOffset = vLeftFollower
ELIF j = 2
vSpawn = vGrazePos[mPack[i].mCoyote[0].iCurSpawn] + vRightFollower
mPack[i].mCoyote[j].vFollowOffset = vRightFollower
ENDIF
mPack[i].mCoyote[j].mCoyPed = CREATE_PED(PEDTYPE_MISSION, mCoyModel, vSpawn, GET_RANDOM_FLOAT_IN_RANGE(0.0, 359.9))
IF DOES_ENTITY_EXIST(mPack[i].mCoyote[j].mCoyPed)
SET_ENTITY_HEALTH(mPack[i].mCoyote[j].mCoyPed, 100)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(mPack[i].mCoyote[j].mCoyPed, TRUE)
mPack[i].mCoyote[j].eCoyState = CS_FOLLOW_LEADER
ENDIF
ENDIF
ENDPROC
FUNC VECTOR GET_DESTINATION_RADIUS(INT iPack)
VECTOR vRadius
INT i = 0
REPEAT MAX_PACK_MEMBERS i
IF mPack[iPack].mCoyote[i].ePackID = CP_LEADER
vRadius = <<0.5, 0.5, 0.5>>
ELSE
vRadius = <<1.5, 1.5, 1.5>>
ENDIF
ENDREPEAT
RETURN vRadius
ENDFUNC
// COYOTE STATES
/// PURPOSE:
/// Tracks and changes the coyotes states.
PROC CHECK_COYOTE_STATES(INT i, INT j)
IF mPack[i].mCoyote[j].eCoyState <> CS_NULL AND mPack[i].mCoyote[j].eCoyState <> CS_CLEAN_UP
IF NOT IS_ENTITY_DEAD(mPack[i].mCoyote[j].mCoyPed)
SET_PED_INCREASED_AVOIDANCE_RADIUS(mPack[i].mCoyote[j].mCoyPed)
ENDIF
CHECK_COYOTE_BLIPS(i, j)
ENDIF
CHECK_MULTI_COYOTE_KILL(i)
SWITCH mPack[i].mCoyote[j].eCoyState
CASE CS_NULL
// DO NOTHING
BREAK
CASE CS_CALC_RANDOM_WAIT_TIME
IF DOES_ENTITY_EXIST(mPack[i].mCoyote[j].mCoyPed)
AND NOT IS_ENTITY_DEAD(mPack[i].mCoyote[j].mCoyPed)
mPack[i].mCoyote[j].iWaitTime = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(3000, 8000)
CPRINTLN(DEBUG_MISSION, "CS_WAIT_RANDOM_TIME")
mPack[i].mCoyote[j].eCoyState = CS_WAIT_RANDOM_TIME
ELSE
CPRINTLN(DEBUG_MISSION, "CS_CALC_RANDOM_WAIT_TIME - CS_CLEAN_UP")
mPack[i].mCoyote[j].eCoyState = CS_CLEAN_UP
ENDIF
BREAK
CASE CS_WAIT_RANDOM_TIME
IF DOES_ENTITY_EXIST(mPack[i].mCoyote[j].mCoyPed)
AND NOT IS_ENTITY_DEAD(mPack[i].mCoyote[j].mCoyPed)
IF GET_GAME_TIMER() > mPack[i].mCoyote[j].iWaitTime
AND mPack[i].mCoyote[j].ePackID = CP_LEADER
HANDLE_COYOTE_SOUNDS(i, j)
INT x
x = 0
REPEAT MAX_PACK_MEMBERS x
IF DOES_ENTITY_EXIST(mPack[i].mCoyote[x].mCoyPed)
AND NOT IS_ENTITY_DEAD(mPack[i].mCoyote[x].mCoyPed)
CPRINTLN(DEBUG_MISSION, "CS_WAIT_RANDOM_TIME - CS_CHOOSE_NEXT_DESTINATION")
mPack[i].mCoyote[x].eCoyState = CS_CHOOSE_NEXT_DESTINATION
ENDIF
ENDREPEAT
ENDIF
ELSE
CPRINTLN(DEBUG_MISSION, "CS_WAIT_RANDOM_TIME - CS_CLEAN_UP")
mPack[i].mCoyote[j].eCoyState = CS_CLEAN_UP
ENDIF
BREAK
CASE CS_CHOOSE_NEXT_DESTINATION
IF DOES_ENTITY_EXIST(mPack[i].mCoyote[j].mCoyPed)
AND NOT IS_ENTITY_DEAD(mPack[i].mCoyote[j].mCoyPed)
mPack[i].mCoyote[j].iRandSpawn = GET_RANDOM_INT_IN_RANGE(0, MAX_GRAZE_AREAS)
IF NOT bIsBooked[mPack[i].mCoyote[j].iRandSpawn]
bIsBooked[mPack[i].mCoyote[j].iCurSpawn] = FALSE
IF mPack[i].mCoyote[j].ePackID = CP_LEADER
CPRINTLN(DEBUG_MISSION, "LEADER - GO TO COORD")
TASK_FOLLOW_NAV_MESH_TO_COORD(mPack[i].mCoyote[j].mCoyPed, vGrazePos[mPack[i].mCoyote[j].iRandSpawn], PEDMOVEBLENDRATIO_WALK, DEFAULT_TIME_NEVER_WARP, DEFAULT_NAVMESH_RADIUS, ENAV_STOP_EXACTLY, GET_RANDOM_FLOAT_IN_RANGE(0.0, 359.9))
ELSE
IF DOES_ENTITY_EXIST(mPack[i].mCoyote[iLeaderID].mCoyPed)
AND NOT IS_ENTITY_DEAD(mPack[i].mCoyote[iLeaderID].mCoyPed)
CPRINTLN(DEBUG_MISSION, "FOLLOWER - FOLLOW TO OFFSET")
TASK_FOLLOW_TO_OFFSET_OF_ENTITY(mPack[i].mCoyote[j].mCoyPed, mPack[i].mCoyote[iLeaderID].mCoyPed, mPack[i].mCoyote[j].vFollowOffset, PEDMOVEBLENDRATIO_WALK, -1, 1.5, TRUE)
ENDIF
ENDIF
mPack[i].mCoyote[j].iCurSpawn = mPack[i].mCoyote[j].iRandSpawn
bIsBooked[mPack[i].mCoyote[j].iCurSpawn] = TRUE
CPRINTLN(DEBUG_MISSION, "CS_GO_NEXT_DESTINATION")
mPack[i].mCoyote[j].eCoyState = CS_GO_NEXT_DESTINATION
ENDIF
ELSE
CPRINTLN(DEBUG_MISSION, "CS_CHOOSE_NEXT_DESTINATION - CS_CLEAN_UP")
mPack[i].mCoyote[j].eCoyState = CS_CLEAN_UP
ENDIF
BREAK
CASE CS_GO_NEXT_DESTINATION
IF DOES_ENTITY_EXIST(mPack[i].mCoyote[j].mCoyPed)
AND NOT IS_ENTITY_DEAD(mPack[i].mCoyote[j].mCoyPed)
IF mPack[i].mCoyote[j].ePackID = CP_LEADER
AND IS_ENTITY_AT_COORD(mPack[i].mCoyote[j].mCoyPed, vGrazePos[mPack[i].mCoyote[j].iCurSpawn], GET_DESTINATION_RADIUS(i), FALSE, FALSE, TM_ANY)
INT x
x = 0
REPEAT MAX_PACK_MEMBERS x
IF DOES_ENTITY_EXIST(mPack[i].mCoyote[j].mCoyPed)
AND NOT IS_ENTITY_DEAD(mPack[i].mCoyote[j].mCoyPed)
CPRINTLN(DEBUG_MISSION, "WANDER")
CLEAR_PED_TASKS(mPack[i].mCoyote[j].mCoyPed)
TASK_WANDER_IN_AREA(mPack[i].mCoyote[j].mCoyPed, vGrazePos[mPack[i].mCoyote[j].iCurSpawn], 7.5, 0, 1)
CPRINTLN(DEBUG_MISSION, "CS_GO_NEXT_DESTINATION - CS_CALC_RANDOM_WAIT_TIME")
mPack[i].mCoyote[j].eCoyState = CS_CALC_RANDOM_WAIT_TIME
ENDIF
ENDREPEAT
ENDIF
ELSE
CPRINTLN(DEBUG_MISSION, "CS_GO_NEXT_DESTINATION - CS_CLEAN_UP")
mPack[i].mCoyote[j].eCoyState = CS_CLEAN_UP
ENDIF
BREAK
CASE CS_RUN_OFF
IF DOES_ENTITY_EXIST(mPack[i].mCoyote[j].mCoyPed)
AND NOT IS_ENTITY_DEAD(mPack[i].mCoyote[j].mCoyPed)
CLEAR_PED_TASKS(mPack[i].mCoyote[j].mCoyPed)
IF bDeathInPack[i]
CPRINTLN(DEBUG_MISSION, "GIVE_COYOTE_FLEE_ORDER bDeathInPack = TRUE")
TASK_SMART_FLEE_COORD(mPack[i].mCoyote[j].mCoyPed, vDeath[i], 50.0, -1, FALSE)
ELSE
CPRINTLN(DEBUG_MISSION, "GIVE_COYOTE_FLEE_ORDER bDeathInPack = FALSE")
TASK_SMART_FLEE_COORD(mPack[i].mCoyote[j].mCoyPed, mPack[i].mCoyote[j].vBulletLoc, 50.0, -1, FALSE)
ENDIF
SET_PED_KEEP_TASK(mPack[i].mCoyote[j].mCoyPed, TRUE)
CPRINTLN(DEBUG_MISSION, "CS_RUNNING_OFF")
mPack[i].mCoyote[j].eCoyState = CS_RUNNING_OFF
ELSE
CPRINTLN(DEBUG_MISSION, "CS_RUN_OFF - CS_CLEAN_UP")
mPack[i].mCoyote[j].eCoyState = CS_CLEAN_UP
ENDIF
BREAK
CASE CS_RUNNING_OFF
IF DOES_ENTITY_EXIST(mPack[i].mCoyote[j].mCoyPed)
AND NOT IS_ENTITY_DEAD(mPack[i].mCoyote[j].mCoyPed)
IF bDeathInPack[i]
IF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(mPack[i].mCoyote[j].mCoyPed, vDeath[i]) >= 45
TASK_GO_TO_COORD_ANY_MEANS(mPack[i].mCoyote[j].mCoyPed, vDeath[i], GET_RANDOM_FLOAT_IN_RANGE(1,2.5), NULL)
CPRINTLN(DEBUG_MISSION, "CS_INVESTIGATING_DEATH")
mPack[i].mCoyote[j].eCoyState = CS_INVESTIGATING_DEATH
ENDIF
ELSE
IF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(mPack[i].mCoyote[j].mCoyPed, mPack[i].mCoyote[j].vBulletLoc) >= 45
IF mPack[i].mCoyote[j].ePackID = CP_LEADER
CPRINTLN(DEBUG_MISSION, " Leader - CS_CHOOSE_NEXT_DESTINATION")
mPack[i].mCoyote[j].eCoyState = CS_CHOOSE_NEXT_DESTINATION
ELSE
CPRINTLN(DEBUG_MISSION, "Follower - CS_FOLLOW_LEADER")
mPack[i].mCoyote[j].eCoyState = CS_FOLLOW_LEADER
ENDIF
ENDIF
ENDIF
ELSE
CPRINTLN(DEBUG_MISSION, "CS_RUNNING_OFF - CS_CLEAN_UP")
mPack[i].mCoyote[j].eCoyState = CS_CLEAN_UP
ENDIF
BREAK
CASE CS_INVESTIGATING_DEATH
IF DOES_ENTITY_EXIST(mPack[i].mCoyote[j].mCoyPed)
AND NOT IS_ENTITY_DEAD(mPack[i].mCoyote[j].mCoyPed)
//IF GET_SCRIPT_TASK_STATUS(mPack[i].mCoyote[j].mCoyPed, SCRIPT_TASK_GO_TO_COORD_ANY_MEANS) = FINISHED_TASK
IF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(mPack[i].mCoyote[j].mCoyPed, vDeath[i], FALSE) < 2.0
CLEAR_PED_TASKS(mPack[i].mCoyote[j].mCoyPed)
bDeathInPack[i] = FALSE
mPack[i].mCoyote[j].eCoyState = CS_CALC_RANDOM_WAIT_TIME
ENDIF
ELSE
CPRINTLN(DEBUG_MISSION, "CS_INVESTIGATING_DEATH - CS_CLEAN_UP")
mPack[i].mCoyote[j].eCoyState = CS_CLEAN_UP
ENDIF
BREAK
CASE CS_FOLLOW_LEADER
IF DOES_ENTITY_EXIST(mPack[i].mCoyote[j].mCoyPed)
AND NOT IS_ENTITY_DEAD(mPack[i].mCoyote[j].mCoyPed)
IF DOES_ENTITY_EXIST(mPack[i].mCoyote[iLeaderID].mCoyPed)
AND NOT IS_ENTITY_DEAD(mPack[i].mCoyote[iLeaderID].mCoyPed)
TASK_FOLLOW_TO_OFFSET_OF_ENTITY(mPack[i].mCoyote[j].mCoyPed, mPack[i].mCoyote[iLeaderID].mCoyPed, mPack[i].mCoyote[j].vFollowOffset, PEDMOVEBLENDRATIO_WALK, -1, 1.5, TRUE)
mPack[i].mCoyote[j].eCoyState = CS_FOLLOWING_LEADER
ENDIF
ELSE
CPRINTLN(DEBUG_MISSION, "CS_FOLLOW_LEADER - CS_CLEAN_UP")
mPack[i].mCoyote[j].eCoyState = CS_CLEAN_UP
ENDIF
BREAK
CASE CS_FOLLOWING_LEADER
IF DOES_ENTITY_EXIST(mPack[i].mCoyote[j].mCoyPed)
AND IS_ENTITY_DEAD(mPack[i].mCoyote[j].mCoyPed)
CPRINTLN(DEBUG_MISSION, "CS_FOLLOWING_LEADER - CS_CLEAN_UP")
mPack[i].mCoyote[j].eCoyState = CS_CLEAN_UP
ENDIF
BREAK
CASE CS_CLEAN_UP
IF DOES_ENTITY_EXIST(mPack[i].mCoyote[j].mCoyPed)
IF IS_ENTITY_DEAD(mPack[i].mCoyote[j].mCoyPed)
IF WAS_TARGET_DAMAGED_BY_SNIPER_RIFLE(mPack[i].mCoyote[j].mCoyPed)
CPRINTLN(DEBUG_MISSION, "Increment targets shot")
iTargetsShot++
bInactiveTimerStarted = FALSE
ELSE
CPRINTLN(DEBUG_MISSION, "Coyote was killed with wrong weapon")
bWrongGunFail = TRUE
ENDIF
ENDIF
CLEAR_ENTITY_LAST_DAMAGE_ENTITY(mPack[i].mCoyote[j].mCoyPed)
ENDIF
mPack[i].mCoyote[j].eCoyState = CS_NULL
BREAK
ENDSWITCH
ENDPROC
/// PURPOSE:
/// Tracks and changes the pack states.
PROC MANAGE_THE_PACKS()
INT i = 0
INT j = 0
REPEAT MAX_PACKS i
REPEAT MAX_PACK_MEMBERS j
IF mPack[i].mCoyote[j].eCoyState <> CS_SPAWN_IN
AND mPack[i].mCoyote[j].eCoyState <> CS_NULL
AND mPack[i].ePackState <> PS_FLEE
AND mPack[i].ePackState <> PS_AFTER_FLEE
IF NOT IS_PED_UNINJURED(mPack[i].mCoyote[j].mCoyPed)
IF NOT mPack[i].mCoyote[j].bDead
bInactiveTimerStarted = FALSE
HANDLE_COYOTE_SOUNDS(i, j)
vDeath[i] = GET_ENTITY_COORDS(mPack[i].mCoyote[j].mCoyPed)
bDeathInPack[i] = TRUE
mPack[i].mCoyote[j].bDead = TRUE
// If the leader is dead, promote a follower to the leader position.
IF mPack[i].mCoyote[0].bDead = TRUE
CPRINTLN(DEBUG_MISSION, "PACK LEADER HAS DIED - PROMOTE")
IF NOT IS_ENTITY_DEAD(mPack[i].mCoyote[1].mCoyPed)
CPRINTLN(DEBUG_MISSION, "PROMOTE FOLLOWER 1 TO LEADER")
mPack[i].mCoyote[1].ePackID = CP_LEADER
iLeaderID = 1
ELIF NOT IS_ENTITY_DEAD(mPack[i].mCoyote[2].mCoyPed)
CPRINTLN(DEBUG_MISSION, "PROMOTE FOLLOWER 2 TO LEADER")
mPack[i].mCoyote[2].ePackID = CP_LEADER
iLeaderID = 2
ENDIF
ENDIF
mPack[i].iAlive--
CPRINTLN(DEBUG_MISSION, "PACK MEMBER HAS DIED - PS FLEE")
mPack[i].ePackState = PS_FLEE
ENDIF
ELSE
IF IS_BULLET_IN_AREA(GET_ENTITY_COORDS(mPack[i].mCoyote[j].mCoyPed), 2.0, FALSE)
bInactiveTimerStarted = FALSE
bMissedCoyote = TRUE
CPRINTLN(DEBUG_MISSION, "BULLET IN AREA - PS FLEE")
iLoop = 0
REPEAT MAX_PACK_MEMBERS iLoop
IF IS_ENTITY_ALIVE(mPack[i].mCoyote[iLoop].mCoyPed)
mPack[i].mCoyote[iLoop].vBulletLoc = GET_ENTITY_COORDS(mPack[i].mCoyote[iLoop].mCoyPed)
mPack[i].ePackState = PS_FLEE
ELSE
IF NOT mPack[i].mCoyote[j].bDead
CPRINTLN(DEBUG_MISSION, "BULLET IN AREA - AT LEAST ONE PACK MEMBER DIED")
bMissedCoyote = FALSE
ENDIF
ENDIF
ENDREPEAT
ENDIF
ENDIF
ENDIF
SWITCH mPack[i].ePackState
CASE PS_SPAWN_IN
IF mPack[i].iAlive < MAX_PACK_MEMBERS
IF mPack[i].mCoyote[j].ePackID = CP_LEADER
SPAWN_LEADER_COYOTE(i, j)
mPack[i].iAlive++
ELIF mPack[i].mCoyote[j].ePackID = CP_FOLLOWER
SPAWN_FOLLOWER_COYOTE(i,j)
mPack[i].iAlive++
ENDIF
ELSE
// IF bCoyoteAssetsInMem
// SET_MODEL_AS_NO_LONGER_NEEDED(mCoyModel)
// bCoyoteAssetsInMem = FALSE
// ENDIF
mPack[i].ePackState = PS_ACTIVE
ENDIF
BREAK
CASE PS_ACTIVE
CHECK_COYOTE_STATES(i,j)
BREAK
CASE PS_FLEE
CPRINTLN(DEBUG_MISSION, "PS FLEE ")
iLoop = 0
REPEAT MAX_PACK_MEMBERS iLoop
IF DOES_ENTITY_EXIST(mPack[i].mCoyote[iLoop].mCoyPed)
AND NOT IS_ENTITY_DEAD(mPack[i].mCoyote[iLoop].mCoyPed)
AND NOT IS_PED_INJURED(mPack[i].mCoyote[iLoop].mCoyPed)
mPack[i].mCoyote[iLoop].eCoyState = CS_RUN_OFF
ENDIF
ENDREPEAT
mPack[i].ePackState = PS_ACTIVE
BREAK
CASE PS_INVESTIGATE
iLoop = 0
REPEAT MAX_PACK_MEMBERS iLoop
IF NOT mPack[i].mCoyote[iLoop].bDead
IF DOES_ENTITY_EXIST(mPack[i].mCoyote[iLoop].mCoyPed)
AND NOT IS_ENTITY_DEAD(mPack[i].mCoyote[iLoop].mCoyPed)
TASK_GO_TO_COORD_ANY_MEANS(mPack[i].mCoyote[iLoop].mCoyPed, vDeath[i], GET_RANDOM_FLOAT_IN_RANGE(1,2.5), NULL)
mPack[i].mCoyote[iLoop].eCoyState = CS_INVESTIGATING_DEATH
ENDIF
ENDIF
ENDREPEAT
mPack[i].ePackState = PS_ACTIVE
BREAK
CASE PS_NULL
BREAK
ENDSWITCH
ENDREPEAT
ENDREPEAT
ENDPROC
// HUNTER FUNCTIONS
FUNC BOOL HAS_PLAYER_ABANDONED_HUNTER()
IF DOES_ENTITY_EXIST(mHunter)
AND NOT IS_ENTITY_DEAD(PLAYER_PED_ID())
IF NOT IS_ENTITY_AT_ENTITY(mHunter, PLAYER_PED_ID(), vFailDist, FALSE, FALSE, TM_ANY)
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Adds a friendly blip to the hunter
PROC BLIP_HUNTER(BOOL bBig = TRUE, BOOL bFlash = FALSE)
IF NOT DOES_BLIP_EXIST(mHunterBlip)
mHunterBlip = CREATE_PED_BLIP(mHunter, TRUE, TRUE)
ENDIF
IF DOES_BLIP_EXIST(mHunterBlip)
IF NOT bBig
SET_BLIP_SCALE(mHunterBlip, 0.75)
ENDIF
SET_BLIP_FLASHES(mHunterBlip, bFlash)
ENDIF
ENDPROC
/// PURPOSE:
/// Checks if the player has left the Hunter behind.
PROC CHECK_HUNTER_WITH_PLAYER()
IF NOT IS_PED_INJURED(mHunter)
AND NOT IS_PED_INJURED(PLAYER_PED_ID())
IF NOT bPlayerLeftHunter
IF NOT IS_ENTITY_AT_ENTITY(mHunter, PLAYER_PED_ID(), vGroupRange)
OR GET_INTERIOR_FROM_ENTITY(PLAYER_PED_ID()) != NULL
IF NOT IS_PED_FALLING(mHunter)
bPlayerLeftHunter = TRUE
ENDIF
ENDIF
ELSE
IF IS_ENTITY_AT_ENTITY(mHunter, PLAYER_PED_ID(), vGroupReturnRange)
AND GET_INTERIOR_FROM_ENTITY(PLAYER_PED_ID()) = NULL
IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) OR ARE_ANY_VEHICLE_SEATS_FREE(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID(), FALSE))
bPlayerLeftHunter = FALSE
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Resets the "good shot" commen bool, so the hunter can deliver his lines when appropriate
PROC RESET_GOOD_SHOT_CONVO()
INT i = 0
REPEAT TARGET_HITS_REQUIRED i
bSaidGoodShotLine[i] = FALSE
ENDREPEAT
ENDPROC
/// PURPOSE:
/// Makes the hunter comment on the fact that the player isn't using the right gun.
PROC HANDLE_WRONG_GUN_CONVO()
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
IF ARE_PEDS_IN_CONVO_RANGE()
IF IS_PED_ARMED(PLAYER_PED_ID(), WF_INCLUDE_GUN|WF_INCLUDE_PROJECTILE)
IF NOT bSaidWrongGunComment
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_UGUN", CONV_PRIORITY_VERY_HIGH)
bSaidWrongGunComment = TRUE
bSaidNoGunComment = FALSE
ENDIF
ENDIF
ELSE
IF NOT bSaidNoGunComment
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT_UGUN2", CONV_PRIORITY_VERY_HIGH)
bSaidNoGunComment = TRUE
bSaidWrongGunComment = FALSE
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Toggles hunter following Player
PROC SET_HUNTER_TO_BUDDY_BEHAVIOUR(BOOL bBuddy)
IF IS_PED_UNINJURED(mHunter)
IF bBuddy
IF DOES_GROUP_EXIST(PLAYER_GROUP_ID())
IF NOT IS_PED_GROUP_MEMBER(mHunter, PLAYER_GROUP_ID())
CLEAR_PED_TASKS(mHunter)
SET_PED_AS_GROUP_MEMBER(mHunter, PLAYER_GROUP_ID())
SET_PED_NEVER_LEAVES_GROUP(mHunter, TRUE)
FREEZE_ENTITY_POSITION(mHunter, FALSE)
//bReturningToPlayer = FALSE
ENDIF
ENDIF
ELSE
// Remove hunter from players group.
IF IS_PED_GROUP_MEMBER(mHunter, PLAYER_GROUP_ID())
CLEAR_PED_TASKS(mHunter)
REMOVE_PED_FROM_GROUP(mHunter)
ENDIF
ENDIF
ENDIF
ENDPROC
FUNC BOOL IS_PLAYER_FIGHTING_HUNTER()
IF IS_PED_UNINJURED(mHunter)
IF eHunterState <> HS_DO_OUTRO_CONV
IF NOT IS_PED_ARMED(PLAYER_PED_ID(), WF_INCLUDE_GUN|WF_INCLUDE_PROJECTILE)
AND IS_PED_IN_MELEE_COMBAT(PLAYER_PED_ID())
AND GET_DISTANCE_BETWEEN_ENTITIES(mHunter, PLAYER_PED_ID()) <=3
RETURN TRUE
ENDIF
ELSE // If it's the last mission state, only quit out of the final conversation if the player
// is threatening the hunter while facing him.
IF NOT IS_PED_ARMED(PLAYER_PED_ID(), WF_INCLUDE_GUN|WF_INCLUDE_PROJECTILE)
AND IS_PED_IN_MELEE_COMBAT(PLAYER_PED_ID())
AND IS_PED_FACING_PED(PLAYER_PED_ID(), mHunter, 30.0)
AND GET_DISTANCE_BETWEEN_ENTITIES(mHunter, PLAYER_PED_ID()) <=2
RETURN TRUE
ENDIF
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL HAS_PLAYER_DAMAGED_BINOS()
IF DOES_ENTITY_EXIST(mBinos)
IF HAS_ENTITY_BEEN_DAMAGED_BY_WEAPON(mBinos, WEAPONTYPE_SNIPERRIFLE)
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Checks to see if the player is trying to punch the hunter, or is aiming his gun at him
PROC CHECK_PLAYER_THREATENING()
// If the player starts throwing projectiles at the hunter, remove the friendly relationship between them.
IF NOT IS_PED_INJURED(mHunter)
IF IS_PROJECTILE_TYPE_IN_AREA(GET_ENTITY_COORDS(mHunter, FALSE) + << 2.0, 2.0, 2.0>>, GET_ENTITY_COORDS(mHunter, FALSE) - << 2.0, 2.0, 2.0>>, WEAPONTYPE_GRENADE, FALSE)
OR IS_PROJECTILE_TYPE_IN_AREA(GET_ENTITY_COORDS(mHunter, FALSE) + << 2.0, 2.0, 2.0>>, GET_ENTITY_COORDS(mHunter, FALSE) - << 2.0, 2.0, 2.0>>, WEAPONTYPE_STICKYBOMB, FALSE)
OR IS_PROJECTILE_TYPE_IN_AREA(GET_ENTITY_COORDS(mHunter, FALSE) + << 2.0, 2.0, 2.0>>, GET_ENTITY_COORDS(mHunter, FALSE) - << 2.0, 2.0, 2.0>>, WEAPONTYPE_MOLOTOV, FALSE)
OR IS_EXPLOSION_IN_SPHERE(EXP_TAG_DONTCARE, GET_ENTITY_COORDS(mHunter, FALSE), 10.0)
CLEAR_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_LIKE, relGroupFriendly, RELGROUPHASH_PLAYER)
ENDIF
IF NOT bDoneThreatSpeech
IF IS_PLAYER_FIGHTING_HUNTER() OR IS_PLAYER_FREE_AIMING_AT_ENTITY(PLAYER_ID(), mHunter)
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
// TEXT_LABEL_23 sResumeRoot = GET_CURRENTLY_PLAYING_STANDARD_CONVERSATION_ROOT()
// TEXT_LABEL_23 sResumeLine = GET_STANDARD_CONVERSATION_LABEL_FOR_FUTURE_RESUMPTION()
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
ENDIF
ADD_NON_CRITICAL_STANDARD_CONVERSATION_TO_BUFFER(mHunterConv, sTextBlock, "HUNT1_PTREAC", CONV_PRIORITY_LOW)
bDoneThreatSpeech = TRUE
ENDIF
ENDIF
IF NOT bFalling
IF IS_PED_FALLING(mHunter)
SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(mHunter, FALSE)
CPRINTLN(DEBUG_MISSION, "SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(mHunter, FALSE)")
bFalling = TRUE
ENDIF
ELSE
IF IS_PED_GETTING_UP(mHunter)
SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(mHunter, TRUE)
CPRINTLN(DEBUG_MISSION, "SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(mHunter, TRUE)")
bFalling = FALSE
ENDIF
ENDIF
ENDIF
ENDPROC
FUNC BOOL HAS_HUNTER_PUT_BINOS_AWAY()
IF NOT IS_ENTITY_PLAYING_ANIM(mHunter, "ODDJOBS@HUNTER", "BINOCULARS_LOOP")
AND NOT IS_ENTITY_PLAYING_ANIM(mHunter, "ODDJOBS@HUNTER", "BINOCULARS_OUTRO")
IF NOT DOES_ENTITY_EXIST(mBinos)
CPRINTLN(DEBUG_MISSION, "HAS_HUNTER_PUT_BINOS_AWAY is TRUE (anims)")
CLEAR_PED_TASKS(mHunter)
RETURN TRUE
ELSE
CPRINTLN(DEBUG_MISSION, "HAS_HUNTER_PUT_BINOS_AWAY is FALSE (visibility)")
DELETE_OBJECT(mBinos)
ENDIF
ELSE
IF NOT DOES_ENTITY_EXIST(mBinos)
CPRINTLN(DEBUG_MISSION, "HAS_HUNTER_PUT_BINOS_AWAY is TRUE (binos not visible)")
CLEAR_PED_TASKS(mHunter)
RETURN TRUE
ENDIF
CPRINTLN(DEBUG_MISSION, "HAS_HUNTER_PUT_BINOS_AWAY is FALSE (anims)")
ENDIF
CPRINTLN(DEBUG_MISSION, "HAS_HUNTER_PUT_BINOS_AWAY is FALSE")
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Creates or removes the binoculars model depending on the hunters animation.
PROC MANAGE_BINOS()
IF NOT IS_PED_INJURED(mHunter)
IF IS_ENTITY_PLAYING_ANIM(mHunter, "ODDJOBS@HUNTER", "BINOCULARS_OUTRO") AND GET_ENTITY_ANIM_CURRENT_TIME(mHunter, "ODDJOBS@HUNTER", "BINOCULARS_OUTRO") >= 0.680
OR iKnockState = 1
IF DOES_ENTITY_EXIST(mBinos)
DELETE_OBJECT(mBinos)
ENDIF
ENDIF
IF NOT DOES_ENTITY_EXIST(mBinos)
IF IS_ENTITY_PLAYING_ANIM(mHunter, "ODDJOBS@HUNTER", "binoculars_intro") AND GET_ENTITY_ANIM_CURRENT_TIME(mHunter, "ODDJOBS@HUNTER", "binoculars_intro") >= 0.242
mBinos = CREATE_OBJECT(mBinoModel, GET_ENTITY_COORDS(mHunter), FALSE, FALSE)
ENDIF
ELSE
IF NOT IS_ENTITY_ATTACHED_TO_ENTITY(mBinos,mHunter)
ATTACH_ENTITY_TO_ENTITY(mBinos, mHunter, GET_PED_BONE_INDEX(mHunter, BONETAG_PH_R_HAND), <<0.0, 0.0, 0.0>>, <<0.0, 0.0, 0.0>>)
ENDIF
ENDIF
ENDIF
ENDPROC
PROC MAKE_HUNTER_PUT_BINOS_AWAY(BOOL bThenWalkOff = FALSE)
CPRINTLN(DEBUG_MISSION, "MAKE_HUNTER_PUT_BINOS_AWAY")
IF bBinosOut
bBinosOut = FALSE
ENDIF
SEQUENCE_INDEX mBinoSeq
IF IS_PED_UNINJURED(mHunter)
IF IS_ENTITY_PLAYING_ANIM(mHunter, "ODDJOBS@HUNTER", "BINOCULARS_LOOP")
OR IS_ENTITY_PLAYING_ANIM(mHunter, "ODDJOBS@HUNTER", "BINOCULARS_INTRO")
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(mHunter, TRUE)
TASK_CLEAR_LOOK_AT(mHunter)
OPEN_SEQUENCE_TASK(mBinoSeq)
CPRINTLN(DEBUG_MISSION, "HUNTER IS PUTTING BINOS AWAY")
TASK_PLAY_ANIM(NULL, "ODDJOBS@HUNTER", "BINOCULARS_OUTRO", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_UPPERBODY|AF_SECONDARY)
IF bThenWalkOff
TASK_WANDER_STANDARD(NULL)
SET_PED_KEEP_TASK(mHunter, TRUE)
ENDIF
CLOSE_SEQUENCE_TASK(mBinoSeq)
TASK_PERFORM_SEQUENCE(mHunter, mBinoSeq)
CLEAR_SEQUENCE_TASK(mBinoSeq)
ENDIF
ENDIF
ENDPROC
PROC MAKE_HUNTER_GET_BINOS_OUT(BOOL bPointFirst, BOOL bFaceHeading = FALSE)
CPRINTLN(DEBUG_MISSION, "MAKE_HUNTER_GET_BINOS_OUT")
IF NOT bFaceHeading
OR bChosenDish
IF HAVE_BINOS_BEEN_CREATED()
IF NOT bBinosOut
bBinosOut = TRUE
ENDIF
SEQUENCE_INDEX mBinoSeq
IF IS_PED_UNINJURED(mHunter)
CLEAR_PED_TASKS(mHunter)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(mHunter, TRUE)
OPEN_SEQUENCE_TASK(mBinoSeq)
TASK_CLEAR_LOOK_AT(NULL)
IF bFaceHeading
TASK_TURN_PED_TO_FACE_COORD(NULL, mDish[iRandomDish].vSpawn)
ENDIF
IF bPointFirst
TASK_PLAY_ANIM(NULL, "ODDJOBS@HUNTER", "point_fwd", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_UPPERBODY)
ENDIF
TASK_PLAY_ANIM(NULL, "ODDJOBS@HUNTER", "binoculars_intro", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_UPPERBODY)
TASK_PLAY_ANIM(NULL, "ODDJOBS@HUNTER", "BINOCULARS_LOOP", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_UPPERBODY | AF_LOOPING)
CLOSE_SEQUENCE_TASK(mBinoSeq)
TASK_PERFORM_SEQUENCE(mHunter, mBinoSeq)
CLEAR_SEQUENCE_TASK(mBinoSeq)
SET_PED_CAN_RAGDOLL_FROM_PLAYER_IMPACT(mHunter, TRUE)
ENDIF
ENDIF
ENDIF
ENDPROC
PROC MONITOR_LEAVE_DISHES_CONVO()
// Are we still hanging about on the balcony
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), vDishShootAreaA, vDishShootAreaB, CLETUS_HOUSE_WIDTH)
IF bTriggeredObjectiveText[OT_GO_MOTEL]
AND NOT IS_THIS_PRINT_BEING_DISPLAYED("HT_NXTLOC") // Wait until go to abandoned motel text has cleared.
AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
IF NOT bGotBalconyIdleTimer
iBalconyIdleTimer = GET_GAME_TIMER() + 15000
bGotBalconyIdleTimer = TRUE
ELSE
IF GET_GAME_TIMER() > iBalconyIdleTimer
IF NOT bTriggeredConvo[HC_LEAVE_DISHES]
AND ARE_PEDS_IN_CONVO_RANGE()
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_WAIT", CONV_PRIORITY_MEDIUM)
bGotBalconyIdleTimer = FALSE
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
bTriggeredConvo[HC_LEAVE_DISHES] = TRUE
ENDIF
ENDPROC
TEXT_LABEL_23 sCurInCarLine = "HUNT1_BANTER_1"
/// PURPOSE:
/// Kicks off the conversation between the player and the hunter after they've been in the car for 5 seconds.
PROC MONITOR_IN_CAR_CONVO()
IF NOT IS_PED_DEAD_OR_DYING (mHunter) AND NOT IS_PED_DEAD_OR_DYING(PLAYER_PED_ID())
IF IS_PED_IN_ANY_VEHICLE(mHunter) AND IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
IF NOT bStartedCarConvoTimer
iCarConvoTime = GET_GAME_TIMER() + CAR_CONVO_DELAY_TIME
bStartedCarConvoTimer = TRUE
ELSE
IF GET_GAME_TIMER() > iCarConvoTime
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
IF NOT bTriggeredConvo[HC_IN_CAR]
IF CREATE_CONVERSATION_FROM_SPECIFIC_LINE(mHunterConv, sTextBlock, "HUNT1_BANTER", sCurInCarLine, CONV_PRIORITY_MEDIUM) // You've got way too much time on your hands...
IF NOT IS_STRING_NULL_OR_EMPTY(sCurInCarLine)
sCurInCarLine = GET_STANDARD_CONVERSATION_LABEL_FOR_FUTURE_RESUMPTION()
ELSE
CPRINTLN(DEBUG_MISSION, "In car convo finished")
bTriggeredConvo[HC_IN_CAR] = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
BOOL bStartedAfterDishTimer
INT iAfterDishTime
/// PURPOSE:
/// Kicks off Cletus complaining if the player hasn't got in a car recently.
PROC MONITOR_AFTER_DISH_BANTER()
IF NOT IS_PED_DEAD_OR_DYING(mHunter) AND NOT IS_PED_DEAD_OR_DYING(PLAYER_PED_ID())
IF NOT bStartedAfterDishTimer
IF bTriggeredObjectiveText[OT_GO_MOTEL]
AND NOT IS_THIS_PRINT_BEING_DISPLAYED("HT_NXTLOC") // Wait until go to abandoned motel text has cleared.
iAfterDishTime = GET_GAME_TIMER() + 3000
bStartedAfterDishTimer = TRUE
ENDIF
ELSE
IF GET_GAME_TIMER() > iAfterDishTime
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
AND ARE_PEDS_IN_CONVO_RANGE()
IF NOT bTriggeredConvo[HC_AFTER_DISH_BANTER]
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_2", CONV_PRIORITY_MEDIUM) // So what now...?
bTriggeredConvo[HC_AFTER_DISH_BANTER] = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Kicks off Cletus complaining if the player hasn't got in a car recently.
PROC MONITOR_NO_CAR_CONVO()
IF NOT IS_PED_DEAD_OR_DYING (mHunter) AND NOT IS_PED_DEAD_OR_DYING(PLAYER_PED_ID())
IF NOT IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), vDishShootAreaA, vDishShootAreaB, DISH_AREA_WIDTH)
IF NOT IS_PED_IN_ANY_VEHICLE(mHunter) AND NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID(), TRUE)
IF NOT bStartedNoCarConvoTimer
IF NOT IS_THIS_PRINT_BEING_DISPLAYED("HT_NXTLOC") // Wait until go to abandoned motel text has cleared.
AND bTriggeredConvo[HC_AFTER_DISH_BANTER] // Only start this timer after the post-dish banter has been triggered.
iNoCarConvoTime = GET_GAME_TIMER() + NO_CAR_CONVO_DELAY_TIME
bStartedNoCarConvoTimer = TRUE
ENDIF
ELSE
IF GET_GAME_TIMER() > iNoCarConvoTime
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
AND ARE_PEDS_IN_CONVO_RANGE()
IF NOT bTriggeredConvo[HC_COMPLAIN]
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_NOVEH", CONV_PRIORITY_MEDIUM) // Motel's a good walk Trevor....
bTriggeredConvo[HC_COMPLAIN] = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
IF RC_IS_THIS_CONVERSATION_ROOT_PLAYING("HUNT1_NOVEH")
KILL_ANY_CONVERSATION()
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Monitor's which car the player gets in and makes Cletus pass comment on it.
PROC MONITOR_CAR_COMMENT()
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
IF NOT bTriggeredConvo[HC_CAR_COMMENT]
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
IF ARE_PEDS_IN_CONVO_RANGE()
IF GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()) = mHunterCar
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_CLVEH", CONV_PRIORITY_MEDIUM) // Ain't she a beauty
bTriggeredConvo[HC_CAR_COMMENT] = TRUE
ENDIF
ELSE
// Make sure the player's chosen car is suitable...
IF ARE_ANY_VEHICLE_SEATS_FREE(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()))
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_OWNVEH", CONV_PRIORITY_MEDIUM) // We'll take your vehicle then
bTriggeredConvo[HC_CAR_COMMENT] = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
BOOL bGotCarHealth = FALSE
INT iCarHealth
PROC MONITOR_HUNTER_CAR_DAMAGE()
IF IS_PED_UNINJURED(PLAYER_PED_ID()) AND IS_PED_UNINJURED(mHunter)
IF IS_PED_IN_ANY_VEHICLE(mHunter) AND IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
IF IS_ENTITY_ALIVE(mHunterCar)
IF GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()) = mHunterCar AND GET_VEHICLE_PED_IS_IN(mHunter) = mHunterCar
IF NOT bGotCarHealth
iCarHealth = GET_ENTITY_HEALTH(mHunterCar)
CPRINTLN(DEBUG_MISSION, "iCarHealth = ", iCarHealth)
bGotCarHealth = TRUE
ELSE
INT iCarHealthThisFrame = GET_ENTITY_HEALTH(mHunterCar)
//CPRINTLN(DEBUG_MISSION, "iCarHealthThisFrame = ", iCarHealthThisFrame)
IF iCarHealthThisFrame < iCarHealth // - 5
CPRINTLN(DEBUG_MISSION, "CAR HAS BEEN DAMAGED!")
KILL_FACE_TO_FACE_CONVERSATION()
// Say something
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_DAMCAR", CONV_PRIORITY_HIGH) // Careful!
// Reset health
bGotCarHealth = FALSE
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
BOOL bTyreBanterTimerStarted = FALSE
INT iTyreBanterStartTime
/// PURPOSE:
/// Triggers Cletus' banter as he walks to the tyre shooting balcony.
PROC MONITOR_WALK_TO_TYRE_CONVO()
IF NOT IS_PED_IN_ANY_VEHICLE(mHunter)
AND NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
IF NOT bTyreBanterTimerStarted
iTyreBanterStartTime = GET_GAME_TIMER() + 3000
bTyreBanterTimerStarted = TRUE
ELSE
IF GET_GAME_TIMER() > iTyreBanterStartTime
IF ARE_PEDS_IN_CONVO_RANGE()
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_TYRBAN", CONV_PRIORITY_MEDIUM) // Ever shot out the tyres on a car before?
bTriggeredConvo[HC_WALK_TO_TYRES] = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
PROC POPULATE_NAV_POINTS()
vNavPoint[0] = <<1524.5667, 3567.5020, 34.3611>>
vNavPoint[1] = <<1543.9569, 3572.7285, 34.3627>>
vNavPoint[2] = <<1561.8881, 3587.1011, 34.3606>>
vNavPoint[3] = <<1594.3850, 3598.8059, 34.4349>>
ENDPROC
/// PURPOSE:
/// Gets Cletus walking back to the spotter's position
/// if the player is being a dick and knocking him off
PROC MONITOR_HUNTERS_POSITION(SHOOT_LOCATION eLoc)
IF IS_PED_UNINJURED(mHunter)
SWITCH iKnockState
// Has the hunter been knocked
CASE 0
SWITCH eLoc
CASE DISH_LOC
IF NOT bChosenDish
IF IS_RANDOM_DISH_ALIVE()
CPRINTLN(DEBUG_MISSION, "Chosen a random dish")
bChosenDish = TRUE
ENDIF
ENDIF
IF bChosenDish
IF NOT IS_ENTITY_AT_COORD(mHunter, vHunterDishPos, <<1.5, 1.5, 1.5>>)
OR NOT IS_PED_HEADING_TOWARDS_POSITION(mHunter, mDish[iRandomDish].vSpawn, 30.0)
IF GET_SCRIPT_TASK_STATUS(mHunter, SCRIPT_TASK_FOLLOW_NAV_MESH_TO_COORD) <> PERFORMING_TASK
OR GET_SCRIPT_TASK_STATUS(mHunter, SCRIPT_TASK_FOLLOW_NAV_MESH_TO_COORD) <> FINISHED_TASK
CPRINTLN(DEBUG_MISSION, "Hunter knocked at dish location")
iKnockState = 1
ENDIF
ENDIF
ENDIF
BREAK
CASE TYRE_LOC
IF NOT IS_ENTITY_AT_COORD(mHunter, vHunterTyrePos, <<1.5, 1.5, 1.5>>) OR NOT IS_PED_CLOSE_TO_IDEAL_HEADING(mHunter, fPedTyreHeading, 30.0)
iKnockState = 1
ENDIF
BREAK
CASE COYOTE_LOC
IF NOT IS_ENTITY_AT_COORD(mHunter, vHunterCoyotePos, <<1.5, 1.5, 1.5>>) OR NOT IS_PED_CLOSE_TO_IDEAL_HEADING(mHunter, fPedCoyoteHeading, 30.0)
iKnockState = 1
ENDIF
BREAK
ENDSWITCH
BREAK
// Give the hunter orders to get back to his spot
CASE 1
IF HAS_HUNTER_PUT_BINOS_AWAY()
SWITCH eLoc
CASE DISH_LOC
TASK_FOLLOW_NAV_MESH_TO_COORD(mHunter, vHunterDishPos, PEDMOVEBLENDRATIO_WALK, 60000, DEFAULT_NAVMESH_RADIUS, ENAV_STOP_EXACTLY, mDish[iRandomDish].fHunterAngleToFace)
SET_PED_CAN_RAGDOLL_FROM_PLAYER_IMPACT(mHunter, FALSE)
BREAK
CASE TYRE_LOC
TASK_FOLLOW_NAV_MESH_TO_COORD(mHunter, vHunterTyrePos, PEDMOVEBLENDRATIO_WALK, 60000, DEFAULT_NAVMESH_RADIUS, ENAV_STOP_EXACTLY, fPedTyreHeading)
SET_PED_CAN_RAGDOLL_FROM_PLAYER_IMPACT(mHunter, FALSE)
BREAK
CASE COYOTE_LOC
TASK_FOLLOW_NAV_MESH_TO_COORD(mHunter, vHunterCoyotePos, PEDMOVEBLENDRATIO_WALK, 60000, DEFAULT_NAVMESH_RADIUS, ENAV_STOP_EXACTLY, fPedCoyoteHeading)
SET_PED_CAN_RAGDOLL_FROM_PLAYER_IMPACT(mHunter, FALSE)
BREAK
ENDSWITCH
iKnockState++
ENDIF
BREAK
CASE 2
IF GET_SCRIPT_TASK_STATUS(mHunter, SCRIPT_TASK_FOLLOW_NAV_MESH_TO_COORD) = FINISHED_TASK
SWITCH eLoc
CASE DISH_LOC
IF IS_PLAYER_USING_SNIPER_RIFLE()
MAKE_HUNTER_GET_BINOS_OUT(FALSE, TRUE)
ENDIF
eHunterState = HS_WATCH_PLAYER_SHOOT_DISHES
BREAK
CASE TYRE_LOC
MAKE_HUNTER_GET_BINOS_OUT(FALSE, FALSE)
eHunterState = HS_WATCH_PLAYER_SHOOT_TYRES
BREAK
CASE COYOTE_LOC
MAKE_HUNTER_GET_BINOS_OUT(FALSE, FALSE)
eHunterState = HS_WATCH_PLAYER_SHOOT_COYOTES
BREAK
ENDSWITCH
iKnockState = 0
ENDIF
BREAK
ENDSWITCH
ENDIF
ENDPROC
VEHICLE_INDEX mVeh
/// PURPOSE:
/// If the player is in a vehicle, checks to see if it has enough spare seats
PROC CHECK_PLAYER_VEHICLE()
IF IS_PED_SITTING_IN_ANY_VEHICLE(PLAYER_PED_ID())
IF NOT bDoneWrongCarComment
mVeh = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID())
IF NOT IS_PED_IN_ANY_VEHICLE(mHunter, TRUE)
IF NOT ARE_ANY_VEHICLE_SEATS_FREE(mVeh)
IF ARE_PEDS_IN_CONVO_RANGE()
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
// And where am I supposed to sit, huh?
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_NOCAR", CONV_PRIORITY_MEDIUM)
bDoneWrongCarComment = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
bDoneWrongCarComment = FALSE
ENDIF
ENDPROC
PROC BLOCK_DISH_PEDS()
// Scenario peds on stairs
CLEAR_AREA_OF_PEDS(vDishStairsPos, 3.0)
SET_PED_NON_CREATION_AREA(vDishStairsAreaA, vDishStairsAreaB)
// Scenario ped on dish balcony
CLEAR_AREA_OF_PEDS(vDishBlockPos, 3.0) // Getting rid of ambient peds on balcony.
SET_PED_NON_CREATION_AREA(vDishBlockAreaA, vDishBlockAreaB)
// Scenario ped at the fence
CLEAR_AREA_OF_PEDS(vFenceBlockPos, 3.0) // Getting rid of ambient peds on balcony.
SET_PED_NON_CREATION_AREA(vFenceBlockAreaA, vFenceBlockAreaB)
//bDishPedsBlocked = TRUE
ENDPROC
PROC BLOCK_TYRE_PEDS()
CPRINTLN(DEBUG_MISSION, "Clearing the motel area of peds...")
// Scenario peds on stairs
ADD_SCENARIO_BLOCKING_AREA(vCoyoteMotelA, vCoyoteMotelB)
SET_PED_NON_CREATION_AREA(vCoyoteMotelA, vCoyoteMotelB)
CLEAR_AREA_OF_PEDS(vTyreBlockPos, 5.0)
ENDPROC
RC_CONV_RESTORE_STATE stateRestoreConversation
TEXT_LABEL_23 tSavedConversationRoot
TEXT_LABEL_23 tSavedConversationLabel
// HUNTER STATES
/// PURPOSE:
/// Hunters state machine
PROC CHECK_HUNTER_STATES()
IF IS_PED_UNINJURED(PLAYER_PED_ID())
//check binoculars
MANAGE_BINOS()
CHECK_PLAYER_THREATENING()
CHECK_FOR_MURDER()
SWITCH eHunterState
CASE HS_NULL
BREAK
// Fail state, to tidy up the hunter.
CASE HS_PUT_BINOS_AWAY_AND_WANDER_OFF
MAKE_HUNTER_PUT_BINOS_AWAY(TRUE)
eHunterState = HS_NULL
BREAK
CASE HS_JUMP_AFTER_INTRO
CPRINTLN(DEBUG_MISSION, "Hunter state - HS_JUMP_AFTER_INTRO")
BLIP_HUNTER(TRUE, FALSE)
iPreDishConvoTime = GET_GAME_TIMER() + 2000
// Warp the hunter to his start position
SET_ENTITY_COORDS(mHunter, vHunterIntroSkipPos)
SET_ENTITY_HEADING(mHunter, fHunterIntroSkipHead)
CPRINTLN(DEBUG_MISSION, "Hunter state - HS_START_WALKING_TO_DISHES")
eHunterState = HS_START_WALKING_TO_DISHES
BREAK
CASE HS_START_WALKING_TO_DISHES
IF IS_PED_UNINJURED(mHunter)
IF HAVE_BINOS_BEEN_CREATED()
CPRINTLN(DEBUG_MISSION, "* * * * Hunter given walk command * * * *")
bHunterStartedWalking = TRUE
iPreDishConvoTime = GET_GAME_TIMER() + 5000
REMOVE_WEAPON_FROM_PED(mHunter, WEAPONTYPE_SNIPERRIFLE)
TASK_FOLLOW_NAV_MESH_TO_COORD(mHunter, vHunterDishPos, PEDMOVEBLENDRATIO_WALK, 60000, DEFAULT_NAVMESH_RADIUS, ENAV_STOP_EXACTLY, mDish[iRandomDish].fHunterAngleToFace)
SET_PED_CAN_RAGDOLL_FROM_PLAYER_IMPACT(mHunter, FALSE)
CPRINTLN(DEBUG_MISSION, "HS_WALK_TO_DISHES")
eHunterState = HS_WALK_TO_DISHES
ENDIF
ENDIF
BREAK
CASE HS_WALK_TO_DISHES
IF GET_SCRIPT_TASK_STATUS(mHunter, SCRIPT_TASK_FOLLOW_NAV_MESH_TO_COORD) = FINISHED_TASK
IF IS_ENTITY_AT_COORD(mHunter, vHunterDishPos, <<1.5, 1.5, 1.5>>)
CLEAR_PED_TASKS(mHunter)
TASK_LOOK_AT_ENTITY(mHunter, PLAYER_PED_ID(), -1, SLF_USE_TORSO)
SET_PED_CAN_RAGDOLL_FROM_PLAYER_IMPACT(mHunter, TRUE)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(mHunter, TRUE)
CPRINTLN(DEBUG_MISSION, "HS_GET_BINOS_OUT_FOR_DISHES")
eHunterState = HS_GET_BINOS_OUT_FOR_DISHES
ENDIF
ELSE
IF NOT bTriggeredConvo[HC_PRE_DISH_BANTER]
IF GET_GAME_TIMER() > iPreDishConvoTime
// I got just the thing. Lets raise some hell neighbor!
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_1", CONV_PRIORITY_MEDIUM, DISPLAY_SUBTITLES)
bTriggeredConvo[HC_PRE_DISH_BANTER] = TRUE
ENDIF
ENDIF
ELSE
HANDLE_CONVERSATION_AND_OBJECTIVE_TEXT_CONFLICT(stateRestoreConversation, mHunterConv, sTextBlock, tSavedConversationRoot, tSavedConversationLabel)
ENDIF
ENDIF
BREAK
CASE HS_JUMP_TO_SHOOT_DISHES
IF NOT IS_PED_INJURED(mHunter)
IF HAS_PED_GOT_WEAPON(mHunter, WEAPONTYPE_SNIPERRIFLE)
REMOVE_WEAPON_FROM_PED(mHunter, WEAPONTYPE_SNIPERRIFLE)
ENDIF
IF HAVE_BINOS_BEEN_CREATED()
IF IS_ENTITY_VISIBLE(mBinos)
SET_ENTITY_VISIBLE(mBinos, FALSE)
ENDIF
RESET_HUNTER_CONVOS()
RESET_GOOD_SHOT_CONVO()
SAFE_REMOVE_BLIP(mHunterBlip)
CLEAR_PED_TASKS_IMMEDIATELY(mHunter)
SET_ENTITY_COORDS(mHunter, vHunterDishPos)
SET_ENTITY_HEADING(mHunter, fPedDishHeading)
bSaidWrongGunComment = FALSE
CPRINTLN(DEBUG_MISSION, "HS_GET_BINOS_OUT_FOR_DISHES")
eHunterState = HS_GET_BINOS_OUT_FOR_DISHES
ENDIF
ENDIF
BREAK
CASE HS_GET_BINOS_OUT_FOR_DISHES
IF NOT bChosenDish
IF IS_RANDOM_DISH_ALIVE()
CPRINTLN(DEBUG_MISSION, "Chosen a random dish from HS_GET_BINOS_OUT_FOR_DISHES")
bChosenDish = TRUE
ENDIF
ELSE
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(),vDishShootAreaA, vDishShootAreaB, DISH_AREA_WIDTH, FALSE)
AND ARE_PEDS_IN_CONVO_RANGE()
IF IS_PLAYER_USING_SNIPER_RIFLE()
RESET_GUN_COMMENTS()
// Blast the three dishes
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_DIARR", CONV_PRIORITY_MEDIUM)
REPLAY_RECORD_BACK_FOR_TIME(2.0, 5.0, REPLAY_IMPORTANCE_HIGHEST)
iKnockState = 0
RESET_HUNTER_CONVOS()
bTriggeredConvo[HC_DISH_INSTRUCT] = TRUE
MAKE_HUNTER_GET_BINOS_OUT(TRUE, TRUE)
CPRINTLN(DEBUG_MISSION, "HS_WATCH_PLAYER_SHOOT_DISHES")
eHunterState = HS_WATCH_PLAYER_SHOOT_DISHES
ENDIF
ELSE
HANDLE_WRONG_GUN_CONVO()
ENDIF
ENDIF
ENDIF
BREAK
CASE HS_WATCH_PLAYER_SHOOT_DISHES
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
MONITOR_HUNTERS_POSITION(DISH_LOC)
ENDIF
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(),vDishShootAreaA, vDishShootAreaB, DISH_AREA_WIDTH, FALSE)
IF NOT bTriggeredConvo[HC_LEAVE_BEFORE_COMPLETE]
bTriggeredConvo[HC_LEAVE_BEFORE_COMPLETE] = FALSE
ENDIF
IF IS_PLAYER_USING_SNIPER_RIFLE()
RESET_GUN_COMMENTS()
COUNT_DEAD_DISHES()
IF bShownDishObjective
AND NOT IS_THIS_PRINT_BEING_DISPLAYED("HT_SHDISH")
CHECK_INACTIVITY(DISH_LOC)
ENDIF
IF iTargetsShot = 1 AND ARE_DISHES_BLIPPED() // Don't talk about shooting the dishes if it's too soon
IF NOT bSaidGoodShotLine[0]
// If the "Snipe the satelitte dishes" god text is still on screen
IF IS_THIS_PRINT_BEING_DISPLAYED("HT_SHDISH")
// Play the hunter's dialogue without subtitle.
IF PLAY_SINGLE_LINE_FROM_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_DISH", "HUNT1_DISH_1", CONV_PRIORITY_MEDIUM, DO_NOT_DISPLAY_SUBTITLES)
bChosenDish = FALSE
MAKE_HUNTER_PUT_BINOS_AWAY()
CPRINTLN(DEBUG_MISSION, "DeadDishes = 1")
bSaidGoodShotLine[0] = TRUE
ENDIF
ELIF PLAY_SINGLE_LINE_FROM_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_DISH", "HUNT1_DISH_1", CONV_PRIORITY_MEDIUM)
bChosenDish = FALSE
MAKE_HUNTER_PUT_BINOS_AWAY()
CPRINTLN(DEBUG_MISSION, "DeadDishes = 1")
bSaidGoodShotLine[0] = TRUE
ENDIF
ELSE
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
IF NOT bBinosOut
MAKE_HUNTER_GET_BINOS_OUT(FALSE, TRUE)
ENDIF
ENDIF
ENDIF
ELIF iTargetsShot = 2 AND ARE_DISHES_BLIPPED()
IF NOT bSaidGoodShotLine[1]
IF PLAY_SINGLE_LINE_FROM_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_DISH", "HUNT1_DISH_2", CONV_PRIORITY_MEDIUM)
bChosenDish = FALSE
MAKE_HUNTER_PUT_BINOS_AWAY()
CPRINTLN(DEBUG_MISSION, "DeadDishes = 2")
bSaidGoodShotLine[1] = TRUE
ENDIF
ELSE
IF NOT bBinosOut
MAKE_HUNTER_GET_BINOS_OUT(FALSE, TRUE)
ENDIF
ENDIF
ELIF iTargetsShot = 3
CPRINTLN(DEBUG_MISSION, "DeadDishes = 3")
IF NOT bSaidGoodShotLine[2]
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
// Well done boy, lead us up to the hotel
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_1A", CONV_PRIORITY_MEDIUM)
REPLAY_RECORD_BACK_FOR_TIME(2.0, 5.0, REPLAY_IMPORTANCE_HIGHEST)
bChosenDish = FALSE
bSaidGoodShotLine[2] = TRUE
bTriggeredConvo[HC_DISH_COMPLETE] = TRUE
CPRINTLN(DEBUG_MISSION, "HS_PUT_BINOS_AWAY_AFTER_DISHES")
MAKE_HUNTER_PUT_BINOS_AWAY()
eHunterState = HS_PUT_BINOS_AWAY_AFTER_DISHES
ENDIF
ENDIF
ENDIF
MONITOR_NEAR_MISSES()
ELSE
HANDLE_WRONG_GUN_CONVO()
ENDIF
ELSE
IF NOT bTriggeredConvo[HC_LEAVE_BEFORE_COMPLETE]
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_LAREA", CONV_PRIORITY_MEDIUM, DO_NOT_DISPLAY_SUBTITLES)
bTriggeredConvo[HC_LEAVE_BEFORE_COMPLETE] = TRUE
ENDIF
ENDIF
ENDIF
BREAK
CASE HS_PUT_BINOS_AWAY_AFTER_DISHES
IF HAS_HUNTER_PUT_BINOS_AWAY()
SET_HUNTER_TO_BUDDY_BEHAVIOUR(TRUE)
CPRINTLN(DEBUG_MISSION, "HS_FOLLOW_PLAYER_TO_MOTEL")
eHunterState = HS_FOLLOW_PLAYER_TO_MOTEL
ENDIF
BREAK
CASE HS_FOLLOW_PLAYER_TO_MOTEL
// Check that the player's vehicle is suitable
CHECK_PLAYER_VEHICLE()
// Check that we are still in the players group
IF IS_ENTITY_AT_ENTITY(mHunter, PLAYER_PED_ID(), vGroupRange)
// We should get out of here...
IF NOT bTriggeredConvo[HC_LEAVE_DISHES]
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(),vDishShootAreaA, vDishShootAreaB, DISH_AREA_WIDTH, FALSE)
MONITOR_LEAVE_DISHES_CONVO()
ELSE
bTriggeredConvo[HC_LEAVE_DISHES] = TRUE
ENDIF
ENDIF
// So what now...
IF bTriggeredObjectiveText[OT_GO_MOTEL]
AND bTriggeredConvo[HC_LEAVE_DISHES] = TRUE
AND NOT bTriggeredConvo[HC_AFTER_DISH_BANTER]
MONITOR_AFTER_DISH_BANTER()
ENDIF
// Motel is a fair old walk...
IF bTriggeredConvo[HC_AFTER_DISH_BANTER]
AND NOT bTriggeredConvo[HC_COMPLAIN]
MONITOR_NO_CAR_CONVO()
ENDIF
IF NOT bTriggeredConvo[HC_CAR_COMMENT]
MONITOR_CAR_COMMENT() // Hunter comments depending on who's car the player chooses.
ELSE
MONITOR_HUNTER_CAR_DAMAGE()
ENDIF
IF NOT bTriggeredConvo[HC_IN_CAR]
AND bTriggeredConvo[HC_AFTER_DISH_BANTER]
MONITOR_IN_CAR_CONVO()
ENDIF
ELSE
IF NOT bFalling
// If we aren't in the player's group
CLEAR_PED_TASKS(mHunter)
BLIP_HUNTER(TRUE, FALSE)
SET_HUNTER_TO_BUDDY_BEHAVIOUR(FALSE)
ePreState = HS_FOLLOW_PLAYER_TO_MOTEL
eHunterState = HS_WAIT_PLAYER_COME_BACK
ENDIF
ENDIF
BREAK
CASE HS_WAIT_PLAYER_COME_BACK
CHECK_HUNTER_WITH_PLAYER()
CHECK_PLAYER_VEHICLE()
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
IF IS_ENTITY_AT_ENTITY(mHunter, PLAYER_PED_ID(), vGroupReturnRange)
IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
OR ARE_ANY_VEHICLE_SEATS_FREE(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID(), FALSE))
// SHALL WE CONTINUE???
// TODO Dont trample the god text here...
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_ENCAR", CONV_PRIORITY_MEDIUM)
SAFE_REMOVE_BLIP(mHunterBlip)
//EXIT_WAITING_ANIMS()
SET_HUNTER_TO_BUDDY_BEHAVIOUR(TRUE)
//bReturningToPlayer = TRUE
eHunterState = ePreState
ENDIF
ELSE
CHECK_PLAYER_VEHICLE()
ENDIF
ELSE
//DO_WAITING_LINE()
//PLAY_WAITING_ANIMS()
ENDIF
ENDIF
BREAK
// Triggered from the player states
CASE HS_WALK_TO_TYRE_BALCONY
// Trigger the "Here we are" dialogue when we are close enough
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_TYARR", CONV_PRIORITY_MEDIUM)
// Block that annoying pole...
IF iPoleBlock = -1
iPoleBlock = ADD_NAVMESH_BLOCKING_OBJECT(vTyrePolePos, vTyrePoleSize, 0.0)
ENDIF
RESET_GUN_COMMENTS()
bTriggeredConvo[HC_FOLLOW_ME] = TRUE
SET_HUNTER_TO_BUDDY_BEHAVIOUR(FALSE)
BLIP_HUNTER(FALSE, FALSE)
iKnockState = 0
// Task the hunter to walk to the tyre shooting spotters point
TASK_LOOK_AT_ENTITY(mHunter, PLAYER_PED_ID(), -1, SLF_USE_TORSO)
TASK_FOLLOW_NAV_MESH_TO_COORD(mHunter, vHunterTyrePos, PEDMOVEBLENDRATIO_WALK, 60000, DEFAULT_NAVMESH_RADIUS, ENAV_STOP_EXACTLY, fPedTyreHeading)
SET_PED_CAN_RAGDOLL_FROM_PLAYER_IMPACT(mHunter, FALSE)
eHunterState = HS_GET_BINOS_OUT_FOR_TYRES
ENDIF
BREAK
CASE HS_JUMP_TO_SHOOT_TYRES
IF NOT IS_PED_INJURED(mHunter)
IF HAVE_BINOS_BEEN_CREATED()
IF IS_ENTITY_VISIBLE(mBinos)
SET_ENTITY_VISIBLE(mBinos, FALSE)
ENDIF
IF HAS_PED_GOT_WEAPON(mHunter, WEAPONTYPE_SNIPERRIFLE)
REMOVE_WEAPON_FROM_PED(mHunter, WEAPONTYPE_SNIPERRIFLE)
ENDIF
CLEAR_PED_TASKS_IMMEDIATELY(mHunter)
SET_ENTITY_COORDS(mHunter, vHunterTyrePos)
SET_ENTITY_HEADING(mHunter, fPedTyreHeading)
RESET_GUN_COMMENTS()
RESET_GOOD_SHOT_CONVO()
RESET_HUNTER_CONVOS()
SAFE_REMOVE_BLIP(mHunterBlip)
iKnockState = 0
RESET_GUN_COMMENTS()
bTriggeredConvo[HC_TYRE_INSTRUCT] = FALSE
eHunterState = HS_GET_BINOS_OUT_FOR_TYRES
ENDIF
ENDIF
BREAK
CASE HS_GET_BINOS_OUT_FOR_TYRES
IF GET_SCRIPT_TASK_STATUS(mHunter, SCRIPT_TASK_FOLLOW_NAV_MESH_TO_COORD) = FINISHED_TASK
IF IS_ENTITY_AT_COORD(mHunter, vHunterTyrePos, <<1.25, 1.25, 2.5>>)
AND IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(),vTyreShootAreaA, vTyreShootAreaB, TYRE_AREA_WIDTH, FALSE)
IF IS_PLAYER_USING_SNIPER_RIFLE()
// Pick a car and shoot a tyre
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_HERE", CONV_PRIORITY_MEDIUM)
OR iKnockState = 1
REPLAY_RECORD_BACK_FOR_TIME(3.0, 5.0, REPLAY_IMPORTANCE_HIGHEST)
iKnockState = 0
IF iPoleBlock != -1
REMOVE_NAVMESH_BLOCKING_OBJECT(iPoleBlock)
iPoleBlock = -1
ENDIF
RESET_GOOD_SHOT_CONVO()
bTriggeredConvo[HC_TYRE_INSTRUCT] = TRUE
MAKE_HUNTER_GET_BINOS_OUT(TRUE)
CPRINTLN(DEBUG_MISSION, "HS_WATCH_PLAYER_SHOOT_TYRES")
eHunterState = HS_WATCH_PLAYER_SHOOT_TYRES
ENDIF
ELSE
HANDLE_WRONG_GUN_CONVO()
ENDIF
ENDIF
ELSE
IF NOT bTriggeredConvo[HC_WALK_TO_TYRES]
MONITOR_WALK_TO_TYRE_CONVO()
ENDIF
ENDIF
BREAK
CASE HS_WATCH_PLAYER_SHOOT_TYRES
MONITOR_HUNTERS_POSITION(TYRE_LOC)
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(),vTyreShootAreaA, vTyreShootAreaB, TYRE_AREA_WIDTH, FALSE)
IF bTriggeredConvo[HC_LEAVE_BEFORE_COMPLETE]
bTriggeredConvo[HC_LEAVE_BEFORE_COMPLETE] = FALSE
ENDIF
IF IS_PLAYER_USING_SNIPER_RIFLE()
CHECK_INACTIVITY(TYRE_LOC)
IF bMissedTyreCar
IF GET_RANDOM_BOOL()
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_TYIN", CONV_PRIORITY_MEDIUM)
bMissedTyreCar = FALSE
bInactiveTimerStarted = FALSE
ENDIF
ELSE
bMissedTyreCar = FALSE
ENDIF
ENDIF
IF NOT bTriggeredConvo[HC_COY_KILL_IN_TYRE]
CHECK_COYOTE_KILL_IN_TYRE_SECTION()
ENDIF
IF iTargetsShot = 1 AND NOT bSaidGoodShotLine[0]
// That's it, a beauty! And again, Trevor!
IF PLAY_SINGLE_LINE_FROM_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_TYRE", "HUNT1_TYRE_1", CONV_PRIORITY_MEDIUM)
bSaidGoodShotLine[0] = TRUE
ENDIF
ELIF iTargetsShot = 2 AND NOT bSaidGoodShotLine[1]
// Nice! Go on, one more... just for the hell of it.
IF PLAY_SINGLE_LINE_FROM_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_TYRE", "HUNT1_TYRE_2", CONV_PRIORITY_MEDIUM)
bSaidGoodShotLine[1] = TRUE
ENDIF
ELSE
IF iTargetsShot = 3
IF NOT bSaidGoodShotLine[2]
IF iShotsFired <= 6 AND CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_TYR2", CONV_PRIORITY_MEDIUM) // Good shootin' boy. Right, follow me.
bSaidGoodShotLine[2] = TRUE
ELIF iShotsFired <= 10 AND CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_TRY3", CONV_PRIORITY_MEDIUM) // Not bad. Right, follow me
bSaidGoodShotLine[2] = TRUE
ELSE
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_TYR4", CONV_PRIORITY_MEDIUM) // Looks like you need more practice
bSaidGoodShotLine[2] = TRUE
ENDIF
ENDIF
ELSE
IF NOT IS_PLAYER_FREE_AIMING(PLAYER_ID())
REPLAY_RECORD_BACK_FOR_TIME(3.0, 4.0, REPLAY_IMPORTANCE_HIGHEST)
bTriggeredConvo[HC_TYRE_COMPLETE] = TRUE
MAKE_HUNTER_PUT_BINOS_AWAY()
CPRINTLN(DEBUG_MISSION, "HS_PUT_BINOS_AWAY_AFTER_TYRES")
eHunterState = HS_PUT_BINOS_AWAY_AFTER_TYRES
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
HANDLE_WRONG_GUN_CONVO()
ENDIF
ELSE
IF NOT bTriggeredConvo[HC_LEAVE_BEFORE_COMPLETE]
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_LAREA", CONV_PRIORITY_MEDIUM, DO_NOT_DISPLAY_SUBTITLES)
bTriggeredConvo[HC_LEAVE_BEFORE_COMPLETE] = TRUE
ENDIF
ENDIF
ENDIF
BREAK
CASE HS_PUT_BINOS_AWAY_AFTER_TYRES
//IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
IF HAS_HUNTER_PUT_BINOS_AWAY()
CPRINTLN(DEBUG_MISSION, "Hunter ready to go...")
// Task the hunter to walk to the balcony wait point
iNavPoint = 0
POPULATE_NAV_POINTS()
TASK_FOLLOW_NAV_MESH_TO_COORD(mHunter, vNavPoint[0], PEDMOVEBLENDRATIO_WALK, 60000, DEFAULT_NAVMESH_RADIUS)
SET_PED_CAN_RAGDOLL_FROM_PLAYER_IMPACT(mHunter, TRUE)
BLIP_HUNTER(FALSE, FALSE)
CPRINTLN(DEBUG_MISSION, "HS_WALK_TO_COLLAPSED_ROOF")
eHunterState = HS_WALK_TO_COLLAPSED_ROOF
ENDIF
BREAK
CASE HS_WALK_TO_COLLAPSED_ROOF
// Increase the walk speed...
SET_PED_MIN_MOVE_BLEND_RATIO(mHunter, 1.4)
// Do the hunter's convo
IF NOT bTriggeredConvo[HC_WALK_TO_WAIT]
IF ARE_PEDS_IN_CONVO_RANGE()
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
IF GET_DISTANCE_BETWEEN_COORDS( GET_ENTITY_COORDS (PLAYER_PED_ID(), FALSE), vTyreShootPos) > 10.0
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_3", CONV_PRIORITY_HIGH)
bTriggeredConvo[HC_WALK_TO_WAIT] = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
SWITCH iNavPoint
CASE 0
IF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(mHunter, vNavPoint[0], FALSE) < 2.0
TASK_FOLLOW_NAV_MESH_TO_COORD(mHunter, vNavPoint[1], PEDMOVEBLENDRATIO_WALK, 60000, DEFAULT_NAVMESH_RADIUS)
iNavPoint++
ENDIF
BREAK
CASE 1
IF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(mHunter, vNavPoint[1], FALSE) < 2.0
TASK_FOLLOW_NAV_MESH_TO_COORD(mHunter, vNavPoint[2], PEDMOVEBLENDRATIO_WALK, 60000, DEFAULT_NAVMESH_RADIUS)
iNavPoint++
ENDIF
BREAK
CASE 2 // Bottom of stairs
IF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(mHunter, vNavPoint[2], FALSE) < 2.0
TASK_FOLLOW_NAV_MESH_TO_COORD(mHunter, vNavPoint[3], PEDMOVEBLENDRATIO_WALK, 60000, DEFAULT_NAVMESH_RADIUS)
iNavPoint++
ENDIF
BREAK
CASE 3
IF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(mHunter, vNavPoint[3], FALSE) < 2.0
TASK_FOLLOW_NAV_MESH_TO_COORD(mHunter, vHunterBalconyWaitPos, PEDMOVEBLENDRATIO_WALK, 60000, DEFAULT_NAVMESH_RADIUS, ENAV_STOP_EXACTLY, fHunterWaitHeading)
iNavPoint++
ENDIF
BREAK
CASE 4
IF GET_SCRIPT_TASK_STATUS(mHunter, SCRIPT_TASK_FOLLOW_NAV_MESH_TO_COORD) = FINISHED_TASK
OR IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), vCollapsedPosA, vCollapsedPosB, COLLAPSED_WIDTH)
AND IS_ENTITY_IN_ANGLED_AREA(mHunter, vCollapsedPosA, vCollapsedPosB, COLLAPSED_WIDTH)
SET_PED_CAN_RAGDOLL_FROM_PLAYER_IMPACT(mHunter, FALSE)
CPRINTLN(DEBUG_MISSION, "HS_WAIT_AT_COLLAPSED_ROOF")
eHunterState = HS_WAIT_AT_COLLAPSED_ROOF
ENDIF
BREAK
ENDSWITCH
BREAK
CASE HS_JUMP_TO_COLLAPSED_ROOF
IF NOT IS_PED_INJURED(mHunter)
IF HAVE_BINOS_BEEN_CREATED()
IF IS_ENTITY_VISIBLE(mBinos)
SET_ENTITY_VISIBLE(mBinos, FALSE)
ENDIF
IF HAS_PED_GOT_WEAPON(mHunter, WEAPONTYPE_SNIPERRIFLE)
REMOVE_WEAPON_FROM_PED(mHunter, WEAPONTYPE_SNIPERRIFLE)
ENDIF
CLEAR_PED_TASKS_IMMEDIATELY(mHunter)
SET_ENTITY_COORDS(mHunter, vHunterBalconyWaitPos)
SET_ENTITY_HEADING(mHunter, fHunterBalconyWaitHead)
RESET_GOOD_SHOT_CONVO()
RESET_HUNTER_CONVOS()
BLIP_HUNTER(TRUE, FALSE)
CPRINTLN(DEBUG_MISSION, "JUMP - HS_WAIT_AT_COLLAPSED_ROOF")
eHunterState = HS_WAIT_AT_COLLAPSED_ROOF
ENDIF
ENDIF
BREAK
CASE HS_WAIT_AT_COLLAPSED_ROOF
// Wait for the player.
IF IS_PED_UNINJURED(PLAYER_PED_ID())
VECTOR vPos
vPos = GET_ENTITY_COORDS(PLAYER_PED_ID())
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), vCollapsedPosA, vCollapsedPosB, COLLAPSED_WIDTH)
OR vPos.z > 41.0 // Are we already on the roof?
// We'll get a better view from up here...
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT_ROOF", CONV_PRIORITY_MEDIUM)
CLEAR_PED_TASKS(mHunter)
// Task the hunter to walk to the balcony wait point
TASK_FOLLOW_NAV_MESH_TO_COORD(mHunter, vHunterCoyotePos, PEDMOVEBLENDRATIO_WALK, 60000, DEFAULT_NAVMESH_RADIUS, ENAV_STOP_EXACTLY, fPedCoyoteHeading)
bTriggeredConvo[HC_WAIT] = TRUE
SET_PED_CAN_RAGDOLL_FROM_PLAYER_IMPACT(mHunter, FALSE)
CPRINTLN(DEBUG_MISSION, "HS_GET_BINOS_OUT_FOR_COYOTES")
eHunterState = HS_GET_BINOS_OUT_FOR_COYOTES
ENDIF
ELSE
IF GET_SCRIPT_TASK_STATUS(mHunter, SCRIPT_TASK_TURN_PED_TO_FACE_ENTITY) <> PERFORMING_TASK
TASK_TURN_PED_TO_FACE_ENTITY(mHunter,PLAYER_PED_ID(), -1)
ENDIF
ENDIF
ENDIF
BREAK
CASE HS_GET_BINOS_OUT_FOR_COYOTES
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), vCoyoteShootAreaA, vCoyoteShootAreaB, COYOTE_AREA_WIDTH, FALSE)
IF GET_SCRIPT_TASK_STATUS(mHunter, SCRIPT_TASK_FOLLOW_NAV_MESH_TO_COORD) = FINISHED_TASK
//IF IS_ENTITY_AT_COORD(mHunter, vHunterCoyotePos, <<1.25, 1.25, 2.5>>)
// We got two packs of coyote down there...
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_COARR", CONV_PRIORITY_MEDIUM)
OR iTargetsShot > 0
OR iKnockState = 1
REPLAY_RECORD_BACK_FOR_TIME(3.0, 5.0, REPLAY_IMPORTANCE_HIGHEST)
iKnockState = 0
bTriggeredConvo[HC_COY_INSTRUCT] = TRUE
MAKE_HUNTER_GET_BINOS_OUT(TRUE)
RESET_GOOD_SHOT_CONVO()
CPRINTLN(DEBUG_MISSION, "HS_WATCH_PLAYER_SHOOT_COYOTES")
eHunterState = HS_WATCH_PLAYER_SHOOT_COYOTES
ENDIF
//ENDIF
ENDIF
ENDIF
BREAK
CASE HS_WATCH_PLAYER_SHOOT_COYOTES
MONITOR_HUNTERS_POSITION(COYOTE_LOC)
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(),vCoyoteShootAreaA, vCoyoteShootAreaB, COYOTE_AREA_WIDTH, FALSE)
IF bTriggeredConvo[HC_LEAVE_BEFORE_COMPLETE]
bTriggeredConvo[HC_LEAVE_BEFORE_COMPLETE] = FALSE
ENDIF
IF iTargetsShot >= TARGET_HITS_REQUIRED
AND NOT bGotDelayTimer
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
iDelayTime = GET_GAME_TIMER() + 2000
bGotDelayTimer = TRUE
ENDIF
IF IS_PLAYER_USING_SNIPER_RIFLE()
RESET_GUN_COMMENTS()
CHECK_INACTIVITY(COYOTE_LOC)
IF iTargetsShot = 1 AND NOT bTriggeredConvo[HC_SHOT_ONE_COYOTE]
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_FIRST", CONV_PRIORITY_MEDIUM)
IF bMissedCoyote
bMissedCoyote = FALSE
ENDIF
bTriggeredConvo[HC_SHOT_ONE_COYOTE] = TRUE
ENDIF
ENDIF
ENDIF
IF iTargetsShot = 2 AND NOT bTriggeredConvo[HC_SHOT_TWO_COYOTE]
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_SEC", CONV_PRIORITY_MEDIUM)
IF bMissedCoyote
bMissedCoyote = FALSE
ENDIF
bTriggeredConvo[HC_SHOT_TWO_COYOTE] = TRUE
ENDIF
ENDIF
ENDIF
IF bMissedCoyote
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_COYMIS", CONV_PRIORITY_MEDIUM)
bMissedCoyote = FALSE
ENDIF
ENDIF
ENDIF
ELSE
HANDLE_WRONG_GUN_CONVO()
ENDIF
ELSE
IF NOT bTriggeredConvo[HC_LEAVE_BEFORE_COMPLETE]
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_LAREA", CONV_PRIORITY_MEDIUM, DO_NOT_DISPLAY_SUBTITLES)
bTriggeredConvo[HC_LEAVE_BEFORE_COMPLETE] = TRUE
ENDIF
ENDIF
ENDIF
IF bGotDelayTimer
IF GET_GAME_TIMER() > iDelayTime
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
CPRINTLN(DEBUG_MISSION, "HS - Player has shot enough coyotes...")
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_FIN", CONV_PRIORITY_HIGH)
REPLAY_RECORD_BACK_FOR_TIME(3.0, 4.0, REPLAY_IMPORTANCE_HIGHEST)
MAKE_HUNTER_PUT_BINOS_AWAY()
eHunterState = HS_BINOS_AWAY_AFTER_COYOTE
ENDIF
ENDIF
ENDIF
BREAK
CASE HS_BINOS_AWAY_AFTER_COYOTE
IF HAS_HUNTER_PUT_BINOS_AWAY()
CPRINTLN(DEBUG_MISSION, "HS - Hunter has put binos away...")
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
AND NOT IS_AIMING_THROUGH_SNIPER_SCOPE(PLAYER_PED_ID())
TASK_TURN_PED_TO_FACE_ENTITY(mHunter, PLAYER_PED_ID(), -1)
bTriggeredConvo[HC_COY_COMPLETE] = TRUE
eHunterState = HS_DO_OUTRO_CONV
ELSE
CPRINTLN(DEBUG_MISSION, "HS - ...but a conversation is ongoing..")
ENDIF
ENDIF
BREAK
CASE HS_JUMP_SET_UP_OUTRO
IF IS_PED_UNINJURED(mHunter)
CLEAR_PED_TASKS_IMMEDIATELY(mHunter)
SET_ENTITY_COORDS(mHunter, vHunterOutroPos)
SET_ENTITY_HEADING(mHunter, fHunterOutroHead)
TASK_LOOK_AT_ENTITY(mHunter, PLAYER_PED_ID(), -1)
IF DOES_ENTITY_EXIST(mBinos)
SET_ENTITY_VISIBLE(mBinos, FALSE)
ENDIF
ELSE
CPRINTLN(DEBUG_MISSION, "HS - Hunter is injured")
ENDIF
CPRINTLN(DEBUG_MISSION, "HS - HS_DO_OUTRO_CONV")
eHunterState = HS_DO_OUTRO_CONV
BREAK
CASE HS_DO_OUTRO_CONV
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
IF NOT bTriggeredConvo[HC_OUTRO_CONVO]
// I reckon you should tag along...
IF CREATE_CONVERSATION(mHunterConv, sTextBlock, "HUNT1_4", CONV_PRIORITY_MEDIUM)
bTriggeredConvo[HC_OUTRO_CONVO] = TRUE
ENDIF
ELSE
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
IF IS_PED_UNINJURED(mHunter)
CLEAR_PED_TASKS(mHunter)
SET_PED_PATH_CAN_DROP_FROM_HEIGHT(mHunter, FALSE)
CPRINTLN(DEBUG_MISSION, "HUNTER IS WALKING AWAY")
OPEN_SEQUENCE_TASK(mWanderSeq)
TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, vWanderPoint1, PEDMOVEBLENDRATIO_WALK, 60000, DEFAULT_NAVMESH_RADIUS)
TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, vWanderPoint2, PEDMOVEBLENDRATIO_WALK, 60000, DEFAULT_NAVMESH_RADIUS)
TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, vWanderPoint3, PEDMOVEBLENDRATIO_WALK, 60000, DEFAULT_NAVMESH_RADIUS)
TASK_WANDER_STANDARD(NULL)
CLOSE_SEQUENCE_TASK(mWanderSeq)
TASK_PERFORM_SEQUENCE(mHunter, mWanderSeq)
CLEAR_SEQUENCE_TASK(mWanderSeq)
SET_PED_KEEP_TASK(mHunter, TRUE)
ENDIF
eHunterState = HS_NULL
ENDIF
ENDIF
ENDIF
BREAK
ENDSWITCH
// Checks for player attacking/killing/injuring Cletus
IF eMissionState <> MS_FAILED_WAIT_FOR_FADE
AND NOT bTriggeredConvo[HC_COY_COMPLETE]
AND eHunterState <> HS_DO_OUTRO_CONV
AND eHunterState <> HS_NULL
IF NOT bGotFailDelay
IF IS_PED_IN_MELEE_COMBAT(PLAYER_PED_ID())
OR IS_PED_PERFORMING_MELEE_ACTION(PLAYER_PED_ID())
IF IS_PED_RAGDOLL(mHunter)
KILL_ANY_CONVERSATION()
iFailDelay = GET_GAME_TIMER() + NICE_LITTLE_PAUSE
bGotFailDelay = TRUE
ENDIF
ENDIF
IF IS_ENTITY_DEAD(mHunter)
OR HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mHunter, PLAYER_PED_ID())
OR HAS_PED_BEEN_DAMAGED_BY_WEAPON(mHunter, WEAPONTYPE_INVALID , GENERALWEAPON_TYPE_ANYWEAPON)
OR IS_EXPLOSION_IN_SPHERE(EXP_TAG_DONTCARE, GET_ENTITY_COORDS(mHunter, FALSE), 10.0)
//OR IS_PED_RAGDOLL(mHunter)
KILL_ANY_CONVERSATION()
iFailDelay = GET_GAME_TIMER() + NICE_LITTLE_PAUSE
bGotFailDelay = TRUE
ENDIF
ELSE
IF GET_GAME_TIMER() > iFailDelay
IF DOES_ENTITY_EXIST(mHunter)
IF NOT IS_ENTITY_DEAD(mHunter)
CLEAR_PED_TASKS(mHunter)
TASK_SMART_FLEE_PED(mHunter, PLAYER_PED_ID(), 100, -1)
SET_PED_KEEP_TASK(mHunter, TRUE)
CPRINTLN(DEBUG_MISSION, "Mission Failed hunter injured Called from Hunter state ")
SET_MISSION_FAILED_REASON(FAIL_HUNTER_INJURED)
ELSE
CPRINTLN(DEBUG_MISSION, "Mission Failed hunter killed Called from hunter state ")
SET_MISSION_FAILED_REASON(FAIL_HUNTER_DEAD)
ENDIF
ENDIF
eHunterState = HS_NULL
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
// PLAYER STATES
PROC INIT_MISSION()
SET_PLAYER_CAN_BE_HASSLED_BY_GANGS(PLAYER_ID(), FALSE)
SET_EVERYONE_IGNORE_PLAYER(PLAYER_ID(), TRUE)
CREATE_REL_GROUP()
ADD_PED_FOR_DIALOGUE(mHunterConv, 2, PLAYER_PED_ID(), "TREVOR")
ADD_PED_FOR_DIALOGUE(mHunterConv, 3, mHunter, "CLETUS")
REQUEST_ANIMS()
REQUEST_SNIPER_RIFLE_ASSET()
REQUEST_DIALOGUE()
REQUEST_COYOTE_ASSETS()
TOGGLE_EMS(FALSE)
RESET_HUNTER_CONVOS()
RECORD_PLAYERS_GUN()
#IF IS_DEBUG_BUILD
s_skip_menu[0].sTxtLabel = "INTRO"
s_skip_menu[1].sTxtLabel = "SHOOT_DISHES"
s_skip_menu[2].sTxtLabel = "SHOOT_TYRES"
s_skip_menu[3].sTxtLabel = "SHOOT_COYOTE"
s_skip_menu[4].sTxtLabel = "OUTRO"
#ENDIF
IF IS_PED_UNINJURED(mHunter)
SET_ENTITY_LOD_DIST(mHunter, 200)
SET_PED_PATH_CAN_DROP_FROM_HEIGHT(mHunter, FALSE)
SET_PED_GROUP_MEMBER_PASSENGER_INDEX(mHunter, VS_FRONT_RIGHT)
SET_PED_CONFIG_FLAG(mHunter, PCF_CannotBeTargeted, TRUE)
SET_PED_CONFIG_FLAG(mHunter, PCF_ForcedToUseSpecificGroupSeatIndex, TRUE)
SET_PED_CONFIG_FLAG(mHunter, PCF_WillFlyThroughWindscreen, FALSE)
SET_PED_DIES_IN_WATER(mHunter, FALSE)
SET_PED_DEFAULT_COMPONENT_VARIATION(mHunter)
SET_PED_STAY_IN_VEHICLE_WHEN_JACKED(mHunter, TRUE)
SET_PED_CAN_BE_DRAGGED_OUT(mHunter, FALSE)
SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(mHunter, TRUE)
SET_PED_CAN_RAGDOLL_FROM_PLAYER_IMPACT(mHunter, FALSE)
SET_PED_CAN_USE_AUTO_CONVERSATION_LOOKAT(mHunter, TRUE)
SET_PED_GET_OUT_UPSIDE_DOWN_VEHICLE(mHunter, TRUE)
ENDIF
INT iReplayState
eSubState = SS_INIT
IF IS_REPLAY_IN_PROGRESS()
CPRINTLN(DEBUG_MISSION, "REPLAY IS IN PROGRESS")
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE)
iReplayState = GET_REPLAY_MID_MISSION_STAGE()
bLetPlayerRun = TRUE
iDeadPeds = 0
IF g_bShitSkipAccepted
CPRINTLN(DEBUG_MISSION, "SHIT SKIP ACCEPTED")
iReplayState++
ENDIF
SWITCH iReplayState
CASE CP_AFTER_MOCAP
CPRINTLN(DEBUG_MISSION, "START_REPLAY_SETUP MS_JUMP_SET_UP_AFTER_INTRO")
START_REPLAY_SETUP(vPlayerIntroSkipPos, fPlayerIntroSkipHead)
eMissionState = MS_JUMP_SET_UP_AFTER_INTRO
BREAK
CASE CP_BEFORE_DISHES
CPRINTLN(DEBUG_MISSION, "START_REPLAY_SETUP MS_JUMP_SET_UP_SHOOT_DISHES")
START_REPLAY_SETUP(vDishShootPos, fPedDishHeading)
eMissionState = MS_JUMP_SET_UP_SHOOT_DISHES
BREAK
CASE CP_AFTER_DISHES
CPRINTLN(DEBUG_MISSION, "START_REPLAY_SETUP MS_JUMP_SET_UP_SHOOT_TYRES")
START_REPLAY_SETUP(vTyreShootPos, fPedTyreHeading)
eMissionState = MS_JUMP_SET_UP_SHOOT_TYRES
BREAK
CASE CP_AFTER_TYRES
CPRINTLN(DEBUG_MISSION, "START_REPLAY_SETUP MS_JUMP_SET_UP_SHOOT_COYOTE")
START_REPLAY_SETUP(vPlayerBalconyWaitPos, fPlayerBalconyWaitHead)
eMissionState = MS_JUMP_SET_UP_SHOOT_COYOTE
BREAK
CASE CP_AFTER_COYOTES
CPRINTLN(DEBUG_MISSION, "START_REPLAY_SETUP MS_JUMP_SET_UP_OUTRO")
START_REPLAY_SETUP(vPlayerOutroPos, fPlayerOutroHead)
eMissionState = MS_MISSION_PASSED
BREAK
CASE CP_BEFORE_PASS
CPRINTLN(DEBUG_MISSION, "START_REPLAY_SETUP MS_JUMP_SET_UP_OUTRO")
START_REPLAY_SETUP(vPlayerOutroPos, fPlayerOutroHead)
eMissionState = MS_MISSION_PASSED
BREAK
DEFAULT
SCRIPT_ASSERT("Replay in progress: Unknown checkpoint selected")
BREAK
ENDSWITCH
ELSE
IF NOT bDishAssetsInMem
REQUEST_DISH_ASSETS()
ENDIF
eMissionState = MS_DO_LEAD_IN
ENDIF
ENDPROC
PROC DO_LEAD_IN()
IF NOT IS_GAMEPLAY_HINT_ACTIVE()
AND GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), mHunter) > HINT_CAM_OVERRIDE
iHintTimer = GET_GAME_TIMER() + 2000
IF IS_PED_UNINJURED(mHunter)
IF IS_PED_UNINJURED(PLAYER_PED_ID())
//SET_PLAYER_CONTROL(PLAYER_ID(), FALSE)
//TASK_TURN_PED_TO_FACE_COORD(PLAYER_PED_ID(), GET_ENTITY_COORDS(mHunter))
//TASK_FOLLOW_TO_OFFSET_OF_ENTITY(PLAYER_PED_ID(), mHunter, <<0.0, 2.0, 0.0>>, PEDMOVEBLENDRATIO_WALK)
//TASK_FOLLOW_NAV_MESH_TO_COORD(PLAYER_PED_ID(), GET_ENTITY_COORDS(mHunter), PEDMOVEBLENDRATIO_WALK, -1)
//SIMULATE_PLAYER_INPUT_GAIT(PLAYER_ID(), PEDMOVEBLENDRATIO_WALK, 2000)
ENDIF
SET_GAMEPLAY_ENTITY_HINT(mHunter, <<0,0,0>>, TRUE, 13000)
SET_GAMEPLAY_HINT_FOV(fHintFov)
SET_GAMEPLAY_HINT_FOLLOW_DISTANCE_SCALAR(fHintFollow)
SET_GAMEPLAY_HINT_BASE_ORBIT_PITCH_OFFSET(fHintPitchOrbit)
SET_GAMEPLAY_HINT_CAMERA_RELATIVE_SIDE_OFFSET(fHintSide)
SET_GAMEPLAY_HINT_CAMERA_RELATIVE_VERTICAL_OFFSET(fHintVert)
SET_GAMEPLAY_HINT_CAMERA_BLEND_TO_FOLLOW_PED_MEDIUM_VIEW_MODE(TRUE)
ENDIF
ELSE
IF IS_PED_UNINJURED(mHunter) AND IS_PED_UNINJURED(PLAYER_PED_ID())
IF GET_GAME_TIMER() > iHintTimer
OR GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), mHunter) <= HINT_CAM_OVERRIDE
IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), mHunter) <= HINT_CAM_OVERRIDE
CPRINTLN(DEBUG_MISSION, "TREV IS TOO CLOSE ")
ENDIF
iCutsceneState = 0
CPRINTLN(DEBUG_MISSION, "MS_RUN_INTRO")
eSubState = SS_INIT
eMissionState = MS_RUN_INTRO
ENDIF
ENDIF
ENDIF
ENDPROC
PROC RUN_INTRO()
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.0)
SWITCH eSubState
CASE SS_INIT
CPRINTLN(DEBUG_MISSION, "INTRO: SS_INIT")
IF HAVE_DISHES_BEEN_CREATED()
RC_REQUEST_CUTSCENE("Cletus_MCS_1_concat", TRUE)
CPRINTLN(DEBUG_MISSION, "iCutsceneState = 0")
eSubState = SS_ACTIVE
ENDIF
BREAK
CASE SS_ACTIVE
SWITCH iCutsceneState
CASE 0
IF RC_IS_CUTSCENE_OK_TO_START()
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
REGISTER_ENTITY_FOR_CUTSCENE(PLAYER_PED_ID(), sTrevor, CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
CPRINTLN(DEBUG_MISSION, "Registered Trevor for intro")
ENDIF
IF IS_ENTITY_ALIVE(mHunter)
REGISTER_ENTITY_FOR_CUTSCENE(mHunter, sCletusCS, CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED(sCletusCS, PLAYER_PED_ID())
mCletusGun = CREATE_WEAPON_OBJECT_FROM_PED_WEAPON_WITH_COMPONENTS(mHunter, WEAPONTYPE_SNIPERRIFLE)
CPRINTLN(DEBUG_MISSION, "Registered Hunter for intro")
ENDIF
IF DOES_ENTITY_EXIST(mCletusGun)
REGISTER_ENTITY_FOR_CUTSCENE(mCletusGun, "Daves_Rifle", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
CPRINTLN(DEBUG_MISSION, "Registered sniper rifle for intro")
ENDIF
// IF DOES_ENTITY_EXIST(mCletusGate)
// REGISTER_ENTITY_FOR_CUTSCENE(mCletusGate, "Cletus_gate", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
// CPRINTLN(DEBUG_MISSION, "DOOR - Registered cletus gate for intro")
// bGateOpened = TRUE
// ENDIF
// Start mocap scene
RC_CLEANUP_LAUNCHER()
START_CUTSCENE()
REPLAY_START_EVENT(REPLAY_IMPORTANCE_HIGHEST)
WAIT(0)
STOP_GAMEPLAY_HINT()
RESOLVE_VEHICLES_INSIDE_ANGLED_AREA(vResolveAreaA, vResolveAreaB, RESOLVE_AREA_WIDTH, vCarResolvePos, fCarResolveHeading)
RESOLVE_VEHICLES_INSIDE_ANGLED_AREA(vResolveAreaC, vResolveAreaD, RESOLVE_AREA_WIDTH, vCarResolvePos, fCarResolveHeading)
RESOLVE_VEHICLES_INSIDE_ANGLED_AREA(vResolveAreaE, vResolveAreaF, RESOLVE_AREA_WIDTH, vCarResolvePos, fCarResolveHeading)
RESOLVE_VEHICLES_INSIDE_ANGLED_AREA(vResolveAreaG, vResolveAreaH, RESOLVE_AREA_WIDTH, vCarResolvePos, fCarResolveHeading)
IF IS_ENTITY_ALIVE(mHunterCar)
SET_ENTITY_COORDS(mHunterCar, << 1806.7319, 3934.3525, 33.3275 >>)
SET_ENTITY_HEADING(mHunterCar, 76.1155)
ENDIF
//mCletusGate = GET_CLOSEST_OBJECT_OF_TYPE(<<1803.94, 3929.01, 33.72 >>, 2.0, PROP_FNCLINK_07GATE1, TRUE)
RC_START_CUTSCENE_MODE(vMocapIntroPos, TRUE, FALSE)
CPRINTLN(DEBUG_MISSION, "iCutsceneState = 1")
iCutsceneState++
ENDIF
BREAK
CASE 1
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY(sCletusCS, P_CLETUS_NECKLACE_S)
IF NOT bHunterStartedWalking
CPRINTLN(DEBUG_MISSION, "Hunter started walking in CASE 1")
SAFE_TELEPORT_ENTITY(mHunter, vHunterIntroSkipPos, fHunterIntroSkipHead)
eHunterState = HS_START_WALKING_TO_DISHES
bHunterStartedWalking = TRUE
ENDIF
ENDIF
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Daves_Rifle")
CPRINTLN(DEBUG_MISSION, "giving weapon object to player 444")
GIVE_WEAPON_OBJECT_TO_PED(mCletusGun, PLAYER_PED_ID())
//FORCE_PED_AI_AND_ANIMATION_UPDATE(PLAYER_PED_ID())
ENDIF
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY(sTrevor)
FORCE_PED_MOTION_STATE(PLAYER_PED_ID(), MS_ON_FOOT_WALK, FALSE, FAUS_CUTSCENE_EXIT)
SIMULATE_PLAYER_INPUT_GAIT(PLAYER_ID(), PEDMOVEBLENDRATIO_WALK, 2000)
bSetIntroExitState = TRUE
ENDIF
// IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Cletus_gate")
// CPRINTLN(DEBUG_MISSION, "INTRO: DOOR STUFF IS HAPPENING!!!!")
// DOOR_SYSTEM_SET_OPEN_RATIO(ENUM_TO_INT(DOORHASH_CLETUS_GATE), -0.8, TRUE, FALSE)
// DOOR_SYSTEM_SET_DOOR_STATE(ENUM_TO_INT(DOORHASH_CLETUS_GATE), DOORSTATE_UNLOCKED, TRUE, TRUE)
// ENDIF
// unfortunately the only way to ensure the mocap camera blends out to gameplay cam at a sensible position
// is to spam this until the player's character exit state has fired
IF NOT bSetIntroExitState
RESET_CAM()
ENDIF
DOOR_SYSTEM_SET_OPEN_RATIO(ENUM_TO_INT(DOORHASH_CLETUS_GATE), -0.8, TRUE, FALSE)
DOOR_SYSTEM_SET_DOOR_STATE(ENUM_TO_INT(DOORHASH_CLETUS_GATE), DOORSTATE_FORCE_LOCKED_THIS_FRAME, TRUE, TRUE)
IF HAS_CUTSCENE_FINISHED()
REPLAY_STOP_EVENT()
SET_PED_INFINITE_AMMO(PLAYER_PED_ID(), TRUE, WEAPONTYPE_SNIPERRIFLE)
CPRINTLN(DEBUG_MISSION, "INTRO: CASE 2")
iCutsceneState++
ENDIF
BREAK
CASE 2
IF WAS_CUTSCENE_SKIPPED()
AND IS_SCREEN_FADED_OUT()
CPRINTLN(DEBUG_MISSION, "WARPING HUNTER TO CUTSCENE SKIP POS")
SAFE_TELEPORT_ENTITY(mHunter, vHunterIntroSkipPos, fHunterIntroSkipHead)
eHunterState = HS_JUMP_AFTER_INTRO
ENDIF
IF NOT IS_CUTSCENE_PLAYING()
CPRINTLN(DEBUG_MISSION, "CUTSCENE IS NOT PLAYING")
iCutsceneState++
ENDIF
BREAK
CASE 3
CPRINTLN(DEBUG_MISSION, "INTRO: CASE 3")
IF IS_CUTSCENE_PLAYING()
STOP_CUTSCENE()
ELSE
IF HAS_CUTSCENE_LOADED()
REMOVE_CUTSCENE()
ENDIF
IF NOT bHunterStartedWalking
CPRINTLN(DEBUG_MISSION, "Hunter start walking from CASE 3")
eHunterState = HS_START_WALKING_TO_DISHES
ENDIF
RC_SET_ENTITY_PROOFS_FOR_CUTSCENE(sRCLauncherDataLocal, FALSE, FALSE)
RC_END_CUTSCENE_MODE(TRUE, FALSE)
eSubState = SS_CLEANUP
ENDIF
BREAK
ENDSWITCH
BREAK
CASE SS_SKIPPED
CPRINTLN(DEBUG_MISSION, "MS_RUN_INTRO: SS_SKIPPED")
SAFE_FADE_OUT()
KILL_ANY_CONVERSATION()
IF IS_SCREEN_FADED_OUT()
IF HAVE_DISHES_BEEN_CREATED()
IF IS_PED_UNINJURED(mHunter)
IF NOT bHunterStartedWalking
SAFE_TELEPORT_ENTITY(mHunter, vHunterIntroSkipPos, fHunterIntroSkipHead)
REMOVE_WEAPON_FROM_PED(mHunter, WEAPONTYPE_SNIPERRIFLE)
CLEAR_PED_TASKS(mHunter)
eHunterState = HS_START_WALKING_TO_DISHES
ENDIF
ENDIF
IF IS_PED_UNINJURED(PLAYER_PED_ID())
CLEAR_PED_TASKS(PLAYER_PED_ID())
ENDIF
RESET_CAM()
CPRINTLN(DEBUG_MISSION, "SS_CLEANUP")
eSubState = SS_CLEANUP
ENDIF
ENDIF
BREAK
CASE SS_CLEANUP
CPRINTLN(DEBUG_MISSION, "MS_RUN_INTRO: SS_CLEANUP")
BLOCK_DISH_PEDS()
BLIP_HUNTER(TRUE, FALSE)
bLetPlayerRun = TRUE
SAFE_FADE_IN()
// Follow Cletus.
PRINT_OBJ("HT_FOLL")
CHECK_CONVERSATION_AND_OBJECTIVE_TEXT_CONFLICT_NOW(stateRestoreConversation)
CPRINTLN(DEBUG_MISSION, "MS_GET_TO_DISH_SPOT")
eMissionState = MS_GET_TO_DISH_SPOT
BREAK
ENDSWITCH
ENDPROC
PROC JUMP_SET_UP_AFTER_INTRO
CPRINTLN(DEBUG_MISSION, "JUMP_SET_UP_AFTER_INTRO")
SWITCH eSubState
CASE SS_INIT
SAFE_FADE_OUT()
eSubState = SS_ACTIVE
BREAK
CASE SS_ACTIVE
IF IS_SCREEN_FADED_OUT()
IF IS_CUTSCENE_PLAYING()
STOP_CUTSCENE()
IF DOES_ENTITY_EXIST(mCletusGun)
DELETE_OBJECT(mCletusGun)
ENDIF
ENDIF
IF HAS_CUTSCENE_LOADED()
REMOVE_CUTSCENE()
ENDIF
IF NOT IS_REPLAY_BEING_SET_UP()
SAFE_TELEPORT_ENTITY(PLAYER_PED_ID(), vPlayerIntroSkipPos, fPlayerIntroSkipHead)
//WAIT_FOR_WORLD_TO_LOAD(vMocapIntroPos)
RESET_CAM()
ENDIF
SAFE_GIVE_SNIPER_TO_PLAYER()
CLEAR_AREA_OF_VEHICLES(vMocapIntroPos, 2.0)
REMOVE_ALL_TARGET_BLIPS()
eSubState = SS_CLEANUP
ENDIF
BREAK
CASE SS_CLEANUP
IF HAVE_DISHES_BEEN_CREATED()
END_REPLAY_SETUP()
BLOCK_DISH_PEDS()
RESET_SHOOTING_AREA()
iCutsceneState = 0
eHunterState = HS_JUMP_AFTER_INTRO
SAFE_FADE_IN()
// Follow the hunter.
PRINT_OBJ("HT_FOLL")
eSubState = SS_INIT
eMissionState = MS_GET_TO_DISH_SPOT
ENDIF
BREAK
ENDSWITCH
ENDPROC
PROC GET_TO_DISH_SPOT()
SET_FORCE_OBJECT_THIS_FRAME(vTankerAPos, fTankerRadius)
SET_FORCE_OBJECT_THIS_FRAME(vTankerBPos, fTankerRadius)
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.5)
//SET_SCENARIO_PED_DENSITY_MULTIPLIER_THIS_FRAME(0.0, 0.0)
//DRAW_DEBUG_AREA(vDishShootAreaA , vDishShootAreaB, DISH_AREA_WIDTH)
//DRAW_DEBUG_AREA(vResolveAreaA, vResolveAreaB, RESOLVE_AREA_WIDTH)
IF GET_FOLLOW_PED_CAM_VIEW_MODE() = CAM_VIEW_MODE_FIRST_PERSON
SET_PED_MAX_MOVE_BLEND_RATIO(PLAYER_PED_ID(), PEDMOVEBLENDRATIO_WALK)
ENDIF
// Are we in the right area?
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), vDishShootAreaA, vDishShootAreaB, DISH_AREA_WIDTH, TRUE)
IF bTriggeredConvo[HC_DISH_INSTRUCT]
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_BEFORE_DISHES, "Player has reached the satellite dishes")
IF IS_THIS_PRINT_BEING_DISPLAYED("HT_BKHTER")
OR IS_THIS_PRINT_BEING_DISPLAYED("HT_FOLL")
CLEAR_PRINTS()
ENDIF
DOOR_SYSTEM_SET_OPEN_RATIO(ENUM_TO_INT(DOORHASH_CLETUS_GATE), 0.0, TRUE, FALSE)
DOOR_SYSTEM_SET_DOOR_STATE(ENUM_TO_INT(DOORHASH_CLETUS_GATE), DOORSTATE_UNLOCKED, TRUE, TRUE)
CPRINTLN(DEBUG_MISSION, "MS_SHOOT_DISHES")
eMissionState = MS_SHOOT_DISHES
ENDIF
COUNT_DEAD_DISHES()
IF bWrongGunFail
eHunterState = HS_PUT_BINOS_AWAY_AND_WANDER_OFF
CPRINTLN(DEBUG_MISSION, "Setting mission failed, wrong gun")
SET_MISSION_FAILED_REASON(FAIL_WRONG_GUN)
ENDIF
IF iTargetsShot >= TARGET_HITS_REQUIRED
eMissionState = MS_DO_AFTER_DISH_CONVO
ENDIF
ELSE
// Check for cheating
INT i = 0
REPEAT MAX_DISHES i
CHECK_FOR_PLAYER_DAMAGE_WHEN_OUTSIDE_SHOOT(mDish[i].mObj)
ENDREPEAT
IF bShotFromWrongPlace
SET_MISSION_FAILED_REASON(FAIL_BAD_SHOT)
ENDIF
// Have we left the Hunter?
IF DOES_BLIP_EXIST(mHunterBlip)
IF NOT IS_BLIP_FLASHING(mHunterBlip)
IF NOT IS_ENTITY_AT_ENTITY(mHunter, PLAYER_PED_ID(), vGroupRange)
KILL_ANY_CONVERSATION()
BLIP_HUNTER(TRUE, FALSE)
PRINT_OBJ("HT_BKHTER") // Get back to the hunter
ENDIF
ELSE
// Have we abandoned the hunter completely?
IF HAS_PLAYER_ABANDONED_HUNTER()
SET_MISSION_FAILED_REASON(FAIL_LEFT_HUNT)
ENDIF
// Have we returned to the Hunter?
IF IS_ENTITY_AT_ENTITY(mHunter, PLAYER_PED_ID(), vGroupReturnRange)
BLIP_HUNTER(TRUE, FALSE)
// Clear the return message
IF IS_THIS_PRINT_BEING_DISPLAYED("HT_BKHTER") // Get back to the hunter
CLEAR_PRINTS()
ENDIF
// Follow the hunter.
PRINT_OBJ("HT_FOLL")
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
PROC JUMP_SET_UP_SHOOT_DISHES()
SWITCH eSubState
CASE SS_INIT
CPRINTLN(DEBUG_MISSION, "JUMP_SET_UP_SHOOT_DISHES has initialised")
SAFE_FADE_OUT()
eSubState = SS_ACTIVE
BREAK
CASE SS_ACTIVE
IF IS_SCREEN_FADED_OUT()
eHunterState = HS_JUMP_TO_SHOOT_DISHES
CLEAR_PED_TASKS_IMMEDIATELY(PLAYER_PED_ID())
IF NOT IS_REPLAY_BEING_SET_UP()
SAFE_TELEPORT_ENTITY(PLAYER_PED_ID(), vDishShootPos, fPedDishHeading)
//WAIT_FOR_WORLD_TO_LOAD(vDishShootPos)
ENDIF
SAFE_REMOVE_BLIP(mBlip)
SAFE_GIVE_SNIPER_TO_PLAYER()
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_BEFORE_DISHES, "Player has reached the satellite dishes")
IF HAVE_DISHES_BEEN_CREATED()
RESET_CAM()
BLOCK_DISH_PEDS()
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
eSubState = SS_CLEANUP
ENDIF
ENDIF
BREAK
CASE SS_CLEANUP
END_REPLAY_SETUP()
RESET_SHOOTING_AREA()
SAFE_FADE_IN()
bShownDishObjective = FALSE
CPRINTLN(DEBUG_MISSION, "JUMP TO MS_SHOOT_DISHES")
eMissionState = MS_SHOOT_DISHES
BREAK
ENDSWITCH
ENDPROC
PROC SHOOT_DISHES()
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.0)
SET_FORCE_OBJECT_THIS_FRAME(vTankerAPos, fTankerRadius)
SET_FORCE_OBJECT_THIS_FRAME(vTankerBPos, fTankerRadius)
//DRAW_DEBUG_AREA(vDishShootAreaA , vDishShootAreaB, DISH_AREA_WIDTH)
// Is the player in the right area
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), vDishShootAreaA, vDishShootAreaB, DISH_AREA_WIDTH, FALSE)
CHECK_PLAYER_AIMING()
COUNT_DEAD_DISHES()
COUNT_SHOTS_FIRED()
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() OR GET_PROFILE_SETTING(PROFILE_DISPLAY_SUBTITLES) = 0
IF NOT bShownDishObjective
SAFE_REMOVE_BLIP(mHunterBlip)
BLIP_DISHES()
PRINT_OBJ ("HT_SHDISH") // Shoot the satellite dishes
bShownDishObjective = TRUE
ENDIF
ENDIF
IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
AND (IS_ENTITY_AT_COORD(mHunter, vHunterDishPos, <<2.0, 2.0, 2.0>>) OR iTargetsShot >= TARGET_HITS_REQUIRED) //For B*2003361 progress mission if player snipes dishes if player pushed him off the balcony.
// This flag is set by the COUNT_DEAD_DISHES function
IF NOT bWrongGunFail
IF iTargetsShot >= TARGET_HITS_REQUIRED
CPRINTLN(DEBUG_MISSION, "MS_DO_AFTER_DISH_CONVO")
//For B*2003361 Set hunter into player's group if player pushed him off the balcony then sniped the dishes.
IF NOT IS_ENTITY_AT_COORD(mHunter, vHunterDishPos, <<2.0, 2.0, 2.0>>)
SET_HUNTER_TO_BUDDY_BEHAVIOUR(TRUE)
ENDIF
eMissionState = MS_DO_AFTER_DISH_CONVO
ENDIF
ELSE
eHunterState = HS_PUT_BINOS_AWAY_AND_WANDER_OFF
CPRINTLN(DEBUG_MISSION, "Setting mission failed, wrong gun")
SET_MISSION_FAILED_REASON(FAIL_WRONG_GUN)
ENDIF
ENDIF
ELSE // Player has left the area...
// So the hunter will remind the player
// when they return if unarmed or wrong gun
RESET_GUN_COMMENTS()
KILL_ANY_CONVERSATION()
CPRINTLN(DEBUG_MISSION, "Player left the shoot area...")
REMOVE_ALL_TARGET_BLIPS()
BLIP_HUNTER(TRUE, FALSE)
PRINT_OBJ("HT_BKHTER") // Get back to the hunter
eMissionState = MS_GET_BACK_TO_DISH_SPOT
ENDIF
ENDPROC
PROC GET_BACK_TO_DISH_SPOT()
SET_FORCE_OBJECT_THIS_FRAME(vTankerAPos, fTankerRadius)
SET_FORCE_OBJECT_THIS_FRAME(vTankerBPos, fTankerRadius)
// Are we in the right area?
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), vDishShootAreaA, vDishShootAreaB, DISH_AREA_WIDTH, TRUE)
// Has the hunter told us what to do yet?
IF bTriggeredConvo[HC_DISH_INSTRUCT]
bShownDishObjective = FALSE
IF IS_THIS_PRINT_BEING_DISPLAYED("HT_BKHTER")
CLEAR_PRINTS()
ENDIF
CPRINTLN(DEBUG_MISSION, "Player back in shoot area...")
eMissionState = MS_SHOOT_DISHES
ENDIF
ELSE
// Check for cheating
INT i = 0
REPEAT MAX_DISHES i
CHECK_FOR_PLAYER_DAMAGE_WHEN_OUTSIDE_SHOOT(mDish[i].mObj)
ENDREPEAT
IF bShotFromWrongPlace
SET_MISSION_FAILED_REASON(FAIL_BAD_SHOT)
ENDIF
// Have we abandoned the hunter completely?
IF HAS_PLAYER_ABANDONED_HUNTER()
SET_MISSION_FAILED_REASON(FAIL_LEFT_HUNT)
ENDIF
ENDIF
ENDPROC
PROC DO_AFTER_DISH_CONVO()
SET_FORCE_OBJECT_THIS_FRAME(vTankerAPos, fTankerRadius)
SET_FORCE_OBJECT_THIS_FRAME(vTankerBPos, fTankerRadius)
//SET_SCENARIO_PED_DENSITY_MULTIPLIER_THIS_FRAME(0.0, 0.0)
IF bTriggeredConvo[HC_DISH_COMPLETE]
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() OR GET_PROFILE_SETTING(PROFILE_DISPLAY_SUBTITLES) = 0
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_AFTER_DISHES, "Player has finished shooting all the satellite dishes")
// Unlock the hunter's car
IF DOES_ENTITY_EXIST(mHunterCar)
SET_VEHICLE_DOORS_LOCKED(mHunterCar, VEHICLELOCK_UNLOCKED)
ENDIF
IF iShotsFired <= MAX_DISHES
INFORM_MISSION_STATS_OF_INCREMENT(HU1_HIT_EACH_SATELLITE_FIRST_GO, 3, TRUE)
ENDIF
mBlip = CREATE_COORD_BLIP(vMotelPos)
PRINT_OBJ ("HT_NXTLOC") // Get to the ~y~abandoned motel.
bTriggeredObjectiveText[OT_GO_MOTEL] = TRUE
CPRINTLN(DEBUG_MISSION, "MS_GET_TO_TYRE_AREA")
eMissionState = MS_GET_TO_TYRE_AREA
ENDIF
ENDIF
ENDPROC
PROC GET_TO_TYRE_AREA()
SET_FORCE_OBJECT_THIS_FRAME(vTankerAPos, fTankerRadius)
SET_FORCE_OBJECT_THIS_FRAME(vTankerBPos, fTankerRadius)
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.5)
CHECK_HUNTER_WITH_PLAYER()
//SET_SCENARIO_PED_DENSITY_MULTIPLIER_THIS_FRAME(0.0, 0.0)
IF NOT bTyreCarAssetsInMem
REQUEST_TYRE_CAR_ASSETS()
ENDIF
IF NOT bTyreStairsSceneBlocked
IF IS_ENTITY_AT_COORD(PLAYER_PED_ID(), vMotelPos, << 50.0, 50.0, 50.0>>)
BLOCK_TYRE_PEDS()
bTyreStairsSceneBlocked = TRUE
ENDIF
ELSE
SET_SCENARIO_PED_DENSITY_MULTIPLIER_THIS_FRAME(0.0, 0.0)
ENDIF
// Are we in range of the hunter
IF NOT bPlayerLeftHunter
IF IS_ENTITY_AT_COORD(PLAYER_PED_ID(), vMotelPos, << 5.0, 5.0, 5.0 >> )
AND STOP_MY_VEHICLE()
// Clear any cars or scenario peds
SET_ALL_VEHICLE_GENERATORS_ACTIVE_IN_AREA(vTyreCarDestLeft, vTyreCarDestRight, FALSE)
SAFE_REMOVE_BLIP(mBlip)
CREATE_TYRE_CARS()
KILL_ANY_CONVERSATION()
RESET_SHOOTING_AREA()
CPRINTLN(DEBUG_MISSION, "HS_WALK_TO_TYRE_BALCONY")
eHunterState = HS_WALK_TO_TYRE_BALCONY
CPRINTLN(DEBUG_MISSION, "MS_FOLLOW_TO_TYRE_BALCONY")
eMissionState = MS_FOLLOW_TO_TYRE_BALCONY
ENDIF
ELSE
IF NOT bFalling
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
SAFE_REMOVE_BLIP(mBlip)
BLIP_HUNTER(FALSE, FALSE)
PRINT_OBJ("HT_BKHTER") // Get back to the hunter.
eMissionState = MS_BACK_TO_HUNTER_FOR_TYRES
ENDIF
ENDIF
ENDPROC
PROC BACK_TO_HUNTER_FOR_TYRES()
SET_FORCE_OBJECT_THIS_FRAME(vTankerAPos, fTankerRadius)
SET_FORCE_OBJECT_THIS_FRAME(vTankerBPos, fTankerRadius)
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.5)
//SET_SCENARIO_PED_DENSITY_MULTIPLIER_THIS_FRAME(0.0, 0.0)
CHECK_HUNTER_WITH_PLAYER()
IF NOT bPlayerLeftHunter
SAFE_REMOVE_BLIP(mHunterBlip)
mBlip = CREATE_COORD_BLIP(vMotelPos)
PRINT_OBJ("HT_NXTLOC") // Get to the abandoned motel.
CPRINTLN(DEBUG_MISSION, "MS_GET_TO_TYRE_AREA")
eMissionState = MS_GET_TO_TYRE_AREA
ENDIF
IF HAS_PLAYER_ABANDONED_HUNTER()
SET_MISSION_FAILED_REASON(FAIL_LEFT_HUNT)
ENDIF
ENDPROC
PROC FOLLOW_TO_TYRE_BALCONY()
SET_FORCE_OBJECT_THIS_FRAME(vTankerAPos, fTankerRadius)
SET_FORCE_OBJECT_THIS_FRAME(vTankerBPos, fTankerRadius)
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.0)
SET_SCENARIO_PED_DENSITY_MULTIPLIER_THIS_FRAME(0.0, 0.0)
IF GET_FOLLOW_PED_CAM_VIEW_MODE() = CAM_VIEW_MODE_FIRST_PERSON
SET_PED_MAX_MOVE_BLEND_RATIO(PLAYER_PED_ID(), PEDMOVEBLENDRATIO_WALK)
ENDIF
CHECK_CAR_STATES()
IF NOT bShotFromWrongPlace
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), vTyreShootAreaA, vTyreShootAreaB, TYRE_AREA_WIDTH, FALSE)
IF bTriggeredConvo[HC_TYRE_INSTRUCT]
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() OR GET_PROFILE_SETTING(PROFILE_DISPLAY_SUBTITLES) = 0
SAFE_REMOVE_BLIP(mHunterBlip)
RESET_GUN_COMMENTS()
bCanBlipTyreCars = TRUE
//bCheckInnocentKills = TRUE
PRINT_OBJ("HT_SHTYRE") // Shoot three tyres on the passing cars
eMissionState = MS_SHOOT_TYRES
ENDIF
ENDIF
ELSE
IF HAS_PLAYER_ABANDONED_HUNTER()
SET_MISSION_FAILED_REASON(FAIL_LEFT_HUNT)
ELSE
INT i = 0
REPEAT MAX_TYRE_CARS i
CHECK_FOR_PLAYER_DAMAGE_WHEN_OUTSIDE_SHOOT(mTyreCar[i].mCar)
ENDREPEAT
CHECK_HUNTER_WITH_PLAYER()
IF bPlayerLeftHunter
IF NOT bTriggeredObjectiveText[OT_RETURN_TO_CLETUS]
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
BLIP_HUNTER(TRUE, FALSE)
PRINT_OBJ("HT_BKHTER") // Get back to the hunter...
bTriggeredObjectiveText[OT_RETURN_TO_CLETUS] = TRUE
ENDIF
ELSE
IF bTriggeredObjectiveText[OT_RETURN_TO_CLETUS]
SAFE_REMOVE_BLIP(mHunterBlip)
bTriggeredObjectiveText[OT_RETURN_TO_CLETUS] = FALSE
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
PROC JUMP_SET_UP_SHOOT_TYRES()
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.0)
SWITCH eSubState
CASE SS_INIT
CPRINTLN(DEBUG_MISSION, "JUMP_SET_UP_SHOOT_TYRES has initialised")
SAFE_FADE_OUT()
eSubState = SS_ACTIVE
BREAK
CASE SS_ACTIVE
IF IS_SCREEN_FADED_OUT()
CPRINTLN(DEBUG_MISSION, "JUMP_SET_UP_SHOOT_TYRES is active")
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_AFTER_DISHES, "Player has finished shooting all the satellite dishes")
eHunterState = HS_JUMP_TO_SHOOT_TYRES
CLEAR_AREA_OF_VEHICLES(vRoadPos, 50.0)
CLEAR_AREA_OF_VEHICLES(vTyreCarDestLeft, 50.0)
CLEAR_AREA_OF_VEHICLES(vTyreCarDestRight, 50.0)
CLEAR_PED_TASKS_IMMEDIATELY(PLAYER_PED_ID())
RESET_GUN_COMMENTS()
RESET_HUNTER_CONVOS()
RESET_GOOD_SHOT_CONVO()
RELEASE_DISH_ASSETS()
SAFE_REMOVE_BLIP(mBlip)
SAFE_GIVE_SNIPER_TO_PLAYER()
iCarsInWorld = 0
IF NOT bTyreCarAssetsInMem
REQUEST_TYRE_CAR_ASSETS()
ENDIF
CREATE_TYRE_CARS()
IF NOT IS_REPLAY_BEING_SET_UP()
SAFE_TELEPORT_ENTITY(PLAYER_PED_ID(), vTyreShootPos, fPedTyreHeading)
RESET_CAM()
//WAIT_FOR_WORLD_TO_LOAD(vTyreShootPos)
ENDIF
eSubState = SS_CLEANUP
ENDIF
BREAK
CASE SS_CLEANUP
END_REPLAY_SETUP()
RESET_SHOOTING_AREA()
SAFE_FADE_IN()
IF bTriggeredConvo[HC_TYRE_INSTRUCT]
eMissionState = MS_SHOOT_TYRES
ENDIF
BREAK
ENDSWITCH
ENDPROC
PROC SHOOT_TYRES()
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.0)
CHECK_CAR_STATES()
COUNT_SHOTS_FIRED()
//DRAW_DEBUG_AREA(vTyreShootAreaA, vTyreShootAreaB, TYRE_AREA_WIDTH)
//DRAW_DEBUG_AREA(vTyreCarDestLeft, vTyreCarDestRight, TYRE_CAR_ROAD_WIDTH)
// Are we in the right area?
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), vTyreShootAreaA, vTyreShootAreaB, TYRE_AREA_WIDTH, FALSE)
IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
CHECK_PLAYER_AIMING()
IF NOT bCanBlipTyreCars
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
PRINT_OBJ("HT_SHTYRE") // Shoot three tyres on the passing cars
CPRINTLN(DEBUG_MISSION, "MS_SHOOT_TYRES From Skip")
bCanBlipTyreCars = TRUE
ENDIF
ENDIF
IF NOT bWrongGunFail
IF iTargetsShot >= TARGET_HITS_REQUIRED
CLEANUP_ACTIVE_TYRE_CARS()
IF bTriggeredConvo[HC_TYRE_COMPLETE]
CPRINTLN(DEBUG_MISSION, "iShotsFired is ", iShotsFired)
FLOAT fAccuracy = (300.0/TO_FLOAT(iShotsFired) )
CPRINTLN(DEBUG_MISSION, "fAccuracy is ", fAccuracy)
INT iAccuracy = CEIL(fAccuracy)
INFORM_MISSION_STATS_OF_INCREMENT(HU1_TYRE_SHOOTING_ACCURACY, iAccuracy, TRUE)
CPRINTLN(DEBUG_MISSION, "iAccuracy is ", iAccuracy)
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_AFTER_TYRES, "Player has finished shooting all the car tyres", TRUE)
RELEASE_TYRE_CAR_ASSETS()
bCanBlipTyreCars = FALSE
//bCheckInnocentKills = FALSE
CPRINTLN(DEBUG_MISSION, "MS_FOLLOW_TO_COLLAPSED_ROOF")
eMissionState = MS_FOLLOW_TO_COLLAPSED_ROOF
ENDIF
ENDIF
ELSE
eHunterState = HS_PUT_BINOS_AWAY_AND_WANDER_OFF
SET_MISSION_FAILED_REASON(FAIL_BAD_SHOT)
ENDIF
ENDIF
ELSE
RESET_GUN_COMMENTS()
REMOVE_ALL_TARGET_BLIPS()
BLIP_HUNTER(TRUE, FALSE)
PRINT_OBJ("HT_BKHTER") // Get back to the hunter
eMissionState = MS_FOLLOW_TO_TYRE_BALCONY
ENDIF
ENDPROC
// JUMP STATE
PROC JUMP_SET_UP_SHOOT_COYOTE()
SWITCH eSubState
CASE SS_INIT
SAFE_FADE_OUT()
// Request required assets...
REQUEST_AMBIENT_CAR_ASSETS()
eSubState = SS_ACTIVE
BREAK
CASE SS_ACTIVE
IF IS_SCREEN_FADED_OUT()
CREATE_COYOTES()
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_AFTER_TYRES, "Player has finished shooting all the car tyres", TRUE)
// Clean up previous assets...
RELEASE_DISH_ASSETS()
CLEANUP_ACTIVE_TYRE_CARS()
eHunterState = HS_JUMP_TO_COLLAPSED_ROOF
CLEAR_PED_TASKS_IMMEDIATELY(PLAYER_PED_ID())
RESET_HUNTER_CONVOS()
RESET_GOOD_SHOT_CONVO()
SAFE_GIVE_SNIPER_TO_PLAYER()
IF NOT IS_REPLAY_BEING_SET_UP()
SAFE_TELEPORT_ENTITY(PLAYER_PED_ID(), vPlayerBalconyWaitPos, fPlayerBalconyWaitHead)
//WAIT_FOR_WORLD_TO_LOAD(vPlayerBalconyWaitPos)
RESET_CAM()
ENDIF
eSubState = SS_CLEANUP
ENDIF
BREAK
CASE SS_CLEANUP
END_REPLAY_SETUP()
RESET_SHOOTING_AREA()
SAFE_FADE_IN()
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
eMissionState = MS_FOLLOW_TO_COLLAPSED_ROOF
BREAK
ENDSWITCH
ENDPROC
PROC FOLLOW_TO_COLLAPSED_ROOF()
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.5)
IF GET_FOLLOW_PED_CAM_VIEW_MODE() = CAM_VIEW_MODE_FIRST_PERSON
SET_PED_MAX_MOVE_BLEND_RATIO(PLAYER_PED_ID(), PEDMOVEBLENDRATIO_WALK)
ENDIF
CHECK_CAR_STATES()
//IF IS_ENTITY_AT_COORD(PLAYER_PED_ID(), vHunterBalconyWaitPos, vHunterWaitRadius )
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), vCollapsedPosA, vCollapsedPosB, COLLAPSED_WIDTH)
OR bTriggeredConvo[HC_WAIT]
CREATE_COYOTES()
RESET_SHOOTING_AREA()
CPRINTLN(DEBUG_MISSION, "MS_GET_TO_COYOTE_SPOT")
eMissionState = MS_GET_TO_COYOTE_SPOT
ENDIF
// Has the player killed any coyote?
INT i = 0
INT j = 0
REPEAT MAX_PACKS i
REPEAT MAX_PACK_MEMBERS j
CHECK_FOR_PLAYER_DAMAGE_WHEN_OUTSIDE_SHOOT(mPack[i].mCoyote[j].mCoyPed)
ENDREPEAT
ENDREPEAT
IF bShotFromWrongPlace
SET_MISSION_FAILED_REASON(FAIL_BAD_SHOT)
ENDIF
IF HAS_PLAYER_ABANDONED_HUNTER()
SET_MISSION_FAILED_REASON(FAIL_LEFT_HUNT)
ENDIF
ENDPROC
PROC GET_TO_COYOTE_SPOT()
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.25)
SET_SCENARIO_PED_DENSITY_MULTIPLIER_THIS_FRAME(0.0, 0.0)
MANAGE_THE_PACKS()
IF GET_FOLLOW_PED_CAM_VIEW_MODE() = CAM_VIEW_MODE_FIRST_PERSON
SET_PED_MAX_MOVE_BLEND_RATIO(PLAYER_PED_ID(), PEDMOVEBLENDRATIO_WALK)
ENDIF
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), vCoyoteShootAreaA, vCoyoteShootAreaB, COYOTE_AREA_WIDTH, FALSE)
//AND bTriggeredConvo[HC_COY_INSTRUCT]
CPRINTLN(DEBUG_MISSION, "MS_SHOOT_COYOTE")
REQUEST_AMBIENT_CAR_ASSETS()
eMissionState = MS_SHOOT_COYOTE
ELSE
// // Has the player killed any coyote?
INT i = 0
INT j = 0
REPEAT MAX_PACKS i
REPEAT MAX_PACK_MEMBERS j
CHECK_FOR_PLAYER_DAMAGE_WHEN_OUTSIDE_SHOOT(mPack[i].mCoyote[j].mCoyPed)
ENDREPEAT
ENDREPEAT
IF bShotFromWrongPlace
SET_MISSION_FAILED_REASON(FAIL_BAD_SHOT)
ENDIF
// Has the player wandered off?
IF HAS_PLAYER_ABANDONED_HUNTER()
SET_MISSION_FAILED_REASON(FAIL_LEFT_HUNT)
ENDIF
ENDIF
ENDPROC
PROC SHOOT_COYOTE()
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.0)
SET_SCENARIO_PED_DENSITY_MULTIPLIER_THIS_FRAME(0.0, 0.0)
MANAGE_THE_PACKS()
// Are we in the right place
IF iTargetsShot < TARGET_HITS_REQUIRED
IF NOT bWrongGunFail
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), vCoyoteShootAreaA, vCoyoteShootAreaB, COYOTE_AREA_WIDTH, FALSE)
CHECK_PLAYER_AIMING()
IF bTriggeredConvo[HC_COY_INSTRUCT]
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() OR GET_PROFILE_SETTING(PROFILE_DISPLAY_SUBTITLES) = 0
IF NOT bCanAddCoyoteBlips
// Shoot three coyote
IF iTargetsShot = 0
PRINT_OBJ("HT_SHCOY")
ELIF iTargetsShot = 1
PRINT_OBJ("HT_2MORE")
ELIF iTargetsShot = 2
PRINT_OBJ("HT_1MORE")
ENDIF
bCanAddCoyoteBlips = TRUE
ENDIF
ENDIF
ELSE
// If the player shoots coyotes too soon, FAIL.
IF (iTargetsShot != 0)
CPRINTLN(DEBUG_MISSION, "MS_SHOOT_COYOTE - SHOT COYOTES TOO SOON FAIL")
eHunterState = HS_PUT_BINOS_AWAY_AND_WANDER_OFF
SET_MISSION_FAILED_REASON(FAIL_BAD_SHOT)
ENDIF
ENDIF
ELSE
CPRINTLN(DEBUG_MISSION, "Player left hunter in SHOOT_COYOTE")
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
IF bCanAddCoyoteBlips
bCanAddCoyoteBlips = FALSE
ENDIF
BLIP_HUNTER(FALSE, FALSE)
PRINT_OBJ("HT_BKHTER") // Get back to the hunter.
// Get back to the hunter
eMissionState = MS_GET_TO_COYOTE_SPOT
ENDIF
ELSE
CPRINTLN(DEBUG_MISSION, "MS_SHOOT_COYOTE - WRONG GUN FAIL")
eHunterState = HS_PUT_BINOS_AWAY_AND_WANDER_OFF
SET_MISSION_FAILED_REASON(FAIL_WRONG_GUN)
ENDIF
ELSE
IF bCanAddCoyoteBlips
CPRINTLN(DEBUG_MISSION, "Shot enough coyotes")
bCanAddCoyoteBlips = FALSE
ENDIF
IF bTriggeredConvo[HC_COY_COMPLETE]
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() OR GET_PROFILE_SETTING(PROFILE_DISPLAY_SUBTITLES) = 0
IF NOT IS_AIMING_THROUGH_SNIPER_SCOPE(PLAYER_PED_ID())
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_BEFORE_PASS, "Player has finished shooting the coyote", TRUE)
CPRINTLN(DEBUG_MISSION, "Triggering Outro")
CREATE_AMBIENT_CARS()
//SET_PLAYER_CONTROL(PLAYER_ID(), FALSE, SPC_LEAVE_CAMERA_CONTROL_ON)
SET_HUNTER_TO_BUDDY_BEHAVIOUR(FALSE)
eSubState = SS_INIT
eMissionState = MS_RUN_OUTRO
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
PROC JUMP_SET_UP_OUTRO()
SWITCH eSubState
CASE SS_INIT
SAFE_FADE_OUT()
eSubState = SS_ACTIVE
BREAK
CASE SS_ACTIVE
IF IS_SCREEN_FADED_OUT()
// Get the hunter in the right spot.
eHunterState = HS_JUMP_SET_UP_OUTRO
IF IS_PED_UNINJURED(PLAYER_PED_ID())
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_BEFORE_PASS, "Player has finished shooting the coyote", TRUE)
CLEAR_PED_TASKS_IMMEDIATELY(PLAYER_PED_ID())
IF NOT IS_REPLAY_BEING_SET_UP()
SAFE_TELEPORT_ENTITY(PLAYER_PED_ID(), vPlayerOutroPos, fPlayerOutroHead)
//WAIT_FOR_WORLD_TO_LOAD(vCoyoteShootPos)
ENDIF
IF IS_PED_UNINJURED(mHunter)
TASK_LOOK_AT_ENTITY(PLAYER_PED_ID(), mHunter, -1)
ENDIF
SAFE_GIVE_SNIPER_TO_PLAYER()
SET_HUNTER_TO_BUDDY_BEHAVIOUR(FALSE)
ENDIF
CPRINTLN(DEBUG_MISSION, "HS_JUMP_SET_UP_OUTRO - SS_CLEANUP")
eSubState = SS_CLEANUP
ENDIF
BREAK
CASE SS_CLEANUP
END_REPLAY_SETUP()
SAFE_FADE_IN()
iCutsceneState = 0
CPRINTLN(DEBUG_MISSION, "MS_RUN_OUTRO called from skip")
eSubState = SS_INIT
eMissionState = MS_RUN_OUTRO
BREAK
ENDSWITCH
ENDPROC
PROC RUN_OUTRO()
SWITCH eSubState
CASE SS_INIT
END_REPLAY_SETUP()
IF NOT bReturnedPlayersGun
RETURN_PLAYERS_GUN()
ENDIF
eSubState = SS_ACTIVE
BREAK
CASE SS_ACTIVE
IF bTriggeredConvo[HC_OUTRO_CONVO]
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
eMissionState = MS_MISSION_PASSED
ENDIF
ENDIF
BREAK
ENDSWITCH
ENDPROC
/// PURPOSE: Check for Forced Pass or Fail
PROC DEBUG_Check_Debug_Keys()
#IF IS_DEBUG_BUILD
INT iMissionState
IF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_S))
CPRINTLN(DEBUG_MISSION, " *** DEBUG SKIP S *** ")
KILL_ANY_CONVERSATION()
CLEAR_PRINTS()
WAIT_FOR_CUTSCENE_TO_STOP()
eSubState = SS_INIT
eMissionState = MS_MISSION_PASSED
ENDIF
// Check for Fail
IF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_F))
CPRINTLN(DEBUG_MISSION, " *** DEBUG SKIP F *** ")
KILL_ANY_CONVERSATION()
CLEAR_PRINTS()
WAIT_FOR_CUTSCENE_TO_STOP()
SET_MISSION_FAILED_REASON(FAIL_NONE)
ENDIF
IF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_J))
CLEAR_PRINTS()
iMissionState = ENUM_TO_INT(eMissionState)
eSubState = SS_INIT
KILL_ANY_CONVERSATION()
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
CPRINTLN(DEBUG_MISSION, " *** DEBUG SKIP J *** ")
IF iMissionState < ENUM_TO_INT(MS_JUMP_SET_UP_AFTER_INTRO)
CPRINTLN(DEBUG_MISSION, "Debug skipping to Set Up After Intro")
eMissionState = MS_JUMP_SET_UP_AFTER_INTRO
ELIF iMissionState < ENUM_TO_INT(MS_SHOOT_DISHES)
CPRINTLN(DEBUG_MISSION, "Debug skipping to Set Up Shoot Dishes")
eMissionState = MS_JUMP_SET_UP_SHOOT_DISHES
ELIF iMissionState < ENUM_TO_INT(MS_SHOOT_TYRES)
CPRINTLN(DEBUG_MISSION, "Debug skipping to Set Up Shoot Tyres")
eMissionState = MS_JUMP_SET_UP_SHOOT_TYRES
ELIF iMissionState < ENUM_TO_INT(MS_FOLLOW_TO_COLLAPSED_ROOF)
CPRINTLN(DEBUG_MISSION, "Debug skipping to Set Up Shoot Coyote")
eMissionState = MS_JUMP_SET_UP_SHOOT_COYOTE
ELIF iMissionState < ENUM_TO_INT(MS_JUMP_SET_UP_OUTRO)
CPRINTLN(DEBUG_MISSION, "Debug skipping to Set Up Run Outro")
eMissionState = MS_JUMP_SET_UP_OUTRO
ELSE
CPRINTLN(DEBUG_MISSION, "Debug skipping to Mission Passed")
eMissionState = MS_MISSION_PASSED
ENDIF
ENDIF
IF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_P))
CPRINTLN(DEBUG_MISSION, " *** DEBUG SKIP P *** ")
CLEAR_PRINTS()
iMissionState = ENUM_TO_INT(eMissionState)
IF iMissionState >= ENUM_TO_INT(MS_RUN_OUTRO)
eMissionState = MS_JUMP_SET_UP_SHOOT_COYOTE
ELIF iMissionState >= ENUM_TO_INT(MS_SHOOT_COYOTE)
eMissionState = MS_JUMP_SET_UP_SHOOT_TYRES
ELIF iMissionState >= ENUM_TO_INT(MS_SHOOT_TYRES)
eMissionState = MS_JUMP_SET_UP_SHOOT_DISHES
ELSE
eMissionState = MS_JUMP_SET_UP_AFTER_INTRO
ENDIF
ENDIF
IF LAUNCH_MISSION_STAGE_MENU(s_skip_menu, i_debug_jump_stage)
SWITCH i_debug_jump_stage
CASE 0 i_debug_jump_stage = ENUM_TO_INT(MS_JUMP_SET_UP_AFTER_INTRO) BREAK // Intro
CASE 1 i_debug_jump_stage = ENUM_TO_INT(MS_JUMP_SET_UP_SHOOT_DISHES) BREAK // Shoot Dishes
CASE 2 i_debug_jump_stage = ENUM_TO_INT(MS_JUMP_SET_UP_SHOOT_TYRES) BREAK // Shoot Tyres
CASE 3 i_debug_jump_stage = ENUM_TO_INT(MS_JUMP_SET_UP_SHOOT_COYOTE) BREAK // Shoot Coyotes
CASE 4 i_debug_jump_stage = ENUM_TO_INT(MS_JUMP_SET_UP_OUTRO) BREAK // Outro
ENDSWITCH
KILL_ANY_CONVERSATION()
CLEAR_PRINTS()
WAIT_FOR_CUTSCENE_TO_STOP()
MISSION_STATE e_stage = INT_TO_ENUM(MISSION_STATE, i_debug_jump_stage)
eSubState = SS_INIT
eMissionState = e_stage
ENDIF
#ENDIF
ENDPROC
// SCRIPT LOOP
SCRIPT(g_structRCScriptArgs sRCLauncherDataIn)
CPRINTLN(DEBUG_MISSION, " *** hunting 1 script triggered *** ")
sRCLauncherDataLocal = sRCLauncherDataIn
RC_TakeEntityOwnership(sRCLauncherDataLocal)
SET_MISSION_FLAG(TRUE)
// Setup callback when player is killed, arrested or goes to multiplayer
IF HAS_FORCE_CLEANUP_OCCURRED(DEFAULT_FORCE_CLEANUP_FLAGS|FORCE_CLEANUP_FLAG_DEBUG_MENU|FORCE_CLEANUP_FLAG_REPEAT_PLAY)
PRINT_LAUNCHER_DEBUG("Force cleanup [TERMINATING]")
Random_Character_Failed()
Script_Cleanup()
TERMINATE_THIS_THREAD()
ENDIF
// Set up the initial scene for replays
IF Is_Replay_In_Progress()
g_bSceneAutoTrigger = TRUE
eInitialSceneStage = IS_REQUEST_SCENE
WHILE NOT SetupScene_HUNTING_1(sRCLauncherDataLocal)
WAIT(0)
ENDWHILE
RC_SET_ENTITY_PROOFS_FOR_CUTSCENE(sRCLauncherDataLocal, FALSE)
g_bSceneAutoTrigger = FALSE
ENDIF
mHunter = sRCLauncherDataLocal.pedID[0]
mHunterCar = sRCLauncherDataLocal.vehID[0]
RANDOM_CHAR_DISPLAY_MISSION_TITLE(RC_HUNTING_1)
// Add the relationship group and set up the relationship between groups
CREATE_REL_GROUP()
ADD_PED_FOR_DIALOGUE(mHunterConv, 2, PLAYER_PED_ID(), "TREVOR")
ADD_PED_FOR_DIALOGUE(mHunterConv, 3, mHunter, "CLETUS")
//INFORM_MISSION_STATS_OF_MISSION_START_HUNTING_1()
//SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(TRUE)
// Loop within here until the mission passes or fails
WHILE(TRUE)
REPLAY_CHECK_FOR_EVENT_THIS_FRAME("SF_TP")
UPDATE_MISSION_NAME_DISPLAYING(sRCLauncherDataLocal.sIntroCutscene)
//DRAW_DEBUG_AREA(vResolveAreaA, vResolveAreaB, RESOLVE_AREA_WIDTH) // Area the shows where cars will be cleaned up in the intro
//DRAW_DEBUG_AREA(vResolveAreaC, vResolveAreaD, RESOLVE_AREA_WIDTH) // Area the shows where cars will be cleaned up in the intro
//DRAW_DEBUG_AREA(vResolveAreaE, vResolveAreaF, RESOLVE_AREA_WIDTH) // Area the shows where cars will be cleaned up in the intro
//DRAW_DEBUG_AREA(vResolveAreaG, vResolveAreaH, RESOLVE_AREA_WIDTH) // Area the shows where cars will be cleaned up in the intro
//DRAW_DEBUG_AREA(vDishBlockAreaA, vDishBlockAreaB, 3.0)
//DRAW_DEBUG_AREA(vFenceBlockAreaA, vFenceBlockAreaB, 3.0)
//DRAW_DEBUG_AREA(vDishStairsAreaA, vDishStairsAreaB, 3.0)
//DRAW_DEBUG_AREA(vTyreBlockAreaA, vTyreBlockAreaB, 3.0)
//DRAW_DEBUG_AREA(vCletusHouseA, vCletusHouseB, CLETUS_HOUSE_WIDTH)
//DRAW_DEBUG_AREA(vTyreMotelA, vTyreMotelB, TYRE_MOTEL_WIDTH)
//DRAW_DEBUG_AREA(vCoyoteMotelA, vCoyoteMotelB, COYOTE_MOTEL_WIDTH)
//DRAW_DEBUG_AREA(vCollapsedPosA, vCollapsedPosB, COLLAPSED_WIDTH)
SET_ALL_RANDOM_PEDS_FLEE_THIS_FRAME(PLAYER_ID())
SET_ALL_NEUTRAL_RANDOM_PEDS_FLEE_THIS_FRAME(PLAYER_ID())
CHECK_HUNTER_STATES()
MONITOR_ACTION_ZONES()
IF NOT bLetPlayerRun
SET_PED_MAX_MOVE_BLEND_RATIO(PLAYER_PED_ID(), PEDMOVEBLENDRATIO_WALK)
//CPRINTLN(DEBUG_MISSION, "MAX MOVE SET TO WALK")
ENDIF
SWITCH eMissionState
CASE MS_INIT_MISSION INIT_MISSION() BREAK
CASE MS_DO_LEAD_IN DO_LEAD_IN() BREAK
CASE MS_RUN_INTRO RUN_INTRO() BREAK
CASE MS_JUMP_SET_UP_AFTER_INTRO JUMP_SET_UP_AFTER_INTRO() BREAK
CASE MS_GET_TO_DISH_SPOT GET_TO_DISH_SPOT() BREAK
CASE MS_JUMP_SET_UP_SHOOT_DISHES JUMP_SET_UP_SHOOT_DISHES() BREAK
CASE MS_SHOOT_DISHES SHOOT_DISHES() BREAK
CASE MS_GET_BACK_TO_DISH_SPOT GET_BACK_TO_DISH_SPOT() BREAK
CASE MS_DO_AFTER_DISH_CONVO DO_AFTER_DISH_CONVO() BREAK
CASE MS_GET_TO_TYRE_AREA GET_TO_TYRE_AREA() BREAK
CASE MS_BACK_TO_HUNTER_FOR_TYRES BACK_TO_HUNTER_FOR_TYRES() BREAK
CASE MS_FOLLOW_TO_TYRE_BALCONY FOLLOW_TO_TYRE_BALCONY() BREAK
CASE MS_JUMP_SET_UP_SHOOT_TYRES JUMP_SET_UP_SHOOT_TYRES() BREAK
CASE MS_SHOOT_TYRES SHOOT_TYRES() BREAK
CASE MS_FOLLOW_TO_COLLAPSED_ROOF FOLLOW_TO_COLLAPSED_ROOF() BREAK
CASE MS_GET_TO_COYOTE_SPOT GET_TO_COYOTE_SPOT() BREAK
CASE MS_JUMP_SET_UP_SHOOT_COYOTE JUMP_SET_UP_SHOOT_COYOTE() BREAK
CASE MS_SHOOT_COYOTE SHOOT_COYOTE() BREAK
CASE MS_JUMP_SET_UP_OUTRO JUMP_SET_UP_OUTRO() BREAK
CASE MS_RUN_OUTRO RUN_OUTRO() BREAK
CASE MS_MISSION_PASSED Script_Passed() BREAK
CASE MS_FAILED_WAIT_FOR_FADE FAILED_WAIT_FOR_FADE() BREAK
ENDSWITCH
WAIT(0)
#IF IS_DEBUG_BUILD
DEBUG_Check_Debug_Keys()
#ENDIF
ENDWHILE
// Script should never reach here. Always terminate with cleanup function.
ENDSCRIPT