abstract class AbstractApplyQuickhackEffector extends ModifyAttackEffector
{
	protected var m_blackboard : weak< IBlackboard >;
	protected var m_applyQuickhackDelayConst : Float;
	default m_applyQuickhackDelayConst = 0.1f;

	protected override function Initialize( record : TweakDBID, game : GameInstance, parentRecord : TweakDBID )
	{
		var blackboardSystem : BlackboardSystem;
		blackboardSystem = GameInstance.GetBlackboardSystem( game );
		m_blackboard = blackboardSystem.GetLocalInstanced( GetPlayer( game ).GetEntityID(), GetAllBlackboardDefs().PlayerStateMachine );
	}

	protected export override function ActionOn( owner : GameObject )
	{
		ProcessAction( owner );
	}

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

	protected function ProcessAction( owner : GameObject )
	{
		var hitEvent : gameHitEvent;
		var hitAttackData : AttackData;
		var playerOwnerPuppet : PlayerPuppet;
		var targetScriptedPuppet : ScriptedPuppet;
		hitEvent = GetHitEvent();
		if( !( hitEvent ) )
		{
			return;
		}
		hitAttackData = hitEvent.attackData;
		playerOwnerPuppet = ( ( PlayerPuppet )( hitAttackData.GetInstigator() ) );
		targetScriptedPuppet = ( ( ScriptedPuppet )( hitEvent.target ) );
		return ProcessApplyQuickhackAction( hitEvent, playerOwnerPuppet, targetScriptedPuppet );
	}

	protected virtual function ProcessApplyQuickhackAction( hitEvent : gameHitEvent, playerPuppet : PlayerPuppet, targetScriptedPuppet : ScriptedPuppet ) {}

	public function TriggerSpecialQuickHackAttack( playerOwnerPuppet : PlayerPuppet, quickhackData : QuickhackData, applyQuickhackDelay : Float )
	{
		var specialQuickhackTriggeredEvent : OnSpecialQuickhackTriggeredEvent;
		var quickhackActionID : TweakDBID;
		if( quickhackData == NULL )
		{
			return;
		}
		specialQuickhackTriggeredEvent = new OnSpecialQuickhackTriggeredEvent;
		specialQuickhackTriggeredEvent.quickhackData = quickhackData;
		quickhackActionID = quickhackData.m_action.GetObjectActionID();
		m_blackboard.SetVariant( GetAllBlackboardDefs().PlayerStateMachine.CostFreeActionID, quickhackActionID );
		GameInstance.GetDelaySystem( playerOwnerPuppet.GetGame() ).DelayEvent( playerOwnerPuppet, specialQuickhackTriggeredEvent, applyQuickhackDelay );
	}

}

class ApplyQuickhackEffector extends AbstractApplyQuickhackEffector
{
	var m_quickhackObjectActionID : TweakDBID;
	var m_quickhackObjectActionRecord : weak< ObjectAction_Record >;
	var m_MaxUploadChance : Float;
	var m_uploadTime : Float;

	protected override function Initialize( record : TweakDBID, game : GameInstance, parentRecord : TweakDBID )
	{
		super.Initialize( record, game, parentRecord );
		m_quickhackObjectActionID = TDB.GetForeignKey( record + T".objectAction" );
		m_quickhackObjectActionRecord = TweakDBInterface.GetObjectActionRecord( m_quickhackObjectActionID );
		m_MaxUploadChance = TDB.GetFloat( record + T".uploadChance" );
		m_uploadTime = TDB.GetFloat( record + T".uploadTime" );
	}

	protected override function ProcessApplyQuickhackAction( hitEvent : gameHitEvent, playerPuppet : PlayerPuppet, targetScriptedPuppet : ScriptedPuppet )
	{
		var playerFreeCostActionIDName : TweakDBID;
		var quickhackData : QuickhackData;
		var randomUploadChanceValue : Float;
		randomUploadChanceValue = RandF();
		if( randomUploadChanceValue > m_MaxUploadChance )
		{
			return;
		}
		playerFreeCostActionIDName = ( ( TweakDBID )( m_blackboard.GetVariant( GetAllBlackboardDefs().PlayerStateMachine.CostFreeActionID ) ) );
		quickhackData = RPGManager.CreateSimpleQuickhackData( playerPuppet, targetScriptedPuppet, m_quickhackObjectActionRecord );
		if( !( quickhackData ) || TDBID.IsValid( playerFreeCostActionIDName ) )
		{
			return;
		}
		quickhackData.m_uploadTime = ( ( m_uploadTime == 0.0 ) ? ( quickhackData.m_uploadTime ) : ( m_uploadTime ) );
		TriggerSpecialQuickHackAttack( playerPuppet, quickhackData, m_applyQuickhackDelayConst );
	}

}

