class NanoTechPlatesEffector extends ModifyAttackEffector
{
	private var m_chanceToTrigger : Float;
	private var m_chanceIncrement : Float;
	private var m_nanoPlatesStacks : Int32;
	private var m_timeWindow : Float;
	private var m_minTimeBetweenBlocks : Float;
	private var m_timeStamps : array< Float >;

	protected override function Initialize( record : TweakDBID, game : GameInstance, parentRecord : TweakDBID )
	{
		m_chanceToTrigger = TDB.GetFloat( record + T".chanceToTrigger" );
		m_chanceIncrement = TDB.GetFloat( record + T".chanceIncrement" );
		m_nanoPlatesStacks = TDB.GetInt( record + T".nanoPlatesStacks" );
		m_timeWindow = TDB.GetFloat( record + T".timeWindow" );
		m_minTimeBetweenBlocks = TDB.GetFloat( record + T".minTimeBetweenBlocks" );
	}

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

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

	private function ProcessAction( owner : GameObject )
	{
		var hitEvent : gameHitEvent;
		var damage : Float;
		var statusEffectSystem : StatusEffectSystem;
		var useIncreasedChance : Bool;
		var calculatedChance : Float;
		var timeStamp : Float;
		var timeStampsSize : Int32;
		var unavailabilityDuration : Float;
		timeStamp = EngineTime.ToFloat( GameInstance.GetTimeSystem( owner.GetGame() ).GetSimTime() );
		hitEvent = GetHitEvent();
		if( !( hitEvent ) )
		{
			return;
		}
		damage = hitEvent.attackComputed.GetTotalAttackValue( gamedataStatPoolType.Health );
		if( damage <= 0.0 )
		{
			return;
		}
		statusEffectSystem = GameInstance.GetStatusEffectSystem( owner.GetGame() );
		useIncreasedChance = statusEffectSystem.HasStatusEffectWithTag( owner.GetEntityID(), 'NanoTechPlatesAfterDash' );
		calculatedChance = m_chanceToTrigger + ( ( useIncreasedChance ) ? ( m_chanceIncrement ) : ( 0.0 ) );
		if( RandF() >= calculatedChance )
		{
			return;
		}
		if( useIncreasedChance )
		{
			CleanUpTimeStamps( owner, timeStamp );
			timeStampsSize = m_timeStamps.Size();
			if( timeStampsSize >= m_nanoPlatesStacks )
			{
				StatusEffectHelper.RemoveStatusEffectsWithTag( owner, 'NanoTechPlatesAfterDash', 0.0 );
				return;
			}
			if( ( timeStampsSize != 0 ) && ( AbsF( m_timeStamps.Last() - timeStamp ) < m_minTimeBetweenBlocks ) )
			{
				return;
			}
			m_timeStamps.PushBack( timeStamp );
			timeStampsSize += 1;
		}
		hitEvent.attackComputed.MultAttackValue( 0.0 );
		StatusEffectHelper.RemoveStatusEffectsWithTag( owner, 'NanoTechPlatesAfterDash', 0.0 );
		if( useIncreasedChance )
		{
			StatusEffectHelper.ApplyStatusEffectForTimeWindow( owner, T"BaseStatusEffect.NanoTechPlatesBlockIndication", owner.GetEntityID(), 0.0, m_timeWindow );
			if( timeStampsSize >= m_nanoPlatesStacks )
			{
				unavailabilityDuration = ( m_timeStamps[ 0 ] + m_timeWindow ) - timeStamp;
				if( unavailabilityDuration <= 0.0 )
				{
					unavailabilityDuration = m_timeWindow;
				}
				StatusEffectHelper.ApplyStatusEffectForTimeWindow( owner, T"BaseStatusEffect.NanoTechPlatesUnavailableStatusEffect", owner.GetEntityID(), 0.0, unavailabilityDuration );
			}
		}
		GameObject.PlaySound( owner, 'w_cyb_nanotech_plates_deflecting' );
	}

	private function CleanUpTimeStamps( owner : GameObject, currentTime : Float )
	{
		var i, size : Int32;
		size = m_timeStamps.Size();
		for( i = 0; i < size; i += 1 )
		{
			if( m_timeStamps[ 0 ] < ( currentTime - m_timeWindow ) )
			{
				m_timeStamps.Remove( m_timeStamps[ 0 ] );
			}
			else
			{
				return;
			}
		}
	}

}

