class SimpleCoverBehaviorCondition extends AIbehaviorconditionScript
{
	private var m_initialized : Bool;
	private var m_isShotgunner : Bool;
	private var m_isHeavyRanged : Bool;

	protected export override function Activate( context : ScriptExecutionContext )
	{
		if( !( m_initialized ) )
		{
			if( AICondition.CheckAbility( context, TweakDBInterface.GetGameplayAbilityRecord( T"Ability.IsShotgunnerArchetype" ) ) )
			{
				m_isShotgunner = true;
			}
			else if( AICondition.CheckAbility( context, TweakDBInterface.GetGameplayAbilityRecord( T"Ability.IsHeavyRangedArchetype" ) ) )
			{
				m_isHeavyRanged = true;
			}
			m_initialized = true;
		}
	}

	protected export override function Check( context : ScriptExecutionContext ) : AIbehaviorConditionOutcomes
	{
		if( m_isShotgunner )
		{
			return true;
		}
		if( m_isHeavyRanged )
		{
			return true;
		}
		return true;
	}

}

class SimpleCanUseAvoidLOSMovement extends AIbehaviorconditionScript
{
	private var m_initialized : Bool;
	private var m_result : Bool;

	protected export override function Activate( context : ScriptExecutionContext )
	{
		if( !( m_initialized ) )
		{
			m_result = true;
			if( AICondition.CheckAbility( context, TweakDBInterface.GetGameplayAbilityRecord( T"Ability.IsShotgunnerArchetype" ) ) )
			{
			}
			else if( AICondition.CheckAbility( context, TweakDBInterface.GetGameplayAbilityRecord( T"Ability.IsHeavyRangedArchetype" ) ) )
			{
			}
			else if( AICondition.CheckAbility( context, TweakDBInterface.GetGameplayAbilityRecord( T"Ability.IsReckless" ) ) )
			{
				m_result = false;
			}
			else if( AICondition.CheckAbility( context, TweakDBInterface.GetGameplayAbilityRecord( T"Ability.IsAggressive" ) ) )
			{
				m_result = false;
			}
			else if( GetPuppet( context ).GetNPCType() == gamedataNPCType.Android )
			{
				m_result = false;
			}
			m_initialized = true;
		}
	}

	protected export override function Check( context : ScriptExecutionContext ) : AIbehaviorConditionOutcomes
	{
		return m_result;
	}

}

class SimpleCanUseCover extends AIbehaviorconditionScript
{
	private var m_ability : weak< GameplayAbility_Record >;
	private var m_prereqs : array< IPrereq >;
	private var m_prereqCount : Int32;
	private var m_game : GameInstance;

	protected export override function Activate( context : ScriptExecutionContext )
	{
		var record : IPrereq_Record;
		var prereq : IPrereq;
		var i : Int32;
		if( !( m_ability ) )
		{
			m_ability = TweakDBInterface.GetGameplayAbilityRecord( T"Ability.CanUseCovers" );
			if( m_ability )
			{
				m_game = ScriptExecutionContext.GetOwner( context ).GetGame();
				m_prereqCount = m_ability.GetPrereqsForUseCount();
				m_prereqs.Resize( m_prereqCount );
				for( i = 0; i < m_prereqCount; i += 1 )
				{
					record = m_ability.GetPrereqsForUseItem( i );
					prereq = IPrereq.CreatePrereq( record.GetID() );
					m_prereqs.PushBack( prereq );
				}
			}
		}
	}

	protected export override function Check( context : ScriptExecutionContext ) : AIbehaviorConditionOutcomes
	{
		if( !( m_ability ) )
		{
			return false;
		}
		if( CheckAbility( context ) )
		{
			return true;
		}
		return false;
	}

	private function CheckAbility( const context : ScriptExecutionContext ) : Bool
	{
		var i : Int32;
		for( i = 0; i < m_prereqCount; i += 1 )
		{
			if( !( m_prereqs[ i ].IsFulfilled( m_game, ScriptExecutionContext.GetOwner( context ) ) ) )
			{
				return false;
			}
		}
		return true;
	}

}

class SimpleCanSwapWeapons extends AIbehaviorconditionScript
{
	private var m_initialized : Bool;
	private var m_result : Bool;
	private var m_items : array< weak< NPCEquipmentItem_Record > >;

