class RoyceComponent extends ScriptableComponent
{
	private var m_owner : weak< NPCPuppet >;
	private var m_owner_id : EntityID;
	private var m_npcCollisionComponent : SimpleColliderComponent;
	private var m_npcDeathCollisionComponent : SimpleColliderComponent;
	private var m_npcHitRepresentationComponent : IComponent;
	private var m_statPoolSystem : StatPoolsSystem;
	private var m_hitData : AnimFeature_HitReactionsData;
	private var m_weakspotDestroyed : Bool;

	public function OnGameAttach()
	{
		m_owner = ( ( NPCPuppet )( GetOwner() ) );
		m_owner_id = m_owner.GetEntityID();
		m_statPoolSystem = GameInstance.GetStatPoolsSystem( m_owner.GetGame() );
		m_npcDeathCollisionComponent.Toggle( false );
		m_weakspotDestroyed = false;
		StatusEffectHelper.ApplyStatusEffect( m_owner, T"Royce.Phase1", m_owner.GetEntityID() );
	}

	protected event OnStatusEffectApplied( evt : ApplyStatusEffectEvent )
	{
		var tags : array< CName >;
		var enableColliderEvent : EnableColliderDelayEvent;
		enableColliderEvent = new EnableColliderDelayEvent;
		tags = evt.staticData.GameplayTags();
		if( StatusEffectSystem.ObjectHasStatusEffect( m_owner, T"BaseStatusEffect.Defeated" ) )
		{
			if( m_npcCollisionComponent )
			{
				GameInstance.GetDelaySystem( m_owner.GetGame() ).DelayEvent( m_owner, enableColliderEvent, 0.1 );
			}
		}
		if( tags.Contains( 'BossSuicide' ) )
		{
			SetPercentLifeForPhase( 0.0 );
		}
		if( tags.Contains( 'BossGrenadeHackEffect' ) )
		{
			StatusEffectHelper.ApplyStatusEffect( m_owner, T"BaseStatusEffect.WeakspotDestructionStatusEffect", m_owner_id );
		}
	}

	protected event OnStatusEffectRemoved( evt : RemoveStatusEffect )
	{
		var tags : array< CName >;
		tags = evt.staticData.GameplayTags();
		if( tags.Contains( 'Madness' ) )
		{
			StatusEffectHelper.ApplyStatusEffect( m_owner, T"BaseStatusEffect.BossSuicide", m_owner.GetEntityID() );
		}
	}

	private function DestroyAllWeakspots()
	{
		var weakspots : array< weak< WeakspotObject > >;
		var scriptWeakspot : ScriptedWeakspotObject;
		var i : Int32;
		m_owner.GetWeakspotComponent().GetWeakspots( weakspots );
		if( weakspots.Size() > 0 )
		{
			for( i = 0; i < weakspots.Size(); i += 1 )
			{
				scriptWeakspot = ( ( ScriptedWeakspotObject )( weakspots[ i ] ) );
				scriptWeakspot.DestroyWeakspot( m_owner );
				ScriptedWeakspotObject.Kill( weakspots[ i ] );
			}
		}
	}

	private function DestroyMainWeakspots()
	{
		var weakspots : array< weak< WeakspotObject > >;
		var scriptWeakspot : ScriptedWeakspotObject;
		m_owner.GetWeakspotComponent().GetWeakspots( weakspots );
		scriptWeakspot = ( ( ScriptedWeakspotObject )( weakspots[ 0 ] ) );
		scriptWeakspot.DestroyWeakspot( m_owner );
		ScriptedWeakspotObject.Kill( weakspots[ 0 ] );
	}

	public function SetPercentLifeForPhase( value : Float )
	{
		m_statPoolSystem = GameInstance.GetStatPoolsSystem( m_owner.GetGame() );
		m_statPoolSystem.RequestChangingStatPoolValue( m_owner.GetEntityID(), gamedataStatPoolType.Health, 100.0, m_owner, true );
		value = 100.0 - value;
		m_statPoolSystem.RequestChangingStatPoolValue( m_owner.GetEntityID(), gamedataStatPoolType.Health, -( value ), m_owner, true );
	}

