Player/PlayerController.Damage.cs
namespace Opium;

public partial class PlayerController
{
	/// <summary>
	/// Reference to a camera effect that is activated when the player dies.
	/// </summary>
	[Property] public CameraEffect DeathCameraEffect { get; set; }
	[Property] public CameraEffect HitByMeleeCameraEffect { get; set; }

	// TODO: Move this to PlayerPostProcessing
	[Property, Category( "Screen Effects" )] public RetroCameraVignette VignetteCameraEffect { get; set; }

	/// <summary>
	/// Can the player take damage?
	/// </summary>
	[ConVar( "op_god" )] public static bool IsGodMode { get; set; } = false;


	[ConCmd( "op_dev_damage" )]
	public static void DevDamage( float damage = 1f )
	{
		var pl = Opium.PlayerController.Local;
		pl.GameObject.TakeDamage( Opium.DamageInfo.Bullet( damage, pl.GameObject, pl.GameObject ) );
	}

	[ConCmd( "op_dev_sethp" )]
	public static void DevSetHP( float health = 100f )
	{
		var pl = Opium.PlayerController.Local;
		pl.Health = health;
	}

	/// <summary>
	/// Called when we die.
	/// </summary>
	/// <param name="damageInfo"></param>
	public override void OnKilled( in Sandbox.DamageInfo damageInfo )
	{
		// Can't die twice.
		if ( !IsAlive ) return;

		Kill();
	}

	/// <summary>
	/// Called when we take damage.
	/// </summary>
	/// <param name="damage"></param>
	public override void OnDamage( in Sandbox.DamageInfo damage )
	{
		if ( IsGodMode ) damage.Damage = 0;

		if ( ActiveWeapon is MeleeWeapon melee && (melee.BlockAttack?.IsActive ?? false) )
		{
			damage.Damage *= melee.BlockDamageFactor;
		}

		if ( HitByMeleeCameraEffect is not null && damage is Opium.DamageInfo dmg && dmg.HasTag( "melee" ) )
		{
			HitByMeleeCameraEffect.Player = this;
			HitByMeleeCameraEffect.Enabled = true;
		}

		base.OnDamage( damage );
	}

	/// <summary>
	/// Called when we die.
	/// </summary>
	public void Kill()
	{
		IsAlive = false;
		LockMovement = true;
		LockCameraMovement = true;

		Inventory.Drop( Inventory.Current );
		Inventory.Clear();

		if ( DeathCameraEffect is not null )
		{
			DeathCameraEffect.Enabled = true;
			DeathCameraEffect.Player = this;
		}
	}

	float smoothHealth = 100f;

	/// <summary>
	/// A method that is called every Update to update damage FX on the screen.
	/// TODO: Maybe make this driven in UI?
	/// </summary>
	void UpdateDamageScreenEffect()
	{
		smoothHealth = smoothHealth.LerpTo( Health, Time.Delta * 5f );

		if ( IsAlive )
		{
			if ( VignetteCameraEffect is not null )
			{
				var timesinceDmg = TimeSinceLastDamage.Relative.Remap( 0, 1f, 0.4f, 0 );
				VignetteCameraEffect.Intensity = smoothHealth.Remap( 100, 0, 0, .5f ) + timesinceDmg;

			}
		}
		else
		{
			if ( VignetteCameraEffect is not null )
				VignetteCameraEffect.Intensity = .75f;
		}
	}
}