	protected export override function Activate( context : ScriptExecutionContext )
	{
		var conditions : array< weak< AIActionCondition_Record > >;
		var equipmentGroup : weak< NPCEquipmentGroup_Record >;
		var characterRecord : weak< Character_Record >;
		var i : Int32;
		m_result = false;
		if( ScriptExecutionContext.GetArgumentBool( context, 'EquipCommandWasActivated' ) )
		{
			m_result = true;
			return;
		}
		if( !( m_initialized ) )
		{
			characterRecord = TweakDBInterface.GetCharacterRecord( ScriptExecutionContext.GetOwner( context ).GetRecordID() );
			if( !( characterRecord ) )
			{
				return;
			}
			equipmentGroup = characterRecord.PrimaryEquipment();
			AIActionTransactionSystem.CalculateEquipmentItems( GetPuppet( context ), equipmentGroup, m_items, -1 );
		}
		m_initialized = true;
		for( i = 0; i < m_items.Size(); i += 1 )
		{
			conditions.Clear();
			m_items[ i ].UnequipCondition( conditions );
			if( conditions.Size() > 0 )
			{
				m_result = true;
				return;
			}
		}
	}

	protected export override function Check( context : ScriptExecutionContext ) : AIbehaviorConditionOutcomes
	{
		return m_result;
	}

}

class SimpleSandevistanHarassCondition extends AIbehaviorconditionScript
{
	private var m_initialized : Bool;
	private var m_result : Bool;

	protected export override function Activate( context : ScriptExecutionContext )
	{
		if( m_initialized )
		{
			return;
		}
		m_initialized = true;
		m_result = true;
		if( !( AIActionHelper.CheckAbility( ScriptExecutionContext.GetOwner( context ), TweakDBInterface.GetGameplayAbilityRecord( T"Ability.CanSprintHarass" ) ) ) )
		{
			m_result = false;
			return;
		}
		if( !( AIActionHelper.CheckAbility( ScriptExecutionContext.GetOwner( context ), TweakDBInterface.GetGameplayAbilityRecord( T"Ability.SandevistanDashShoot" ) ) ) )
		{
			m_result = false;
		}
	}

	protected export override function Check( context : ScriptExecutionContext ) : AIbehaviorConditionOutcomes
	{
		return m_result;
	}

}

class SimpleSandevistanDashShootCondition extends AIbehaviorconditionScript
{
	private var m_initialized : Bool;
	private var m_result : Bool;

	protected export override function Activate( context : ScriptExecutionContext )
	{
		if( m_initialized )
		{
			return;
		}
		m_initialized = true;
		if( AIActionHelper.CheckAbility( ScriptExecutionContext.GetOwner( context ), TweakDBInterface.GetGameplayAbilityRecord( T"Ability.SandevistanDashShoot" ) ) )
		{
			m_result = true;
		}
	}

	protected export override function Check( context : ScriptExecutionContext ) : AIbehaviorConditionOutcomes
	{
		return m_result;
	}

}

class SimpleSprintHarassCondition extends AIbehaviorconditionScript
{
	private var m_initialized : Bool;
	private var m_result : Bool;

	protected export override function Activate( context : ScriptExecutionContext )
	{
		if( m_initialized )
		{
			return;
		}
		m_initialized = true;
		if( AIActionHelper.CheckAbility( ScriptExecutionContext.GetOwner( context ), TweakDBInterface.GetGameplayAbilityRecord( T"Ability.CanSprintHarass" ) ) )
		{
			m_result = true;
		}
	}

	protected export override function Check( context : ScriptExecutionContext ) : AIbehaviorConditionOutcomes
	{
		return m_result;
	}

}

class SimpleSetUnequipWeapons extends AIbehaviortaskScript
{
	private var m_puppet : weak< ScriptedPuppet >;
	private var m_game : GameInstance;
	private var m_transactionSystem : TransactionSystem;
	private var m_primaryItems : array< weak< NPCEquipmentItem_Record > >;
	private var m_secondaryItems : array< weak< NPCEquipmentItem_Record > >;
	private var m_secondaryEquipmentDuplicatesPrimary : Bool;
	private var m_initialized : Bool;

	protected export override function Activate( context : ScriptExecutionContext )
	{
		if( !( m_initialized ) )
		{
			m_initialized = true;
			Init( context );
		}
	}

	protected export override function Update( context : ScriptExecutionContext ) : AIbehaviorUpdateOutcome
	{
		var itemsList : array< NPCItemToEquip >;
		if( GetItemsToUnequip( context, itemsList ) )
		{
			AIActionHelper.SetItemsUnequipData( m_puppet, itemsList, false );
			return AIbehaviorUpdateOutcome.SUCCESS;
		}
		return AIbehaviorUpdateOutcome.FAILURE;
	}

