perks/PerkOnly1HpBulletHoming.cs

A legendary perk component that increases bullet homing radius while the player is at 1 HP. It toggles modifiers on the player when health drops to or above 1 HP, updates display values, and exposes level-based radius scaling.

Networking
using System;
using Sandbox;

[Perk( Rarity.Legendary, includedAtStart: false, locked: true, minUnlocksReq: 1, alwaysOfferDebug: false )]
public class PerkOnly1HpBulletHoming : Perk
{
	private enum Mod { Radius };

	private bool _isActive;

	static PerkOnly1HpBulletHoming()
	{
		Register<PerkOnly1HpBulletHoming>(
			name: "Heightened Awareness",
			imagePath: "textures/icons/vector/only_1hp_bullet_homing.png",
			description: level => $"+{GetValue( level, Mod.Radius, true ).ToString( "0.##" )}m bullet homing range\nwhile at 1 hp",
			upgradeDescription: level => $"+{GetValue( level - 1, Mod.Radius, true ).ToString( "0.##" )}→{GetValue( level, Mod.Radius, true ).ToString( "0.##" )}m bullet homing range\nwhile at 1 hp"
		);
	}

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

		ShouldUpdate = true;
		DisplayCooldownColor = new Color( 0.3f, 0.3f, 1f, 0.25f );
	}

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

		if ( !(Player.Health > 1f) )
			Enable();
	}

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

		if( _isActive )
		{
			if ( Player.Health > 1f )
				Disable();
		}
		else
		{
			if ( !(Player.Health > 1f) )
				Enable();
		}
	}

	void Enable()
	{
		Player.Modify( this, PlayerStat.BulletHomingRadius, GetValue( Level, Mod.Radius ), ModifierType.Add );
		Player.Modify( this, PlayerStat.BulletHomingRadiusDisplay, GetValue( Level, Mod.Radius, true ), ModifierType.Add );
		_isActive = true;
		DisplayCooldown = 1f;
		DisplayText = $"✅";
	}

	void Disable()
	{
		Player.StopModifying( this, PlayerStat.BulletHomingRadius );
		Player.StopModifying( this, PlayerStat.BulletHomingRadiusDisplay );
		_isActive = false;
		DisplayCooldown = 0f;
		DisplayText = " ";
	}

	private static float GetValue( int level, Mod mod, bool isPercent = false )
	{
		switch ( mod )
		{
			case Mod.Radius:
			default:
				return 0.70f * level * (isPercent ? 1f : Utils.Meter2Unit);
		}
	}
}