class GrenadeChangedCallback extends AttachmentSlotsScriptCallback
{
	var grenadeChangeEntity : weak< GameObject >;
	var grenadeChangeListener : AttachmentSlotsScriptListener;

	public export override function OnItemEquippedVisual( slot : TweakDBID, item : ItemID )
	{
		var itemObject : ItemObject;
		itemObject = GameInstance.GetTransactionSystem( grenadeChangeEntity.GetGame() ).GetItemInSlot( grenadeChangeEntity, T"AttachmentSlots.WeaponLeft" );
		if( !( itemObject ) )
		{
			return;
		}
		TriggerItemActivation( ( ( gamePuppet )( grenadeChangeEntity ) ), T"AttachmentSlots.WeaponLeft" );
		if( grenadeChangeListener && grenadeChangeEntity )
		{
			GameInstance.GetTransactionSystem( grenadeChangeEntity.GetGame() ).UnregisterAttachmentSlotListener( grenadeChangeEntity, grenadeChangeListener );
		}
	}

	private function TriggerItemActivation( puppet : gamePuppet, attachmentSlotID : TweakDBID )
	{
		var transactionSystem : TransactionSystem;
		var item : weak< ItemObject >;
		var launchEvent : gameprojectileSetUpAndLaunchEvent;
		var forceActivationEvent : gameprojectileForceActivationEvent;
		var orientation : Quaternion;
		transactionSystem = GameInstance.GetTransactionSystem( puppet.GetGame() );
		if( !( transactionSystem ) )
		{
			return;
		}
		item = transactionSystem.GetItemInSlot( puppet, attachmentSlotID );
		if( !( item ) )
		{
			return;
		}
		launchEvent = new gameprojectileSetUpAndLaunchEvent;
		forceActivationEvent = new gameprojectileForceActivationEvent;
		transactionSystem.RemoveItemFromSlot( puppet, attachmentSlotID, false );
		launchEvent.launchParams.logicalPositionProvider = IPositionProvider.CreateEntityPositionProvider( item );
		launchEvent.launchParams.logicalOrientationProvider = IOrientationProvider.CreateEntityOrientationProvider( NULL, '', puppet );
		launchEvent.launchParams.visualPositionProvider = IPositionProvider.CreateEntityPositionProvider( item );
		Quaternion.SetIdentity( orientation );
		launchEvent.launchParams.visualOrientationProvider = IOrientationProvider.CreateStaticOrientationProvider( orientation );
		launchEvent.launchParams.ownerVelocityProvider = MoveComponentVelocityProvider.CreateMoveComponentVelocityProvider( puppet );
		launchEvent.owner = puppet;
		item.QueueEvent( launchEvent );
		item.QueueEvent( forceActivationEvent );
	}

}

class GrenadeLvl4HackEffector extends Effector
{
	private var m_grenadeChangeEntity : weak< GameObject >;
	private var m_grenadeChangedListener : AttachmentSlotsScriptListener;

	protected export override function ActionOn( owner : GameObject )
	{
		var grenadeChangedCallback : GrenadeChangedCallback;
		if( !( m_grenadeChangedListener ) )
		{
			m_grenadeChangeEntity = owner;
			grenadeChangedCallback = new GrenadeChangedCallback;
			grenadeChangedCallback.grenadeChangeEntity = m_grenadeChangeEntity;
			grenadeChangedCallback.slotID = T"AttachmentSlots.WeaponLeft";
			m_grenadeChangedListener = GameInstance.GetTransactionSystem( owner.GetGame() ).RegisterAttachmentSlotListener( m_grenadeChangeEntity, grenadeChangedCallback );
			grenadeChangedCallback.grenadeChangeListener = m_grenadeChangedListener;
		}
		ProcessEffector( owner );
	}

	protected export override function RepeatedAction( owner : GameObject )
	{
		ProcessEffector( owner );
	}

	private function ProcessEffector( owner : GameObject )
	{
		var puppet : gamePuppet;
		var transactionSystem : TransactionSystem;
		var statSystem : StatsSystem;
		var hasFrag : Bool;
		var hasFire : Bool;
		var hasBio : Bool;
		var hasEMP : Bool;
		var item : TweakDBID;
		var itemID : ItemID;
		var highPriority : Bool;
		var inventoryManager : InventoryDataManagerV2;
		puppet = ( ( gamePuppet )( owner ) );
		transactionSystem = GameInstance.GetTransactionSystem( puppet.GetGame() );
		statSystem = GameInstance.GetStatsSystem( puppet.GetGame() );
		hasFrag = statSystem.GetStatValue( owner.GetEntityID(), gamedataStatType.CanUseFragGrenades ) > 0.0;
		hasFire = statSystem.GetStatValue( owner.GetEntityID(), gamedataStatType.CanUseIncendiaryGrenades ) > 0.0;
		hasBio = statSystem.GetStatValue( owner.GetEntityID(), gamedataStatType.CanUseBiohazardGrenades ) > 0.0;
		hasEMP = statSystem.GetStatValue( owner.GetEntityID(), gamedataStatType.CanUseEMPGrenades ) > 0.0;
		inventoryManager = new InventoryDataManagerV2;
		inventoryManager.Initialize( ( ( PlayerPuppet )( owner ) ) );
		if( !( puppet ) )
		{
			return;
		}
		if( hasFrag )
		{
			item = T"Items.GrenadeFragRegularHack";
		}
		else if( hasFire )
		{
			item = T"Items.GrenadeIncendiaryRegularHack";
		}
		else if( hasBio )
		{
			item = T"Items.GrenadeBiohazardRegularHack";
		}
		else if( hasEMP )
		{
			item = T"Items.GrenadeEMPRegularHack";
		}
		else
		{
			item = T"Items.GrenadeFragRegularHack";
		}
		itemID = ItemID.CreateQuery( item );
		if( !( ItemID.IsValid( itemID ) ) )
		{
			return;
		}
		if( !( transactionSystem ) )
		{
			return;
		}
		if( transactionSystem.HasItemInAnySlot( owner, itemID ) )
		{
			if( !( transactionSystem.HasItem( owner, itemID ) ) )
			{
				if( !( transactionSystem.GiveItem( owner, itemID, 1 ) ) )
				{
					return;
				}
			}
			if( !( transactionSystem.ChangeItemToSlot( owner, T"AttachmentSlots.WeaponLeft", itemID ) ) )
			{
				return;
			}
		}
		else
		{
			if( !( transactionSystem.HasItem( owner, itemID ) ) )
			{
				if( !( transactionSystem.GiveItem( owner, itemID, 1 ) ) )
				{
					return;
				}
			}
			highPriority = WeaponObject.GetWeaponType( itemID ) != gamedataItemType.Invalid;
			if( !( transactionSystem.AddItemToSlot( owner, T"AttachmentSlots.WeaponLeft", itemID, highPriority ) ) )
			{
				return;
			}
		}
		AIActionHelper.ClearItemsToEquip( ( ( ScriptedPuppet )( owner ) ) );
	}

}

