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.
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;
}
}