import enum gameDismBodyPart
{
	LEFT_ARM,
	RIGHT_ARM,
	LEFT_LEG,
	RIGHT_LEG,
	HEAD,
	BODY,
}

import enum gameDismWoundType
{
	CLEAN,
	COARSE,
	HOLE,
}

import enum entAudioDismembermentPart
{
	Head,
	Leg,
	Arm,
}

importonly final struct DismemberedLimbCount
{
	import var fleshDismemberments : Uint32;
	import var cyberDismemberments : Uint32;
}

importonly final class DismembermentAudioEvent extends Event
{
	import var bodyPart : entAudioDismembermentPart;
	import var position : Vector4;
}

class DismembermentEvent extends Event
{
	var m_bodyPart : gameDismBodyPart;
	var m_woundType : gameDismWoundType;
	var m_strength : Float;
	var m_isCritical : Bool;
	var m_debrisPath : String;
	var m_debrisStrength : Float;
}

class DismembermentExplosionEvent extends Event
{
	var m_epicentrum : Vector4;
	var m_strength : Float;
}

class DismembermentDebrisEvent extends Event
{
	var m_resourcePath : String;
	var m_strength : Float;
}

import class DismembermentComponent extends IComponent
{
	private import function ReportExplosion( hitPosition : Vector4, strength : Float );
	private import function DoDismemberment( bodyPart : gameDismBodyPart, woundType : gameDismWoundType, optional strength : Float, isCritical : Bool, optional debrisPath : String, optional debrisStrength : Float );
	private import function SpawnGutsFromLastHit( resourcePath : String, strength : Float );
	public import function GetDismemberedLimbCount() : DismemberedLimbCount;

	public static function RequestGutsFromLastHit( obj : GameObject, const resourcePath : ref< String >, strength : Float )
	{
		var evt : DismembermentDebrisEvent;
		evt = new DismembermentDebrisEvent;
		evt.m_resourcePath = resourcePath;
		evt.m_strength = strength;
		obj.QueueEvent( evt );
	}

	public static function RequestDismemberment( obj : GameObject, bodyPart : gameDismBodyPart, woundType : gameDismWoundType, optional hitPosition : Vector4, optional isCritical : Bool, optional debrisPath : String, optional debrisStrength : Float )
	{
		var evt : DismembermentEvent;
		var audioEvt : DismembermentAudioEvent;
		var playerObject : GameObject;
		evt = new DismembermentEvent;
		evt.m_bodyPart = bodyPart;
		evt.m_woundType = woundType;
		evt.m_strength = 8.0;
		evt.m_isCritical = isCritical;
		evt.m_debrisPath = debrisPath;
		evt.m_debrisStrength = debrisStrength;
		obj.QueueEvent( evt );
		if( Vector4.IsZero( hitPosition ) )
		{
			return;
		}
		audioEvt = new DismembermentAudioEvent;
		switch( evt.m_bodyPart )
		{
			case gameDismBodyPart.HEAD:
				audioEvt.bodyPart = entAudioDismembermentPart.Head;
			break;
			case gameDismBodyPart.LEFT_ARM:
			case gameDismBodyPart.RIGHT_ARM:
				audioEvt.bodyPart = entAudioDismembermentPart.Arm;
			break;
			case gameDismBodyPart.LEFT_LEG:
			case gameDismBodyPart.RIGHT_LEG:
				audioEvt.bodyPart = entAudioDismembermentPart.Leg;
			break;
			default:
				break;
		}
		audioEvt.position = hitPosition;
		obj.QueueEvent( audioEvt );
		if( !( obj.IsPlayer() ) )
		{
			playerObject = GameInstance.GetPlayerSystem( obj.GetGame() ).GetLocalPlayerMainGameObject();
			if( PlayerDevelopmentSystem.GetData( playerObject ).IsNewPerkBought( gamedataNewPerkType.Reflexes_Master_Perk_5 ) > 0 )
			{
				StatusEffectHelper.ApplyStatusEffect( playerObject, T"BaseStatusEffect.Reflexes_Master_Perk_5_Buff_Level_1" );
			}
		}
	}

	protected event OnDismemberment( evt : DismembermentEvent )
	{
		DoDismemberment( evt.m_bodyPart, evt.m_woundType, evt.m_strength, evt.m_isCritical, evt.m_debrisPath, evt.m_debrisStrength );
	}

	protected event OnDismembermentExplosion( evt : DismembermentExplosionEvent )
	{
		ReportExplosion( evt.m_epicentrum, evt.m_strength );
	}

	protected event OnDismembermentDebris( evt : DismembermentDebrisEvent )
	{
		SpawnGutsFromLastHit( evt.m_resourcePath, evt.m_strength );
	}

}