	private function Init( context : ScriptExecutionContext )
	{
		var characterRecord : weak< Character_Record >;
		var equipmentGroup : weak< NPCEquipmentGroup_Record >;
		var i : Int32;
		m_puppet = GetPuppet( context );
		if( !( m_puppet ) )
		{
			return;
		}
		characterRecord = TweakDBInterface.GetCharacterRecord( m_puppet.GetRecordID() );
		if( !( characterRecord ) )
		{
			return;
		}
		m_game = m_puppet.GetGame();
		m_transactionSystem = GameInstance.GetTransactionSystem( m_game );
		equipmentGroup = characterRecord.PrimaryEquipment();
		AIActionTransactionSystem.CalculateEquipmentItems( m_puppet, equipmentGroup, m_primaryItems, -1 );
		equipmentGroup = characterRecord.SecondaryEquipment();
		AIActionTransactionSystem.CalculateEquipmentItems( m_puppet, equipmentGroup, m_secondaryItems, -1 );
		for( i = 0; i < m_secondaryItems.Size(); i += 1 )
		{
			if( m_primaryItems.Contains( m_secondaryItems[ i ] ) )
			{
				m_secondaryEquipmentDuplicatesPrimary = true;
			}
		}
	}

	private function GetItemsToUnequip( context : ScriptExecutionContext, itemsList : ref< array< NPCItemToEquip > > ) : Bool
	{
		var item : NPCItemToEquip;
		var itemID : ItemID;
		var primaryItemID : ItemID;
		var conditions : array< weak< AIActionCondition_Record > >;
		var itemsToEquip : array< NPCItemToEquip >;
		var bodySlotId : TweakDBID;
		var currentItem : NPCEquipmentItem_Record;
		var hasFistsWoundedEquipped : Bool;
		var defaultID : TweakDBID;
		var i, j : Int32;
		if( !( m_puppet ) )
		{
			return false;
		}
		if( ItemID.GetTDBID( m_transactionSystem.GetItemInSlot( m_puppet, T"AttachmentSlots.WeaponRight" ).GetItemID() ) == T"Items.Npc_fists_wounded" )
		{
			hasFistsWoundedEquipped = true;
		}
		for( i = 0; i < m_primaryItems.Size(); i += 1 )
		{
			currentItem = m_primaryItems[ i ];
			if( !( currentItem.Item() ) )
			{
				continue;
			}
			if( !( currentItem.EquipSlot() ) )
			{
				continue;
			}
			if( currentItem.OnBodySlot() )
			{
				bodySlotId = currentItem.OnBodySlot().GetID();
			}
			if( AIActionTransactionSystem.GetItemID( m_puppet, currentItem.Item(), bodySlotId, itemID ) )
			{
				conditions.Clear();
				if( !( hasFistsWoundedEquipped ) && !( m_transactionSystem.HasItemInSlot( m_puppet, currentItem.EquipSlot().GetID(), itemID ) ) )
				{
					continue;
				}
				currentItem.UnequipCondition( conditions );
				if( ( conditions.Size() == 0 ) && !( hasFistsWoundedEquipped ) )
				{
					continue;
				}
				if( ( conditions.Size() > 0 ) && !( AICondition.CheckActionConditions( context, conditions ) ) )
				{
					continue;
				}
				item.itemID = itemID;
				item.slotID = currentItem.EquipSlot().GetID();
				item.bodySlotID = bodySlotId;
				itemsList.PushBack( item );
			}
		}
		if( itemsList.Size() > 0 )
		{
			return true;
		}
		for( i = 0; i < m_secondaryItems.Size(); i += 1 )
		{
			currentItem = m_secondaryItems[ i ];
			if( !( currentItem.Item() ) )
			{
				continue;
			}
			if( !( currentItem.EquipSlot() ) )
			{
				continue;
			}
			if( currentItem.OnBodySlot() )
			{
				bodySlotId = currentItem.OnBodySlot().GetID();
			}
			if( AIActionTransactionSystem.GetItemID( m_puppet, currentItem.Item(), bodySlotId, itemID ) )
			{
				conditions.Clear();
				if( !( hasFistsWoundedEquipped ) && !( m_transactionSystem.HasItemInSlot( m_puppet, currentItem.EquipSlot().GetID(), itemID ) ) )
				{
					continue;
				}
				currentItem.UnequipCondition( conditions );
				if( ( conditions.Size() > 0 ) && !( AICondition.CheckActionConditions( context, conditions ) ) )
				{
					continue;
				}
				GetItemsToEquip( context, itemsToEquip );
				if( itemsToEquip.Size() == 0 )
				{
					continue;
				}
				else
				{
					if( m_transactionSystem.HasItemInSlot( m_puppet, itemsToEquip[ 0 ].slotID, itemsToEquip[ 0 ].itemID ) )
					{
						continue;
					}
					if( m_secondaryEquipmentDuplicatesPrimary )
					{
						for( j = 0; j < m_primaryItems.Size(); j += 1 )
						{
							AIActionTransactionSystem.GetItemID( m_puppet, m_primaryItems[ j ].Item(), ( ( m_primaryItems[ j ].OnBodySlot() ) ? ( m_primaryItems[ j ].OnBodySlot().GetID() ) : ( defaultID ) ), primaryItemID );
							if( itemID == primaryItemID )
							{
								conditions.Clear();
								m_primaryItems[ j ].EquipCondition( conditions );
								if( AICondition.CheckActionConditions( context, conditions ) )
								{
									continue;
								}
							}
						}
					}
				}
				item.itemID = itemID;
				item.slotID = currentItem.EquipSlot().GetID();
				item.bodySlotID = bodySlotId;
				itemsList.PushBack( item );
			}
		}
		return itemsList.Size() > 0;
	}

