things/enemies/ChargerSpecial.cs
using Sandbox;
using Sandbox.ModelEditor.Nodes;
using System.Net.NetworkInformation;

public class ChargerSpecial : Charger
{
	private TimeSince _timeSinceHitWall;

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

		Health = 320f;
		MaxHealth = Health;

		Radius = 0.5f;
		Scale = 2.3125f;
		Sprite.LocalScale = new Vector3( Scale * Game.Random.Float( 1f - HeightVariance, 1f + HeightVariance ), Scale * Game.Random.Float( 1f - WidthVariance, 1f + WidthVariance ), 1f ) * Globals.SPRITE_SCALE;

		ShadowScale = 2.375f;
		ShadowSpriteDirty = true;

		CHARGE_TIME_MIN = 50f;
		CHARGE_TIME_MAX = 60f;

		_chargeDelayTimer = Game.Random.Float( 1f, 3f );

		PushStrength = 45f;
		ChargeRange = 8.5f;

		REDIRECT_DELAY_MIN = 5f;
		REDIRECT_DELAY_MAX = 20f;

		DamageToPlayer = 12f;

		CoinChance = 1f;
		CoinValueMin = 5;
		CoinValueMax = 10;
	}

	protected override void HandleCharging( float dt )
	{
		float chargeSpeed = 5f;
		_chargeVel = _chargeDir * chargeSpeed * Utils.Map( Math.Min(_chargeTimer, _timeSinceHitWall), 0f, 0.75f, 0f, 1f );

		float BUFFER = 0.01f;
		var x_min = Manager.Instance.BOUNDS_MIN.x + Radius + BUFFER;
		var x_max = Manager.Instance.BOUNDS_MAX.x - Radius - BUFFER;
		var y_min = Manager.Instance.BOUNDS_MIN.y + BUFFER;
		var y_max = Manager.Instance.BOUNDS_MAX.y - Radius - BUFFER;

		if ( !Target.IsValid() )
			return;

		if ( Position2D.x < x_min && _chargeDir.x < 0f )
		{
			ChangeDir();
			//_chargeDir = _chargeDir.WithX( Math.Abs( _chargeDir.x ) );
			//_chargeVel = _chargeVel.WithX( Math.Abs( _chargeVel.x ) * 0.1f );
			FlipX = _chargeDir.x > 0f;
			Sprite.SpriteFlags = SpriteFlags.HorizontalFlip;
			_timeSinceHitWall = 0f;
		}
		else if ( Position2D.x > x_max && _chargeDir.x > 0f )
		{
			ChangeDir();
			//_chargeDir = _chargeDir.WithX( -Math.Abs( _chargeDir.x ) );
			//_chargeVel = _chargeVel.WithX( -Math.Abs( _chargeVel.x ) * 0.1f );
			FlipX = _chargeDir.x > 0f;
			Sprite.SpriteFlags = SpriteFlags.None;
			_timeSinceHitWall = 0f;
		}

		if ( Position2D.y < y_min && _chargeDir.y < 0f )
		{
			ChangeDir();
			//_chargeDir = _chargeDir.WithY( Math.Abs( _chargeDir.y ) );
			//_chargeVel = _chargeDir.WithY( Math.Abs( _chargeVel.y ) * 0.1f );
			_timeSinceHitWall = 0f;
			FlipX = _chargeDir.x > 0f;
		}
		else if ( Position2D.y > y_max && _chargeDir.y > 0f )
		{
			ChangeDir();
			//_chargeDir = _chargeDir.WithY( -Math.Abs( _chargeDir.y ) );
			//_chargeVel = _chargeDir.WithY( -Math.Abs( _chargeVel.y ) * 0.1f );
			_timeSinceHitWall = 0f;
			FlipX = _chargeDir.x > 0f;
		}
	}

	void ChangeDir()
	{
		_chargeDir = IsFeared
			? (new Vector2(Game.Random.Float(-3f, 3f), Game.Random.Float( -3f, 3f ) ) - Position2D).Normal
			: ((Target.Position2D + Target.Velocity * Game.Random.Float( -0.5f, 4f )) - Position2D).Normal;
	}
}