	protected event OnDeathAfterDefeatedRoyce( evt : gameDeathEvent )
	{
		m_npcDeathCollisionComponent.Toggle( true );
	}

	protected event OnDefeated( evt : DefeatedEvent )
	{
		StatusEffectHelper.ApplyStatusEffect( m_owner, T"AdamSmasher.InvulnerableDefeated", m_owner_id );
	}

	protected event OnEnableColliderDelayEvent( enableColliderEvent : EnableColliderDelayEvent )
	{
		m_npcDeathCollisionComponent.Toggle( true );
	}

	protected event OnRequestComponents( ri : EntityRequestComponentsInterface )
	{
		EntityRequestComponentsInterface.RequestComponent( ri, 'npcCollision', 'SimpleColliderComponent', true );
		EntityRequestComponentsInterface.RequestComponent( ri, 'deathCollision', 'SimpleColliderComponent', true );
	}

	protected event OnTakeControl( ri : EntityResolveComponentsInterface )
	{
		m_npcCollisionComponent = ( ( SimpleColliderComponent )( EntityResolveComponentsInterface.GetComponent( ri, 'npcCollision' ) ) );
		m_npcDeathCollisionComponent = ( ( SimpleColliderComponent )( EntityResolveComponentsInterface.GetComponent( ri, 'deathCollision' ) ) );
	}

	protected event OnAudioEvent( evt : AudioEvent )
	{
		var evtFootstep : HeavyFootstepEvent;
		var player : weak< PlayerPuppet >;
		evtFootstep = new HeavyFootstepEvent;
		player = ( ( PlayerPuppet )( GetPlayerSystem().GetLocalPlayerControlledGameObject() ) );
		if( !( player ) )
		{
			return false;
		}
		if( evt.eventName == 'lcm_npc_exo_' )
		{
			evtFootstep.instigator = m_owner;
			evtFootstep.audioEventName = evt.eventName;
			player.QueueEvent( evtFootstep );
		}
	}

	protected event OnDeath( evt : gameDeathEvent )
	{
		if( ( ( ScriptedPuppet )( GetOwner() ) ).GetHitReactionComponent().GetHitStimEvent().hitBodyPart == ( ( Int32 )( EAIHitBodyPart.Head ) ) )
		{
			StartEffect( 'death_head_explode' );
			StatusEffectHelper.ApplyStatusEffect( m_owner, T"Royce.HeadExploded", m_owner.GetEntityID() );
		}
	}

	private function StartEffect( effectName : CName )
	{
		var spawnEffectEvent : entSpawnEffectEvent;
		spawnEffectEvent = new entSpawnEffectEvent;
		spawnEffectEvent.effectName = effectName;
		m_owner.QueueEvent( spawnEffectEvent );
	}

	protected event OnShotOnShield( hitEvent : gameHitEvent )
	{
		var empty : HitShapeData;
		var hitShapeData : HitShapeData;
		hitShapeData = ( ( HitShapeData )( hitEvent.hitRepresentationResult.hitShapes[ 0 ] ) );
		if( hitShapeData != empty && HitShapeUserDataBase.GetHitReactionZone( ( ( HitShapeUserDataBase )( hitShapeData.userData ) ) ) == EHitReactionZone.Special )
		{
			StartEffect( 'weakspot_compensating' );
		}
	}

}

class RoyceHealthChangeListener extends CustomValueStatPoolsListener
{
	var m_owner : weak< NPCPuppet >;
	private var m_royceComponent : RoyceComponent;
	private var m_weakspots : array< weak< WeakspotObject > >;

	public override function OnStatPoolValueChanged( oldValue : Float, newValue : Float, percToPoints : Float ) {}
}

class EnableColliderDelayEvent extends DelayEvent
{
}