	private function GetItemsToEquip( const context : ScriptExecutionContext, itemsList : ref< array< NPCItemToEquip > > ) : Bool
	{
		itemsList = IterateOverEquipItems( context, m_primaryItems );
		if( itemsList.Size() > 0 )
		{
			return true;
		}
		itemsList = IterateOverEquipItems( context, m_secondaryItems );
		return itemsList.Size() > 0;
	}

	private function IterateOverEquipItems( const context : ScriptExecutionContext, const itemsToCheck : ref< array< weak< NPCEquipmentItem_Record > > > ) : array< NPCItemToEquip >
	{
		var itemsList : array< NPCItemToEquip >;
		var item : NPCItemToEquip;
		var itemID : ItemID;
		var conditions : array< weak< AIActionCondition_Record > >;
		var bodySlotId : TweakDBID;
		var currentItem : NPCEquipmentItem_Record;
		var i, j : Int32;
		for( i = 0; i < itemsToCheck.Size(); i += 1 )
		{
			currentItem = itemsToCheck[ i ];
			if( !( currentItem.Item() ) )
			{
				continue;
			}
			if( !( currentItem.EquipSlot() ) )
			{
				continue;
			}
			if( currentItem.OnBodySlot() )
			{
				bodySlotId = currentItem.OnBodySlot().GetID();
			}
			if( AIActionTransactionSystem.GetItemID( m_puppet, currentItem.Item(), bodySlotId, itemID ) )
			{
				if( m_transactionSystem.HasItemInSlot( m_puppet, currentItem.EquipSlot().GetID(), itemID ) )
				{
					continue;
				}
				if( !( m_transactionSystem.HasItem( m_puppet, itemID ) ) )
				{
					continue;
				}
				conditions.Clear();
				currentItem.EquipCondition( conditions );
				if( ( conditions.Size() > 0 ) && !( AICondition.CheckActionConditions( context, conditions ) ) )
				{
					continue;
				}
				if( ( conditions.Size() == 0 ) && ( itemsList.Size() > 0 ) )
				{
					for( j = 0; j < itemsList.Size(); j += 1 )
					{
						if( itemsList[ j ].slotID == currentItem.EquipSlot().GetID() )
						{
							continue;
						}
					}
				}
				item.itemID = itemID;
				item.slotID = currentItem.EquipSlot().GetID();
				item.bodySlotID = bodySlotId;
				itemsList.PushBack( item );
			}
		}
		return itemsList;
	}

}

class SimpleSetEquipWeapons extends AIbehaviortaskScript
{
	editable var m_primary : Bool;
	default m_primary = true;
	editable var m_secondary : Bool;
	default m_secondary = true;
	private var m_puppet : weak< ScriptedPuppet >;
	private var m_game : GameInstance;
	private var m_transactionSystem : TransactionSystem;
	private var m_primaryItems : array< weak< NPCEquipmentItem_Record > >;
	private var m_secondaryItems : array< weak< NPCEquipmentItem_Record > >;
	private var m_initialized : Bool;

	protected export override function Activate( context : ScriptExecutionContext )
	{
		if( !( m_initialized ) )
		{
			m_initialized = true;
			Init( context );
		}
	}

	protected export override function Update( context : ScriptExecutionContext ) : AIbehaviorUpdateOutcome
	{
		var itemsList : array< NPCItemToEquip >;
		if( GetItemsToEquip( context, itemsList ) )
		{
			AIActionHelper.SetItemsEquipData( m_puppet, itemsList );
			return AIbehaviorUpdateOutcome.SUCCESS;
		}
		return AIbehaviorUpdateOutcome.FAILURE;
	}

