8289 lines
307 KiB
XML
Executable File
8289 lines
307 KiB
XML
Executable File
//╒═════════════════════════════════════════════════════════════════════════════╕
|
|
//│ Author: Adam Westwood Date: 07/02/14 │
|
|
//│ Michael Wadelin Date: 10/09/14 │
|
|
//╞═════════════════════════════════════════════════════════════════════════════╡
|
|
//│ │
|
|
//│ Crowd Control Minigame │
|
|
//│ │
|
|
//│ Minigame for controlling a crowd │
|
|
//│ │
|
|
//│ │
|
|
//│ │
|
|
//╘═════════════════════════════════════════════════════════════════════════════╛
|
|
|
|
USING "timer_public.sch"
|
|
|
|
USING "rage_builtins.sch"
|
|
USING "globals.sch"
|
|
|
|
USING "commands_audio.sch"
|
|
USING "script_audio.sch"
|
|
USING "commands_camera.sch"
|
|
USING "commands_clock.sch"
|
|
USING "commands_debug.sch"
|
|
USING "commands_fire.sch"
|
|
USING "commands_graphics.sch"
|
|
USING "commands_hud.sch"
|
|
USING "commands_misc.sch"
|
|
USING "commands_object.sch"
|
|
USING "commands_pad.sch"
|
|
USING "commands_ped.sch"
|
|
USING "commands_player.sch"
|
|
USING "commands_script.sch"
|
|
USING "commands_streaming.sch"
|
|
USING "commands_task.sch"
|
|
USING "commands_vehicle.sch"
|
|
USING "commands_interiors.sch"
|
|
USING "net_include.sch"
|
|
USING "script_ped.sch"
|
|
|
|
USING "model_enums.sch"
|
|
USING "script_player.sch"
|
|
USING "script_misc.sch"
|
|
USING "selector_public.sch"
|
|
USING "timer_public.sch"
|
|
|
|
USING "LineActivation.sch"
|
|
|
|
USING "clothes_shop_private.sch"
|
|
USING "script_audio.sch"
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
USING "shared_debug.sch"
|
|
USING "script_debug.sch"
|
|
#ENDIF
|
|
|
|
|
|
|
|
// Enums
|
|
//----------------------------------------------------------------
|
|
|
|
ENUM CROWD_CONTROL_HEIST_TYPE
|
|
CCHEIST_NORMAL,
|
|
CCHEIST_CUSTOM_FLEECA,
|
|
CCHEIST_CUSTOM_ORNATE
|
|
ENDENUM
|
|
|
|
ENUM CROWD_CONTROL_PED_HERO_ACTION
|
|
CCHERO_NONE,
|
|
CCHERO_GUN,
|
|
CCHERO_PHONE,
|
|
CCHERO_ALARM
|
|
ENDENUM
|
|
|
|
ENUM CROWD_CONTROL_FAIL_REASON
|
|
CCFAIL_NONE,
|
|
CCFAIL_PEDHEROGUN,
|
|
CCFAIL_PEDHEROPHONE,
|
|
CCFAIL_PEDHEROALARM,
|
|
CCFAIL_PEDKILLED,
|
|
CCFAIL_PEDSKILLED,
|
|
CCFAIL_FEARLOW,
|
|
CCFAIL_TOOMANYKNOCKOUTS,
|
|
CCFAIL_NOHITSREMAINING
|
|
ENDENUM
|
|
|
|
ENUM CROWD_CONTROL_PED_ENUM
|
|
CCPED_CASHIER_A,
|
|
CCPED_CASHIER_B,
|
|
CCPED_CUSTOMER_A,
|
|
CCPED_CUSTOMER_B,
|
|
CCPED_CUSTOMER_C,
|
|
CCPED_CUSTOMER_D,
|
|
CCPED_CUSTOMER_E,
|
|
CCPED_CUSTOMER_F,
|
|
CCPED_CUSTOMER_G,
|
|
CCPED_CUSTOMER_H
|
|
ENDENUM
|
|
|
|
ENUM CROWD_CONTROL_PED_STATE
|
|
CCPS_INVALID = -1,
|
|
CCPS_INTRO,
|
|
CCPS_COWER,
|
|
CCPS_FLINCH,
|
|
CCPS_FLINCH_UNDERFIRE,
|
|
CCPS_BEATDOWN,
|
|
CCPS_HERO_ATTEMPT,
|
|
CCPS_HERO,
|
|
CCPS_COMBAT
|
|
ENDENUM
|
|
|
|
// List of all the anim types for the custom animated versions of the minigame
|
|
ENUM CROWD_CONTROL_PED_ANIM_TYPE
|
|
CCPANIM_INTRO_LOOP,
|
|
CCPANIM_INTRO,
|
|
CCPANIM_COWER_LOOP,
|
|
// Flinch
|
|
CCPANIM_COWER_TO_FLINCH_INTRO,
|
|
CCPANIM_FLINCH_LOOP,
|
|
CCPANIM_FLINCH_TO_IDLE_OUTRO,
|
|
// Flinch underfire
|
|
CCPANIM_COWER_TO_FLINCH_UNDERFIRE_INTRO,
|
|
CCPANIM_FLINCH_TO_FLINCH_UNDERFIRE_INTRO,
|
|
CCPANIM_FLINCH_UNDERFIRE_LOOP,
|
|
CCPANIM_FLINCH_UNDERFIRE_TO_FLINCH_OUTRO,
|
|
|
|
CCPANIM_BEATDOWN_INTRO,
|
|
CCPANIM_BEATDOWN_LOOP,
|
|
CCPANIM_BEATDOWN_HIT_A,
|
|
CCPANIM_BEATDOWN_HIT_B,
|
|
CCPANIM_BEATDOWN_DIE,
|
|
CCPANIM_BEATDOWN_DIE_LOOP,
|
|
CCPANIM_BEATDOWN_OUTRO,
|
|
CCPANIM_HERO_START,
|
|
CCPANIM_HERO_LOOP,
|
|
CCPANIM_HERO_PASS,
|
|
CCPANIM_HERO_FAIL
|
|
ENDENUM
|
|
|
|
// List of anims for the player ped to play in the custom anim version of this minigame
|
|
ENUM CROWD_CONTROL_PLAYER_ANIM_TYPE
|
|
CCPLAYERANIM_INVALID = -1,
|
|
CCPLAYERANIM_BEATDOWN_PISTOL_A,
|
|
CCPLAYERANIM_BEATDOWN_PISTOL_B,
|
|
CCPLAYERANIM_BEATDOWN_PISTOL_KICK_A,
|
|
CCPLAYERANIM_BEATDOWN_PISTOL_KICK_B,
|
|
CCPLAYERANIM_BEATDOWN_RIFLE_A,
|
|
CCPLAYERANIM_BEATDOWN_RIFLE_B,
|
|
CCPLAYERANIM_BEATDOWN_RIFLE_KICK_A,
|
|
CCPLAYERANIM_BEATDOWN_RIFLE_KICK_B,
|
|
CCPLAYERANIM_BEATDOWN_LONG_PISTOL_A,
|
|
CCPLAYERANIM_BEATDOWN_LONG_PISTOL_KICK_A,
|
|
CCPLAYERANIM_BEATDOWN_LONG_RIFLE_A,
|
|
CCPLAYERANIM_BEATDOWN_LONG_RIFLE_B,
|
|
CCPLAYERANIM_BEATDOWN_LONG_RIFLE_KICK_A,
|
|
CCPLAYERANIM_BEATDOWN_LONG_RIFLE_KICK_B
|
|
ENDENUM
|
|
|
|
|
|
// Represents the type of threat the player is imposing on a crowd control ped
|
|
ENUM CROWD_CONTROL_THREAT_TYPE
|
|
CCTHREAT_NONE,
|
|
CCTHREAT_PROXIMITY,
|
|
CCTHREAT_SHOUTING,
|
|
CCTHREAT_BEATING_NEIGHBOUR,
|
|
CCTHREAT_SHOUTING_CLOSE,
|
|
CCTHREAT_AIMED_AT,
|
|
CCTHREAT_BEATING,
|
|
CCTHREAT_SHOOTING,
|
|
CCTHREAT_KILLED_OTHER,
|
|
CCTHREAT_PROJECTILE_EXPLOSIVE,
|
|
CCTHREAT_PROJECTILE_EXPLOSIVE_STICKY_BOMB,
|
|
CCTHREAT_SHOOTING_CLOSE
|
|
ENDENUM
|
|
|
|
|
|
// PRIORITY ORDER
|
|
ENUM CROWD_CONTROL_DIALOGUE
|
|
CCDIA_NONE,
|
|
CCDIA_COWER_LOW_FEAR,
|
|
CCDIA_COWER_HIGH_FEAR,
|
|
CCDIA_APPROACH,
|
|
CCDIA_ALARM_GOES_OFF,
|
|
CCDIA_RECEIVES_SCARE,
|
|
CCDIA_STICKS_UP_FOR_OTHER,
|
|
CCDIA_SEES_OTHER_KILLED,
|
|
CCDIA_SHOT_NEAR,
|
|
CCDIA_SHOT_DIRECTLY_AT,
|
|
CCDIA_ALARM_GOES_OFF_INITIAL,
|
|
|
|
// Hero stuff should be higher than general stuff
|
|
CCDIA_HERO_ALARM_START,
|
|
CCDIA_HERO_ALARM_CAUGHT,
|
|
CCDIA_HERO_ALARM_COMPLETE,
|
|
CCDIA_HERO_GUN_START,
|
|
CCDIA_HERO_GUN_CAUGHT,
|
|
CCDIA_HERO_GUN_COMPLETE,
|
|
CCDIA_HERO_PHONE_START,
|
|
CCDIA_HERO_PHONE_CAUGHT,
|
|
CCDIA_HERO_PHONE_COMPLETE,
|
|
CCDIA_HERO_PHONE_APOLOGISE,
|
|
|
|
// 1 offs, high priority
|
|
CCDIA_INITIAL_PANIC
|
|
ENDENUM
|
|
|
|
|
|
// List of the different context timers
|
|
ENUM CROWD_CONTROL_DIALOGUE_CONTEXT
|
|
CCDIACONTEXT_SCARED_HIGH,
|
|
CCDIACONTEXT_SCARED_MEDIUM,
|
|
CCDIACONTEXT_SCARED_LOW,
|
|
CCDIACONTEXT_SCARED_SECOND_HAND,
|
|
CCDIACONTEXT_AMBIENT,
|
|
CCDIACONTEXT_NUM_CONTEXTS
|
|
ENDENUM
|
|
|
|
|
|
// List of all the sequences used to task the crowd ped animations
|
|
ENUM CROWD_CONTROL_SEQUENCES
|
|
CCSEQ_COWER_TO_FLINCH,
|
|
CCSEQ_COWER_TO_FLINCH_UNDERFIRE,
|
|
CCSEQ_FLINCH_TO_FLINCH_UNDERFIRE,
|
|
CCSEQ_FLINCH_UNDERFIRE_TO_FLINCH,
|
|
CCSEQ_FLINCH_TO_COWER,
|
|
// CCSEQ_OPEN_SAFE,
|
|
CCSEQ_HERO_START,
|
|
// CCSEQ_HERO_ALT,
|
|
CCSEQ_HERO_FAIL,
|
|
CCSEQ_HERO_PASS,
|
|
CCSEQ_BEATDOWN_TO_FLINCH,
|
|
CCSEQ_NUM_SEQUENCES
|
|
ENDENUM
|
|
|
|
|
|
// Server bitset flags
|
|
ENUM CROWD_CONTROL_DATA_BITSET_FLAGS
|
|
CCDATA_Active // 0
|
|
,CCDATA_Failed
|
|
,CCDATA_FailProcessed
|
|
,CCDATA_FailDisabled
|
|
,CCDATA_Restricted
|
|
,CCDATA_EasyPassComplete // 5
|
|
,CCDATA_EasyPassProcessed
|
|
,CCDATA_FearFailsBlocked
|
|
,CCDATA_RaiseAlarmDiagloue
|
|
#IF IS_DEBUG_BUILD
|
|
,CCDATA_DebugUnlimitedBeatings
|
|
,CCDATA_DebugDisableFails // 10
|
|
,CCDATA_RestrictedDebug
|
|
#ENDIF
|
|
ENDENUM
|
|
|
|
|
|
// Local bitset flags
|
|
ENUM CROWD_CONTROL_LOCAL_DATA_BITSET_FLAGS
|
|
CCLOCALDATA_IntroAnimsRequested // 0
|
|
,CCLOCALDATA_MainAnimsRequested
|
|
,CCLOCALDATA_StartedFailCutscene
|
|
,CCLOCALDATA_RecievedSyncedScene
|
|
,CCLOCALDATA_HelpText1
|
|
,CCLOCALDATA_HelpText2 // 5
|
|
,CCLOCALDATA_HelpText3
|
|
,CCLOCALDATA_DisplayHUD
|
|
,CCLOCALDATA_Initialised
|
|
,CCLOCALDATA_RaiseAlarms
|
|
,CCLOCALDATA_AlarmsPlaying // 10
|
|
,CCLOCALDATA_AwardGiven
|
|
,CCLOCALDATA_BeatdownInterrupt
|
|
,CCLOCALDATA_BeatdownFirst
|
|
,CCLOCALDATA_BeatdownInputTaken
|
|
,CCLOCALDATA_BeatdownProbeResultAllowHit // 15
|
|
,CCLOCALDATA_HUDWarning
|
|
,CCLOCALDATA_TimerSetFearFail
|
|
,CCLOCALDATA_TimerSetFearUnblocked
|
|
,CCLOCALDATA_TimeSetNextHeroPick
|
|
,CCLOCALDATA_BlockingActionMode // 20
|
|
#IF IS_DEBUG_BUILD
|
|
,CCLOCALDATA_DebugLogDialogue
|
|
#ENDIF
|
|
ENDENUM
|
|
|
|
|
|
|
|
// Server ped data bit flags
|
|
ENUM CROWD_CONTROL_PED_DATA_BITSET_FLAGS
|
|
CCPEDDATA_HasBeenInitialised
|
|
,CCPEDDATA_RunningBespokeAnims
|
|
,CCPEDDATA_KnockedOut
|
|
,CCPEDDATA_Dead
|
|
,CCPEDDATA_DeadProcessed
|
|
,CCPEDDATA_FearLocked
|
|
,CCPEDDATA_HeroComplete
|
|
,CCPEDDATA_HeroBroken
|
|
,CCPEDDATA_HeroAttempted
|
|
,CCPEDDATA_BeatdownSyncSceneStarted
|
|
,CCPEDDATA_IgnoreStickyBombs
|
|
ENDENUM
|
|
|
|
// Local ped data bit flags
|
|
ENUM CROWD_CONTROL_LOCAL_PED_DATA_BITSET_FLAGS
|
|
CCLOCALPEDDATA_OwnThisPed
|
|
,CCLOCALPEDDATA_LocallyInitialised
|
|
,CCLOCALPEDDATA_DialogueClientToHostForcePain
|
|
,CCLOCALPEDDATA_DialogueClientToHostForceCritical
|
|
,CCLOCALPEDDATA_DialogueHostToClientInterrupt
|
|
,CCLOCALPEDDATA_DialogueHostToClientPain
|
|
,CCLOCALPEDDATA_ShotAtFearWasClose
|
|
,CCLOCALPEDDATA_TimeLastThreatenedSet
|
|
,CCLOCALPEDDATA_TimeLastShotAtSet
|
|
,CCLOCALPEDDATA_TimeLastBeatSet
|
|
,CCLOCALPEDDATA_TimeSetStartThreaten
|
|
,CCLOCALPEDDATA_TimeSetHoldBeforeEscape
|
|
,CCLOCALPEDDATA_TimeSetStartFearProjectile
|
|
,CCLOCALPEDDATA_TimeSetStartProximityThreat
|
|
,CCLOCALPEDDATA_TimeSetShootingCloseFlinching
|
|
,CCLOCALPEDDATA_BeatdownFired
|
|
,CCLOCALPEDDATA_HeroPropDetatchedForLastTime
|
|
ENDENUM
|
|
|
|
ENUM CROWD_CONTROL_PED_DECORATOR
|
|
CCPDECOR_iState
|
|
,CCPDECOR_iStatePrev
|
|
,CCPDECOR_iBitSet
|
|
,CCPDECOR_fInfluenceDirectThreat
|
|
,CCPDECOR_fInfluenceShouting
|
|
,CCPDECOR_iBeatdownHitsRemaining
|
|
,CCPDECOR_iBeatdownRounds
|
|
ENDENUM
|
|
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
|
|
ENUM CROWD_CONTROL_DEBUG_DISPLAY
|
|
CCDEBUG_OFF = -1,
|
|
CCDEBUG_ALL,
|
|
CCDEBUG_BASIC,
|
|
CCDEBUG_FEAR_AND_THREATS,
|
|
CCDEBUG_HERO,
|
|
CCDEBUG_BEATDOWNS,
|
|
CCDEBUG_DIALOGUE,
|
|
CCDEBUG_MISC,
|
|
CCDEBUG_NUM_DEBUG
|
|
ENDENUM
|
|
|
|
#ENDIF
|
|
|
|
|
|
// Constants
|
|
//----------------------------------------------------------------
|
|
|
|
CONST_INT ciCC_MaxActiveHeros 1
|
|
CONST_FLOAT cfCC_ShoutVolumeLevel 0.75
|
|
|
|
CONST_INT ciCC_DialogueBroadcastDelay 2000
|
|
CONST_INT ciCC_MaxNumberOfAmbientDialogue 1
|
|
CONST_INT ciCC_MaxNumberOfPain 3
|
|
CONST_INT ciCC_MaxNumberOfSpeakers ciCC_MaxNumberOfAmbientDialogue + ciCC_MaxNumberOfPain
|
|
|
|
CONST_INT ciCC_MaxBeatdownHits 2
|
|
CONST_INT ciCC_MaxBeatdownHitsTotal 6
|
|
CONST_INT ciCC_BeatdownHitsLostOnPedDeath 3
|
|
TWEAK_FLOAT cfCC_BeatdownDistMin 0.5
|
|
TWEAK_FLOAT cfCC_BeatdownDistMax 1.5
|
|
TWEAK_FLOAT cfCC_BeatdownLongAnimDistThreshold 1.25
|
|
TWEAK_FLOAT cfCC_BeatdownMeleeDisableDist 2.0
|
|
TWEAK_FLOAT cfCC_BeatdownFacingAngleChangeDistMin 0.75
|
|
TWEAK_FLOAT cfCC_BeatdownFacingAngleChangeDistMax 1.3
|
|
TWEAK_FLOAT cfCC_BeatdownFacingAngleRangeMin 23.5
|
|
TWEAK_FLOAT cfCC_BeatdownFacingAngleRangeMax 80.0
|
|
|
|
CONST_FLOAT cfCC_PlayerPedCapsuleRadiusStationary 0.25
|
|
|
|
CONST_FLOAT cfCC_PedBreakoutCowerThreshold 25.0
|
|
CONST_INT ciCC_PedThreatenCoolOffDuration 2000
|
|
CONST_INT ciCC_PedShotAtCoolOffDuration 1000
|
|
CONST_INT ciCC_PedShotAtCoolOffDurationClose 3000
|
|
CONST_INT ciCC_ProjectileCoolOffDuration 6000
|
|
CONST_INT ciCC_ProximityCoolOffDuration 5000
|
|
|
|
CONST_INT ciCC_FearFailMin 0
|
|
|
|
TWEAK_FLOAT cfCC_FearIncreaseRateMin 1.0
|
|
TWEAK_FLOAT cfCC_FearIncreaseRateMax 8.0
|
|
TWEAK_FLOAT cfCC_FearDecreaseRateMin 0.5
|
|
TWEAK_FLOAT cfCC_FearDecreaseRateMax 4.0
|
|
|
|
CONST_INT ciCC_Range 30
|
|
|
|
CONST_INT ciCC_ThreatTypeDataBitWidth 4 // max 16 numbers/states
|
|
CONST_INT ciCC_DialogueDataBitWidth 5 // max 32 numbers/states
|
|
CONST_INT ciCC_HeroAttemptsDataBitWidth 6 // max 64 numbers/states
|
|
|
|
CONST_INT ciCC_MaxAlarms 2
|
|
|
|
ANIMATION_FLAGS eCrowdControlAnimFlags = AF_USE_KINEMATIC_PHYSICS | AF_USE_MOVER_EXTRACTION // | AF_NOT_INTERRUPTABLE
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
|
|
TWEAK_INT ciCC_DebugColNormalR 0
|
|
TWEAK_INT ciCC_DebugColNormalG 0
|
|
TWEAK_INT ciCC_DebugColNormalB 255
|
|
|
|
TWEAK_INT ciCC_DebugColWarningR 30
|
|
TWEAK_INT ciCC_DebugColWarningG 255
|
|
TWEAK_INT ciCC_DebugColWarningB 255
|
|
|
|
TWEAK_INT ciCC_DebugColActiveR 190
|
|
TWEAK_INT ciCC_DebugColActiveG 0
|
|
TWEAK_INT ciCC_DebugColActiveB 255
|
|
|
|
#ENDIF
|
|
|
|
|
|
// Structs
|
|
//----------------------------------------------------------------
|
|
|
|
STRUCT CROWD_CONTROL_SERVER_DATA
|
|
|
|
INT iMinigameStage = 0
|
|
INT iCrowdControlCloudIndex[FMMC_MAX_CROWD_PEDS] // can this be cached locally?
|
|
FLOAT fFear = -1.0 // the overall fear level of the crowd
|
|
INT iBitSet = 0
|
|
INT iCurrentActiveHeros = 0
|
|
INT iHeroAttempts[2] // use 6 bits per ped to save storage (instead of an int per ped i.e. 10 ints)
|
|
INT iSyncScene = -1
|
|
INT iPedIsNowInvolvedInCrowdControl[2] // can this be removed?
|
|
INT iNumCrowdControlPeds
|
|
INT iNumHitsRemaining = ciCC_MaxBeatdownHitsTotal
|
|
|
|
ENDSTRUCT
|
|
|
|
|
|
STRUCT CROWD_CONTROL_LOCAL_DATA
|
|
|
|
// Locals cached info
|
|
INT iCCRule[FMMC_MAX_TEAMS]
|
|
INT iThermiteTeam = -1
|
|
INT iThermiteRule = -1
|
|
CROWD_CONTROL_HEIST_TYPE eHeistType = CCHEIST_NORMAL
|
|
INT iCashierPed = -1
|
|
INTERIOR_INSTANCE_INDEX interiorHeist = NULL
|
|
|
|
// Local Variables
|
|
|
|
// General
|
|
INT iBitSet = 0
|
|
INT iSyncSceneIntroLoop = -1
|
|
|
|
// Heroes
|
|
TIME_DATATYPE timeNextHeroPick
|
|
|
|
// Dialogue
|
|
TIME_DATATYPE timeDialogueGlobalContextTimers[CCDIACONTEXT_NUM_CONTEXTS]
|
|
TIME_DATATYPE timeCrowdKickedOff
|
|
|
|
// Beating
|
|
INT iSyncSceneBeatdown = -1
|
|
INT iPlayerBeatingThisPed = -1
|
|
CROWD_CONTROL_PLAYER_ANIM_TYPE eLastBeatdown = CCPLAYERANIM_INVALID
|
|
SHAPETEST_INDEX shapetestBeatdownProbe = NULL
|
|
INT iCrowdPedBeatdownProbe = -1
|
|
|
|
// Fear
|
|
FLOAT fFear
|
|
FLOAT fIntimidationBar
|
|
FLOAT fIntimidationBarInterpRate
|
|
INT iUpdateTimer = 0
|
|
|
|
// Fail
|
|
INT iFailCutsceneHash = 0
|
|
INT iFailCausedByPed = -1
|
|
TIME_DATATYPE timeFailDelay
|
|
TIME_DATATYPE timeFearFail
|
|
TIME_DATATYPE timeFearFailsUnblocked
|
|
CROWD_CONTROL_FAIL_REASON eFailReason = CCFAIL_NONE
|
|
|
|
// Alarms
|
|
INT iSFXAlarms[ciCC_MaxAlarms]
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
|
|
// Debug vars
|
|
CROWD_CONTROL_DEBUG_DISPLAY eDebugDisplay = CCDEBUG_OFF
|
|
|
|
#ENDIF
|
|
|
|
ENDSTRUCT
|
|
|
|
|
|
// Used locally for delaying the update of decorators
|
|
STRUCT CROWD_CONTROL_PED_DECORATOR_DATA
|
|
CROWD_CONTROL_PED_STATE eState
|
|
CROWD_CONTROL_PED_STATE eStatePrev
|
|
INT iBitSet
|
|
FLOAT fInfluenceDirectThreat
|
|
FLOAT fInfluenceShouting
|
|
INT iBeatdownHitsRemaining
|
|
INT iBeatdownRounds
|
|
ENDSTRUCT
|
|
|
|
|
|
STRUCT CROWD_CONTROL_LOCAL_PED_DATA
|
|
|
|
// Cached ped data
|
|
CROWD_CONTROL_PED_ENUM eCreatorAssignedPedID
|
|
|
|
// Local ped variables
|
|
INT iBitSet = 0
|
|
INT iUpdateTimer
|
|
|
|
// Prop related stuff
|
|
OBJECT_INDEX objProp = NULL //For props like phones
|
|
|
|
// Dialogue
|
|
CROWD_CONTROL_DIALOGUE eDialogueClientToHost = CCDIA_NONE // what a ped wants to play
|
|
CROWD_CONTROL_DIALOGUE eDialogueHostToClient = CCDIA_NONE // what they have been allowed to play
|
|
CROWD_CONTROL_DIALOGUE eDialogueCurrentlyPlaying = CCDIA_NONE // what they are currently playing
|
|
|
|
TIME_DATATYPE timeDialogueLastBroadcast // the last time a ped told the host it wanted to speak
|
|
TIME_DATATYPE timeDialogueContextTimers[CCDIACONTEXT_NUM_CONTEXTS] // last time dialogue from each context was spoken
|
|
|
|
// Threat
|
|
CROWD_CONTROL_THREAT_TYPE eBiggestThreat = CCTHREAT_NONE
|
|
PED_INDEX pedBiggestThreat = NULL
|
|
TIME_DATATYPE timeThreatUpdate // used to control how often we update the player threat BD
|
|
TIME_DATATYPE timeStartThreaten
|
|
TIME_DATATYPE timeLastThreatened
|
|
TIME_DATATYPE timeLastShotAt
|
|
TIME_DATATYPE timeLastBeat
|
|
TIME_DATATYPE timeStartProjectileFear
|
|
TIME_DATATYPE timeStartProximityThreat
|
|
TIME_DATATYPE timeShootingCloseFlinchingStarted
|
|
|
|
TIME_DATATYPE timeDied
|
|
|
|
// Sequences
|
|
SEQUENCE_INDEX seqs[CCSEQ_NUM_SEQUENCES]
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
CROWD_CONTROL_THREAT_TYPE eDebugThreatFelt = CCTHREAT_NONE
|
|
CROWD_CONTROL_THREAT_TYPE eDebugThreatUsedForFear = CCTHREAT_NONE
|
|
#ENDIF
|
|
|
|
ENDSTRUCT
|
|
|
|
|
|
// Cleanup
|
|
//----------------------------------------------------------------------------
|
|
|
|
PROC RESET_CROWD_CONTROL_SERVER_DATA( CROWD_CONTROL_SERVER_DATA &sCrowdControlData )
|
|
CPRINTLN(DEBUG_NET_MINIGAME, "RESET_CROWD_CONTROL_SERVER_DATA()")
|
|
CROWD_CONTROL_SERVER_DATA sEmpty
|
|
sCrowdControlData = sEmpty
|
|
ENDPROC
|
|
|
|
|
|
PROC RESET_CROWD_CONTROL_LOCAL_DATA( CROWD_CONTROL_LOCAL_DATA &sLocalData )
|
|
CPRINTLN(DEBUG_NET_MINIGAME, "RESET_CROWD_CONTROL_LOCAL_DATA()")
|
|
CROWD_CONTROL_LOCAL_DATA sEmpty
|
|
sEmpty.iSFXAlarms[0] = -1
|
|
sEmpty.iSFXAlarms[1] = -1
|
|
sLocalData = sEmpty
|
|
ENDPROC
|
|
|
|
|
|
PROC RESET_CROWD_CONTROL_PED_DECOR_DATA(CROWD_CONTROL_PED_DECORATOR_DATA &sPedDecorData[] )
|
|
CPRINTLN(DEBUG_NET_MINIGAME, "RESET_CROWD_CONTROL_PED_DECOR_DATA()")
|
|
CROWD_CONTROL_PED_DECORATOR_DATA sEmpty
|
|
INT i
|
|
REPEAT COUNT_OF(sPedDecorData) i
|
|
sPedDecorData[i] = sEmpty
|
|
ENDREPEAT
|
|
ENDPROC
|
|
|
|
|
|
PROC RESET_CROWD_CONTROL_LOCAL_PED_DATA( CROWD_CONTROL_LOCAL_PED_DATA &sLocalPedData[] )
|
|
CPRINTLN(DEBUG_NET_MINIGAME, "RESET_CROWD_CONTROL_LOCAL_PED_DATA()")
|
|
CROWD_CONTROL_LOCAL_PED_DATA sEmpty
|
|
INT i
|
|
REPEAT COUNT_OF(sLocalPedData) i
|
|
sLocalPedData[i] = sEmpty
|
|
ENDREPEAT
|
|
ENDPROC
|
|
|
|
|
|
PROC CLEANUP_CROWD_CONTROL_MINIGAME( CROWD_CONTROL_LOCAL_DATA &sLocalData, CROWD_CONTROL_LOCAL_PED_DATA &sLocalPedData[] )
|
|
CPRINTLN(DEBUG_NET_MINIGAME, "CLEANUP_CROWD_CONTROL_MINIGAME()")
|
|
INT i
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_Initialised )
|
|
|
|
REPEAT COUNT_OF( sLocalData.iSFXAlarms ) i
|
|
IF sLocalData.iSFXAlarms[i] != -1
|
|
IF NOT HAS_SOUND_FINISHED( sLocalData.iSFXAlarms[i] )
|
|
STOP_SOUND( sLocalData.iSFXAlarms[i] )
|
|
ENDIF
|
|
sLocalData.iSFXAlarms[i] = -1
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
REPEAT COUNT_OF( sLocalPedData ) i
|
|
IF DOES_ENTITY_EXIST( sLocalPedData[i].objProp )
|
|
DELETE_OBJECT( sLocalPedData[i].objProp )
|
|
ENDIF
|
|
|
|
INT j
|
|
REPEAT CCSEQ_NUM_SEQUENCES j
|
|
IF sLocalPedData[i].seqs[j] != NULL
|
|
CLEAR_SEQUENCE_TASK( sLocalPedData[i].seqs[j] )
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
ENDREPEAT
|
|
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
// Debug procs/funcs
|
|
//----------------------------------------------------------------------------
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
|
|
PROC SETUP_CROWD_CONTROL_DEBUG( CROWD_CONTROL_SERVER_DATA &sServerData, CROWD_CONTROL_LOCAL_DATA &sLocalData )
|
|
START_WIDGET_GROUP( "Crowd Control" )
|
|
ADD_BIT_FIELD_WIDGET( "Server bitset", sServerData.iBitSet )
|
|
ADD_BIT_FIELD_WIDGET( "Local bitset", sLocalData.iBitSet )
|
|
|
|
START_WIDGET_GROUP( "Fear" )
|
|
ADD_WIDGET_FLOAT_SLIDER( "FearIncreaseRateMin", cfCC_FearIncreaseRateMin, 0.0, 20.0, 0.1 )
|
|
ADD_WIDGET_FLOAT_SLIDER( "FearIncreaseRateMax", cfCC_FearIncreaseRateMax, 0.0, 20.0, 0.1 )
|
|
ADD_WIDGET_FLOAT_SLIDER( "FearDecreaseRateMin", cfCC_FearDecreaseRateMin, 0.0, 20.0, 0.1 )
|
|
ADD_WIDGET_FLOAT_SLIDER( "FearDecreaseRateMax", cfCC_FearDecreaseRateMax, 0.0, 20.0, 0.1 )
|
|
STOP_WIDGET_GROUP()
|
|
|
|
START_WIDGET_GROUP( "Beatdown" )
|
|
ADD_WIDGET_FLOAT_SLIDER( "Distance Min", cfCC_BeatdownDistMin, 0.0, 10.0, 0.1 )
|
|
ADD_WIDGET_FLOAT_SLIDER( "Distance Max", cfCC_BeatdownDistMax, 0.0, 10.0, 0.1 )
|
|
ADD_WIDGET_FLOAT_SLIDER( "Long Anim Dist", cfCC_BeatdownLongAnimDistThreshold, 0.0, 10.0, 0.1 )
|
|
ADD_WIDGET_FLOAT_SLIDER( "Standard Melee Disable Dist", cfCC_BeatdownMeleeDisableDist, 0.0, 10.0, 0.1 )
|
|
ADD_WIDGET_FLOAT_SLIDER( "Facing Angle Change Dist Min", cfCC_BeatdownFacingAngleChangeDistMin, 0.0, 10.0, 0.1 )
|
|
ADD_WIDGET_FLOAT_SLIDER( "Facing Angle Change Dist Max", cfCC_BeatdownFacingAngleChangeDistMax, 0.0, 10.0, 0.1 )
|
|
ADD_WIDGET_FLOAT_SLIDER( "Facing Angle Min", cfCC_BeatdownFacingAngleRangeMin, 0.0, 360.0, 0.1 )
|
|
ADD_WIDGET_FLOAT_SLIDER( "Facing Angle Max", cfCC_BeatdownFacingAngleRangeMax, 0.0, 360.0, 0.1 )
|
|
STOP_WIDGET_GROUP()
|
|
|
|
START_WIDGET_GROUP( "Debug Display" )
|
|
|
|
ADD_WIDGET_INT_SLIDER( "ciCC_DebugColNormalR", ciCC_DebugColNormalR, 0, 255, 1 )
|
|
ADD_WIDGET_INT_SLIDER( "ciCC_DebugColNormalG", ciCC_DebugColNormalG, 0, 255, 1 )
|
|
ADD_WIDGET_INT_SLIDER( "ciCC_DebugColNormalB", ciCC_DebugColNormalB, 0, 255, 1 )
|
|
|
|
ADD_WIDGET_INT_SLIDER( "ciCC_DebugColWarningR", ciCC_DebugColWarningR, 0, 255, 1 )
|
|
ADD_WIDGET_INT_SLIDER( "ciCC_DebugColWarningG", ciCC_DebugColWarningG, 0, 255, 1 )
|
|
ADD_WIDGET_INT_SLIDER( "ciCC_DebugColWarningB", ciCC_DebugColWarningB, 0, 255, 1 )
|
|
|
|
ADD_WIDGET_INT_SLIDER( "ciCC_DebugColActiveR", ciCC_DebugColActiveR, 0, 255, 1 )
|
|
ADD_WIDGET_INT_SLIDER( "ciCC_DebugColActiveG", ciCC_DebugColActiveG, 0, 255, 1 )
|
|
ADD_WIDGET_INT_SLIDER( "ciCC_DebugColActiveB", ciCC_DebugColActiveB, 0, 255, 1 )
|
|
|
|
STOP_WIDGET_GROUP()
|
|
|
|
|
|
STOP_WIDGET_GROUP()
|
|
ENDPROC
|
|
|
|
FUNC STRING GET_CROWD_CONTROL_PED_STATE_STRING( CROWD_CONTROL_PED_STATE eState )
|
|
SWITCH eState
|
|
CASE CCPS_INVALID RETURN "CCPS_INVALID" BREAK
|
|
CASE CCPS_INTRO RETURN "CCPS_INTRO" BREAK
|
|
CASE CCPS_COWER RETURN "CCPS_COWER" BREAK
|
|
CASE CCPS_FLINCH RETURN "CCPS_FLINCH" BREAK
|
|
CASE CCPS_FLINCH_UNDERFIRE RETURN "CCPS_FLINCH_UNDERFIRE" BREAK
|
|
CASE CCPS_BEATDOWN RETURN "CCPS_BEATDOWN" BREAK
|
|
CASE CCPS_HERO_ATTEMPT RETURN "CCPS_HERO_ATTEMPT" BREAK
|
|
CASE CCPS_HERO RETURN "CCPS_HERO" BREAK
|
|
CASE CCPS_COMBAT RETURN "CCPS_COMBAT" BREAK
|
|
ENDSWITCH
|
|
RETURN ""
|
|
|
|
ENDFUNC
|
|
|
|
FUNC STRING GET_CROWD_CONTROL_PED_ANIM_ENUM_NAME( CROWD_CONTROL_PED_ANIM_TYPE eAnim )
|
|
SWITCH eAnim
|
|
CASE CCPANIM_INTRO_LOOP RETURN "CCPANIM_INTRO_LOOP" BREAK
|
|
CASE CCPANIM_INTRO RETURN "CCPANIM_INTRO" BREAK
|
|
CASE CCPANIM_COWER_LOOP RETURN "CCPANIM_COWER_LOOP" BREAK
|
|
CASE CCPANIM_COWER_TO_FLINCH_INTRO RETURN "CCPANIM_COWER_TO_FLINCH_INTRO" BREAK
|
|
CASE CCPANIM_COWER_TO_FLINCH_UNDERFIRE_INTRO RETURN "CCPANIM_COWER_TO_FLINCH_UNDERFIRE_INTRO" BREAK
|
|
CASE CCPANIM_FLINCH_LOOP RETURN "CCPANIM_FLINCH_LOOP" BREAK
|
|
CASE CCPANIM_FLINCH_TO_IDLE_OUTRO RETURN "CCPANIM_FLINCH_TO_IDLE_OUTRO" BREAK
|
|
CASE CCPANIM_FLINCH_TO_FLINCH_UNDERFIRE_INTRO RETURN "CCPANIM_FLINCH_TO_FLINCH_UNDERFIRE_INTRO" BREAK
|
|
CASE CCPANIM_FLINCH_UNDERFIRE_LOOP RETURN "CCPANIM_FLINCH_UNDERFIRE_LOOP" BREAK
|
|
CASE CCPANIM_FLINCH_UNDERFIRE_TO_FLINCH_OUTRO RETURN "CCPANIM_FLINCH_UNDERFIRE_TO_FLINCH_OUTRO" BREAK
|
|
CASE CCPANIM_BEATDOWN_INTRO RETURN "CCPANIM_BEATDOWN_INTRO" BREAK
|
|
CASE CCPANIM_BEATDOWN_LOOP RETURN "CCPANIM_BEATDOWN_LOOP" BREAK
|
|
CASE CCPANIM_BEATDOWN_HIT_A RETURN "CCPANIM_BEATDOWN_HIT_A" BREAK
|
|
CASE CCPANIM_BEATDOWN_HIT_B RETURN "CCPANIM_BEATDOWN_HIT_B" BREAK
|
|
CASE CCPANIM_BEATDOWN_DIE RETURN "CCPANIM_BEATDOWN_DIE" BREAK
|
|
CASE CCPANIM_BEATDOWN_DIE_LOOP RETURN "CCPANIM_BEATDOWN_DIE_LOOP" BREAK
|
|
CASE CCPANIM_HERO_START RETURN "CCPANIM_HERO_START" BREAK
|
|
CASE CCPANIM_HERO_LOOP RETURN "CCPANIM_HERO_LOOP" BREAK
|
|
CASE CCPANIM_HERO_PASS RETURN "CCPANIM_HERO_PASS" BREAK
|
|
CASE CCPANIM_HERO_FAIL RETURN "CCPANIM_HERO_FAIL" BREAK
|
|
ENDSWITCH
|
|
RETURN ""
|
|
ENDFUNC
|
|
|
|
|
|
FUNC STRING GET_CROWD_CONTROL_PED_NAME_FROM_ANIM_ID( CROWD_CONTROL_PED_ENUM eCrowdPedAnimID )
|
|
|
|
SWITCH eCrowdPedAnimID
|
|
CASE CCPED_CASHIER_A RETURN "Cashier A" BREAK
|
|
CASE CCPED_CASHIER_B RETURN "Cashier B" BREAK
|
|
CASE CCPED_CUSTOMER_A RETURN "Ped A" BREAK
|
|
CASE CCPED_CUSTOMER_B RETURN "Ped B" BREAK
|
|
CASE CCPED_CUSTOMER_C RETURN "Ped C" BREAK
|
|
CASE CCPED_CUSTOMER_D RETURN "Ped D" BREAK
|
|
CASE CCPED_CUSTOMER_E RETURN "Ped E" BREAK
|
|
CASE CCPED_CUSTOMER_F RETURN "Ped F" BREAK
|
|
CASE CCPED_CUSTOMER_G RETURN "Ped G" BREAK
|
|
CASE CCPED_CUSTOMER_H RETURN "Ped H" BREAK
|
|
ENDSWITCH
|
|
|
|
RETURN ""
|
|
ENDFUNC
|
|
|
|
|
|
FUNC STRING GET_CROWD_CONTROL_THREAT_TYPE_STRING( CROWD_CONTROL_THREAT_TYPE eThreat )
|
|
SWITCH eThreat
|
|
CASE CCTHREAT_NONE RETURN "CCTHREAT_NONE" BREAK
|
|
CASE CCTHREAT_PROXIMITY RETURN "CCTHREAT_PROXIMITY" BREAK
|
|
CASE CCTHREAT_SHOUTING RETURN "CCTHREAT_SHOUTING" BREAK
|
|
CASE CCTHREAT_SHOUTING_CLOSE RETURN "CCTHREAT_SHOUTING_CLOSE" BREAK
|
|
CASE CCTHREAT_BEATING_NEIGHBOUR RETURN "CCTHREAT_BEATING_NEIGHBOUR" BREAK
|
|
CASE CCTHREAT_KILLED_OTHER RETURN "CCTHREAT_KILLED_OTHER" BREAK
|
|
CASE CCTHREAT_AIMED_AT RETURN "CCTHREAT_AIMED_AT" BREAK
|
|
CASE CCTHREAT_BEATING RETURN "CCTHREAT_BEATING" BREAK
|
|
CASE CCTHREAT_SHOOTING RETURN "CCTHREAT_SHOOTING" BREAK
|
|
CASE CCTHREAT_PROJECTILE_EXPLOSIVE RETURN "CCTHREAT_PROJECTILE_EXPLOSIVE" BREAK
|
|
CASE CCTHREAT_PROJECTILE_EXPLOSIVE_STICKY_BOMB RETURN "CCTHREAT_PROJECTILE_EXPLOSIVE_STICKY_BOMB" BREAK
|
|
CASE CCTHREAT_SHOOTING_CLOSE RETURN "CCTHREAT_SHOOTING_CLOSE" BREAK
|
|
ENDSWITCH
|
|
RETURN "no debug name"
|
|
ENDFUNC
|
|
|
|
|
|
FUNC STRING GET_CROWD_CONTROL_HEIST_TYPE_STRING( CROWD_CONTROL_HEIST_TYPE eHeistType )
|
|
SWITCH eHeistType
|
|
CASE CCHEIST_NORMAL RETURN "CCHEIST_NORMAL" BREAK
|
|
CASE CCHEIST_CUSTOM_FLEECA RETURN "CCHEIST_CUSTOM_FLEECA" BREAK
|
|
CASE CCHEIST_CUSTOM_ORNATE RETURN "CCHEIST_CUSTOM_ORNATE" BREAK
|
|
ENDSWITCH
|
|
RETURN "no debug name"
|
|
ENDFUNC
|
|
|
|
|
|
FUNC STRING GET_CROWD_CONTROL_HERO_ACTION( CROWD_CONTROL_PED_HERO_ACTION eHeroAction )
|
|
SWITCH eHeroAction
|
|
CASE CCHERO_NONE RETURN "CCHERO_NONE" BREAK
|
|
CASE CCHERO_ALARM RETURN "CCHERO_ALARM" BREAK
|
|
CASE CCHERO_PHONE RETURN "CCHERO_PHONE" BREAK
|
|
CASE CCHERO_GUN RETURN "CCHERO_GUN" BREAK
|
|
ENDSWITCH
|
|
RETURN "no debug name"
|
|
ENDFUNC
|
|
|
|
|
|
FUNC STRING GET_CROWD_CONTROL_FAIL_REASON_STRING( CROWD_CONTROL_FAIL_REASON eFailReason )
|
|
SWITCH eFailReason
|
|
CASE CCFAIL_NONE RETURN "CCFAIL_NONE" BREAK
|
|
CASE CCFAIL_PEDKILLED RETURN "CCFAIL_PEDKILLED" BREAK
|
|
CASE CCFAIL_PEDSKILLED RETURN "CCFAIL_PEDSKILLED" BREAK
|
|
CASE CCFAIL_PEDHEROALARM RETURN "CCFAIL_PEDHEROALARM" BREAK
|
|
CASE CCFAIL_PEDHEROPHONE RETURN "CCFAIL_PEDHEROPHONE" BREAK
|
|
CASE CCFAIL_PEDHEROGUN RETURN "CCFAIL_PEDHEROGUN" BREAK
|
|
CASE CCFAIL_FEARLOW RETURN "CCFAIL_FEARLOW" BREAK
|
|
CASE CCFAIL_TOOMANYKNOCKOUTS RETURN "CCFAIL_TOOMANYKNOCKOUTS" BREAK
|
|
CASE CCFAIL_NOHITSREMAINING RETURN "CCFAIL_NOHITSREMAINING" BREAK
|
|
ENDSWITCH
|
|
RETURN "no debug name"
|
|
ENDFUNC
|
|
|
|
|
|
FUNC STRING GET_CROWD_CONTROL_DIALOGUE_ENUM_STRING( CROWD_CONTROL_DIALOGUE eDialogue )
|
|
SWITCH eDialogue
|
|
CASE CCDIA_NONE RETURN "CCDIA_NONE" BREAK
|
|
CASE CCDIA_APPROACH RETURN "CCDIA_APPROACH" BREAK
|
|
CASE CCDIA_ALARM_GOES_OFF RETURN "CCDIA_ALARM_GOES_OFF" BREAK
|
|
CASE CCDIA_ALARM_GOES_OFF_INITIAL RETURN "CCDIA_ALARM_GOES_OFF_INITIAL" BREAK
|
|
CASE CCDIA_COWER_HIGH_FEAR RETURN "CCDIA_COWER_HIGH_FEAR" BREAK
|
|
CASE CCDIA_COWER_LOW_FEAR RETURN "CCDIA_COWER_LOW_FEAR" BREAK
|
|
CASE CCDIA_HERO_ALARM_CAUGHT RETURN "CCDIA_HERO_ALARM_CAUGHT" BREAK
|
|
CASE CCDIA_HERO_ALARM_COMPLETE RETURN "CCDIA_HERO_ALARM_COMPLETE" BREAK
|
|
CASE CCDIA_HERO_ALARM_START RETURN "CCDIA_HERO_ALARM_START" BREAK
|
|
CASE CCDIA_HERO_GUN_CAUGHT RETURN "CCDIA_HERO_GUN_CAUGHT" BREAK
|
|
CASE CCDIA_HERO_GUN_COMPLETE RETURN "CCDIA_HERO_GUN_COMPLETE" BREAK
|
|
CASE CCDIA_HERO_GUN_START RETURN "CCDIA_HERO_GUN_START" BREAK
|
|
CASE CCDIA_HERO_PHONE_CAUGHT RETURN "CCDIA_HERO_PHONE_CAUGHT" BREAK
|
|
CASE CCDIA_HERO_PHONE_COMPLETE RETURN "CCDIA_HERO_PHONE_COMPLETE" BREAK
|
|
CASE CCDIA_HERO_PHONE_START RETURN "CCDIA_HERO_PHONE_START" BREAK
|
|
CASE CCDIA_HERO_PHONE_APOLOGISE RETURN "CCDIA_HERO_PHONE_APOLOGISE" BREAK
|
|
CASE CCDIA_INITIAL_PANIC RETURN "CCDIA_INITIAL_PANIC" BREAK
|
|
CASE CCDIA_RECEIVES_SCARE RETURN "CCDIA_RECEIVES_SCARE" BREAK
|
|
CASE CCDIA_SEES_OTHER_KILLED RETURN "CCDIA_SEES_OTHER_KILLED" BREAK
|
|
CASE CCDIA_SHOT_NEAR RETURN "CCDIA_SHOT_NEAR" BREAK
|
|
CASE CCDIA_SHOT_DIRECTLY_AT RETURN "CCDIA_SHOT_DIRECTLY_AT" BREAK
|
|
CASE CCDIA_STICKS_UP_FOR_OTHER RETURN "CCDIA_STICKS_UP_FOR_OTHER" BREAK
|
|
ENDSWITCH
|
|
RETURN "no debug name"
|
|
ENDFUNC
|
|
|
|
|
|
FUNC STRING GET_CROWD_CONTROL_SEQUENCE_NAME( CROWD_CONTROL_SEQUENCES eSeq )
|
|
SWITCH eSeq
|
|
CASE CCSEQ_BEATDOWN_TO_FLINCH RETURN "CCSEQ_BEATDOWN_TO_FLINCH" BREAK
|
|
CASE CCSEQ_COWER_TO_FLINCH RETURN "CCSEQ_COWER_TO_FLINCH" BREAK
|
|
CASE CCSEQ_COWER_TO_FLINCH_UNDERFIRE RETURN "CCSEQ_COWER_TO_FLINCH_UNDERFIRE" BREAK
|
|
CASE CCSEQ_FLINCH_TO_FLINCH_UNDERFIRE RETURN "CCSEQ_FLINCH_TO_FLINCH_UNDERFIRE" BREAK
|
|
CASE CCSEQ_FLINCH_UNDERFIRE_TO_FLINCH RETURN "CCSEQ_FLINCH_UNDERFIRE_TO_FLINCH" BREAK
|
|
CASE CCSEQ_FLINCH_TO_COWER RETURN "CCSEQ_FLINCH_TO_COWER" BREAK
|
|
CASE CCSEQ_HERO_FAIL RETURN "CCSEQ_HERO_FAIL" BREAK
|
|
CASE CCSEQ_HERO_PASS RETURN "CCSEQ_HERO_PASS" BREAK
|
|
CASE CCSEQ_HERO_START RETURN "CCSEQ_HERO_START" BREAK
|
|
CASE CCSEQ_NUM_SEQUENCES RETURN "CCSEQ_NUM_SEQUENCES" BREAK
|
|
ENDSWITCH
|
|
RETURN "no debug name"
|
|
ENDFUNC
|
|
|
|
FUNC STRING GET_CROWD_CONTROL_DEBUG_NAME( CROWD_CONTROL_DEBUG_DISPLAY eDebug )
|
|
SWITCH eDebug
|
|
CASE CCDEBUG_OFF RETURN "OFF" BREAK
|
|
CASE CCDEBUG_ALL RETURN "ALL" BREAK
|
|
CASE CCDEBUG_BASIC RETURN "BASIC" BREAK
|
|
CASE CCDEBUG_FEAR_AND_THREATS RETURN "FEAR & THREATS" BREAK
|
|
CASE CCDEBUG_HERO RETURN "HERO" BREAK
|
|
CASE CCDEBUG_BEATDOWNS RETURN "BEATDOWNS" BREAK
|
|
CASE CCDEBUG_DIALOGUE RETURN "DIALOGUE" BREAK
|
|
CASE CCDEBUG_MISC RETURN "MISC" BREAK
|
|
ENDSWITCH
|
|
RETURN "no debug name"
|
|
ENDFUNC
|
|
|
|
FUNC STRING GET_CROWD_CONTROL_DEBUG_ENUM_NAME( CROWD_CONTROL_DEBUG_DISPLAY eDebug )
|
|
SWITCH eDebug
|
|
CASE CCDEBUG_OFF RETURN "CCDEBUG_OFF" BREAK
|
|
CASE CCDEBUG_ALL RETURN "CCDEBUG_ALL" BREAK
|
|
CASE CCDEBUG_BASIC RETURN "CCDEBUG_BASIC" BREAK
|
|
CASE CCDEBUG_FEAR_AND_THREATS RETURN "CCDEBUG_FEAR_AND_THREATS" BREAK
|
|
CASE CCDEBUG_HERO RETURN "CCDEBUG_HERO" BREAK
|
|
CASE CCDEBUG_BEATDOWNS RETURN "CCDEBUG_BEATDOWNS" BREAK
|
|
CASE CCDEBUG_DIALOGUE RETURN "CCDEBUG_DIALOGUE" BREAK
|
|
CASE CCDEBUG_MISC RETURN "CCDEBUG_MISC" BREAK
|
|
ENDSWITCH
|
|
RETURN "no debug name"
|
|
ENDFUNC
|
|
|
|
#ENDIF
|
|
|
|
|
|
FUNC STRING GET_CROWD_CONTROL_PED_DECOR_NAME( CROWD_CONTROL_PED_DECORATOR eDecor )
|
|
|
|
SWITCH eDecor
|
|
CASE CCPDECOR_iState RETURN "CC_iState" BREAK
|
|
CASE CCPDECOR_iStatePrev RETURN "CC_iStatePrev" BREAK
|
|
CASE CCPDECOR_iBitSet RETURN "CC_iBitSet" BREAK
|
|
CASE CCPDECOR_fInfluenceDirectThreat RETURN "CC_fInfluenceDirectThreat" BREAK
|
|
CASE CCPDECOR_fInfluenceShouting RETURN "CC_fInfluenceShouting" BREAK
|
|
CASE CCPDECOR_iBeatdownHitsRemaining RETURN "CC_iBeatdownHitsRemaining" BREAK
|
|
CASE CCPDECOR_iBeatdownRounds RETURN "CC_iBeatdownRounds" BREAK
|
|
ENDSWITCH
|
|
RETURN ""
|
|
ENDFUNC
|
|
|
|
|
|
FUNC INTERIOR_INSTANCE_INDEX GET_CROWD_CONTROL_HEIST_INTERIOR( CROWD_CONTROL_HEIST_TYPE eHeistType )
|
|
|
|
SWITCH eHeistType
|
|
CASE CCHEIST_NORMAL
|
|
RETURN NULL
|
|
BREAK
|
|
CASE CCHEIST_CUSTOM_FLEECA
|
|
RETURN GET_INTERIOR_AT_COORDS_WITH_TYPE( <<-2962.8086, 482.2888, 14.7081>>, "hei_generic_bank_dlc" ) // v_genbank
|
|
BREAK
|
|
CASE CCHEIST_CUSTOM_ORNATE
|
|
RETURN GET_INTERIOR_AT_COORDS_WITH_TYPE( <<235.9299, 216.6042, 105.2867>>, "hei_heist_ornate_bank" ) // v_bank
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
RETURN NULL
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL HAS_PED_ENTERED_CROWD_CONTROL_TRIGGER_ZONE( PED_INDEX ped, CROWD_CONTROL_LOCAL_DATA &sLocalData, BOOL bSoftTrigger )
|
|
|
|
BOOL bInsideInterior = ( sLocalData.interiorHeist = GET_INTERIOR_FROM_ENTITY( ped ) )
|
|
|
|
IF NOT bSoftTrigger
|
|
|
|
// HARD TRIGGER - the actual trigger we go off for triggering the crowd to kick off
|
|
SWITCH sLocalData.eHeistType
|
|
|
|
CASE CCHEIST_CUSTOM_FLEECA
|
|
// If inside the bank or near the bank doors
|
|
IF bInsideInterior
|
|
RETURN TRUE
|
|
// In a car near the doors
|
|
ELIF IS_PED_IN_ANY_VEHICLE( ped )
|
|
|
|
VEHICLE_INDEX veh
|
|
veh = GET_VEHICLE_PED_IS_IN( ped )
|
|
|
|
IF HAS_ENTITY_COLLIDED_WITH_ANYTHING( veh )
|
|
AND IS_ENTITY_IN_ANGLED_AREA( ped, <<-2967.208496,481.097839,14.468699>>, <<-2967.038574,484.783356,17.786673>>, 3.062500 )
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE CCHEIST_CUSTOM_ORNATE
|
|
// Player is inside the interior and main bank room
|
|
// Additional area check to make sure the player has fulled walked into the room
|
|
IF bInsideInterior
|
|
AND GET_ROOM_KEY_FROM_ENTITY( ped ) = HASH( "Bank_MainRm" )
|
|
// revised locate size for bug 2093267
|
|
AND IS_ENTITY_IN_ANGLED_AREA( ped, <<259.844116,215.006775,105.288048>>, <<237.827515,222.779510,109.395790>>, 11.500000 )
|
|
//AND IS_ENTITY_IN_ANGLED_AREA( ped, <<259.546387,214.301697,105.286835>>, <<238.274490,222.332184,109.029305>>, 10.687500 )
|
|
RETURN TRUE
|
|
ENDIF
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
ELSE
|
|
|
|
// SOFT TRIGGER - just outside the hard trigger area, this is used to check for the player shouting
|
|
SWITCH sLocalData.eHeistType
|
|
|
|
CASE CCHEIST_CUSTOM_FLEECA
|
|
// Inside the bank
|
|
IF bInsideInterior
|
|
OR IS_ENTITY_IN_ANGLED_AREA( ped, <<-2965.820801,482.966461,14.635263>>, <<-2967.116699,483.018555,17.441607>>, 3.562500 )
|
|
RETURN TRUE
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE CCHEIST_CUSTOM_ORNATE
|
|
// Inside the bank in the main room, not the little area by the door
|
|
IF bInsideInterior
|
|
AND GET_ROOM_KEY_FROM_ENTITY( ped ) = HASH( "Bank_MainRm" )
|
|
RETURN TRUE
|
|
ENDIF
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL HAS_TEAM_PASSED_CROWD_CONTROL_RULE( CROWD_CONTROL_LOCAL_DATA &sLocalData, INT &iCurrentHighestPriority, INT iTeam )
|
|
|
|
IF sLocalData.iCCRule[iTeam] != -1 AND sLocalData.iCCRule[iTeam] < FMMC_MAX_RULES
|
|
AND iCurrentHighestPriority <= sLocalData.iCCRule[iTeam]
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL HAVE_ALL_PLAYERS_PASSED_CROWD_CONTROL_RULE( CROWD_CONTROL_LOCAL_DATA &sLocalData, INT &iCurrentHighestPriority[], INT iLocalPlayersTeam )
|
|
BOOL bAllPassedRule
|
|
bAllPassedRule = TRUE
|
|
INT iTeam
|
|
FOR iTeam = 0 TO FMMC_MAX_TEAMS-1
|
|
|
|
IF NOT IS_FAKE_MULTIPLAYER_MODE_SET()
|
|
OR iTeam = iLocalPlayersTeam
|
|
|
|
IF HAS_TEAM_PASSED_CROWD_CONTROL_RULE( sLocalData, iCurrentHighestPriority[iTeam], iTeam )
|
|
bAllPassedRule = FALSE
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDFOR
|
|
RETURN bAllPassedRule
|
|
ENDFUNC
|
|
|
|
FUNC BOOL SHOULD_DISABLE_CROWD_CONTROL_FAIL( CROWD_CONTROL_LOCAL_DATA &sLocalData, INT &iCurrentHighestPriority[], INT iLocalPlayersTeam )
|
|
|
|
IF g_bMissionEnding
|
|
|
|
RETURN TRUE
|
|
|
|
ELSE
|
|
|
|
SWITCH sLocalData.eHeistType
|
|
|
|
CASE CCHEIST_CUSTOM_FLEECA
|
|
|
|
// Fleeca never disables the fail
|
|
RETURN FALSE
|
|
|
|
BREAK
|
|
|
|
CASE CCHEIST_CUSTOM_ORNATE
|
|
|
|
// If we have passed the crowd control objective for all teams, disable the fail
|
|
RETURN HAVE_ALL_PLAYERS_PASSED_CROWD_CONTROL_RULE( sLocalData, iCurrentHighestPriority, iLocalPlayersTeam )
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
FUNC BOOL SHOULD_PLAYER_PLAY_CROWD_CONTROL_CUTSCENE( PED_INDEX pedPlayer,
|
|
CROWD_CONTROL_LOCAL_DATA &sLocalData, INT &iCurrentHighestPriority[], INT iLocalPlayersTeam )
|
|
|
|
INT iTeam
|
|
|
|
SWITCH sLocalData.eHeistType
|
|
|
|
CASE CCHEIST_CUSTOM_FLEECA
|
|
|
|
IF NOT HAVE_ALL_PLAYERS_PASSED_CROWD_CONTROL_RULE( sLocalData, iCurrentHighestPriority, iLocalPlayersTeam )
|
|
|
|
IF GET_INTERIOR_FROM_ENTITY( pedPlayer ) = sLocalData.interiorHeist
|
|
OR GET_DISTANCE_BETWEEN_ENTITY_AND_COORD( pedPlayer, <<-2962.8086, 482.2888, 14.7081>> ) < 50.0
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE CCHEIST_CUSTOM_ORNATE
|
|
|
|
FOR iTeam = 0 TO FMMC_MAX_TEAMS-1
|
|
|
|
// Before or while the crowd control rule is active
|
|
IF sLocalData.iCCRule[iTeam] != -1 AND sLocalData.iCCRule[iTeam] < FMMC_MAX_RULES
|
|
AND iCurrentHighestPriority[iTeam] <= sLocalData.iCCRule[iTeam]
|
|
|
|
// Only those in the bank lobby area for ORNATE
|
|
IF GET_INTERIOR_FROM_ENTITY( pedPlayer ) = sLocalData.interiorHeist
|
|
|
|
INT iRoomHash
|
|
iRoomHash = GET_ROOM_KEY_FROM_ENTITY( pedPlayer )
|
|
|
|
IF iRoomHash = HASH( "Bank_MainRm" )
|
|
OR iRoomHash = HASH( "Bank_CashierRm" )
|
|
OR iRoomHash = HASH( "Bank_Lobby" )
|
|
OR iRoomHash = HASH( "Bank_ATMS" )
|
|
OR iRoomHash = HASH( "Bank_Vestibule" )
|
|
OR iRoomHash = HASH( "Bank_Upperhall1" )
|
|
OR iRoomHash = HASH( "Bank_Upperhall2" )
|
|
|
|
RETURN TRUE
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDFOR
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
FUNC INT GET_CROWD_CONTROL_NUMBER_OF_DEAD_PEDS_WITH_PED_ID( CROWD_CONTROL_PED_DECORATOR_DATA &sPedData[], CROWD_CONTROL_SERVER_DATA &sServerData, INT &iOptionalDeadPedID )
|
|
INT iCount
|
|
iOptionalDeadPedID = -1
|
|
|
|
INT i
|
|
FOR i = 0 TO sServerData.iNumCrowdControlPeds-1
|
|
|
|
// Count the number of dead peds
|
|
IF IS_BIT_SET_ENUM( sPedData[i].iBitSet, CCPEDDATA_Dead )
|
|
AND NOT IS_BIT_SET_ENUM( sPedData[i].iBitSet, CCPEDDATA_KnockedOut )
|
|
IF iOptionalDeadPedID = -1
|
|
iOptionalDeadPedID = sServerData.iCrowdControlCloudIndex[i]
|
|
ENDIF
|
|
iCount++
|
|
ENDIF
|
|
|
|
ENDFOR
|
|
RETURN iCount
|
|
ENDFUNC
|
|
|
|
|
|
FUNC INT GET_CROWD_CONTROL_NUMBER_OF_DEAD_PEDS( CROWD_CONTROL_PED_DECORATOR_DATA &sPedData[], CROWD_CONTROL_SERVER_DATA &sServerData )
|
|
INT iDummy
|
|
RETURN GET_CROWD_CONTROL_NUMBER_OF_DEAD_PEDS_WITH_PED_ID( sPedData, sServerData, iDummy )
|
|
ENDFUNC
|
|
|
|
|
|
FUNC INT GET_CROWD_CONTROL_NUMBER_OF_KNOCKED_OUT_PEDS_WITH_PED_ID( CROWD_CONTROL_PED_DECORATOR_DATA &sPedData[], CROWD_CONTROL_SERVER_DATA &sServerData, INT &iOptionalKnockedOutPedID )
|
|
INT iCount
|
|
iOptionalKnockedOutPedID = -1
|
|
|
|
INT i
|
|
FOR i = 0 TO sServerData.iNumCrowdControlPeds-1
|
|
|
|
// Count the number of knocked out peds
|
|
IF IS_BIT_SET_ENUM( sPedData[i].iBitSet, CCPEDDATA_KnockedOut )
|
|
IF iOptionalKnockedOutPedID = -1
|
|
iOptionalKnockedOutPedID = sServerData.iCrowdControlCloudIndex[i]
|
|
ENDIF
|
|
iCount++
|
|
ENDIF
|
|
|
|
ENDFOR
|
|
RETURN iCount
|
|
ENDFUNC
|
|
|
|
FUNC INT GET_CROWD_CONTROL_NUMBER_OF_KNOCKED_OUT_PEDS( CROWD_CONTROL_PED_DECORATOR_DATA &sPedData[], CROWD_CONTROL_SERVER_DATA &sServerData )
|
|
INT iDummy
|
|
RETURN GET_CROWD_CONTROL_NUMBER_OF_KNOCKED_OUT_PEDS_WITH_PED_ID( sPedData, sServerData, iDummy )
|
|
ENDFUNC
|
|
|
|
|
|
FUNC INT GET_CROWD_CONTROL_PED_DEAD_LIMIT( CROWD_CONTROL_HEIST_TYPE eHeistType )
|
|
INT iResult
|
|
SWITCH eHeistType
|
|
CASE CCHEIST_CUSTOM_ORNATE
|
|
iResult = 1
|
|
BREAK
|
|
DEFAULT
|
|
iResult = 0
|
|
BREAK
|
|
ENDSWITCH
|
|
RETURN iResult
|
|
ENDFUNC
|
|
|
|
|
|
FUNC FLOAT GET_CROWD_CONTROL_PED_ESCAPED_DISTANCE( CROWD_CONTROL_HEIST_TYPE eHeistType )
|
|
UNUSED_PARAMETER( eHeistType )
|
|
RETURN 20.0
|
|
ENDFUNC
|
|
|
|
|
|
FUNC INT GET_CROWD_CONTROL_FAIL_CUTSCENE( CROWD_CONTROL_HEIST_TYPE eHeistType, NETWORK_INDEX &niPeds[], INT &iCrowdCloudIndex[], CROWD_CONTROL_LOCAL_PED_DATA &sLocalPedData[], INT iNumCrowdControlPeds, TEXT_LABEL_63 &tlCutsceneNameOut, CUTSCENE_SECTION &eCutsceneSectionOut )
|
|
INT i
|
|
BOOL bDeadCashierA, bDeadCashierB
|
|
FOR i = 0 TO iNumCrowdControlPeds-1
|
|
IF sLocalPedData[i].eCreatorAssignedPedID = CCPED_CASHIER_A
|
|
OR sLocalPedData[i].eCreatorAssignedPedID = CCPED_CASHIER_B
|
|
IF NOT NETWORK_DOES_ENTITY_EXIST_WITH_NETWORK_ID( niPeds[iCrowdCloudIndex[i]] )
|
|
OR IS_PED_INJURED( NET_TO_PED( niPeds[iCrowdCloudIndex[i]] ) )
|
|
IF sLocalPedData[i].eCreatorAssignedPedID = CCPED_CASHIER_A
|
|
bDeadCashierA = TRUE
|
|
ELIF sLocalPedData[i].eCreatorAssignedPedID = CCPED_CASHIER_B
|
|
bDeadCashierB = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDFOR
|
|
|
|
SWITCH eHeistType
|
|
|
|
CASE CCHEIST_CUSTOM_FLEECA
|
|
|
|
IF NOT bDeadCashierA
|
|
|
|
tlCutsceneNameOut = "MPH_TUT_MCS1"
|
|
eCutsceneSectionOut = INT_TO_ENUM( CUTSCENE_SECTION, -1 )
|
|
|
|
ELSE
|
|
// cashier dead bail on cutscene
|
|
tlCutsceneNameOut = ""
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE CCHEIST_CUSTOM_ORNATE
|
|
|
|
IF NOT bDeadCashierA
|
|
|
|
tlCutsceneNameOut = "MPH_PAC_FIN_MCS2"
|
|
eCutsceneSectionOut = CS_SECTION_1
|
|
|
|
ELIF NOT bDeadCashierB
|
|
|
|
tlCutsceneNameOut = "MPH_PAC_FIN_MCS2"
|
|
eCutsceneSectionOut = CS_SECTION_2
|
|
|
|
ELSE
|
|
// both dead bail on cutscene
|
|
tlCutsceneNameOut = ""
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
// Create hash for comparison
|
|
TEXT_LABEL_63 tlTemp
|
|
tlTemp = tlCutsceneNameOut
|
|
tlTemp += ENUM_TO_INT( eCutsceneSectionOut )
|
|
RETURN GET_HASH_KEY( tlTemp )
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL GET_CROWD_CONTROL_FAIL_CUTSCENE_FROM_HASH( INT iHashIn, TEXT_LABEL_63 &tlName, CUTSCENE_SECTION &eSection )
|
|
|
|
TEXT_LABEL_63 tlTemp
|
|
|
|
tlTemp = "MPH_TUT_MCS1"
|
|
tlTemp += -1
|
|
IF iHashIn = GET_HASH_KEY( tlTemp )
|
|
tlName = "MPH_TUT_MCS1"
|
|
eSection = INT_TO_ENUM( CUTSCENE_SECTION, -1 )
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
tlTemp = "MPH_PAC_FIN_MCS2"
|
|
tlTemp += ENUM_TO_INT( CS_SECTION_1 )
|
|
IF iHashIn = GET_HASH_KEY( tlTemp )
|
|
tlName = "MPH_PAC_FIN_MCS2"
|
|
eSection = CS_SECTION_1
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
tlTemp = "MPH_PAC_FIN_MCS2"
|
|
tlTemp += ENUM_TO_INT( CS_SECTION_2 )
|
|
IF iHashIn = GET_HASH_KEY( tlTemp )
|
|
tlName = "MPH_PAC_FIN_MCS2"
|
|
eSection = CS_SECTION_2
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL GET_CROWD_CONTROL_PED_DETAILS_FOR_FAIL_CUTSCENE_FROM_HASH( INT iHashIn, NETWORK_INDEX &niPeds[], INT &iCrowdCloudIndex[], CROWD_CONTROL_LOCAL_PED_DATA &sLocalPedData[], INT iNumCrowdControlPeds, PED_INDEX &pedOut, TEXT_LABEL_63 &tlHandleOut, INT &iAnimEventHashAlarmOut )
|
|
|
|
TEXT_LABEL_63 tlCutsceneName
|
|
CUTSCENE_SECTION eSection
|
|
|
|
IF GET_CROWD_CONTROL_FAIL_CUTSCENE_FROM_HASH( iHashIn, tlCutsceneName, eSection )
|
|
|
|
TEXT_LABEL_63 tlHandleTemp
|
|
INT iAnimEventHashAlarmTemp
|
|
PED_INDEX pedTemp
|
|
|
|
CROWD_CONTROL_PED_ENUM ePedWanted
|
|
|
|
// Find the handle name and the ped enum
|
|
IF ARE_STRINGS_EQUAL( tlCutsceneName, "MPH_TUT_MCS1" )
|
|
|
|
tlHandleTemp = "Cashier"
|
|
ePedWanted = CCPED_CASHIER_A
|
|
iAnimEventHashAlarmTemp = HASH( "GET_HYPE" )
|
|
|
|
ELIF ARE_STRINGS_EQUAL( tlCutsceneName, "MPH_PAC_FIN_MCS2" )
|
|
|
|
SWITCH eSection
|
|
CASE CS_SECTION_1
|
|
ePedWanted = CCPED_CASHIER_A
|
|
tlHandleTemp = "Bank_Teller_02"
|
|
iAnimEventHashAlarmTemp = HASH( "GET_HYPE1" )
|
|
BREAK
|
|
CASE CS_SECTION_2
|
|
ePedWanted = CCPED_CASHIER_B
|
|
tlHandleTemp = "Bank_Teller_01"
|
|
iAnimEventHashAlarmTemp = HASH( "GET_HYPE2" )
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
ENDIF
|
|
|
|
|
|
// Find the ped ID
|
|
INT i
|
|
FOR i = 0 TO iNumCrowdControlPeds-1
|
|
IF sLocalPedData[i].eCreatorAssignedPedID = ePedWanted
|
|
IF NETWORK_DOES_ENTITY_EXIST_WITH_NETWORK_ID( niPeds[iCrowdCloudIndex[i]] )
|
|
|
|
pedTemp = NET_TO_PED( niPeds[iCrowdCloudIndex[i]] )
|
|
i = FMMC_MAX_CROWD_PEDS // break the loop
|
|
|
|
ENDIF
|
|
ENDIF
|
|
ENDFOR
|
|
|
|
IF NOT IS_STRING_NULL_OR_EMPTY( tlHandleTemp )
|
|
AND iAnimEventHashAlarmTemp != 0
|
|
AND DOES_ENTITY_EXIST( pedTemp )
|
|
|
|
tlHandleOut = tlHandleTemp
|
|
iAnimEventHashAlarmOut = iAnimEventHashAlarmTemp
|
|
pedOut = pedTemp
|
|
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
FUNC STRING GET_CROWD_CONTROL_PED_ANIM_DICTIONARY( CROWD_CONTROL_PED_ANIM_TYPE eAnimType, CROWD_CONTROL_PED_ENUM eCrowdControlAnimID, CROWD_CONTROL_HEIST_TYPE eHeistType )
|
|
|
|
IF eHeistType = CCHEIST_CUSTOM_FLEECA
|
|
SWITCH eCrowdControlAnimID
|
|
CASE CCPED_CASHIER_A eCrowdControlAnimID = CCPED_CUSTOMER_D BREAK
|
|
CASE CCPED_CUSTOMER_A eCrowdControlAnimID = CCPED_CUSTOMER_A BREAK
|
|
CASE CCPED_CUSTOMER_B eCrowdControlAnimID = CCPED_CUSTOMER_E BREAK
|
|
ENDSWITCH
|
|
ENDIF
|
|
|
|
// Common
|
|
|
|
SWITCH eAnimType
|
|
|
|
CASE CCPANIM_COWER_LOOP
|
|
|
|
CASE CCPANIM_COWER_TO_FLINCH_INTRO
|
|
CASE CCPANIM_COWER_TO_FLINCH_UNDERFIRE_INTRO
|
|
CASE CCPANIM_FLINCH_LOOP
|
|
CASE CCPANIM_FLINCH_TO_IDLE_OUTRO
|
|
CASE CCPANIM_FLINCH_TO_FLINCH_UNDERFIRE_INTRO
|
|
CASE CCPANIM_FLINCH_UNDERFIRE_LOOP
|
|
CASE CCPANIM_FLINCH_UNDERFIRE_TO_FLINCH_OUTRO
|
|
|
|
SWITCH eCrowdControlAnimID
|
|
CASE CCPED_CASHIER_A RETURN "anim@heists@ornate_bank@hostages@cashier_a@" BREAK
|
|
CASE CCPED_CASHIER_B RETURN "anim@heists@ornate_bank@hostages@cashier_b@" BREAK
|
|
CASE CCPED_CUSTOMER_A RETURN "anim@heists@ornate_bank@hostages@ped_a@" BREAK
|
|
CASE CCPED_CUSTOMER_B RETURN "anim@heists@ornate_bank@hostages@ped_b@" BREAK
|
|
CASE CCPED_CUSTOMER_C RETURN "anim@heists@ornate_bank@hostages@ped_c@" BREAK
|
|
CASE CCPED_CUSTOMER_D
|
|
IF eHeistType = CCHEIST_CUSTOM_FLEECA
|
|
RETURN "anim@heists@fleeca_bank@hostages@ped_d@"
|
|
ELSE
|
|
RETURN "anim@heists@ornate_bank@hostages@ped_d@"
|
|
ENDIF
|
|
BREAK
|
|
CASE CCPED_CUSTOMER_E RETURN "anim@heists@ornate_bank@hostages@ped_e@" BREAK
|
|
CASE CCPED_CUSTOMER_F RETURN "anim@heists@ornate_bank@hostages@ped_f@" BREAK
|
|
CASE CCPED_CUSTOMER_G RETURN "anim@heists@ornate_bank@hostages@ped_g@" BREAK
|
|
CASE CCPED_CUSTOMER_H RETURN "anim@heists@ornate_bank@hostages@ped_h@" BREAK
|
|
ENDSWITCH
|
|
|
|
BREAK
|
|
|
|
|
|
|
|
CASE CCPANIM_BEATDOWN_INTRO
|
|
CASE CCPANIM_BEATDOWN_LOOP
|
|
CASE CCPANIM_BEATDOWN_HIT_A
|
|
CASE CCPANIM_BEATDOWN_HIT_B
|
|
CASE CCPANIM_BEATDOWN_DIE
|
|
CASE CCPANIM_BEATDOWN_DIE_LOOP
|
|
CASE CCPANIM_BEATDOWN_OUTRO
|
|
RETURN "anim@heists@ornate_bank@hostages@hit"
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
// heist specific
|
|
SWITCH eHeistType
|
|
|
|
CASE CCHEIST_CUSTOM_FLEECA
|
|
|
|
SWITCH eAnimType
|
|
|
|
CASE CCPANIM_INTRO_LOOP
|
|
CASE CCPANIM_INTRO
|
|
RETURN "anim@heists@fleeca_bank@hostages@intro"
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
BREAK
|
|
|
|
CASE CCHEIST_CUSTOM_ORNATE
|
|
|
|
SWITCH eAnimType
|
|
|
|
CASE CCPANIM_INTRO_LOOP
|
|
CASE CCPANIM_INTRO
|
|
RETURN "anim@heists@ornate_bank@hostages@intro"
|
|
BREAK
|
|
|
|
CASE CCPANIM_HERO_START
|
|
CASE CCPANIM_HERO_LOOP
|
|
CASE CCPANIM_HERO_PASS
|
|
CASE CCPANIM_HERO_FAIL
|
|
|
|
SWITCH eCrowdControlAnimID
|
|
CASE CCPED_CASHIER_A RETURN "anim@heists@ornate_bank@hostages@cashier_a@" BREAK
|
|
CASE CCPED_CUSTOMER_B RETURN "anim@heists@ornate_bank@hostages@ped_b@" BREAK
|
|
CASE CCPED_CUSTOMER_C RETURN "anim@heists@ornate_bank@hostages@ped_c@" BREAK
|
|
CASE CCPED_CUSTOMER_D RETURN "anim@heists@ornate_bank@hostages@ped_d@" BREAK
|
|
CASE CCPED_CUSTOMER_G RETURN "anim@heists@ornate_bank@hostages@ped_g@" BREAK
|
|
ENDSWITCH
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
RETURN ""
|
|
ENDFUNC
|
|
|
|
|
|
FUNC STRING GET_CROWD_CONTROL_PED_ANIM_NAME( CROWD_CONTROL_PED_ANIM_TYPE eAnimType, CROWD_CONTROL_PED_ENUM eCrowdControlAnimID, CROWD_CONTROL_HEIST_TYPE eHeistType )
|
|
|
|
IF eHeistType = CCHEIST_CUSTOM_FLEECA
|
|
SWITCH eCrowdControlAnimID
|
|
CASE CCPED_CASHIER_A eCrowdControlAnimID = CCPED_CUSTOMER_D BREAK
|
|
CASE CCPED_CUSTOMER_A eCrowdControlAnimID = CCPED_CUSTOMER_A BREAK
|
|
CASE CCPED_CUSTOMER_B eCrowdControlAnimID = CCPED_CUSTOMER_E BREAK
|
|
ENDSWITCH
|
|
ENDIF
|
|
|
|
// Generic
|
|
SWITCH eAnimType
|
|
|
|
CASE CCPANIM_COWER_LOOP RETURN "idle" BREAK
|
|
|
|
CASE CCPANIM_COWER_TO_FLINCH_INTRO RETURN "flinch_intro" BREAK
|
|
CASE CCPANIM_FLINCH_LOOP RETURN "flinch_loop" BREAK
|
|
CASE CCPANIM_FLINCH_TO_IDLE_OUTRO RETURN "flinch_outro" BREAK
|
|
|
|
CASE CCPANIM_COWER_TO_FLINCH_UNDERFIRE_INTRO RETURN "flinch_under_fire_intro" BREAK
|
|
|
|
CASE CCPANIM_FLINCH_TO_FLINCH_UNDERFIRE_INTRO
|
|
SWITCH eCrowdControlAnimID
|
|
CASE CCPED_CUSTOMER_B
|
|
CASE CCPED_CUSTOMER_C
|
|
CASE CCPED_CUSTOMER_D
|
|
CASE CCPED_CUSTOMER_E
|
|
CASE CCPED_CUSTOMER_F
|
|
CASE CCPED_CUSTOMER_G
|
|
CASE CCPED_CUSTOMER_H
|
|
RETURN "flinch_to_underfire"
|
|
BREAK
|
|
ENDSWITCH
|
|
BREAK
|
|
CASE CCPANIM_FLINCH_UNDERFIRE_TO_FLINCH_OUTRO
|
|
SWITCH eCrowdControlAnimID
|
|
CASE CCPED_CUSTOMER_B
|
|
CASE CCPED_CUSTOMER_C
|
|
CASE CCPED_CUSTOMER_D
|
|
CASE CCPED_CUSTOMER_E
|
|
CASE CCPED_CUSTOMER_F
|
|
CASE CCPED_CUSTOMER_G
|
|
CASE CCPED_CUSTOMER_H
|
|
RETURN "flinch_under_fire_outro"
|
|
BREAK
|
|
ENDSWITCH
|
|
BREAK
|
|
|
|
CASE CCPANIM_FLINCH_UNDERFIRE_LOOP RETURN "flinch_loop_underfire" BREAK
|
|
|
|
CASE CCPANIM_BEATDOWN_INTRO
|
|
SWITCH eCrowdControlAnimID
|
|
CASE CCPED_CASHIER_A RETURN "hit_intro_cashier_a" BREAK
|
|
CASE CCPED_CASHIER_B RETURN "hit_intro_cashier_b" BREAK
|
|
CASE CCPED_CUSTOMER_A RETURN "hit_intro_ped_a" BREAK
|
|
CASE CCPED_CUSTOMER_B RETURN "hit_intro_ped_b" BREAK
|
|
CASE CCPED_CUSTOMER_C RETURN "hit_intro_ped_c" BREAK
|
|
CASE CCPED_CUSTOMER_D RETURN "hit_intro_ped_d" BREAK
|
|
CASE CCPED_CUSTOMER_E RETURN "hit_intro_ped_e" BREAK
|
|
CASE CCPED_CUSTOMER_F RETURN "hit_intro_ped_f" BREAK
|
|
CASE CCPED_CUSTOMER_G RETURN "hit_intro_ped_g" BREAK
|
|
CASE CCPED_CUSTOMER_H RETURN "hit_intro_ped_h" BREAK
|
|
ENDSWITCH
|
|
BREAK
|
|
CASE CCPANIM_BEATDOWN_LOOP
|
|
SWITCH eCrowdControlAnimID
|
|
CASE CCPED_CASHIER_A RETURN "hit_loop_cashier_a" BREAK
|
|
CASE CCPED_CASHIER_B RETURN "hit_loop_cashier_b" BREAK
|
|
CASE CCPED_CUSTOMER_A RETURN "hit_loop_ped_a" BREAK
|
|
CASE CCPED_CUSTOMER_B RETURN "hit_loop_ped_b" BREAK
|
|
CASE CCPED_CUSTOMER_C RETURN "hit_loop_ped_c" BREAK
|
|
CASE CCPED_CUSTOMER_D RETURN "hit_loop_ped_d" BREAK
|
|
CASE CCPED_CUSTOMER_E RETURN "hit_loop_ped_e" BREAK
|
|
CASE CCPED_CUSTOMER_F RETURN "hit_loop_ped_f" BREAK
|
|
CASE CCPED_CUSTOMER_G RETURN "hit_loop_ped_g" BREAK
|
|
CASE CCPED_CUSTOMER_H RETURN "hit_loop_ped_h" BREAK
|
|
ENDSWITCH
|
|
BREAK
|
|
CASE CCPANIM_BEATDOWN_HIT_A
|
|
SWITCH eCrowdControlAnimID
|
|
CASE CCPED_CASHIER_A RETURN "hit_react_a_cashier_a" BREAK
|
|
CASE CCPED_CASHIER_B RETURN "hit_react_a_cashier_b" BREAK
|
|
CASE CCPED_CUSTOMER_A RETURN "hit_react_a_ped_a" BREAK
|
|
CASE CCPED_CUSTOMER_B RETURN "hit_react_a_ped_b" BREAK
|
|
CASE CCPED_CUSTOMER_C RETURN "hit_react_a_ped_c" BREAK
|
|
CASE CCPED_CUSTOMER_D RETURN "hit_react_a_ped_d" BREAK
|
|
CASE CCPED_CUSTOMER_E RETURN "hit_react_a_ped_e" BREAK
|
|
CASE CCPED_CUSTOMER_F RETURN "hit_react_a_ped_f" BREAK
|
|
CASE CCPED_CUSTOMER_G RETURN "hit_react_a_ped_g" BREAK
|
|
CASE CCPED_CUSTOMER_H RETURN "hit_react_a_ped_h" BREAK
|
|
ENDSWITCH
|
|
BREAK
|
|
CASE CCPANIM_BEATDOWN_HIT_B
|
|
SWITCH eCrowdControlAnimID
|
|
CASE CCPED_CASHIER_A RETURN "hit_react_b_cashier_a" BREAK
|
|
CASE CCPED_CASHIER_B RETURN "hit_react_b_cashier_b" BREAK
|
|
CASE CCPED_CUSTOMER_A RETURN "hit_react_b_ped_a" BREAK
|
|
CASE CCPED_CUSTOMER_B RETURN "hit_react_b_ped_b" BREAK
|
|
CASE CCPED_CUSTOMER_C RETURN "hit_react_b_ped_c" BREAK
|
|
CASE CCPED_CUSTOMER_D RETURN "hit_react_b_ped_d" BREAK
|
|
CASE CCPED_CUSTOMER_E RETURN "hit_react_b_ped_e" BREAK
|
|
CASE CCPED_CUSTOMER_F RETURN "hit_react_b_ped_f" BREAK
|
|
CASE CCPED_CUSTOMER_G RETURN "hit_react_b_ped_g" BREAK
|
|
CASE CCPED_CUSTOMER_H RETURN "hit_react_b_ped_h" BREAK
|
|
ENDSWITCH
|
|
BREAK
|
|
CASE CCPANIM_BEATDOWN_DIE
|
|
SWITCH eCrowdControlAnimID
|
|
CASE CCPED_CASHIER_A RETURN "hit_react_die_cashier_a" BREAK
|
|
CASE CCPED_CASHIER_B RETURN "hit_react_die_cashier_b" BREAK
|
|
CASE CCPED_CUSTOMER_A RETURN "hit_react_die_ped_a" BREAK
|
|
CASE CCPED_CUSTOMER_B RETURN "hit_react_die_ped_b" BREAK
|
|
CASE CCPED_CUSTOMER_C RETURN "hit_react_die_ped_c" BREAK
|
|
CASE CCPED_CUSTOMER_D RETURN "hit_react_die_ped_d" BREAK
|
|
CASE CCPED_CUSTOMER_E RETURN "hit_react_die_ped_e" BREAK
|
|
CASE CCPED_CUSTOMER_F RETURN "hit_react_die_ped_f" BREAK
|
|
CASE CCPED_CUSTOMER_G RETURN "hit_react_die_ped_g" BREAK
|
|
CASE CCPED_CUSTOMER_H RETURN "hit_react_die_ped_h" BREAK
|
|
ENDSWITCH
|
|
BREAK
|
|
CASE CCPANIM_BEATDOWN_DIE_LOOP
|
|
SWITCH eCrowdControlAnimID
|
|
CASE CCPED_CASHIER_A RETURN "hit_react_die_loop_cashier_a" BREAK
|
|
CASE CCPED_CASHIER_B RETURN "hit_react_die_loop_cashier_b" BREAK
|
|
CASE CCPED_CUSTOMER_A RETURN "hit_react_die_loop_ped_a" BREAK
|
|
CASE CCPED_CUSTOMER_B RETURN "hit_react_die_loop_ped_b" BREAK
|
|
CASE CCPED_CUSTOMER_C RETURN "hit_react_die_loop_ped_c" BREAK
|
|
CASE CCPED_CUSTOMER_D RETURN "hit_react_die_loop_ped_d" BREAK
|
|
CASE CCPED_CUSTOMER_E RETURN "hit_react_die_loop_ped_e" BREAK
|
|
CASE CCPED_CUSTOMER_F RETURN "hit_react_die_loop_ped_f" BREAK
|
|
CASE CCPED_CUSTOMER_G RETURN "hit_react_die_loop_ped_g" BREAK
|
|
CASE CCPED_CUSTOMER_H RETURN "hit_react_die_loop_ped_h" BREAK
|
|
ENDSWITCH
|
|
BREAK
|
|
CASE CCPANIM_BEATDOWN_OUTRO
|
|
SWITCH eCrowdControlAnimID
|
|
CASE CCPED_CASHIER_A RETURN "hit_react_outro_cashier_a" BREAK
|
|
CASE CCPED_CASHIER_B RETURN "hit_react_outro_cashier_b" BREAK
|
|
CASE CCPED_CUSTOMER_A RETURN "hit_react_outro_ped_a" BREAK
|
|
CASE CCPED_CUSTOMER_B RETURN "hit_react_outro_ped_b" BREAK
|
|
CASE CCPED_CUSTOMER_C RETURN "hit_react_outro_ped_c" BREAK
|
|
CASE CCPED_CUSTOMER_D RETURN "hit_react_outro_ped_d" BREAK
|
|
CASE CCPED_CUSTOMER_E RETURN "hit_react_outro_ped_e" BREAK
|
|
CASE CCPED_CUSTOMER_F RETURN "hit_react_outro_ped_f" BREAK
|
|
CASE CCPED_CUSTOMER_G RETURN "hit_react_outro_ped_g" BREAK
|
|
CASE CCPED_CUSTOMER_H RETURN "hit_react_outro_ped_h" BREAK
|
|
ENDSWITCH
|
|
BREAK
|
|
|
|
CASE CCPANIM_HERO_START RETURN "reach" BREAK
|
|
CASE CCPANIM_HERO_LOOP RETURN "reach_loop" BREAK
|
|
CASE CCPANIM_HERO_PASS RETURN "pass" BREAK
|
|
CASE CCPANIM_HERO_FAIL RETURN "fail" BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
// Heist specific
|
|
SWITCH eHeistType
|
|
|
|
CASE CCHEIST_CUSTOM_FLEECA
|
|
|
|
SWITCH eAnimType
|
|
|
|
CASE CCPANIM_INTRO_LOOP
|
|
SWITCH eCrowdControlAnimID
|
|
CASE CCPED_CUSTOMER_D RETURN "intro_loop_ped_d" BREAK
|
|
CASE CCPED_CUSTOMER_A RETURN "intro_loop_ped_a" BREAK
|
|
CASE CCPED_CUSTOMER_E RETURN "intro_loop_ped_e" BREAK
|
|
ENDSWITCH
|
|
BREAK
|
|
|
|
CASE CCPANIM_INTRO
|
|
SWITCH eCrowdControlAnimID
|
|
CASE CCPED_CUSTOMER_D RETURN "intro_standing_ped_d" BREAK // "intro_ped_d"
|
|
CASE CCPED_CUSTOMER_A RETURN "intro_ped_a" BREAK
|
|
CASE CCPED_CUSTOMER_E RETURN "intro_ped_e" BREAK
|
|
ENDSWITCH
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
BREAK
|
|
|
|
CASE CCHEIST_CUSTOM_ORNATE
|
|
|
|
SWITCH eAnimType
|
|
|
|
CASE CCPANIM_INTRO_LOOP
|
|
SWITCH eCrowdControlAnimID
|
|
CASE CCPED_CASHIER_A RETURN "intro_loop_cashier_a" BREAK
|
|
CASE CCPED_CASHIER_B RETURN "intro_loop_cashier_b" BREAK
|
|
CASE CCPED_CUSTOMER_A RETURN "intro_loop_ped_a" BREAK
|
|
CASE CCPED_CUSTOMER_B RETURN "intro_loop_ped_b" BREAK
|
|
CASE CCPED_CUSTOMER_C RETURN "intro_loop_ped_c" BREAK
|
|
CASE CCPED_CUSTOMER_D RETURN "intro_loop_ped_d" BREAK
|
|
CASE CCPED_CUSTOMER_E RETURN "intro_loop_ped_e" BREAK
|
|
CASE CCPED_CUSTOMER_F RETURN "intro_loop_ped_f" BREAK
|
|
CASE CCPED_CUSTOMER_G RETURN "intro_loop_ped_g" BREAK
|
|
CASE CCPED_CUSTOMER_H RETURN "intro_loop_ped_h" BREAK
|
|
ENDSWITCH
|
|
BREAK
|
|
|
|
CASE CCPANIM_INTRO
|
|
SWITCH eCrowdControlAnimID
|
|
CASE CCPED_CASHIER_A RETURN "intro_cashier_a" BREAK
|
|
CASE CCPED_CASHIER_B RETURN "intro_cashier_b" BREAK
|
|
CASE CCPED_CUSTOMER_A RETURN "intro_ped_a" BREAK
|
|
CASE CCPED_CUSTOMER_B RETURN "intro_ped_b" BREAK
|
|
CASE CCPED_CUSTOMER_C RETURN "intro_ped_c" BREAK
|
|
CASE CCPED_CUSTOMER_D RETURN "intro_ped_d" BREAK
|
|
CASE CCPED_CUSTOMER_E RETURN "intro_ped_e" BREAK
|
|
CASE CCPED_CUSTOMER_F RETURN "intro_ped_f" BREAK
|
|
CASE CCPED_CUSTOMER_G RETURN "intro_ped_g" BREAK
|
|
CASE CCPED_CUSTOMER_H RETURN "intro_ped_h" BREAK
|
|
ENDSWITCH
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
RETURN ""
|
|
ENDFUNC
|
|
|
|
|
|
FUNC STRING GET_CROWD_CONTROL_PLAYER_ANIM_DICTIONARY( CROWD_CONTROL_PLAYER_ANIM_TYPE eAnimType )
|
|
SWITCH eAnimType
|
|
|
|
CASE CCPLAYERANIM_BEATDOWN_PISTOL_A
|
|
CASE CCPLAYERANIM_BEATDOWN_PISTOL_B
|
|
CASE CCPLAYERANIM_BEATDOWN_PISTOL_KICK_A
|
|
CASE CCPLAYERANIM_BEATDOWN_PISTOL_KICK_B
|
|
CASE CCPLAYERANIM_BEATDOWN_RIFLE_A
|
|
CASE CCPLAYERANIM_BEATDOWN_RIFLE_B
|
|
CASE CCPLAYERANIM_BEATDOWN_RIFLE_KICK_A
|
|
CASE CCPLAYERANIM_BEATDOWN_RIFLE_KICK_B
|
|
CASE CCPLAYERANIM_BEATDOWN_LONG_PISTOL_A
|
|
CASE CCPLAYERANIM_BEATDOWN_LONG_PISTOL_KICK_A
|
|
CASE CCPLAYERANIM_BEATDOWN_LONG_RIFLE_A
|
|
CASE CCPLAYERANIM_BEATDOWN_LONG_RIFLE_B
|
|
CASE CCPLAYERANIM_BEATDOWN_LONG_RIFLE_KICK_A
|
|
CASE CCPLAYERANIM_BEATDOWN_LONG_RIFLE_KICK_B
|
|
RETURN "anim@heists@ornate_bank@hostages@hit"
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
RETURN ""
|
|
ENDFUNC
|
|
|
|
|
|
FUNC STRING GET_CROWD_CONTROL_PLAYER_ANIM_NAME( CROWD_CONTROL_PLAYER_ANIM_TYPE eAnimType )
|
|
SWITCH eAnimType
|
|
|
|
CASE CCPLAYERANIM_BEATDOWN_PISTOL_A RETURN "player_melee_pistol_a" BREAK
|
|
CASE CCPLAYERANIM_BEATDOWN_PISTOL_B RETURN "player_melee_pistol_b" BREAK
|
|
CASE CCPLAYERANIM_BEATDOWN_PISTOL_KICK_A RETURN "player_melee_pistol_kick_a" BREAK
|
|
CASE CCPLAYERANIM_BEATDOWN_PISTOL_KICK_B RETURN "player_melee_pistol_kick_b" BREAK
|
|
CASE CCPLAYERANIM_BEATDOWN_LONG_PISTOL_A RETURN "player_melee_long_pistol_a" BREAK
|
|
CASE CCPLAYERANIM_BEATDOWN_LONG_PISTOL_KICK_A RETURN "player_melee_long_pistol_kick_a" BREAK
|
|
|
|
CASE CCPLAYERANIM_BEATDOWN_RIFLE_A RETURN "player_melee_rifle_a" BREAK
|
|
CASE CCPLAYERANIM_BEATDOWN_RIFLE_B RETURN "player_melee_rifle_b" BREAK
|
|
CASE CCPLAYERANIM_BEATDOWN_RIFLE_KICK_A RETURN "player_melee_rifle_kick_a" BREAK
|
|
CASE CCPLAYERANIM_BEATDOWN_RIFLE_KICK_B RETURN "player_melee_rifle_kick_b" BREAK
|
|
CASE CCPLAYERANIM_BEATDOWN_LONG_RIFLE_A RETURN "player_melee_long_rifle_a" BREAK
|
|
CASE CCPLAYERANIM_BEATDOWN_LONG_RIFLE_B RETURN "player_melee_long_rifle_b" BREAK
|
|
CASE CCPLAYERANIM_BEATDOWN_LONG_RIFLE_KICK_A RETURN "player_melee_long_rifle_kick_a" BREAK
|
|
CASE CCPLAYERANIM_BEATDOWN_LONG_RIFLE_KICK_B RETURN "player_melee_long_rifle_kick_b" BREAK
|
|
|
|
ENDSWITCH
|
|
RETURN ""
|
|
ENDFUNC
|
|
|
|
|
|
FUNC CROWD_CONTROL_PED_HERO_ACTION GET_CROWD_CONTROL_PED_HERO_ACTION_FOR_ANIMATED_PED( CROWD_CONTROL_PED_ENUM eCrowdControlAnimID, CROWD_CONTROL_HEIST_TYPE eHeistType )
|
|
|
|
SWITCH eHeistType
|
|
|
|
CASE CCHEIST_CUSTOM_FLEECA
|
|
SWITCH eCrowdControlAnimID
|
|
CASE CCPED_CASHIER_A RETURN CCHERO_ALARM BREAK
|
|
ENDSWITCH
|
|
BREAK
|
|
|
|
CASE CCHEIST_CUSTOM_ORNATE
|
|
|
|
SWITCH eCrowdControlAnimID
|
|
// cashier A has a hero anim set
|
|
CASE CCPED_CASHIER_A RETURN CCHERO_ALARM BREAK
|
|
CASE CCPED_CUSTOMER_B RETURN CCHERO_GUN BREAK
|
|
CASE CCPED_CUSTOMER_C RETURN CCHERO_PHONE BREAK
|
|
CASE CCPED_CUSTOMER_D RETURN CCHERO_PHONE BREAK
|
|
CASE CCPED_CUSTOMER_G RETURN CCHERO_GUN BREAK
|
|
ENDSWITCH
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
RETURN CCHERO_NONE
|
|
ENDFUNC
|
|
|
|
|
|
FUNC VECTOR GET_CROWD_CONTROL_PED_ANIM_SCENE_COORD( CROWD_CONTROL_HEIST_TYPE eHeistType, CROWD_CONTROL_PED_ANIM_TYPE eAnim )
|
|
SWITCH eHeistType
|
|
|
|
// Fleeca uses an origin only for the intro loop and intro transition
|
|
// after which the anims are played in place so no origin needed
|
|
CASE CCHEIST_CUSTOM_FLEECA
|
|
IF eAnim = CCPANIM_INTRO OR eAnim = CCPANIM_INTRO_LOOP
|
|
RETURN << -2965.760, 484.220, 16.036 >>
|
|
ENDIF
|
|
BREAK
|
|
|
|
// All ornate anims use the same origin
|
|
CASE CCHEIST_CUSTOM_ORNATE
|
|
IF eAnim = CCPANIM_INTRO OR eAnim = CCPANIM_INTRO_LOOP
|
|
RETURN <<249.2121, 217.7811, 105.277>>
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
RETURN <<0,0,0>>
|
|
ENDFUNC
|
|
|
|
|
|
FUNC VECTOR GET_CROWD_CONTROL_PED_ANIM_SCENE_ROT( CROWD_CONTROL_HEIST_TYPE eHeistType )
|
|
SWITCH eHeistType
|
|
CASE CCHEIST_CUSTOM_FLEECA RETURN <<0,0,-92.750>> BREAK
|
|
CASE CCHEIST_CUSTOM_ORNATE RETURN <<0,0,-20>> BREAK
|
|
ENDSWITCH
|
|
RETURN <<0,0,0>>
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL DOES_CROWD_CONTROL_PED_HAVE_ANIM( CROWD_CONTROL_PED_ANIM_TYPE eAnimType, CROWD_CONTROL_PED_ENUM eCrowdControlAnimID, CROWD_CONTROL_HEIST_TYPE eHeistType )
|
|
IF NOT IS_STRING_NULL_OR_EMPTY( GET_CROWD_CONTROL_PED_ANIM_DICTIONARY( eAnimType, eCrowdControlAnimID, eHeistType ) )
|
|
AND NOT IS_STRING_NULL_OR_EMPTY( GET_CROWD_CONTROL_PED_ANIM_NAME( eAnimType, eCrowdControlAnimID, eHeistType ) )
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL IS_PED_PLAYING_ANIM( PED_INDEX ped, STRING strAnimDict, STRING strAnimName, BOOL bUseSyncSceneCheck = FALSE )
|
|
|
|
BOOL bRunning
|
|
ANIM_TYPE eAnimType
|
|
IF bUseSyncSceneCheck
|
|
bRunning = IS_SCRIPT_TASK_RUNNING_OR_STARTING( ped, SCRIPT_TASK_SYNCHRONIZED_SCENE )
|
|
eAnimType = ANIM_SYNCED_SCENE
|
|
ELSE
|
|
bRunning = IS_SCRIPT_TASK_RUNNING_OR_STARTING( ped, SCRIPT_TASK_PLAY_ANIM )
|
|
OR IS_SCRIPT_TASK_RUNNING_OR_STARTING( ped, SCRIPT_TASK_PERFORM_SEQUENCE )
|
|
eAnimType = ANIM_DEFAULT
|
|
ENDIF
|
|
|
|
IF bRunning
|
|
IF IS_ENTITY_PLAYING_ANIM( ped, strAnimDict, strAnimName, eAnimType )
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL IS_CROWD_CONTROL_PED_PLAYING_ANIM( PED_INDEX ped, CROWD_CONTROL_PED_ANIM_TYPE eAnim, CROWD_CONTROL_PED_ENUM eCrowdControlAnimID, CROWD_CONTROL_HEIST_TYPE eHeistType, BOOL bUseSyncSceneCheck = FALSE )
|
|
IF DOES_CROWD_CONTROL_PED_HAVE_ANIM( eAnim, eCrowdControlAnimID, eHeistType )
|
|
STRING strAnimDict = GET_CROWD_CONTROL_PED_ANIM_DICTIONARY( eAnim, eCrowdControlAnimID, eHeistType )
|
|
STRING strAnimName = GET_CROWD_CONTROL_PED_ANIM_NAME( eAnim, eCrowdControlAnimID, eHeistType )
|
|
RETURN IS_PED_PLAYING_ANIM( ped, strAnimDict, strAnimName, bUseSyncSceneCheck )
|
|
ENDIF
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL IS_CROWD_CONTROL_PLAYER_PLAYING_ANIM( PED_INDEX ped, CROWD_CONTROL_PLAYER_ANIM_TYPE eAnim, BOOL bUseSyncSceneCheck = FALSE )
|
|
STRING strAnimDict = GET_CROWD_CONTROL_PLAYER_ANIM_DICTIONARY( eAnim )
|
|
STRING strAnimName = GET_CROWD_CONTROL_PLAYER_ANIM_NAME( eAnim )
|
|
RETURN IS_PED_PLAYING_ANIM( ped, strAnimDict, strAnimName, bUseSyncSceneCheck )
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL HAS_PED_FINISHED_ANIM( PED_INDEX ped, STRING strAnimDict, STRING strAnimName, FLOAT fFinishPhase = 1.0, BOOL bUseSyncSceneCheck = FALSE, INT iNetSyncSceneID = -1, INT iAnimEndTagHash = 0 )
|
|
|
|
IF IS_PED_PLAYING_ANIM( ped, strAnimDict, strAnimName, bUseSyncSceneCheck )
|
|
|
|
BOOL bResult
|
|
FLOAT fPhase
|
|
|
|
IF bUseSyncSceneCheck
|
|
|
|
IF iNetSyncSceneID = -1
|
|
|
|
SCRIPT_ASSERT( "HAS_PED_FINISHED_ANIM() - Invalid sync scene ID, iNetSyncSceneID = -1" )
|
|
|
|
ELSE
|
|
|
|
INT iLocalSyncSceneID = NETWORK_GET_LOCAL_SCENE_FROM_NETWORK_ID( iNetSyncSceneID )
|
|
IF IS_SYNCHRONIZED_SCENE_RUNNING( iLocalSyncSceneID )
|
|
fPhase = GET_SYNCHRONIZED_SCENE_PHASE( iLocalSyncSceneID )
|
|
IF fPhase >= fFinishPhase
|
|
bResult = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ELSE
|
|
|
|
fPhase = GET_ENTITY_ANIM_CURRENT_TIME( ped, strAnimDict, strAnimName )
|
|
IF fPhase >= fFinishPhase
|
|
bResult = TRUE
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
IF iAnimEndTagHash != 0
|
|
AND HAS_ANIM_EVENT_FIRED( ped, iAnimEndTagHash )
|
|
CPRINTLN(DEBUG_NET_MINIGAME, "HAS_PED_FINISHED_ANIM() - ANIM EVENT \"", iAnimEndTagHash, "\" FIRED - PHASE = ", fPhase, " Dictionary = \"", strAnimDict, "\" AnimName = \"", strAnimName, "\"" )
|
|
bResult = TRUE
|
|
ENDIF
|
|
|
|
RETURN bResult
|
|
ENDIF
|
|
|
|
RETURN TRUE
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL HAS_CROWD_CONTROL_PED_FINISHED_ANIM( PED_INDEX ped, CROWD_CONTROL_PED_ANIM_TYPE eAnim, CROWD_CONTROL_PED_ENUM eCrowdControlAnimID, CROWD_CONTROL_HEIST_TYPE eHeistType, FLOAT fFinishPhase = 1.0, BOOL bUseSyncSceneCheck = FALSE, INT iNetSyncSceneID = -1, INT iAnimEndTagHash = 0 )
|
|
RETURN HAS_PED_FINISHED_ANIM( ped,
|
|
GET_CROWD_CONTROL_PED_ANIM_DICTIONARY( eAnim, eCrowdControlAnimID, eHeistType ),
|
|
GET_CROWD_CONTROL_PED_ANIM_NAME( eAnim, eCrowdControlAnimID, eHeistType ),
|
|
fFinishPhase, bUseSyncSceneCheck, iNetSyncSceneID, iAnimEndTagHash )
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL HAS_CROWD_CONTROL_PLAYER_FINISHED_ANIM( PED_INDEX ped, CROWD_CONTROL_PLAYER_ANIM_TYPE eAnim, FLOAT fFinishPhase = 1.0, BOOL bUseSyncSceneCheck = FALSE, INT iNetSyncSceneID = -1, INT iAnimEndTagHash = 0 )
|
|
RETURN HAS_PED_FINISHED_ANIM( ped,
|
|
GET_CROWD_CONTROL_PLAYER_ANIM_DICTIONARY( eAnim ),
|
|
GET_CROWD_CONTROL_PLAYER_ANIM_NAME( eAnim ),
|
|
fFinishPhase, bUseSyncSceneCheck, iNetSyncSceneID, iAnimEndTagHash )
|
|
ENDFUNC
|
|
|
|
|
|
PROC REQUEST_CROWD_CONTROL_PED_ANIM( CROWD_CONTROL_PED_ANIM_TYPE eAnimType, CROWD_CONTROL_HEIST_TYPE eHeist, CROWD_CONTROL_PED_ENUM eCrowdControlAnimID )
|
|
IF DOES_CROWD_CONTROL_PED_HAVE_ANIM( eAnimType, eCrowdControlAnimID, eHeist )
|
|
REQUEST_ANIM_DICT( GET_CROWD_CONTROL_PED_ANIM_DICTIONARY( eAnimType, eCrowdControlAnimID, eHeist ) )
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
|
|
PROC RELEASE_CROWD_CONTROL_PED_ANIM( CROWD_CONTROL_PED_ANIM_TYPE eAnimType, CROWD_CONTROL_HEIST_TYPE eHeist, CROWD_CONTROL_PED_ENUM eCrowdControlAnimID )
|
|
IF DOES_CROWD_CONTROL_PED_HAVE_ANIM( eAnimType, eCrowdControlAnimID, eHeist )
|
|
REMOVE_ANIM_DICT( GET_CROWD_CONTROL_PED_ANIM_DICTIONARY( eAnimType, eCrowdControlAnimID, eHeist ) )
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
|
|
FUNC BOOL HAS_CROWD_CONTROL_PED_ANIM_LOADED( CROWD_CONTROL_PED_ANIM_TYPE eAnimType, CROWD_CONTROL_HEIST_TYPE eHeist, CROWD_CONTROL_PED_ENUM eCrowdControlAnimID )
|
|
IF DOES_CROWD_CONTROL_PED_HAVE_ANIM( eAnimType, eCrowdControlAnimID, eHeist )
|
|
IF HAS_ANIM_DICT_LOADED( GET_CROWD_CONTROL_PED_ANIM_DICTIONARY( eAnimType, eCrowdControlAnimID, eHeist ) )
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
PROC REQUEST_CROWD_CONTROL_PED_ANIMS_FOR_SCENE( CROWD_CONTROL_PED_ANIM_TYPE eAnimType, CROWD_CONTROL_HEIST_TYPE eHeist, CROWD_CONTROL_LOCAL_PED_DATA &sCrowdControlLocalPedData[], INT iNumCrowdPeds )
|
|
INT i
|
|
FOR i = 0 TO iNumCrowdPeds
|
|
IF i < FMMC_MAX_CROWD_PEDS
|
|
REQUEST_CROWD_CONTROL_PED_ANIM( eAnimType, eHeist, sCrowdControlLocalPedData[i].eCreatorAssignedPedID )
|
|
ENDIF
|
|
ENDFOR
|
|
ENDPROC
|
|
|
|
|
|
PROC RELEASE_CROWD_CONTROL_PED_ANIMS_FOR_SCENE( CROWD_CONTROL_PED_ANIM_TYPE eAnimType, CROWD_CONTROL_HEIST_TYPE eHeist, CROWD_CONTROL_LOCAL_PED_DATA &sCrowdControlLocalPedData[], INT iNumCrowdPeds )
|
|
INT i
|
|
FOR i = 0 TO iNumCrowdPeds
|
|
IF i < FMMC_MAX_CROWD_PEDS
|
|
RELEASE_CROWD_CONTROL_PED_ANIM( eAnimType, eHeist, sCrowdControlLocalPedData[i].eCreatorAssignedPedID )
|
|
ENDIF
|
|
ENDFOR
|
|
ENDPROC
|
|
|
|
|
|
FUNC BOOL HAVE_CROWD_CONTROL_PED_ANIMS_LOADED_FOR_SCENE( CROWD_CONTROL_PED_ANIM_TYPE eAnimType, CROWD_CONTROL_HEIST_TYPE eHeist, CROWD_CONTROL_LOCAL_PED_DATA &sCrowdControlLocalPedData[], INT iNumCrowdPeds )
|
|
BOOL bFinished = TRUE
|
|
INT i
|
|
FOR i = 0 TO iNumCrowdPeds
|
|
IF i < FMMC_MAX_CROWD_PEDS
|
|
IF NOT HAS_CROWD_CONTROL_PED_ANIM_LOADED( eAnimType, eHeist, sCrowdControlLocalPedData[i].eCreatorAssignedPedID )
|
|
bFinished = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
ENDFOR
|
|
RETURN bFinished
|
|
ENDFUNC
|
|
|
|
|
|
PROC PLAY_CROWD_CONTROL_ANIM( PED_INDEX pedCrowd,
|
|
CROWD_CONTROL_PED_ANIM_TYPE eAnim, CROWD_CONTROL_PED_ENUM eCreatorAssignedID, CROWD_CONTROL_HEIST_TYPE eHeistType,
|
|
FLOAT fBlendInDelta = NORMAL_BLEND_IN, FLOAT fBlendOutDelta = NORMAL_BLEND_OUT,
|
|
INT iAnimDuration = -1, ANIMATION_FLAGS eAnimFlags = AF_DEFAULT )
|
|
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PLAY_CROWD_CONTROL_ANIM() - ", GET_CROWD_CONTROL_PED_NAME_FROM_ANIM_ID( eCreatorAssignedID ),
|
|
" | AnimType = ", GET_CROWD_CONTROL_PED_ANIM_ENUM_NAME( eAnim ),
|
|
" | fBlendIn = ", fBlendInDelta,
|
|
" | fBlendOut = ", fBlendOutDelta,
|
|
" | iAnimDuration = ", iAnimDuration )
|
|
|
|
// Playing from where the ped is
|
|
IF IS_VECTOR_ZERO( GET_CROWD_CONTROL_PED_ANIM_SCENE_COORD( eHeistType, eAnim ) )
|
|
|
|
TASK_PLAY_ANIM( pedCrowd,
|
|
GET_CROWD_CONTROL_PED_ANIM_DICTIONARY( eAnim, eCreatorAssignedID, eHeistType ),
|
|
GET_CROWD_CONTROL_PED_ANIM_NAME( eAnim, eCreatorAssignedID, eHeistType ),
|
|
fBlendInDelta, fBlendOutDelta, iAnimDuration, eAnimFlags, DEFAULT, DEFAULT, AIK_DISABLE_LEG_IK )
|
|
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PLAY_CROWD_CONTROL_ANIM() Played with TASK_PLAY_ANIM" )
|
|
|
|
// Playing from an offset so use anim advanced and extract the initial offset
|
|
ELSE
|
|
|
|
TASK_PLAY_ANIM_ADVANCED( pedCrowd,
|
|
GET_CROWD_CONTROL_PED_ANIM_DICTIONARY( eAnim, eCreatorAssignedID, eHeistType ),
|
|
GET_CROWD_CONTROL_PED_ANIM_NAME( eAnim, eCreatorAssignedID, eHeistType ),
|
|
GET_CROWD_CONTROL_PED_ANIM_SCENE_COORD( eHeistType, eAnim ),
|
|
GET_CROWD_CONTROL_PED_ANIM_SCENE_ROT( eHeistType ),
|
|
fBlendInDelta, fBlendOutDelta, iAnimDuration, eAnimFlags | AF_EXTRACT_INITIAL_OFFSET, DEFAULT, DEFAULT, AIK_DISABLE_LEG_IK )
|
|
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PLAY_CROWD_CONTROL_ANIM() Played with TASK_PLAY_ANIM_ADVANCED" )
|
|
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
PROC PLAY_CROWD_CONTROL_SYNC_SCENE( INT &iSyncSceneID, NETWORK_INDEX &pedsGlobalArray[], INT &iCloudPedIDLookupArray[], CROWD_CONTROL_LOCAL_PED_DATA &sCrowdControlLocalPedData[], INT iNumCrowdPeds, CROWD_CONTROL_PED_ANIM_TYPE eAnim, CROWD_CONTROL_HEIST_TYPE eHeistType, FLOAT fBlendInDelta, FLOAT fBlendOutDelta, BOOL bLoop, BOOL bHoldLastFrame, SYNCED_SCENE_PLAYBACK_FLAGS eSyncSceneFlags, RAGDOLL_BLOCKING_FLAGS eRagdollBlockingFlags )
|
|
|
|
iSyncSceneID = NETWORK_CREATE_SYNCHRONISED_SCENE(
|
|
GET_CROWD_CONTROL_PED_ANIM_SCENE_COORD( eHeistType, eAnim ),
|
|
GET_CROWD_CONTROL_PED_ANIM_SCENE_ROT( eHeistType ), DEFAULT, bHoldLastFrame, bLoop )
|
|
|
|
IF bLoop
|
|
eSyncSceneFlags = eSyncSceneFlags | SYNCED_SCENE_LOOP_WITHIN_SCENE
|
|
ENDIF
|
|
|
|
// Task all the peds with their intro loop anim
|
|
INT i
|
|
FOR i = 0 TO iNumCrowdPeds-1
|
|
|
|
IF NETWORK_DOES_ENTITY_EXIST_WITH_NETWORK_ID( pedsGlobalArray[iCloudPedIDLookupArray[i]] )
|
|
AND NOT IS_PED_INJURED( NET_TO_PED( pedsGlobalArray[iCloudPedIDLookupArray[i]] ) )
|
|
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PLAY_CROWD_CONTROL_SYNC_SCENE() - TASKING ANIM dict: ", GET_CROWD_CONTROL_PED_ANIM_DICTIONARY( eAnim, sCrowdControlLocalPedData[i].eCreatorAssignedPedID, eHeistType ),
|
|
" anim: ", GET_CROWD_CONTROL_PED_ANIM_NAME( eAnim, sCrowdControlLocalPedData[i].eCreatorAssignedPedID, eHeistType ))
|
|
|
|
NETWORK_ADD_PED_TO_SYNCHRONISED_SCENE( NET_TO_PED( pedsGlobalArray[iCloudPedIDLookupArray[i]] ),
|
|
iSyncSceneID,
|
|
GET_CROWD_CONTROL_PED_ANIM_DICTIONARY( eAnim, sCrowdControlLocalPedData[i].eCreatorAssignedPedID, eHeistType ),
|
|
GET_CROWD_CONTROL_PED_ANIM_NAME( eAnim, sCrowdControlLocalPedData[i].eCreatorAssignedPedID, eHeistType ),
|
|
fBlendInDelta, fBlendOutDelta,
|
|
eSyncSceneFlags, eRagdollBlockingFlags
|
|
)
|
|
|
|
ENDIF
|
|
|
|
ENDFOR
|
|
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PLAY_CROWD_CONTROL_SYNC_SCENE() - START SCENE" )
|
|
NETWORK_START_SYNCHRONISED_SCENE( iSyncSceneID )
|
|
|
|
ENDPROC
|
|
|
|
|
|
PROC SET_CROWD_CONTROL_PED_DECORATORS( PED_INDEX pedCrowd, CROWD_CONTROL_PED_DECORATOR_DATA &sPedNewDecorators )
|
|
|
|
DECOR_SET_INT( pedCrowd, GET_CROWD_CONTROL_PED_DECOR_NAME( CCPDECOR_iState ), ENUM_TO_INT( sPedNewDecorators.eState ) )
|
|
DECOR_SET_INT( pedCrowd, GET_CROWD_CONTROL_PED_DECOR_NAME( CCPDECOR_iStatePrev ), ENUM_TO_INT( sPedNewDecorators.eStatePrev ) )
|
|
DECOR_SET_INT( pedCrowd, GET_CROWD_CONTROL_PED_DECOR_NAME( CCPDECOR_iBitSet ), sPedNewDecorators.iBitSet )
|
|
DECOR_SET_FLOAT( pedCrowd, GET_CROWD_CONTROL_PED_DECOR_NAME( CCPDECOR_fInfluenceDirectThreat ), sPedNewDecorators.fInfluenceDirectThreat )
|
|
DECOR_SET_FLOAT( pedCrowd, GET_CROWD_CONTROL_PED_DECOR_NAME( CCPDECOR_fInfluenceShouting ), sPedNewDecorators.fInfluenceShouting )
|
|
DECOR_SET_INT( pedCrowd, GET_CROWD_CONTROL_PED_DECOR_NAME( CCPDECOR_iBeatdownHitsRemaining ), sPedNewDecorators.iBeatdownHitsRemaining )
|
|
DECOR_SET_INT( pedCrowd, GET_CROWD_CONTROL_PED_DECOR_NAME( CCPDECOR_iBeatdownRounds ), sPedNewDecorators.iBeatdownRounds )
|
|
|
|
ENDPROC
|
|
|
|
|
|
FUNC CROWD_CONTROL_PED_DECORATOR_DATA GET_CROWD_CONTROL_PED_DECORATOR_DATA( PED_INDEX pedCrowd )
|
|
CROWD_CONTROL_PED_DECORATOR_DATA sPedData
|
|
|
|
STRING strTemp = GET_CROWD_CONTROL_PED_DECOR_NAME( CCPDECOR_iState )
|
|
IF DECOR_EXIST_ON( pedCrowd, strTemp )
|
|
sPedData.eState = INT_TO_ENUM( CROWD_CONTROL_PED_STATE, DECOR_GET_INT( pedCrowd, strTemp ) )
|
|
ENDIF
|
|
|
|
strTemp = GET_CROWD_CONTROL_PED_DECOR_NAME( CCPDECOR_iStatePrev )
|
|
IF DECOR_EXIST_ON( pedCrowd, strTemp )
|
|
sPedData.eStatePrev = INT_TO_ENUM( CROWD_CONTROL_PED_STATE, DECOR_GET_INT( pedCrowd, strTemp ) )
|
|
ENDIF
|
|
|
|
strTemp = GET_CROWD_CONTROL_PED_DECOR_NAME( CCPDECOR_iBitSet )
|
|
IF DECOR_EXIST_ON( pedCrowd, strTemp )
|
|
sPedData.iBitSet = DECOR_GET_INT( pedCrowd, strTemp )
|
|
ENDIF
|
|
|
|
strTemp = GET_CROWD_CONTROL_PED_DECOR_NAME( CCPDECOR_fInfluenceDirectThreat )
|
|
IF DECOR_EXIST_ON( pedCrowd, strTemp )
|
|
sPedData.fInfluenceDirectThreat = DECOR_GET_FLOAT( pedCrowd, strTemp )
|
|
ENDIF
|
|
|
|
strTemp = GET_CROWD_CONTROL_PED_DECOR_NAME( CCPDECOR_fInfluenceShouting )
|
|
IF DECOR_EXIST_ON( pedCrowd, strTemp )
|
|
sPedData.fInfluenceShouting = DECOR_GET_FLOAT( pedCrowd, strTemp )
|
|
ENDIF
|
|
|
|
strTemp = GET_CROWD_CONTROL_PED_DECOR_NAME( CCPDECOR_iBeatdownHitsRemaining )
|
|
IF DECOR_EXIST_ON( pedCrowd, strTemp )
|
|
sPedData.iBeatdownHitsRemaining = DECOR_GET_INT( pedCrowd, strTemp )
|
|
ENDIF
|
|
|
|
strTemp = GET_CROWD_CONTROL_PED_DECOR_NAME( CCPDECOR_iBeatdownRounds )
|
|
IF DECOR_EXIST_ON( pedCrowd, strTemp )
|
|
sPedData.iBeatdownRounds = DECOR_GET_INT( pedCrowd, strTemp )
|
|
ENDIF
|
|
|
|
RETURN sPedData
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL CAN_WE_UPDATE_CROWD_CONTROL_DATA( PED_INDEX pedCrowd, CROWD_CONTROL_PED_DECORATOR_DATA &sPedNewDecorators, INT iUpdateTimer )
|
|
|
|
CROWD_CONTROL_PED_DECORATOR_DATA sPedData = GET_CROWD_CONTROL_PED_DECORATOR_DATA( pedCrowd )
|
|
|
|
// Critical stuff, should update regardless of time
|
|
IF sPedData.eState != sPedNewDecorators.eState
|
|
OR sPedData.iBeatDownRounds != sPedNewDecorators.iBeatDownRounds
|
|
OR sPedData.iBeatDownHitsRemaining != sPedNewDecorators.iBeatDownHitsRemaining
|
|
OR sPedData.iBitSet != sPedNewDecorators.iBitSet
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
// Non critical stuff, should only update once enough time has passed
|
|
IF iUpdateTimer > 20 // minimum of 20 frames
|
|
IF sPedData.fInfluenceDirectThreat != sPedNewDecorators.fInfluenceDirectThreat
|
|
OR sPedData.fInfluenceShouting != sPedNewDecorators.fInfluenceShouting
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL IS_CROWD_CONTROL_PED_RESTRICTED( CROWD_CONTROL_PED_ENUM eAssignedCrowdID, CROWD_CONTROL_HEIST_TYPE eHeistType, CROWD_CONTROL_PED_STATE eState, BOOL bIsCrowdRestricted )
|
|
|
|
SWITCH eHeistType
|
|
|
|
// Always restrict both cashiers
|
|
CASE CCHEIST_NORMAL
|
|
|
|
IF eAssignedCrowdID = CCPED_CASHIER_A
|
|
OR eAssignedCrowdID = CCPED_CASHIER_B
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE CCHEIST_CUSTOM_FLEECA
|
|
|
|
SWITCH eState
|
|
|
|
// Neither cashiers can attmped an hero action at any time
|
|
CASE CCPS_HERO_ATTEMPT
|
|
|
|
IF bIsCrowdRestricted
|
|
IF eAssignedCrowdID = CCPED_CASHIER_A
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
BREAK
|
|
|
|
// Restrict the cashiers while waiting for the thermite to blow the door open objective
|
|
CASE CCHEIST_CUSTOM_ORNATE
|
|
|
|
SWITCH eState
|
|
|
|
CASE CCPS_HERO_ATTEMPT
|
|
|
|
// Cashier A cannot attempt a hero action until the crowd is unrestricted
|
|
IF eAssignedCrowdID = CCPED_CASHIER_A
|
|
|
|
IF bIsCrowdRestricted
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL IS_CROWD_CONTROL_PED_A_VALID_HERO( CROWD_CONTROL_PED_DECORATOR_DATA &sPedData, CROWD_CONTROL_PED_ENUM ePed, CROWD_CONTROL_HEIST_TYPE eHeistType, BOOL bIsPedRestricted )
|
|
|
|
// Ped doesn't have custom animation even though running anims
|
|
IF IS_BIT_SET_ENUM( sPedData.iBitSet, CCPEDDATA_RunningBespokeAnims )
|
|
AND NOT DOES_CROWD_CONTROL_PED_HAVE_ANIM( CCPANIM_HERO_START, ePed, eHeistType )
|
|
|
|
RETURN FALSE
|
|
|
|
// Ped is not allowed to do a hero attempt at this stage
|
|
ELIF IS_CROWD_CONTROL_PED_RESTRICTED( ePed, eHeistType, CCPS_HERO_ATTEMPT, bIsPedRestricted )
|
|
|
|
RETURN FALSE
|
|
|
|
// Already attempted
|
|
ELIF IS_BIT_SET_ENUM( sPedData.iBitSet, CCPEDDATA_HeroAttempted )
|
|
|
|
RETURN FALSE
|
|
|
|
// Hero prop has been broken, can't perform hero task any more.
|
|
ELIF IS_BIT_SET_ENUM( sPedData.iBitSet, CCPEDDATA_HeroBroken )
|
|
|
|
RETURN FALSE
|
|
|
|
|
|
ELIF IS_BIT_SET_ENUM( sPedData.iBitSet, CCPEDDATA_HeroComplete )
|
|
|
|
RETURN FALSE
|
|
|
|
ENDIF
|
|
|
|
RETURN TRUE
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL IS_CROWD_CONTROL_PED_HERO_ALWAYS_ACTIVE( CROWD_CONTROL_PED_ENUM ePed, CROWD_CONTROL_HEIST_TYPE eHeistType )
|
|
|
|
SWITCH eHeistType
|
|
|
|
CASE CCHEIST_CUSTOM_ORNATE
|
|
|
|
SWITCH ePed
|
|
CASE CCPED_CASHIER_A RETURN TRUE BREAK
|
|
ENDSWITCH
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL SHOULD_CROWD_CONTROL_PED_DIRECT_THREAT_INFLUENCE_DECREASE( CROWD_CONTROL_THREAT_TYPE eThreat )
|
|
|
|
IF eThreat = CCTHREAT_SHOOTING_CLOSE
|
|
OR eThreat = CCTHREAT_AIMED_AT
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
PROC UPDATE_CROWD_CONTROL_PED_DIRECT_THREAT_INFLUENCE(
|
|
CROWD_CONTROL_PED_DECORATOR_DATA &sPedData,
|
|
CROWD_CONTROL_LOCAL_PED_DATA &sLocalPedData,
|
|
CROWD_CONTROL_THREAT_TYPE eThreat,
|
|
FLOAT fInfluenceDeficitPerPed )
|
|
|
|
INT iChangeSign = 0
|
|
FLOAT fChangeRate = 0.0
|
|
|
|
// Decrease because there is an over powered threat
|
|
IF SHOULD_CROWD_CONTROL_PED_DIRECT_THREAT_INFLUENCE_DECREASE( eThreat )
|
|
|
|
iChangeSign = -1
|
|
|
|
SWITCH eThreat
|
|
|
|
CASE CCTHREAT_SHOOTING_CLOSE fChangeRate = 0.2 BREAK
|
|
CASE CCTHREAT_AIMED_AT fChangeRate = 0.15 BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
// Hold while a threat wears off unless theres a deficit
|
|
ELIF fInfluenceDeficitPerPed <= 0.0
|
|
AND ( IS_TIME_LESS_THAN( GET_NETWORK_TIME(), GET_TIME_OFFSET( sLocalPedData.timeLastShotAt, 8000 ) )
|
|
OR IS_TIME_LESS_THAN( GET_NETWORK_TIME(), GET_TIME_OFFSET( sLocalPedData.timeStartThreaten, 5000 ) ) )
|
|
|
|
iChangeSign = 0
|
|
fChangeRate = 0
|
|
|
|
// Increase now all threats have worn off
|
|
ELSE
|
|
|
|
iChangeSign = 1
|
|
fChangeRate = 0.1 + fInfluenceDeficitPerPed
|
|
|
|
ENDIF
|
|
|
|
sPedData.fInfluenceDirectThreat = CLAMP( sPedData.fInfluenceDirectThreat + ( iChangeSign * fChangeRate * TIMESTEP() ), 0.0, 1.0 )
|
|
|
|
ENDPROC
|
|
|
|
|
|
FUNC BOOL SHOULD_CROWD_CONTROL_PED_SHOUT_THREAT_INFLUENCE_DECREASE( CROWD_CONTROL_THREAT_TYPE eThreat )
|
|
|
|
IF eThreat = CCTHREAT_SHOUTING_CLOSE
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
PROC UPDATE_CROWD_CONTROL_PED_SHOUT_THREAT_INFLUENCE(
|
|
CROWD_CONTROL_PED_DECORATOR_DATA &sPedData,
|
|
CROWD_CONTROL_LOCAL_PED_DATA &sLocalPedData,
|
|
CROWD_CONTROL_THREAT_TYPE eThreat,
|
|
FLOAT fInfluenceDeficitPerPed )
|
|
|
|
INT iChangeSign = 0
|
|
FLOAT fChangeRate = 0.0
|
|
|
|
// Decrease because there is an over powered threat
|
|
IF SHOULD_CROWD_CONTROL_PED_SHOUT_THREAT_INFLUENCE_DECREASE( eThreat )
|
|
|
|
iChangeSign = -1
|
|
|
|
SWITCH eThreat
|
|
|
|
CASE CCTHREAT_SHOUTING_CLOSE fChangeRate = 0.15 BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
// Hold while a threat wears off unless theres a deficit
|
|
ELIF fInfluenceDeficitPerPed <= 0.0
|
|
AND IS_TIME_LESS_THAN( GET_NETWORK_TIME(), GET_TIME_OFFSET( sLocalPedData.timeStartThreaten, 5000 ) )
|
|
|
|
iChangeSign = 0
|
|
fChangeRate = 0
|
|
|
|
// Increase now all threats have worn off
|
|
ELSE
|
|
|
|
iChangeSign = 1
|
|
fChangeRate = 0.1
|
|
fChangeRate += fInfluenceDeficitPerPed
|
|
|
|
ENDIF
|
|
|
|
sPedData.fInfluenceShouting = CLAMP( sPedData.fInfluenceShouting + ( iChangeSign * fChangeRate * TIMESTEP() ), 0.0, 1.0 )
|
|
|
|
ENDPROC
|
|
|
|
|
|
FUNC FLOAT GET_CROWD_CONTROL_PED_FEAR_DELTA( CROWD_CONTROL_SERVER_DATA &sData,
|
|
CROWD_CONTROL_LOCAL_DATA &sLocalData,
|
|
CROWD_CONTROL_PED_DECORATOR_DATA &sPedData,
|
|
PED_INDEX pedPlayer, CROWD_CONTROL_THREAT_TYPE eThreat,
|
|
INT iCrowdNum,
|
|
INT iCrowdSize)
|
|
|
|
// Initialise multipliers
|
|
FLOAT fCrowdSizeMultiplier = FMMC_MAX_CROWD_PEDS / TO_FLOAT( iCrowdSize )
|
|
FLOAT fThreatMultiplier = 1.0
|
|
FLOAT fHeroMultiplier = 1.0
|
|
FLOAT fHeistMultiplier = 1.0
|
|
FLOAT fFearInfluence = 1.0
|
|
INT iChangeSign = 0
|
|
|
|
// Increase
|
|
IF eThreat != CCTHREAT_NONE
|
|
|
|
fFearInfluence = sPedData.fInfluenceDirectThreat * sPedData.fInfluenceShouting
|
|
iChangeSign = 1
|
|
|
|
// Decide whether to apply a threat multipler
|
|
SWITCH eThreat
|
|
|
|
CASE CCTHREAT_PROXIMITY
|
|
fThreatMultiplier = 0.25
|
|
BREAK
|
|
|
|
CASE CCTHREAT_SHOUTING
|
|
fThreatMultiplier = 0.25
|
|
BREAK
|
|
|
|
CASE CCTHREAT_BEATING_NEIGHBOUR
|
|
fThreatMultiplier = 1.5
|
|
BREAK
|
|
|
|
CASE CCTHREAT_KILLED_OTHER
|
|
fThreatMultiplier = 4.0
|
|
BREAK
|
|
|
|
CASE CCTHREAT_BEATING
|
|
fThreatMultiplier = 5.0
|
|
BREAK
|
|
|
|
CASE CCTHREAT_SHOOTING
|
|
fThreatMultiplier = 1.0
|
|
BREAK
|
|
|
|
CASE CCTHREAT_SHOUTING_CLOSE
|
|
fThreatMultiplier = 10.0 // has diminishing effect so start it strong
|
|
BREAK
|
|
|
|
CASE CCTHREAT_AIMED_AT
|
|
fThreatMultiplier = 10.0 // has diminishing effect and only on 1 ped at a time so make it strong
|
|
BREAK
|
|
|
|
CASE CCTHREAT_SHOOTING_CLOSE // has diminishing effect so make it strong
|
|
|
|
WEAPON_TYPE eWeap
|
|
|
|
IF GET_CURRENT_PED_WEAPON( pedPlayer, eWeap )
|
|
|
|
// Weapon damage ( clamped between pistol and sawnoff )
|
|
FLOAT fWeaponDamageAlpha
|
|
fWeaponDamageAlpha = CLAMP( GET_WEAPON_DAMAGE( eWeap, WEAPONCOMPONENT_INVALID ), 26.0, 40.0 )
|
|
fWeaponDamageAlpha -= 26.0 // minus lower boundry
|
|
fWeaponDamageAlpha /= 14.0 // divide range
|
|
|
|
// between 400% and 900% faster depending on weapon damage
|
|
fThreatMultiplier = 5.0 + ( fWeaponDamageAlpha * 5.0 )
|
|
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE CCTHREAT_PROJECTILE_EXPLOSIVE
|
|
fThreatMultiplier = 5.0 // 400% Faster
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
// Decide whether to apply a hero multiplier
|
|
IF IS_BIT_SET( sData.iCurrentActiveHeros, iCrowdNum )
|
|
fHeroMultiplier = 0.5 // 50% slower (halved)
|
|
ENDIF
|
|
|
|
// Decrease
|
|
ELIF eThreat = CCTHREAT_NONE
|
|
|
|
iChangeSign = -1
|
|
|
|
IF sLocalData.eHeistType = CCHEIST_CUSTOM_FLEECA
|
|
// b* 2235971 - removed heist multiplier for Fleeca, was decreasing too fast
|
|
// fHeistMultiplier = 2.0 // 100% faster (double)
|
|
ENDIF
|
|
|
|
IF IS_BIT_SET( sData.iCurrentActiveHeros, iCrowdNum )
|
|
fHeroMultiplier = 0.85 // 15% slower
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
IF iChangeSign = 0
|
|
RETURN 0.0
|
|
ELSE
|
|
RETURN iChangeSign * fFearInfluence * fThreatMultiplier * fHeroMultiplier * fHeistMultiplier * fCrowdSizeMultiplier
|
|
ENDIF
|
|
|
|
ENDFUNC
|
|
|
|
|
|
FUNC FLOAT GET_CROWD_CONTROL_PED_CAPSULE_SIZE( CROWD_CONTROL_PED_ENUM ePed, CROWD_CONTROL_HEIST_TYPE eHeistType )
|
|
SWITCH eHeistType
|
|
|
|
CASE CCHEIST_CUSTOM_FLEECA
|
|
|
|
SWITCH ePed
|
|
|
|
CASE CCPED_CUSTOMER_A RETURN 0.4 BREAK
|
|
CASE CCPED_CUSTOMER_B RETURN 0.3 BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
BREAK
|
|
|
|
CASE CCHEIST_CUSTOM_ORNATE
|
|
|
|
SWITCH ePed
|
|
|
|
CASE CCPED_CUSTOMER_A RETURN 0.4 BREAK
|
|
CASE CCPED_CUSTOMER_B RETURN 0.3 BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
RETURN -1.0
|
|
ENDFUNC
|
|
|
|
|
|
//PURPOSE: Return True if the Player is in front of the Ped
|
|
FUNC BOOL IS_PLAYER_IN_FRONT_OF_PED(VECTOR vPlayerCoord, VECTOR vPedCoord, FLOAT fPedHeading)
|
|
|
|
VECTOR posA // Player position
|
|
VECTOR posB // Ped position
|
|
VECTOR posC
|
|
VECTOR vecBA // vector from Ped to Player
|
|
VECTOR vecPed // unit vector pointing in the direction the Ped is facing
|
|
FLOAT fTemp
|
|
|
|
// get positions
|
|
posA = vPlayerCoord
|
|
posB = vPedCoord
|
|
|
|
// get vec from Player to Ped
|
|
vecBA = posA - posB
|
|
|
|
// get unit vector pointing forwards from Ped
|
|
posC = GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(vPedCoord, fPedHeading, <<0.0, 7.0, 0.0>>)
|
|
vecPed = posC - posB
|
|
|
|
// calculate dot product of vecBA and vecPed
|
|
fTemp = GET_ANGLE_BETWEEN_2D_VECTORS(vecPed.x,vecPed.y,vecBA.x,vecBA.y)
|
|
IF (fTemp < 80.0)
|
|
RETURN(TRUE)
|
|
ENDIF
|
|
|
|
RETURN(FALSE)
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL IS_CROWD_CONTROL_PLAYER_ABLE_TO_THREATEN_FROM_CURRENT_LOCATION( PED_INDEX pedPlayer, CROWD_CONTROL_LOCAL_DATA sLocalData )
|
|
|
|
SWITCH sLocalData.eHeistType
|
|
|
|
CASE CCHEIST_CUSTOM_FLEECA
|
|
|
|
IF GET_INTERIOR_FROM_ENTITY( pedPlayer ) = sLocalData.interiorHeist
|
|
|
|
INT iRoomKey
|
|
iRoomKey = GET_ROOM_KEY_FROM_ENTITY( pedPlayer )
|
|
|
|
IF iRoomKey = HASH("Bankvault")
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
ELSE
|
|
// do not exempt the exterior of the bank as players can shoot through the glass front
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE CCHEIST_CUSTOM_ORNATE
|
|
|
|
IF GET_INTERIOR_FROM_ENTITY( pedPlayer ) = sLocalData.interiorHeist
|
|
|
|
INT iRoomKey
|
|
iRoomKey = GET_ROOM_KEY_FROM_ENTITY( pedPlayer )
|
|
|
|
IF iRoomKey = HASH("Bank_basementRm")
|
|
OR iRoomKey = HASH("_")
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
// Not inside the bank, no possible way to threaten from outside this bank, return false
|
|
ELSE
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
|
|
RETURN TRUE
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL IS_PLAYER_STARTING_CROWD_CONTROL_PED_REACTION( PED_INDEX playerPed, CROWD_CONTROL_LOCAL_DATA &sLocalData )
|
|
|
|
PLAYER_INDEX playerID = NETWORK_GET_PLAYER_INDEX_FROM_PED( playerPed )
|
|
|
|
IF playerID != INVALID_PLAYER_INDEX()
|
|
AND IS_NET_PLAYER_OK( playerID )
|
|
|
|
BOOL bPlayerLooksHostile
|
|
|
|
// ... with a gun
|
|
WEAPON_TYPE CurrentWeapon
|
|
IF GET_CURRENT_PED_WEAPON( playerPed, CurrentWeapon )
|
|
IF CurrentWeapon != WEAPONTYPE_UNARMED
|
|
AND CurrentWeapon != WEAPONTYPE_OBJECT
|
|
AND CurrentWeapon != WEAPONTYPE_FLARE
|
|
bPlayerLooksHostile = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// ... in a mask
|
|
IF IS_PED_WEARING_A_MASK( playerPed )
|
|
bPlayerLooksHostile = TRUE
|
|
ENDIF
|
|
|
|
IF IS_PED_IN_ANY_VEHICLE( playerPed )
|
|
bPlayerLooksHostile = TRUE
|
|
ENDIF
|
|
|
|
// Looks hostile and can be seen
|
|
IF bPlayerLooksHostile
|
|
// 2068869, this check only works on peds you own which fucks things up
|
|
//AND NETWORK_HAS_CONTROL_OF_ENTITY( crowdPed ) AND CAN_PED_SEE_HATED_PED( crowdPed, playerPed )
|
|
|
|
IF HAS_PED_ENTERED_CROWD_CONTROL_TRIGGER_ZONE( playerPed, sLocalData, FALSE )
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
// Player is shouting
|
|
IF NETWORK_IS_PLAYER_TALKING( playerID ) AND NETWORK_GET_PLAYER_LOUDNESS( playerID ) > 0.75
|
|
|
|
IF HAS_PED_ENTERED_CROWD_CONTROL_TRIGGER_ZONE( playerPed, sLocalData, TRUE )
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
FUNC CROWD_CONTROL_THREAT_TYPE IS_PLAYER_THREATENING_CROWD_CONTROL_PED(
|
|
PLAYER_INDEX threateningPlayer, PED_INDEX threateningPed,
|
|
PED_INDEX crowdPed, INT iCrowdNum,
|
|
CROWD_CONTROL_SERVER_DATA &sServerData,
|
|
CROWD_CONTROL_LOCAL_DATA &sLocalData,
|
|
CROWD_CONTROL_PED_DECORATOR_DATA &sPedData[FMMC_MAX_CROWD_PEDS],
|
|
CROWD_CONTROL_LOCAL_PED_DATA &sLocalPedData[FMMC_MAX_CROWD_PEDS],
|
|
PED_INDEX pedBeingBeat )
|
|
|
|
CONST_FLOAT cfCC_ShootingDistClose 2.0
|
|
CONST_FLOAT cfCC_ShootingDist 5.0
|
|
CONST_FLOAT cfCC_ProjectileDist 5.0
|
|
CONST_FLOAT cfCC_AimingDist 8.0
|
|
CONST_FLOAT cfCC_ShoutingDist 6.0
|
|
CONST_FLOAT cfCC_ShoutingDistClose 2.5
|
|
CONST_FLOAT cfCC_ProximityDistNormal 3.5
|
|
CONST_FLOAT cfCC_ProximityDistClose 2.0
|
|
CONST_FLOAT cfCC_BeatingNeighbourDist 5.0
|
|
CONST_FLOAT cfCC_DeadNeighbourDist 3.0
|
|
|
|
INT i
|
|
|
|
BOOL bIsThreateningPedOk
|
|
FLOAT fDistanceFromPed
|
|
|
|
IF (threateningPlayer != INVALID_PLAYER_INDEX())
|
|
AND IS_NET_PLAYER_OK(threateningPlayer)
|
|
fDistanceFromPed = GET_DISTANCE_BETWEEN_ENTITIES( threateningPed, crowdPed, FALSE )
|
|
bIsThreateningPedOk = TRUE
|
|
ENDIF
|
|
|
|
BOOL bIsArmed
|
|
WEAPON_TYPE CurrentWeapon
|
|
IF GET_CURRENT_PED_WEAPON(threateningPed, CurrentWeapon)
|
|
IF CurrentWeapon != WEAPONTYPE_UNARMED
|
|
bIsArmed = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
BOOL bIsPlayerFacingPed = IS_PED_FACING_PED(threateningPed, crowdPed, 60.0)
|
|
BOOL bIsPedFacingPlayer = IS_PED_FACING_PED(crowdPed, threateningPed, 90.0)
|
|
BOOL bIsPlayerShouting = NETWORK_IS_PLAYER_TALKING(threateningPlayer) AND NETWORK_GET_PLAYER_LOUDNESS(threateningPlayer) > cfCC_ShoutVolumeLevel
|
|
|
|
VECTOR vPedCoord = GET_ENTITY_COORDS(crowdPed)
|
|
|
|
REPEAT COUNT_OF(CROWD_CONTROL_THREAT_TYPE) i
|
|
|
|
CROWD_CONTROL_THREAT_TYPE eThreatToTest = INT_TO_ENUM( CROWD_CONTROL_THREAT_TYPE, ( COUNT_OF(CROWD_CONTROL_THREAT_TYPE) - 1) - i )
|
|
|
|
SWITCH eThreatToTest
|
|
|
|
CASE CCTHREAT_SHOOTING_CLOSE
|
|
|
|
// Shooting Close
|
|
// Bullet impacted near the ped
|
|
// OR the player is within range of the ped and is shooting
|
|
IF bIsThreateningPedOk
|
|
IF IS_BULLET_IN_AREA(vPedCoord, cfCC_ShootingDistClose) // Bullet flew past them
|
|
OR HAS_BULLET_IMPACTED_IN_AREA(vPedCoord, cfCC_ShootingDistClose) // Bullet hit near them
|
|
OR ( fDistanceFromPed < cfCC_ShootingDistClose AND IS_PED_SHOOTING(threateningPed) ) // Shooting anywhere near them
|
|
|
|
RETURN CCTHREAT_SHOOTING_CLOSE
|
|
|
|
ENDIF
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE CCTHREAT_PROJECTILE_EXPLOSIVE_STICKY_BOMB
|
|
|
|
// Sticky Bomb
|
|
// Ped not set to ignore sticky bombs
|
|
// Sticky bomb in area near ped
|
|
IF NOT IS_BIT_SET_ENUM( sPedData[iCrowdNum].iBitSet, CCPEDDATA_IgnoreStickyBombs )
|
|
AND IS_PROJECTILE_TYPE_WITHIN_DISTANCE( vPedCoord, WEAPONTYPE_STICKYBOMB, cfCC_ProjectileDist )
|
|
|
|
RETURN CCTHREAT_PROJECTILE_EXPLOSIVE_STICKY_BOMB
|
|
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE CCTHREAT_PROJECTILE_EXPLOSIVE
|
|
|
|
// Projectile
|
|
// Is an explosive projectile within range of the ped
|
|
IF IS_PROJECTILE_TYPE_WITHIN_DISTANCE( vPedCoord, WEAPONTYPE_GRENADE, cfCC_ProjectileDist )
|
|
OR IS_PROJECTILE_TYPE_WITHIN_DISTANCE( vPedCoord, WEAPONTYPE_GRENADELAUNCHER, cfCC_ProjectileDist )
|
|
OR IS_PROJECTILE_TYPE_WITHIN_DISTANCE( vPedCoord, WEAPONTYPE_RPG, cfCC_ProjectileDist )
|
|
OR IS_PROJECTILE_TYPE_WITHIN_DISTANCE( vPedCoord, WEAPONTYPE_BZGAS, cfCC_ProjectileDist )
|
|
OR IS_PROJECTILE_TYPE_WITHIN_DISTANCE( vPedCoord, WEAPONTYPE_SMOKEGRENADE, cfCC_ProjectileDist )
|
|
OR IS_PROJECTILE_TYPE_WITHIN_DISTANCE( vPedCoord, WEAPONTYPE_MOLOTOV, cfCC_ProjectileDist )
|
|
OR IS_PROJECTILE_TYPE_WITHIN_DISTANCE( vPedCoord, WEAPONTYPE_FLARE, cfCC_ProjectileDist )
|
|
|
|
RETURN CCTHREAT_PROJECTILE_EXPLOSIVE
|
|
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE CCTHREAT_SHOOTING
|
|
|
|
// Shooting
|
|
// Bullet is near the ped
|
|
// OR Bullet impacted near the ped
|
|
// OR the player is within range of the ped and is shooting
|
|
IF bIsThreateningPedOk
|
|
AND bIsArmed
|
|
IF IS_BULLET_IN_AREA(vPedCoord, cfCC_ShootingDist) // Bullet flew past them
|
|
OR HAS_BULLET_IMPACTED_IN_AREA(vPedCoord, cfCC_ShootingDist) // Bullet hit near them
|
|
OR ( fDistanceFromPed < cfCC_ShootingDist AND IS_PED_SHOOTING(threateningPed) ) // Shooting anywhere near them
|
|
|
|
RETURN CCTHREAT_SHOOTING
|
|
|
|
ENDIF
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE CCTHREAT_BEATING
|
|
|
|
// Local data says the player is beating this ped
|
|
IF bIsThreateningPedOk
|
|
AND bIsArmed
|
|
IF sLocalData.iPlayerBeatingThisPed != -1
|
|
AND sLocalData.iPlayerBeatingThisPed = iCrowdNum
|
|
|
|
RETURN CCTHREAT_BEATING
|
|
|
|
ENDIF
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE CCTHREAT_AIMED_AT
|
|
|
|
// Aiming at ped
|
|
// Is facing the player
|
|
// Player not using the cellphone
|
|
// Player is within aim range OR is shouting to prompt the ped
|
|
IF bIsThreateningPedOk
|
|
AND bIsArmed
|
|
IF ( IS_PLAYER_FREE_AIMING_AT_ENTITY(threateningPlayer, crowdPed) OR IS_PLAYER_TARGETTING_ENTITY(threateningPlayer, crowdPed ) )
|
|
AND bIsPedFacingPlayer
|
|
AND NOT IS_CELLPHONE_CAMERA_IN_USE()
|
|
AND ( fDistanceFromPed < cfCC_AimingDist OR bIsPlayerShouting )
|
|
|
|
RETURN CCTHREAT_AIMED_AT
|
|
|
|
ENDIF
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE CCTHREAT_KILLED_OTHER
|
|
|
|
// Killed someone
|
|
// Player has killed someone near by
|
|
IF bIsThreateningPedOk
|
|
|
|
INT j
|
|
FOR j = 0 TO sServerData.iNumCrowdControlPeds-1
|
|
// exclude this ped from being checked
|
|
IF j != iCrowdNum
|
|
//IF IS_BIT_SET_ENUM( sPedData[j].iBitSet, CCPEDDATA_Dead )
|
|
//OR IS_BIT_SET_ENUM( sPedData[j].iBitSet, CCPEDDATA_KnockedOut )
|
|
IF IS_BIT_SET_ENUM( sPedData[j].iBitSet, CCPEDDATA_Dead )
|
|
IF IS_TIME_LESS_THAN( GET_NETWORK_TIME(), GET_TIME_OFFSET( sLocalPedData[j].timeDied, 3000 ) )
|
|
RETURN CCTHREAT_KILLED_OTHER
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDFOR
|
|
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE CCTHREAT_BEATING_NEIGHBOUR
|
|
|
|
// Beating someone
|
|
// Player is beating someone near by
|
|
IF bIsThreateningPedOk
|
|
AND bIsArmed
|
|
IF sLocalData.iPlayerBeatingThisPed != -1
|
|
AND GET_DISTANCE_BETWEEN_ENTITIES( pedBeingBeat, crowdPed ) < cfCC_BeatingNeighbourDist
|
|
|
|
RETURN CCTHREAT_BEATING_NEIGHBOUR
|
|
|
|
ENDIF
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE CCTHREAT_SHOUTING_CLOSE
|
|
|
|
// Shouting close
|
|
// Within shout close range
|
|
IF bIsThreateningPedOk
|
|
IF bIsPlayerShouting AND fDistanceFromPed < cfCC_ShoutingDistClose
|
|
|
|
RETURN CCTHREAT_SHOUTING_CLOSE
|
|
|
|
ENDIF
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE CCTHREAT_SHOUTING
|
|
|
|
// Shouting
|
|
// Within shout range
|
|
IF bIsThreateningPedOk
|
|
IF bIsPlayerShouting AND fDistanceFromPed < cfCC_ShoutingDist
|
|
|
|
RETURN CCTHREAT_SHOUTING
|
|
|
|
ENDIF
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE CCTHREAT_PROXIMITY
|
|
|
|
// Proximity
|
|
// Player is within normal range both the ped and the player are facing
|
|
// OR player is within close range
|
|
IF bIsThreateningPedOk
|
|
IF ( fDistanceFromPed < cfCC_ProximityDistNormal AND bIsPlayerFacingPed AND bIsPedFacingPlayer )
|
|
OR fDistanceFromPed < cfCC_ProximityDistClose
|
|
|
|
RETURN CCTHREAT_PROXIMITY
|
|
|
|
ENDIF
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
ENDREPEAT
|
|
|
|
RETURN CCTHREAT_NONE
|
|
|
|
ENDFUNC
|
|
|
|
|
|
FUNC INT CREATE_CROWD_CONTROL_PED_SEQUENCES( CROWD_CONTROL_LOCAL_DATA &sLocalData, CROWD_CONTROL_LOCAL_PED_DATA &sLocalPedData )
|
|
|
|
INT iSeqCount
|
|
|
|
// Hero fail -> Cower
|
|
IF sLocalPedData.seqs[CCSEQ_HERO_FAIL] = NULL
|
|
AND DOES_CROWD_CONTROL_PED_HAVE_ANIM( CCPANIM_HERO_FAIL, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
AND DOES_CROWD_CONTROL_PED_HAVE_ANIM( CCPANIM_COWER_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
OPEN_SEQUENCE_TASK( sLocalPedData.seqs[CCSEQ_HERO_FAIL] )
|
|
PLAY_CROWD_CONTROL_ANIM( NULL, CCPANIM_HERO_FAIL, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType,
|
|
REALLY_SLOW_BLEND_IN, -0.1, -1, eCrowdControlAnimFlags )
|
|
PLAY_CROWD_CONTROL_ANIM( NULL, CCPANIM_COWER_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType,
|
|
SLOW_BLEND_IN, -0.1, -1, AF_LOOPING | eCrowdControlAnimFlags )
|
|
CLOSE_SEQUENCE_TASK( sLocalPedData.seqs[CCSEQ_HERO_FAIL] )
|
|
iSeqCount++
|
|
ENDIF
|
|
|
|
// Flinch -> Cower
|
|
IF sLocalPedData.seqs[CCSEQ_FLINCH_TO_COWER] = NULL
|
|
AND DOES_CROWD_CONTROL_PED_HAVE_ANIM( CCPANIM_FLINCH_TO_IDLE_OUTRO, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
AND DOES_CROWD_CONTROL_PED_HAVE_ANIM( CCPANIM_COWER_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
OPEN_SEQUENCE_TASK( sLocalPedData.seqs[CCSEQ_FLINCH_TO_COWER] )
|
|
PLAY_CROWD_CONTROL_ANIM( NULL, CCPANIM_FLINCH_TO_IDLE_OUTRO, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType,
|
|
REALLY_SLOW_BLEND_IN, -0.1, -1, eCrowdControlAnimFlags )
|
|
PLAY_CROWD_CONTROL_ANIM( NULL, CCPANIM_COWER_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType,
|
|
SLOW_BLEND_IN, -0.1, -1, AF_LOOPING | eCrowdControlAnimFlags )
|
|
CLOSE_SEQUENCE_TASK( sLocalPedData.seqs[CCSEQ_FLINCH_TO_COWER] )
|
|
iSeqCount++
|
|
ENDIF
|
|
|
|
// Cower -> Flinch
|
|
IF sLocalPedData.seqs[CCSEQ_COWER_TO_FLINCH] = NULL
|
|
AND DOES_CROWD_CONTROL_PED_HAVE_ANIM( CCPANIM_COWER_TO_FLINCH_INTRO, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
AND DOES_CROWD_CONTROL_PED_HAVE_ANIM( CCPANIM_FLINCH_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
OPEN_SEQUENCE_TASK( sLocalPedData.seqs[CCSEQ_COWER_TO_FLINCH] )
|
|
PLAY_CROWD_CONTROL_ANIM( NULL, CCPANIM_COWER_TO_FLINCH_INTRO, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType,
|
|
SLOW_BLEND_IN, -0.1, -1, eCrowdControlAnimFlags )
|
|
PLAY_CROWD_CONTROL_ANIM( NULL, CCPANIM_FLINCH_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType,
|
|
SLOW_BLEND_IN, -0.1, -1, AF_LOOPING | eCrowdControlAnimFlags )
|
|
CLOSE_SEQUENCE_TASK( sLocalPedData.seqs[CCSEQ_COWER_TO_FLINCH] )
|
|
|
|
iSeqCount++
|
|
ENDIF
|
|
|
|
// Cower -> Flinch underfire
|
|
IF sLocalPedData.seqs[CCSEQ_COWER_TO_FLINCH_UNDERFIRE] = NULL
|
|
AND DOES_CROWD_CONTROL_PED_HAVE_ANIM( CCPANIM_COWER_TO_FLINCH_INTRO, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
AND DOES_CROWD_CONTROL_PED_HAVE_ANIM( CCPANIM_FLINCH_UNDERFIRE_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
OPEN_SEQUENCE_TASK( sLocalPedData.seqs[CCSEQ_COWER_TO_FLINCH_UNDERFIRE] )
|
|
PLAY_CROWD_CONTROL_ANIM( NULL, CCPANIM_COWER_TO_FLINCH_UNDERFIRE_INTRO, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType,
|
|
SLOW_BLEND_IN, -0.1, -1, eCrowdControlAnimFlags )
|
|
PLAY_CROWD_CONTROL_ANIM( NULL, CCPANIM_FLINCH_UNDERFIRE_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType,
|
|
SLOW_BLEND_IN, -0.1, -1, AF_LOOPING | eCrowdControlAnimFlags )
|
|
CLOSE_SEQUENCE_TASK( sLocalPedData.seqs[CCSEQ_COWER_TO_FLINCH_UNDERFIRE] )
|
|
iSeqCount++
|
|
ENDIF
|
|
|
|
FLOAT fLoopBlendIn
|
|
|
|
// Flinch -> Flinch underfire
|
|
IF sLocalPedData.seqs[CCSEQ_FLINCH_TO_FLINCH_UNDERFIRE] = NULL
|
|
AND DOES_CROWD_CONTROL_PED_HAVE_ANIM( CCPANIM_FLINCH_UNDERFIRE_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
OPEN_SEQUENCE_TASK( sLocalPedData.seqs[CCSEQ_FLINCH_TO_FLINCH_UNDERFIRE] )
|
|
IF DOES_CROWD_CONTROL_PED_HAVE_ANIM( CCPANIM_FLINCH_TO_FLINCH_UNDERFIRE_INTRO, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
PLAY_CROWD_CONTROL_ANIM( NULL, CCPANIM_FLINCH_TO_FLINCH_UNDERFIRE_INTRO, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType,
|
|
SLOW_BLEND_IN, -0.1, -1, eCrowdControlAnimFlags )
|
|
ENDIF
|
|
PLAY_CROWD_CONTROL_ANIM( NULL, CCPANIM_FLINCH_UNDERFIRE_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType,
|
|
SLOW_BLEND_IN, -0.1, -1, AF_LOOPING | eCrowdControlAnimFlags )
|
|
CLOSE_SEQUENCE_TASK( sLocalPedData.seqs[CCSEQ_FLINCH_TO_FLINCH_UNDERFIRE] )
|
|
iSeqCount++
|
|
ENDIF
|
|
|
|
// Flinch underfire -> Flinch
|
|
IF sLocalPedData.seqs[CCSEQ_FLINCH_UNDERFIRE_TO_FLINCH] = NULL
|
|
AND DOES_CROWD_CONTROL_PED_HAVE_ANIM( CCPANIM_FLINCH_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
OPEN_SEQUENCE_TASK( sLocalPedData.seqs[CCSEQ_FLINCH_UNDERFIRE_TO_FLINCH] )
|
|
fLoopBlendIn = REALLY_SLOW_BLEND_IN
|
|
IF DOES_CROWD_CONTROL_PED_HAVE_ANIM( CCPANIM_FLINCH_UNDERFIRE_TO_FLINCH_OUTRO, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
PLAY_CROWD_CONTROL_ANIM( NULL, CCPANIM_FLINCH_UNDERFIRE_TO_FLINCH_OUTRO, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType,
|
|
SLOW_BLEND_IN, -0.1, -1, eCrowdControlAnimFlags )
|
|
fLoopBlendIn = SLOW_BLEND_IN
|
|
ENDIF
|
|
PLAY_CROWD_CONTROL_ANIM( NULL, CCPANIM_FLINCH_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType,
|
|
fLoopBlendIn, -0.1, -1, AF_LOOPING | eCrowdControlAnimFlags )
|
|
CLOSE_SEQUENCE_TASK( sLocalPedData.seqs[CCSEQ_FLINCH_UNDERFIRE_TO_FLINCH] )
|
|
iSeqCount++
|
|
ENDIF
|
|
|
|
// Beatdown -> Flinch
|
|
IF sLocalPedData.seqs[CCSEQ_BEATDOWN_TO_FLINCH] = NULL
|
|
AND DOES_CROWD_CONTROL_PED_HAVE_ANIM( CCPANIM_BEATDOWN_OUTRO, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
AND DOES_CROWD_CONTROL_PED_HAVE_ANIM( CCPANIM_FLINCH_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
OPEN_SEQUENCE_TASK( sLocalPedData.seqs[CCSEQ_BEATDOWN_TO_FLINCH] )
|
|
PLAY_CROWD_CONTROL_ANIM( NULL, CCPANIM_BEATDOWN_OUTRO, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType,
|
|
REALLY_SLOW_BLEND_IN, -0.1, -1, eCrowdControlAnimFlags )
|
|
PLAY_CROWD_CONTROL_ANIM( NULL, CCPANIM_FLINCH_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType,
|
|
SLOW_BLEND_IN, -0.1, -1, AF_LOOPING | eCrowdControlAnimFlags )
|
|
CLOSE_SEQUENCE_TASK( sLocalPedData.seqs[CCSEQ_BEATDOWN_TO_FLINCH] )
|
|
iSeqCount++
|
|
ENDIF
|
|
|
|
// Cower -> Hero start -> Hero loop
|
|
IF sLocalPedData.seqs[CCSEQ_HERO_START] = NULL
|
|
AND DOES_CROWD_CONTROL_PED_HAVE_ANIM( CCPANIM_COWER_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
AND DOES_CROWD_CONTROL_PED_HAVE_ANIM( CCPANIM_HERO_START, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
OPEN_SEQUENCE_TASK( sLocalPedData.seqs[CCSEQ_HERO_START] )
|
|
PLAY_CROWD_CONTROL_ANIM( NULL, CCPANIM_HERO_START, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType,
|
|
REALLY_SLOW_BLEND_IN, 0.1, -1, eCrowdControlAnimFlags )
|
|
PLAY_CROWD_CONTROL_ANIM( NULL, CCPANIM_HERO_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType,
|
|
SLOW_BLEND_IN, -0.1, -1, AF_LOOPING | eCrowdControlAnimFlags )
|
|
CLOSE_SEQUENCE_TASK( sLocalPedData.seqs[CCSEQ_HERO_START] )
|
|
iSeqCount++
|
|
ENDIF
|
|
|
|
// Hero loop -> Hero pass -> Cower
|
|
IF sLocalPedData.seqs[CCSEQ_HERO_PASS] = NULL
|
|
AND DOES_CROWD_CONTROL_PED_HAVE_ANIM( CCPANIM_HERO_PASS, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
AND DOES_CROWD_CONTROL_PED_HAVE_ANIM( CCPANIM_COWER_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
OPEN_SEQUENCE_TASK( sLocalPedData.seqs[CCSEQ_HERO_PASS] )
|
|
PLAY_CROWD_CONTROL_ANIM( NULL, CCPANIM_HERO_PASS, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType,
|
|
REALLY_SLOW_BLEND_IN, -0.1, -1, eCrowdControlAnimFlags )
|
|
PLAY_CROWD_CONTROL_ANIM( NULL, CCPANIM_COWER_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType,
|
|
SLOW_BLEND_IN, -0.1, -1, AF_LOOPING | eCrowdControlAnimFlags )
|
|
CLOSE_SEQUENCE_TASK( sLocalPedData.seqs[CCSEQ_HERO_PASS] )
|
|
iSeqCount++
|
|
ENDIF
|
|
|
|
RETURN iSeqCount
|
|
ENDFUNC
|
|
|
|
|
|
PROC PLAY_CROWD_CONTROL_SEQUENCE( PED_INDEX ped, CROWD_CONTROL_SEQUENCES eSeq, INT iCrowdNum, CROWD_CONTROL_LOCAL_PED_DATA &sLocalPedData )
|
|
|
|
TASK_PERFORM_SEQUENCE( ped, sLocalPedData.seqs[eSeq] )
|
|
|
|
#IF NOT IS_DEBUG_BUILD
|
|
UNUSED_PARAMETER( iCrowdNum )
|
|
#ENDIF
|
|
#IF IS_DEBUG_BUILD
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PLAY_CROWD_CONTROL_SEQUENCE() - ", GET_CROWD_CONTROL_PED_NAME_FROM_ANIM_ID( sLocalPedData.eCreatorAssignedPedID ),
|
|
"[", iCrowdNum,
|
|
"] - Seq = ", GET_CROWD_CONTROL_SEQUENCE_NAME( eSeq ) )
|
|
#ENDIF
|
|
|
|
ENDPROC
|
|
|
|
|
|
PROC CACHE_CROWD_CONTROL_LOCAL_DATA( CROWD_CONTROL_LOCAL_DATA &sLocalData )
|
|
|
|
// Cache which rule is the crowd control rule for each team
|
|
INT iTeam
|
|
INT iPed
|
|
FOR iTeam = 0 TO FMMC_MAX_TEAMS-1
|
|
|
|
sLocalData.iCCRule[iTeam] = -1
|
|
|
|
FOR iPed = 0 TO FMMC_MAX_PEDS-1
|
|
|
|
IF g_FMMC_STRUCT_ENTITIES.sPlacedPed[iPed].iRule[iTeam] = FMMC_OBJECTIVE_LOGIC_CROWD_CONTROL
|
|
AND g_FMMC_STRUCT_ENTITIES.sPlacedPed[iPed].iPriority[iTeam] < FMMC_MAX_RULES
|
|
sLocalData.iCCRule[iTeam] = g_FMMC_STRUCT_ENTITIES.sPlacedPed[iPed].iPriority[iTeam]
|
|
ENDIF
|
|
|
|
ENDFOR
|
|
|
|
ENDFOR
|
|
|
|
FOR iTeam = 0 TO FMMC_MAX_TEAMS-1
|
|
FOR iPed = 0 TO FMMC_MAX_PEDS-1
|
|
IF INT_TO_ENUM( CROWD_CONTROL_PED_ENUM, g_FMMC_STRUCT_ENTITIES.sPlacedPed[iPed].iCrowdControlID ) = CCPED_CASHIER_A
|
|
OR INT_TO_ENUM( CROWD_CONTROL_PED_ENUM, g_FMMC_STRUCT_ENTITIES.sPlacedPed[iPed].iCrowdControlID ) = CCPED_CASHIER_B
|
|
sLocalData.iCashierPed = iPed
|
|
ENDIF
|
|
ENDFOR
|
|
ENDFOR
|
|
|
|
// Determine which heist we are on
|
|
FOR iTeam = 0 TO FMMC_MAX_TEAMS-1
|
|
|
|
IF sLocalData.iCCRule[iTeam] > -1
|
|
AND sLocalData.iCCRule[iTeam] < FMMC_MAX_RULES
|
|
|
|
IF IS_BIT_SET(g_FMMC_STRUCT.sFMMCEndConditions[iTeam].iRuleBitset[sLocalData.iCCRule[iTeam]],ciBS_RULE_CUSTOM_CROWD_CONTROL_FLEECA)
|
|
|
|
sLocalData.eHeistType = CCHEIST_CUSTOM_FLEECA
|
|
|
|
ELIF IS_BIT_SET(g_FMMC_STRUCT.sFMMCEndConditions[iTeam].iRuleBitset[sLocalData.iCCRule[iTeam]],ciBS_RULE_CUSTOM_CROWD_CONTROL_ORNATE)
|
|
|
|
sLocalData.eHeistType = CCHEIST_CUSTOM_ORNATE
|
|
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDFOR
|
|
|
|
|
|
// Cache which rule is the thermite rule and which team has it
|
|
IF sLocalData.iThermiteTeam = -1
|
|
OR sLocalData.iThermiteRule = -1
|
|
|
|
INT iObj
|
|
FOR iTeam = 0 TO FMMC_MAX_TEAMS-1
|
|
FOR iObj = 0 TO FMMC_MAX_NUM_OBJECTS-1
|
|
|
|
IF g_FMMC_STRUCT_ENTITIES.sPlacedObject[iObj].iRule[iTeam] = FMMC_OBJECTIVE_LOGIC_MINIGAME
|
|
AND g_FMMC_STRUCT_ENTITIES.sPlacedObject[iObj].iPriority[iTeam] < FMMC_MAX_RULES
|
|
AND IS_BIT_SET( g_FMMC_STRUCT_ENTITIES.sPlacedObject[iObj].iLegacyMiniGameBitSet, cibsLEGACY_FMMC_MINI_GAME_USE_THERMAL_CHARGE )
|
|
|
|
sLocalData.iThermiteTeam = iTeam
|
|
sLocalData.iThermiteRule = g_FMMC_STRUCT_ENTITIES.sPlacedObject[iObj].iPriority[iTeam]
|
|
|
|
// Break loop
|
|
iTeam = FMMC_MAX_TEAMS
|
|
iObj = FMMC_MAX_NUM_OBJECTS
|
|
ENDIF
|
|
|
|
ENDFOR
|
|
ENDFOR
|
|
|
|
ENDIF
|
|
|
|
// 2221150 - Cache the interior, too many calls per frame on per ped checks to fetching the interior (EXPENSIVE)
|
|
IF sLocalData.interiorHeist = NULL
|
|
sLocalData.interiorHeist = GET_CROWD_CONTROL_HEIST_INTERIOR( sLocalData.eHeistType )
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
|
|
PROC CACHE_CROWD_CONTROL_LOCAL_PED_DATA( CROWD_CONTROL_LOCAL_PED_DATA &sPedData, INT iPlacedPedID )
|
|
|
|
sPedData.eCreatorAssignedPedID = INT_TO_ENUM( CROWD_CONTROL_PED_ENUM, g_FMMC_STRUCT_ENTITIES.sPlacedPed[iPlacedPedID].iCrowdControlID )
|
|
|
|
ENDPROC
|
|
|
|
|
|
PROC SET_CROWD_CONTROL_PED_STATE( CROWD_CONTROL_PED_DECORATOR_DATA &sPedData, CROWD_CONTROL_PED_STATE eNewState, INT iCrowdID, CROWD_CONTROL_PED_ENUM eCreatorAssignedPedID)
|
|
DEBUG_PRINTCALLSTACK()
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "SET_CROWD_CONTROL_PED_STATE() - [", iCrowdID, "] ", GET_CROWD_CONTROL_PED_NAME_FROM_ANIM_ID( eCreatorAssignedPedID ), " - State: ", GET_CROWD_CONTROL_PED_STATE_STRING( sPedData.eState ), " -> ", GET_CROWD_CONTROL_PED_STATE_STRING( eNewState ) )
|
|
sPedData.eStatePrev = sPedData.eState
|
|
sPedData.eState = eNewState
|
|
ENDPROC
|
|
|
|
|
|
FUNC BOOL SETUP_CROWD_CONTROL_PED_DATA( PED_INDEX ped, CROWD_CONTROL_PED_DECORATOR_DATA &sPedData, CROWD_CONTROL_LOCAL_PED_DATA &sLocalPedData, CROWD_CONTROL_HEIST_TYPE eHeistType )
|
|
|
|
BOOL bReady = TRUE
|
|
|
|
// Hero struff
|
|
CROWD_CONTROL_PED_HERO_ACTION eHeroAction
|
|
IF eHeistType != CCHEIST_NORMAL
|
|
eHeroAction = GET_CROWD_CONTROL_PED_HERO_ACTION_FOR_ANIMATED_PED( sLocalPedData.eCreatorAssignedPedID, eHeistType )
|
|
ELSE
|
|
eHeroAction = INT_TO_ENUM( CROWD_CONTROL_PED_HERO_ACTION, sLocalPedData.eCreatorAssignedPedID )
|
|
IF eHeroAction = CCHERO_ALARM
|
|
eHeroAction = CCHERO_NONE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Give gun hero a their gun
|
|
IF eHeroAction = CCHERO_GUN
|
|
|
|
GIVE_WEAPON_TO_PED( ped, WEAPONTYPE_PISTOL, INFINITE_AMMO, FALSE, FALSE )
|
|
|
|
ENDIF
|
|
|
|
IF bReady
|
|
|
|
// Initialise struct
|
|
SET_CROWD_CONTROL_PED_STATE( sPedData, CCPS_INTRO, -1, sLocalPedData.eCreatorAssignedPedID )
|
|
|
|
sPedData.iBeatdownHitsRemaining = ciCC_MaxBeatdownHits
|
|
sPedData.fInfluenceDirectThreat = 1.0
|
|
sPedData.fInfluenceShouting = 1.0
|
|
|
|
IF eHeistType != CCHEIST_NORMAL
|
|
|
|
SET_BIT_ENUM( sPedData.iBitSet, CCPEDDATA_RunningBespokeAnims )
|
|
|
|
// Has alt anims, set ped to initially use them
|
|
// IF DOES_CROWD_CONTROL_PED_HAVE_ANIM( CCPANIM_COWER_LOOP_ALT, sLocalPedData.eCreatorAssignedPedID, eHeistType )
|
|
// SET_BIT( sPedData.iBitSet, CCPEDDATA_UseAlternativeAnims )
|
|
// ENDIF
|
|
|
|
ENDIF
|
|
|
|
// Initialise ped
|
|
SET_PED_COMBAT_ATTRIBUTES(ped, CA_ALWAYS_FLEE, FALSE)
|
|
SET_PED_FLEE_ATTRIBUTES(ped, FA_DISABLE_COWER,TRUE)
|
|
SET_PED_FLEE_ATTRIBUTES(ped, FA_DISABLE_FLEE_FROM_INDIRECT_THREATS,TRUE)
|
|
SET_PED_FLEE_ATTRIBUTES(ped, FA_COWER_INSTEAD_OF_FLEE,TRUE)
|
|
SET_RAGDOLL_BLOCKING_FLAGS(ped, RBF_PLAYER_BUMP | RBF_PLAYER_IMPACT | RBF_PLAYER_RAGDOLL_BUMP )
|
|
SET_PED_CAN_BE_TARGETTED(ped, FALSE) // 2048337
|
|
SET_PED_CONFIG_FLAG(ped, PCF_DisableExplosionReactions, TRUE)
|
|
SET_PED_CONFIG_FLAG(ped, PCF_DontActivateRagdollFromExplosions, TRUE)
|
|
SET_PED_CONFIG_FLAG(ped, PCF_AvoidTearGas, TRUE ) // FALSE)
|
|
SET_ENTITY_HEALTH(ped, 101)
|
|
CLEAR_PED_PROP( ped, ANCHOR_LEFT_HAND )
|
|
CLEAR_PED_PROP( ped, ANCHOR_RIGHT_HAND )
|
|
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL SETUP_CROWD_CONTROL_PED_LOCAL_PROPS( PED_INDEX ped, CROWD_CONTROL_LOCAL_PED_DATA &sLocalPedData, CROWD_CONTROL_HEIST_TYPE eHeistType )
|
|
|
|
BOOL bReady = TRUE
|
|
|
|
CROWD_CONTROL_PED_HERO_ACTION eHeroAction
|
|
IF eHeistType != CCHEIST_NORMAL
|
|
eHeroAction = GET_CROWD_CONTROL_PED_HERO_ACTION_FOR_ANIMATED_PED( sLocalPedData.eCreatorAssignedPedID, eHeistType )
|
|
ELSE
|
|
eHeroAction = INT_TO_ENUM( CROWD_CONTROL_PED_HERO_ACTION, sLocalPedData.eCreatorAssignedPedID )
|
|
IF eHeroAction = CCHERO_ALARM
|
|
eHeroAction = CCHERO_NONE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "SETUP_CROWD_CONTROL_PED_LOCAL_PROPS() - ", GET_CROWD_CONTROL_PED_NAME_FROM_ANIM_ID( sLocalPedData.eCreatorAssignedPedID ), " - eHeroAction = ", GET_CROWD_CONTROL_HERO_ACTION( eHeroAction ), " - eHeistType = ", GET_CROWD_CONTROL_HEIST_TYPE_STRING( eHeistType ) )
|
|
|
|
IF NOT DOES_ENTITY_EXIST( sLocalPedData.objProp )
|
|
|
|
// Need to spawn a phone for the ped
|
|
IF eHeroAction = CCHERO_PHONE
|
|
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "SETUP_CROWD_CONTROL_PED_LOCAL_PROPS() - Spawning phone for phone hero ped..." )
|
|
|
|
IF HAS_MODEL_LOADED( PROP_PHONE_ING )
|
|
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "SETUP_CROWD_CONTROL_PED_LOCAL_PROPS() - ... phone created." )
|
|
sLocalPedData.objProp = CREATE_OBJECT( PROP_PHONE_ING, GET_ENTITY_COORDS( ped ), FALSE )
|
|
ATTACH_ENTITY_TO_ENTITY( sLocalPedData.objProp, ped, GET_PED_BONE_INDEX( ped, BONETAG_PH_R_HAND ), <<0,0,0>>, <<0,0,0>>, TRUE, FALSE )
|
|
|
|
ELSE
|
|
bReady = FALSE
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
RETURN bReady
|
|
ENDFUNC
|
|
|
|
|
|
FUNC CROWD_CONTROL_DIALOGUE_CONTEXT GET_CROWD_CONTROL_DIALOGUE_CONTEXT_TIMER( CROWD_CONTROL_DIALOGUE eDialogue )
|
|
|
|
SWITCH eDialogue
|
|
|
|
CASE CCDIA_SHOT_DIRECTLY_AT
|
|
RETURN CCDIACONTEXT_SCARED_HIGH
|
|
BREAK
|
|
|
|
CASE CCDIA_SHOT_NEAR
|
|
RETURN CCDIACONTEXT_SCARED_MEDIUM
|
|
BREAK
|
|
|
|
CASE CCDIA_INITIAL_PANIC
|
|
CASE CCDIA_RECEIVES_SCARE
|
|
RETURN CCDIACONTEXT_SCARED_LOW
|
|
BREAK
|
|
|
|
CASE CCDIA_SEES_OTHER_KILLED
|
|
CASE CCDIA_STICKS_UP_FOR_OTHER
|
|
RETURN CCDIACONTEXT_SCARED_SECOND_HAND
|
|
BREAK
|
|
|
|
CASE CCDIA_COWER_LOW_FEAR
|
|
CASE CCDIA_COWER_HIGH_FEAR
|
|
CASE CCDIA_ALARM_GOES_OFF
|
|
RETURN CCDIACONTEXT_AMBIENT
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
RETURN CCDIACONTEXT_NUM_CONTEXTS
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL RESET_CROWD_CONTROL_GLOBAL_DIALOGUE_CONTEXT_TIMER( CROWD_CONTROL_DIALOGUE eDialogue, CROWD_CONTROL_LOCAL_DATA &sLocalData )
|
|
CROWD_CONTROL_DIALOGUE_CONTEXT eContext = GET_CROWD_CONTROL_DIALOGUE_CONTEXT_TIMER( eDialogue )
|
|
IF eContext != CCDIACONTEXT_NUM_CONTEXTS
|
|
|
|
INT iDelay
|
|
SWITCH eContext
|
|
CASE CCDIACONTEXT_SCARED_HIGH iDelay = 500 + ( GET_RANDOM_INT_IN_RANGE( 0, 6 ) * 100 ) /* 0.5 -> 1 secs */ BREAK
|
|
CASE CCDIACONTEXT_SCARED_MEDIUM iDelay = 1000 + ( GET_RANDOM_INT_IN_RANGE( 0, 5 ) * 500 ) /* 1 -> 3 secs */ BREAK
|
|
CASE CCDIACONTEXT_SCARED_LOW iDelay = 2000 + ( GET_RANDOM_INT_IN_RANGE( 0, 5 ) * 500 ) /* 2 -> 4 secs */ BREAK
|
|
CASE CCDIACONTEXT_SCARED_SECOND_HAND iDelay = 2000 + ( GET_RANDOM_INT_IN_RANGE( 0, 5 ) * 500 ) /* 2 -> 4 secs */ BREAK
|
|
CASE CCDIACONTEXT_AMBIENT iDelay = 5000 + ( GET_RANDOM_INT_IN_RANGE( 0, 6 ) * 1000 ) /* 5 -> 10 secs */ BREAK
|
|
ENDSWITCH
|
|
|
|
sLocalData.timeDialogueGlobalContextTimers[eContext] = GET_TIME_OFFSET( GET_NETWORK_TIME(), iDelay )
|
|
RETURN TRUE
|
|
ENDIF
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL HAS_CROWD_CONTROL_GLOBAL_DIALOGUE_CONTEXT_TIMER_EXPIRED( CROWD_CONTROL_DIALOGUE eDialogue, CROWD_CONTROL_LOCAL_DATA &sLocalData )
|
|
CROWD_CONTROL_DIALOGUE_CONTEXT eContext = GET_CROWD_CONTROL_DIALOGUE_CONTEXT_TIMER( eDialogue )
|
|
// No context timer exists, ignore timer and return TRUE
|
|
// Context exists, check its timer
|
|
IF eContext = CCDIACONTEXT_NUM_CONTEXTS
|
|
OR IS_TIME_MORE_THAN( GET_NETWORK_TIME(), sLocalData.timeDialogueGlobalContextTimers[eContext] )
|
|
RETURN TRUE
|
|
ENDIF
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL RESET_CROWD_CONTROL_PED_DIALOGUE_CONTEXT_TIMER( CROWD_CONTROL_DIALOGUE eDialogue, CROWD_CONTROL_LOCAL_PED_DATA &sLocalPedData )
|
|
CROWD_CONTROL_DIALOGUE_CONTEXT eContext = GET_CROWD_CONTROL_DIALOGUE_CONTEXT_TIMER( eDialogue )
|
|
IF eContext != CCDIACONTEXT_NUM_CONTEXTS
|
|
|
|
INT iDelay
|
|
SWITCH eContext
|
|
CASE CCDIACONTEXT_SCARED_HIGH iDelay = 1000 + ( GET_RANDOM_INT_IN_RANGE( 0, 3 ) * 500 ) /* 1 -> 2 secs */ BREAK
|
|
CASE CCDIACONTEXT_SCARED_MEDIUM iDelay = 3000 + ( GET_RANDOM_INT_IN_RANGE( 0, 3 ) * 500 ) /* 3 -> 4 secs */ BREAK
|
|
CASE CCDIACONTEXT_SCARED_LOW iDelay = 5000 + ( GET_RANDOM_INT_IN_RANGE( 0, 5 ) * 500 ) /* 5 -> 7 secs */ BREAK
|
|
CASE CCDIACONTEXT_SCARED_SECOND_HAND iDelay = 5000 + ( GET_RANDOM_INT_IN_RANGE( 0, 5 ) * 500 ) /* 5 -> 7 secs */ BREAK
|
|
CASE CCDIACONTEXT_AMBIENT iDelay = 12000 + ( GET_RANDOM_INT_IN_RANGE( 0, 6 ) * 1000 ) /* 12 -> 17 secs */ BREAK
|
|
ENDSWITCH
|
|
|
|
sLocalPedData.timeDialogueContextTimers[eContext] = GET_TIME_OFFSET( GET_NETWORK_TIME(), iDelay )
|
|
RETURN TRUE
|
|
ENDIF
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL HAS_CROWD_CONTROL_PED_DIALOGUE_CONTEXT_TIMER_EXPIRED( CROWD_CONTROL_DIALOGUE eDialogue, CROWD_CONTROL_LOCAL_PED_DATA &sLocalPedData )
|
|
CROWD_CONTROL_DIALOGUE_CONTEXT eContext = GET_CROWD_CONTROL_DIALOGUE_CONTEXT_TIMER( eDialogue )
|
|
// No context timer exists, ignore timer and return TRUE
|
|
// Context exists, check its timer
|
|
IF eContext = CCDIACONTEXT_NUM_CONTEXTS
|
|
OR IS_TIME_MORE_THAN( GET_NETWORK_TIME(), sLocalPedData.timeDialogueContextTimers[eContext] )
|
|
RETURN TRUE
|
|
ENDIF
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL IS_CROWD_CONTROL_PED_DIALOGUE_PRIORITY( CROWD_CONTROL_DIALOGUE eDialogueNew, CROWD_CONTROL_DIALOGUE eDialogueOld )
|
|
IF eDialogueNew != CCDIA_NONE
|
|
AND eDialogueNew > eDialogueOld
|
|
RETURN TRUE
|
|
ENDIF
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL IS_CROWD_CONTROL_PED_DIALOGUE_CRITICAL( CROWD_CONTROL_DIALOGUE eDialogue )
|
|
IF eDialogue = CCDIA_HERO_ALARM_START
|
|
OR eDialogue = CCDIA_HERO_ALARM_CAUGHT
|
|
OR eDialogue = CCDIA_HERO_ALARM_COMPLETE
|
|
OR eDialogue = CCDIA_HERO_GUN_START
|
|
OR eDialogue = CCDIA_HERO_GUN_CAUGHT
|
|
OR eDialogue = CCDIA_HERO_GUN_COMPLETE
|
|
OR eDialogue = CCDIA_HERO_PHONE_START
|
|
OR eDialogue = CCDIA_HERO_PHONE_CAUGHT
|
|
OR eDialogue = CCDIA_HERO_PHONE_COMPLETE
|
|
OR eDialogue = CCDIA_ALARM_GOES_OFF_INITIAL
|
|
RETURN TRUE
|
|
ENDIF
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL CHECK_CROWD_CONTROL_PED_DIALOGUE_CONTEXT_RANDOM_CHANCE( CROWD_CONTROL_DIALOGUE eDialogue )
|
|
|
|
SWITCH eDialogue
|
|
CASE CCDIA_SHOT_DIRECTLY_AT
|
|
RETURN GET_RANDOM_FLOAT_IN_RANGE(0, 1.0) <= 0.3 // 30% chance of playing
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
RETURN TRUE
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL GET_CROWD_CONTROL_VOICE_RACE_GENDER_PREFIX( CROWD_CONTROL_PED_ENUM ePed, CROWD_CONTROL_HEIST_TYPE eHeistType, TEXT_LABEL_15 &tlRaceGenderPrefix, TEXT_LABEL_23 &tlVoiceName )
|
|
|
|
BOOL bIsPedMale
|
|
BOOL bIsPedBlack
|
|
INT iPedNumber
|
|
|
|
SWITCH eHeistType
|
|
|
|
CASE CCHEIST_CUSTOM_FLEECA
|
|
|
|
SWITCH ePed
|
|
CASE CCPED_CASHIER_A
|
|
bIsPedMale = TRUE
|
|
bIsPedBlack = FALSE
|
|
iPedNumber = 1
|
|
BREAK
|
|
CASE CCPED_CUSTOMER_A
|
|
bIsPedMale = TRUE
|
|
bIsPedBlack = FALSE
|
|
iPedNumber = 1
|
|
BREAK
|
|
CASE CCPED_CUSTOMER_B
|
|
bIsPedMale = FALSE
|
|
bIsPedBlack = FALSE
|
|
iPedNumber = 1
|
|
BREAK
|
|
DEFAULT
|
|
RETURN FALSE
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
BREAK
|
|
|
|
CASE CCHEIST_CUSTOM_ORNATE
|
|
|
|
SWITCH ePed
|
|
CASE CCPED_CASHIER_A
|
|
bIsPedMale = TRUE
|
|
bIsPedBlack = FALSE
|
|
iPedNumber = 1
|
|
BREAK
|
|
CASE CCPED_CASHIER_B
|
|
bIsPedMale = TRUE
|
|
bIsPedBlack = FALSE
|
|
iPedNumber = 2
|
|
BREAK
|
|
CASE CCPED_CUSTOMER_A
|
|
bIsPedMale = TRUE
|
|
bIsPedBlack = FALSE
|
|
iPedNumber = 2
|
|
BREAK
|
|
CASE CCPED_CUSTOMER_B
|
|
bIsPedMale = TRUE
|
|
bIsPedBlack = TRUE
|
|
iPedNumber = 1
|
|
BREAK
|
|
CASE CCPED_CUSTOMER_C
|
|
bIsPedMale = FALSE
|
|
bIsPedBlack = FALSE
|
|
iPedNumber = 1
|
|
BREAK
|
|
CASE CCPED_CUSTOMER_D
|
|
bIsPedMale = TRUE
|
|
bIsPedBlack = FALSE
|
|
iPedNumber = 2
|
|
BREAK
|
|
CASE CCPED_CUSTOMER_E
|
|
bIsPedMale = FALSE
|
|
bIsPedBlack = TRUE
|
|
iPedNumber = 1
|
|
BREAK
|
|
CASE CCPED_CUSTOMER_F
|
|
bIsPedMale = FALSE
|
|
bIsPedBlack = FALSE
|
|
iPedNumber = 2
|
|
BREAK
|
|
CASE CCPED_CUSTOMER_G
|
|
bIsPedMale = TRUE
|
|
bIsPedBlack = FALSE
|
|
iPedNumber = 1
|
|
BREAK
|
|
CASE CCPED_CUSTOMER_H
|
|
bIsPedMale = FALSE
|
|
bIsPedBlack = FALSE
|
|
iPedNumber = 1
|
|
BREAK
|
|
DEFAULT
|
|
RETURN FALSE
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
BREAK
|
|
DEFAULT
|
|
RETURN FALSE
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
|
|
// Add hostages prefix
|
|
IF ePed = CCPED_CASHIER_A
|
|
OR ePed = CCPED_CASHIER_B
|
|
tlRaceGenderPrefix += "B"
|
|
tlVoiceName += "BANK"
|
|
ELSE
|
|
tlRaceGenderPrefix += "H"
|
|
tlVoiceName += "HOSTAGE"
|
|
ENDIF
|
|
|
|
// Add ethnicity prefix
|
|
IF bIsPedBlack
|
|
tlRaceGenderPrefix += "B"
|
|
tlVoiceName += "B"
|
|
ELSE
|
|
tlRaceGenderPrefix += "W"
|
|
tlVoiceName += "W"
|
|
ENDIF
|
|
|
|
// Add gender prefix
|
|
IF bIsPedMale
|
|
tlRaceGenderPrefix += "M"
|
|
tlVoiceName += "M"
|
|
ELSE
|
|
tlRaceGenderPrefix += "F"
|
|
tlVoiceName += "F"
|
|
ENDIF
|
|
|
|
// Add optional id number
|
|
IF iPedNumber != -1
|
|
tlRaceGenderPrefix += iPedNumber
|
|
tlVoiceName += iPedNumber
|
|
ENDIF
|
|
|
|
RETURN TRUE
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL GET_CROWD_CONTROL_PED_DIALOGUE_CONVO_SUFFIX( CROWD_CONTROL_DIALOGUE eDialogue, TEXT_LABEL_15 &tlConvoSuffix, INT &iLineNumber )
|
|
|
|
SWITCH eDialogue
|
|
// Generic, everyone should have these
|
|
CASE CCDIA_INITIAL_PANIC tlConvoSuffix += "C" BREAK
|
|
CASE CCDIA_COWER_LOW_FEAR tlConvoSuffix += "RE" BREAK
|
|
CASE CCDIA_COWER_HIGH_FEAR tlConvoSuffix += "SC" BREAK
|
|
CASE CCDIA_RECEIVES_SCARE tlConvoSuffix += "RS" BREAK
|
|
CASE CCDIA_STICKS_UP_FOR_OTHER tlConvoSuffix += "SF" BREAK
|
|
CASE CCDIA_SEES_OTHER_KILLED tlConvoSuffix += "HK" BREAK
|
|
CASE CCDIA_SHOT_NEAR tlConvoSuffix += "SN" BREAK
|
|
CASE CCDIA_SHOT_DIRECTLY_AT tlConvoSuffix += "SA" BREAK
|
|
CASE CCDIA_ALARM_GOES_OFF tlConvoSuffix += "AL" BREAK
|
|
CASE CCDIA_ALARM_GOES_OFF_INITIAL tlConvoSuffix += "GO" BREAK
|
|
|
|
// Hero stuff, specific peds will have these
|
|
CASE CCDIA_HERO_ALARM_START
|
|
tlConvoSuffix += "GP"
|
|
iLineNumber = 1
|
|
BREAK
|
|
CASE CCDIA_HERO_ALARM_CAUGHT
|
|
tlConvoSuffix += "DPA"
|
|
iLineNumber = 1
|
|
BREAK
|
|
CASE CCDIA_HERO_ALARM_COMPLETE
|
|
tlConvoSuffix += "PA"
|
|
iLineNumber = 1
|
|
BREAK
|
|
CASE CCDIA_HERO_PHONE_START
|
|
tlConvoSuffix += "DP"
|
|
iLineNumber = 1
|
|
BREAK
|
|
CASE CCDIA_HERO_PHONE_CAUGHT
|
|
tlConvoSuffix += "PA"
|
|
iLineNumber = 1
|
|
BREAK
|
|
CASE CCDIA_HERO_PHONE_COMPLETE
|
|
tlConvoSuffix += "CC"
|
|
iLineNumber = 1
|
|
BREAK
|
|
CASE CCDIA_HERO_PHONE_APOLOGISE
|
|
tlConvoSuffix += "SS"
|
|
iLineNumber = 1
|
|
BREAK
|
|
CASE CCDIA_HERO_GUN_START
|
|
tlConvoSuffix += "DG"
|
|
iLineNumber = 1
|
|
BREAK
|
|
CASE CCDIA_HERO_GUN_CAUGHT
|
|
tlConvoSuffix += "GA"
|
|
iLineNumber = 1
|
|
BREAK
|
|
CASE CCDIA_HERO_GUN_COMPLETE
|
|
tlConvoSuffix += "A"
|
|
iLineNumber = 1
|
|
BREAK
|
|
DEFAULT
|
|
RETURN FALSE
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
RETURN TRUE
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL GET_CROWD_CONTROL_PED_DIALOGUE_ROOT_LABEL( CROWD_CONTROL_PED_ENUM ePed, CROWD_CONTROL_DIALOGUE eDialogue, CROWD_CONTROL_HEIST_TYPE eHeistType, TEXT_LABEL_23 &tlRootLabel, TEXT_LABEL_23 &tlVoiceName, INT &iLineNumber )
|
|
|
|
TEXT_LABEL_15 tlRaceGenderPrefix
|
|
|
|
IF GET_CROWD_CONTROL_VOICE_RACE_GENDER_PREFIX( ePed, eHeistType, tlRaceGenderPrefix, tlVoiceName )
|
|
|
|
TEXT_LABEL_15 tlConvoSuffix
|
|
|
|
IF GET_CROWD_CONTROL_PED_DIALOGUE_CONVO_SUFFIX( eDialogue, tlConvoSuffix, iLineNumber )
|
|
|
|
tlRootLabel = "OBHF_"
|
|
tlRootLabel += tlRaceGenderPrefix
|
|
tlRootLabel += tlConvoSuffix
|
|
|
|
RETURN TRUE
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
PROC PLAY_CROWD_CONTROL_AMBIENT_SPEECH( PED_INDEX pedCrowd, CROWD_CONTROL_PED_ENUM ePed, CROWD_CONTROL_DIALOGUE eDialogueToPlay, CROWD_CONTROL_HEIST_TYPE eHeistType, BOOL bNeedsToInterrupt, BOOL bSyncOverNetwork = FALSE )
|
|
|
|
TEXT_LABEL_23 tlConvo
|
|
TEXT_LABEL_23 tlVoiceName
|
|
INT iLineNumber = -1
|
|
|
|
IF GET_CROWD_CONTROL_PED_DIALOGUE_ROOT_LABEL( ePed, eDialogueToPlay, eHeistType, tlConvo, tlVoiceName, iLineNumber )
|
|
|
|
SPEECH_PARAMS eParams
|
|
// IF bNeedsToInterrupt
|
|
// eParams = SPEECH_PARAMS_INTERRUPT_SHOUTED_CRITICAL
|
|
// ELSE
|
|
// eParams = SPEECH_PARAMS_FORCE_SHOUTED_CRITICAL
|
|
// ENDIF
|
|
UNUSED_PARAMETER(bNeedsToInterrupt)
|
|
eParams = SPEECH_PARAMS_FORCE_SHOUTED_CRITICAL
|
|
|
|
PLAY_AMBIENT_SPEECH_USING_LINE_FROM_CONVERSATION( pedCrowd, tlConvo, tlVoiceName, iLineNumber, eParams, bSyncOverNetwork )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PLAY_CROWD_CONTROL_AMBIENT_SPEECH() - Conversation Root = ", tlConvo, " Voice Name = ", tlVoiceName, " iLineNumber = ", iLineNumber, " Params = ", AUDIO_SPEECH_GET_PARAM_STRING_FROM_ENUM( eParams ) )
|
|
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
|
|
FUNC AUD_DAMAGE_REASON GET_CROWD_CONTROL_PED_ALTERNATIVE_PAIN_DIALOGUE( CROWD_CONTROL_DIALOGUE eDialogue )
|
|
|
|
/* For screams only use the following:
|
|
SCREAM_PANIC_SHORT = really short "huh"
|
|
SCREAM_PANIC = longer "huh"
|
|
SCREAM_SHOCKED = quick "aaahh"
|
|
SCREAM_TERROR = longer "ahhhh"
|
|
|
|
Other screams may or may not be present on a per ped basis */
|
|
|
|
SWITCH eDialogue
|
|
|
|
CASE CCDIA_APPROACH
|
|
RETURN AUD_DAMAGE_REASON_SCREAM_PANIC_SHORT
|
|
BREAK
|
|
|
|
CASE CCDIA_COWER_HIGH_FEAR
|
|
CASE CCDIA_COWER_LOW_FEAR
|
|
CASE CCDIA_ALARM_GOES_OFF
|
|
CASE CCDIA_ALARM_GOES_OFF_INITIAL
|
|
|
|
SWITCH GET_RANDOM_INT_IN_RANGE( 0, 2 )
|
|
CASE 0 RETURN AUD_DAMAGE_REASON_WHIMPER BREAK
|
|
CASE 1 RETURN AUD_DAMAGE_REASON_COWER BREAK
|
|
ENDSWITCH
|
|
|
|
BREAK
|
|
|
|
CASE CCDIA_STICKS_UP_FOR_OTHER
|
|
RETURN AUD_DAMAGE_REASON_SCREAM_PANIC
|
|
BREAK
|
|
|
|
CASE CCDIA_INITIAL_PANIC
|
|
|
|
SWITCH GET_RANDOM_INT_IN_RANGE( 0, 2 )
|
|
CASE 0 RETURN AUD_DAMAGE_REASON_SCREAM_SHOCKED BREAK
|
|
CASE 1 RETURN AUD_DAMAGE_REASON_SCREAM_PANIC BREAK
|
|
ENDSWITCH
|
|
|
|
BREAK
|
|
|
|
CASE CCDIA_SHOT_DIRECTLY_AT
|
|
RETURN AUD_DAMAGE_REASON_SCREAM_TERROR
|
|
BREAK
|
|
|
|
CASE CCDIA_SHOT_NEAR
|
|
CASE CCDIA_SEES_OTHER_KILLED
|
|
RETURN AUD_DAMAGE_REASON_SCREAM_SHOCKED
|
|
BREAK
|
|
|
|
CASE CCDIA_RECEIVES_SCARE
|
|
|
|
SWITCH GET_RANDOM_INT_IN_RANGE( 0, 2 )
|
|
CASE 0 RETURN AUD_DAMAGE_REASON_SCREAM_SHOCKED BREAK
|
|
CASE 1 RETURN AUD_DAMAGE_REASON_SCREAM_PANIC BREAK
|
|
ENDSWITCH
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
RETURN AUD_DAMAGE_REASON_DEFAULT
|
|
ENDFUNC
|
|
|
|
ENUM CROWD_CONTROL_DIALOGUE_PLAYBACK_FLAGS
|
|
CCDIAPLAYBACK_NONE = 0
|
|
,CCDIAPLAYBACK_FORCE_PAIN = 1
|
|
,CCDIAPLAYBACK_FORCE_CRITICAL = 2
|
|
ENDENUM
|
|
|
|
/// PURPOSE:
|
|
/// Queues up a conversation locally and priority checks against what is already stored. Keeps this local ready to be packed and sent to the host later.
|
|
/// PARAMS:
|
|
/// sLocalPedData - peds local data where the info will be stored
|
|
/// eDialogue - the dialogue you want to queue up
|
|
/// bIsCritical - is it critical? this will affect if this conversation ignores timers, max number of speakers, interrupts, etc.
|
|
PROC QUEUE_CROWD_CONTROL_DIALOGUE_CLIENT_TO_HOST( CROWD_CONTROL_LOCAL_DATA &sLocalData, CROWD_CONTROL_LOCAL_PED_DATA &sLocalPedData, CROWD_CONTROL_DIALOGUE eDialogue, CROWD_CONTROL_DIALOGUE_PLAYBACK_FLAGS eFlags = CCDIAPLAYBACK_NONE )
|
|
|
|
#IF NOT IS_DEBUG_BUILD
|
|
UNUSED_PARAMETER( sLocalData )
|
|
#ENDIF
|
|
|
|
IF IS_CROWD_CONTROL_PED_DIALOGUE_PRIORITY( eDialogue, sLocalPedData.eDialogueClientToHost )
|
|
OR IS_BITMASK_ENUM_AS_ENUM_SET( eFlags, CCDIAPLAYBACK_FORCE_CRITICAL )
|
|
|
|
// Update the local ped owners local ped data, this is needed for case we attempt to play more than 1 convo on 1 ped in the same update
|
|
// we would decide here which takes priority for this ped
|
|
sLocalPedData.eDialogueClientToHost = eDialogue
|
|
IF IS_BITMASK_ENUM_AS_ENUM_SET( eFlags, CCDIAPLAYBACK_FORCE_PAIN )
|
|
SET_BIT_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_DialogueClientToHostForcePain )
|
|
ELSE
|
|
CLEAR_BIT_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_DialogueClientToHostForcePain )
|
|
ENDIF
|
|
|
|
IF IS_BITMASK_ENUM_AS_ENUM_SET( eFlags, CCDIAPLAYBACK_FORCE_CRITICAL )
|
|
SET_BIT_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_DialogueClientToHostForceCritical )
|
|
ELSE
|
|
CLEAR_BIT_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_DialogueClientToHostForceCritical )
|
|
ENDIF
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_DebugLogDialogue )
|
|
CDEBUG1LN( DEBUG_NET_MINIGAME, "QUEUE_CROWD_CONTROL_DIALOGUE_CLIENT_TO_HOST() - ", GET_CROWD_CONTROL_PED_NAME_FROM_ANIM_ID( sLocalPedData.eCreatorAssignedPedID ),
|
|
" - Conversation queued = ", GET_CROWD_CONTROL_DIALOGUE_ENUM_STRING( sLocalPedData.eDialogueClientToHost ),
|
|
" - Force Pain = ", BOOL_TO_STRING( IS_BITMASK_ENUM_AS_ENUM_SET( eFlags, CCDIAPLAYBACK_FORCE_PAIN ) ),
|
|
" - Force Critical = ", BOOL_TO_STRING( IS_BITMASK_ENUM_AS_ENUM_SET( eFlags, CCDIAPLAYBACK_FORCE_CRITICAL ) ) )
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
|
|
/// PURPOSE:
|
|
/// Collects all the conversations on peds this machine owns and sends them on to the host
|
|
/// PARAMS:
|
|
/// sLocalPedData - local ped data which will have all the
|
|
/// iNumCrowdPeds - number of crowd control peds
|
|
PROC PROCESS_CROWD_CONTROL_DIALOGUE_CLIENT_TO_HOST_QUEUE( INT iCrowdPed, CROWD_CONTROL_LOCAL_DATA &sLocalData, CROWD_CONTROL_LOCAL_PED_DATA &sLocalPedData,
|
|
INT &iPackedDialogueConversations[], INT &iPackedDialoguePainFlags, INT &iPackedDialogueCriticalFlags )
|
|
|
|
BOOL bDiscardDialogue
|
|
bDiscardDialogue = FALSE
|
|
|
|
// Theres something to send, add it to the packed data
|
|
// To avoid spamming
|
|
IF sLocalPedData.eDialogueClientToHost != CCDIA_NONE
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitset, CCLOCALDATA_DebugLogDialogue )
|
|
CDEBUG1LN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_DIALOGUE_CLIENT_TO_HOST_QUEUE() - ",
|
|
GET_CROWD_CONTROL_PED_NAME_FROM_ANIM_ID( sLocalPedData.eCreatorAssignedPedID ),
|
|
" - Dialogue = ", GET_CROWD_CONTROL_DIALOGUE_ENUM_STRING( sLocalPedData.eDialogueClientToHost ) )
|
|
ENDIF
|
|
#ENDIF
|
|
#IF NOT IS_DEBUG_BUILD
|
|
UNUSED_PARAMETER(sLocalData)
|
|
#ENDIF
|
|
|
|
IF IS_TIME_MORE_THAN( GET_NETWORK_TIME(), sLocalPedData.timeDialogueLastBroadcast )
|
|
OR IS_CROWD_CONTROL_PED_DIALOGUE_CRITICAL( sLocalPedData.eDialogueClientToHost )
|
|
OR IS_BIT_SET_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_DialogueClientToHostForceCritical )
|
|
|
|
SET_PACKED_BITFIELD_VALUE_IN_ARRAY( iPackedDialogueConversations, iCrowdPed, ciCC_DialogueDataBitWidth, ENUM_TO_INT( sLocalPedData.eDialogueClientToHost ) )
|
|
|
|
IF IS_BIT_SET_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_DialogueClientToHostForcePain )
|
|
SET_BIT( iPackedDialoguePainFlags, iCrowdPed )
|
|
ELSE
|
|
CLEAR_BIT( iPackedDialoguePainFlags, iCrowdPed )
|
|
ENDIF
|
|
|
|
IF IS_BIT_SET_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_DialogueClientToHostForceCritical )
|
|
SET_BIT( iPackedDialogueCriticalFlags, iCrowdPed )
|
|
ELSE
|
|
CLEAR_BIT( iPackedDialogueCriticalFlags, iCrowdPed )
|
|
ENDIF
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitset, CCLOCALDATA_DebugLogDialogue )
|
|
CDEBUG1LN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_DIALOGUE_CLIENT_TO_HOST_QUEUE() packed for broadcast" )
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
sLocalPedData.timeDialogueLastBroadcast = GET_TIME_OFFSET( GET_NETWORK_TIME(), 1000 + ( GET_RANDOM_INT_IN_RANGE( 0, 5 ) * 250 ) ) // 1 -> 2 seconds (250ms intervals)
|
|
|
|
ELSE
|
|
bDiscardDialogue = TRUE
|
|
ENDIF
|
|
|
|
// Reset this machines local dialogue data if not the host (leave alone for the host unless bDiscardDialogue = TRUE)
|
|
IF bDiscardDialogue
|
|
OR NOT NETWORK_IS_HOST_OF_THIS_SCRIPT()
|
|
|
|
sLocalPedData.eDialogueClientToHost = CCDIA_NONE
|
|
CLEAR_BIT_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_DialogueClientToHostForcePain )
|
|
CLEAR_BIT_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_DialogueClientToHostForceCritical )
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitset, CCLOCALDATA_DebugLogDialogue )
|
|
IF NOT NETWORK_IS_HOST_OF_THIS_SCRIPT()
|
|
CDEBUG1LN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_DIALOGUE_CLIENT_TO_HOST_QUEUE() discarded(not host)" )
|
|
ELSE
|
|
CDEBUG1LN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_DIALOGUE_CLIENT_TO_HOST_QUEUE() discarded(timer not ready)" )
|
|
ENDIF
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
|
|
|
|
|
|
|
|
/// PURPOSE:
|
|
/// Processes the queue of conversations that have come in from other clients (and itself) to decide who is allowed to speak (and who to ignore).
|
|
/// PARAMS:
|
|
/// niPed - array of mission controller peds
|
|
/// sLocalData - local data
|
|
/// sLocalPedData - local ped data (this will have the received CLIENT to HOST conversations stored )
|
|
/// iCrowdControlCloudIndex - lookup indices for crowd control peds
|
|
/// iNumCrowdControlPeds - number of crowd control peds in this crowd
|
|
PROC PROCESS_CROWD_CONTROL_DIALOGUE_SELECTION( NETWORK_INDEX &niPed[],
|
|
CROWD_CONTROL_SERVER_DATA &sData,
|
|
CROWD_CONTROL_LOCAL_DATA &sLocalData,
|
|
CROWD_CONTROL_LOCAL_PED_DATA &sLocalPedData[],
|
|
INT &iCrowdControlCloudIndex[], INT iNumCrowdControlPeds )
|
|
|
|
INT i
|
|
|
|
// INITIAL PASS - Last time talking timer & number of current speakers
|
|
//------------------------------------------------------------------------------
|
|
INT iNumberOfPedsCurrentlySpeaking
|
|
INT iNumberOfPedsCurrentlyPlayingPain
|
|
|
|
PED_INDEX pedsTemp[FMMC_MAX_CROWD_PEDS]
|
|
BOOL bPedInjured[FMMC_MAX_CROWD_PEDS]
|
|
BOOL bIsAmbientSpeechPlaying[FMMC_MAX_CROWD_PEDS]
|
|
BOOL bIsAnySpeechPlaying[FMMC_MAX_CROWD_PEDS]
|
|
|
|
FOR i = 0 TO iNumCrowdControlPeds-1
|
|
|
|
INT iPed = iCrowdControlCloudIndex[i]
|
|
|
|
IF NETWORK_DOES_ENTITY_EXIST_WITH_NETWORK_ID( niPed[iPed] )
|
|
|
|
pedsTemp[i] = NET_TO_PED( niPed[iPed] )
|
|
bPedInjured[i] = IS_PED_INJURED( pedsTemp[i] )
|
|
IF NOT bPedInjured[i]
|
|
bIsAnySpeechPlaying[i] = IS_ANY_SPEECH_PLAYING( pedsTemp[i] )
|
|
bIsAmbientSpeechPlaying[i] = IS_AMBIENT_SPEECH_PLAYING( pedsTemp[i] )
|
|
ELSE
|
|
bIsAnySpeechPlaying[i] = FALSE
|
|
bIsAmbientSpeechPlaying[i] = FALSE
|
|
ENDIF
|
|
|
|
IF NOT bPedInjured[i]
|
|
IF bIsAmbientSpeechPlaying[i]
|
|
iNumberOfPedsCurrentlySpeaking++
|
|
ELIF bIsAnySpeechPlaying[i]
|
|
iNumberOfPedsCurrentlyPlayingPain++
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDFOR
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_DebugLogDialogue )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "\n" )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_DIALOGUE_QUEUE() <1st PASS> - Count the speakers - Total speakers = ", iNumberOfPedsCurrentlySpeaking + iNumberOfPedsCurrentlyPlayingPain, "/", ciCC_MaxNumberOfSpeakers,
|
|
" Dialogue = ", iNumberOfPedsCurrentlySpeaking, "/", ciCC_MaxNumberOfAmbientDialogue,
|
|
" Pain = ", iNumberOfPedsCurrentlyPlayingPain, "/", ciCC_MaxNumberOfPain )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "\n" )
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
|
|
// 2nd PASS - Find the highest priority dialogues to play
|
|
//------------------------------------------------------------------------------
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_DebugLogDialogue )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_DIALOGUE_QUEUE() <2nd PASS> - Populating the queue.")
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "\n" )
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
// Create random look up table to mix up the queue
|
|
INT iRnd[FMMC_MAX_CROWD_PEDS]
|
|
|
|
FOR i = 0 TO iNumCrowdControlPeds-1
|
|
// Initialise numbers
|
|
iRnd[i] = i
|
|
ENDFOR
|
|
|
|
FOR i = 0 TO iNumCrowdControlPeds-1
|
|
// Randomise numbers
|
|
INT iRndIndex = GET_RANDOM_INT_IN_RANGE( 0, iNumCrowdControlPeds )
|
|
INT iTemp = iRnd[i]
|
|
iRnd[i] = iRnd[iRndIndex]
|
|
iRnd[iRndIndex] = iTemp
|
|
ENDFOR
|
|
|
|
|
|
// Initialise priority queue to -1
|
|
INT iCrowdNumSpeakerPriorityQueue[FMMC_MAX_CROWD_PEDS]
|
|
FOR i = 0 TO COUNT_OF( iCrowdNumSpeakerPriorityQueue ) - 1
|
|
iCrowdNumSpeakerPriorityQueue[i] = -1
|
|
ENDFOR
|
|
|
|
// Go through each ped wanting to speak and check them against the priority queue
|
|
FOR i = 0 TO iNumCrowdControlPeds-1
|
|
|
|
INT iCrowdPed = iRnd[i] // randomises the
|
|
|
|
IF sLocalPedData[iCrowdPed].eDialogueClientToHost != CCDIA_NONE
|
|
|
|
IF pedsTemp[iCrowdPed] != NULL
|
|
|
|
IF NOT bPedInjured[iCrowdPed]
|
|
AND ( NOT bIsAnySpeechPlaying[iCrowdPed]
|
|
//OR IS_BIT_SET_ENUM( sLocalPedData[iCrowdPed].iBitset, CCLOCALPEDDATA_DialogueClientToHostCritical ) )
|
|
OR IS_CROWD_CONTROL_PED_DIALOGUE_PRIORITY( sLocalPedData[iCrowdPed].eDialogueClientToHost, sLocalPedData[iCrowdPed].eDialogueCurrentlyPlaying ) )
|
|
|
|
BOOL bConvoStored
|
|
INT j
|
|
// Run through the queue comparing with whats already stored
|
|
FOR j = 0 TO COUNT_OF( iCrowdNumSpeakerPriorityQueue ) - 1
|
|
|
|
// Can store this, is higher priority
|
|
IF iCrowdNumSpeakerPriorityQueue[j] = -1
|
|
OR IS_CROWD_CONTROL_PED_DIALOGUE_PRIORITY(
|
|
sLocalPedData[iCrowdPed].eDialogueClientToHost,
|
|
sLocalPedData[iCrowdNumSpeakerPriorityQueue[j]].eDialogueClientToHost )
|
|
|
|
// Push everything down 1 entry
|
|
INT k
|
|
k = COUNT_OF( iCrowdNumSpeakerPriorityQueue ) - 1
|
|
|
|
// If theres anything currently stored in the bottom of the queue, get rid of it as we're not going to use it
|
|
IF iCrowdNumSpeakerPriorityQueue[k] != -1
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_DebugLogDialogue )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_DIALOGUE_QUEUE() - [", iCrowdNumSpeakerPriorityQueue[k], "] ",
|
|
GET_CROWD_CONTROL_PED_NAME_FROM_ANIM_ID( sLocalPedData[iCrowdNumSpeakerPriorityQueue[k]].eCreatorAssignedPedID ),
|
|
" - Dialogue = ", GET_CROWD_CONTROL_DIALOGUE_ENUM_STRING( sLocalPedData[iCrowdNumSpeakerPriorityQueue[k]].eDialogueClientToHost ),
|
|
" discared from SLOT[", k, "]" )
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
sLocalPedData[k].eDialogueClientToHost = CCDIA_NONE
|
|
CLEAR_BIT_ENUM( sLocalPedData[k].iBitSet, CCLOCALPEDDATA_DialogueClientToHostForcePain )
|
|
ENDIF
|
|
|
|
WHILE k >= j
|
|
IF k = j
|
|
iCrowdNumSpeakerPriorityQueue[k] = iCrowdPed
|
|
ELSE
|
|
iCrowdNumSpeakerPriorityQueue[k] = iCrowdNumSpeakerPriorityQueue[k-1]
|
|
ENDIF
|
|
k--
|
|
ENDWHILE
|
|
|
|
bConvoStored = TRUE
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_DebugLogDialogue )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_DIALOGUE_QUEUE() - [", iCrowdPed, "] ",
|
|
GET_CROWD_CONTROL_PED_NAME_FROM_ANIM_ID( sLocalPedData[iCrowdPed].eCreatorAssignedPedID ),
|
|
" - Dialogue = ", GET_CROWD_CONTROL_DIALOGUE_ENUM_STRING( sLocalPedData[iCrowdPed].eDialogueClientToHost ),
|
|
" inserted into queue SLOT[", j, "]" )
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
j = COUNT_OF( iCrowdNumSpeakerPriorityQueue ) // break loop
|
|
|
|
ENDIF
|
|
|
|
ENDFOR
|
|
|
|
// Convo wasn't high enough priority to beat other conversations, erase
|
|
IF NOT bConvoStored
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_DebugLogDialogue )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_DIALOGUE_QUEUE() - ", GET_CROWD_CONTROL_DIALOGUE_ENUM_STRING( sLocalPedData[iCrowdPed].eDialogueClientToHost ), " not high enough priority, cleared dialogue" )
|
|
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_DIALOGUE_QUEUE() - [", iCrowdPed, "] ",
|
|
GET_CROWD_CONTROL_PED_NAME_FROM_ANIM_ID( sLocalPedData[iCrowdPed].eCreatorAssignedPedID ),
|
|
" - Dialogue = ", GET_CROWD_CONTROL_DIALOGUE_ENUM_STRING( sLocalPedData[iCrowdPed].eDialogueClientToHost ),
|
|
" discarded, priority not high enough" )
|
|
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
sLocalPedData[iCrowdPed].eDialogueClientToHost = CCDIA_NONE
|
|
CLEAR_BIT_ENUM( sLocalPedData[iCrowdPed].iBitSet, CCLOCALPEDDATA_DialogueClientToHostForcePain )
|
|
ENDIF
|
|
|
|
ELSE
|
|
#IF IS_DEBUG_BUILD
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_DebugLogDialogue )
|
|
CDEBUG1LN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_DIALOGUE_QUEUE() - [", iCrowdPed, "] ",
|
|
GET_CROWD_CONTROL_PED_NAME_FROM_ANIM_ID( sLocalPedData[iCrowdPed].eCreatorAssignedPedID ),
|
|
" - Dialogue = ", GET_CROWD_CONTROL_DIALOGUE_ENUM_STRING( sLocalPedData[iCrowdPed].eDialogueClientToHost ),
|
|
" - Unable to start queue up of this dialogue, ped already speaking " )
|
|
ENDIF
|
|
#ENDIF
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDFOR
|
|
|
|
|
|
// FINAL(3rd) PASS - Play the dialogue we have queued
|
|
//------------------------------------------------------------------------------
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_DebugLogDialogue )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "\n" )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_DIALOGUE_QUEUE() - <3rd PASS> Processing the queue." )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "\n" )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_DIALOGUE_QUEUE() - Queue Snapshop" )
|
|
ENDIF
|
|
|
|
#ENDIF
|
|
|
|
// Print the queue
|
|
FOR i = 0 TO COUNT_OF( iCrowdNumSpeakerPriorityQueue ) - 1
|
|
IF iCrowdNumSpeakerPriorityQueue[i] != -1
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_DebugLogDialogue )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_DIALOGUE_QUEUE() SLOT[", i, "] = ",
|
|
"[", iCrowdNumSpeakerPriorityQueue[i], "] ", GET_CROWD_CONTROL_PED_NAME_FROM_ANIM_ID( sLocalPedData[iCrowdNumSpeakerPriorityQueue[i]].eCreatorAssignedPedID ),
|
|
" - Dialogue = ", GET_CROWD_CONTROL_DIALOGUE_ENUM_STRING( sLocalPedData[iCrowdNumSpeakerPriorityQueue[i]].eDialogueClientToHost ) )
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
ENDIF
|
|
ENDFOR
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_DebugLogDialogue )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "\n" )
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
INT iPackedDialogueConversations[2]
|
|
INT iPackedDialogueIsPainFlags
|
|
|
|
FOR i = 0 TO COUNT_OF( iCrowdNumSpeakerPriorityQueue )-1
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_DebugLogDialogue )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_DIALOGUE_QUEUE() - Processing SLOT[", i, "]" )
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
// Ped queued
|
|
IF iCrowdNumSpeakerPriorityQueue[i] != -1
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_DebugLogDialogue )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_DIALOGUE_QUEUE() [", iCrowdNumSpeakerPriorityQueue[i], "] ",
|
|
GET_CROWD_CONTROL_PED_NAME_FROM_ANIM_ID( sLocalPedData[iCrowdNumSpeakerPriorityQueue[i]].eCreatorAssignedPedID ),
|
|
" - Dialogue = ", GET_CROWD_CONTROL_DIALOGUE_ENUM_STRING( sLocalPedData[iCrowdNumSpeakerPriorityQueue[i]].eDialogueClientToHost ) )
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
INT iCrowdPed = iCrowdNumSpeakerPriorityQueue[i]
|
|
IF sLocalPedData[iCrowdPed].eDialogueClientToHost != CCDIA_NONE
|
|
|
|
IF pedsTemp[iCrowdPed] != NULL
|
|
|
|
IF NOT bPedInjured[iCrowdPed]
|
|
// Ped is not already speaking
|
|
AND ( NOT bIsAnySpeechPlaying[iCrowdPed]
|
|
// OR the new dialogue is a higher priority than what is already being said
|
|
// AND is critical
|
|
OR ( ( IS_CROWD_CONTROL_PED_DIALOGUE_CRITICAL( sLocalPedData[iCrowdPed].eDialogueClientToHost )
|
|
OR IS_BIT_SET_ENUM( sLocalPedDAta[iCrowdPed].iBitSet, CCLOCALPEDDATA_DialogueClientToHostForceCritical ) )
|
|
AND IS_CROWD_CONTROL_PED_DIALOGUE_PRIORITY( sLocalPedData[iCrowdPed].eDialogueClientToHost, sLocalPedData[iCrowdPed].eDialogueCurrentlyPlaying ) ) )
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_DebugLogDialogue )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_DIALOGUE_QUEUE() Attempting dialogue - Speakers(Total) = ", iNumberOfPedsCurrentlySpeaking + iNumberOfPedsCurrentlyPlayingPain, "/", ciCC_MaxNumberOfSpeakers,
|
|
" Dialogue = ", iNumberOfPedsCurrentlySpeaking, "/", ciCC_MaxNumberOfAmbientDialogue,
|
|
" Pain = ", iNumberOfPedsCurrentlyPlayingPain, "/", ciCC_MaxNumberOfPain )
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
|
|
BOOL bCanPlayThisDialogue
|
|
TEXT_LABEL_23 tlConvo = ""
|
|
TEXT_LABEL_23 tlDummy = ""
|
|
INT iLine = -1
|
|
IF GET_CROWD_CONTROL_PED_DIALOGUE_ROOT_LABEL( sLocalPedData[iCrowdPed].eCreatorAssignedPedID, sLocalPedData[iCrowdPed].eDialogueClientToHost, sLocalData.eHeistType, tlConvo, tlDummy, iLine )
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_DebugLogDialogue )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_DIALOGUE_QUEUE() - Found Root Label \"", tlConvo, "\" iLine = ", iLine )
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
|
|
TEXT_LABEL_23 tlConvoFilename = GET_CONVERSATION_LINE_FILENAME_FROM_CONVERSATION_ROOT( tlConvo, iLine )
|
|
IF NOT IS_STRING_NULL_OR_EMPTY( tlConvoFilename )
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_DebugLogDialogue )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_DIALOGUE_QUEUE() - Convo Filename \"", tlConvoFilename, "\" does exist!" )
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
bCanPlayThisDialogue = TRUE
|
|
ELSE
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_DebugLogDialogue )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_DIALOGUE_QUEUE() - Convo Filename \"", tlConvoFilename, "\" does not exist" )
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// SELECT - PLAY AMBIENT SPEECH
|
|
//----------------------------------------------------------------
|
|
|
|
// IF this dialogue context exists
|
|
// AND we don't specifically want to play pain
|
|
// AND we've checked the random chance for this context
|
|
IF bCanPlayThisDialogue
|
|
AND NOT IS_BIT_SET_ENUM( sLocalPedData[iCrowdPed].iBitSet, CCLOCALPEDDATA_DialogueClientToHostForcePain )
|
|
AND CHECK_CROWD_CONTROL_PED_DIALOGUE_CONTEXT_RANDOM_CHANCE( sLocalPedData[iCrowdPed].eDialogueClientToHost )
|
|
// Only ever have CCDIA_ALARM_GOES_OFF_INITIAL said once
|
|
// by a ped that definitely has the dialogue
|
|
AND ( sLocalPedData[iCrowdPed].eDialogueClientToHost != CCDIA_ALARM_GOES_OFF_INITIAL
|
|
OR NOT IS_BIT_SET_ENUM( sData.iBitSet, CCDATA_RaiseAlarmDiagloue ) )
|
|
// AND is this a critical line of dialogue (actual or forced)
|
|
AND ( ( IS_CROWD_CONTROL_PED_DIALOGUE_CRITICAL( sLocalPedData[iCrowdPed].eDialogueClientToHost )
|
|
OR IS_BIT_SET_ENUM( sLocalPedData[iCrowdPed].iBitSet, CCLOCALPEDDATA_DialogueClientToHostForceCritical ) )
|
|
// OR context timer for this dialogue has expired and there is room for another speaker
|
|
OR ( iNumberOfPedsCurrentlySpeaking < ciCC_MaxNumberOfAmbientDialogue
|
|
AND HAS_CROWD_CONTROL_GLOBAL_DIALOGUE_CONTEXT_TIMER_EXPIRED( sLocalPedData[iCrowdPed].eDialogueClientToHost, sLocalData )
|
|
AND HAS_CROWD_CONTROL_PED_DIALOGUE_CONTEXT_TIMER_EXPIRED( sLocalPedData[iCrowdPed].eDialogueClientToHost, sLocalPedData[iCrowdPed] ) ) )
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_DebugLogDialogue )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_DIALOGUE_QUEUE() HOST wants to play ambient speech." )
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
// Already speaking/playing pain
|
|
IF bIsAnySpeechPlaying[iCrowdPed]
|
|
|
|
// Was playing dialogue, counters not change
|
|
IF NOT bIsAmbientSpeechPlaying[iCrowdPed]
|
|
iNumberOfPedsCurrentlyPlayingPain--
|
|
iNumberOfPedsCurrentlySpeaking++
|
|
ENDIF
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_DebugLogDialogue )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_DIALOGUE_QUEUE() Ambient speech already playing - OVERRIDING" )
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
// Wasn't playing anything
|
|
ELSE
|
|
iNumberOfPedsCurrentlySpeaking++
|
|
ENDIF
|
|
|
|
|
|
IF sLocalPedData[iCrowdPed].eDialogueClientToHost = CCDIA_ALARM_GOES_OFF_INITIAL
|
|
SET_BIT_ENUM( sData.iBitSet, CCDATA_RaiseAlarmDiagloue )
|
|
ENDIF
|
|
|
|
// Store ready to be played (for this machine)
|
|
sLocalPedData[iCrowdPed].eDialogueHostToClient = sLocalPedData[iCrowdPed].eDialogueClientToHost
|
|
CLEAR_BIT_ENUM( sLocalPedData[iCrowdPed].iBitSet, CCLOCALPEDDATA_DialogueHostToClientPain )
|
|
|
|
// Host resets the context timer and sends it to the remote players too as it uses a random delay
|
|
// (if done on each machine the delay would be different for each machine)
|
|
RESET_CROWD_CONTROL_PED_DIALOGUE_CONTEXT_TIMER( sLocalPedData[iCrowdPed].eDialogueHostToClient, sLocalPedData[iCrowdPed] )
|
|
RESET_CROWD_CONTROL_GLOBAL_DIALOGUE_CONTEXT_TIMER( sLocalPedData[iCrowdPed].eDialogueHostToClient, sLocalData )
|
|
|
|
// Also pack ready for broadcast (to all other remote machines)
|
|
SET_PACKED_BITFIELD_VALUE_IN_ARRAY_FROM_ENUM( iPackedDialogueConversations, iCrowdPed, ciCC_DialogueDataBitWidth, sLocalPedData[iCrowdPed].eDialogueClientToHost )
|
|
CLEAR_BIT( iPackedDialogueIsPainFlags, iCrowdPed )
|
|
|
|
|
|
// SELECT - PLAY PAIN
|
|
//----------------------------------------------------------------
|
|
|
|
ELIF NOT bIsAnySpeechPlaying[iCrowdPed]
|
|
OR IS_CROWD_CONTROL_PED_DIALOGUE_CRITICAL( sLocalPedData[iCrowdPed].eDialogueClientToHost )
|
|
OR IS_BIT_SET_ENUM( sLocalPedData[iCrowdPed].iBitSet, CCLOCALPEDDATA_DialogueClientToHostForceCritical )
|
|
|
|
// ... Check if the ped has an alternative Pain based dialogue
|
|
// Force through critical pain
|
|
IF iNumberOfPedsCurrentlyPlayingPain < ciCC_MaxNumberOfPain
|
|
OR sLocalPedData[iCrowdPed].eDialogueClientToHost = CCDIA_INITIAL_PANIC
|
|
OR IS_BIT_SET_ENUM( sLocalPedData[iCrowdPed].iBitSet, CCLOCALPEDDATA_DialogueClientToHostForceCritical )
|
|
|
|
IF GET_CROWD_CONTROL_PED_ALTERNATIVE_PAIN_DIALOGUE( sLocalPedData[iCrowdPed].eDialogueClientToHost ) != AUD_DAMAGE_REASON_DEFAULT
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_DebugLogDialogue )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_DIALOGUE_QUEUE() HOST wants to play pain audio" )
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
// Store ready to be played
|
|
sLocalPedData[iCrowdPed].eDialogueHostToClient = sLocalPedData[iCrowdPed].eDialogueClientToHost
|
|
SET_BIT_ENUM( sLocalPedData[iCrowdPed].iBitSet, CCLOCALPEDDATA_DialogueHostToClientPain )
|
|
|
|
// Also pack ready for broadcast
|
|
SET_PACKED_BITFIELD_VALUE_IN_ARRAY_FROM_ENUM( iPackedDialogueConversations, iCrowdPed, ciCC_DialogueDataBitWidth, sLocalPedData[iCrowdPed].eDialogueClientToHost )
|
|
SET_BIT( iPackedDialogueIsPainFlags, iCrowdPed )
|
|
|
|
// Already speaking/playing pain
|
|
IF bIsAnySpeechPlaying[iCrowdPed]
|
|
|
|
// Was playing dialogue, counters not change
|
|
IF NOT bIsAmbientSpeechPlaying[iCrowdPed]
|
|
iNumberOfPedsCurrentlyPlayingPain++
|
|
iNumberOfPedsCurrentlySpeaking--
|
|
ENDIF
|
|
|
|
ELSE
|
|
iNumberOfPedsCurrentlyPlayingPain++
|
|
ENDIF
|
|
|
|
ELSE
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_DebugLogDialogue )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_DIALOGUE_QUEUE() No alt pain version of this dialogue" )
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
ENDIF
|
|
|
|
ELSE
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_DebugLogDialogue )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_DIALOGUE_QUEUE() Too many speakers, can't play pain audio" )
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
ENDIF
|
|
|
|
ELSE
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_DebugLogDialogue )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_DIALOGUE_QUEUE() Ped already speaking, cant play pain audio" )
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
ENDIF
|
|
|
|
ELSE
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_DebugLogDialogue )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_DIALOGUE_QUEUE() Ped is dead" )
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
ENDIF
|
|
ELSE
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_DebugLogDialogue )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_DIALOGUE_QUEUE() Net id invalid" )
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
ENDIF
|
|
|
|
ELSE
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_DebugLogDialogue )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_DIALOGUE_QUEUE() No dialogue stored" )
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
ENDIF
|
|
|
|
ELSE
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_DebugLogDialogue )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_DIALOGUE_QUEUE() SLOT empty" )
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDFOR
|
|
|
|
// Broadcast dialogue to be played to all clients, if there is something to play
|
|
IF iPackedDialogueConversations[0] != 0
|
|
OR iPackedDialogueConversations[1] != 0
|
|
BROADCAST_FMMC_CC_DIALOGUE_HOST_TO_CLIENTS( iPackedDialogueConversations, iPackedDialogueIsPainFlags )
|
|
ENDIF
|
|
|
|
// Reset client to host data (DO NOT ERASE HostToClient data, otherwise this machine won't play any dialogue locally)
|
|
FOR i = 0 TO iNumCrowdControlPeds-1
|
|
sLocalPedData[i].eDialogueClientToHost = CCDIA_NONE
|
|
CLEAR_BIT_ENUM( sLocalPedData[i].iBitSet, CCLOCALPEDDATA_DialogueClientToHostForcePain )
|
|
CLEAR_BIT_ENUM( sLocalPedData[i].iBitSet, CCLOCALPEDDATA_DialogueClientToHostForceCritical )
|
|
ENDFOR
|
|
|
|
ENDPROC
|
|
|
|
|
|
/// PURPOSE:
|
|
/// Dialogue for each ped that has come in from the host and now needs to be player is played here locally on this machine. Each machine will need to call this in order to process playing the dialogue locally.
|
|
/// PARAMS:
|
|
/// niPeds - array of mission controller peds
|
|
/// iCrowdPedCloudIndex - lookup array used to index crowd control peds
|
|
/// iNumCrowdPeds - number of crowd control peds available
|
|
/// sLocalPedData - local ped data (this will have the received HOST to CLIENT conversations stored )
|
|
/// sLocalData - other local cached data
|
|
PROC PROCESS_CROWD_CONTROL_DIALOGUE_HOST_TO_CLIENT_QUEUE( PED_INDEX ped, CROWD_CONTROL_LOCAL_PED_DATA &sLocalPedData, CROWD_CONTROL_LOCAL_DATA &sLocalData )
|
|
|
|
IF sLocalPedData.eDialogueHostToClient != CCDIA_NONE
|
|
|
|
BOOL bIsAnySpeechPlaying = IS_ANY_SPEECH_PLAYING( ped )
|
|
|
|
BOOL bInterrupt
|
|
IF bIsAnySpeechPlaying
|
|
|
|
// Only interrupt if higher priority and its either critical or is we are interrupting dialogue with pain audio
|
|
IF IS_CROWD_CONTROL_PED_DIALOGUE_PRIORITY( sLocalPedData.eDialogueHostToClient, sLocalPedData.eDialogueCurrentlyPlaying )
|
|
AND ( IS_CROWD_CONTROL_PED_DIALOGUE_CRITICAL( sLocalPedData.eDialogueHostToClient )
|
|
OR ( IS_AMBIENT_SPEECH_PLAYING( ped )
|
|
AND IS_BIT_SET_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_DialogueHostToClientPain ) ) )
|
|
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_PLAYING_LOCAL_DIALOGUE() - IS_ANY_SPEECH_PLAYING() = true, Calling STOP_CURRENT_PLAYING_SPEECH()" )
|
|
|
|
STOP_CURRENT_PLAYING_SPEECH( ped )
|
|
bInterrupt = TRUE
|
|
|
|
ENDIF
|
|
|
|
ELSE
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_PLAYING_LOCAL_DIALOGUE() - IS_ANY_SPEECH_PLAYING() = false, nothing to stop." )
|
|
ENDIF
|
|
|
|
IF NOT bIsAnySpeechPlaying
|
|
OR bInterrupt
|
|
|
|
IF NOT IS_BIT_SET_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_DialogueHostToClientPain )
|
|
|
|
PLAY_CROWD_CONTROL_AMBIENT_SPEECH( ped,
|
|
sLocalPedData.eCreatorAssignedPedID,
|
|
sLocalPedData.eDialogueHostToClient,
|
|
sLocalData.eHeistType, bInterrupt )
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_DebugLogDialogue )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_PLAYING_LOCAL_DIALOGUE() - ",
|
|
GET_CROWD_CONTROL_PED_NAME_FROM_ANIM_ID( sLocalPedData.eCreatorAssignedPedID ),
|
|
" - Played Ambient Speech = ",
|
|
GET_CROWD_CONTROL_DIALOGUE_ENUM_STRING( sLocalPedData.eDialogueHostToClient ) )
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
ELSE
|
|
|
|
AUD_DAMAGE_REASON ePainAudio = GET_CROWD_CONTROL_PED_ALTERNATIVE_PAIN_DIALOGUE( sLocalPedData.eDialogueHostToClient )
|
|
PLAY_PAIN( ped, ePainAudio, 0, FALSE )
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_PLAYING_LOCAL_DIALOGUE() - ",
|
|
GET_CROWD_CONTROL_PED_NAME_FROM_ANIM_ID( sLocalPedData.eCreatorAssignedPedID ),
|
|
" - Played Pain Dialogue = ",
|
|
GET_CROWD_CONTROL_DIALOGUE_ENUM_STRING( sLocalPedData.eDialogueHostToClient ),
|
|
" - Pain Audio = ",
|
|
ePainAudio )
|
|
#ENDIF
|
|
|
|
ENDIF
|
|
|
|
sLocalPedData.eDialogueCurrentlyPlaying = sLocalPedData.eDialogueHostToClient
|
|
|
|
// Reset peds local dialogue data
|
|
sLocalPedData.eDialogueHostToClient = CCDIA_NONE
|
|
CLEAR_BIT_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_DialogueHostToClientPain )
|
|
|
|
ELSE
|
|
|
|
// Keep dialogue until the ped is no longer speaking
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
|
|
PROC PROCESS_CROWD_CONTROL_FEAR( CROWD_CONTROL_SERVER_DATA &sData, CROWD_CONTROL_LOCAL_DATA &sLocalData,
|
|
NETWORK_INDEX &niPeds[], CROWD_CONTROL_PED_DECORATOR_DATA &sPedData[], CROWD_CONTROL_LOCAL_PED_DATA &sLocalPedData[],
|
|
BOOL bRestrictCrowdPed )
|
|
|
|
INT i
|
|
|
|
BOOL bBlockFearDrop
|
|
|
|
// Do not update fear if fear is currently blocked for that rule
|
|
IF IS_BIT_SET_ENUM( sData.iBitSet, CCDATA_FearFailsBlocked )
|
|
CLEAR_BIT_ENUM( sLocalData.iBitSet, CCLOCALDATA_TimerSetFearUnblocked )
|
|
EXIT
|
|
ELSE
|
|
// 2184755
|
|
// also do not update the fear for fleeca for the first 5 seconds of the fear becoming unblocked
|
|
IF sLocalData.eHeistType = CCHEIST_CUSTOM_FLEECA
|
|
IF NOT IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_TimerSetFearUnblocked )
|
|
sLocalData.timeFearFailsUnblocked = GET_NETWORK_TIME()
|
|
SET_BIT_ENUM( sLocalData.iBitSet, CCLOCALDATA_TimerSetFearUnblocked )
|
|
ENDIF
|
|
|
|
IF IS_TIME_LESS_THAN( GET_NETWORK_TIME(), GET_TIME_OFFSET( sLocalData.timeFearFailsUnblocked, 5000 ) )
|
|
bBlockFearDrop = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
PED_INDEX pedsTemp[FMMC_MAX_CROWD_PEDS]
|
|
BOOL bPedInjured[FMMC_MAX_CROWD_PEDS]
|
|
BOOL bHasControl[FMMC_MAX_CROWD_PEDS]
|
|
|
|
// Pre-update
|
|
//----------------------------------------------------------------------------------------------------
|
|
|
|
// Count the number of peds alive left to influence the fear level
|
|
INT iCrowdSize
|
|
FLOAT fInfluenceDirectThreatTotal, fInfluenceShoutingTotal
|
|
|
|
FOR i = 0 TO sData.iNumCrowdControlPeds-1
|
|
INT iPed = sData.iCrowdControlCloudIndex[i]
|
|
IF NETWORK_DOES_ENTITY_EXIST_WITH_NETWORK_ID( niPeds[iPed] )
|
|
|
|
pedsTemp[i] = NET_TO_PED( niPeds[iPed] )
|
|
bPedInjured[i] = IS_PED_INJURED( pedsTemp[i] )
|
|
bHasControl[i] = NETWORK_HAS_CONTROL_OF_NETWORK_ID( niPeds[iPed] )
|
|
|
|
IF NOT bPedInjured[i]
|
|
iCrowdSize++
|
|
fInfluenceDirectThreatTotal += sPedData[i].fInfluenceDirectThreat
|
|
fInfluenceShoutingTotal += sPedData[i].fInfluenceShouting
|
|
ENDIF
|
|
|
|
ELSE
|
|
pedsTemp[i] = NULL
|
|
bPedInjured[i] = FALSE
|
|
ENDIF
|
|
ENDFOR
|
|
|
|
// Work out the deficit of fear and redistribute it to other peds that are no currently being intimidated
|
|
FLOAT fLowerInfluenceThreshold = 0.5 * iCrowdSize
|
|
FLOAT fInfluenceDirectThreatDeficit = FMAX( fLowerInfluenceThreshold - fInfluenceDirectThreatTotal, 0.0 )
|
|
FLOAT fInfluenceShoutingDeficit = FMAX( fLowerInfluenceThreshold - fInfluenceShoutingTotal, 0.0 )
|
|
|
|
// Find the threat we want to use for fear
|
|
//----------------------------------------------------------------------------------------------------
|
|
|
|
CROWD_CONTROL_THREAT_TYPE eThreatUsedForFear[FMMC_MAX_CROWD_PEDS]
|
|
INT iRedistibuteDirectThreatDeficitCount, iRedistributeShoutDeficitCount
|
|
BOOL bShouldUpdateFear[FMMC_MAX_CROWD_PEDS]
|
|
|
|
FOR i = 0 TO sData.iNumCrowdControlPeds-1
|
|
|
|
IF pedsTemp[i] != NULL
|
|
|
|
IF NOT bPedInjured[i]
|
|
|
|
// HOST & OWNER ONLY: Work out this peds contribution to fear change
|
|
IF NETWORK_IS_HOST_OF_THIS_SCRIPT()
|
|
OR bHasControl[i]
|
|
|
|
eThreatUsedForFear[i] = sLocalPedData[i].eBiggestThreat
|
|
|
|
BOOL bPlayingIntro
|
|
IF IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedsTemp[i], CCPANIM_INTRO_LOOP, sLocalPedData[i].eCreatorAssignedPedID, sLocalData.eHeistType, TRUE )
|
|
OR IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedsTemp[i], CCPANIM_INTRO, sLocalPedData[i].eCreatorAssignedPedID, sLocalData.eHeistType, TRUE )
|
|
bPlayingIntro = TRUE
|
|
ENDIF
|
|
|
|
// Don't update this ped's fear while they are forcibly restricted
|
|
IF NOT IS_CROWD_CONTROL_PED_RESTRICTED( sLocalPedData[i].eCreatorAssignedPedID, sLocalData.eHeistType, CCPS_HERO_ATTEMPT, bRestrictCrowdPed )
|
|
// and not until the intro scene has finished
|
|
AND NOT bPlayingIntro
|
|
AND sPedData[i].eState != CCPS_COMBAT
|
|
AND IS_BIT_SET_ENUM( sPedData[i].iBitSet, CCDATA_Active )
|
|
|
|
bShouldUpdateFear[i] = TRUE
|
|
|
|
IF IS_BIT_SET_ENUM( sPedData[i].iBitSet, CCPEDDATA_FearLocked )
|
|
CLEAR_BIT_ENUM( sPedData[i].iBitSet, CCPEDDATA_FearLocked )
|
|
ENDIF
|
|
|
|
// Update ped's fear level
|
|
// Use threat type overrides for different states
|
|
SWITCH sPedData[i].eState
|
|
|
|
CASE CCPS_INVALID
|
|
CASE CCPS_INTRO
|
|
CASE CCPS_HERO
|
|
|
|
// NO FEAR!
|
|
eThreatUsedForFear[i] = CCTHREAT_NONE
|
|
|
|
BREAK
|
|
|
|
CASE CCPS_COWER
|
|
// no override
|
|
BREAK
|
|
|
|
CASE CCPS_FLINCH
|
|
IF eThreatUsedForFear[i] < CCTHREAT_PROXIMITY
|
|
eThreatUsedForFear[i] = CCTHREAT_PROXIMITY
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE CCPS_BEATDOWN
|
|
|
|
// If in the beat down state force the fear to be at least the beating fear
|
|
IF eThreatUsedForFear[i] < CCTHREAT_BEATING
|
|
eThreatUsedForFear[i] = CCTHREAT_BEATING
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE CCPS_HERO_ATTEMPT
|
|
|
|
// Only decrease the fear at this point as we will snap their fear when caught instead
|
|
eThreatUsedForFear[i] = CCTHREAT_NONE
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
// OWNER ONLY: Count the number of peds whos influence should increase
|
|
IF bHasControl[i]
|
|
|
|
IF NOT SHOULD_CROWD_CONTROL_PED_DIRECT_THREAT_INFLUENCE_DECREASE( eThreatUsedForFear[i] )
|
|
iRedistibuteDirectThreatDeficitCount++
|
|
ENDIF
|
|
|
|
IF NOT SHOULD_CROWD_CONTROL_PED_SHOUT_THREAT_INFLUENCE_DECREASE( eThreatUsedForFear[i] )
|
|
iRedistributeShoutDeficitCount++
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ELSE
|
|
// Only mark as locked while not playing the intro
|
|
IF NOT bPlayingIntro
|
|
IF NOT IS_BIT_SET_ENUM( sPedData[i].iBitSet, CCPEDDATA_FearLocked )
|
|
SET_BIT_ENUM( sPedData[i].iBitSet, CCPEDDATA_FearLocked )
|
|
ENDIF
|
|
ELSE
|
|
IF IS_BIT_SET_ENUM( sPedData[i].iBitSet, CCPEDDATA_FearLocked )
|
|
CLEAR_BIT_ENUM( sPedData[i].iBitSet, CCPEDDATA_FearLocked )
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
ENDIF
|
|
ENDFOR
|
|
|
|
// Redistribute any deficit of influence and update the peds fear
|
|
//----------------------------------------------------------------------------------------------------
|
|
|
|
FLOAT fFearDelta
|
|
FLOAT fInfluenceDirectThreatDeficitPerPed = fInfluenceDirectThreatDeficit / iRedistibuteDirectThreatDeficitCount
|
|
FLOAT fInfluenceShoutingDeficitPerPed = fInfluenceShoutingDeficit / iRedistributeShoutDeficitCount
|
|
|
|
FOR i = 0 TO sData.iNumCrowdControlPeds-1
|
|
|
|
IF bShouldUpdateFear[i]
|
|
|
|
IF pedsTemp[i] != NULL
|
|
|
|
IF NOT bPedInjured[i]
|
|
|
|
// OWNER ONLY: Update the influence
|
|
IF bHasControl[i]
|
|
|
|
UPDATE_CROWD_CONTROL_PED_DIRECT_THREAT_INFLUENCE(
|
|
sPedData[i],
|
|
sLocalPedData[i],
|
|
eThreatUsedForFear[i],
|
|
fInfluenceDirectThreatDeficitPerPed )
|
|
|
|
UPDATE_CROWD_CONTROL_PED_SHOUT_THREAT_INFLUENCE(
|
|
sPedData[i],
|
|
sLocalPedData[i],
|
|
eThreatUsedForFear[i],
|
|
fInfluenceShoutingDeficitPerPed )
|
|
|
|
ENDIF
|
|
|
|
// HOST ONLY: Take fear contribution
|
|
IF NETWORK_IS_HOST_OF_THIS_SCRIPT()
|
|
fFearDelta += GET_CROWD_CONTROL_PED_FEAR_DELTA(
|
|
sData,
|
|
sLocalData,
|
|
sPedData[i],
|
|
sLocalPedData[i].pedBiggestThreat,
|
|
eThreatUsedForFear[i],
|
|
i,
|
|
iCrowdSize )
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDFOR
|
|
|
|
// HOST ONLY: calculate new fear value and update broadcast data when possible
|
|
//----------------------------------------------------------------------------------------------------
|
|
|
|
IF NETWORK_IS_HOST_OF_THIS_SCRIPT()
|
|
|
|
IF fFearDelta != 0
|
|
AND ( NOT bBlockFearDrop OR fFearDelta > 0 )
|
|
|
|
FLOAT fChangeRate
|
|
|
|
IF fFearDelta > 0.0
|
|
|
|
// Adjust the change rate in the ranges 0.0 -> 75.0
|
|
FLOAT fRange = 100.0 - cfCC_PedBreakoutCowerThreshold
|
|
FLOAT fAlpha = CLAMP( FMIN( sLocalData.fFear / fRange, 100.0 ), 0.0, 1.0 )
|
|
|
|
// As the fear increases, make the increase rate decrease
|
|
fChangeRate = INTERP_FLOAT( cfCC_FearIncreaseRateMax, cfCC_FearIncreaseRateMin, fAlpha )
|
|
|
|
ELIF fFearDelta < 0.0
|
|
|
|
// Adjust the change rate in the ranges 25.0 -> 100.0
|
|
FLOAT fRange = 100.0 - cfCC_PedBreakoutCowerThreshold
|
|
FLOAT fAlpha = CLAMP( FMAX( sLocalData.fFear - cfCC_PedBreakoutCowerThreshold, 0.0 ) / fRange, 0.0, 1.0 )
|
|
|
|
// As the fear decreases, make the decrease rate decrease
|
|
fChangeRate = INTERP_FLOAT( cfCC_FearDecreaseRateMin, cfCC_FearDecreaseRateMax, fAlpha )
|
|
|
|
ENDIF
|
|
|
|
// Adjust for ACCEL/DECEL
|
|
fFearDelta *= fChangeRate
|
|
|
|
// Adjust for framerate
|
|
fFearDelta *= TIMESTEP()
|
|
|
|
// Apply the fear change
|
|
sLocalData.fFear = CLAMP( sLocalData.fFear + fFearDelta, 0.0, 100.0 )
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
|
|
|
|
// HOST
|
|
BOOL bFearUpdated
|
|
IF NETWORK_IS_HOST_OF_THIS_SCRIPT()
|
|
|
|
// Check if we can update the server fear value
|
|
IF ( sLocalData.fFear != sData.fFear AND sLocalData.iUpdateTimer >= 10 ) // values are different but wait for at least 10 frames to have elapsed since previous update
|
|
OR ABSF( sData.fFear - sLocalData.fFear ) >= 3.0 // difference is greater than 3%, update now
|
|
|
|
// Update the server fear value
|
|
sData.fFear = sLocalData.fFear
|
|
bFearUpdated = TRUE
|
|
|
|
sLocalData.iUpdateTimer = 0 // reset the timer
|
|
ELSE
|
|
sLocalData.iUpdateTimer++ // increment timer
|
|
ENDIF
|
|
|
|
// REMOTE
|
|
ELSE
|
|
|
|
// Server value differs to ours
|
|
IF sData.fFear != sLocalData.fFear
|
|
|
|
// pull the updated value from the server
|
|
sLocalData.fFear = sData.fFear
|
|
bFearUpdated = TRUE
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
|
|
// An update has occurred on the host or a remote player, update interpolation rate
|
|
IF bFearUpdated
|
|
sLocalData.fIntimidationBarInterpRate = ABSF( sLocalData.fIntimidationBar - sLocalData.fFear )
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
|
|
PROC PROCESS_CROWD_CONTROL_PED_AI( PED_INDEX pedCrowd,
|
|
CROWD_CONTROL_SERVER_DATA &sCrowdControlData, CROWD_CONTROL_LOCAL_DATA &sLocalData,
|
|
CROWD_CONTROL_PED_DECORATOR_DATA &sCrowdControlPedData, CROWD_CONTROL_LOCAL_PED_DATA &sLocalPedData,
|
|
INT iPed, INT iCrowdStructID, BOOL bRestrictCrowdPed, BOOL bIsInjured )
|
|
|
|
IF IS_BIT_SET_ENUM( sCrowdControlPedData.iBitSet, CCPEDDATA_HasBeenInitialised )
|
|
|
|
CROWD_CONTROL_THREAT_TYPE eThreatActual = sLocalPedData.eBiggestThreat
|
|
CROWD_CONTROL_THREAT_TYPE eThreatFelt = sLocalPedData.eBiggestThreat
|
|
|
|
// Ped state
|
|
//------------------------------------------------
|
|
|
|
// Ped has been killed
|
|
IF IS_BIT_SET_ENUM( sCrowdControlPedData.iBitSet, CCPEDDATA_Dead )
|
|
OR ( DOES_ENTITY_EXIST( pedCrowd ) AND bIsInjured )
|
|
|
|
IF NOT IS_BIT_SET_ENUM( sCrowdControlPedData.iBitSet, CCPEDDATA_KnockedOut )
|
|
|
|
IF NOT IS_BIT_SET_ENUM( sCrowdControlPedData.iBitSet, CCPEDDATA_Dead )
|
|
sLocalPedData.timeDied = GET_NETWORK_TIME()
|
|
SET_BIT_ENUM( sCrowdControlPedData.iBitSet, CCPEDDATA_Dead )
|
|
ENDIF
|
|
|
|
IF NOT IS_BIT_SET_ENUM( sCrowdControlPedData.iBitSet, CCPEDDATA_DeadProcessed )
|
|
IF NETWORK_IS_HOST_OF_THIS_SCRIPT()
|
|
sCrowdControlData.iNumHitsRemaining -= ciCC_BeatdownHitsLostOnPedDeath
|
|
ELSE
|
|
BROADCAST_FMMC_CC_PED_BEATDOWN_HIT( -ciCC_BeatdownHitsLostOnPedDeath )
|
|
ENDIF
|
|
SET_BIT_ENUM( sCrowdControlPedData.iBitSet, CCPEDDATA_DeadProcessed )
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
|
|
// Hero details
|
|
//------------------------------------------------
|
|
|
|
CROWD_CONTROL_PED_HERO_ACTION eHeroAction = CCHERO_NONE
|
|
|
|
// Animated hero
|
|
//IF IS_BIT_SET_ENUM( sCrowdControlPedData.iBitSet, CCPEDDATA_RunningBespokeAnims )
|
|
IF DOES_CROWD_CONTROL_PED_HAVE_ANIM( CCPANIM_HERO_START, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
|
|
eHeroAction = GET_CROWD_CONTROL_PED_HERO_ACTION_FOR_ANIMATED_PED( sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
|
|
// None anim hero (set by content creators)
|
|
ELSE
|
|
|
|
eHeroAction = INT_TO_ENUM( CROWD_CONTROL_PED_HERO_ACTION, g_FMMC_STRUCT_ENTITIES.sPlacedPed[iPed].iCrowdControlAction )
|
|
IF eHeroAction = CCHERO_ALARM
|
|
eHeroAction = CCHERO_NONE
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
// Reset hero attempted flag if this ped is no longer a hero
|
|
IF IS_BIT_SET_ENUM( sCrowdControlPedData.iBitSet, CCPEDDATA_HeroAttempted )
|
|
IF NOT IS_BIT_SET( sCrowdControlData.iCurrentActiveHeros, iCrowdStructID )
|
|
CLEAR_BIT_ENUM( sCrowdControlPedData.iBitSet, CCPEDDATA_HeroAttempted )
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Fail checks
|
|
//------------------------------------------------
|
|
|
|
// While crowd control is active and no other fail has already occured
|
|
// Also don't fail if we have already passed
|
|
IF IS_BIT_SET_ENUM( sCrowdControlData.iBitSet, CCDATA_Active )
|
|
AND NOT IS_BIT_SET_ENUM( sCrowdControlData.iBitSet, CCDATA_Failed )
|
|
AND NOT IS_BIT_SET_ENUM( sCrowdControlData.iBitSet, CCDATA_FailDisabled )
|
|
AND sLocalData.eFailReason = CCFAIL_NONE
|
|
|
|
IF IS_BIT_SET_ENUM( sCrowdControlPedData.iBitSet, CCPEDDATA_HeroComplete )
|
|
|
|
IF IS_BIT_SET_ENUM( sCrowdControlPedData.iBitSet, CCPEDDATA_Dead )
|
|
|
|
IF eHeroAction = CCHERO_GUN
|
|
sLocalData.eFailReason = CCFAIL_PEDHEROGUN
|
|
sLocalData.iFailCausedByPed = iPed
|
|
sLocalData.timeFailDelay = GET_TIME_OFFSET( GET_NETWORK_TIME(), 5000 )
|
|
ENDIF
|
|
|
|
ELSE
|
|
|
|
SWITCH eHeroAction
|
|
CASE CCHERO_PHONE
|
|
sLocalData.eFailReason = CCFAIL_PEDHEROPHONE
|
|
sLocalData.iFailCausedByPed = iPed
|
|
sLocalData.timeFailDelay = GET_TIME_OFFSET( GET_NETWORK_TIME(), 5000 )
|
|
BREAK
|
|
CASE CCHERO_ALARM
|
|
sLocalData.eFailReason = CCFAIL_PEDHEROALARM
|
|
sLocalData.iFailCausedByPed = sLocalData.iCashierPed
|
|
sLocalData.timeFailDelay = GET_NETWORK_TIME() // no delay
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
CPRINTLN(DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_PED_AI() - [", iCrowdStructID,"] FAIL CHECKS - HeroComplete = ", GET_CROWD_CONTROL_HERO_ACTION( eHeroAction ) )
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
// A fail has been set locally & broadcast it
|
|
IF sLocalData.eFailReason != CCFAIL_NONE
|
|
|
|
// If we are the server set the server data to indicate a fail
|
|
IF NETWORK_IS_HOST_OF_THIS_SCRIPT()
|
|
SET_BIT_ENUM( sCrowdControlData.iBitSet, CCDATA_Failed )
|
|
ENDIF
|
|
|
|
CPRINTLN(DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_PED_AI() - [", iCrowdStructID,"] FAIL DETECTED - Fail Reason = ", GET_CROWD_CONTROL_FAIL_REASON_STRING( sLocalData.eFailReason ) )
|
|
BROADCAST_FMMC_CC_FAIL( ENUM_TO_INT( sLocalData.eFailReason ), sLocalData.iFailCausedByPed, sLocalData.timeFailDelay )
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
// Check to see if the a hero peds prop(phone) has been broken
|
|
// IF NOT IS_BIT_SET( sCrowdControlPedData.iBitSet, CCPEDDATA_HeroBroken )
|
|
// IF NETWORK_DOES_ENTITY_EXIST_WITH_NETWORK_ID( sCrowdControlPedData.niProp )
|
|
// IF HAS_ENTITY_BEEN_DAMAGED_BY_ANY_PED( NET_TO_OBJ( sCrowdControlPedData.niProp ) )
|
|
// SET_BIT( sCrowdControlPedData.iBitSet, CCPEDDATA_HeroBroken )
|
|
// ENDIF
|
|
// ENDIF
|
|
// ENDIF
|
|
|
|
|
|
// Update Ped
|
|
//------------------------------------------------
|
|
|
|
IF DOES_ENTITY_EXIST( pedCrowd )
|
|
AND NOT bIsInjured
|
|
|
|
FLOAT fCapSize
|
|
fCapSize = GET_CROWD_CONTROL_PED_CAPSULE_SIZE( sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
IF fCapSize != -1
|
|
SET_PED_CAPSULE( pedCrowd, fCapSize )
|
|
ENDIF
|
|
|
|
// Check here if the ped should get knocked out of the animated state and go to AI logic
|
|
IF IS_BIT_SET_ENUM( sCrowdControlPedData.iBitSet, CCPEDDATA_RunningBespokeAnims )
|
|
|
|
SET_PED_RESET_FLAG( pedCrowd, PRF_PreventAllMeleeTakedowns, TRUE )
|
|
SET_PED_RESET_FLAG( pedCrowd, PRF_DisableMeleeHitReactions, TRUE )
|
|
|
|
// Any ped has shot or hurt the ped to kick them out of their anim.
|
|
IF HAS_ENTITY_BEEN_DAMAGED_BY_ANY_PED( pedCrowd )
|
|
|
|
CLEAR_BIT_ENUM( sCrowdControlPedData.iBitSet, CCPEDDATA_RunningBespokeAnims )
|
|
//sCrowdControlPedData.eState = CCPS_COWER
|
|
SET_CROWD_CONTROL_PED_STATE( sCrowdControlPedData, CCPS_COWER, iCrowdStructID, sLocalPedData.eCreatorAssignedPedID )
|
|
|
|
IF NOT HAS_ENTITY_BEEN_DAMAGED_BY_WEAPON( pedCrowd, WEAPONTYPE_SMOKEGRENADE )
|
|
AND NOT HAS_ENTITY_BEEN_DAMAGED_BY_WEAPON( pedCrowd, WEAPONTYPE_BZGAS )
|
|
CLEAR_PED_TASKS( pedCrowd )
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
// Threat
|
|
//--------------------------------------------------------------------------------------------
|
|
|
|
// Update last time shot at
|
|
IF eThreatActual != CCTHREAT_SHOOTING
|
|
AND eThreatActual != CCTHREAT_SHOOTING_CLOSE
|
|
|
|
IF NOT IS_BIT_SET_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_TimeLastShotAtSet )
|
|
sLocalPedData.timeLastShotAt = GET_NETWORK_TIME()
|
|
SET_BIT_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_TimeLastShotAtSet )
|
|
ENDIF
|
|
|
|
ELSE
|
|
|
|
IF eThreatActual = CCTHREAT_SHOOTING
|
|
CLEAR_BIT_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_ShotAtFearWasClose )
|
|
ELIF eThreatActual = CCTHREAT_SHOOTING_CLOSE
|
|
SET_BIT_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_ShotAtFearWasClose )
|
|
ENDIF
|
|
|
|
CLEAR_BIT_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_TimeLastShotAtSet )
|
|
|
|
ENDIF
|
|
|
|
|
|
// Update projectile fear timer
|
|
|
|
// Don't start the timer if the threat is a sticky bomb and this ped is set to ignore sticky bombs
|
|
IF ( NOT IS_BIT_SET_ENUM( sCrowdControlPedData.iBitSet, CCPEDDATA_IgnoreStickyBombs )
|
|
AND eThreatActual = CCTHREAT_PROJECTILE_EXPLOSIVE_STICKY_BOMB )
|
|
OR eThreatActual = CCTHREAT_PROJECTILE_EXPLOSIVE
|
|
|
|
IF NOT IS_BIT_SET_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_TimeSetStartFearProjectile )
|
|
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_PED_AI() - [", iCrowdStructID,"] Projectile fear time stored" )
|
|
|
|
SET_BIT_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_TimeSetStartFearProjectile )
|
|
sLocalPedData.timeStartProjectileFear = GET_NETWORK_TIME()
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
// Update proxmity fear timer
|
|
|
|
IF eThreatActual = CCTHREAT_PROXIMITY
|
|
|
|
IF NOT IS_BIT_SET_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_TimeSetStartProximityThreat )
|
|
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_PED_AI() - [", iCrowdStructID,"] Proximity fear time stored" )
|
|
|
|
sLocalPedData.timeStartProximityThreat = GET_NETWORK_TIME()
|
|
SET_BIT_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_TimeSetStartProximityThreat )
|
|
|
|
ENDIF
|
|
|
|
ELSE
|
|
IF IS_BIT_SET_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_TimeSetStartProximityThreat )
|
|
CLEAR_BIT_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_TimeSetStartProximityThreat )
|
|
ENDIF
|
|
ENDIF
|
|
|
|
|
|
// Fear overrides
|
|
IF IS_BIT_SET_ENUM( sCrowdControlData.iBitSet, CCDATA_Active )
|
|
|
|
// Shooting fear adjustments
|
|
// IF IS_BIT_SET_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_ShotAtFearWasClose )
|
|
//
|
|
// IF eThreatFelt < CCTHREAT_SHOOTING_CLOSE
|
|
//
|
|
// IF NOT IS_BIT_SET_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_TimeLastShotAtSet )
|
|
// OR IS_TIME_LESS_THAN( GET_NETWORK_TIME(), GET_TIME_OFFSET( sLocalPedData.timeLastShotAt, ciCC_PedShotAtCoolOffDurationClose ) )
|
|
//
|
|
// eThreatFelt = CCTHREAT_SHOOTING_CLOSE
|
|
//
|
|
// ENDIF
|
|
//
|
|
// ENDIF
|
|
//
|
|
// ELSE
|
|
|
|
IF eThreatFelt < CCTHREAT_SHOOTING
|
|
IF NOT IS_BIT_SET_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_TimeLastShotAtSet )
|
|
OR IS_TIME_LESS_THAN( GET_NETWORK_TIME(), GET_TIME_OFFSET( sLocalPedData.timeLastShotAt, ciCC_PedShotAtCoolOffDuration ) )
|
|
|
|
eThreatFelt = CCTHREAT_SHOOTING
|
|
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// ENDIF
|
|
|
|
|
|
// Projectile fear adjustments
|
|
IF IS_BIT_SET_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_TimeSetStartFearProjectile )
|
|
|
|
// Keep the ped scared of the projectile for a period of time
|
|
IF IS_TIME_LESS_THAN( GET_NETWORK_TIME(),
|
|
GET_TIME_OFFSET( sLocalPedData.timeStartProjectileFear, ciCC_ProjectileCoolOffDuration ) )
|
|
|
|
IF eThreatFelt <= CCTHREAT_PROJECTILE_EXPLOSIVE
|
|
eThreatFelt = CCTHREAT_PROJECTILE_EXPLOSIVE
|
|
ENDIF
|
|
|
|
// Timer has run out and the threat was a sticky bomb, set this ped to ignore them from now on
|
|
ELSE
|
|
|
|
IF eThreatFelt = CCTHREAT_PROJECTILE_EXPLOSIVE_STICKY_BOMB
|
|
SET_BIT_ENUM( sCrowdControlPedData.iBitSet, CCPEDDATA_IgnoreStickyBombs )
|
|
ENDIF
|
|
|
|
// only reset the timer if theres no longer a projectile threat
|
|
IF eThreatFelt != CCTHREAT_PROJECTILE_EXPLOSIVE
|
|
CLEAR_BIT_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_TimeSetStartFearProjectile )
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
// Proximity fear adjustment
|
|
IF IS_BIT_SET_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_TimeSetStartProximityThreat )
|
|
|
|
IF IS_TIME_MORE_THAN( GET_NETWORK_TIME(),
|
|
GET_TIME_OFFSET( sLocalPedData.timeStartProximityThreat, ciCC_ProximityCoolOffDuration ) )
|
|
|
|
IF eThreatFelt = CCTHREAT_PROXIMITY
|
|
eThreatFelt = CCTHREAT_NONE
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
// Update last time threatened
|
|
IF eThreatFelt = CCTHREAT_NONE
|
|
//AND sCrowdControlPedData.eState != CCPS_FLINCH
|
|
AND sCrowdControlPedData.eState != CCPS_BEATDOWN
|
|
IF NOT IS_BIT_SET_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_TimeLastThreatenedSet )
|
|
sLocalPedData.timeLastThreatened = GET_NETWORK_TIME()
|
|
SET_BIT_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_TimeLastThreatenedSet )
|
|
ENDIF
|
|
ELSE
|
|
CLEAR_BIT_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_TimeLastThreatenedSet )
|
|
ENDIF
|
|
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
// Store out for debug rendering
|
|
sLocalPedData.eDebugThreatFelt = eThreatFelt
|
|
#ENDIF
|
|
|
|
// Brain
|
|
//------------------------------------------------
|
|
|
|
// Cancel look at while flinching or being beat
|
|
IF sCrowdControlPedData.eState = CCPS_FLINCH
|
|
OR sCrowdControlPedData.eState = CCPS_FLINCH_UNDERFIRE
|
|
OR sCrowdControlPedData.eState = CCPS_BEATDOWN
|
|
|
|
TASK_CLEAR_LOOK_AT( pedCrowd )
|
|
|
|
// Look at potential threat regardless of wheather they are threatening at the time
|
|
ELIF sCrowdControlPedData.eState != CCPS_INTRO
|
|
|
|
IF NOT IS_SCRIPT_TASK_RUNNING_OR_STARTING( pedCrowd, SCRIPT_TASK_LOOK_AT_ENTITY )
|
|
TASK_LOOK_AT_ENTITY( pedCrowd, sLocalPedData.pedBiggestThreat, -1, SLF_WHILE_NOT_IN_FOV | SLF_NARROWEST_YAW_LIMIT )
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
BOOL bSafeToTransition
|
|
|
|
|
|
// Start beating
|
|
IF sCrowdControlPedData.eState != CCPS_BEATDOWN
|
|
|
|
IF IS_BIT_SET_ENUM( sLocalPedData.iBitset, CCLOCALPEDDATA_BeatdownFired )
|
|
|
|
// Set the number of hits this ped can take this round
|
|
sCrowdControlPedData.iBeatdownHitsRemaining = CLAMP_INT( ciCC_MaxBeatdownHits - sCrowdControlPedData.iBeatdownRounds, 1, ciCC_MaxBeatdownHits )
|
|
sCrowdControlPedData.iBeatdownRounds++
|
|
|
|
// Take 1 off for the first hit
|
|
sCrowdControlPedData.iBeatdownHitsRemaining--
|
|
|
|
BROADCAST_FMMC_CC_PED_BEATDOWN_CLEAR( iCrowdStructID )
|
|
CLEAR_BIT_ENUM( sLocalPedData.iBitset, CCLOCALPEDDATA_BeatdownFired )
|
|
|
|
SET_CROWD_CONTROL_PED_STATE( sCrowdControlPedData, CCPS_BEATDOWN, iCrowdStructID, sLocalPedData.eCreatorAssignedPedID )
|
|
|
|
ENDIF
|
|
|
|
// Already in beating
|
|
ELSE
|
|
|
|
IF IS_BIT_SET_ENUM( sLocalPedData.iBitset, CCLOCALPEDDATA_BeatdownFired )
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF NOT IS_BIT_SET_ENUM( sCrowdControlData.iBitSet, CCDATA_DebugUnlimitedBeatings )
|
|
#ENDIF
|
|
|
|
// Beatdown loop -> Beatdown hit a/b -> Beatdown loop
|
|
IF sCrowdControlPedData.iBeatdownHitsRemaining > 0
|
|
|
|
sCrowdControlPedData.iBeatdownHitsRemaining--
|
|
|
|
// Beatdown loop -> Beatdown die -> Beatdown die loop
|
|
ELSE
|
|
|
|
SET_BIT_ENUM( sCrowdControlPedData.iBitSet, CCPEDDATA_KnockedOut )
|
|
sLocalPedData.timeDied = GET_NETWORK_TIME()
|
|
sCrowdControlPedData.iBeatdownHitsRemaining = 0
|
|
|
|
ENDIF
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
BROADCAST_FMMC_CC_PED_BEATDOWN_CLEAR( iCrowdStructID )
|
|
CLEAR_BIT_ENUM( sLocalPedData.iBitset, CCLOCALPEDDATA_BeatdownFired )
|
|
|
|
// Playing the loop, wait until the threat has finished then start the timer
|
|
ELIF eThreatFelt = CCTHREAT_NONE
|
|
AND IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_BEATDOWN_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
|
|
IF NOT IS_BIT_SET_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_TimeLastBeatSet )
|
|
sLocalPedData.timeLastBeat = GET_NETWORK_TIME()
|
|
SET_BIT_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_TimeLastBeatSet )
|
|
ENDIF
|
|
|
|
IF IS_BIT_SET_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_TimeLastBeatSet )
|
|
AND IS_TIME_MORE_THAN( GET_NETWORK_TIME(), GET_TIME_OFFSET( sLocalPedData.timeLastBeat, 3000 ) )
|
|
//sCrowdControlPedData.eState = CCPS_FLINCH
|
|
SET_CROWD_CONTROL_PED_STATE( sCrowdControlPedData, CCPS_FLINCH, iCrowdStructID, sLocalPedData.eCreatorAssignedPedID )
|
|
ENDIF
|
|
|
|
ELSE
|
|
|
|
CLEAR_BIT_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_TimeLastBeatSet )
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
|
|
SWITCH sCrowdControlPedData.eState
|
|
|
|
CASE CCPS_INTRO
|
|
|
|
// Crowd has been activated
|
|
IF IS_BIT_SET_ENUM( sCrowdControlData.iBitSet, CCDATA_Active )
|
|
// this ped has been threatened
|
|
OR eThreatActual != CCTHREAT_NONE
|
|
// this ped has been attacked
|
|
OR HAS_ENTITY_BEEN_DAMAGED_BY_ANY_PED( pedCrowd )
|
|
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_PED_AI() - [", iCrowdStructID,"] CCPS_INTRO going to CCPS_COWER - CCDATA_Active: ", BOOL_TO_STRING( IS_BIT_SET_ENUM( sCrowdControlData.iBitSet, CCDATA_Active ) ), " WasThreatened?: ", BOOL_TO_STRING( eThreatActual != CCTHREAT_NONE ) )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, " - Threat felt = ", GET_CROWD_CONTROL_THREAT_TYPE_STRING( eThreatActual ), "\n" )
|
|
|
|
// Set a random start delay for broadcasting dialogue, this is to help avoid synchronised screaming and dialogue
|
|
// by stopping all the dialogue kicking off in the same frame.
|
|
sLocalPedData.timeDialogueLastBroadcast = GET_TIME_OFFSET( GET_NETWORK_TIME(), ( GET_RANDOM_INT_IN_RANGE( 0, 11 ) * 50 ) ) // 0 -> 0.5 seconds (50ms intervals)
|
|
|
|
//sCrowdControlPedData.eState = CCPS_COWER
|
|
SET_CROWD_CONTROL_PED_STATE( sCrowdControlPedData, CCPS_COWER, iCrowdStructID, sLocalPedData.eCreatorAssignedPedID )
|
|
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE CCPS_COWER
|
|
|
|
IF IS_BIT_SET_ENUM( sCrowdControlPedData.iBitset, CCPEDDATA_RunningBespokeAnims )
|
|
//IF HAS_CROWD_CONTROL_PED_FINISHED_ANIM( pedCrowd, CCPANIM_INTRO, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType, DEFAULT, TRUE, sCrowdControlData.iSyncScene, HASH( "Event" ) )
|
|
IF IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_COWER_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
OR IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_FLINCH_TO_IDLE_OUTRO, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
bSafeToTransition = TRUE
|
|
ENDIF
|
|
ELSE
|
|
bSafeToTransition = TRUE
|
|
ENDIF
|
|
|
|
IF bSafeToTransition
|
|
|
|
// Use a timer to make sure the player has aimed at a ped and not just moved their aim past them
|
|
IF eThreatActual = CCTHREAT_AIMED_AT
|
|
|
|
IF NOT IS_BIT_SET_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_TimeSetStartThreaten )
|
|
|
|
// 250ms + random 0-250ms increments of 50ms
|
|
sLocalPedData.timeStartThreaten = GET_TIME_OFFSET( GET_NETWORK_TIME(), 250 + ( GET_RANDOM_INT_IN_RANGE(0, 6 ) * 50 ) )
|
|
SET_BIT_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_TimeSetStartThreaten )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_PED_AI() - [", iCrowdStructID,"] Escape/Hero attempt threat react timer started" )
|
|
|
|
ENDIF
|
|
|
|
ELSE
|
|
CLEAR_BIT_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_TimeSetStartThreaten )
|
|
ENDIF
|
|
|
|
// Every threat is instant apart from aiming at, this is so the player can't just spin or weave there aim over peds quickly to keep their fear up
|
|
IF eThreatFelt != CCTHREAT_NONE
|
|
|
|
IF ( eThreatFelt != CCTHREAT_AIMED_AT
|
|
OR ( eThreatFelt = CCTHREAT_AIMED_AT
|
|
AND IS_BIT_SET_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_TimeSetStartThreaten )
|
|
AND IS_TIME_MORE_THAN( GET_NETWORK_TIME(), sLocalPedData.timeStartThreaten ) ) )
|
|
|
|
SWITCH eThreatFelt
|
|
CASE CCTHREAT_SHOOTING_CLOSE
|
|
QUEUE_CROWD_CONTROL_DIALOGUE_CLIENT_TO_HOST( sLocalData, sLocalPedData, CCDIA_SHOT_DIRECTLY_AT, CCDIAPLAYBACK_FORCE_PAIN | CCDIAPLAYBACK_FORCE_CRITICAL )
|
|
BREAK
|
|
CASE CCTHREAT_SHOOTING
|
|
QUEUE_CROWD_CONTROL_DIALOGUE_CLIENT_TO_HOST( sLocalData, sLocalPedData, CCDIA_SHOT_NEAR, CCDIAPLAYBACK_FORCE_PAIN | CCDIAPLAYBACK_FORCE_CRITICAL )
|
|
BREAK
|
|
CASE CCTHREAT_AIMED_AT
|
|
CASE CCTHREAT_PROJECTILE_EXPLOSIVE
|
|
CASE CCTHREAT_PROJECTILE_EXPLOSIVE_STICKY_BOMB
|
|
QUEUE_CROWD_CONTROL_DIALOGUE_CLIENT_TO_HOST( sLocalData, sLocalPedData, CCDIA_RECEIVES_SCARE, CCDIAPLAYBACK_FORCE_PAIN | CCDIAPLAYBACK_FORCE_CRITICAL )
|
|
BREAK
|
|
DEFAULT
|
|
QUEUE_CROWD_CONTROL_DIALOGUE_CLIENT_TO_HOST( sLocalData, sLocalPedData, CCDIA_APPROACH, CCDIAPLAYBACK_FORCE_PAIN | CCDIAPLAYBACK_FORCE_CRITICAL )
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
IF eThreatFelt = CCTHREAT_SHOOTING_CLOSE
|
|
SET_CROWD_CONTROL_PED_STATE( sCrowdControlPedData, CCPS_FLINCH_UNDERFIRE, iCrowdStructID, sLocalPedData.eCreatorAssignedPedID )
|
|
CLEAR_BIT_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_TimeSetShootingCloseFlinching )
|
|
ELSE
|
|
SET_CROWD_CONTROL_PED_STATE( sCrowdControlPedData, CCPS_FLINCH, iCrowdStructID, sLocalPedData.eCreatorAssignedPedID )
|
|
ENDIF
|
|
|
|
CLEAR_BIT_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_TimeSetStartThreaten )
|
|
|
|
ENDIF
|
|
|
|
// Fear level dropped, attempt to escape
|
|
ELIF sLocalData.fIntimidationBar < cfCC_PedBreakoutCowerThreshold
|
|
AND eThreatActual = CCTHREAT_NONE
|
|
AND IS_BIT_SET_ENUM( sCrowdControlPedData.iBitset, CCPEDDATA_RunningBespokeAnims ) // can only transition to this if ped is playing anims
|
|
|
|
// Is a valid hero & the minigame's not failed
|
|
IF eHeroAction != CCHERO_NONE AND IS_BIT_SET( sCrowdControlData.iCurrentActiveHeros, iCrowdStructID )
|
|
AND IS_CROWD_CONTROL_PED_A_VALID_HERO( sCrowdControlPedData, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType, bRestrictCrowdPed )
|
|
AND NOT IS_BIT_SET_ENUM( sCrowdControlData.iBitset, CCDATA_Failed )
|
|
|
|
SWITCH eHeroAction
|
|
CASE CCHERO_ALARM
|
|
QUEUE_CROWD_CONTROL_DIALOGUE_CLIENT_TO_HOST( sLocalData, sLocalPedData, CCDIA_HERO_ALARM_START )
|
|
BREAK
|
|
CASE CCHERO_PHONE
|
|
QUEUE_CROWD_CONTROL_DIALOGUE_CLIENT_TO_HOST( sLocalData, sLocalPedData, CCDIA_HERO_PHONE_START )
|
|
BREAK
|
|
CASE CCHERO_GUN
|
|
QUEUE_CROWD_CONTROL_DIALOGUE_CLIENT_TO_HOST( sLocalData, sLocalPedData, CCDIA_HERO_GUN_START )
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
CPRINTLN(DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_PED_AI() - [", iCrowdStructID,"] CCPS_COWER going to CCPS_HERO_ATTEMPT")
|
|
SET_BIT_ENUM( sCrowdControlPedData.iBitSet, CCPEDDATA_HeroAttempted )
|
|
//sCrowdControlPedData.eState = CCPS_HERO_ATTEMPT
|
|
SET_CROWD_CONTROL_PED_STATE( sCrowdControlPedData, CCPS_HERO_ATTEMPT, iCrowdStructID, sLocalPedData.eCreatorAssignedPedID )
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE CCPS_FLINCH
|
|
|
|
// Is it safe to transition out of this state?
|
|
IF IS_BIT_SET_ENUM( sCrowdControlPedData.iBitset, CCPEDDATA_RunningBespokeAnims )
|
|
|
|
IF IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_FLINCH_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
bSafeToTransition = TRUE
|
|
ENDIF
|
|
|
|
ELSE
|
|
bSafeToTransition = TRUE
|
|
ENDIF
|
|
|
|
|
|
IF eThreatFelt = CCTHREAT_SHOOTING_CLOSE
|
|
|
|
QUEUE_CROWD_CONTROL_DIALOGUE_CLIENT_TO_HOST( sLocalData, sLocalPedData, CCDIA_SHOT_DIRECTLY_AT, CCDIAPLAYBACK_FORCE_PAIN | CCDIAPLAYBACK_FORCE_CRITICAL )
|
|
|
|
SET_CROWD_CONTROL_PED_STATE( sCrowdControlPedData, CCPS_FLINCH_UNDERFIRE, iCrowdStructID, sLocalPedData.eCreatorAssignedPedID )
|
|
CLEAR_BIT_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_TimeSetShootingCloseFlinching )
|
|
|
|
// No threat, go back to regular cower
|
|
ELIF bSafeToTransition
|
|
|
|
IF eThreatFelt = CCTHREAT_NONE
|
|
// 2121009 - removed as part of this bug in order to get a more immediate response.
|
|
// UNDONE now we have new anims to go in
|
|
AND ( NOT IS_BIT_SET_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_TimeLastThreatenedSet )
|
|
OR IS_TIME_MORE_THAN( GET_NETWORK_TIME(), GET_TIME_OFFSET( sLocalPedData.timeLastThreatened, 5000 ) ) )
|
|
AND ( NOT IS_BIT_SET_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_TimeLastShotAtSet )
|
|
OR IS_TIME_MORE_THAN( GET_NETWORK_TIME(), GET_TIME_OFFSET( sLocalPedData.timeLastShotAt, 8000 ) ) )
|
|
|
|
SET_CROWD_CONTROL_PED_STATE( sCrowdControlPedData, CCPS_COWER, iCrowdStructID, sLocalPedData.eCreatorAssignedPedID )
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE CCPS_FLINCH_UNDERFIRE
|
|
|
|
// Is it safe to transition out of this state?
|
|
IF IS_BIT_SET_ENUM( sCrowdControlPedData.iBitset, CCPEDDATA_RunningBespokeAnims )
|
|
|
|
IF IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_FLINCH_UNDERFIRE_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
|
|
IF NOT IS_BIT_SET_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_TimeSetShootingCloseFlinching )
|
|
sLocalPedData.timeShootingCloseFlinchingStarted = GET_NETWORK_TIME()
|
|
SET_BIT_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_TimeSetShootingCloseFlinching )
|
|
ENDIF
|
|
|
|
// Minimum 1 second of frantic flinching
|
|
IF IS_TIME_MORE_THAN( GET_NETWORK_TIME(), GET_TIME_OFFSET( sLocalPedData.timeShootingCloseFlinchingStarted, 1000 ) )
|
|
bSafeToTransition = TRUE
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ELSE
|
|
bSafeToTransition = TRUE
|
|
ENDIF
|
|
|
|
IF bSafeToTransition
|
|
|
|
IF eThreatFelt != CCTHREAT_SHOOTING_CLOSE
|
|
SET_CROWD_CONTROL_PED_STATE( sCrowdControlPedData, CCPS_FLINCH, iCrowdStructID, sLocalPedData.eCreatorAssignedPedID )
|
|
CLEAR_BIT_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_TimeSetShootingCloseFlinching )
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE CCPS_BEATDOWN
|
|
|
|
// see top of switch for this logic
|
|
|
|
BREAK
|
|
|
|
CASE CCPS_HERO_ATTEMPT
|
|
|
|
// Any threat to the ped, instant response
|
|
IF eThreatFelt != CCTHREAT_NONE
|
|
// Hero prop damaged
|
|
OR IS_BIT_SET_ENUM( sCrowdControlPedData.iBitSet, CCPEDDATA_HeroBroken )
|
|
|
|
CLEAR_BIT_ENUM( sCrowdControlPedData.iBitSet, CCLOCALPEDDATA_TimeSetHoldBeforeEscape )
|
|
|
|
SWITCH eHeroAction
|
|
CASE CCHERO_ALARM
|
|
QUEUE_CROWD_CONTROL_DIALOGUE_CLIENT_TO_HOST( sLocalData, sLocalPedData, CCDIA_HERO_ALARM_CAUGHT )
|
|
BREAK
|
|
CASE CCHERO_PHONE
|
|
QUEUE_CROWD_CONTROL_DIALOGUE_CLIENT_TO_HOST( sLocalData, sLocalPedData, CCDIA_HERO_PHONE_CAUGHT )
|
|
BREAK
|
|
CASE CCHERO_GUN
|
|
QUEUE_CROWD_CONTROL_DIALOGUE_CLIENT_TO_HOST( sLocalData, sLocalPedData, CCDIA_HERO_GUN_CAUGHT )
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
// Ped has become too scared to finish the escape, return to cower
|
|
CPRINTLN(DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_PED_AI() - [", iCrowdStructID,"] CCPS_HERO_ATTEMPT going to CCPS_COWER")
|
|
//sCrowdControlPedData.eState = CCPS_COWER
|
|
SET_CROWD_CONTROL_PED_STATE( sCrowdControlPedData, CCPS_COWER, iCrowdStructID, sLocalPedData.eCreatorAssignedPedID )
|
|
|
|
ELSE
|
|
|
|
BOOL bReadyToTransition
|
|
|
|
// Animated version can only transition once it reaches the Escape/Hero loop
|
|
IF IS_BIT_SET_ENUM( sCrowdControlPedData.iBitSet, CCPEDDATA_RunningBespokeAnims )
|
|
|
|
IF IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_HERO_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
|
|
bReadyToTransition = TRUE
|
|
|
|
ENDIF
|
|
|
|
// Non animated version can go straight away (may add additional conditions, i.e. a timer)
|
|
ELSE
|
|
|
|
bReadyToTransition = TRUE
|
|
|
|
ENDIF
|
|
|
|
|
|
IF bReadyToTransition
|
|
|
|
// Go to combat
|
|
IF eHeroAction = CCHERO_GUN
|
|
|
|
QUEUE_CROWD_CONTROL_DIALOGUE_CLIENT_TO_HOST( sLocalData, sLocalPedData, CCDIA_HERO_GUN_COMPLETE )
|
|
|
|
CPRINTLN(DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_PED_AI() - [", iCrowdStructID,"] CCPS_HERO_ATTEMPT going to CCPS_COMBAT")
|
|
SET_PED_CAN_BE_TARGETTED( pedCrowd, TRUE ) // 2048337
|
|
|
|
// Rob - 2167482 - make sure all teams can target the hero combat ped
|
|
INT iRepeat
|
|
FOR iRepeat = 0 TO (FMMC_MAX_TEAMS-1)
|
|
SET_PED_CAN_BE_TARGETTED_BY_TEAM(pedCrowd, iRepeat, TRUE)
|
|
ENDFOR
|
|
|
|
//sCrowdControlPedData.eState = CCPS_COMBAT
|
|
SET_CROWD_CONTROL_PED_STATE( sCrowdControlPedData, CCPS_COMBAT, iCrowdStructID, sLocalPedData.eCreatorAssignedPedID )
|
|
|
|
// go to special hero state
|
|
ELIF eHeroAction = CCHERO_ALARM
|
|
OR eHeroAction = CCHERO_PHONE
|
|
|
|
SWITCH eHeroAction
|
|
CASE CCHERO_ALARM
|
|
QUEUE_CROWD_CONTROL_DIALOGUE_CLIENT_TO_HOST( sLocalData, sLocalPedData, CCDIA_HERO_ALARM_COMPLETE )
|
|
BREAK
|
|
CASE CCHERO_PHONE
|
|
QUEUE_CROWD_CONTROL_DIALOGUE_CLIENT_TO_HOST( sLocalData, sLocalPedData, CCDIA_HERO_PHONE_COMPLETE )
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
CPRINTLN(DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_PED_AI() - [", iCrowdStructID,"] CCPS_HERO_ATTEMPT going to CCPS_HERO")
|
|
SET_CROWD_CONTROL_PED_STATE( sCrowdControlPedData, CCPS_HERO, iCrowdStructID, sLocalPedData.eCreatorAssignedPedID )
|
|
|
|
ENDIF
|
|
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
// For successful heros with a non violent action (phone call or button press)
|
|
CASE CCPS_HERO
|
|
|
|
IF IS_BIT_SET_ENUM( sCrowdControlPedData.iBitSet, CCPEDDATA_RunningBespokeAnims )
|
|
|
|
BOOL bReadyToTransition
|
|
|
|
IF eHeroAction = CCHERO_ALARM
|
|
|
|
// Alarm guy signals a hero complete fail immediately
|
|
// and then waits to move on until the fail has been processed
|
|
SET_BIT_ENUM( sCrowdControlPedData.iBitSet, CCPEDDATA_HeroComplete )
|
|
IF IS_BIT_SET_ENUM( sCrowdControlData.iBitSet, CCDATA_FailProcessed )
|
|
|
|
QUEUE_CROWD_CONTROL_DIALOGUE_CLIENT_TO_HOST( sLocalData, sLocalPedData, CCDIA_ALARM_GOES_OFF )
|
|
|
|
bReadyToTransition = TRUE
|
|
ENDIF
|
|
|
|
ELSE
|
|
|
|
IF IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_COWER_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
SET_BIT_ENUM( sCrowdControlPedData.iBitSet, CCPEDDATA_HeroComplete )
|
|
bReadyToTransition = TRUE
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
IF bReadyToTransition
|
|
|
|
CPRINTLN(DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_PED_AI() - [", iCrowdStructID,"] CCPS_HERO going to CCPS_COWER")
|
|
SET_CROWD_CONTROL_PED_STATE( sCrowdControlPedData, CCPS_COWER, iCrowdStructID, sLocalPedData.eCreatorAssignedPedID )
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE CCPS_COMBAT
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
|
|
// Body - Animated state logic ONLY
|
|
//------------------------------------------------
|
|
IF IS_BIT_SET_ENUM( sCrowdControlPedData.iBitSet, CCPEDDATA_RunningBespokeAnims )
|
|
AND IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_RecievedSyncedScene )
|
|
|
|
SWITCH sCrowdControlPedData.eState
|
|
|
|
CASE CCPS_COWER
|
|
|
|
// Hero start/loop -> Hero fail -> Cower loop
|
|
IF sCrowdControlPedData.eStatePrev = CCPS_HERO_ATTEMPT
|
|
AND ( ( IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_HERO_START, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
AND HAS_CROWD_CONTROL_PED_FINISHED_ANIM( pedCrowd, CCPANIM_HERO_START, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType, 0.5 ) )
|
|
OR IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_HERO_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType ) )
|
|
|
|
IF HAS_CROWD_CONTROL_PED_ANIM_LOADED( CCPANIM_HERO_FAIL, sLocalData.eHeistType, sLocalPedData.eCreatorAssignedPedID )
|
|
|
|
PLAY_CROWD_CONTROL_SEQUENCE( pedCrowd, CCSEQ_HERO_FAIL, iCrowdStructID, sLocalPedData )
|
|
|
|
ENDIF
|
|
|
|
// Flinch loop -> Flinch outro -> Cower loop
|
|
ELIF sCrowdControlPedData.eStatePrev = CCPS_FLINCH
|
|
AND IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_FLINCH_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
|
|
IF HAS_CROWD_CONTROL_PED_ANIM_LOADED( CCPANIM_FLINCH_TO_IDLE_OUTRO, sLocalData.eHeistType, sLocalPedData.eCreatorAssignedPedID )
|
|
|
|
PLAY_CROWD_CONTROL_SEQUENCE( pedCrowd, CCSEQ_FLINCH_TO_COWER, iCrowdStructID, sLocalPedData )
|
|
|
|
ENDIF
|
|
|
|
// X -> Cower loop
|
|
ELIF NOT IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_COWER_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
|
|
// Make sure we don't interupt any flinching or transitions back into the cower
|
|
// Has finished intro
|
|
IF ( sCrowdControlPedData.eStatePrev = CCPS_INTRO
|
|
AND HAS_CROWD_CONTROL_PED_FINISHED_ANIM( pedCrowd, CCPANIM_INTRO_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType, DEFAULT, TRUE, sLocalData.iSyncSceneIntroLoop )
|
|
AND HAS_CROWD_CONTROL_PED_FINISHED_ANIM( pedCrowd, CCPANIM_INTRO, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType, DEFAULT, TRUE, sCrowdControlData.iSyncScene, HASH( "blendout" ) ) )
|
|
// Has finished hero attempt fail
|
|
OR ( sCrowdControlPedData.eStatePrev = CCPS_HERO_ATTEMPT
|
|
AND ( NOT DOES_CROWD_CONTROL_PED_HAVE_ANIM( CCPANIM_HERO_FAIL, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
OR HAS_CROWD_CONTROL_PED_FINISHED_ANIM( pedCrowd, CCPANIM_HERO_FAIL, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType, DEFAULT ) ) )
|
|
// Has finished flinch
|
|
OR ( sCrowdControlPedData.eStatePrev = CCPS_FLINCH
|
|
AND NOT IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_COWER_TO_FLINCH_INTRO, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
AND NOT IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_FLINCH_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
AND HAS_CROWD_CONTROL_PED_FINISHED_ANIM( pedCrowd, CCPANIM_FLINCH_TO_IDLE_OUTRO, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType ) )
|
|
|
|
IF HAS_CROWD_CONTROL_PED_ANIM_LOADED( CCPANIM_COWER_LOOP, sLocalData.eHeistType, sLocalPedData.eCreatorAssignedPedID )
|
|
|
|
PLAY_CROWD_CONTROL_ANIM( pedCrowd, CCPANIM_COWER_LOOP,
|
|
sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType,
|
|
REALLY_SLOW_BLEND_IN, -0.1, -1,
|
|
AF_LOOPING | eCrowdControlAnimFlags )
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE CCPS_FLINCH
|
|
|
|
// Cower loop -> Flinch intro -> Flinch loop
|
|
IF ( sCrowdControlPedData.eStatePrev = CCPS_COWER
|
|
AND ( IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_COWER_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
OR IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_FLINCH_TO_IDLE_OUTRO, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType ) )
|
|
AND NOT IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_COWER_TO_FLINCH_INTRO, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType ) )
|
|
|
|
IF HAS_CROWD_CONTROL_PED_ANIM_LOADED( CCPANIM_COWER_TO_FLINCH_INTRO, sLocalData.eHeistType, sLocalPedData.eCreatorAssignedPedID )
|
|
|
|
PLAY_CROWD_CONTROL_SEQUENCE( pedCrowd, CCSEQ_COWER_TO_FLINCH, iCrowdStructID, sLocalPedData )
|
|
|
|
ENDIF
|
|
|
|
// Flinch underfire -> Flinch loop
|
|
ELIF ( sCrowdControlPedData.eStatePrev = CCPS_FLINCH_UNDERFIRE
|
|
AND IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_FLINCH_UNDERFIRE_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
AND NOT IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_FLINCH_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType ) )
|
|
|
|
IF HAS_CROWD_CONTROL_PED_ANIM_LOADED( CCPANIM_FLINCH_LOOP, sLocalData.eHeistType, sLocalPedData.eCreatorAssignedPedID )
|
|
|
|
PLAY_CROWD_CONTROL_SEQUENCE( pedCrowd, CCSEQ_FLINCH_UNDERFIRE_TO_FLINCH, iCrowdStructID, sLocalPedData )
|
|
|
|
// PLAY_CROWD_CONTROL_ANIM( pedCrowd,
|
|
// CCPANIM_FLINCH_LOOP,
|
|
// sLocalPedData.eCreatorAssignedPedID,
|
|
// sLocalData.eHeistType,
|
|
// REALLY_SLOW_BLEND_IN, -0.1, -1,
|
|
// AF_LOOPING | eCrowdControlAnimFlags )
|
|
|
|
ENDIF
|
|
|
|
// Beatdown loop -> Beatdown outro -> Flinch loop
|
|
ELIF ( sCrowdControlPedData.eStatePrev = CCPS_BEATDOWN
|
|
AND IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_BEATDOWN_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
AND NOT IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_BEATDOWN_OUTRO, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType ) )
|
|
|
|
IF HAS_CROWD_CONTROL_PED_ANIM_LOADED( CCPANIM_BEATDOWN_OUTRO, sLocalData.eHeistType, sLocalPedData.eCreatorAssignedPedID )
|
|
|
|
PLAY_CROWD_CONTROL_SEQUENCE( pedCrowd, CCSEQ_BEATDOWN_TO_FLINCH, iCrowdStructID, sLocalPedData )
|
|
|
|
ENDIF
|
|
|
|
// // bugs 2114141 & 2123699
|
|
// // trying to avoid bug where peds are standing doing nothing, this will task them with the flinch anims
|
|
// // always seem to be in the flinch state but no idea how they go here, looks like a migration problem
|
|
// ELIF NOT IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_COWER_TO_FLINCH_INTRO, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
// AND NOT IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_FLINCH_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
// AND NOT IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_BEATDOWN_OUTRO, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
//
|
|
// IF HAS_CROWD_CONTROL_PED_ANIM_LOADED( CCPANIM_COWER_TO_FLINCH_INTRO, sLocalData.eHeistType, sLocalPedData.eCreatorAssignedPedID )
|
|
//
|
|
// CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_PED_AI() - EMERGENCY SEQUENCE TASK, PED HAS LOST ANIMATION TASK" )
|
|
// PLAY_CROWD_CONTROL_SEQUENCE( pedCrowd, CCSEQ_COWER_TO_FLINCH, iCrowdStructID, sLocalPedData )
|
|
//
|
|
// ENDIF
|
|
//
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE CCPS_FLINCH_UNDERFIRE
|
|
|
|
// Cower loop /Flinch outro -> Flinch intro -> Flinch loop shot at
|
|
IF ( sCrowdControlPedData.eStatePrev = CCPS_COWER
|
|
AND ( IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_COWER_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
OR IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_FLINCH_TO_IDLE_OUTRO, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType ) )
|
|
AND NOT IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_COWER_TO_FLINCH_INTRO, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
AND NOT IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_FLINCH_UNDERFIRE_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType ) )
|
|
|
|
IF HAS_CROWD_CONTROL_PED_ANIM_LOADED( CCPANIM_COWER_TO_FLINCH_INTRO, sLocalData.eHeistType, sLocalPedData.eCreatorAssignedPedID )
|
|
|
|
PLAY_CROWD_CONTROL_SEQUENCE( pedCrowd, CCSEQ_COWER_TO_FLINCH_UNDERFIRE, iCrowdStructID, sLocalPedData )
|
|
|
|
ENDIF
|
|
|
|
// Flinch loop -> Flinch underfire
|
|
ELIF ( sCrowdControlPedData.eStatePrev = CCPS_FLINCH
|
|
AND ( IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_FLINCH_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
OR IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_COWER_TO_FLINCH_INTRO, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
OR IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_FLINCH_UNDERFIRE_TO_FLINCH_OUTRO, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType ) )
|
|
AND NOT IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_FLINCH_TO_FLINCH_UNDERFIRE_INTRO, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
AND NOT IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_FLINCH_UNDERFIRE_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType ) )
|
|
|
|
IF HAS_CROWD_CONTROL_PED_ANIM_LOADED( CCPANIM_FLINCH_UNDERFIRE_LOOP, sLocalData.eHeistType, sLocalPedData.eCreatorAssignedPedID )
|
|
|
|
PLAY_CROWD_CONTROL_SEQUENCE( pedCrowd, CCSEQ_FLINCH_TO_FLINCH_UNDERFIRE, iCrowdStructID, sLocalPedData )
|
|
|
|
// PLAY_CROWD_CONTROL_ANIM( pedCrowd,
|
|
// CCPANIM_FLINCH_UNDERFIRE_LOOP,
|
|
// sLocalPedData.eCreatorAssignedPedID,
|
|
// sLocalData.eHeistType,
|
|
// SLOW_BLEND_IN, -0.1, -1,
|
|
// AF_LOOPING | eCrowdControlAnimFlags )
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE CCPS_BEATDOWN
|
|
|
|
SET_PED_RESET_FLAG( pedCrowd, PRF_UseKinematicPhysics, TRUE )
|
|
|
|
IF NOT IS_BIT_SET_ENUM( sCrowdControlPedData.iBitSet, CCPEDDATA_BeatdownSyncSceneStarted )
|
|
|
|
IF IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_BEATDOWN_INTRO, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType, TRUE )
|
|
OR IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_BEATDOWN_HIT_A, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType, TRUE )
|
|
OR IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_BEATDOWN_HIT_B, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType, TRUE )
|
|
OR IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_BEATDOWN_DIE, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType, TRUE )
|
|
|
|
SET_BIT_ENUM( sCrowdControlPedData.iBitSet, CCPEDDATA_BeatdownSyncSceneStarted )
|
|
|
|
ENDIF
|
|
|
|
ELSE
|
|
|
|
IF NOT IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_BEATDOWN_INTRO, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType, TRUE )
|
|
AND NOT IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_BEATDOWN_HIT_A, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType, TRUE )
|
|
AND NOT IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_BEATDOWN_HIT_B, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType, TRUE )
|
|
AND NOT IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_BEATDOWN_DIE, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType, TRUE )
|
|
AND NOT IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_BEATDOWN_DIE_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType, FALSE )
|
|
AND NOT IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_BEATDOWN_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType, FALSE )
|
|
|
|
IF IS_BIT_SET_ENUM( sCrowdControlPedData.iBitSet, CCPEDDATA_KnockedOut )
|
|
|
|
PLAY_CROWD_CONTROL_ANIM( pedCrowd, CCPANIM_BEATDOWN_DIE_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType,
|
|
REALLY_SLOW_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_ENDS_IN_DEAD_POSE | eCrowdControlAnimFlags )
|
|
|
|
ELSE
|
|
|
|
PLAY_CROWD_CONTROL_ANIM( pedCrowd, CCPANIM_BEATDOWN_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType,
|
|
REALLY_SLOW_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_LOOPING | eCrowdControlAnimFlags )
|
|
|
|
ENDIF
|
|
|
|
CLEAR_BIT_ENUM( sCrowdControlPedData.iBitSet, CCPEDDATA_BeatdownSyncSceneStarted )
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE CCPS_HERO_ATTEMPT
|
|
|
|
// Cower loop -> Hero start -> Hero loop
|
|
IF ( sCrowdControlPedData.eStatePrev = CCPS_COWER
|
|
AND IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_COWER_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType ) // playing cower?
|
|
AND NOT IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_HERO_START, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType ) ) // not playing escape start?
|
|
|
|
IF HAS_CROWD_CONTROL_PED_ANIM_LOADED( CCPANIM_HERO_START, sLocalData.eHeistType, sLocalPedData.eCreatorAssignedPedID )
|
|
|
|
PLAY_CROWD_CONTROL_SEQUENCE( pedCrowd, CCSEQ_HERO_START, iCrowdStructID, sLocalPedData )
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE CCPS_HERO
|
|
|
|
// Hero loop -> Hero pass -> Cower
|
|
IF sCrowdControlPedData.eStatePrev = CCPS_HERO_ATTEMPT
|
|
AND IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_HERO_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType ) // playing hero start?
|
|
AND NOT IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_HERO_PASS, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType ) // not playing hero pass?
|
|
|
|
IF eHeroAction = CCHERO_ALARM
|
|
|
|
IF HAS_CROWD_CONTROL_PED_ANIM_LOADED( CCPANIM_HERO_FAIL, sLocalData.eHeistType, sLocalPedData.eCreatorAssignedPedID )
|
|
PLAY_CROWD_CONTROL_SEQUENCE( pedCrowd, CCSEQ_HERO_FAIL, iCrowdStructID, sLocalPedData )
|
|
ENDIF
|
|
|
|
ELSE
|
|
|
|
IF HAS_CROWD_CONTROL_PED_ANIM_LOADED( CCPANIM_HERO_PASS, sLocalData.eHeistType, sLocalPedData.eCreatorAssignedPedID )
|
|
PLAY_CROWD_CONTROL_SEQUENCE( pedCrowd, CCSEQ_HERO_PASS, iCrowdStructID, sLocalPedData )
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE CCPS_COMBAT
|
|
|
|
// Hero loop -> Hero Pass
|
|
IF IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_HERO_LOOP, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType ) // playing escape loop?
|
|
AND NOT IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_HERO_PASS, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType ) // not playing escape pass?
|
|
|
|
IF HAS_CROWD_CONTROL_PED_ANIM_LOADED( CCPANIM_HERO_PASS, sLocalData.eHeistType, sLocalPedData.eCreatorAssignedPedID )
|
|
|
|
WEAPON_TYPE eWeap
|
|
GET_CURRENT_PED_WEAPON( pedCrowd, eWeap )
|
|
IF eWeap != WEAPONTYPE_PISTOL
|
|
SET_CURRENT_PED_WEAPON( pedCrowd, WEAPONTYPE_PISTOL, TRUE )
|
|
ENDIF
|
|
|
|
PLAY_CROWD_CONTROL_ANIM( pedCrowd, CCPANIM_HERO_PASS,
|
|
sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType,
|
|
REALLY_SLOW_BLEND_IN, -0.1, -1,
|
|
AF_HOLD_LAST_FRAME | eCrowdControlAnimFlags )
|
|
|
|
SET_PED_USING_ACTION_MODE( pedCrowd, TRUE, -1, "DEFAULT_ACTION" )
|
|
|
|
ENDIF
|
|
|
|
// Hero pass -> AI combat
|
|
ELIF IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_HERO_PASS, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType ) // playing escape pass?
|
|
AND HAS_CROWD_CONTROL_PED_FINISHED_ANIM( pedCrowd, CCPANIM_HERO_PASS, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType ) // finished escape pass?
|
|
|
|
// TRANSFER TO AI COMBAT
|
|
//SET_PED_RESET_FLAG( pedCrowd, PRF_InstantBlendToAim, TRUE )
|
|
|
|
CLEAR_BIT_ENUM( sCrowdControlPedData.iBitSet, CCPEDDATA_RunningBespokeAnims )
|
|
SET_BIT_ENUM( sCrowdControlPedData.iBitSet, CCPEDDATA_HeroComplete )
|
|
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
ENDIF
|
|
|
|
// Body - AI driven logic ONLY
|
|
//------------------------------------------------
|
|
IF NOT IS_BIT_SET_ENUM( sCrowdControlPedData.iBitSet, CCPEDDATA_RunningBespokeAnims )
|
|
|
|
// Run AI state machine
|
|
SWITCH sCrowdControlPedData.eState
|
|
|
|
// Idle, unalert to player's prescence
|
|
CASE CCPS_INTRO
|
|
BREAK
|
|
|
|
CASE CCPS_COWER
|
|
CASE CCPS_FLINCH
|
|
|
|
IF NOT IS_SCRIPT_TASK_RUNNING_OR_STARTING( pedCrowd, SCRIPT_TASK_HANDS_UP )
|
|
AND NOT IS_SCRIPT_TASK_RUNNING_OR_STARTING( pedCrowd, SCRIPT_TASK_COWER )
|
|
|
|
SET_PED_COMBAT_ATTRIBUTES( pedCrowd, CA_ALWAYS_FLEE, FALSE )
|
|
SET_PED_FLEE_ATTRIBUTES( pedCrowd, FA_DISABLE_COWER, TRUE )
|
|
SET_PED_FLEE_ATTRIBUTES( pedCrowd, FA_DISABLE_FLEE_FROM_INDIRECT_THREATS, TRUE )
|
|
SET_PED_FLEE_ATTRIBUTES( pedCrowd, FA_COWER_INSTEAD_OF_FLEE, TRUE )
|
|
|
|
TASK_HANDS_UP( pedCrowd,-1, sLocalPedData.pedBiggestThreat, -1, HANDS_UP_NOTHING )
|
|
sLocalPedData.timeLastThreatened = GET_NETWORK_TIME()
|
|
|
|
ELIF IS_SCRIPT_TASK_RUNNING_OR_STARTING( pedCrowd, SCRIPT_TASK_HANDS_UP )
|
|
AND NOT IS_SCRIPT_TASK_RUNNING_OR_STARTING( pedCrowd, SCRIPT_TASK_COWER )
|
|
AND eThreatFelt = CCTHREAT_NONE
|
|
AND IS_TIME_MORE_THAN( GET_NETWORK_TIME(), GET_TIME_OFFSET( sLocalPedData.timeLastThreatened, 5000 ) )
|
|
|
|
TASK_COWER( pedCrowd, -1 )
|
|
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE CCPS_COMBAT
|
|
|
|
WEAPON_TYPE eWeap
|
|
GET_CURRENT_PED_WEAPON( pedCrowd, eWeap )
|
|
IF eWeap != WEAPONTYPE_PISTOL
|
|
SET_CURRENT_PED_WEAPON( pedCrowd, WEAPONTYPE_PISTOL, FALSE )
|
|
ENDIF
|
|
|
|
IF NOT IS_SCRIPT_TASK_RUNNING_OR_STARTING( pedCrowd, SCRIPT_TASK_COMBAT )
|
|
|
|
SET_PED_COMBAT_ATTRIBUTES(pedCrowd, CA_ALWAYS_FLEE, FALSE)
|
|
TASK_COMBAT_PED( pedCrowd, sLocalPedData.pedBiggestThreat )
|
|
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
ENDIF
|
|
|
|
// Other dialogue which plays based on threats and/or state
|
|
//-----------------------------------------------------------------------
|
|
IF IS_BIT_SET_ENUM( sCrowdControlData.iBitSet, CCDATA_Active )
|
|
AND NOT IS_PED_IN_COMBAT( pedCrowd )
|
|
AND sCrowdControlPedData.eState != CCPS_COMBAT
|
|
AND sCrowdControlPedData.eState != CCPS_HERO_ATTEMPT
|
|
AND sCrowdControlPedData.eState != CCPS_HERO
|
|
|
|
BOOL bPassedInitialScreaming = IS_TIME_MORE_THAN( GET_NETWORK_TIME(), GET_TIME_OFFSET( sLocalData.timeCrowdKickedOff, 4000 ) )
|
|
|
|
// THREAT BASED
|
|
IF eThreatFelt != CCTHREAT_NONE
|
|
AND bPassedInitialScreaming
|
|
|
|
SWITCH eThreatFelt
|
|
|
|
CASE CCTHREAT_PROXIMITY
|
|
|
|
QUEUE_CROWD_CONTROL_DIALOGUE_CLIENT_TO_HOST( sLocalData, sLocalPedData, CCDIA_COWER_HIGH_FEAR )
|
|
|
|
BREAK
|
|
|
|
CASE CCTHREAT_BEATING_NEIGHBOUR
|
|
|
|
QUEUE_CROWD_CONTROL_DIALOGUE_CLIENT_TO_HOST( sLocalData, sLocalPedData, CCDIA_STICKS_UP_FOR_OTHER )
|
|
|
|
BREAK
|
|
|
|
CASE CCTHREAT_KILLED_OTHER
|
|
|
|
QUEUE_CROWD_CONTROL_DIALOGUE_CLIENT_TO_HOST( sLocalData, sLocalPedData, CCDIA_SEES_OTHER_KILLED )
|
|
|
|
BREAK
|
|
|
|
CASE CCTHREAT_AIMED_AT
|
|
CASE CCTHREAT_PROJECTILE_EXPLOSIVE
|
|
CASE CCTHREAT_PROJECTILE_EXPLOSIVE_STICKY_BOMB
|
|
|
|
QUEUE_CROWD_CONTROL_DIALOGUE_CLIENT_TO_HOST( sLocalData, sLocalPedData, CCDIA_RECEIVES_SCARE )
|
|
|
|
BREAK
|
|
|
|
CASE CCTHREAT_SHOOTING
|
|
|
|
QUEUE_CROWD_CONTROL_DIALOGUE_CLIENT_TO_HOST( sLocalData, sLocalPedData, CCDIA_SHOT_NEAR )
|
|
|
|
BREAK
|
|
|
|
CASE CCTHREAT_SHOOTING_CLOSE
|
|
|
|
QUEUE_CROWD_CONTROL_DIALOGUE_CLIENT_TO_HOST( sLocalData, sLocalPedData, CCDIA_SHOT_DIRECTLY_AT )
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
ENDIF
|
|
|
|
// STATE BASED
|
|
SWITCH sCrowdControlPedData.eState
|
|
|
|
// While
|
|
CASE CCPS_COWER
|
|
|
|
IF IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_INTRO, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType, TRUE )
|
|
|
|
// Initially only allow the peds crowd to scream
|
|
IF NOT bPassedInitialScreaming
|
|
QUEUE_CROWD_CONTROL_DIALOGUE_CLIENT_TO_HOST( sLocalData, sLocalPedData, CCDIA_INITIAL_PANIC, CCDIAPLAYBACK_FORCE_PAIN )
|
|
ELSE
|
|
QUEUE_CROWD_CONTROL_DIALOGUE_CLIENT_TO_HOST( sLocalData, sLocalPedData, CCDIA_INITIAL_PANIC )
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
// AMBIENT
|
|
BOOL bCanPlayLowFearAmbientDialogue = IS_TIME_MORE_THAN( GET_NETWORK_TIME(), GET_TIME_OFFSET( sLocalData.timeCrowdKickedOff, 20000 ) )
|
|
|
|
CROWD_CONTROL_DIALOGUE eAmbientRandomDialogue
|
|
|
|
// Alarm has just gone off
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_RaiseAlarms )
|
|
AND NOT IS_BIT_SET_ENUM( sCrowdControlData.iBitSet, CCDATA_RaiseAlarmDiagloue )
|
|
AND NOT IS_CUTSCENE_PLAYING() // dnt try and fire off this line behind a cutscene as it might get missed
|
|
|
|
eAmbientRandomDialogue = CCDIA_ALARM_GOES_OFF_INITIAL
|
|
|
|
// Otherwise select a line based off fear level
|
|
ELSE
|
|
|
|
// Fear low
|
|
IF sLocalData.fIntimidationBar < 40.0
|
|
AND sCrowdControlPedData.eState != CCPS_FLINCH
|
|
AND sCrowdControlPedData.eState != CCPS_BEATDOWN
|
|
AND bCanPlayLowFearAmbientDialogue
|
|
|
|
// Once the alarm has gone off theres a random chance of hearing alarm/cops are coming related dialogue
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_RaiseAlarms )
|
|
AND GET_RANDOM_BOOL()
|
|
eAmbientRandomDialogue = CCDIA_ALARM_GOES_OFF
|
|
ELSE
|
|
eAmbientRandomDialogue = CCDIA_COWER_LOW_FEAR
|
|
ENDIF
|
|
|
|
|
|
// Fear high
|
|
ELSE
|
|
eAmbientRandomDialogue = CCDIA_COWER_HIGH_FEAR
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
// Play ambient context
|
|
QUEUE_CROWD_CONTROL_DIALOGUE_CLIENT_TO_HOST( sLocalData, sLocalPedData, eAmbientRandomDialogue )
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
|
|
PROC PROCESS_CROWD_CONTROL_PED_LOCAL( PED_INDEX pedCrowd, INT iCrowdID,
|
|
CROWD_CONTROL_PED_DECORATOR_DATA &sPedData,
|
|
CROWD_CONTROL_LOCAL_PED_DATA &sLocalPedData,
|
|
CROWD_CONTROL_SERVER_DATA &sServerData,
|
|
CROWD_CONTROL_LOCAL_DATA &sLocalData )
|
|
|
|
#IF NOT IS_DEBUG_BUILD
|
|
UNUSED_PARAMETER( iCrowdID )
|
|
#ENDIF
|
|
|
|
CROWD_CONTROL_PED_HERO_ACTION eHeroAction = CCHERO_NONE
|
|
IF DOES_CROWD_CONTROL_PED_HAVE_ANIM( CCPANIM_HERO_START, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
eHeroAction = GET_CROWD_CONTROL_PED_HERO_ACTION_FOR_ANIMATED_PED( sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
ENDIF
|
|
|
|
IF IS_BIT_SET_ENUM( sPedData.iBitSet, CCPEDDATA_RunningBespokeAnims )
|
|
|
|
SWITCH eHeroAction
|
|
|
|
CASE CCHERO_PHONE
|
|
|
|
SWITCH sPedData.eState
|
|
|
|
CASE CCPS_COWER
|
|
|
|
// Detach the phone
|
|
IF DOES_ENTITY_EXIST( sLocalPedData.objProp )
|
|
|
|
IF IS_ENTITY_ATTACHED( sLocalPedData.objProp )
|
|
|
|
IF sServerData.iSyncScene != -1
|
|
AND IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_INTRO, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType, TRUE )
|
|
AND HAS_CROWD_CONTROL_PED_FINISHED_ANIM( pedCrowd, CCPANIM_INTRO, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType, DEFAULT, TRUE, sServerData.iSyncScene, HASH( "drop" ) )
|
|
|
|
CPRINTLN(DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_PED_LOCAL() - [", iCrowdID,"] Detatched phone for CCPANIM_INTRO")
|
|
DETACH_ENTITY( sLocalPedData.objProp )
|
|
FREEZE_ENTITY_POSITION( sLocalPedData.objProp, TRUE )
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE CCPS_HERO
|
|
|
|
IF DOES_ENTITY_EXIST( sLocalPedData.objProp )
|
|
|
|
// Attach the phone, as they start playing the hero anim
|
|
IF NOT IS_ENTITY_ATTACHED( sLocalPedData.objProp )
|
|
|
|
IF NOT IS_BIT_SET_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_HeroPropDetatchedForLastTime )
|
|
|
|
IF IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_HERO_PASS, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
|
|
CPRINTLN(DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_PED_LOCAL() - [", iCrowdID,"] Attached phone for CCPANIM_HERO_PASS")
|
|
|
|
FREEZE_ENTITY_POSITION( sLocalPedData.objProp, FALSE )
|
|
ATTACH_ENTITY_TO_ENTITY( sLocalPedData.objProp, pedCrowd, GET_PED_BONE_INDEX( pedCrowd, BONETAG_PH_R_HAND ), <<0,0,0>>, <<0,0,0>>, TRUE, FALSE )
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ELSE
|
|
|
|
// Detach phone during hero pass
|
|
IF IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_HERO_PASS, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
AND HAS_CROWD_CONTROL_PED_FINISHED_ANIM( pedCrowd, CCPANIM_HERO_PASS, sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType, 0.9 )
|
|
|
|
// During the HERO PASS anim
|
|
CPRINTLN(DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_PED_LOCAL() - [", iCrowdID,"] Detatched phone for CCPANIM_HERO_PASS")
|
|
|
|
DETACH_ENTITY( sLocalPedData.objProp )
|
|
FREEZE_ENTITY_POSITION( sLocalPedData.objProp, TRUE )
|
|
|
|
SET_BIT_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_HeroPropDetatchedForLastTime )
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
|
|
FUNC BOOL IS_WEAPON_SUITABLE_FOR_CROWD_CONTROL_BEATDOWN_1H( WEAPON_TYPE eWeapType, BOOL bIncludeHit = FALSE )
|
|
|
|
IF IS_WEAPON_A_PISTOL( eWeapType )
|
|
OR eWeapType = WEAPONTYPE_STUNGUN
|
|
OR eWeapType = WEAPONTYPE_MICROSMG
|
|
OR eWeapType = WEAPONTYPE_DLC_FLAREGUN
|
|
// 2183699
|
|
OR eWeapType = WEAPONTYPE_KNIFE
|
|
OR eWeapType = WEAPONTYPE_DLC_BOTTLE
|
|
OR eWeapType = WEAPONTYPE_DLC_DAGGER
|
|
|
|
RETURN TRUE
|
|
|
|
// kick only - 1H weapons that we want to only allow kicking
|
|
// 2183699
|
|
ELIF eWeapType = WEAPONTYPE_CROWBAR
|
|
OR eWeapType = WEAPONTYPE_UNARMED
|
|
OR eWeapType = WEAPONTYPE_HAMMER
|
|
OR eWeapType = WEAPONTYPE_NIGHTSTICK
|
|
OR eWeapType = WEAPONTYPE_DLC_KNUCKLE
|
|
OR eWeapType = WEAPONTYPE_DLC_HATCHET
|
|
|
|
IF NOT bIncludeHit
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL IS_WEAPON_SUITABLE_FOR_CROWD_CONTROL_BEATDOWN_2H( WEAPON_TYPE eWeapType, BOOL bIncludeHit = FALSE )
|
|
|
|
IF IS_WEAPON_SUITABLE_FOR_TWO_HANDED_ANIMS( eWeapType )
|
|
OR eWeapType = WEAPONTYPE_SMG
|
|
OR eWeapType = WEAPONTYPE_MG
|
|
OR eWeapType = WEAPONTYPE_COMBATMG
|
|
OR eWeapType = WEAPONTYPE_GRENADELAUNCHER
|
|
OR eWeapType = WEAPONTYPE_DLC_ASSAULTMG
|
|
OR eWeapType = WEAPONTYPE_DLC_ASSAULTSMG
|
|
|
|
RETURN TRUE
|
|
|
|
// kick only
|
|
ELIF eWeapType = WEAPONTYPE_RPG
|
|
OR eWeapType = WEAPONTYPE_DLC_FIREWORK
|
|
|
|
IF NOT bIncludeHit
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL IS_CROWD_CONTROL_PLAYER_MELEE_ANIM_A_KICK( CROWD_CONTROL_PLAYER_ANIM_TYPE eAnim )
|
|
|
|
IF eAnim = CCPLAYERANIM_BEATDOWN_PISTOL_KICK_A
|
|
OR eAnim = CCPLAYERANIM_BEATDOWN_PISTOL_KICK_B
|
|
OR eAnim = CCPLAYERANIM_BEATDOWN_RIFLE_KICK_A
|
|
OR eAnim = CCPLAYERANIM_BEATDOWN_RIFLE_KICK_B
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL IS_CROWD_CONTROL_PLAYER_PERFORMING_A_BEATDOWN( PED_INDEX pedPlayer )
|
|
|
|
IF IS_CROWD_CONTROL_PLAYER_PLAYING_ANIM( pedPlayer, CCPLAYERANIM_BEATDOWN_PISTOL_A, TRUE )
|
|
OR IS_CROWD_CONTROL_PLAYER_PLAYING_ANIM( pedPlayer, CCPLAYERANIM_BEATDOWN_PISTOL_B, TRUE )
|
|
OR IS_CROWD_CONTROL_PLAYER_PLAYING_ANIM( pedPlayer, CCPLAYERANIM_BEATDOWN_PISTOL_KICK_A, TRUE )
|
|
OR IS_CROWD_CONTROL_PLAYER_PLAYING_ANIM( pedPlayer, CCPLAYERANIM_BEATDOWN_PISTOL_KICK_B, TRUE )
|
|
OR IS_CROWD_CONTROL_PLAYER_PLAYING_ANIM( pedPlayer, CCPLAYERANIM_BEATDOWN_RIFLE_A, TRUE )
|
|
OR IS_CROWD_CONTROL_PLAYER_PLAYING_ANIM( pedPlayer, CCPLAYERANIM_BEATDOWN_RIFLE_B, TRUE )
|
|
OR IS_CROWD_CONTROL_PLAYER_PLAYING_ANIM( pedPlayer, CCPLAYERANIM_BEATDOWN_RIFLE_KICK_A, TRUE )
|
|
OR IS_CROWD_CONTROL_PLAYER_PLAYING_ANIM( pedPlayer, CCPLAYERANIM_BEATDOWN_RIFLE_KICK_B, TRUE )
|
|
OR IS_CROWD_CONTROL_PLAYER_PLAYING_ANIM( pedPlayer, CCPLAYERANIM_BEATDOWN_LONG_PISTOL_A, TRUE )
|
|
OR IS_CROWD_CONTROL_PLAYER_PLAYING_ANIM( pedPlayer, CCPLAYERANIM_BEATDOWN_LONG_PISTOL_KICK_A, TRUE )
|
|
OR IS_CROWD_CONTROL_PLAYER_PLAYING_ANIM( pedPlayer, CCPLAYERANIM_BEATDOWN_LONG_RIFLE_A, TRUE )
|
|
OR IS_CROWD_CONTROL_PLAYER_PLAYING_ANIM( pedPlayer, CCPLAYERANIM_BEATDOWN_LONG_RIFLE_B, TRUE )
|
|
OR IS_CROWD_CONTROL_PLAYER_PLAYING_ANIM( pedPlayer, CCPLAYERANIM_BEATDOWN_LONG_RIFLE_KICK_A, TRUE )
|
|
OR IS_CROWD_CONTROL_PLAYER_PLAYING_ANIM( pedPlayer, CCPLAYERANIM_BEATDOWN_LONG_RIFLE_KICK_B, TRUE )
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
FUNC BOOL CAN_CROWD_CONTROL_PLAYER_PERFORM_A_BEATDOWN( PLAYER_INDEX playerID, PED_INDEX pedPlayer )
|
|
|
|
IF NOT IS_PED_INJURED( pedPlayer )
|
|
AND NOT IS_PED_RELOADING( pedPlayer )
|
|
AND NOT IS_PLAYER_FREE_AIMING( playerID )
|
|
AND NOT IS_PLAYER_TARGETTING_ANYTHING( playerID )
|
|
|
|
WEAPON_TYPE eWeapType
|
|
GET_CURRENT_PED_WEAPON( PLAYER_PED_ID(), eWeapType )
|
|
|
|
IF IS_WEAPON_SUITABLE_FOR_CROWD_CONTROL_BEATDOWN_1H( eWeapType )
|
|
CDEBUG2LN( DEBUG_NET_MINIGAME, "CAN_CROWD_CONTROL_PLAYER_PERFORM_A_BEATDOWN() - Player armed with a 1 handed weapon" )
|
|
RETURN TRUE
|
|
ELIF IS_WEAPON_SUITABLE_FOR_CROWD_CONTROL_BEATDOWN_2H( eWeapType )
|
|
CDEBUG2LN( DEBUG_NET_MINIGAME, "CAN_CROWD_CONTROL_PLAYER_PERFORM_A_BEATDOWN() - Player armed with a 2 handed weapon" )
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
ELSE
|
|
CDEBUG2LN( DEBUG_NET_MINIGAME, "CAN_CROWD_CONTROL_PLAYER_PERFORM_A_BEATDOWN() - Player is aiming/reloading" )
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL CAN_CROWD_CONTROL_PED_BE_BEATDOWN( PED_INDEX pedCrowd, CROWD_CONTROL_PED_DECORATOR_DATA &sPedDecorData, CROWD_CONTROL_PED_ENUM eAssignedPedID, CROWD_CONTROL_HEIST_TYPE eHeistType )
|
|
|
|
IF NOT IS_BIT_SET_ENUM( sPedDecorData.iBitSet, CCPEDDATA_Dead )
|
|
AND NOT IS_BIT_SET_ENUM( sPedDecorData.iBitSet, CCPEDDATA_KnockedOut )
|
|
AND DOES_CROWD_CONTROL_PED_HAVE_ANIM( CCPANIM_BEATDOWN_INTRO, eAssignedPedID, eHeistType )
|
|
|
|
IF IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_COWER_LOOP, eAssignedPedID, eHeistType )
|
|
OR IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_COWER_TO_FLINCH_INTRO, eAssignedPedID, eHeistType )
|
|
OR IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_FLINCH_LOOP, eAssignedPedID, eHeistType )
|
|
OR IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_FLINCH_TO_IDLE_OUTRO, eAssignedPedID, eHeistType )
|
|
OR IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_BEATDOWN_LOOP, eAssignedPedID, eHeistType )
|
|
OR IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_BEATDOWN_OUTRO, eAssignedPedID, eHeistType )
|
|
OR IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_BEATDOWN_INTRO, eAssignedPedID, eHeistType, TRUE )
|
|
OR IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_BEATDOWN_HIT_A, eAssignedPedID, eHeistType, TRUE )
|
|
OR IS_CROWD_CONTROL_PED_PLAYING_ANIM( pedCrowd, CCPANIM_BEATDOWN_HIT_B, eAssignedPedID, eHeistType, TRUE )
|
|
|
|
RETURN TRUE
|
|
|
|
ELSE
|
|
CDEBUG2LN( DEBUG_NET_MINIGAME, "CAN_CROWD_CONTROL_PED_BE_BEATDOWN() - Not playing a suitable anim to hit in from" )
|
|
ENDIF
|
|
|
|
ELSE
|
|
CDEBUG2LN( DEBUG_NET_MINIGAME, "CAN_CROWD_CONTROL_PED_BE_BEATDOWN() - Cannot beat dead/knockedout ped OR does not have animation" )
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL GET_CROWD_CONTROL_PED_BEATDOWN_MOVER_OFFSET_MIN_MAX( CROWD_CONTROL_PED_ENUM ePedCrowd, CROWD_CONTROL_HEIST_TYPE eHeistType, VECTOR &vMin, VECTOR &vMax )
|
|
|
|
SWITCH eHeistType
|
|
|
|
CASE CCHEIST_CUSTOM_FLEECA
|
|
|
|
SWITCH ePedCrowd
|
|
|
|
CASE CCPED_CUSTOMER_A
|
|
vMin = <<0,0,0>>
|
|
vMax = <<0,0.5,0>>
|
|
RETURN TRUE
|
|
BREAK
|
|
|
|
CASE CCPED_CUSTOMER_B
|
|
vMin = <<0,0,0>>
|
|
vMax = <<0,0.4,0>>
|
|
RETURN TRUE
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
BREAK
|
|
|
|
CASE CCHEIST_CUSTOM_ORNATE
|
|
|
|
SWITCH ePedCrowd
|
|
|
|
CASE CCPED_CASHIER_A
|
|
vMin = <<0,-0.25,0>>
|
|
vMax = <<0,0.25,0>>
|
|
RETURN TRUE
|
|
BREAK
|
|
|
|
CASE CCPED_CASHIER_B
|
|
vMin = <<0,-0.25,0>>
|
|
vMax = <<0,0.25,0>>
|
|
RETURN TRUE
|
|
BREAK
|
|
|
|
CASE CCPED_CUSTOMER_A
|
|
vMin = <<0,0,0>>
|
|
vMax = <<0,0.5,0>>
|
|
RETURN TRUE
|
|
BREAK
|
|
|
|
CASE CCPED_CUSTOMER_B
|
|
vMin = <<0,0,0>>
|
|
vMax = <<0,0.4,0>>
|
|
RETURN TRUE
|
|
BREAK
|
|
|
|
CASE CCPED_CUSTOMER_D
|
|
vMin = <<0,-0.1,0>>
|
|
vMax = <<0,0.4,0>>
|
|
RETURN TRUE
|
|
BREAK
|
|
|
|
CASE CCPED_CUSTOMER_G
|
|
vMin = <<0,0,0>>
|
|
vMax = <<0,0.25,0>>
|
|
RETURN TRUE
|
|
BREAK
|
|
|
|
CASE CCPED_CUSTOMER_H
|
|
vMin = <<0,-0.25,0>>
|
|
vMax = <<0,0.25,0>>
|
|
RETURN TRUE
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
// no custom mover offsets for this ped, return false
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
FUNC VECTOR GET_CROWD_CONTROL_PED_BEATDOWN_MOVER_OFFSET( PED_INDEX pedCrowd, CROWD_CONTROL_PED_ENUM ePedCrowd, VECTOR vPlayerCoord, CROWD_CONTROL_HEIST_TYPE eHeistType )
|
|
|
|
VECTOR vMin
|
|
VECTOR vMax
|
|
IF GET_CROWD_CONTROL_PED_BEATDOWN_MOVER_OFFSET_MIN_MAX( ePedCrowd, eHeistType, vMin, vMax )
|
|
vMin = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS( pedCrowd, vMin )
|
|
vMax = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS( pedCrowd, vMax )
|
|
RETURN GET_CLOSEST_POINT_ON_LINE( vPlayerCoord, vMin, vMax, TRUE )
|
|
ENDIF
|
|
|
|
RETURN GET_ENTITY_COORDS( pedCrowd, FALSE )
|
|
ENDFUNC
|
|
|
|
|
|
/// PURPOSE:
|
|
/// Obtains the angular range based on the probe's distance from the target ped's coords.
|
|
/// PARAMS:
|
|
/// vProbeCoord - The coord we're using to query (usually the players coord)
|
|
/// vPedCoord - The coord we're queryng against (usually the victims coord)
|
|
/// RETURNS:
|
|
/// FLOAT angular range, this is the range that is acceptable for the probes facing direction against the ped queried
|
|
FUNC FLOAT GET_CROWD_CONTROL_PED_BEATDOWN_FACING_ANGLE_RANGE( VECTOR vProbeCoord, VECTOR vPedCoord )
|
|
|
|
FLOAT fDist = GET_DISTANCE_BETWEEN_COORDS( vProbeCoord, vPedCoord, FALSE )
|
|
FLOAT fDistanceAlpha = CLAMP( ( fDist - cfCC_BeatdownFacingAngleChangeDistMin ) / ( cfCC_BeatdownFacingAngleChangeDistMax - cfCC_BeatdownFacingAngleChangeDistMin ), 0.0, 1.0 )
|
|
|
|
RETURN LERP_FLOAT( cfCC_BeatdownFacingAngleRangeMax, cfCC_BeatdownFacingAngleRangeMin, fDistanceAlpha )
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL IS_CROWD_CONTROL_PED_WITHIN_BEATDOWN_RANGE( PED_INDEX pedCrowd, PED_INDEX pedPlayer, CROWD_CONTROL_LOCAL_DATA &sLocalData, CROWD_CONTROL_LOCAL_PED_DATA &sLocalPedData )
|
|
|
|
BOOL bResult
|
|
|
|
VECTOR vPlayerCoord = GET_ENTITY_COORDS( pedPlayer )
|
|
VECTOR vPedMoverOffset = GET_CROWD_CONTROL_PED_BEATDOWN_MOVER_OFFSET( pedCrowd, sLocalPedData.eCreatorAssignedPedID, vPlayerCoord, sLocalData.eHeistType )
|
|
|
|
FLOAT fCurrentFacingAngleRange = cfCC_BeatdownFacingAngleRangeMin
|
|
|
|
IF GET_INTERIOR_FROM_ENTITY( pedPlayer ) = GET_INTERIOR_FROM_ENTITY( pedCrowd )
|
|
|
|
IF ABSF( vPlayerCoord.z - vPedMoverOffset.z ) <= 1.0
|
|
|
|
FLOAT fDist = GET_DISTANCE_BETWEEN_COORDS( vPlayerCoord, vPedMoverOffset, FALSE )
|
|
IF fDist <= cfCC_BeatdownDistMax
|
|
|
|
// is player facing ped within an angular range
|
|
fCurrentFacingAngleRange = GET_CROWD_CONTROL_PED_BEATDOWN_FACING_ANGLE_RANGE( vPlayerCoord, vPedMoverOffset )
|
|
IF IS_ENTITY_FACING_COORD_WITHIN_RANGE( PLAYER_PED_ID(), vPedMoverOffset, fCurrentFacingAngleRange )
|
|
bResult = TRUE
|
|
ELSE
|
|
CDEBUG2LN( DEBUG_NET_MINIGAME, "IS_CROWD_CONTROL_PED_WITHIN_BEATDOWN_RANGE() - not within the facing limits for the ped" )
|
|
ENDIF
|
|
|
|
ELSE
|
|
CDEBUG2LN( DEBUG_NET_MINIGAME, "IS_CROWD_CONTROL_PED_WITHIN_BEATDOWN_RANGE() - not close enough to the ped" )
|
|
ENDIF
|
|
|
|
ELSE
|
|
CDEBUG2LN( DEBUG_NET_MINIGAME, "IS_CROWD_CONTROL_PED_WITHIN_BEATDOWN_RANGE() - z difference is too big" )
|
|
ENDIF
|
|
|
|
ELSE
|
|
CDEBUG2LN( DEBUG_NET_MINIGAME, "IS_CROWD_CONTROL_PED_WITHIN_BEATDOWN_RANGE() - not in the same interior, cannot hit ped" )
|
|
ENDIF
|
|
|
|
RETURN bResult
|
|
ENDFUNC
|
|
|
|
|
|
FUNC BOOL PLAY_CROWD_CONTROL_BEATDOWN( NETWORK_INDEX niPed,
|
|
INT iCrowd,
|
|
WEAPON_TYPE eWeapType,
|
|
CROWD_CONTROL_SERVER_DATA &sData,
|
|
CROWD_CONTROL_LOCAL_DATA &sLocalData,
|
|
CROWD_CONTROL_PED_DECORATOR_DATA &sPedData,
|
|
CROWD_CONTROL_LOCAL_PED_DATA &sPedLocalData )
|
|
|
|
BOOL bCanUseWeaponButt
|
|
BOOL bCanUseKick
|
|
|
|
// First time, force gun butt
|
|
IF NOT IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_BeatdownFirst )
|
|
|
|
bCanUseWeaponButt = TRUE
|
|
bCanUseKick = FALSE
|
|
|
|
// no follow up, start on a random
|
|
ELIF sLocalData.eLastBeatdown = CCPLAYERANIM_INVALID
|
|
|
|
bCanUseWeaponButt = TRUE
|
|
bCanUseKick = TRUE
|
|
|
|
// follow up kick
|
|
ELIF IS_CROWD_CONTROL_PLAYER_MELEE_ANIM_A_KICK( sLocalData.eLastBeatdown )
|
|
|
|
bCanUseWeaponButt = FALSE
|
|
bCanUseKick = TRUE
|
|
|
|
// follow up gun butt
|
|
ELSE
|
|
|
|
bCanUseWeaponButt = TRUE
|
|
bCanUseKick = FALSE
|
|
|
|
ENDIF
|
|
|
|
PED_INDEX pedCrowd = NET_TO_PED( niPed )
|
|
BOOL bUseLongAnim = GET_DISTANCE_BETWEEN_ENTITIES( PLAYER_PED_ID(), pedCrowd ) >= cfCC_BeatdownLongAnimDistThreshold
|
|
|
|
// Select anim
|
|
CROWD_CONTROL_PLAYER_ANIM_TYPE eAnim
|
|
INT iStart
|
|
INT iEnd
|
|
IF IS_WEAPON_SUITABLE_FOR_CROWD_CONTROL_BEATDOWN_1H( eWeapType )
|
|
|
|
IF NOT IS_WEAPON_SUITABLE_FOR_CROWD_CONTROL_BEATDOWN_1H( eWeapType, TRUE )
|
|
bCanUseWeaponButt = FALSE
|
|
bCanUseKick = TRUE
|
|
ELSE
|
|
// Disabled long kicks - player slides on planted leg, looks bad
|
|
IF bUseLongAnim
|
|
bCanUseKick = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF bUseLongAnim
|
|
|
|
IF bCanUseWeaponButt
|
|
iStart = 0
|
|
ELSE
|
|
iStart = 1
|
|
ENDIF
|
|
|
|
IF bCanUseKick
|
|
iEnd = 2
|
|
ELSE
|
|
iEnd = 1
|
|
ENDIF
|
|
|
|
IF iStart >= iEnd
|
|
SCRIPT_ASSERT( "PLAY_CROWD_CONTROL_BEATDOWN() - random anim selection for 1H PISTOL LONG melee broken, iStart >= iEnd, see logs for details, bug Michael Wadelin" )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PLAY_CROWD_CONTROL_BEATDOWN() - random anim selection for 1H PISTOL LONG melee broken, iStart >= iEnd. iStart = ", iStart, " iEnd = ", iEnd )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PLAY_CROWD_CONTROL_BEATDOWN() bCanUseWeaponButt = ", BOOL_TO_STRING( bCanUseWeaponButt ) )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PLAY_CROWD_CONTROL_BEATDOWN() bCanUseKick = ", BOOL_TO_STRING( bCanUseKick ) )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PLAY_CROWD_CONTROL_BEATDOWN() bUseLongAnim = ", BOOL_TO_STRING( bUseLongAnim ) )
|
|
ENDIF
|
|
|
|
SWITCH GET_RANDOM_INT_IN_RANGE( iStart, iEnd )
|
|
CASE 0 eAnim = CCPLAYERANIM_BEATDOWN_LONG_PISTOL_A BREAK
|
|
CASE 1 eAnim = CCPLAYERANIM_BEATDOWN_LONG_PISTOL_KICK_A BREAK
|
|
ENDSWITCH
|
|
|
|
ELSE
|
|
|
|
IF bCanUseWeaponButt
|
|
iStart = 0
|
|
ELSE
|
|
iStart = 2
|
|
ENDIF
|
|
|
|
IF bCanUseKick
|
|
iEnd = 4
|
|
ELSE
|
|
iEnd = 2
|
|
ENDIF
|
|
|
|
IF iStart >= iEnd
|
|
SCRIPT_ASSERT( "PLAY_CROWD_CONTROL_BEATDOWN() - random anim selection for 1H PISTOL NORMAL melee broken, iStart >= iEnd, see logs for details, bug Michael Wadelin" )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PLAY_CROWD_CONTROL_BEATDOWN() - random anim selection for 1H PISTOL NORMAL melee broken, iStart >= iEnd. iStart = ", iStart, " iEnd = ", iEnd )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PLAY_CROWD_CONTROL_BEATDOWN() bCanUseWeaponButt = ", BOOL_TO_STRING( bCanUseWeaponButt ) )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PLAY_CROWD_CONTROL_BEATDOWN() bCanUseKick = ", BOOL_TO_STRING( bCanUseKick ) )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PLAY_CROWD_CONTROL_BEATDOWN() bUseLongAnim = ", BOOL_TO_STRING( bUseLongAnim ) )
|
|
ENDIF
|
|
|
|
SWITCH GET_RANDOM_INT_IN_RANGE( iStart, iEnd )
|
|
CASE 0 eAnim = CCPLAYERANIM_BEATDOWN_PISTOL_A BREAK
|
|
CASE 1 eAnim = CCPLAYERANIM_BEATDOWN_PISTOL_B BREAK
|
|
CASE 2 eAnim = CCPLAYERANIM_BEATDOWN_PISTOL_KICK_A BREAK
|
|
CASE 3 eAnim = CCPLAYERANIM_BEATDOWN_PISTOL_KICK_B BREAK
|
|
ENDSWITCH
|
|
ENDIF
|
|
|
|
ELIF IS_WEAPON_SUITABLE_FOR_CROWD_CONTROL_BEATDOWN_2H( eWeapType )
|
|
|
|
// only kicks allowed for weapons such as RPGs
|
|
IF NOT IS_WEAPON_SUITABLE_FOR_CROWD_CONTROL_BEATDOWN_2H( eWeapType, TRUE )
|
|
bCanUseWeaponButt = FALSE
|
|
bCanUseKick = TRUE
|
|
ELSE
|
|
// Disabled long kicks - player slides on planted leg, looks bad
|
|
IF bUseLongAnim
|
|
bCanUseKick = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF bCanUseWeaponButt
|
|
iStart = 0
|
|
ELSE
|
|
iStart = 2
|
|
ENDIF
|
|
|
|
IF bCanUseKick
|
|
iEnd = 4
|
|
ELSE
|
|
iEnd = 2
|
|
ENDIF
|
|
|
|
IF iStart >= iEnd
|
|
SCRIPT_ASSERT( "PLAY_CROWD_CONTROL_BEATDOWN() - random anim selection for 2H RIFLE melee broken, iStart >= iEnd, see logs for details, bug Michael Wadelin" )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PLAY_CROWD_CONTROL_BEATDOWN() - random anim selection for 2H RIFLE melee broken, iStart >= iEnd. iStart = ", iStart, " iEnd = ", iEnd )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PLAY_CROWD_CONTROL_BEATDOWN() bCanUseWeaponButt = ", BOOL_TO_STRING( bCanUseWeaponButt ) )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PLAY_CROWD_CONTROL_BEATDOWN() bCanUseKick = ", BOOL_TO_STRING( bCanUseKick ) )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PLAY_CROWD_CONTROL_BEATDOWN() bUseLongAnim = ", BOOL_TO_STRING( bUseLongAnim ) )
|
|
ENDIF
|
|
|
|
IF bUseLongAnim
|
|
|
|
SWITCH GET_RANDOM_INT_IN_RANGE( iStart, iEnd )
|
|
CASE 0 eAnim = CCPLAYERANIM_BEATDOWN_LONG_RIFLE_A BREAK
|
|
CASE 1 eAnim = CCPLAYERANIM_BEATDOWN_LONG_RIFLE_B BREAK
|
|
CASE 2 eAnim = CCPLAYERANIM_BEATDOWN_LONG_RIFLE_KICK_A BREAK
|
|
CASE 3 eAnim = CCPLAYERANIM_BEATDOWN_LONG_RIFLE_KICK_B BREAK
|
|
ENDSWITCH
|
|
|
|
ELSE
|
|
SWITCH GET_RANDOM_INT_IN_RANGE( iStart, iEnd )
|
|
CASE 0 eAnim = CCPLAYERANIM_BEATDOWN_RIFLE_A BREAK
|
|
CASE 1 eAnim = CCPLAYERANIM_BEATDOWN_RIFLE_B BREAK
|
|
CASE 2 eAnim = CCPLAYERANIM_BEATDOWN_RIFLE_KICK_A BREAK
|
|
CASE 3 eAnim = CCPLAYERANIM_BEATDOWN_RIFLE_KICK_B BREAK
|
|
ENDSWITCH
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
CROWD_CONTROL_PED_ANIM_TYPE eVictimAnim
|
|
|
|
IF sPedData.iBeatdownHitsRemaining <= 0
|
|
eVictimAnim = CCPANIM_BEATDOWN_DIE
|
|
ELIF sPedData.eState != CCPS_BEATDOWN
|
|
eVictimAnim = CCPANIM_BEATDOWN_INTRO
|
|
ELSE
|
|
IF GET_RANDOM_BOOL()
|
|
eVictimAnim = CCPANIM_BEATDOWN_HIT_A
|
|
ELSE
|
|
eVictimAnim = CCPANIM_BEATDOWN_HIT_B
|
|
ENDIF
|
|
ENDIF
|
|
|
|
|
|
IF HAS_ANIM_DICT_LOADED( GET_CROWD_CONTROL_PLAYER_ANIM_DICTIONARY( eAnim ) )
|
|
AND HAS_ANIM_DICT_LOADED( GET_CROWD_CONTROL_PED_ANIM_DICTIONARY( eVictimAnim, sPedLocalData.eCreatorAssignedPedID, sLocalData.eHeistType ) )
|
|
|
|
// Calculate position and orientation we want to play the anim at
|
|
VECTOR vPlayerCoord = GET_ENTITY_COORDS( PLAYER_PED_ID() )
|
|
//VECTOR vVictimCoord = GET_ENTITY_COORDS( pedCrowd )
|
|
|
|
// Get the peds mover coord, this is the coord we will offset the animation from
|
|
// We don't just use the mover directly as some peds need their mover adjusting depending on the player's angle of approach
|
|
VECTOR vMoverCoord = GET_CROWD_CONTROL_PED_BEATDOWN_MOVER_OFFSET( pedCrowd, sPedLocalData.eCreatorAssignedPedID, vPlayerCoord, sLocalData.eHeistType )
|
|
|
|
// Calculate a distance that means the ped capsules won't intersect
|
|
FLOAT fOffsetDistance = cfCC_BeatdownDistMin
|
|
//= FMAX( cfCC_BeatdownDistMin, cfCC_PlayerPedCapsuleRadiusStationary + GET_CROWD_CONTROL_PED_CAPSULE_SIZE( sPedLocalData.eCreatorAssignedPedID, sLocalData.eHeistType ) )
|
|
|
|
VECTOR vPos = ( NORMALISE_VECTOR( vPlayerCoord - vMoverCoord ) * fOffsetDistance ) + vMoverCoord
|
|
FLOAT fRot = ATAN2( -(vMoverCoord.X - vPlayerCoord.X), vMoverCoord.Y - vPlayerCoord.Y )
|
|
// VECTOR vPos = ( NORMALISE_VECTOR( vPlayerCoord - vVictimCoord ) * fOffsetDistance ) + vVictimCoord
|
|
// FLOAT fRot = ATAN2( -(vVictimCoord.X - vPlayerCoord.X), vVictimCoord.Y - vPlayerCoord.Y )
|
|
|
|
sLocalData.iSyncSceneBeatdown = NETWORK_CREATE_SYNCHRONISED_SCENE( vPos, <<0,0,fRot>>, DEFAULT, FALSE, FALSE )
|
|
|
|
// Player
|
|
NETWORK_ADD_PED_TO_SYNCHRONISED_SCENE(
|
|
PLAYER_PED_ID(),
|
|
sLocalData.iSyncSceneBeatdown,
|
|
GET_CROWD_CONTROL_PLAYER_ANIM_DICTIONARY( eAnim ),
|
|
GET_CROWD_CONTROL_PLAYER_ANIM_NAME( eAnim ),
|
|
WALK_BLEND_IN, NORMAL_BLEND_OUT,
|
|
DEFAULT,
|
|
RBF_PLAYER_BUMP | RBF_PLAYER_IMPACT | RBF_PLAYER_RAGDOLL_BUMP | RBF_PED_RAGDOLL_BUMP,
|
|
WALK_BLEND_IN )
|
|
|
|
// Victim
|
|
NETWORK_ADD_PED_TO_SYNCHRONISED_SCENE(
|
|
pedCrowd,
|
|
sLocalData.iSyncSceneBeatdown,
|
|
GET_CROWD_CONTROL_PED_ANIM_DICTIONARY( eVictimAnim, sPedLocalData.eCreatorAssignedPedID, sLocalData.eHeistType ),
|
|
GET_CROWD_CONTROL_PED_ANIM_NAME( eVictimAnim, sPedLocalData.eCreatorAssignedPedID, sLocalData.eHeistType ),
|
|
WALK_BLEND_IN, -0.1,
|
|
SYNCED_SCENE_BLOCK_MOVER_UPDATE,
|
|
RBF_PLAYER_BUMP | RBF_PLAYER_IMPACT | RBF_PLAYER_RAGDOLL_BUMP | RBF_PED_RAGDOLL_BUMP,
|
|
DEFAULT )
|
|
|
|
NETWORK_START_SYNCHRONISED_SCENE( sLocalData.iSyncSceneBeatdown )
|
|
|
|
sLocalData.iPlayerBeatingThisPed = iCrowd
|
|
sLocalData.eLastBeatdown = eAnim
|
|
|
|
SET_BIT_ENUM( sLocalData.iBitSet, CCLOCALDATA_BeatdownFirst )
|
|
CLEAR_BIT_ENUM( sLocalData.iBitset, CCLOCALDATA_BeatdownInterrupt )
|
|
|
|
// REMOVED: causes animations to look strange, bent necks, etc
|
|
// Make them look at the ped for a short while when kicking them
|
|
//TASK_LOOK_AT_ENTITY( PLAYER_PED_ID(), pedCrowd, 5000, DEFAULT, SLF_LOOKAT_VERY_HIGH )
|
|
|
|
// Mark ped as being hit
|
|
// If we own the ped update it directly
|
|
IF NETWORK_HAS_CONTROL_OF_NETWORK_ID( niPed )
|
|
SET_BIT_ENUM( sPedLocalData.iBitset, CCLOCALPEDDATA_BeatdownFired )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PLAY_CROWD_CONTROL_BEATDOWN() - Setting ped flag CCPEDDATA_BeatdownFired" )
|
|
// Otherwise broadcast event
|
|
ELSE
|
|
BROADCAST_FMMC_CC_PED_BEATDOWN( iCrowd )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PLAY_CROWD_CONTROL_BEATDOWN() - broadcasting ped flag CCPEDDATA_BeatdownFired" )
|
|
ENDIF
|
|
|
|
// Decrement hits remaining
|
|
IF NETWORK_IS_HOST_OF_THIS_SCRIPT()
|
|
sData.iNumHitsRemaining--
|
|
ELSE
|
|
BROADCAST_FMMC_CC_PED_BEATDOWN_HIT()
|
|
ENDIF
|
|
|
|
RETURN TRUE
|
|
ELSE
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PLAY_CROWD_CONTROL_BEATDOWN() - Anims not loaded" )
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
PROC PROCESS_CROWD_CONTROL_BEATDOWNS( NETWORK_INDEX &niPeds[],
|
|
CROWD_CONTROL_SERVER_DATA &sData,
|
|
CROWD_CONTROL_LOCAL_DATA &sLocalData,
|
|
CROWD_CONTROL_PED_DECORATOR_DATA &sPedData[],
|
|
CROWD_CONTROL_LOCAL_PED_DATA &sLocalPedData[] )
|
|
|
|
// Weapon Blocking
|
|
//-------------------------------------------------------------
|
|
|
|
BOOL bPlayerCurrentlyPerformingBeatdown = IS_CROWD_CONTROL_PLAYER_PERFORMING_A_BEATDOWN( PLAYER_PED_ID() )
|
|
|
|
// While in a beatdown
|
|
IF bPlayerCurrentlyPerformingBeatdown
|
|
|
|
// Don't allow player to change weapon while doing 1 of the beat down anims
|
|
DISABLE_CONTROL_ACTION( PLAYER_CONTROL, INPUT_SELECT_WEAPON )
|
|
|
|
IF HAS_ANIM_EVENT_FIRED( PLAYER_PED_ID(), HASH( "vibrate" ) )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_BEATDOWNS() - Melee impact vibration triggered" )
|
|
SET_CONTROL_SHAKE( PLAYER_CONTROL, 150, 255 ) // 150, 200
|
|
ENDIF
|
|
|
|
// Break out of the anim early
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_BeatdownInterrupt )
|
|
OR HAS_ANIM_EVENT_FIRED( PLAYER_PED_ID(), HASH( "breakout" ) )
|
|
|
|
IF NOT IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_BeatdownInterrupt )
|
|
|
|
SET_BIT_ENUM( sLocalData.iBitSet, CCLOCALDATA_BeatdownInterrupt )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_BEATDOWNS() - Beatdown interrupt hit" )
|
|
|
|
ENDIF
|
|
|
|
IF IS_CONTROL_PRESSED( PLAYER_CONTROL, INPUT_MOVE_UD )
|
|
OR IS_CONTROL_PRESSED( PLAYER_CONTROL, INPUT_MOVE_LR )
|
|
OR IS_CONTROL_PRESSED( PLAYER_CONTROL, INPUT_AIM )
|
|
|
|
CLEAR_PED_TASKS( PLAYER_PED_ID() )
|
|
CLEAR_BIT_ENUM( sLocalData.iBitSet, CCLOCALDATA_BeatdownInputTaken )
|
|
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_BEATDOWNS() - Beatdown has been interrupted by player input" )
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ELSE
|
|
// Reset the ped being hit and last anim
|
|
sLocalData.iPlayerBeatingThisPed = -1
|
|
sLocalData.eLastBeatdown = CCPLAYERANIM_INVALID
|
|
ENDIF
|
|
|
|
// Check if the player can beat the ped, no anim playing or anim ready to interrupt and player has suitible weapon and in suitible state
|
|
BOOL bCanPlayerBeat
|
|
IF NOT bPlayerCurrentlyPerformingBeatdown
|
|
OR IS_BIT_SET_ENUM( sLocalData.iBitset, CCLOCALDATA_BeatdownInterrupt )
|
|
IF CAN_CROWD_CONTROL_PLAYER_PERFORM_A_BEATDOWN( PLAYER_ID(), PLAYER_PED_ID() )
|
|
bCanPlayerBeat = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Take input - we can detect this earlier than the interrupt window so that it doesn't feel unresponsive.
|
|
BOOL bNeedsAReload
|
|
WEAPON_TYPE eWeaponCurrent
|
|
IF GET_CURRENT_PED_WEAPON( PLAYER_PED_ID(), eWeaponCurrent )
|
|
INT iAmmoInClip
|
|
IF GET_AMMO_IN_CLIP( PLAYER_PED_ID(), eWeaponCurrent, iAmmoInClip )
|
|
INT iAmmoInClipMax, iWeaponAmmo
|
|
iWeaponAmmo = GET_AMMO_IN_PED_WEAPON( PLAYER_PED_ID(), eWeaponCurrent )
|
|
iAmmoInClipMax = GET_MAX_AMMO_IN_CLIP( PLAYER_PED_ID(), eWeaponCurrent )
|
|
|
|
IF iAmmoInClip < iWeaponAmmo
|
|
AND iAmmoInClip < iAmmoInClipMax
|
|
bNeedsAReload = TRUE
|
|
ENDIF
|
|
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// If control is pressed or early input is made
|
|
BOOL bMeleePressed
|
|
IF NOT bNeedsAReload
|
|
AND ( IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_BeatdownInputTaken )
|
|
OR IS_CONTROL_JUST_PRESSED( PLAYER_CONTROL, INPUT_MELEE_ATTACK_LIGHT )
|
|
OR IS_DISABLED_CONTROL_JUST_PRESSED( PLAYER_CONTROL, INPUT_MELEE_ATTACK_LIGHT ) )
|
|
|
|
// Look out for early input
|
|
IF bPlayerCurrentlyPerformingBeatdown
|
|
AND sLocalData.eLastBeatdown != CCPLAYERANIM_INVALID
|
|
AND HAS_CROWD_CONTROL_PLAYER_FINISHED_ANIM( PLAYER_PED_ID(), sLocalData.eLastBeatdown, 0.25, TRUE, sLocalData.iSyncSceneBeatdown )
|
|
|
|
SET_BIT_ENUM( sLocalData.iBitSet, CCLOCALDATA_BeatdownInputTaken )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_BEATDOWNS() - Early input taken and stored" )
|
|
|
|
ENDIF
|
|
|
|
bMeleePressed = TRUE
|
|
|
|
ENDIF
|
|
|
|
|
|
BOOL bDisableMelee
|
|
|
|
INT iPedToBeat = -1
|
|
INT iCrowd
|
|
|
|
IF bCanPlayerBeat
|
|
|
|
REPEAT sData.iNumCrowdControlPeds iCrowd
|
|
|
|
BOOL bResetProbe = FALSE
|
|
bResetProbe = FALSE
|
|
|
|
IF NETWORK_DOES_ENTITY_EXIST_WITH_NETWORK_ID( niPeds[sData.iCrowdControlCloudIndex[iCrowd]] )
|
|
|
|
PED_INDEX pedCrowd = NET_TO_PED( niPeds[sData.iCrowdControlCloudIndex[iCrowd]] )
|
|
|
|
IF NOT IS_PED_INJURED( pedCrowd )
|
|
AND IS_BIT_SET_ENUM( sPedData[iCrowd].iBitSet, CCPEDDATA_RunningBespokeAnims )
|
|
|
|
// disable regular melee buttons for player while near a crowd ped
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES( PLAYER_PED_ID(), pedCrowd ) < cfCC_BeatdownMeleeDisableDist
|
|
bDisableMelee = TRUE
|
|
ENDIF
|
|
|
|
// found a ped we want for the beat down, but need to do 1 final test to probe for collision
|
|
IF IS_CROWD_CONTROL_PED_WITHIN_BEATDOWN_RANGE( pedCrowd, PLAYER_PED_ID(), sLocalData, sLocalPedData[iCrowd] )
|
|
|
|
IF CAN_CROWD_CONTROL_PED_BE_BEATDOWN( pedCrowd, sPedData[iCrowd], sLocalPedData[iCrowd].eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
|
|
INT iWasSomethingHit = 0
|
|
VECTOR vHitPos = <<0,0,0>>
|
|
VECTOR vHitNormal = <<0,0,0>>
|
|
ENTITY_INDEX entityHit = NULL
|
|
|
|
SHAPETEST_STATUS eStatus = GET_SHAPE_TEST_RESULT( sLocalData.shapetestBeatdownProbe, iWasSomethingHit, vHitPos, vHitNormal, entityHit )
|
|
|
|
// Start a new shape test
|
|
// either 1 hadn't been started or we want to test a different ped
|
|
IF eStatus = SHAPETEST_STATUS_NONEXISTENT
|
|
OR sLocalData.iCrowdPedBeatdownProbe != iCrowd
|
|
|
|
VECTOR vCrowdPedCoord = GET_CROWD_CONTROL_PED_BEATDOWN_MOVER_OFFSET( pedCrowd, sLocalPedData[iCrowd].eCreatorAssignedPedID, GET_ENTITY_COORDS( PLAYER_PED_ID() ), sLocalData.eHeistType )
|
|
|
|
sLocalData.shapetestBeatdownProbe = START_SHAPE_TEST_CAPSULE( GET_ENTITY_COORDS( PLAYER_PED_ID() ),
|
|
vCrowdPedCoord,
|
|
0.25,
|
|
SCRIPT_INCLUDE_ALL,
|
|
PLAYER_PED_ID(),
|
|
SCRIPT_SHAPETEST_OPTION_IGNORE_NO_COLLISION )
|
|
|
|
sLocalData.iCrowdPedBeatdownProbe = iCrowd
|
|
|
|
CDEBUG2LN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_BEATDOWNS() iCrowd = ", iCrowd, " - Starting new probe." )
|
|
|
|
// Results ready, process them
|
|
ELIF eStatus = SHAPETEST_STATUS_RESULTS_READY
|
|
|
|
// We only update this flag once the test result comes back, we do not clear it and only set it to true
|
|
// for the frames the result comes back on, this would lead to nothing happening a lot of the time input is pressed.
|
|
IF iWasSomethingHit = 0
|
|
OR ( DOES_ENTITY_EXIST( entityHit )
|
|
AND IS_ENTITY_A_PED( entityHit )
|
|
AND GET_PED_INDEX_FROM_ENTITY_INDEX( entityHit ) = pedCrowd )
|
|
SET_BIT_ENUM( sLocalData.iBitSet, CCLOCALDATA_BeatdownProbeResultAllowHit )
|
|
CDEBUG2LN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_BEATDOWNS() iCrowd = ", iCrowd, " - Probe successfull, Setting flag CCLOCALDATA_BeatdownProbeResultAllowHit" )
|
|
sLocalData.shapetestBeatdownProbe = NULL
|
|
ELSE
|
|
CDEBUG2LN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_BEATDOWNS() iCrowd = ", iCrowd, " - Probe hit something, reset probe." )
|
|
bResetProbe = TRUE
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
// SUCCESS, we are allowed to hit the ped
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_BeatdownProbeResultAllowHit )
|
|
iPedToBeat = iCrowd
|
|
CDEBUG2LN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_BEATDOWNS() iCrowd = ", iCrowd, " - CCLOCALDATA_BeatdownProbeResultAllowHit is set, allow ped to be hit." )
|
|
ENDIF
|
|
|
|
// Stop testing other peds
|
|
iCrowd = sData.iNumCrowdControlPeds // BREAK LOOP
|
|
|
|
ELSE
|
|
CDEBUG2LN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_BEATDOWNS() iCrowd = ", iCrowd, " - CAN_CROWD_CONTROL_PED_BE_BEATDOWN() failed." )
|
|
IF sLocalData.iCrowdPedBeatdownProbe = iCrowd
|
|
CDEBUG2LN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_BEATDOWNS() iCrowd = ", iCrowd, " - mark probe for reset." )
|
|
bResetProbe = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ELSE
|
|
CDEBUG2LN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_BEATDOWNS() iCrowd = ", iCrowd, " - IS_CROWD_CONTROL_PED_WITHIN_BEATDOWN_RANGE() failed." )
|
|
IF sLocalData.iCrowdPedBeatdownProbe = iCrowd
|
|
CDEBUG2LN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_BEATDOWNS() iCrowd = ", iCrowd, " - mark probe for reset." )
|
|
bResetProbe = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ELSE
|
|
CDEBUG2LN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_BEATDOWNS() iCrowd = ", iCrowd, " - ped dead or not running custom anims." )
|
|
IF sLocalData.iCrowdPedBeatdownProbe = iCrowd
|
|
CDEBUG2LN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_BEATDOWNS() iCrowd = ", iCrowd, " - mark probe for reset." )
|
|
bResetProbe = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ELSE
|
|
CDEBUG2LN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_BEATDOWNS() iCrowd = ", iCrowd, " - net id does not exist." )
|
|
IF sLocalData.iCrowdPedBeatdownProbe = iCrowd
|
|
CDEBUG2LN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_BEATDOWNS() iCrowd = ", iCrowd, " - mark probe for reset." )
|
|
bResetProbe = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF bResetProbe
|
|
CDEBUG2LN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_BEATDOWNS() iCrowd = ", iCrowd, " - resetting probe, clearing flag CCLOCALDATA_BeatdownProbeResultAllowHit, sLocalData.iCrowdPedBeatdownProbe = ", sLocalData.iCrowdPedBeatdownProbe )
|
|
sLocalData.shapetestBeatdownProbe = NULL
|
|
sLocalData.iCrowdPedBeatdownProbe = -1
|
|
CLEAR_BIT_ENUM( sLocalData.iBitSet, CCLOCALDATA_BeatdownProbeResultAllowHit )
|
|
ENDIF
|
|
|
|
ENDREPEAT
|
|
|
|
ENDIF
|
|
|
|
IF bDisableMelee
|
|
DISABLE_CONTROL_ACTION( PLAYER_CONTROL, INPUT_MELEE_ATTACK_HEAVY )
|
|
DISABLE_CONTROL_ACTION( PLAYER_CONTROL, INPUT_MELEE_ATTACK_LIGHT )
|
|
DISABLE_CONTROL_ACTION( PLAYER_CONTROL, INPUT_MELEE_ATTACK_ALTERNATE )
|
|
SET_PED_CONFIG_FLAG( PLAYER_PED_ID(), PCF_DisableMelee, TRUE )
|
|
SET_PED_RESET_FLAG( PLAYER_PED_ID(), PRF_DisableAmbientMeleeMoves, TRUE )
|
|
SET_PED_RESET_FLAG( PLAYER_PED_ID(), PRF_SuspendInitiatedMeleeActions, TRUE )
|
|
ELSE
|
|
SET_PED_CONFIG_FLAG( PLAYER_PED_ID(), PCF_DisableMelee, FALSE )
|
|
ENDIF
|
|
|
|
IF bCanPlayerBeat
|
|
|
|
IF iPedToBeat != -1
|
|
|
|
IF bMeleePressed
|
|
|
|
IF bPlayerCurrentlyPerformingBeatdown
|
|
AND IS_BIT_SET_ENUM( sLocalData.iBitset, CCLOCALDATA_BeatdownInterrupt )
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_BEATDOWNS() - Beatdown has been interrupted by new melee request" )
|
|
ENDIF
|
|
|
|
WEAPON_TYPE eWeapType
|
|
GET_CURRENT_PED_WEAPON( PLAYER_PED_ID(), eWeapType )
|
|
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_BEATDOWNS() - Playing beatdown on ped[", iPedToBeat, "] = ", GET_CROWD_CONTROL_PED_NAME_FROM_ANIM_ID( sLocalPedData[iPedToBeat].eCreatorAssignedPedID ) )
|
|
|
|
PLAY_CROWD_CONTROL_BEATDOWN( niPeds[sData.iCrowdControlCloudIndex[iPedToBeat]],
|
|
iPedToBeat,
|
|
eWeapType,
|
|
sData,
|
|
sLocalData,
|
|
sPedData[iPedToBeat],
|
|
sLocalPedData[iPedToBeat] )
|
|
|
|
CLEAR_BIT_ENUM( sLocalData.iBitSet, CCLOCALDATA_BeatdownInputTaken )
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
|
|
|
|
ENDPROC
|
|
|
|
|
|
/// PURPOSE:
|
|
/// Run by each player manages the minigame state for the host and also various local assets, cutscenes, etc for each player.
|
|
PROC PROCESS_CROWD_CONTROL_MINIGAME_STATE(
|
|
CROWD_CONTROL_SERVER_DATA &sCrowdControlData, CROWD_CONTROL_LOCAL_DATA &sLocalData,
|
|
CROWD_CONTROL_PED_DECORATOR_DATA &sCrowdControlPedData[], CROWD_CONTROL_LOCAL_PED_DATA &sCrowdControlLocalPedData[],
|
|
INT &iCrowdControlPedCloudIndex[], INT iNumCrowdPeds, NETWORK_INDEX &niPeds[],
|
|
INT &iCurrentHighestPriority[], INT iLocalPlayersTeam )
|
|
|
|
UNUSED_PARAMETER(niPeds)
|
|
UNUSED_PARAMETER(iCrowdControlPedCloudIndex)
|
|
|
|
INT i
|
|
|
|
// this is here cus stupid language won't let me declare is inside a switch case, BOOOOOOOOOOOOOOOOOO
|
|
INT iLookupArray[FMMC_MAX_CROWD_PEDS]
|
|
|
|
VECTOR vAlarmCoords[ciCC_MaxAlarms]
|
|
|
|
// Custom anims required
|
|
BOOL bRequireCustomAnims
|
|
IF sLocalData.eHeistType = CCHEIST_CUSTOM_FLEECA
|
|
OR sLocalData.eHeistType = CCHEIST_CUSTOM_ORNATE
|
|
bRequireCustomAnims = TRUE
|
|
ENDIF
|
|
|
|
//STAGE ZERO - Wait for peds to initialise and start their intro idle scene
|
|
SWITCH sCrowdControlData.iMinigameStage
|
|
CASE 0
|
|
IF bRequireCustomAnims
|
|
REQUEST_MODEL( PROP_PHONE_ING )
|
|
ENDIF
|
|
|
|
IF NETWORK_IS_HOST_OF_THIS_SCRIPT()
|
|
|
|
// Check if all peds are initialised
|
|
BOOL bAllPedsReady
|
|
bAllPedsReady = TRUE
|
|
FOR i = 0 TO iNumCrowdPeds-1
|
|
IF NOT IS_BIT_SET_ENUM( sCrowdControlPedData[i].iBitSet, CCPEDDATA_HasBeenInitialised )
|
|
bAllPedsReady = FALSE
|
|
ENDIF
|
|
ENDFOR
|
|
|
|
IF bAllPedsReady
|
|
|
|
// has already been reset else where, doubling up causes some issues
|
|
//RESET_CROWD_CONTROL_LOCAL_DATA( sLocalData )
|
|
|
|
// Crowd is restricted to start with
|
|
SET_BIT_ENUM( sCrowdControlData.iBitset, CCDATA_Restricted )
|
|
|
|
// Set hero pick timer make sure an initial hero is selected
|
|
SET_BIT_ENUM( sLocalData.iBitSet, CCLOCALDATA_TimeSetNextHeroPick )
|
|
|
|
sLocalData.fFear = 0.0
|
|
sCrowdControlData.iMinigameStage++
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
//STAGE ONE - Kick off the crowd panic
|
|
CASE 1
|
|
|
|
IF bRequireCustomAnims
|
|
AND NOT IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_IntroAnimsRequested )
|
|
REQUEST_CROWD_CONTROL_PED_ANIMS_FOR_SCENE( CCPANIM_INTRO, sLocalData.eHeistType, sCrowdControlLocalPedData, iNumCrowdPeds )
|
|
REQUEST_CROWD_CONTROL_PED_ANIMS_FOR_SCENE( CCPANIM_COWER_LOOP, sLocalData.eHeistType, sCrowdControlLocalPedData, iNumCrowdPeds )
|
|
IF sLocalData.eHeistType != CCHEIST_CUSTOM_ORNATE
|
|
REQUEST_ADDITIONAL_TEXT_FOR_DLC( "OBHFAU", DLC_TEXT_SLOT0 )
|
|
ENDIF
|
|
SET_BIT_ENUM( sLocalData.iBitSet, CCLOCALDATA_IntroAnimsRequested )
|
|
ENDIF
|
|
|
|
IF NETWORK_IS_HOST_OF_THIS_SCRIPT()
|
|
|
|
BOOL bKickOffCrowd
|
|
|
|
// Has at least 1 ped kicked off?
|
|
FOR i = 0 TO iNumCrowdPeds-1
|
|
|
|
// Crowd ped is no longer in intro state
|
|
IF sCrowdControlPedData[i].eState != CCPS_INTRO
|
|
bKickOffCrowd = TRUE
|
|
i = FMMC_MAX_CROWD_PEDS // break loop
|
|
ENDIF
|
|
|
|
ENDFOR
|
|
|
|
IF bRequireCustomAnims
|
|
|
|
// SYNC SCENE: Intro transition to Cower
|
|
// (note: only 1 machine can create and start the sync scene including on peds it doesnt own this is why we are doing it this way)
|
|
IF HAVE_CROWD_CONTROL_PED_ANIMS_LOADED_FOR_SCENE( CCPANIM_INTRO, sLocalData.eHeistType, sCrowdControlLocalPedData, iNumCrowdPeds )
|
|
AND HAVE_CROWD_CONTROL_PED_ANIMS_LOADED_FOR_SCENE( CCPANIM_COWER_LOOP, sLocalData.eHeistType, sCrowdControlLocalPedData, iNumCrowdPeds )
|
|
|
|
IF NOT bKickOffCrowd
|
|
|
|
// Intro loop not running, run it
|
|
IF sLocalData.iSyncSceneIntroLoop = -1
|
|
OR NOT IS_SYNCHRONIZED_SCENE_RUNNING( NETWORK_GET_LOCAL_SCENE_FROM_NETWORK_ID( sLocalData.iSyncSceneIntroLoop ) )
|
|
|
|
PLAY_CROWD_CONTROL_SYNC_SCENE( sLocalData.iSyncSceneIntroLoop,
|
|
niPeds, iCrowdControlPedCloudIndex, sCrowdControlLocalPedData, iNumCrowdPeds,
|
|
CCPANIM_INTRO_LOOP, sLocalData.eHeistType,
|
|
REALLY_SLOW_BLEND_IN, -0.1, TRUE, FALSE,
|
|
SYNCED_SCENE_USE_PHYSICS,
|
|
RBF_PLAYER_IMPACT
|
|
)
|
|
|
|
ENDIF
|
|
|
|
ELSE
|
|
|
|
// Intro loop -> Intro main (transition to cower where it all kicks off)
|
|
PLAY_CROWD_CONTROL_SYNC_SCENE( sCrowdControlData.iSyncScene,
|
|
niPeds, iCrowdControlPedCloudIndex, sCrowdControlLocalPedData, iNumCrowdPeds,
|
|
CCPANIM_INTRO, sLocalData.eHeistType,
|
|
REALLY_SLOW_BLEND_IN, -0.1, FALSE, TRUE,
|
|
SYNCED_SCENE_USE_PHYSICS,
|
|
RBF_PLAYER_IMPACT
|
|
)
|
|
|
|
SET_BIT_ENUM( sLocalData.iBitSet, CCLOCALDATA_RecievedSyncedScene ) // host will have the sync scene straight way so set this
|
|
sCrowdControlData.iMinigameStage++
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
// No anim req so just go to the next stage
|
|
ELSE
|
|
sCrowdControlData.iMinigameStage++
|
|
|
|
ENDIF
|
|
|
|
|
|
IF sCrowdControlData.iMinigameStage > 1
|
|
|
|
// Initialise the fear to full
|
|
sLocalData.fFear = 100.0
|
|
|
|
// Set when the panic should be over
|
|
sLocalData.timeCrowdKickedOff = GET_NETWORK_TIME()
|
|
|
|
CPRINTLN( DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_MINIGAME_STATE() - bit set CCDATA_Active" )
|
|
SET_BIT_ENUM( sCrowdControlData.iBitSet, CCDATA_Active ) // Set active to inform other peds they need to kick off
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
//STAGE TWO - Main minigame controller
|
|
CASE 2
|
|
|
|
IF bRequireCustomAnims
|
|
IF NOT IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_MainAnimsRequested )
|
|
|
|
REQUEST_CROWD_CONTROL_PED_ANIMS_FOR_SCENE( CCPANIM_FLINCH_LOOP, sLocalData.eHeistType, sCrowdControlLocalPedData, iNumCrowdPeds )
|
|
REQUEST_CROWD_CONTROL_PED_ANIMS_FOR_SCENE( CCPANIM_HERO_LOOP, sLocalData.eHeistType, sCrowdControlLocalPedData, iNumCrowdPeds )
|
|
REQUEST_ANIM_DICT( GET_CROWD_CONTROL_PLAYER_ANIM_DICTIONARY( CCPLAYERANIM_BEATDOWN_RIFLE_A ) )
|
|
|
|
SET_BIT_ENUM( sLocalData.iBitSet, CCLOCALDATA_MainAnimsRequested )
|
|
ENDIF
|
|
|
|
// release the intro stuff now, we dont need it again
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_IntroAnimsRequested )
|
|
|
|
RELEASE_CROWD_CONTROL_PED_ANIMS_FOR_SCENE( CCPANIM_INTRO_LOOP, sLocalData.eHeistType, sCrowdControlLocalPedData, iNumCrowdPeds )
|
|
|
|
CLEAR_BIT_ENUM( sLocalData.iBitSet, CCLOCALDATA_IntroAnimsRequested )
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF NETWORK_IS_HOST_OF_THIS_SCRIPT()
|
|
|
|
// Fail/Pass logic
|
|
//-------------------------------------------------------------------------
|
|
|
|
// Fail not currently disabled
|
|
IF NOT IS_BIT_SET_ENUM( sCrowdControlData.iBitset, CCDATA_FailDisabled )
|
|
|
|
IF SHOULD_DISABLE_CROWD_CONTROL_FAIL( sLocalData, iCurrentHighestPriority, iLocalPlayersTeam )
|
|
|
|
SET_BIT_ENUM( sCrowdControlData.iBitset, CCDATA_FailDisabled )
|
|
|
|
// Not picked up a fail from a ped
|
|
ELIF NOT IS_BIT_SET_ENUM( sCrowdControlData.iBitset, CCDATA_Failed )
|
|
|
|
INT iDeadCount, iKnockedOutPeds
|
|
INT iDeadPedID, iKnockedOutPedID
|
|
|
|
iDeadPedID = -1
|
|
iDeadCount = GET_CROWD_CONTROL_NUMBER_OF_DEAD_PEDS_WITH_PED_ID( sCrowdControlPedData, sCrowdControlData, iDeadPedID )
|
|
|
|
iKnockedOutPedID = -1
|
|
iKnockedOutPeds = GET_CROWD_CONTROL_NUMBER_OF_KNOCKED_OUT_PEDS_WITH_PED_ID( sCrowdControlPedData, sCrowdControlData, iKnockedOutPedID )
|
|
|
|
INT iDeadLimit, iKnockoutLimit
|
|
iDeadLimit = GET_CROWD_CONTROL_PED_DEAD_LIMIT( sLocalData.eHeistType )
|
|
|
|
SWITCH sLocalData.eHeistType
|
|
CASE CCHEIST_CUSTOM_ORNATE
|
|
iKnockoutLimit = 2
|
|
BREAK
|
|
DEFAULT
|
|
iKnockoutLimit = -1
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
|
|
// dead limit reached - fail
|
|
IF iDeadCount != -1
|
|
AND iDeadCount > iDeadLimit
|
|
|
|
IF iDeadCount <= 1
|
|
sLocalData.eFailReason = CCFAIL_PEDKILLED
|
|
ELSE
|
|
sLocalData.eFailReason = CCFAIL_PEDSKILLED
|
|
ENDIF
|
|
sLocalData.iFailCausedByPed = iDeadPedID
|
|
sLocalData.timeFailDelay = GET_TIME_OFFSET( GET_NETWORK_TIME(), 2000 ) // 2 second delay
|
|
|
|
// knocked out limit reached, fail
|
|
ELIF iKnockoutLimit != -1
|
|
AND iKnockedOutPeds > iKnockoutLimit
|
|
|
|
sLocalData.eFailReason = CCFAIL_TOOMANYKNOCKOUTS
|
|
sLocalData.iFailCausedByPed = sLocalData.iCashierPed
|
|
sLocalData.timeFailDelay = GET_TIME_OFFSET( GET_NETWORK_TIME(), 3000 )
|
|
|
|
// no hits remaining
|
|
ELIF sCrowdControlData.iNumHitsRemaining <= 0
|
|
|
|
sLocalData.eFailReason = CCFAIL_NOHITSREMAINING
|
|
sLocalData.iFailCausedByPed = sLocalData.iCashierPed
|
|
sLocalData.timeFailDelay = GET_TIME_OFFSET( GET_NETWORK_TIME(), 3000 )
|
|
|
|
ELSE
|
|
|
|
CLEAR_BIT_ENUM( sCrowdControlData.iBitset, CCDATA_FearFailsBlocked )
|
|
FOR i = 0 TO FMMC_MAX_TEAMS-1
|
|
IF iCurrentHighestPriority[i] < FMMC_MAX_RULES
|
|
IF IS_BIT_SET( g_FMMC_STRUCT.sFMMCEndConditions[i].iRuleBitsetTwo[iCurrentHighestPriority[i]], ciBS_RULE2_DISABLE_CROWD_FEAR )
|
|
SET_BIT_ENUM( sCrowdControlData.iBitset, CCDATA_FearFailsBlocked )
|
|
ENDIF
|
|
ENDIF
|
|
ENDFOR
|
|
|
|
// Fail for overall fear level not acceptable
|
|
IF IS_BIT_SET_ENUM( sCrowdControlData.iBitset, CCDATA_Active )
|
|
AND NOT IS_BIT_SET_ENUM( sCrowdControlData.iBitset, CCDATA_FearFailsBlocked )
|
|
AND NOT HAVE_ALL_PLAYERS_PASSED_CROWD_CONTROL_RULE( sLocalData, iCurrentHighestPriority, iLocalPlayersTeam )
|
|
AND sLocalData.fFear != -1
|
|
AND sLocalData.fIntimidationBar != -1
|
|
AND sLocalData.fIntimidationBar <= ciCC_FearFailMin
|
|
|
|
// start the timer
|
|
IF NOT IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_TimerSetFearFail )
|
|
|
|
sLocalData.timeFearFail = GET_TIME_OFFSET( GET_NETWORK_TIME(), 2000 )
|
|
SET_BIT_ENUM( sLocalData.iBitSet, CCLOCALDATA_TimerSetFearFail )
|
|
ENDIF
|
|
|
|
// Fail by fear timer has expired and the fear is still not withint acceptable ranges
|
|
IF IS_TIME_MORE_THAN( GET_NETWORK_TIME(), sLocalData.timeFearFail )
|
|
|
|
sLocalData.eFailReason = CCFAIL_FEARLOW
|
|
sLocalData.timeFailDelay = GET_NETWORK_TIME() // no delay
|
|
sLocalData.iFailCausedByPed = sLocalData.iCashierPed
|
|
|
|
ENDIF
|
|
|
|
ELSE
|
|
// reset the fail timer
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_TimerSetFearFail )
|
|
CLEAR_BIT_ENUM( sLocalData.iBitSet, CCLOCALDATA_TimerSetFearFail )
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
IF sLocalData.eFailReason != CCFAIL_NONE
|
|
|
|
SET_BIT_ENUM( sCrowdControlData.iBitSet, CCDATA_Failed )
|
|
|
|
CPRINTLN(DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_MINIGAME_STATE() - FAIL DETECTED - Fail Reason = ", GET_CROWD_CONTROL_FAIL_REASON_STRING( sLocalData.eFailReason ) )
|
|
BROADCAST_FMMC_CC_FAIL( ENUM_TO_INT( sLocalData.eFailReason ), sLocalData.iFailCausedByPed, sLocalData.timeFailDelay )
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
// Hero picking logic
|
|
//-------------------------------------------------------------------------
|
|
|
|
SWITCH sLocalData.eHeistType
|
|
|
|
CASE CCHEIST_CUSTOM_FLEECA
|
|
|
|
// Restrict the crowd after the easy pass and the cashier is into normal cower
|
|
IF IS_BIT_SET_ENUM( sCrowdControlData.iBitset, CCDATA_EasyPassComplete )
|
|
IF NOT IS_BIT_SET_ENUM( sCrowdControlData.iBitset, CCDATA_Restricted )
|
|
SET_BIT_ENUM( sCrowdControlData.iBitset, CCDATA_Restricted )
|
|
ENDIF
|
|
ELSE
|
|
IF IS_BIT_SET_ENUM( sCrowdControlData.iBitset, CCDATA_Restricted )
|
|
CLEAR_BIT_ENUM( sCrowdControlData.iBitset, CCDATA_Restricted )
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE CCHEIST_CUSTOM_ORNATE
|
|
|
|
// Restrict the cashiers while waiting for the thermite to blow the door open objective
|
|
IF ( sLocalData.iThermiteTeam != -1 AND sLocalData.iThermiteTeam < FMMC_MAX_TEAMS
|
|
AND sLocalData.iThermiteRule != -1 AND sLocalData.iThermiteRule < FMMC_MAX_RULES
|
|
AND iCurrentHighestPriority[sLocalData.iThermiteTeam] > sLocalData.iThermiteRule )
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
OR IS_BIT_SET_ENUM( sCrowdControlData.iBitset, CCDATA_RestrictedDebug )
|
|
#ENDIF
|
|
IF IS_BIT_SET_ENUM( sCrowdControlData.iBitset, CCDATA_Restricted )
|
|
CLEAR_BIT_ENUM( sCrowdControlData.iBitset, CCDATA_Restricted )
|
|
ENDIF
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
// Clear any active heros that are no longer valid
|
|
INT iLowestHeroAttempts
|
|
iLowestHeroAttempts = -1
|
|
FOR i = 0 TO iNumCrowdPeds-1
|
|
|
|
INT iCurrentHeroAttemptsValue
|
|
iCurrentHeroAttemptsValue = GET_PACKED_BITFIELD_VALUE_FROM_ARRAY( sCrowdControlData.iHeroAttempts, i, ciCC_HeroAttemptsDataBitWidth )
|
|
|
|
IF IS_BIT_SET( sCrowdControlData.iCurrentActiveHeros, i )
|
|
|
|
// If the mission has failed or passed or the hero is no longer valid or the crowd is now locked in clear the hero
|
|
IF IS_BIT_SET_ENUM( sCrowdControlPedData[i].iBitSet, CCPEDDATA_Dead )
|
|
OR IS_BIT_SET_ENUM( sCrowdControlPedData[i].iBitSet, CCPEDDATA_KnockedOut )
|
|
OR IS_BIT_SET_ENUM( sCrowdControlData.iBitset, CCDATA_Failed )
|
|
OR IS_BIT_SET_ENUM( sCrowdControlData.iBitset, CCDATA_FailDisabled )
|
|
OR ( NOT IS_CROWD_CONTROL_PED_A_VALID_HERO( sCrowdControlPedData[i], sCrowdControlLocalPedData[i].eCreatorAssignedPedID, sLocalData.eHeistType, IS_BIT_SET_ENUM( sCrowdControlData.iBitset, CCDATA_Restricted ) )
|
|
AND sCrowdControlPedData[i].eState != CCPS_HERO_ATTEMPT
|
|
AND sCrowdControlPedData[i].eState != CCPS_HERO
|
|
AND sCrowdControlPedData[i].eState != CCPS_COMBAT )
|
|
|
|
// Increment the attempts by 1
|
|
IF IS_BIT_SET_ENUM( sCrowdControlPedData[i].iBitSet, CCPEDDATA_HeroAttempted )
|
|
iCurrentHeroAttemptsValue++
|
|
SET_PACKED_BITFIELD_VALUE_IN_ARRAY( sCrowdControlData.iHeroAttempts, i, ciCC_HeroAttemptsDataBitWidth, iCurrentHeroAttemptsValue )
|
|
ENDIF
|
|
|
|
CLEAR_BIT( sCrowdControlData.iCurrentActiveHeros, i )
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
// Check out all valid heroes who are not always active and see who has the lowest number of attempts
|
|
IF NOT IS_BIT_SET_ENUM( sCrowdControlPedData[i].iBitSet, CCPEDDATA_Dead )
|
|
AND NOT IS_BIT_SET_ENUM( sCrowdControlPedData[i].iBitSet, CCPEDDATA_KnockedOut )
|
|
AND NOT IS_CROWD_CONTROL_PED_HERO_ALWAYS_ACTIVE( sCrowdControlLocalPedData[i].eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
AND IS_CROWD_CONTROL_PED_A_VALID_HERO( sCrowdControlPedData[i], sCrowdControlLocalPedData[i].eCreatorAssignedPedID, sLocalData.eHeistType, IS_BIT_SET_ENUM( sCrowdControlData.iBitset, CCDATA_Restricted ) )
|
|
|
|
IF iLowestHeroAttempts = -1
|
|
OR iCurrentHeroAttemptsValue < iLowestHeroAttempts
|
|
iLowestHeroAttempts = iCurrentHeroAttemptsValue
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDFOR
|
|
|
|
// Either minigame has failed or the fail has now been disabled, don't assign heros and go to next stage
|
|
IF IS_BIT_SET_ENUM( sCrowdControlData.iBitset, CCDATA_FailDisabled )
|
|
OR IS_BIT_SET_ENUM( sCrowdControlData.iBitset, CCDATA_Failed )
|
|
|
|
sCrowdControlData.iMinigameStage++
|
|
|
|
ELSE
|
|
|
|
INT iHeroCount
|
|
FOR i = 0 TO iNumCrowdPeds-1
|
|
|
|
// Initialse look up array with start numbers
|
|
iLookupArray[i] = i
|
|
|
|
// Count the current number of active regular heroes
|
|
IF IS_BIT_SET( sCrowdControlData.iCurrentActiveHeros, i )
|
|
IF NOT IS_CROWD_CONTROL_PED_HERO_ALWAYS_ACTIVE( sCrowdControlLocalPedData[i].eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
iHeroCount++
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Make sure always active heros are turned on now
|
|
IF NOT IS_BIT_SET_ENUM( sCrowdControlPedData[i].iBitSet, CCPEDDATA_Dead )
|
|
AND NOT IS_BIT_SET_ENUM( sCrowdControlPedData[i].iBitSet, CCPEDDATA_KnockedOut )
|
|
AND IS_CROWD_CONTROL_PED_HERO_ALWAYS_ACTIVE( sCrowdControlLocalPedData[i].eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
AND IS_CROWD_CONTROL_PED_A_VALID_HERO( sCrowdControlPedData[i], sCrowdControlLocalPedData[i].eCreatorAssignedPedID, sLocalData.eHeistType, IS_BIT_SET_ENUM( sCrowdControlData.iBitset, CCDATA_Restricted ) )
|
|
CPRINTLN(DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_MINIGAME_STATE() - HERO SELECTED(always on hero) = ", GET_CROWD_CONTROL_PED_NAME_FROM_ANIM_ID( sCrowdControlLocalPedData[i].eCreatorAssignedPedID ) )
|
|
SET_BIT( sCrowdControlData.iCurrentActiveHeros, i )
|
|
ENDIF
|
|
|
|
ENDFOR
|
|
|
|
|
|
// Setup to only pick 1 new normal hero each time, even if we increase the max active heroes we still want this
|
|
// so that we have a delay between heroes becoming active to avoid getting 2 becoming active at the same time
|
|
// Only pick a new hero if there is space
|
|
IF iHeroCount < ciCC_MaxActiveHeros
|
|
|
|
IF NOT IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_TimeSetNextHeroPick )
|
|
// Random time between 10 - 25 seconds (in 1 second intervals)
|
|
sLocalData.timeNextHeroPick = GET_TIME_OFFSET( GET_NETWORK_TIME(), GET_RANDOM_INT_IN_RANGE( 7, 15 ) * 1000 )
|
|
SET_BIT_ENUM( sLocalData.iBitSet, CCLOCALDATA_TimeSetNextHeroPick )
|
|
ENDIF
|
|
|
|
// If the hero pick timer has expired then select a new hero
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_TimeSetNextHeroPick )
|
|
AND IS_TIME_MORE_THAN( GET_NETWORK_TIME(), sLocalData.timeNextHeroPick )
|
|
|
|
// Randomise array by using random value switching
|
|
FOR i = 0 TO iNumCrowdPeds-1
|
|
INT iRand, iTemp
|
|
iRand = GET_RANDOM_INT_IN_RANGE( 0, iNumCrowdPeds )
|
|
iTemp = iLookupArray[i]
|
|
iLookupArray[i] = iLookupArray[iRand]
|
|
iLookupArray[iRand] = iTemp
|
|
ENDFOR
|
|
|
|
// Set new heros in the random array
|
|
FOR i = 0 TO iNumCrowdPeds-1
|
|
|
|
// Check if we can set this hero active
|
|
IF NOT IS_BIT_SET( sCrowdControlData.iCurrentActiveHeros, iLookupArray[i] )
|
|
AND NOT IS_BIT_SET_ENUM( sCrowdControlPedData[i].iBitSet, CCPEDDATA_Dead )
|
|
AND NOT IS_BIT_SET_ENUM( sCrowdControlPedData[i].iBitSet, CCPEDDATA_KnockedOut )
|
|
AND IS_CROWD_CONTROL_PED_A_VALID_HERO( sCrowdControlPedData[iLookupArray[i]], sCrowdControlLocalPedData[iLookupArray[i]].eCreatorAssignedPedID, sLocalData.eHeistType, IS_BIT_SET_ENUM( sCrowdControlData.iBitset, CCDATA_Restricted ) )
|
|
AND NOT IS_CROWD_CONTROL_PED_HERO_ALWAYS_ACTIVE( sCrowdControlLocalPedData[iLookupArray[i]].eCreatorAssignedPedID, sLocalData.eHeistType )
|
|
AND GET_PACKED_BITFIELD_VALUE_FROM_ARRAY( sCrowdControlData.iHeroAttempts, iLookupArray[i], ciCC_HeroAttemptsDataBitWidth ) = iLowestHeroAttempts
|
|
|
|
CPRINTLN(DEBUG_NET_MINIGAME, "PROCESS_CROWD_CONTROL_MINIGAME_STATE() - HERO SELECTED = ", GET_CROWD_CONTROL_PED_NAME_FROM_ANIM_ID( sCrowdControlLocalPedData[iLookupArray[i]].eCreatorAssignedPedID ) )
|
|
SET_BIT( sCrowdControlData.iCurrentActiveHeros, iLookupArray[i] )
|
|
|
|
// Reset the hero pick timer and break the loop, only want to pick 1 this timer around
|
|
CLEAR_BIT_ENUM( sLocalData.iBitSet, CCLOCALDATA_TimeSetNextHeroPick )
|
|
i = FMMC_MAX_CROWD_PEDS // break the loop
|
|
ENDIF
|
|
|
|
ENDFOR
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
// Client machines check to see if their synced scene has started and if they can start updating the individual
|
|
// peds that they own
|
|
IF NOT IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_RecievedSyncedScene )
|
|
|
|
IF sCrowdControlData.iSyncScene != -1
|
|
|
|
INT iLocalSSID
|
|
iLocalSSID = NETWORK_GET_LOCAL_SCENE_FROM_NETWORK_ID( sCrowdControlData.iSyncScene )
|
|
IF IS_SYNCHRONIZED_SCENE_RUNNING( iLocalSSID )
|
|
AND GET_SYNCHRONIZED_SCENE_PHASE( iLocalSSID ) > 0.5 // gives time for the anims to start
|
|
SET_BIT_ENUM( sLocalData.iBitSet, CCLOCALDATA_RecievedSyncedScene )
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
//STAGE THREE - Post Crowd Control - Pass/Fail
|
|
CASE 3
|
|
|
|
// Cleanup assets
|
|
//----------------------------------------------------------------------------------
|
|
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_MainAnimsRequested )
|
|
|
|
BOOL bAllCleanedUp
|
|
bAllCleanedUp = TRUE
|
|
|
|
FOR i = 0 TO sCrowdControlData.iNumCrowdControlPeds-1
|
|
|
|
IF NOT NETWORK_DOES_ENTITY_EXIST_WITH_NETWORK_ID( niPeds[sCrowdControlData.iCrowdControlCloudIndex[i]] )
|
|
OR IS_PED_INJURED( NET_TO_PED( niPeds[sCrowdControlData.iCrowdControlCloudIndex[i]] ) )
|
|
|
|
RELEASE_CROWD_CONTROL_PED_ANIM( CCPANIM_COWER_LOOP, sLocalData.eHeistType, sCrowdControlLocalPedData[i].eCreatorAssignedPedID )
|
|
RELEASE_CROWD_CONTROL_PED_ANIM( CCPANIM_FLINCH_LOOP, sLocalData.eHeistType, sCrowdControlLocalPedData[i].eCreatorAssignedPedID )
|
|
RELEASE_CROWD_CONTROL_PED_ANIM( CCPANIM_HERO_LOOP, sLocalData.eHeistType, sCrowdControlLocalPedData[i].eCreatorAssignedPedID )
|
|
|
|
ELSE
|
|
bAllCleanedUp = FALSE
|
|
ENDIF
|
|
|
|
ENDFOR
|
|
|
|
IF bAllCleanedUp
|
|
|
|
REMOVE_ANIM_DICT( GET_CROWD_CONTROL_PLAYER_ANIM_DICTIONARY( CCPLAYERANIM_BEATDOWN_PISTOL_A ) )
|
|
|
|
CLEAR_BIT_ENUM( sLocalData.iBitSet, CCLOCALDATA_MainAnimsRequested )
|
|
ENDIF
|
|
ENDIF
|
|
|
|
|
|
// Raise the alarms
|
|
//----------------------------------------------------------------------------------
|
|
|
|
IF IS_BIT_SET_ENUM( sCrowdControlData.iBitset, CCDATA_Failed )
|
|
|
|
BOOL bAlarmAvailable
|
|
TEXT_LABEL_23 tlAlarmSoundBank
|
|
TEXT_LABEL_23 tlAlarmName
|
|
TEXT_LABEL_23 tlAlarmSountSet
|
|
|
|
SWITCH sLocalData.eHeistType
|
|
|
|
CASE CCHEIST_CUSTOM_FLEECA
|
|
|
|
bAlarmAvailable = TRUE
|
|
|
|
tlAlarmSoundBank = "ALARM_BELL_01"
|
|
tlAlarmName = "Bell_01"
|
|
tlAlarmSountSet = "ALARMS_SOUNDSET"
|
|
|
|
vAlarmCoords[0] = <<-2965.2305, 486.2513, 17.5822>>
|
|
|
|
BREAK
|
|
|
|
CASE CCHEIST_CUSTOM_ORNATE
|
|
|
|
bAlarmAvailable = TRUE
|
|
|
|
tlAlarmSoundBank = "ALARM_BELL_01"
|
|
tlAlarmName = "Bell_01"
|
|
tlAlarmSountSet = "ALARMS_SOUNDSET"
|
|
|
|
vAlarmCoords[0] = <<246.5,228.0,113.3>>
|
|
vAlarmCoords[1] = <<260.3,216.0,104.1>>
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
// Process loading and playing the alarms, if one is avilable
|
|
IF bAlarmAvailable
|
|
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_RaiseAlarms )
|
|
AND NOT IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_AlarmsPlaying )
|
|
|
|
IF REQUEST_SCRIPT_AUDIO_BANK( tlAlarmSoundBank )
|
|
|
|
REPEAT ciCC_MaxAlarms i
|
|
|
|
IF sLocalData.iSFXAlarms[i] = -1
|
|
sLocalData.iSFXAlarms[i] = GET_SOUND_ID()
|
|
ENDIF
|
|
|
|
IF sLocalData.iSFXAlarms[i] != -1
|
|
IF HAS_SOUND_FINISHED( sLocalData.iSFXAlarms[i] )
|
|
PLAY_SOUND_FROM_COORD( sLocalData.iSFXAlarms[i], tlAlarmName, vAlarmCoords[i], tlAlarmSountSet )
|
|
ENDIF
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
SET_BIT_ENUM( sLocalData.iBitSet, CCLOCALDATA_AlarmsPlaying )
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
|
|
ENDSWITCH
|
|
|
|
|
|
ENDPROC
|
|
|
|
|
|
PROC PROCESS_CROWD_CONTROL_MINIGAME_HUD(
|
|
CROWD_CONTROL_SERVER_DATA &sCrowdControlServerData,
|
|
CROWD_CONTROL_LOCAL_DATA &sLocalData,
|
|
BOOL bObjectiveIsCrowdControl )
|
|
|
|
IF bObjectiveIsCrowdControl
|
|
|
|
// Player has entered the bank
|
|
IF NOT IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_DisplayHUD )
|
|
IF HAS_PED_ENTERED_CROWD_CONTROL_TRIGGER_ZONE( PLAYER_PED_ID(), sLocalData, TRUE )
|
|
OR IS_BIT_SET_ENUM( sCrowdControlServerData.iBitset, CCDATA_Active )
|
|
SET_BIT_ENUM( sLocalData.iBitSet, CCLOCALDATA_DisplayHUD )
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ELSE
|
|
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_DisplayHUD )
|
|
CLEAR_BIT_ENUM( sLocalData.iBitSet, CCLOCALDATA_DisplayHUD )
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
IF NOT IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_StartedFailCutscene )
|
|
|
|
// Initialise the bar to the current level of fear
|
|
IF sLocalData.fIntimidationBar = -1
|
|
|
|
sLocalData.fIntimidationBar = 0.0
|
|
|
|
ELIF IS_BIT_SET_ENUM( sCrowdControlServerData.iBitset, CCDATA_Active )
|
|
|
|
// Interpolate the current bars value towards the desired one
|
|
IF sLocalData.fIntimidationBar < sLocalData.fFear
|
|
|
|
sLocalData.fIntimidationBar = CLAMP( sLocalData.fIntimidationBar + ( sLocalData.fIntimidationBarInterpRate * TIMESTEP() ), sLocalData.fIntimidationBar, sLocalData.fFear )
|
|
|
|
ELIF sLocalData.fIntimidationBar > sLocalData.fFear
|
|
|
|
sLocalData.fIntimidationBar = CLAMP( sLocalData.fIntimidationBar - ( sLocalData.fIntimidationBarInterpRate * TIMESTEP() ), sLocalData.fFear, sLocalData.fIntimidationBar )
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
|
|
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_DisplayHUD )
|
|
//AND NOT IS_BIT_SET(iLocalBoolCheck5,LBOOL5_PED_INVOLVED_IN_CUTSCENE)
|
|
//AND NOT IS_BIT_SET(MC_playerBD[iPartToUse].iClientBitSet,PBBOOL_FINISHED)
|
|
AND NOT g_bMissionEnding
|
|
AND NOT IS_CUTSCENE_PLAYING()
|
|
|
|
// Intimidation bar
|
|
//--------------------------------------------------------------------------------
|
|
|
|
HUD_COLOURS eColor
|
|
INT iFlashTimer
|
|
|
|
|
|
// Enable the colour change and flashing once the bar has gone above the threshold for the first time
|
|
IF NOT IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_HUDWarning )
|
|
AND sLocalData.fIntimidationBar > cfCC_PedBreakoutCowerThreshold
|
|
SET_BIT_ENUM( sLocalData.iBitSet, CCLOCALDATA_HUDWarning )
|
|
ENDIF
|
|
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_HUDWarning )
|
|
AND sLocalData.fIntimidationBar <= cfCC_PedBreakoutCowerThreshold
|
|
eColor = HUD_COLOUR_RED
|
|
ELSE
|
|
eColor = HUD_COLOUR_YELLOW
|
|
ENDIF
|
|
|
|
IF IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_HUDWarning )
|
|
AND sLocalData.fIntimidationBar <= 15.0
|
|
iFlashTimer = 999999999
|
|
ELSE
|
|
iFlashTimer = 0
|
|
ENDIF
|
|
|
|
DRAW_GENERIC_METER( ROUND( sLocalData.fIntimidationBar ), 100, "MC_CRCON_L", eColor, iFlashTimer, HUDORDER_DONTCARE, -1, -1, FALSE, TRUE )
|
|
|
|
|
|
// Help text
|
|
//--------------------------------------------------------------------------------
|
|
|
|
// HELP 1 - Brief
|
|
IF NOT IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_HelpText1 )
|
|
|
|
PRINT_HELP( "CC_HELP1", 7000 )
|
|
SET_BIT_ENUM( sLocalData.iBitSet, CCLOCALDATA_HelpText1 )
|
|
|
|
// HELP 2 - Intimidation instructions
|
|
ELIF NOT IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_HelpText2 )
|
|
|
|
IF IS_BIT_SET_ENUM( sCrowdControlServerData.iBitset, CCDATA_Active )
|
|
AND NOT IS_THIS_HELP_MESSAGE_BEING_DISPLAYED( "CC_HELP1" )
|
|
PRINT_HELP( "CC_HELP2" )
|
|
SET_BIT_ENUM( sLocalData.iBitSet, CCLOCALDATA_HelpText2 )
|
|
ENDIF
|
|
|
|
// HELP 3 - Warning about hitting peds too much
|
|
ELIF NOT IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_HelpText3 )
|
|
|
|
IF IS_BIT_SET_ENUM( sCrowdControlServerData.iBitset, CCDATA_Active )
|
|
|
|
IF sCrowdControlServerData.iNumHitsRemaining < ciCC_MaxBeatdownHitsTotal / 2
|
|
PRINT_HELP( "CC_HELP3" )
|
|
SET_BIT_ENUM( sLocalData.iBitSet, CCLOCALDATA_HelpText3 )
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ELSE
|
|
IF IS_THIS_HELP_MESSAGE_BEING_DISPLAYED( "CC_HELP1" )
|
|
OR IS_THIS_HELP_MESSAGE_BEING_DISPLAYED( "CC_HELP2" )
|
|
CLEAR_HELP()
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
|
|
CONST_FLOAT cfXOffsetStartHeader 0.03
|
|
CONST_FLOAT cfXOffsetStart 0.05
|
|
CONST_FLOAT cfYOffsetStart 0.15
|
|
CONST_FLOAT cfYOffset 0.015
|
|
|
|
PROC DISPLAY_DEBUG_PROGRESS_BAR( STRING strBarName, FLOAT fValue, INT &iCounter, FLOAT fMaxValue = 1.0, FLOAT fMinValue = 0.0, BOOL bIncludeWrittenValue = TRUE, FLOAT fUpperThreshold = -1.0, FLOAT fLowerThreshold = -1.0 )
|
|
|
|
TEXT_LABEL_63 tlDebug = strBarName
|
|
tlDebug += ": "
|
|
IF bIncludeWrittenValue
|
|
tlDebug += GET_STRING_FROM_FLOAT( fValue, 2 )
|
|
ENDIF
|
|
tlDebug += " ["
|
|
|
|
// Clamp and adjust value for rendering the bar
|
|
FLOAT fBarValue = CLAMP( fValue, fMinValue, fMaxValue )
|
|
fBarValue = ( fBarValue - fMinValue ) / ( fMaxValue - fMinValue )
|
|
|
|
INT i
|
|
FOR i = 0 TO 9
|
|
IF fBarValue > ( i / 10.0 )
|
|
tlDebug += "x"
|
|
ELSE
|
|
tlDebug += "."
|
|
ENDIF
|
|
ENDFOR
|
|
tlDebug += "]"
|
|
IF ( fUpperThreshold != -1 AND fValue >= fUpperThreshold )
|
|
OR ( fLowerThreshold != -1 AND fValue <= fLowerThreshold )
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<cfXOffsetStart, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, ciCC_DebugColWarningR, ciCC_DebugColWarningG, ciCC_DebugColWarningB, 255 )
|
|
ELSE
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<cfXOffsetStart, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, 255 )
|
|
ENDIF
|
|
iCounter++
|
|
|
|
ENDPROC
|
|
|
|
|
|
PROC DISPLAY_CROWD_CONTROL_DEBUG(
|
|
CROWD_CONTROL_SERVER_DATA &sCrowdControlData, CROWD_CONTROL_LOCAL_DATA &sLocalData,
|
|
INT &iThreatenData[], INT iNumCrowdPeds, INT &iCurrentHighestPriority[], INT iThisTeam )
|
|
|
|
IF sLocalData.eDebugDisplay != CCDEBUG_OFF
|
|
|
|
INT iCounter
|
|
TEXT_LABEL_63 tlDebug
|
|
|
|
tlDebug = "CROWD CONTROL DEBUG: "
|
|
tlDebug += GET_CROWD_CONTROL_DEBUG_NAME( sLocalData.eDebugDisplay )
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<cfXOffsetStartHeader, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, 255, 255, 255, 255 )
|
|
iCounter++
|
|
|
|
tlDebug = "STATE DATA"
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<cfXOffsetStartHeader, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, 255, 255, 255, 255 )
|
|
iCounter++
|
|
|
|
IF NETWORK_IS_HOST_OF_THIS_SCRIPT()
|
|
tlDebug = "I AM HOST"
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<cfXOffsetStart, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, ciCC_DebugColActiveR, ciCC_DebugColActiveG, ciCC_DebugColActiveB, 255 )
|
|
ELSE
|
|
tlDebug = "I AM A CLIENT"
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<cfXOffsetStart, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, 255 )
|
|
ENDIF
|
|
iCounter++
|
|
|
|
tlDebug = "eHeistType: "
|
|
tlDebug += GET_CROWD_CONTROL_HEIST_TYPE_STRING( sLocalData.eHeistType )
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<cfXOffsetStart, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, 255 )
|
|
iCounter++
|
|
|
|
tlDebug = "iMinigameStage: "
|
|
tlDebug += sCrowdControlData.iMinigameStage
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<cfXOffsetStart, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, 255 )
|
|
iCounter++
|
|
|
|
INT i
|
|
FOR i = 0 TO FMMC_MAX_TEAMS-1
|
|
tlDebug = "iPriority["
|
|
tlDebug += i
|
|
tlDebug += "]: "
|
|
tlDebug += iCurrentHighestPriority[i]
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<cfXOffsetStart, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, 255 )
|
|
iCounter++
|
|
ENDFOR
|
|
|
|
iCounter++ // space
|
|
|
|
// Bit flags
|
|
tlDebug = "CrowdControlActive: "
|
|
tlDebug += BOOL_TO_STRING( IS_BIT_SET_ENUM( sCrowdControlData.iBitSet, CCDATA_Active ) )
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<cfXOffsetStart, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, 255 )
|
|
iCounter++
|
|
|
|
tlDebug = "CrowdRestricted: "
|
|
tlDebug += BOOL_TO_STRING( IS_BIT_SET_ENUM( sCrowdControlData.iBitSet, CCDATA_Restricted ) )
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<0.05, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, 255 )
|
|
iCounter++
|
|
|
|
tlDebug = "iNumHitsRemaining: "
|
|
tlDebug += sCrowdControlData.iNumHitsRemaining
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<0.05, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, 255 )
|
|
iCounter++
|
|
|
|
iCounter++ // space
|
|
|
|
tlDebug = "PASS/FAIL"
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<cfXOffsetStartHeader, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, 255, 255, 255, 255 )
|
|
iCounter++
|
|
|
|
tlDebug = "CrowdControlFailed: "
|
|
tlDebug += BOOL_TO_STRING( IS_BIT_SET_ENUM( sCrowdControlData.iBitSet, CCDATA_Failed ) )
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<0.05, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, 255 )
|
|
iCounter++
|
|
|
|
tlDebug = "FailDisabled: "
|
|
tlDebug += BOOL_TO_STRING( IS_BIT_SET_ENUM( sCrowdControlData.iBitSet, CCDATA_FailDisabled ) )
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<0.05, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, 255 )
|
|
iCounter++
|
|
|
|
tlDebug = "FailProcessed: "
|
|
tlDebug += BOOL_TO_STRING( IS_BIT_SET_ENUM( sCrowdControlData.iBitSet, CCDATA_FailProcessed ) )
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<0.05, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, 255 )
|
|
iCounter++
|
|
|
|
tlDebug = "FailReason: "
|
|
tlDebug += GET_CROWD_CONTROL_FAIL_REASON_STRING( sLocalData.eFailReason )
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<0.05, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, 255 )
|
|
iCounter++
|
|
|
|
tlDebug = "EasyPassComplete: "
|
|
tlDebug += BOOL_TO_STRING( IS_BIT_SET_ENUM( sCrowdControlData.iBitSet, CCDATA_EasyPassComplete ) )
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<0.05, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, 255 )
|
|
iCounter++
|
|
|
|
tlDebug = "EasyPassProcessed: "
|
|
tlDebug += BOOL_TO_STRING( IS_BIT_SET_ENUM( sCrowdControlData.iBitSet, CCDATA_EasyPassProcessed ) )
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<0.05, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, 255 )
|
|
iCounter++
|
|
|
|
tlDebug = "FearFailsBlocked: "
|
|
tlDebug += BOOL_TO_STRING( IS_BIT_SET_ENUM( sCrowdControlData.iBitSet, CCDATA_FearFailsBlocked ) )
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<0.05, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, 255 )
|
|
iCounter++
|
|
|
|
tlDebug = "RaiseAlarms: "
|
|
tlDebug += BOOL_TO_STRING( IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_RaiseAlarms ) )
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<0.05, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, 255 )
|
|
iCounter++
|
|
|
|
tlDebug = "RaiseAlarmDialogue: "
|
|
tlDebug += BOOL_TO_STRING( IS_BIT_SET_ENUM( sCrowdControlData.iBitSet, CCDATA_RaiseAlarmDiagloue ) )
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<0.05, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, 255 )
|
|
iCounter++
|
|
|
|
iCounter++ // space
|
|
|
|
IF sLocalData.eDebugDisplay = CCDEBUG_FEAR_AND_THREATS
|
|
OR sLocalData.eDebugDisplay = CCDEBUG_ALL
|
|
OR sLocalData.eDebugDisplay = CCDEBUG_BASIC
|
|
|
|
tlDebug = "FEAR & THREATS"
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<cfXOffsetStartHeader, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, 255, 255, 255, 255 )
|
|
iCounter++
|
|
|
|
DISPLAY_DEBUG_PROGRESS_BAR( "Fear(Local)", sLocalData.fFear, iCounter, 100.0, 0.0, DEFAULT, -1, cfCC_PedBreakoutCowerThreshold )
|
|
DISPLAY_DEBUG_PROGRESS_BAR( "Fear(Server)", sCrowdControlData.fFear, iCounter, 100.0, 0.0, DEFAULT, -1, cfCC_PedBreakoutCowerThreshold )
|
|
DISPLAY_DEBUG_PROGRESS_BAR( "Intimidation", sLocalData.fIntimidationBar, iCounter, 100.0, 0.0, DEFAULT, -1, cfCC_PedBreakoutCowerThreshold )
|
|
|
|
tlDebug = "BarInterpRate: "
|
|
tlDebug += GET_STRING_FROM_FLOAT( sLocalData.fIntimidationBarInterpRate )
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<0.05, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, 255 )
|
|
iCounter++
|
|
|
|
DISPLAY_DEBUG_PROGRESS_BAR( "PlayerVoice", NETWORK_GET_PLAYER_LOUDNESS( PLAYER_ID() ), iCounter, DEFAULT, DEFAULT, DEFAULT, cfCC_ShoutVolumeLevel )
|
|
|
|
// Players threats to each crowd member
|
|
FOR i = 0 TO iNumCrowdPeds-1
|
|
|
|
tlDebug = "["
|
|
tlDebug += i
|
|
tlDebug += "]: "
|
|
tlDebug += GET_CROWD_CONTROL_THREAT_TYPE_STRING( INT_TO_ENUM( CROWD_CONTROL_THREAT_TYPE, GET_PACKED_BITFIELD_VALUE_FROM_ARRAY( iThreatenData, i, ciCC_ThreatTypeDataBitWidth ) ) )
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<cfXOffsetStart, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, 255 )
|
|
iCounter++
|
|
|
|
ENDFOR
|
|
|
|
iCounter++ // space
|
|
|
|
ENDIF
|
|
|
|
// BEATDOWNS
|
|
//--------------------------------------------------------------------------------
|
|
IF sLocalData.eDebugDisplay = CCDEBUG_BEATDOWNS
|
|
OR sLocalData.eDebugDisplay = CCDEBUG_ALL
|
|
OR sLocalData.eDebugDisplay = CCDEBUG_BASIC
|
|
|
|
tlDebug = "BEATDOWN"
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<cfXOffsetStartHeader, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, 255, 255, 255, 255 )
|
|
iCounter++
|
|
|
|
tlDebug = "iCrowdPedBeatdownProbe: "
|
|
tlDebug += sLocalData.iCrowdPedBeatdownProbe
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<cfXOffsetStart, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, 255 )
|
|
iCounter++
|
|
|
|
tlDebug = "ProbeResultAllowHit: "
|
|
tlDebug += BOOL_TO_STRING( IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_BeatdownProbeResultAllowHit ) )
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<cfXOffsetStart, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, 255 )
|
|
iCounter++
|
|
|
|
iCounter++ // space
|
|
|
|
ENDIF
|
|
|
|
// Misc
|
|
//--------------------------------------------------------------------------------
|
|
|
|
IF sLocalData.eDebugDisplay = CCDEBUG_MISC
|
|
OR sLocalData.eDebugDisplay = CCDEBUG_ALL
|
|
OR sLocalData.eDebugDisplay = CCDEBUG_BASIC
|
|
|
|
tlDebug = "MISC DATA"
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<cfXOffsetStartHeader, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, 255, 255, 255, 255 )
|
|
iCounter++
|
|
|
|
tlDebug = "DisplayHUD: "
|
|
tlDebug += BOOL_TO_STRING( IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_DisplayHUD ) )
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<0.05, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, 255 )
|
|
iCounter++
|
|
|
|
tlDebug = "ReceivedSyncScene: "
|
|
tlDebug += BOOL_TO_STRING( IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_RecievedSyncedScene ) )
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<0.05, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, 255 )
|
|
iCounter++
|
|
|
|
tlDebug = "SSIntroToCower: "
|
|
tlDebug += sCrowdControlData.iSyncScene
|
|
INT iSyncSceneLocal = NETWORK_GET_LOCAL_SCENE_FROM_NETWORK_ID( sCrowdControlData.iSyncScene )
|
|
tlDebug += "("
|
|
tlDebug += iSyncSceneLocal
|
|
tlDebug += ")"
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<cfXOffsetStart, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, 255 )
|
|
iCounter++
|
|
|
|
tlDebug = "SSIntroLoop: "
|
|
tlDebug += sLocalData.iSyncSceneIntroLoop
|
|
iSyncSceneLocal = NETWORK_GET_LOCAL_SCENE_FROM_NETWORK_ID( sCrowdControlData.iSyncScene )
|
|
tlDebug += "("
|
|
tlDebug += iSyncSceneLocal
|
|
tlDebug += ")"
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<cfXOffsetStart, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, 255 )
|
|
iCounter++
|
|
|
|
tlDebug = "iCCRule["
|
|
tlDebug += iThisTeam
|
|
tlDebug += "]: "
|
|
tlDebug += sLocalData.iCCRule[iThisTeam]
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<cfXOffsetStart, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, 255 )
|
|
iCounter++
|
|
|
|
tlDebug = "BlockingActionMode"
|
|
tlDebug += BOOL_TO_STRING( IS_BIT_SET_ENUM( sLocalData.iBitSet, CCLOCALDATA_BlockingActionMode ) )
|
|
DRAW_DEBUG_TEXT_2D( tlDebug, <<cfXOffsetStart, cfYOffsetStart + (cfYOffset * iCounter), 0.0>>, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, 255 )
|
|
iCounter++
|
|
|
|
iCounter++ // space
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
|
|
|
|
PROC DISPLAY_CROWD_CONTROL_PED_DEBUG( PED_INDEX ped, CROWD_CONTROL_SERVER_DATA &sData, CROWD_CONTROL_LOCAL_DATA &sLocalData, CROWD_CONTROL_PED_DECORATOR_DATA &sPedData, CROWD_CONTROL_LOCAL_PED_DATA &sLocalPedData, INT iCrowdNum, BOOL bIsOwned )
|
|
|
|
IF sLocalData.eDebugDisplay != CCDEBUG_OFF
|
|
|
|
CONST_INT icXOffset 10
|
|
CONST_INT icYOffset 10
|
|
|
|
IF DOES_ENTITY_EXIST( ped )
|
|
|
|
VECTOR vPlayerCoord = GET_ENTITY_COORDS( PLAYER_PED_ID(), FALSE )
|
|
VECTOR vPedCoord = GET_ENTITY_COORDS( ped, FALSE )
|
|
|
|
IF NOT IS_VECTOR_ZERO( vPedCoord )
|
|
|
|
vPedCoord.Z += 0.75
|
|
|
|
FLOAT fDist = GET_DISTANCE_BETWEEN_COORDS( GET_FINAL_RENDERED_CAM_COORD(), vPedCoord )
|
|
INT iAlpha = ROUND( 255 * ( 1 - CLAMP( FMAX( fDist - 5.0, 0.0 ) / 10.0, 0.0, 1.0 ) ) )
|
|
|
|
INT iCounter
|
|
TEXT_LABEL_63 tlDebug
|
|
|
|
// BASIC
|
|
//--------------------------------------------------------------------------------
|
|
tlDebug = "BASIC"
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, 0, icYOffset * iCounter, 255, 255, 255, iAlpha )
|
|
iCounter++
|
|
|
|
IF bIsOwned
|
|
tlDebug = "OWNED"
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColActiveR, ciCC_DebugColActiveG, ciCC_DebugColActiveB, iAlpha )
|
|
ELSE
|
|
tlDebug = "REMOTE"
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
ENDIF
|
|
iCounter++
|
|
|
|
tlDebug = "["
|
|
tlDebug += iCrowdNum
|
|
tlDebug += "] "
|
|
tlDebug += GET_CROWD_CONTROL_PED_NAME_FROM_ANIM_ID( sLocalPedData.eCreatorAssignedPedID )
|
|
IF IS_BIT_SET( sData.iCurrentActiveHeros, iCrowdNum )
|
|
OR IS_BIT_SET_ENUM( sPedData.iBitSet, CCPEDDATA_HeroComplete )
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColWarningR, ciCC_DebugColWarningG, ciCC_DebugColWarningB, iAlpha )
|
|
ELSE
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
ENDIF
|
|
iCounter++
|
|
|
|
tlDebug = "State: "
|
|
tlDebug += GET_CROWD_CONTROL_PED_STATE_STRING( sPedData.eState )
|
|
SWITCH sPedData.eState
|
|
CASE CCPS_COMBAT
|
|
CASE CCPS_HERO_ATTEMPT
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColWarningR, ciCC_DebugColWarningG, ciCC_DebugColWarningB, iAlpha )
|
|
BREAK
|
|
DEFAULT
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
BREAK
|
|
ENDSWITCH
|
|
iCounter++
|
|
|
|
tlDebug = "StatePrev: "
|
|
tlDebug += GET_CROWD_CONTROL_PED_STATE_STRING( sPedData.eStatePrev )
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
iCounter++
|
|
|
|
IF NOT IS_PED_INJURED( ped )
|
|
tlDebug = "Speech: "
|
|
IF IS_ANY_SPEECH_PLAYING( ped )
|
|
IF IS_AMBIENT_SPEECH_PLAYING( ped )
|
|
tlDebug += "Dialogue"
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColActiveR, ciCC_DebugColActiveG, ciCC_DebugColActiveB, iAlpha )
|
|
ELSE
|
|
tlDebug += "Pain"
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColWarningR, ciCC_DebugColWarningG, ciCC_DebugColWarningB, iAlpha )
|
|
ENDIF
|
|
ELSE
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
ENDIF
|
|
ENDIF
|
|
iCounter++
|
|
|
|
iCounter++ // space
|
|
|
|
// FEAR
|
|
//--------------------------------------------------------------------------------
|
|
IF sLocalData.eDebugDisplay = CCDEBUG_FEAR_AND_THREATS
|
|
OR sLocalData.eDebugDisplay = CCDEBUG_ALL
|
|
|
|
tlDebug = "FEAR & THREATS"
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, 0, icYOffset * iCounter, 255, 255, 255, iAlpha )
|
|
iCounter++
|
|
|
|
tlDebug = "InfluenceDirectThreat: "
|
|
tlDebug += GET_STRING_FROM_FLOAT( sPedData.fInfluenceDirectThreat, 2 )
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
iCounter++
|
|
|
|
tlDebug = "InfluenceShouting: "
|
|
tlDebug += GET_STRING_FROM_FLOAT( sPedData.fInfluenceShouting, 2 )
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
iCounter++
|
|
|
|
tlDebug = "CCPEDDATA_FearLocked: "
|
|
tlDebug += BOOL_TO_STRING( IS_BIT_SET_ENUM( sPedData.iBitSet, CCPEDDATA_FearLocked ) )
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
iCounter++
|
|
|
|
iCounter++ // space
|
|
|
|
IF bIsOwned
|
|
|
|
tlDebug = "*OWNER ONLY* eBiggestThreat: "
|
|
tlDebug += GET_CROWD_CONTROL_THREAT_TYPE_STRING( sLocalPedData.eBiggestThreat )
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
iCounter++
|
|
|
|
tlDebug = "*OWNER ONLY* eThreatFelt: "
|
|
tlDebug += GET_CROWD_CONTROL_THREAT_TYPE_STRING( sLocalPedData.eDebugThreatFelt )
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
iCounter++
|
|
|
|
// draw line between ped and the player threatening them
|
|
IF DOES_ENTITY_EXIST( sLocalPedData.pedBiggestThreat )
|
|
DRAW_DEBUG_LINE( vPedCoord, GET_ENTITY_COORDS( sLocalPedData.pedBiggestThreat ), 255, 0, 0, 255 )
|
|
ENDIF
|
|
|
|
iCounter++ // space
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
// HERO
|
|
//--------------------------------------------------------------------------------
|
|
IF sLocalData.eDebugDisplay = CCDEBUG_HERO
|
|
OR sLocalData.eDebugDisplay = CCDEBUG_ALL
|
|
|
|
tlDebug = "HERO"
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, 0, icYOffset * iCounter, 255, 255, 255, iAlpha )
|
|
iCounter++
|
|
|
|
tlDebug = "CCPEDDATA_HeroAttempted: "
|
|
tlDebug += BOOL_TO_STRING( IS_BIT_SET_ENUM( sPedData.iBitSet, CCPEDDATA_HeroAttempted ) )
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
iCounter++
|
|
|
|
tlDebug = "CCPEDDATA_HeroComplete: "
|
|
tlDebug += BOOL_TO_STRING( IS_BIT_SET_ENUM( sPedData.iBitSet, CCPEDDATA_HeroComplete ) )
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
iCounter++
|
|
|
|
tlDebug = "CCPEDDATA_HeroBroken: "
|
|
tlDebug += BOOL_TO_STRING( IS_BIT_SET_ENUM( sPedData.iBitSet, CCPEDDATA_HeroBroken ) )
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
iCounter++
|
|
|
|
tlDebug = "iHeroAttempts: "
|
|
tlDebug += GET_PACKED_BITFIELD_VALUE_FROM_ARRAY( sData.iHeroAttempts, iCrowdNum, ciCC_HeroAttemptsDataBitWidth )
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
iCounter++
|
|
|
|
iCounter++ // space
|
|
|
|
ENDIF
|
|
|
|
// BEATDOWNS
|
|
//--------------------------------------------------------------------------------
|
|
IF sLocalData.eDebugDisplay = CCDEBUG_BEATDOWNS
|
|
OR sLocalData.eDebugDisplay = CCDEBUG_ALL
|
|
|
|
tlDebug = "BEATDOWNS"
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, 0, icYOffset * iCounter, 255, 255, 255, iAlpha )
|
|
iCounter++
|
|
|
|
tlDebug = "iBeatdownRounds: "
|
|
tlDebug += sPedData.iBeatdownRounds
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
iCounter++
|
|
|
|
tlDebug = "iBeatdownHitsRemaining: "
|
|
tlDebug += sPedData.iBeatdownHitsRemaining
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
iCounter++
|
|
|
|
tlDebug = "BeatdownFired: "
|
|
tlDebug += BOOL_TO_STRING( IS_BIT_SET_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_BeatdownFired ) )
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
iCounter++
|
|
|
|
tlDebug = "BeatdownSyncSceneStarted: "
|
|
tlDebug += BOOL_TO_STRING( IS_BIT_SET_ENUM( sPedData.iBitSet, CCPEDDATA_BeatdownSyncSceneStarted ) )
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
iCounter++
|
|
|
|
iCounter++ // space
|
|
|
|
IF IS_BIT_SET_ENUM( sPedData.iBitSet, CCPEDDATA_RunningBespokeAnims )
|
|
|
|
VECTOR vMoverOffset
|
|
VECTOR vGroundCoord
|
|
vMoverOffset = GET_CROWD_CONTROL_PED_BEATDOWN_MOVER_OFFSET( ped, sLocalPedData.eCreatorAssignedPedID, GET_ENTITY_COORDS( PLAYER_PED_ID(), FALSE ), sLocalData.eHeistType )
|
|
vGroundCoord = vMoverOffset
|
|
GET_GROUND_Z_FOR_3D_COORD( vMoverOffset, vGroundCoord.Z )
|
|
|
|
// Melee disable range
|
|
INT iColR, iColG, iColB
|
|
// Animated melee range
|
|
FLOAT fDistToMover
|
|
fDistToMover = GET_DISTANCE_BETWEEN_ENTITY_AND_COORD( PLAYER_PED_ID(), vMoverOffset, FALSE )
|
|
IF fDistToMover <= cfCC_BeatdownDistMax
|
|
|
|
// Set the color to green
|
|
iColR = 0
|
|
iColG = 255
|
|
iColB = 0
|
|
|
|
// Draw debug showing the mover offset
|
|
VECTOR vMin, vMax
|
|
IF GET_CROWD_CONTROL_PED_BEATDOWN_MOVER_OFFSET_MIN_MAX( sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType, vMin, vMax )
|
|
|
|
vMin = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS( ped, vMin )
|
|
vMax = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS( ped, vMax )
|
|
|
|
// joining line
|
|
DRAW_DEBUG_LINE( vMin, vMax, 0, 0, 255, 255 )
|
|
|
|
// min node and line to ground
|
|
DRAW_DEBUG_LINE( vMin, <<vMin.x, vMin.y, vGroundCoord.z >>, 0, 0, 255, 255 )
|
|
DRAW_DEBUG_SPHERE( vMin, 0.03, 0, 0, 255, 255 )
|
|
|
|
// max node and line to ground
|
|
DRAW_DEBUG_LINE( vMax, <<vMax.x, vMax.y, vGroundCoord.z >>, 0, 0, 255, 255 )
|
|
DRAW_DEBUG_SPHERE( vMax, 0.03, 0, 0, 255, 255 )
|
|
|
|
ENDIF
|
|
|
|
// Mover offset
|
|
DRAW_DEBUG_SPHERE( vMoverOffset, 0.05, 255, 0, 0, 255 )
|
|
|
|
ELSE
|
|
iColR = 255
|
|
iColG = 0
|
|
iColB = 0
|
|
ENDIF
|
|
DRAW_MARKER(MARKER_CONE, vGroundCoord+<<0,0,0.01>>, <<0,0,0>>, <<0,0,0>>, <<cfCC_BeatdownDistMax*2, cfCC_BeatdownDistMax*2, 0.0>>, iColR, iColG, iColB, iAlpha )
|
|
|
|
FLOAT fCoronaHeight
|
|
IF fDistToMover <= cfCC_BeatdownMeleeDisableDist
|
|
|
|
// Draw the angle range debug once within melee disable range
|
|
FLOAT fCurrentFacingAngleRange, fPlayerHeading
|
|
VECTOR vLeftBoundary, vRightBoundary
|
|
fCurrentFacingAngleRange = GET_CROWD_CONTROL_PED_BEATDOWN_FACING_ANGLE_RANGE( vPlayerCoord, vMoverOffset )
|
|
fPlayerHeading = GET_ENTITY_HEADING( PLAYER_PED_ID() )
|
|
vLeftBoundary = GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS( vPlayerCoord, fPlayerHeading - fCurrentFacingAngleRange, << 0, cfCC_BeatdownDistMax, 0 >> )
|
|
vRightBoundary = GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS( vPlayerCoord, fPlayerHeading + fCurrentFacingAngleRange, << 0, cfCC_BeatdownDistMax, 0 >> )
|
|
|
|
IF IS_ENTITY_FACING_COORD_WITHIN_RANGE( PLAYER_PED_ID(), vMoverOffset, fCurrentFacingAngleRange )
|
|
iColR = 0
|
|
iColG = 255
|
|
iColB = 0
|
|
ELSE
|
|
iColR = 255
|
|
iColG = 50
|
|
iColB = 0
|
|
ENDIF
|
|
|
|
tlDebug = GET_STRING_FROM_FLOAT( -fCurrentFacingAngleRange, 2 )
|
|
DRAW_DEBUG_LINE( vPlayerCoord, vLeftBoundary, iColR, iColG, iColB, 255 )
|
|
DRAW_DEBUG_TEXT( tlDebug, vLeftBoundary, iColR, iColG, iColB, 255 )
|
|
|
|
tlDebug = GET_STRING_FROM_FLOAT( fCurrentFacingAngleRange, 2 )
|
|
DRAW_DEBUG_LINE( vPlayerCoord, vRightBoundary, iColR, iColG, iColB, 255 )
|
|
DRAW_DEBUG_TEXT( tlDebug, vRightBoundary, iColR, iColG, iColB, 255 )
|
|
|
|
// Melee disable corona color & height
|
|
iColR = 255
|
|
iColG = 0
|
|
iColB = 0
|
|
fCoronaHeight = 0.1
|
|
|
|
ELSE
|
|
iColR = 255
|
|
iColG = 255
|
|
iColB = 255
|
|
fCoronaHeight = 0.05
|
|
ENDIF
|
|
|
|
// Draw the disable melee corona
|
|
DRAW_MARKER(MARKER_CYLINDER, vGroundCoord, <<0,0,0>>, <<0,0,0>>, <<cfCC_BeatdownMeleeDisableDist*2, cfCC_BeatdownMeleeDisableDist*2, fCoronaHeight>>, iColR, iColG, iColB, iAlpha )
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
// Dialogue
|
|
//--------------------------------------------------------------------------------
|
|
IF sLocalData.eDebugDisplay = CCDEBUG_DIALOGUE
|
|
|
|
tlDebug = "DIALOGUE"
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, 0, icYOffset * iCounter, 255, 255, 255, iAlpha )
|
|
iCounter++
|
|
|
|
tlDebug = "Current: "
|
|
tlDebug += GET_CROWD_CONTROL_DIALOGUE_ENUM_STRING( sLocalPedData.eDialogueCurrentlyPlaying )
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
iCounter++
|
|
|
|
tlDebug = "Context: "
|
|
IF IS_ANY_SPEECH_PLAYING( ped )
|
|
IF IS_AMBIENT_SPEECH_PLAYING( ped )
|
|
TEXT_LABEL_23 tlConvo, tlDummy
|
|
INT iLine
|
|
IF GET_CROWD_CONTROL_PED_DIALOGUE_ROOT_LABEL( sLocalPedData.eCreatorAssignedPedID, sLocalPedData.eDialogueCurrentlyPlaying, sLocalData.eHeistType, tlConvo, tlDummy, iLine )
|
|
tlDebug += tlConvo
|
|
tlDebug += " ("
|
|
tlDebug += GET_CONVERSATION_LINE_FILENAME_FROM_CONVERSATION_ROOT( tlConvo, iLine )
|
|
tlDebug += ")"
|
|
ENDIF
|
|
ELSE
|
|
tlDebug += GET_AUD_DAMAGE_REASON_DEBUG_STRING( GET_CROWD_CONTROL_PED_ALTERNATIVE_PAIN_DIALOGUE( sLocalPedData.eDialogueCurrentlyPlaying ) )
|
|
ENDIF
|
|
ENDIF
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
iCounter++
|
|
|
|
tlDebug = "Client->Host: "
|
|
tlDebug += GET_CROWD_CONTROL_DIALOGUE_ENUM_STRING( sLocalPedData.eDialogueClientToHost )
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
iCounter++
|
|
|
|
tlDebug = "Host->Client: "
|
|
tlDebug += GET_CROWD_CONTROL_DIALOGUE_ENUM_STRING( sLocalPedData.eDialogueHostToClient )
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
iCounter++
|
|
|
|
iCounter++ // space
|
|
|
|
TEXT_LABEL_15 tlProfile
|
|
TEXT_LABEL_23 tlDummy
|
|
GET_CROWD_CONTROL_VOICE_RACE_GENDER_PREFIX( sLocalPedData.eCreatorAssignedPedID, sLocalData.eHeistType, tlProfile, tlDummy )
|
|
tlDebug = "Profile: "
|
|
tlDebug += tlProfile
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
iCounter++
|
|
|
|
tlDebug = "LastTriggered: "
|
|
tlDebug += GET_TIME_DIFFERENCE( sLocalPedData.timeDialogueLastBroadcast, GET_NETWORK_TIME() )
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
iCounter++
|
|
|
|
iCounter++ // space
|
|
|
|
tlDebug = "Timer(SCARED_HIGH): "
|
|
tlDebug += IMAX( 0, GET_TIME_DIFFERENCE( sLocalPedData.timeDialogueContextTimers[CCDIACONTEXT_SCARED_HIGH], GET_NETWORK_TIME() ) )
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
iCounter++
|
|
|
|
tlDebug = "Timer(SCARED_MEDIUM): "
|
|
tlDebug += IMAX( 0, GET_TIME_DIFFERENCE( sLocalPedData.timeDialogueContextTimers[CCDIACONTEXT_SCARED_MEDIUM], GET_NETWORK_TIME() ) )
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
iCounter++
|
|
|
|
tlDebug = "Timer(SCARED_LOW): "
|
|
tlDebug += IMAX( 0, GET_TIME_DIFFERENCE( sLocalPedData.timeDialogueContextTimers[CCDIACONTEXT_SCARED_LOW], GET_NETWORK_TIME() ) )
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
iCounter++
|
|
|
|
tlDebug = "Timer(SCARED_SECOND_HAND): "
|
|
tlDebug += IMAX( 0, GET_TIME_DIFFERENCE( sLocalPedData.timeDialogueContextTimers[CCDIACONTEXT_SCARED_SECOND_HAND], GET_NETWORK_TIME() ) )
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
iCounter++
|
|
|
|
tlDebug = "Timer(AMBIENT): "
|
|
tlDebug += IMAX( 0, GET_TIME_DIFFERENCE( sLocalPedData.timeDialogueContextTimers[CCDIACONTEXT_AMBIENT], GET_NETWORK_TIME() ) )
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
iCounter++
|
|
|
|
iCounter++ // space
|
|
|
|
ENDIF
|
|
|
|
// MISC
|
|
//--------------------------------------------------------------------------------
|
|
IF sLocalData.eDebugDisplay = CCDEBUG_MISC
|
|
OR sLocalData.eDebugDisplay = CCDEBUG_ALL
|
|
|
|
tlDebug = "MISC"
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, 0, icYOffset * iCounter, 255, 255, 255, iAlpha )
|
|
iCounter++
|
|
|
|
tlDebug = "CCPEDDATA_Dead: "
|
|
tlDebug += BOOL_TO_STRING( IS_BIT_SET_ENUM( sPedData.iBitSet, CCPEDDATA_Dead ) )
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
iCounter++
|
|
|
|
tlDebug = "CCPEDDATA_KnockedOut: "
|
|
tlDebug += BOOL_TO_STRING( IS_BIT_SET_ENUM( sPedData.iBitSet, CCPEDDATA_KnockedOut ) )
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
iCounter++
|
|
|
|
tlDebug = "CCPEDDATA_HasBeenInitialised: "
|
|
tlDebug += BOOL_TO_STRING( IS_BIT_SET_ENUM( sPedData.iBitSet, CCPEDDATA_HasBeenInitialised ) )
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
iCounter++
|
|
|
|
tlDebug = "CCLOCALPEDDATA_LocallyInitialised: "
|
|
tlDebug += BOOL_TO_STRING( IS_BIT_SET_ENUM( sLocalPedData.iBitSet, CCLOCALPEDDATA_LocallyInitialised ) )
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
iCounter++
|
|
|
|
tlDebug = "CCPEDDATA_RunningBespokeAnims: "
|
|
tlDebug += BOOL_TO_STRING( IS_BIT_SET_ENUM( sPedData.iBitSet, CCPEDDATA_RunningBespokeAnims ) )
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
iCounter++
|
|
|
|
tlDebug = "CCPEDDATA_IgnoreStickyBombs: "
|
|
tlDebug += BOOL_TO_STRING( IS_BIT_SET_ENUM( sPedData.iBitSet, CCPEDDATA_IgnoreStickyBombs ) )
|
|
DRAW_DEBUG_TEXT_WITH_OFFSET( tlDebug, vPedCoord, icXOffset, icYOffset * iCounter, ciCC_DebugColNormalR, ciCC_DebugColNormalG, ciCC_DebugColNormalB, iAlpha )
|
|
iCounter++
|
|
|
|
iCounter++ // space
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
|
|
#ENDIF
|
|
|
|
|
|
|