unitStatus/UnitStatusPunched.cs

A unit status class representing a 'punched' state applied to a unit. It sets a short lifetime, handles collisions with Enemy instances to apply damage, stun and knockback, and removes itself after the lifetime or after a heavy collision.

Networking
using System;
using Sandbox;

public class UnitStatusPunched : UnitStatus
{
	public Enemy EnemySource { get; set; } // todo: never set
	public Player PlayerSource { get; set; }

	public UnitStatusPunched()
	{
		
	}

	public override void Init( Unit unit )
	{
		base.Init( unit );

		//Unit.SetStateStunned( true );

		Lifetime = 0.5f;
	}

	public override void Update( float dt )
	{
		base.Update( dt );

		if ( !Unit.IsValid() )
			return;

		if ( ElapsedTime > Lifetime )
			Unit.RemoveUnitStatus( this );

		//Gizmo.Draw.Color = Color.White;
		//Gizmo.Draw.Text( $"{Unit.ExplosionVelocity.Length.ToString("N2")}", new global::Transform( Unit.WorldPosition ) );

		// todo: clouds
	}

	public override void Die( Player player )
	{
		base.Die( player );

	}

	public override void Colliding( Thing other, float percent, float dt )
	{
		base.Colliding( other, percent, dt );

		if( other is Enemy enemy )
		{
			// only happen if weight is low enough to make it be moving fast enough
			if ( Unit.ExplosionVelocity.LengthSquared > Math.Pow( 250f, 2f ) )
			{
				var dir = Vector2.Lerp( (enemy.Position2D - Unit.Position2D).Normal, Unit.ExplosionVelocity.Normal, 0.33f );

				enemy.DamageRpc( 3f, PlayerSource, DamageType.Other, enemy.Position2D, force: dir * Unit.ExplosionVelocity.Length * 0.4f, isCrit: false, shouldFlinch: true );
				enemy.Stun( PlayerSource, null, 0.5f );

				//Unit.ExplosionVelocity = (Unit.Position2D - enemy.Position2D).Normal * Unit.ExplosionVelocity.Length * 0.4f;
				Unit.ExplosionVelocity = -dir * Unit.ExplosionVelocity.Length * 0.2f;
				Unit.RemoveUnitStatus( this );
				Unit.Stun( PlayerSource, null, 0.5f );
			}
		}
	}

	public override void OnRemove( bool playEffects = true )
	{
		//Unit.SetStateStunned( false );
	}

	public override void Refresh()
	{
		base.Refresh();

		ElapsedTime = 0f;
	}
}