perks/PerkFocusFire.cs

A game perk class named PerkFocusFire. It tracks hitting the same enemy to grant stacking attack and reload speed multipliers, updates UI display text and cooldown fill, and highlights when switching targets.

Obfuscated Code
using System;
using Sandbox;

[Perk( Rarity.Epic, locked: true, alwaysOfferDebug: false )]
public class PerkFocusFire : Perk
{
	private enum Mod { Speed, MaxStacks };

	private Enemy _currHitEnemy;
	private int _hitCounter;

	static PerkFocusFire()
	{
		Register<PerkFocusFire>(
			name: "Focus Fire",
			imagePath: "textures/icons/vector/focus_fire.png",
			description: level => $"+{GetValue( level, Mod.Speed, isPercent: true )}% attack/reload speed when you hit the same enemy again (max: +{GetValue( level, Mod.MaxStacks ) * GetValue( level, Mod.Speed, isPercent: true )}%)",
			//upgradeDescription: level => $"+{GetValue( level - 1, Mod.Speed, isPercent: true )}%→{GetValue( level, Mod.Speed, isPercent: true )}% attack/reload speed when you hit the same enemy again\n(max: +{GetValue( level - 1, Mod.MaxStacks ) * GetValue( level - 1, Mod.Speed, isPercent: true )}%→{GetValue( level, Mod.MaxStacks ) * GetValue( level, Mod.Speed, isPercent: true )}%)"
			upgradeDescription: level => $"+{GetValue( level, Mod.Speed, isPercent: true )}% attack/reload speed when you hit the same enemy again\n(max: +{GetValue( level - 1, Mod.MaxStacks ) * GetValue( level - 1, Mod.Speed, isPercent: true )}%→{GetValue( level, Mod.MaxStacks ) * GetValue( level, Mod.Speed, isPercent: true )}%)"
		);
	}

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

		HighlightColor = new Color( 1f, 0.5f, 0.5f );
		HighlightDuration = 0.2f;
		HighlightOpacity = 1.5f;
	}

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

		DisplayCooldownColor = new Color( 0f, 0.7f, 1f, 3f );
	}

	public override void OnDamageEnemy( Enemy enemy, float amount, DamageType damageType, Vector2 dir, bool isCrit )
	{
		base.OnDamageEnemy( enemy, amount, damageType, dir, isCrit );

		if ( damageType != DamageType.Bullet && damageType != DamageType.Punch )
			return;

		if ( enemy == _currHitEnemy )
		{
			_hitCounter++;
		}
		else
		{
			_currHitEnemy = enemy;
			_hitCounter = 0;

			Highlight();
		}

		RefreshBuffs();
	}

	void RefreshBuffs()
	{
		int maxStacks = (int)GetValue( Level, Mod.MaxStacks );
		int currStacks = Math.Min( _hitCounter, maxStacks );
		float speed = 1f + currStacks * GetValue( Level, Mod.Speed );

		Player.Modify( this, PlayerStat.AttackSpeed, speed, ModifierType.Mult );
		Player.Modify( this, PlayerStat.ReloadSpeed, speed, ModifierType.Mult );

		DisplayText = currStacks > 0 ? $"{currStacks * GetValue( Level, Mod.Speed, isPercent: true )}%" : " ";
		DisplayCooldown = Utils.Map( currStacks, 0f, maxStacks, 0f, 1f );
	}

	private static float GetValue( int level, Mod mod, bool isPercent = false )
	{
		switch ( mod )
		{
			case Mod.Speed:
			default:
				//return isPercent
				//	? 2f + 1f * level
				//	: 0.02f + 0.01f * level;
				return isPercent
					? 2f
					: 0.02f;
			case Mod.MaxStacks:
				return 5 + 5 * level;
		}
	}
}