enemyStatus/BurningEnemyStatus.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Sandbox;
public class BurningEnemyStatus : EnemyStatus
{
private TimeSince _sinceDamageTime;
private const float DAMAGE_INTERVAL = 0.42f;
public float Lifetime { get; set; }
public float SpreadChance { get; set; }
public Player Player { get; set; }
public float Damage { get; set; }
private TimeSince _damageOtherTime;
public static float BURN_REAPPLY_COOLDOWN = 0.5f;
public int NumStacks { get; set; }
public BurningEnemyStatus()
{
}
public override void Init( Enemy enemy )
{
base.Init( enemy );
Enemy.CreateBurningVfx();
}
public void AddStack( float damage, float lifetime, float spreadChance )
{
var maxStacks = (int)Player.Stats[PlayerStat.MaxFireStacks];
if ( NumStacks >= maxStacks )
{
//Refresh();
}
else
{
Manager.Instance.PlaySfxNearby( "burn", Enemy.Position2D, pitch: Utils.Map(NumStacks, 0, 7, 1.35f, 1.65f), volume: 0.5f, maxDist: 3f );
NumStacks = Math.Min( NumStacks + 1, maxStacks );
if ( Enemy.BurningVfx.IsValid() )
Enemy.BurningVfx.SetStacks( NumStacks );
}
Damage = damage;
Lifetime = lifetime;
SpreadChance = spreadChance;
//Log.Info( $"NumStacks: {NumStacks} maxStacks: {maxStacks}" );
}
public override void Update( float dt )
{
if ( Enemy == null || !Enemy.IsValid() )
return;
//Gizmo.Draw.Color = Color.White;
//Gizmo.Draw.Text( $"{NumStacks}\n{ElapsedTime}", new global::Transform( (Vector3)Enemy.Position2D + new Vector3( 0f, -0.5f, 0f ) ) );
if ( ElapsedTime > Lifetime )
{
if(NumStacks > 0)
{
NumStacks--;
if ( Enemy.BurningVfx.IsValid() )
Enemy.BurningVfx.SetStacks( NumStacks );
ElapsedTime = 0f;
}
else
{
Enemy.RemoveEnemyStatus( this );
return;
}
}
if ( _sinceDamageTime > DAMAGE_INTERVAL )
{
Enemy.DamageFire( Damage * (NumStacks + 1), Player );
_sinceDamageTime = 0f;
}
}
public override void Remove()
{
Enemy.RemoveBurningVfx();
}
public override void Refresh()
{
ElapsedTime = 0f;
}
public override void Colliding( Thing other, float percent, float dt )
{
bool didDamage = false;
if ( other is Enemy enemy && !enemy.IsDying && !enemy.HasEnemyStatus( this ) )
{
if ( _damageOtherTime > DAMAGE_INTERVAL )
{
// should stack damage apply to nearby enemies?
enemy.DamageFire( Damage, Player );
if ( Game.Random.Float( 0f, 1f ) < SpreadChance )
{
var burning = enemy.GetEnemyStatus<BurningEnemyStatus>();
if ( burning != null )
{
burning.AddStack( Damage, Lifetime, SpreadChance );
}
else
{
enemy.Burn( Player, Damage, Lifetime, SpreadChance );
Manager.Instance.PlaySfxNearby( "burn", enemy.Position2D, pitch: Sandbox.Game.Random.Float( 1.15f, 1.35f ), volume: 0.7f, maxDist: 4f );
}
enemy.TimeSinceBurn = 0f;
}
didDamage = true;
}
}
else if ( other is Player player && !player.IsDead )
{
if ( _damageOtherTime > DAMAGE_INTERVAL )
{
// should stack damage apply to nearby player?
player.Damage( Damage );
Manager.Instance.PlaySfxNearby( "burn", player.Position2D, pitch: Game.Random.Float( 1.15f, 1.35f ), volume: 0.6f, maxDist: 4f );
didDamage = true;
}
}
if ( didDamage )
_damageOtherTime = 0f;
}
}