perks/PerkHealOnKill.cs

A perk component named PerkHealOnKill that grants the player health when they kill enemies and applies a periodic health drain modifier. It tracks accumulated kills and heals the player by a scaled amount, and applies stat modifiers on Refresh.

Networking
using System;
using Sandbox;

[Perk( Rarity.Rare, disabled: true, alwaysOfferDebug: false, IncludedCategories = new[] { PerkCategory.SelfDmg })]
public class PerkHealOnKill : Perk
{
	private enum Mod { KillRegenAmount, DrainAmount };

	private const float DRAIN_DELAY = 3f;

	private int _numAccumKills;


	static PerkHealOnKill()
	{
		//Register<PerkHealOnKill>(
		//	name: "Vampire Fangs",
		//	imagePath: "textures/icons/vector/heal_on_kill.png",
		//	description: level => $"+{GetValue( level, Mod.KillRegenAmount ).ToString("0.##")} hp on kill\n-{GetValue( level, Mod.DrainAmount ).ToString( "0.#" )} hp every {DRAIN_DELAY}s",
		//	upgradeDescription: level => $"+{GetValue( level - 1, Mod.KillRegenAmount ).ToString("0.##")}→{GetValue(level, Mod.KillRegenAmount).ToString("0.##")} hp on kill\n-{GetValue( level - 1, Mod.DrainAmount ).ToString( "0.#" )}→-{GetValue( level, Mod.DrainAmount ).ToString( "0.#" )} hp every {DRAIN_DELAY}s"
		//);
	}

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

	}

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

		Player.Modify( this, PlayerStat.HealthDrain, -GetValue( Level, Mod.DrainAmount ), ModifierType.Add );
		Player.Modify( this, PlayerStat.HpRegenPerKillDisplay, GetValue( Level, Mod.KillRegenAmount ), ModifierType.Add );
	}

	private static float GetValue( int level, Mod mod, bool isPercent = false )
	{
		switch ( mod )
		{
			case Mod.KillRegenAmount:
			default:
				return 0.15f + 0.25f * level;
			case Mod.DrainAmount:
				return 0.1f + 0.3f * level;
		}
	}

	public override void OnKill( Enemy enemy, DamageType damageType, bool countsAsKill )
	{
		base.OnKill( enemy, damageType, countsAsKill );
		if ( !countsAsKill ) return;

		_numAccumKills++;

		if ( _numAccumKills > 0 )
		{
			Player.Heal( GetValue( Level, Mod.KillRegenAmount ) * _numAccumKills );

			_numAccumKills = 0;
		}
	}
}