class AIActionHelper { public static function ActionDebugHelper( entity : weak< Entity >, const actionName : ref< String > ) : Bool { var actionNameCheck : String; actionNameCheck = ( ( GameObject )( entity ) ).GetTracedActionName(); if( entity || ( IsStringValid( actionNameCheck ) && IsStringValid( actionName ) ) ) { if( IsStringValid( actionNameCheck ) ) { if( StrContains( actionName, actionNameCheck ) ) { if( ( ( GameObject )( entity ) ) ) { if( ( ( GameObject )( entity ) ).IsSelectedForDebugging() ) { return true; } return false; } return true; } return false; } if( ( ( GameObject )( entity ) ) ) { if( ( ( GameObject )( entity ) ).IsSelectedForDebugging() ) { return true; } return false; } } return false; } public static function ActionDebugHelper( const actionNameCheck : ref< String >, entity : weak< Entity >, const actionName : ref< String > ) : Bool { if( entity || ( IsStringValid( actionNameCheck ) && IsStringValid( actionName ) ) ) { if( IsStringValid( actionNameCheck ) ) { if( StrContains( actionName, actionNameCheck ) ) { if( ( ( GameObject )( entity ) ) ) { if( ( ( GameObject )( entity ) ).IsSelectedForDebugging() ) { return true; } return false; } return true; } return false; } if( ( ( GameObject )( entity ) ) ) { if( ( ( GameObject )( entity ) ).IsSelectedForDebugging() ) { return true; } return false; } } return false; } public static function ActionDebugHelper( const actionNameCheck : ref< String >, const actionName : ref< String > ) : Bool { if( IsStringValid( actionNameCheck ) && IsStringValid( actionName ) ) { if( StrContains( actionName, actionNameCheck ) ) { return true; } return false; } return false; } public static function SetActionExclusivity( owner : GameObject, active : Bool ) { var puppet : ScriptedPuppet; puppet = ( ( ScriptedPuppet )( owner ) ); puppet.GetPuppetStateBlackboard().SetBool( GetAllBlackboardDefs().PuppetState.InExclusiveAction, active ); } public static function HasLostTarget( owner : ScriptedPuppet, target : GameObject ) : Bool { var threat : TrackedLocation; var targetTrackerComponent : TargetTrackerComponent; if( ( owner && target ) && ( target != owner ) ) { targetTrackerComponent = owner.GetTargetTrackerComponent(); if( targetTrackerComponent && target.IsPuppet() ) { return !( targetTrackerComponent.ThreatFromEntity( target, threat ) ); } } return false; } public static function HasCombatAICommand( owner : weak< ScriptedPuppet > ) : Bool { var aiComponent : AIHumanComponent; aiComponent = owner.GetAIControllerComponent(); if( !( aiComponent ) ) { return false; } return aiComponent.IsCommandActive( 'AICombatRelatedCommand' ); } public static function HasWorkspotAICommand( owner : weak< ScriptedPuppet > ) : Bool { var aiComponent : AIHumanComponent; aiComponent = owner.GetAIControllerComponent(); if( !( aiComponent ) ) { return false; } return aiComponent.IsCommandActive( 'AIUseWorkspotCommand' ); } public static function HasFollowerCombatAICommand( owner : weak< ScriptedPuppet > ) : Bool { var aiComponent : AIHumanComponent; aiComponent = owner.GetAIControllerComponent(); if( !( aiComponent ) ) { return false; } return aiComponent.IsCommandActive( 'AIFollowerCombatCommand' ); } public static function GetActionBlackboard( owner : ScriptedPuppet ) : IBlackboard { return owner.GetAIControllerComponent().GetActionBlackboard(); } public static function GetShootingBlackboard( owner : ScriptedPuppet ) : IBlackboard { return owner.GetAIControllerComponent().GetShootingBlackboard(); } public static function ShouldShootDirectlyAtTarget( weaponOwner : weak< GameObject >, weapon : weak< WeaponObject >, targetPosition : Vector4 ) : Bool { var coneAngle : Float; var absAngleToCombatTarget : Float; var vecToTarget : Vector4; if( weapon.IsTargetLocked() ) { return true; } if( Vector4.IsZero( targetPosition ) || !( weaponOwner.GetTargetTrackerComponent().IsPositionValid( targetPosition ) ) ) { return false; } vecToTarget = targetPosition - weapon.GetWorldPosition(); coneAngle = MinF( 6.0 * Vector4.Length( vecToTarget ), 30.0 ); absAngleToCombatTarget = AbsF( Vector4.GetAngleDegAroundAxis( vecToTarget, weapon.GetWorldForward(), weaponOwner.GetWorldUp() ) ); if( ( ( absAngleToCombatTarget >= 0.0 ) && ( coneAngle > 0.0 ) ) && ( absAngleToCombatTarget <= ( coneAngle * 0.5 ) ) ) { return true; } return false; } public static function GetTargetSlotPosition( target : weak< GameObject >, slotName : CName, out slotPosition : Vector4 ) : Bool { var slotTransform : WorldTransform; Vector4.Zero( slotPosition ); if( !( IsNameValid( slotName ) ) ) { slotName = 'Head'; } if( GetTargetSlotTransform( target, slotName, slotTransform ) ) { slotPosition = WorldPosition.ToVector4( WorldTransform.GetWorldPosition( slotTransform ) ); return true; } return false; } public static function GetTargetPositionFromPast( target : weak< GameObject >, delay : Float, out position : Vector4 ) : Bool { var targetSP : weak< ScriptedPuppet >; targetSP = ( ( ScriptedPuppet )( target ) ); if( targetSP && targetSP.GetTransformHistoryComponent() ) { position = targetSP.GetTransformHistoryComponent().GetInterpolatedPositionFromHistory( delay ); return true; } return false; } public static function GetTargetSlotTransform( target : weak< GameObject >, slotName : CName, out slotTransform : WorldTransform ) : Bool { var targetPuppet : ScriptedPuppet; var targetMuppet : Muppet; var hitRepresentationSlotComponent : SlotComponent; var slotComponent : SlotComponent; targetPuppet = ( ( ScriptedPuppet )( target ) ); if( targetPuppet ) { hitRepresentationSlotComponent = targetPuppet.GetHitRepresantationSlotComponent(); slotComponent = targetPuppet.GetSlotComponent(); } else { targetMuppet = ( ( Muppet )( target ) ); if( targetMuppet ) { hitRepresentationSlotComponent = targetMuppet.GetHitRepresantationSlotComponent(); slotComponent = targetMuppet.GetSlotComponent(); } } if( hitRepresentationSlotComponent && hitRepresentationSlotComponent.GetSlotTransform( slotName, slotTransform ) ) { return true; } if( slotComponent && slotComponent.GetSlotTransform( slotName, slotTransform ) ) { return true; } return false; } public static function AnimationsLoadedSignal( ownerPuppet : weak< ScriptedPuppet > ) { var signalId : Uint16; signalId = ownerPuppet.GetSignalTable().GetOrCreateSignal( 'AnimationsLoaded' ); ownerPuppet.GetSignalTable().Set( signalId, false ); ownerPuppet.GetSignalTable().Set( signalId, true ); } public static function CombatQueriesInit( ownerPuppet : weak< ScriptedPuppet > ) { var signalId : Uint16; var signalTable : gameBoolSignalTable; signalTable = ownerPuppet.GetSignalTable(); signalId = signalTable.GetOrCreateSignal( 'CombatQueriesRequest' ); signalTable.Set( signalId, false ); signalTable.Set( signalId, true ); } public static function TryChangingAttitudeToHostile( owner : ScriptedPuppet, target : GameObject ) : Bool { var attitudeOwner : AttitudeAgent; var attitudeTarget : AttitudeAgent; var currentAttitude : EAIAttitude; attitudeOwner = owner.GetAttitudeAgent(); attitudeTarget = target.GetAttitudeAgent(); if( !( target.IsPuppet() ) && !( target.IsSensor() ) ) { return false; } if( !( target.IsActive() ) ) { return false; } if( attitudeOwner && attitudeTarget ) { currentAttitude = attitudeOwner.GetAttitudeTowards( attitudeTarget ); switch( currentAttitude ) { case EAIAttitude.AIA_Friendly: return false; case EAIAttitude.AIA_Hostile: return true; default: if( owner.IsAggressive() ) { attitudeOwner.SetAttitudeTowardsAgentGroup( attitudeTarget, attitudeOwner, EAIAttitude.AIA_Hostile ); return true; } return false; } } return false; } public static function TryStartCombatWithTarget( owner : ScriptedPuppet, target : GameObject ) : Bool { if( AIActionHelper.TryChangingAttitudeToHostile( owner, target ) ) { TargetTrackingExtension.InjectThreat( owner, target ); return true; } return false; } public static function SetCommandCombatTarget( context : ScriptExecutionContext, target : weak< GameObject >, isPersistant : Bool, persistenceSource : Uint32 ) : Bool { if( !( target ) || ( ScriptExecutionContext.GetOwner( context ) == target ) ) { return false; } if( target.IsPuppet() ) { if( !( ScriptedPuppet.IsActive( target ) ) ) { return false; } GameObject.ChangeAttitudeToHostile( ScriptExecutionContext.GetOwner( context ), target ); TargetTrackingExtension.InjectThreat( ( ( ScriptedPuppet )( ScriptExecutionContext.GetOwner( context ) ) ), target ); if( isPersistant ) { TargetTrackingExtension.SetThreatPersistence( ( ( ScriptedPuppet )( ScriptExecutionContext.GetOwner( context ) ) ), target, true, persistenceSource ); } } ScriptExecutionContext.SetArgumentObject( context, 'CommandCombatTarget', target ); return true; } public static function ClearCommandCombatTarget( context : ScriptExecutionContext, persistenceSource : Uint32, optional ignoreCombatTargetCommand : Bool ) { var puppet : weak< ScriptedPuppet >; var tt : TargetTrackerComponent; var target : weak< GameObject >; var combatTargetCmdSourceRecord : AIThreatPersistenceSource_Record; puppet = ( ( ScriptedPuppet )( ScriptExecutionContext.GetOwner( context ) ) ); tt = puppet.GetTargetTrackerComponent(); target = ScriptExecutionContext.GetArgumentObject( context, 'CommandCombatTarget' ); TargetTrackingExtension.SetThreatPersistence( puppet, target, false, persistenceSource ); if( !( ignoreCombatTargetCommand ) && tt ) { combatTargetCmdSourceRecord = TweakDBInterface.GetAIThreatPersistenceSourceRecord( T"AIThreatPersistenceSource.CommandInjectCombatTarget" ); if( tt.GetThreatPersistenceBySource( target, ( ( Uint32 )( combatTargetCmdSourceRecord.EnumValue() ) ) ) == AIThreatPersistenceStatus.Persistent ) { return; } } ScriptExecutionContext.SetArgumentObject( context, 'CommandCombatTarget', NULL ); } public static function IsCommandCombatTargetValid( context : ScriptExecutionContext, commandName : CName ) : Bool { var target : weak< GameObject >; target = ScriptExecutionContext.GetArgumentObject( context, 'CommandCombatTarget' ); if( !( ScriptedPuppet.IsActive( ScriptExecutionContext.GetOwner( context ) ) ) ) { ScriptExecutionContext.DebugLog( context, commandName, "Canceling command, owner is Dead, Defeated or Unconscious" ); return false; } if( !( target ) ) { ScriptExecutionContext.DebugLog( context, commandName, "Canceling command, Target no longer exists" ); return false; } if( target.IsPuppet() ) { if( !( ScriptedPuppet.IsActive( target ) ) ) { ScriptExecutionContext.DebugLog( context, commandName, "Canceling command, Target no longer active" ); return false; } else if( GameObject.GetAttitudeBetween( ScriptExecutionContext.GetOwner( context ), target ) == EAIAttitude.AIA_Friendly ) { ScriptExecutionContext.DebugLog( context, commandName, "Canceling command, Target is Friendly" ); return false; } else if( HasLostTarget( ( ( ScriptedPuppet )( ScriptExecutionContext.GetOwner( context ) ) ), target ) ) { ScriptExecutionContext.DebugLog( context, commandName, "Canceling command, lost track of target" ); return false; } } return true; } public static function TargetAllSquadMembers( owner : weak< GameObject > ) { var attitudeOwner : AttitudeAgent; var attitudeTarget : AttitudeAgent; var squadMembers : array< weak< Entity > >; var target : weak< GameObject >; var i : Int32; var targetTrackerComponent : TargetTrackerComponent; attitudeOwner = owner.GetAttitudeAgent(); attitudeOwner.SetAttitudeGroup( 'HostileToEveryone' ); targetTrackerComponent = owner.GetTargetTrackerComponent(); if( !( AISquadHelper.GetSquadmates( ( ( ScriptedPuppet )( owner ) ), squadMembers ) ) ) { return; } for( i = 0; i < squadMembers.Size(); i += 1 ) { target = ( ( GameObject )( squadMembers[ i ] ) ); if( ( !( target ) || ( target == owner ) ) || !( ScriptedPuppet.IsActive( target ) ) ) { continue; } attitudeTarget = target.GetAttitudeAgent(); attitudeOwner.SetAttitudeTowards( attitudeTarget, EAIAttitude.AIA_Hostile ); if( targetTrackerComponent ) { targetTrackerComponent.AddThreat( target, true, target.GetWorldPosition(), 1.0, -1.0, false ); } } return; } public static function SetFriendlyTargetAllSquadMembers( owner : weak< GameObject > ) { var attitudeOwner : AttitudeAgent; var attitudeTarget : AttitudeAgent; var squadMembers : array< weak< Entity > >; var target : weak< GameObject >; var i : Int32; var targetTrackerComponent : TargetTrackerComponent; attitudeOwner = owner.GetAttitudeAgent(); if( !( AISquadHelper.GetSquadmates( ( ( ScriptedPuppet )( owner ) ), squadMembers ) ) ) { return; } targetTrackerComponent = owner.GetTargetTrackerComponent(); if( targetTrackerComponent ) { targetTrackerComponent.ClearThreats(); } for( i = 0; i < squadMembers.Size(); i += 1 ) { target = ( ( GameObject )( squadMembers[ i ] ) ); if( ( !( target ) || ( target == owner ) ) || !( ScriptedPuppet.IsActive( target ) ) ) { continue; } attitudeTarget = target.GetAttitudeAgent(); attitudeOwner.SetAttitudeTowards( attitudeTarget, EAIAttitude.AIA_Hostile ); if( targetTrackerComponent ) { targetTrackerComponent.AddThreat( target, true, target.GetWorldPosition(), 1.0, -1.0, false ); } } return; } public static function ChangeAttitudeToFriendlyAllSquad( owner : weak< GameObject >, const squadMembers : ref< array< EntityID > > ) { var attitudeOwner : AttitudeAgent; var attitudeTarget : AttitudeAgent; var target : weak< GameObject >; var i : Int32; attitudeOwner = owner.GetAttitudeAgent(); for( i = 0; i < squadMembers.Size(); i += 1 ) { target = ( ( GameObject )( GameInstance.FindEntityByID( owner.GetGame(), squadMembers[ i ] ) ) ); if( !( target ) || ( target == owner ) ) { continue; } attitudeTarget = target.GetAttitudeAgent(); attitudeOwner.SetAttitudeTowards( attitudeTarget, EAIAttitude.AIA_Friendly ); } return; } public static function GetActiveTopHostilePuppetThreat( puppet : ScriptedPuppet, threat : ref< TrackedLocation > ) : Bool { var targetTrackerComponent : TargetTrackerComponent; var currentTopThreat : TrackedLocation; var allThreats : array< TrackedLocation >; var newTargetPuppet : ScriptedPuppet; var i : Int32; targetTrackerComponent = puppet.GetTargetTrackerComponent(); if( targetTrackerComponent.GetTopHostileThreat( false, currentTopThreat ) ) { threat = currentTopThreat; newTargetPuppet = ( ( ScriptedPuppet )( currentTopThreat.entity ) ); if( newTargetPuppet ) { if( ScriptedPuppet.IsActive( newTargetPuppet ) ) { return true; } else { allThreats = targetTrackerComponent.GetHostileThreats( false ); for( i = allThreats.Size() - 1; i >= 0; i -= 1 ) { newTargetPuppet = ( ( ScriptedPuppet )( allThreats[ i ].entity ) ); if( ScriptedPuppet.IsActive( newTargetPuppet ) ) { threat = allThreats[ i ]; return true; } } } } } return false; } public static function GetAnimWrapperNameBasedOnItemID( itemID : ItemID ) : CName { var animWrapperName : CName; animWrapperName = TDB.GetCName( ItemID.GetTDBID( itemID ) + T".NPCAnimWrapperWeightOverride" ); if( !( IsNameValid( animWrapperName ) ) ) { animWrapperName = TweakDBInterface.GetItemRecord( ItemID.GetTDBID( itemID ) ).ItemType().Name(); } return animWrapperName; } public static function GetAnimWrapperNameBasedOnItemTag( itemID : ItemID ) : CName { var itemRecord : Item_Record; itemRecord = TweakDBInterface.GetItemRecord( ItemID.GetTDBID( itemID ) ); if( itemRecord.TagsContains( WeaponObject.GetMeleeWeaponTag() ) ) { return 'MeleeWeapon'; } else if( itemRecord.TagsContains( WeaponObject.GetRangedWeaponTag() ) ) { return 'RangedWeapon'; } return ''; } public static function SendItemHandling( owner : weak< GameObject >, itemRecord : weak< Item_Record >, animFeatureName : CName, equipped : Bool ) { var itemHandling : AnimFeature_EquipUnequipItem; itemHandling = new AnimFeature_EquipUnequipItem; itemHandling.itemState = ( ( equipped ) ? ( 2 ) : ( 0 ) ); itemHandling.itemType = itemRecord.ItemType().AnimFeatureIndex(); AnimationControllerComponent.ApplyFeatureToReplicate( owner, animFeatureName, itemHandling ); } public static function GetReactionPresetGroup( puppet : weak< ScriptedPuppet > ) : String { var reactionGroup : String; var reactionComponent : ReactionManagerComponent; if( puppet ) { reactionComponent = puppet.GetStimReactionComponent(); if( reactionComponent ) { reactionGroup = reactionComponent.GetReactionPreset().ReactionGroup(); } } return reactionGroup; } public static function PlayWeaponEffect( weapon : WeaponObject, effectName : CName ) { var spawnEffectEvent : entSpawnEffectEvent; spawnEffectEvent = new entSpawnEffectEvent; spawnEffectEvent.effectName = effectName; weapon.QueueEventToChildItems( spawnEffectEvent ); } public static function BreakWeaponEffectLoop( weapon : WeaponObject, effectName : CName ) { var evt : entBreakEffectLoopEvent; evt = new entBreakEffectLoopEvent; evt.effectName = effectName; weapon.QueueEventToChildItems( evt ); } public static function KillWeaponEffect( weapon : WeaponObject, effectName : CName ) { var evt : entKillEffectEvent; evt = new entKillEffectEvent; evt.effectName = effectName; weapon.QueueEventToChildItems( evt ); } public static function CheckFlatheadStatPoolRequirements( game : GameInstance, const actionName : ref< String > ) : Bool { var statPoolsAffected : array< CName >; var statPoolsValueChanges : array< Float >; var statPoolType : gamedataStatPoolType; var actionID : TweakDBID; var flathead : weak< GameObject >; var currentStatPoolValue : Float; var i : Int32; actionID = TDBID.Create( "SpiderbotArchetype." + actionName ); statPoolsAffected = AITweakParams.GetCNameArrayFromTweak( actionID, "statPoolsAffected" ); statPoolsValueChanges = AITweakParams.GetFloatArrayFromTweak( actionID, "statPoolsValueChanges" ); flathead = ( ( SubCharacterSystem )( GameInstance.GetScriptableSystemsContainer( game ).Get( 'SubCharacterSystem' ) ) ).GetFlathead(); for( i = 0; i < statPoolsAffected.Size(); i += 1 ) { statPoolType = ( ( gamedataStatPoolType )( ( ( Int32 )( EnumValueFromName( 'gamedataStatPoolType', statPoolsAffected[ i ] ) ) ) ) ); currentStatPoolValue = GameInstance.GetStatPoolsSystem( game ).GetStatPoolValue( flathead.GetEntityID(), statPoolType, false ); if( ( currentStatPoolValue + statPoolsValueChanges[ i ] ) < 0.0 ) { return false; } } return true; } public static function IsCurrentlyCrouching( puppet : ScriptedPuppet ) : Bool { if( puppet.GetStanceStateFromBlackboard() == gamedataNPCStanceState.Crouch ) { return true; } if( !( AICoverHelper.IsCurrentlyInCover( puppet ) ) ) { return false; } if( AICoverHelper.GetCurrentCoverStance( puppet ) == 'High' ) { return false; } else { if( AICoverHelper.GetCoverNPCCurrentlyExposed( puppet ) && AICoverHelper.IsStandingExposureMethod( AICoverHelper.GetCoverExposureMethod( puppet ) ) ) { return false; } } return true; } public static function IsCurrentlyExposedInCover( puppet : ScriptedPuppet ) : Bool { if( !( AICoverHelper.IsCurrentlyInCover( puppet ) ) ) { return false; } if( AICoverHelper.GetCoverNPCCurrentlyExposed( puppet ) && AICoverHelper.IsUnsafeExposureMethod( AICoverHelper.GetCoverExposureMethod( puppet ) ) ) { return true; } return false; } public static function IsCurrentlyInCoverAttackAction( puppet : ScriptedPuppet ) : Bool { if( !( AICoverHelper.IsCurrentlyInCover( puppet ) ) ) { return false; } if( AICoverHelper.GetCoverNPCCurrentlyExposed( puppet ) ) { return true; } return false; } public static function GetItemsFromWeaponSlots( owner : weak< GameObject >, items : ref< array< weak< ItemObject > > > ) : Bool { var item : weak< ItemObject >; item = GameInstance.GetTransactionSystem( owner.GetGame() ).GetItemInSlot( owner, T"AttachmentSlots.WeaponRight" ); if( item ) { items.PushBack( item ); } item = GameInstance.GetTransactionSystem( owner.GetGame() ).GetItemInSlot( owner, T"AttachmentSlots.WeaponLeft" ); if( item ) { items.PushBack( item ); } return items.Size() > 0; } public static function HasEquippedWeaponWithTag( owner : weak< GameObject >, tag : CName ) : Bool { var item : ItemObject; var items : array< ItemObject >; var i : Int32; item = GameInstance.GetTransactionSystem( owner.GetGame() ).GetItemInSlot( owner, T"AttachmentSlots.WeaponRight" ); if( item ) { items.PushBack( item ); } item = GameInstance.GetTransactionSystem( owner.GetGame() ).GetItemInSlot( owner, T"AttachmentSlots.WeaponLeft" ); if( item ) { items.PushBack( item ); } for( i = 0; i < items.Size(); i += 1 ) { if( item.GetItemData().HasTag( tag ) ) { return true; } } return false; } public static function IsInWorkspot( owner : weak< GameObject > ) : Bool { var workspotSystem : WorkspotGameSystem; var res : Bool; workspotSystem = GameInstance.GetWorkspotSystem( owner.GetGame() ); if( workspotSystem ) { res = workspotSystem.IsActorInWorkspot( owner ); } return res; } public static function IsPointInRestrictedMovementArea( ownerPuppet : weak< ScriptedPuppet >, point : Vector4 ) : Bool { if( !( ownerPuppet ) ) { return false; } return GameInstance.GetRestrictMovementAreaManager( ownerPuppet.GetGame() ).IsPointInRestrictMovementArea( ownerPuppet.GetEntityID(), point ); } public static function IsPointInRMA( ownerPuppet : weak< ScriptedPuppet >, point : Vector4 ) : Bool { return IsPointInRestrictedMovementArea( ownerPuppet, point ); } public static function GetCurrentStrongArmsTrailEffect( weapon : ItemObject ) : CName { var cachedThreshold : Float; var statSystem : StatsSystem; var weaponID : StatsObjectID; var damageType : gamedataDamageType; statSystem = GameInstance.GetStatsSystem( weapon.GetGame() ); weaponID = weapon.GetEntityID(); cachedThreshold = statSystem.GetStatValue( weaponID, gamedataStatType.PhysicalDamage ); damageType = gamedataDamageType.Physical; if( statSystem.GetStatValue( weaponID, gamedataStatType.ThermalDamage ) > cachedThreshold ) { cachedThreshold = statSystem.GetStatValue( weaponID, gamedataStatType.ThermalDamage ); damageType = gamedataDamageType.Thermal; } if( statSystem.GetStatValue( weaponID, gamedataStatType.ElectricDamage ) > cachedThreshold ) { cachedThreshold = statSystem.GetStatValue( weaponID, gamedataStatType.ElectricDamage ); damageType = gamedataDamageType.Electric; } if( statSystem.GetStatValue( weaponID, gamedataStatType.ChemicalDamage ) > cachedThreshold ) { cachedThreshold = statSystem.GetStatValue( weaponID, gamedataStatType.ChemicalDamage ); damageType = gamedataDamageType.Chemical; } switch( damageType ) { case gamedataDamageType.Physical: return 'trail_physical'; case gamedataDamageType.Thermal: return 'trail_thermal'; case gamedataDamageType.Chemical: return 'trail_chemical'; case gamedataDamageType.Electric: return 'trail_electric'; default: return 'trail_physical'; } return 'trail_physical'; } public static function StartCooldown( self : GameObject, record : weak< AIActionCooldown_Record > ) : Int32 { var context : ScriptExecutionContext; var cdRequest : RegisterNewCooldownRequest; var cs : ICooldownSystem; var i : Int32; var count : Int32; var activationCondition : Bool; if( !( record ) ) { return -1; } if( !( AIHumanComponent.GetScriptContext( ( ( ScriptedPuppet )( self ) ), context ) ) ) { return -1; } if( ( record.Duration() < 0.0 ) || !( IsNameValid( record.Name() ) ) ) { return -1; } if( record.Duration() == 0.0 ) { GameObject.RemoveCooldown( self, record.Name() ); return -1; } count = record.GetActivationConditionCount(); if( count > 0 ) { activationCondition = false; for( i = 0; i < count; i += 1 ) { if( AICondition.CheckActionCondition( context, record.GetActivationConditionItem( i ) ) ) { activationCondition = true; break; } } } else { activationCondition = true; } if( !( activationCondition ) ) { return -1; } cs = CSH.GetCooldownSystem( self ); cdRequest.cooldownName = record.Name(); cdRequest.duration = record.Duration(); cdRequest.owner = self; return cs.Register( cdRequest ); } public static function StartCooldown( self : GameObject, cooldownName : CName, duration : Float ) : Int32 { var cdRequest : RegisterNewCooldownRequest; var cs : ICooldownSystem; if( ( duration < 0.0 ) || !( IsNameValid( cooldownName ) ) ) { return -1; } if( duration == 0.0 ) { GameObject.RemoveCooldown( self, cooldownName ); return -1; } cs = CSH.GetCooldownSystem( self ); cdRequest.cooldownName = cooldownName; cdRequest.duration = duration; cdRequest.owner = self; return cs.Register( cdRequest ); } public static function IsCooldownActive( self : GameObject, record : weak< AIActionCooldown_Record > ) : Bool { var context : ScriptExecutionContext; var cooldownName : CName; if( !( record ) ) { return false; } if( !( AIHumanComponent.GetScriptContext( ( ( ScriptedPuppet )( self ) ), context ) ) ) { return false; } cooldownName = record.Name(); if( !( IsNameValid( cooldownName ) ) ) { return false; } return GameObject.IsCooldownActive( self, cooldownName ); } public static function GetBaseShootingPatternPackages( patternPackages : ref< array< weak< AIPatternsPackage_Record > > > ) : Bool { var packageIDNames : array< String >; var tweakID : TweakDBID; var i, size : Int32; packageIDNames = TDB.GetStringArray( T"AIGeneralSettings.baseShootingPatternPackages" ); size = packageIDNames.Size(); patternPackages.Resize( size ); for( i = 0; i < size; i += 1 ) { tweakID = TDBID.Create( packageIDNames[ i ] ); patternPackages[ i ] = TweakDBInterface.GetAIPatternsPackageRecord( tweakID ); } return size > 0; } public static function ClearWorkspotCommand( puppet : weak< ScriptedPuppet >, optional doNotRepeat : Bool ) : Bool { var aiComponent : AIHumanComponent; var workspotCommand : weak< AIBaseUseWorkspotCommand >; var commandID : Uint32; if( !( puppet ) ) { return false; } aiComponent = puppet.GetAIControllerComponent(); if( !( aiComponent ) ) { return false; } commandID = ( ( Uint32 )( aiComponent.GetActiveCommandID( 'AIUseWorkspotCommand' ) ) ); if( aiComponent.CancelCommandById( commandID, doNotRepeat ) ) { return true; } else { workspotCommand = ( ( weak< weak< AIBaseUseWorkspotCommand > > )( aiComponent.GetBehaviorArgument( '_command' ) ) ); if( !( workspotCommand ) ) { workspotCommand = ( ( weak< weak< AIBaseUseWorkspotCommand > > )( aiComponent.GetBehaviorArgument( 'UseWorkspotCommand' ) ) ); } if( workspotCommand && workspotCommand.state == AICommandState.Executing ) { aiComponent.StopExecutingCommand( workspotCommand, true ); } } return false; } public static function GetDistanceRangeFromRingType( ringRecord : weak< AIRingType_Record >, out distanceRange : Vector2 ) : Bool { if( ringRecord.Distance() >= 0.0 ) { distanceRange.X = ringRecord.Distance(); distanceRange.Y = distanceRange.X; } else { return false; } if( ringRecord.Tolerance() > 0.0 ) { distanceRange.X = ringRecord.Distance() - ringRecord.Tolerance(); distanceRange.Y = ringRecord.Distance() + ringRecord.Tolerance(); } return distanceRange.Y > 0.0; } public static function GetDistanceRangeFromRingType( ringRecord : weak< AIRingType_Record >, condition : weak< AIOptimalDistanceCond_Record >, out distanceRange : Vector2 ) : Bool { var tolerance : Float; if( ringRecord.Distance() < 0.0 ) { return false; } distanceRange.X = ringRecord.Distance(); if( condition.DistanceMult() >= 0.0 ) { distanceRange.X *= condition.DistanceMult(); } if( condition.DistanceOffset() != 0.0 ) { distanceRange.X += condition.DistanceOffset(); } distanceRange.Y = distanceRange.X; if( distanceRange.X < 0.0 ) { return false; } if( ringRecord.Tolerance() >= 0.0 ) { tolerance = ringRecord.Tolerance(); if( condition.ToleranceMult() >= 0.0 ) { tolerance *= condition.ToleranceMult(); } if( condition.ToleranceOffset() != 0.0 ) { tolerance += condition.ToleranceOffset(); } } if( tolerance > 0.0 ) { distanceRange.X = ringRecord.Distance() - tolerance; distanceRange.Y = ringRecord.Distance() + tolerance; } return distanceRange.Y > 0.0; } public static function GetDistanceRangeFromRingType( ringRecord : weak< AIRingType_Record >, condition : weak< MovementPolicy_Record >, out distanceRange : Vector2 ) : Bool { var tolerance : Float; if( ringRecord.Distance() < 0.0 ) { return false; } distanceRange.X = ringRecord.Distance(); if( condition.RingDistanceMult() >= 0.0 ) { distanceRange.X *= condition.RingDistanceMult(); } if( condition.RingDistanceOffset() != 0.0 ) { distanceRange.X += condition.RingDistanceOffset(); } distanceRange.Y = distanceRange.X; if( distanceRange.X < 0.0 ) { return false; } if( ringRecord.Tolerance() >= 0.0 ) { tolerance = ringRecord.Tolerance(); if( condition.RingToleranceMult() >= 0.0 ) { tolerance *= condition.RingToleranceMult(); } if( condition.RingToleranceOffset() != 0.0 ) { tolerance += condition.RingToleranceOffset(); } } if( tolerance > 0.0 ) { distanceRange.X = ringRecord.Distance() - tolerance; distanceRange.Y = ringRecord.Distance() + tolerance; } return distanceRange.Y > 0.0; } public static function GetDistanceAndToleranceFromRingType( record : weak< MovementPolicy_Record >, out distance : Float, out tolerance : Float ) : Bool { if( record.Ring().Distance() < 0.0 ) { return false; } distance = record.Ring().Distance(); if( record.RingDistanceMult() >= 0.0 ) { distance *= record.RingDistanceMult(); } if( record.RingDistanceOffset() != 0.0 ) { distance += record.RingDistanceOffset(); } if( distance < 0.0 ) { return false; } if( record.Ring().Tolerance() >= 0.0 ) { tolerance = record.Ring().Tolerance(); if( record.RingToleranceMult() >= 0.0 ) { tolerance *= record.RingToleranceMult(); } if( record.RingToleranceOffset() != 0.0 ) { tolerance += record.RingToleranceOffset(); } } if( tolerance < 0.0 ) { tolerance = 0.0; } return true; } public static function GetAdditionalTraceTypeValueFromTweakEnum( value : gamedataAIAdditionalTraceType ) : AdditionalTraceType { switch( value ) { case gamedataAIAdditionalTraceType.Chest: return AdditionalTraceType.Chest; case gamedataAIAdditionalTraceType.Hip: return AdditionalTraceType.Hip; case gamedataAIAdditionalTraceType.Knee: return AdditionalTraceType.Knee; default: return AdditionalTraceType.Chest; } } public static function GetLatestActiveRingTypeRecord( puppet : weak< ScriptedPuppet > ) : AIRingType_Record { var currentRing : gamedataAIRingType; currentRing = AISquadHelper.GetCurrentSquadRing( puppet ); switch( currentRing ) { case gamedataAIRingType.Melee: return TweakDBInterface.GetAIRingTypeRecord( T"AIRingType.Melee" ); case gamedataAIRingType.Close: return TweakDBInterface.GetAIRingTypeRecord( T"AIRingType.Close" ); case gamedataAIRingType.Medium: return TweakDBInterface.GetAIRingTypeRecord( T"AIRingType.Medium" ); case gamedataAIRingType.Far: return TweakDBInterface.GetAIRingTypeRecord( T"AIRingType.Far" ); case gamedataAIRingType.Extreme: return TweakDBInterface.GetAIRingTypeRecord( T"AIRingType.Extreme" ); default: return TweakDBInterface.GetAIRingTypeRecord( T"AIRingType.Default" ); } } public export static function GetLatestActiveRingTypeRecordHelper( object : GameObject ) : AIRingType_Record { var puppet : ScriptedPuppet; puppet = ( ( ScriptedPuppet )( object ) ); if( puppet == NULL ) { return NULL; } return GetLatestActiveRingTypeRecord( puppet ); } public static function WeaponHasTriggerModes( weapon : weak< WeaponObject >, weaponRecord : weak< WeaponItem_Record >, const triggerModes : ref< array< weak< TriggerMode_Record > > > ) : Bool { var triggerModesSize : Int32; var i, j : Int32; triggerModesSize = triggerModes.Size(); if( triggerModesSize == 0 ) { return false; } for( i = 0; i < triggerModesSize; i += 1 ) { if( triggerModes[ i ].Type() == gamedataTriggerMode.Charge ) { if( GameInstance.GetStatsSystem( weapon.GetGame() ).GetStatValue( weapon.GetEntityID(), gamedataStatType.ChargeTime ) > 0.0 ) { j += 1; continue; } } else if( triggerModes[ i ].Type() == gamedataTriggerMode.Burst ) { if( GameInstance.GetStatsSystem( weapon.GetGame() ).GetStatValue( weapon.GetEntityID(), gamedataStatType.CycleTime_Burst ) > 0.0 ) { j += 1; continue; } } if( triggerModes[ i ] == weaponRecord.PrimaryTriggerMode() ) { j += 1; continue; } } return triggerModesSize == j; } public static function WeaponHasTriggerMode( weapon : weak< WeaponObject >, weaponRecord : weak< WeaponItem_Record >, triggerMode : weak< TriggerMode_Record > ) : Bool { if( triggerMode.Type() == gamedataTriggerMode.Charge ) { if( GameInstance.GetStatsSystem( weapon.GetGame() ).GetStatValue( weapon.GetEntityID(), gamedataStatType.ChargeTime ) > 0.0 ) { return true; } } else if( triggerMode.Type() == gamedataTriggerMode.Burst ) { if( GameInstance.GetStatsSystem( weapon.GetGame() ).GetStatValue( weapon.GetEntityID(), gamedataStatType.CycleTime_Burst ) > 0.0 ) { return true; } } if( triggerMode == weaponRecord.PrimaryTriggerMode() ) { return true; } return false; } public static function WeaponHasTriggerMode( weapon : weak< WeaponObject >, weaponRecord : weak< WeaponItem_Record >, triggerMode : gamedataTriggerMode ) : Bool { if( triggerMode == gamedataTriggerMode.Charge ) { if( GameInstance.GetStatsSystem( weapon.GetGame() ).GetStatValue( weapon.GetEntityID(), gamedataStatType.ChargeTime ) > 0.0 ) { return true; } } else if( triggerMode == gamedataTriggerMode.Burst ) { if( GameInstance.GetStatsSystem( weapon.GetGame() ).GetStatValue( weapon.GetEntityID(), gamedataStatType.CycleTime_Burst ) > 0.0 ) { return true; } } if( triggerMode == weaponRecord.PrimaryTriggerMode().Type() ) { return true; } return false; } public static function WeaponHasTriggerMode( weapon : weak< WeaponObject >, triggerMode : gamedataTriggerMode ) : Bool { var weaponRecord : weak< WeaponItem_Record >; if( triggerMode == gamedataTriggerMode.Charge ) { if( GameInstance.GetStatsSystem( weapon.GetGame() ).GetStatValue( weapon.GetEntityID(), gamedataStatType.ChargeTime ) > 0.0 ) { return true; } } else if( triggerMode == gamedataTriggerMode.Burst ) { if( GameInstance.GetStatsSystem( weapon.GetGame() ).GetStatValue( weapon.GetEntityID(), gamedataStatType.CycleTime_Burst ) > 0.0 ) { return true; } } weaponRecord = ( ( WeaponItem_Record )( TweakDBInterface.GetItemRecord( ItemID.GetTDBID( weapon.GetItemID() ) ) ) ); if( triggerMode == weaponRecord.PrimaryTriggerMode().Type() ) { return true; } return false; } public static function WeaponHasTriggerMode( weapon : weak< WeaponObject >, triggerMode : weak< TriggerMode_Record > ) : Bool { var weaponRecord : weak< WeaponItem_Record >; if( triggerMode.Type() == gamedataTriggerMode.Charge ) { if( GameInstance.GetStatsSystem( weapon.GetGame() ).GetStatValue( weapon.GetEntityID(), gamedataStatType.ChargeTime ) > 0.0 ) { return true; } } else if( triggerMode.Type() == gamedataTriggerMode.Burst ) { if( GameInstance.GetStatsSystem( weapon.GetGame() ).GetStatValue( weapon.GetEntityID(), gamedataStatType.CycleTime_Burst ) > 0.0 ) { return true; } } weaponRecord = ( ( WeaponItem_Record )( TweakDBInterface.GetItemRecord( ItemID.GetTDBID( weapon.GetItemID() ) ) ) ); if( triggerMode == weaponRecord.PrimaryTriggerMode() ) { return true; } return false; } public static function GetLastRequestedTriggerMode( weapon : weak< WeaponObject > ) : gamedataTriggerMode { return ( ( gamedataTriggerMode )( weapon.GetAIBlackboard().GetInt( GetAllBlackboardDefs().AIShooting.requestedTriggerMode ) ) ); } public static function UpdateLinkedStatusEffects( owner : weak< GameObject >, linkedStatusEffect : ref< LinkedStatusEffect > ) { var overheatT1 : TweakDBID; var overheatT2 : TweakDBID; var overheatT3 : TweakDBID; var hackMalfunctiontT1 : TweakDBID; var hackMalfunctionT2 : TweakDBID; var hackMalfunctionT3 : TweakDBID; var hackLocomotionT1 : TweakDBID; var hackLocomotionT2 : TweakDBID; var hackLocomotionT3 : TweakDBID; var i : Int32; if( EntityID.IsDefined( linkedStatusEffect.targetID ) ) { overheatT1 = T"AIQuickHackStatusEffect.HackOverheat"; overheatT2 = T"AIQuickHackStatusEffect.HackOverheatTier2"; overheatT3 = T"AIQuickHackStatusEffect.HackOverheatTier3"; hackMalfunctiontT1 = T"AIQuickHackStatusEffect.HackWeaponMalfunction"; hackMalfunctionT2 = T"AIQuickHackStatusEffect.HackWeaponMalfunctionTier2"; hackMalfunctionT3 = T"AIQuickHackStatusEffect.HackWeaponMalfunctionTier3"; hackLocomotionT1 = T"AIQuickHackStatusEffect.HackLocomotion"; hackLocomotionT2 = T"AIQuickHackStatusEffect.HackLocomotionTier2"; hackLocomotionT3 = T"AIQuickHackStatusEffect.HackLocomotionTier3"; } for( i = 0; i < linkedStatusEffect.statusEffectList.Size(); i += 1 ) { if( linkedStatusEffect.netrunnerIDs.Size() > 0 ) { if( ( ( linkedStatusEffect.statusEffectList[ i ] == overheatT1 ) || ( linkedStatusEffect.statusEffectList[ i ] == overheatT2 ) ) || ( linkedStatusEffect.statusEffectList[ i ] == overheatT3 ) ) { StatusEffectHelper.RemoveStatusEffect( owner, linkedStatusEffect.statusEffectList[ i ] ); switch( linkedStatusEffect.netrunnerIDs.Size() ) { case 1: linkedStatusEffect.statusEffectList[ i ] = overheatT1; StatusEffectHelper.ApplyStatusEffect( owner, overheatT1, linkedStatusEffect.netrunnerIDs[ 0 ] ); break; case 2: linkedStatusEffect.statusEffectList[ i ] = overheatT2; StatusEffectHelper.ApplyStatusEffect( owner, overheatT2, linkedStatusEffect.netrunnerIDs[ 0 ] ); break; case 3: linkedStatusEffect.statusEffectList[ i ] = overheatT3; StatusEffectHelper.ApplyStatusEffect( owner, overheatT3, linkedStatusEffect.netrunnerIDs[ 0 ] ); break; default: break; } } if( ( ( linkedStatusEffect.statusEffectList[ i ] == hackMalfunctiontT1 ) || ( linkedStatusEffect.statusEffectList[ i ] == hackMalfunctionT2 ) ) || ( linkedStatusEffect.statusEffectList[ i ] == hackMalfunctionT3 ) ) { StatusEffectHelper.RemoveStatusEffect( owner, linkedStatusEffect.statusEffectList[ i ] ); switch( linkedStatusEffect.netrunnerIDs.Size() ) { case 1: linkedStatusEffect.statusEffectList[ i ] = hackMalfunctiontT1; StatusEffectHelper.ApplyStatusEffect( owner, hackMalfunctiontT1, linkedStatusEffect.netrunnerIDs[ 0 ] ); break; case 2: linkedStatusEffect.statusEffectList[ i ] = hackMalfunctionT2; StatusEffectHelper.ApplyStatusEffect( owner, hackMalfunctionT2, linkedStatusEffect.netrunnerIDs[ 0 ] ); break; case 3: linkedStatusEffect.statusEffectList[ i ] = hackMalfunctionT3; StatusEffectHelper.ApplyStatusEffect( owner, hackMalfunctionT3, linkedStatusEffect.netrunnerIDs[ 0 ] ); break; default: break; } } if( ( ( linkedStatusEffect.statusEffectList[ i ] == hackLocomotionT1 ) || ( linkedStatusEffect.statusEffectList[ i ] == hackLocomotionT2 ) ) || ( linkedStatusEffect.statusEffectList[ i ] == hackLocomotionT3 ) ) { StatusEffectHelper.RemoveStatusEffect( owner, linkedStatusEffect.statusEffectList[ i ] ); switch( linkedStatusEffect.netrunnerIDs.Size() ) { case 1: linkedStatusEffect.statusEffectList[ i ] = hackLocomotionT1; StatusEffectHelper.ApplyStatusEffect( owner, hackLocomotionT1, linkedStatusEffect.netrunnerIDs[ 0 ] ); break; case 2: linkedStatusEffect.statusEffectList[ i ] = hackLocomotionT2; StatusEffectHelper.ApplyStatusEffect( owner, hackLocomotionT2, linkedStatusEffect.netrunnerIDs[ 0 ] ); break; case 3: linkedStatusEffect.statusEffectList[ i ] = hackLocomotionT3; StatusEffectHelper.ApplyStatusEffect( owner, hackLocomotionT3, linkedStatusEffect.netrunnerIDs[ 0 ] ); break; default: break; } } } else { StatusEffectHelper.RemoveStatusEffect( owner, linkedStatusEffect.statusEffectList[ i ] ); } } } private static function GetCallingAlliesToCombatDelay( postCombatStart : Bool ) : Float { var delay : Float; delay = TweakDBInterface.GetFloat( T"AIGeneralSettings.callingAlliesToCombatDelay", 2.5 ); if( postCombatStart ) { delay -= TweakDBInterface.GetFloat( T"AIGeneralSettings.avoidCombatBuffer", 1.5 ); } return delay; } public static function QueuePullSquadSync( owner : weak< GameObject >, optional postCombatStart : Bool ) : DelayID { var pullSquadSyncRequest : PullSquadSyncRequest; pullSquadSyncRequest = new PullSquadSyncRequest; pullSquadSyncRequest.squadType = AISquadType.Combat; return GameInstance.GetDelaySystem( owner.GetGame() ).DelayEvent( owner, pullSquadSyncRequest, GetCallingAlliesToCombatDelay( postCombatStart ) ); } public static function QueueSecuritySystemCombatNotification( owner : weak< GameObject >, optional postCombatStart : Bool ) { var notificationEvent : NotifySecuritySystemCombatEvent; notificationEvent = new NotifySecuritySystemCombatEvent; GameInstance.GetDelaySystem( owner.GetGame() ).DelayEvent( owner, notificationEvent, GetCallingAlliesToCombatDelay( postCombatStart ) ); } public static function QueueNearbyCombatNotification( owner : weak< GameObject > ) : DelayID { var notificationEvent : NotifyNearbyAboutCombatEvent; notificationEvent = new NotifyNearbyAboutCombatEvent; return GameInstance.GetDelaySystem( owner.GetGame() ).DelayEvent( owner, notificationEvent, TweakDBInterface.GetFloat( T"AIGeneralSettings.avoidCombatBuffer", 1.5 ) ); } public static function PreloadBaseAnimations( puppet : weak< ScriptedPuppet >, optional melee : Bool ) : Bool { var result1, result2 : Bool; if( melee ) { result1 = PreloadAnimations( puppet, 'melee', true ); } else { result1 = PreloadAnimations( puppet, 'ranged_base', true ); } result2 = PreloadAnimations( puppet, 'hit_reaction_base', true ); return result1 && result2; } public static function PreloadCoreAnimations( puppet : weak< ScriptedPuppet >, optional melee : Bool ) : Bool { var result1, result2 : Bool; if( melee ) { result1 = PreloadAnimations( puppet, 'melee', true ); } else { result1 = PreloadAnimations( puppet, 'ranged_core', true ); } result2 = PreloadAnimations( puppet, 'hit_reaction_core', true ); return result1 && result2; } public static function PreloadAllBaseAnimations( puppet : weak< ScriptedPuppet > ) { PreloadAnimations( puppet, 'melee', true ); PreloadAnimations( puppet, 'ranged_core', true ); PreloadAnimations( puppet, 'ranged_base', true ); PreloadAnimations( puppet, 'hit_reaction_core', true ); PreloadAnimations( puppet, 'hit_reaction_base', true ); } public static function PreloadAnimations( puppet : weak< ScriptedPuppet >, streamingContextName : CName, highPriority : Bool ) : Bool { var animComponent : AnimationControllerComponent; if( !( puppet ) ) { return false; } animComponent = puppet.GetAnimationControllerComponent(); if( !( animComponent ) ) { return false; } if( !( animComponent.PreloadAnimations( streamingContextName, highPriority ) ) ) { return false; } return true; } public static function QueuePreloadCoreAnimationsEvent( puppet : weak< ScriptedPuppet > ) { var evt : PreloadAnimationsEvent; if( !( puppet ) ) { return; } evt = new PreloadAnimationsEvent; evt.m_streamingContextName = 'ranged_core'; evt.m_highPriority = true; puppet.QueueEvent( evt ); } public static function QueuePreloadBaseAnimationsEvent( puppet : weak< ScriptedPuppet > ) { var evt : PreloadAnimationsEvent; if( !( puppet ) ) { return; } evt = new PreloadAnimationsEvent; evt.m_streamingContextName = 'ranged_base'; evt.m_highPriority = true; puppet.QueueEvent( evt ); } public static function CheckAbility( const object : weak< GameObject >, ability : weak< GameplayAbility_Record > ) : Bool { var i : Int32; var count : Int32; var record : IPrereq_Record; count = ability.GetPrereqsForUseCount(); for( i = 0; i < count; i += 1 ) { record = ability.GetPrereqsForUseItem( i ); if( !( IPrereq.CreatePrereq( record.GetID() ).IsFulfilled( object.GetGame(), object ) ) ) { return false; } } return true; } public static function SetItemsEquipData( puppet : weak< ScriptedPuppet >, itemsToEquip : array< NPCItemToEquip > ) { var BBoard : IBlackboard; var itemData : gameItemData; var actionDuration : Float; var animDuration : Float; if( !( puppet ) ) { return; } BBoard = puppet.GetAIControllerComponent().GetActionBlackboard(); if( !( BBoard ) ) { return; } BBoard.SetVariant( GetAllBlackboardDefs().AIAction.ownerItemsToEquip, itemsToEquip ); itemData = GameInstance.GetTransactionSystem( puppet.GetGame() ).GetItemData( puppet, itemsToEquip[ 0 ].itemID ); if( puppet.IsCharacterGanger() ) { BBoard.SetFloat( GetAllBlackboardDefs().AIAction.ownerEquipItemTime, itemData.GetStatValueByType( gamedataStatType.EquipItemTime_Gang ) ); actionDuration = itemData.GetStatValueByType( gamedataStatType.EquipActionDuration_Gang ); animDuration = itemData.GetStatValueByType( gamedataStatType.EquipAnimationDuration_Gang ); if( animDuration == 0.0 ) { BBoard.SetFloat( GetAllBlackboardDefs().AIAction.ownerEquipDuration, actionDuration ); } else { BBoard.SetFloat( GetAllBlackboardDefs().AIAction.ownerEquipDuration, animDuration ); } } else { BBoard.SetFloat( GetAllBlackboardDefs().AIAction.ownerEquipItemTime, itemData.GetStatValueByType( gamedataStatType.EquipItemTime_Corpo ) ); actionDuration = itemData.GetStatValueByType( gamedataStatType.EquipActionDuration_Corpo ); animDuration = itemData.GetStatValueByType( gamedataStatType.EquipAnimationDuration_Corpo ); if( animDuration == 0.0 ) { BBoard.SetFloat( GetAllBlackboardDefs().AIAction.ownerEquipDuration, actionDuration ); } else { BBoard.SetFloat( GetAllBlackboardDefs().AIAction.ownerEquipDuration, animDuration ); } } } public static function SetItemsUnequipData( puppet : weak< ScriptedPuppet >, itemsToUnequip : array< NPCItemToEquip >, dropItem : Bool ) { var BBoard : IBlackboard; var itemData : gameItemData; var actionDuration : Float; var animDuration : Float; if( !( puppet ) ) { return; } BBoard = puppet.GetAIControllerComponent().GetActionBlackboard(); if( !( BBoard ) ) { return; } BBoard.SetVariant( GetAllBlackboardDefs().AIAction.ownerItemsToEquip, itemsToUnequip ); itemData = GameInstance.GetTransactionSystem( puppet.GetGame() ).GetItemData( puppet, itemsToUnequip[ 0 ].itemID ); if( puppet.IsCharacterGanger() ) { BBoard.SetFloat( GetAllBlackboardDefs().AIAction.ownerEquipItemTime, itemData.GetStatValueByType( gamedataStatType.UnequipItemTime_Gang ) ); actionDuration = itemData.GetStatValueByType( gamedataStatType.UnequipDuration_Gang ); animDuration = itemData.GetStatValueByType( gamedataStatType.UnequipAnimationDuration_Gang ); if( animDuration == 0.0 ) { BBoard.SetFloat( GetAllBlackboardDefs().AIAction.ownerEquipDuration, actionDuration ); } else { BBoard.SetFloat( GetAllBlackboardDefs().AIAction.ownerEquipDuration, animDuration ); } } else { BBoard.SetFloat( GetAllBlackboardDefs().AIAction.ownerEquipItemTime, itemData.GetStatValueByType( gamedataStatType.UnequipItemTime_Corpo ) ); actionDuration = itemData.GetStatValueByType( gamedataStatType.UnequipDuration_Corpo ); animDuration = itemData.GetStatValueByType( gamedataStatType.UnequipAnimationDuration_Corpo ); if( animDuration == 0.0 ) { BBoard.SetFloat( GetAllBlackboardDefs().AIAction.ownerEquipDuration, actionDuration ); } else { BBoard.SetFloat( GetAllBlackboardDefs().AIAction.ownerEquipDuration, animDuration ); } } BBoard.SetBool( GetAllBlackboardDefs().AIAction.dropItemOnUnequip, dropItem ); } public static function ClearItemsToEquip( puppet : weak< ScriptedPuppet > ) { var BBoard : IBlackboard; var itemsToEquip : array< NPCItemToEquip >; if( !( puppet ) ) { return; } BBoard = puppet.GetAIControllerComponent().GetActionBlackboard(); if( !( BBoard ) ) { return; } BBoard.SetVariant( GetAllBlackboardDefs().AIAction.ownerItemsToEquip, itemsToEquip ); } public static function ClearItemsToUnequip( puppet : weak< ScriptedPuppet > ) { var BBoard : IBlackboard; var itemsToUnequip : array< NPCItemToEquip >; if( !( puppet ) ) { return; } BBoard = puppet.GetAIControllerComponent().GetActionBlackboard(); if( !( BBoard ) ) { return; } BBoard.SetVariant( GetAllBlackboardDefs().AIAction.ownerItemsToEquip, itemsToUnequip ); } public static function ClearItemsUnequipped( puppet : weak< ScriptedPuppet > ) { var BBoard : IBlackboard; var itemsToUnequipped : array< NPCItemToEquip >; if( !( puppet ) ) { return; } BBoard = puppet.GetAIControllerComponent().GetActionBlackboard(); if( !( BBoard ) ) { return; } BBoard.SetVariant( GetAllBlackboardDefs().AIAction.ownerItemsUnequipped, itemsToUnequipped ); } public static function ClearItemsForceUnequipped( puppet : weak< ScriptedPuppet > ) { var BBoard : IBlackboard; var itemsToUnequipped : array< NPCItemToEquip >; if( !( puppet ) ) { return; } BBoard = puppet.GetAIControllerComponent().GetActionBlackboard(); if( !( BBoard ) ) { return; } BBoard.SetVariant( GetAllBlackboardDefs().AIAction.ownerItemsForceUnequipped, itemsToUnequipped ); } public static function IsMoveCommand( commandName : CName ) : Bool { switch( commandName ) { case 'AIMoveCommand': return true; case 'AIMoveToCommand': return true; case 'AICommsCallMoveToCommand': return true; case 'AIMoveOnSplineCommand': return true; case 'AIAnimMoveOnSplineCommand': return true; case 'AIRotateToCommand': return true; case 'AIJoinCrowdCommand': return true; case 'AIFollowTargetCommand': return true; case 'AIRootMotionCommand': return true; case 'AIHoldPositionCommand': return true; case 'AIMoveToCoverCommand': return true; default: return false; } } } class AIActionChecks { public static function CheckOwnerState( puppet : ScriptedPuppet, const npcStates : ref< AIActionNPCStates >, checkAll : Bool ) : Bool { if( !( puppet ) ) { return true; } if( checkAll ) { return CheckAllNPCStateTypes( puppet, npcStates ); } return CheckNPCState( puppet, npcStates ); } public static function CheckTargetState( target : ScriptedPuppet, const targetStates : ref< AIActionTargetStates >, checkAll : Bool ) : Bool { if( !( target ) ) { return true; } if( target.IsPlayer() ) { if( checkAll ) { return CheckAllPlayerStateTypes( target, targetStates.playerStates ); } return CheckPlayerState( target, targetStates.playerStates ); } else if( target.IsNPC() ) { if( checkAll ) { return CheckAllNPCStateTypes( target, targetStates.npcStates ); } return CheckNPCState( target, targetStates.npcStates ); } return true; } public static function CheckAllNPCStateTypes( puppet : ScriptedPuppet, const npcStates : ref< AIActionNPCStates > ) : Bool { if( ( ( ( ( ( npcStates.highLevelStates.Size() == 0 ) && ( npcStates.upperBodyStates.Size() == 0 ) ) && ( npcStates.stanceStates.Size() == 0 ) ) && ( npcStates.behaviorStates.Size() == 0 ) ) && ( npcStates.defenseMode.Size() == 0 ) ) && ( npcStates.locomotionMode.Size() == 0 ) ) { return true; } if( ( npcStates.highLevelStates.Size() > 0 ) && !( CheckHighLevelState( puppet, npcStates.highLevelStates ) ) ) { return false; } if( ( npcStates.upperBodyStates.Size() > 0 ) && !( CheckUpperBodyState( puppet, npcStates.upperBodyStates ) ) ) { return false; } if( ( npcStates.stanceStates.Size() > 0 ) && !( CheckStanceState( puppet, npcStates.stanceStates ) ) ) { return false; } if( ( npcStates.behaviorStates.Size() > 0 ) && !( CheckBehaviorState( puppet, npcStates.behaviorStates ) ) ) { return false; } if( ( npcStates.locomotionMode.Size() > 0 ) && !( CheckLocomotionMode( puppet, npcStates.locomotionMode ) ) ) { return false; } if( ( npcStates.defenseMode.Size() > 0 ) && !( CheckDefenseMode( puppet, npcStates.defenseMode ) ) ) { return false; } return true; } public static function CheckNPCState( puppet : ScriptedPuppet, const npcStates : ref< AIActionNPCStates > ) : Bool { if( ( ( ( ( ( npcStates.highLevelStates.Size() == 0 ) && ( npcStates.upperBodyStates.Size() == 0 ) ) && ( npcStates.stanceStates.Size() == 0 ) ) && ( npcStates.behaviorStates.Size() == 0 ) ) && ( npcStates.defenseMode.Size() == 0 ) ) && ( npcStates.locomotionMode.Size() == 0 ) ) { return true; } if( ( npcStates.highLevelStates.Size() > 0 ) && CheckHighLevelState( puppet, npcStates.highLevelStates ) ) { return true; } if( ( npcStates.upperBodyStates.Size() > 0 ) && CheckUpperBodyState( puppet, npcStates.upperBodyStates ) ) { return true; } if( ( npcStates.stanceStates.Size() > 0 ) && CheckStanceState( puppet, npcStates.stanceStates ) ) { return true; } if( ( npcStates.behaviorStates.Size() > 0 ) && CheckBehaviorState( puppet, npcStates.behaviorStates ) ) { return true; } if( ( npcStates.locomotionMode.Size() > 0 ) && CheckLocomotionMode( puppet, npcStates.locomotionMode ) ) { return true; } if( ( npcStates.defenseMode.Size() > 0 ) && CheckDefenseMode( puppet, npcStates.defenseMode ) ) { return true; } return false; } public static function CheckAllPlayerStateTypes( playerPuppet : ScriptedPuppet, const playerStates : ref< AIActionPlayerStates > ) : Bool { if( ( ( ( ( ( playerStates.locomotionStates.Size() == 0 ) && ( playerStates.upperBodyStates.Size() == 0 ) ) && ( playerStates.meleeStates.Size() == 0 ) ) && ( playerStates.zoneStates.Size() == 0 ) ) && ( playerStates.bodyCarryStates.Size() == 0 ) ) && ( playerStates.combatStates.Size() == 0 ) ) { return true; } if( ( playerStates.locomotionStates.Size() > 0 ) && !( CheckPSMLocomotionState( playerPuppet, playerStates.locomotionStates ) ) ) { return false; } if( ( playerStates.upperBodyStates.Size() > 0 ) && !( CheckPSMUpperBodyState( playerPuppet, playerStates.upperBodyStates ) ) ) { return false; } if( ( playerStates.meleeStates.Size() > 0 ) && !( CheckPSMMeleeState( playerPuppet, playerStates.meleeStates ) ) ) { return false; } if( ( playerStates.zoneStates.Size() > 0 ) && !( CheckPSMZoneState( playerPuppet, playerStates.zoneStates ) ) ) { return false; } if( ( playerStates.bodyCarryStates.Size() > 0 ) && !( CheckPSMBodyCarryState( playerPuppet, playerStates.bodyCarryStates ) ) ) { return false; } if( ( playerStates.combatStates.Size() > 0 ) && !( CheckPSMCombatState( playerPuppet, playerStates.combatStates ) ) ) { return false; } return true; } public static function CheckPlayerState( playerPuppet : ScriptedPuppet, const playerStates : ref< AIActionPlayerStates > ) : Bool { if( ( ( ( ( ( playerStates.locomotionStates.Size() == 0 ) && ( playerStates.upperBodyStates.Size() == 0 ) ) && ( playerStates.meleeStates.Size() == 0 ) ) && ( playerStates.zoneStates.Size() == 0 ) ) && ( playerStates.bodyCarryStates.Size() == 0 ) ) && ( playerStates.combatStates.Size() == 0 ) ) { return true; } if( ( playerStates.locomotionStates.Size() > 0 ) && CheckPSMLocomotionState( playerPuppet, playerStates.locomotionStates ) ) { return true; } if( ( playerStates.upperBodyStates.Size() > 0 ) && CheckPSMUpperBodyState( playerPuppet, playerStates.upperBodyStates ) ) { return true; } if( ( playerStates.meleeStates.Size() > 0 ) && CheckPSMMeleeState( playerPuppet, playerStates.meleeStates ) ) { return true; } if( ( playerStates.zoneStates.Size() > 0 ) && CheckPSMZoneState( playerPuppet, playerStates.zoneStates ) ) { return true; } if( ( playerStates.bodyCarryStates.Size() > 0 ) && CheckPSMBodyCarryState( playerPuppet, playerStates.bodyCarryStates ) ) { return true; } if( ( playerStates.combatStates.Size() > 0 ) && CheckPSMCombatState( playerPuppet, playerStates.combatStates ) ) { return true; } return false; } public static function CheckHighLevelState( puppet : ScriptedPuppet, const highLevelStates : ref< array< gamedataNPCHighLevelState > > ) : Bool { var currentHighLevelState : gamedataNPCHighLevelState; currentHighLevelState = ( ( gamedataNPCHighLevelState )( puppet.GetPuppetStateBlackboard().GetInt( GetAllBlackboardDefs().PuppetState.HighLevel ) ) ); if( !( highLevelStates.Contains( currentHighLevelState ) ) ) { return false; } return true; } public static function CheckUpperBodyState( puppet : ScriptedPuppet, const upperBodyStates : ref< array< gamedataNPCUpperBodyState > > ) : Bool { var currentUpperBodyState : gamedataNPCUpperBodyState; currentUpperBodyState = ( ( gamedataNPCUpperBodyState )( puppet.GetPuppetStateBlackboard().GetInt( GetAllBlackboardDefs().PuppetState.UpperBody ) ) ); if( !( puppet ) || !( upperBodyStates.Contains( currentUpperBodyState ) ) ) { return false; } return true; } public static function CheckStanceState( puppet : ScriptedPuppet, const stanceStates : ref< array< gamedataNPCStanceState > > ) : Bool { var currentStanceState : gamedataNPCStanceState; currentStanceState = ( ( gamedataNPCStanceState )( puppet.GetPuppetStateBlackboard().GetInt( GetAllBlackboardDefs().PuppetState.Stance ) ) ); if( !( stanceStates.Contains( currentStanceState ) ) ) { return false; } return true; } public static function CheckBehaviorState( puppet : ScriptedPuppet, const behaviorStates : ref< array< gamedataNPCBehaviorState > > ) : Bool { var currentBehaviorState : gamedataNPCBehaviorState; currentBehaviorState = ( ( gamedataNPCBehaviorState )( puppet.GetPuppetStateBlackboard().GetInt( GetAllBlackboardDefs().PuppetState.BehaviorState ) ) ); if( !( behaviorStates.Contains( currentBehaviorState ) ) ) { return false; } return true; } public static function CheckDefenseMode( puppet : ScriptedPuppet, const defenseMode : ref< array< gamedataDefenseMode > > ) : Bool { var currentDefenseMode : gamedataDefenseMode; currentDefenseMode = ( ( gamedataDefenseMode )( puppet.GetPuppetStateBlackboard().GetInt( GetAllBlackboardDefs().PuppetState.DefenseMode ) ) ); if( !( defenseMode.Contains( currentDefenseMode ) ) ) { return false; } return true; } public static function CheckLocomotionMode( puppet : ScriptedPuppet, const locomotionMode : ref< array< gamedataLocomotionMode > > ) : Bool { var currentlocomotionMode : gamedataLocomotionMode; currentlocomotionMode = ( ( gamedataLocomotionMode )( puppet.GetPuppetStateBlackboard().GetInt( GetAllBlackboardDefs().PuppetState.LocomotionMode ) ) ); if( !( locomotionMode.Contains( currentlocomotionMode ) ) ) { return false; } return true; } public static function GetPSMBlackbordInt( playerPuppet : ScriptedPuppet, id : BlackboardID_Int ) : Int32 { var blackboardSystem : BlackboardSystem; var blackboard : IBlackboard; blackboardSystem = GameInstance.GetBlackboardSystem( playerPuppet.GetGame() ); blackboard = blackboardSystem.GetLocalInstanced( playerPuppet.GetEntityID(), GetAllBlackboardDefs().PlayerStateMachine ); return blackboard.GetInt( id ); } public static function CheckPSMLocomotionState( playerPuppet : ScriptedPuppet, const locomotionStates : ref< array< gamePSMLocomotionStates > > ) : Bool { var currentState : gamePSMLocomotionStates; currentState = ( ( gamePSMLocomotionStates )( GetPSMBlackbordInt( playerPuppet, GetAllBlackboardDefs().PlayerStateMachine.Locomotion ) ) ); if( !( locomotionStates.Contains( currentState ) ) ) { return false; } return true; } public static function CheckPSMUpperBodyState( playerPuppet : ScriptedPuppet, const upperBodyStates : ref< array< gamePSMUpperBodyStates > > ) : Bool { var currentState : gamePSMUpperBodyStates; currentState = ( ( gamePSMUpperBodyStates )( GetPSMBlackbordInt( playerPuppet, GetAllBlackboardDefs().PlayerStateMachine.UpperBody ) ) ); if( !( upperBodyStates.Contains( currentState ) ) ) { return false; } return true; } public static function CheckPSMMeleeState( playerPuppet : ScriptedPuppet, const meleeStates : ref< array< gamePSMMelee > > ) : Bool { var currentState : gamePSMMelee; currentState = ( ( gamePSMMelee )( GetPSMBlackbordInt( playerPuppet, GetAllBlackboardDefs().PlayerStateMachine.Melee ) ) ); if( !( meleeStates.Contains( currentState ) ) ) { return false; } return true; } public static function CheckPSMZoneState( playerPuppet : ScriptedPuppet, const zoneStates : ref< array< gamePSMZones > > ) : Bool { var currentState : gamePSMZones; currentState = ( ( gamePSMZones )( GetPSMBlackbordInt( playerPuppet, GetAllBlackboardDefs().PlayerStateMachine.Zones ) ) ); if( !( zoneStates.Contains( currentState ) ) ) { return false; } return true; } public static function CheckPSMBodyCarryState( playerPuppet : ScriptedPuppet, const bodyCarryStates : ref< array< gamePSMBodyCarrying > > ) : Bool { var currentState : gamePSMBodyCarrying; currentState = ( ( gamePSMBodyCarrying )( GetPSMBlackbordInt( playerPuppet, GetAllBlackboardDefs().PlayerStateMachine.BodyCarrying ) ) ); if( !( bodyCarryStates.Contains( currentState ) ) ) { return false; } return true; } public static function CheckPSMCombatState( playerPuppet : ScriptedPuppet, const combatStates : ref< array< gamePSMCombat > > ) : Bool { var currentState : gamePSMCombat; currentState = ( ( gamePSMCombat )( GetPSMBlackbordInt( playerPuppet, GetAllBlackboardDefs().PlayerStateMachine.Combat ) ) ); if( !( combatStates.Contains( currentState ) ) ) { return false; } return true; } public static function CheckMountedVehicleDesiredTags( puppet : ScriptedPuppet, const desiredTags : ref< array< CName > > ) : Bool { var vehicleRecord : Vehicle_Record; var tags : array< CName >; var i : Int32; if( desiredTags.Size() <= 0 ) { return true; } if( !( VehicleComponent.GetVehicleRecord( puppet.GetGame(), puppet.GetEntityID(), vehicleRecord ) ) ) { return false; } tags = vehicleRecord.Tags(); for( i = 0; i < desiredTags.Size(); i += 1 ) { if( tags.Contains( desiredTags[ i ] ) ) { return true; } } return false; } }