	private function Init( context : ScriptExecutionContext )
	{
		var characterRecord : weak< Character_Record >;
		var equipmentGroup : weak< NPCEquipmentGroup_Record >;
		m_puppet = GetPuppet( context );
		if( !( m_puppet ) )
		{
			return;
		}
		characterRecord = TweakDBInterface.GetCharacterRecord( m_puppet.GetRecordID() );
		if( !( characterRecord ) )
		{
			return;
		}
		m_game = m_puppet.GetGame();
		m_transactionSystem = GameInstance.GetTransactionSystem( m_game );
		equipmentGroup = characterRecord.PrimaryEquipment();
		AIActionTransactionSystem.CalculateEquipmentItems( m_puppet, equipmentGroup, m_primaryItems, -1 );
		equipmentGroup = characterRecord.SecondaryEquipment();
		AIActionTransactionSystem.CalculateEquipmentItems( m_puppet, equipmentGroup, m_secondaryItems, -1 );
	}

	private function GetItemsToEquip( const context : ScriptExecutionContext, itemsList : ref< array< NPCItemToEquip > > ) : Bool
	{
		if( !( m_puppet ) )
		{
			return false;
		}
		if( m_primary )
		{
			itemsList = IterateOverEquipItems( context, m_primaryItems );
			if( itemsList.Size() > 0 )
			{
				return true;
			}
		}
		if( m_secondary )
		{
			itemsList = IterateOverEquipItems( context, m_secondaryItems );
			if( itemsList.Size() > 0 )
			{
				return true;
			}
		}
		return false;
	}

	private function IterateOverEquipItems( const context : ScriptExecutionContext, const itemsToCheck : ref< array< weak< NPCEquipmentItem_Record > > > ) : array< NPCItemToEquip >
	{
		var itemsList : array< NPCItemToEquip >;
		var item : NPCItemToEquip;
		var itemID : ItemID;
		var conditions : array< weak< AIActionCondition_Record > >;
		var bodySlotId : TweakDBID;
		var currentItem : NPCEquipmentItem_Record;
		var i, j : Int32;
		for( i = 0; i < itemsToCheck.Size(); i += 1 )
		{
			currentItem = itemsToCheck[ i ];
			if( !( currentItem.Item() ) )
			{
				continue;
			}
			if( !( currentItem.EquipSlot() ) )
			{
				continue;
			}
			if( currentItem.OnBodySlot() )
			{
				bodySlotId = currentItem.OnBodySlot().GetID();
			}
			if( AIActionTransactionSystem.GetItemID( m_puppet, currentItem.Item(), bodySlotId, itemID ) )
			{
				if( m_transactionSystem.HasItemInSlot( m_puppet, currentItem.EquipSlot().GetID(), itemID ) )
				{
					continue;
				}
				if( !( m_transactionSystem.HasItem( m_puppet, itemID ) ) )
				{
					continue;
				}
				conditions.Clear();
				currentItem.EquipCondition( conditions );
				if( ( conditions.Size() > 0 ) && !( AICondition.CheckActionConditions( context, conditions ) ) )
				{
					continue;
				}
				if( ( conditions.Size() == 0 ) && ( itemsList.Size() > 0 ) )
				{
					for( j = 0; j < itemsList.Size(); j += 1 )
					{
						if( itemsList[ j ].slotID == currentItem.EquipSlot().GetID() )
						{
							continue;
						}
					}
				}
				item.itemID = itemID;
				item.slotID = currentItem.EquipSlot().GetID();
				item.bodySlotID = bodySlotId;
				itemsList.PushBack( item );
			}
		}
		return itemsList;
	}

}

class SimpleShouldEvadeCondition extends AIbehaviorconditionScript
{
	private var m_hitReactionComponent : HitReactionComponent;

	protected export override function Activate( context : ScriptExecutionContext )
	{
		if( !( m_hitReactionComponent ) )
		{
			m_hitReactionComponent = GetPuppet( context ).GetHitReactionComponent();
		}
	}

	protected export override function Check( context : ScriptExecutionContext ) : AIbehaviorConditionOutcomes
	{
		if( m_hitReactionComponent.GetHasKerenzikov() )
		{
			if( !( m_hitReactionComponent.GetCanBlock() ) )
			{
				return true;
			}
			if( m_hitReactionComponent.GetShouldEvade() )
			{
				return true;
			}
		}
		return false;
	}

}

