things/enemies/ZombieTemporary.cs

Enemy subclass for a temporary zombie variant. It sets type, stats, coin drops, movement and lifetime, spawns with randomized appearance and automatically dies after a short random lifetime.

Networking
using System;
using Sandbox;

public class ZombieTemporary : Zombie
{
	public override EnemyType EnemyType => EnemyType.ZombieTemporary;
	public override string GibFolder => Manager.GetStringForEnemyType( EnemyType.Zombie );
	public override EnemyType KillStatEnemyType => EnemyType.Zombie;

	public override float GetMaxHealth()
	{
		switch ( Manager.Instance.Difficulty )
		{
			case 0: default: return 32f;
			case 1: return 37f;
			case 2: return 40f;
		}
	}

	public override Vector3 SpawnScale => new Vector3( 1f );

	private float _lifetime;

	public override float SpawnTime => 0.75f;

	protected override void OnStart()
	{
		base.OnStart();

		CoinValueMin = 1;
		CoinValueMax = 2;
		CoinChance = 0.25f;

		PushStrength = 5000f;

		_personalSpeedScale = Game.Random.Float( 0.85f, 1.25f );
		_personalSpeedFreq = Game.Random.Float( 6f, 12f );
		_fullMeleeAttackAnimSpeed = 2.5f;

		// todo: make networked?
		ModelRenderer.SetBodyGroup( 0, Game.Random.Int( 0, 4 ) );

		if ( IsProxy )
			return;

		AggroRange = 100f;
		DetectTargetRange = 350f;
		LoseTargetRange = 900f;
		LoseTargetTime = 3f;
		MeleeDamage = Utils.Select( Manager.Instance.Difficulty, 5f, 6f, 7f );
		DamageTargetDelay = 0.5f;
		//_personalTurnSpeed = Game.Random.Float( 1.5f, 4f );
		_personalTurnSpeed = Game.Random.Float( 3.5f, 5f );
		//Acceleration = 110f;
		//AccelerationAttacking = 130f;
		Acceleration = 450f;
		AccelerationAttacking = 650f;
		Deceleration = 1.85f;
		DecelerationAttacking = 1.55f;

		_lifetime = Game.Random.Float( 4f, 8f );
	}

	protected override void OnUpdate()
	{
		base.OnUpdate();

		if ( IsProxy || IsDying || Manager.Instance.IsGameOver )
			return;

		// todo: flash and change tint based on lifetime left

		if ( TimeSinceSpawn > _lifetime )
		{
			Die( dir: Utils.GetRandomVector(), force: 0f, player: null, DamageType.Self );
		}
	}
}