perks/PerkBulletArcStill.cs

Perk class that modifies player stats when equipped. It enables an "arc while still" bullet behavior, increases arc height, adds damage per level and adjusts arc bullet speed, and updates icon visuals when the player is not moving.

Networking
using System;
using Sandbox;

[Perk( Rarity.Mythic, locked: true, minUnlocksReq: 1, alwaysOfferDebug: false, IncludedCategories = new[] { PerkCategory.ArcBullets })]
public class PerkBulletArcStill : Perk
{
	private enum Mod { ArcBulletDamageAdd, ArcBulletSpeedMult };


	static PerkBulletArcStill()
	{
		Register<PerkBulletArcStill>(
			name: "Lob Shots",
			imagePath: "textures/icons/vector/bullet_lob.png",
			description: level => $"While not moving, lob your bullet-icon\nwith +{GetValue( level, Mod.ArcBulletDamageAdd ).ToString( "0.#" )} bullet-icon dmg",
			upgradeDescription: level => $"While not moving, lob your bullet-icon\nwith +{GetValue( level - 1, Mod.ArcBulletDamageAdd ).ToString( "0.#" )}→{GetValue( level, Mod.ArcBulletDamageAdd ).ToString( "0.#" )} bullet-icon dmg"
		);
	}

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

		ShouldUpdate = true;
		DisplayCooldownColor = new Color( 0.75f, 0.2f, 0.9f, 0.8f );
	}

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

		Player.Modify( this, PlayerStat.ArcBulletsStill, 1f, ModifierType.Add );
		Player.Modify( this, PlayerStat.BulletArcHeight, 160f, ModifierType.Add );
		
		// todo: need to update damage/speed stats on stats screen?
		Player.Modify( this, PlayerStat.ArcBulletDamageAdd, GetValue( Level, Mod.ArcBulletDamageAdd ), ModifierType.Add );
		Player.Modify( this, PlayerStat.ArcBulletSpeedMult, GetValue( Level, Mod.ArcBulletSpeedMult ), ModifierType.Mult );
	}

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

		IconScale = 1f + (Utils.FastSin( RealTime.Now * 15f ) * 0.025f) * (Player.IsMoving ? 0f : 1f);
		DisplayCooldown = Player.IsMoving ? 0f : 1f;
	}

	private static float GetValue( int level, Mod mod, bool isPercent = false )
	{
		switch ( mod )
		{
			case Mod.ArcBulletDamageAdd:
			default:
				return 1f * level;
			case Mod.ArcBulletSpeedMult:
				return isPercent
					? 25f
					: 1f - (0.25f);
		}
	}

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

		if ( Player.IsMoving )
			return;

		IconScale = Game.Random.Float( 1.05f, 1.1f );
		IconAngleOffset = Game.Random.Float( 9f, 12f ) * (Game.Random.Int( 0, 1 ) == 0 ? -1f : 1f);
	}
}