import class Muppet extends gamePuppetBase
{
	private var m_hitRepresantation : SlotComponent;
	private var m_slotComponent : SlotComponent;
	var m_highDamageThreshold : Float;
	var m_medDamageThreshold : Float;
	var m_lowDamageThreshold : Float;
	var m_effectTimeStamp : Float;

	public import const final function GetAttitude() : AttitudeAgent;
	public import const final function IsMuppetIncapacitated() : Bool;
	public import const final function GetItemQuantity( itemId : ItemID ) : Int32;

	public const override function GetAttitudeAgent() : AttitudeAgent
	{
		return GetAttitude();
	}

	public const function GetHitRepresantationSlotComponent() : SlotComponent
	{
		return m_hitRepresantation;
	}

	public const function GetSlotComponent() : SlotComponent
	{
		return m_slotComponent;
	}

	public const override function IsPlayer() : Bool
	{
		return true;
	}

	protected event OnRequestComponents( ri : EntityRequestComponentsInterface )
	{
		EntityRequestComponentsInterface.RequestComponent( ri, 'HitRepresentation', 'SlotComponent', false );
		EntityRequestComponentsInterface.RequestComponent( ri, 'Item_Attachment_Slot', 'SlotComponent', false );
		super.OnRequestComponents( ri );
	}

	protected event OnTakeControl( ri : EntityResolveComponentsInterface )
	{
		m_hitRepresantation = ( ( SlotComponent )( EntityResolveComponentsInterface.GetComponent( ri, 'HitRepresentation' ) ) );
		m_slotComponent = ( ( SlotComponent )( EntityResolveComponentsInterface.GetComponent( ri, 'Item_Attachment_Slot' ) ) );
		super.OnTakeControl( ri );
	}

	public const override function IsIncapacitated() : Bool
	{
		return IsMuppetIncapacitated();
	}

	private function GetDamageThresholdParams()
	{
		m_highDamageThreshold = TDB.GetFloat( T"player.damageThresholds.highDamageThreshold", 40.0 );
		m_medDamageThreshold = TDB.GetFloat( T"player.damageThresholds.medDamageThreshold", 20.0 );
		m_lowDamageThreshold = TDB.GetFloat( T"player.damageThresholds.lowDamageThreshold", 1.0 );
	}

	private override function OnHitVFX( hitEvent : gameHitEvent )
	{
		var damageDealt : Float;
		var currentHitStamp : Float;
		var effectDelay : Float;
		if( ( IsClient() && IsControlledByLocalPeer() ) || !( IsMultiplayer() ) )
		{
			damageDealt = hitEvent.attackComputed.GetTotalAttackValue( gamedataStatPoolType.Health );
			GetDamageThresholdParams();
			effectDelay = TDB.GetFloat( T"player.hitVFX.delay", 0.40000001 );
			currentHitStamp = EngineTime.ToFloat( GameInstance.GetSimTime( GetGame() ) );
			if( ( currentHitStamp - effectDelay ) >= m_effectTimeStamp )
			{
				if( damageDealt <= 0.0 )
				{
					return;
				}
				else if( damageDealt >= m_highDamageThreshold )
				{
					GameObjectEffectHelper.StartEffectEvent( this, 'fx_damage_high' );
				}
				else if( damageDealt >= m_medDamageThreshold )
				{
					GameObjectEffectHelper.StartEffectEvent( this, 'fx_damage_medium' );
				}
				else if( damageDealt >= m_lowDamageThreshold )
				{
					GameObjectEffectHelper.StartEffectEvent( this, 'fx_damage_low' );
				}
				m_effectTimeStamp = EngineTime.ToFloat( GameInstance.GetSimTime( GetGame() ) );
			}
		}
	}

	private override final function OnHitSounds( hitEvent : gameHitEvent )
	{
		var soundEvent : SoundPlayEvent;
		var damageSwitch : SoundSwitchEvent;
		var soundParamAxisX : SoundParameterEvent;
		var soundParamAxisY : SoundParameterEvent;
		var hitDirection : Vector4;
		var target : GameObject;
		var forwardLocalToWorldAngle : Float;
		var damageValue : Float;
		var playerOutOfOxygen : Bool;
		super.OnHitSounds( hitEvent );
		if( IsServer() )
		{
			if( GameInstance.GetStatPoolsSystem( GetGame() ).GetStatPoolValue( GetEntityID(), gamedataStatPoolType.Health ) < 30.0 )
			{
				ChatterHelper.PlayCpoServerSyncVoiceOver( this, 'cpo_nearly_dead' );
			}
			if( GameInstance.GetStatPoolsSystem( GetGame() ).GetStatPoolValue( GetEntityID(), gamedataStatPoolType.CPO_Armor ) == 0.0 )
			{
				ChatterHelper.PlayCpoServerSyncVoiceOver( this, 'cpo_armor_broken' );
			}
			return;
		}
		playerOutOfOxygen = hitEvent.attackData.GetAttackDefinition().GetRecord().GetID() == T"Attacks.OutOfOxygenDamageOverTime";
		if( playerOutOfOxygen )
		{
			return;
		}
		soundEvent = new SoundPlayEvent;
		damageSwitch = new SoundSwitchEvent;
		soundParamAxisX = new SoundParameterEvent;
		soundParamAxisY = new SoundParameterEvent;
		target = hitEvent.target;
		forwardLocalToWorldAngle = Vector4.Heading( target.GetWorldForward() );
		hitDirection = Vector4.RotByAngleXY( hitEvent.hitDirection, forwardLocalToWorldAngle );
		soundParamAxisX.parameterName = 'RTPC_Positioning_2D_LR_axis';
		soundParamAxisX.parameterValue = hitDirection.X * 100.0;
		soundParamAxisY.parameterName = 'RTPC_Positioning_2D_FB_axis';
		soundParamAxisY.parameterValue = hitDirection.Y * 100.0;
		target.QueueEvent( soundParamAxisX );
		target.QueueEvent( soundParamAxisY );
		damageSwitch.switchName = 'SW_Impact_Velocity';
		damageValue = hitEvent.attackComputed.GetTotalAttackValue( gamedataStatPoolType.Health );
		if( damageValue >= m_highDamageThreshold )
		{
			damageSwitch.switchValue = 'SW_Impact_Velocity_Hi';
		}
		else if( damageValue >= m_medDamageThreshold )
		{
			damageSwitch.switchValue = 'SW_Impact_Velocity_Med';
		}
		else if( damageValue >= m_lowDamageThreshold )
		{
			damageSwitch.switchValue = 'SW_Impact_Velocity_Low';
		}
		target.QueueEvent( damageSwitch );
		GameObject.PlayVoiceOver( this, 'onPlayerHit', 'Scripts:OnHitSounds' );
		if( !( hitEvent.attackData.GetWeapon().GetItemData().HasTag( WeaponObject.GetMeleeWeaponTag() ) ) )
		{
			soundEvent.soundName = 'w_feedback_player_damage';
			target.QueueEvent( soundEvent );
		}
		if( ( IsClient() && IsControlledByLocalPeer() ) && ( GameInstance.GetStatPoolsSystem( GetGame() ).GetStatPoolValue( GetEntityID(), gamedataStatPoolType.CPO_Armor ) == 0.0 ) )
		{
			soundEvent.soundName = 'test_ad_emitter_2_1';
			target.QueueEvent( soundEvent );
		}
	}

}

