Perk component that grants the player a health pack when they accumulate enough self-inflicted damage. It tracks accumulated self-damage, shows UI cooldown/text, gives a health_pack item and triggers a highlight when thresholds are reached. Values scale by perk level.
using System;
using Sandbox;
[Perk( Rarity.Epic, includedAtStart: false, locked: true, alwaysOfferDebug: false )]
public class PerkSelfDmgHealthPack : Perk
{
private enum Mod { DmgReq };
private float _dmgAccum;
static PerkSelfDmgHealthPack()
{
Register<PerkSelfDmgHealthPack>(
name: "Tasty Scabs",
imagePath: "textures/icons/vector/self_dmg_healthpack.png",
description: level => $"+1 healthpack for every [+]{(int)GetValue( level, Mod.DmgReq )}[/+] self dmg taken",
upgradeDescription: level => $"+1 healthpack for every\n{(int)GetValue( level - 1, Mod.DmgReq )}→{(int)GetValue( level, Mod.DmgReq )} self dmg taken"
);
}
public override void Start()
{
base.Start();
DisplayCooldownColor = new Color( 0.3f, 0.7f, 0.3f, 0.75f );
HighlightColor = new Color( 0f, 1f, 0.7f );
HighlightDuration = 0.66f;
HighlightOpacity = 4f;
}
public override void Refresh()
{
base.Refresh();
if ( _dmgAccum > GetValue( Level, Mod.DmgReq ) )
{
Player.GiveItemRpc( "health_pack", Utils.GetRandomVectorInCone( -Player.FacingDir ) );
_dmgAccum -= GetValue( Level, Mod.DmgReq );
Highlight();
}
DisplayText = $"{MathX.CeilToInt( GetValue( Level, Mod.DmgReq ) - _dmgAccum )}";
DisplayCooldown = Utils.Map( _dmgAccum, 0f, GetValue( Level, Mod.DmgReq ), 0f, 1f );
}
private static float GetValue( int level, Mod mod, bool isPercent = false )
{
switch ( mod )
{
case Mod.DmgReq:
default:
return 115f - 15f * level;
}
}
public override void OnHit( float amount, DamageType damageType, bool isSelfInflicted, Vector2 dir, float force, Enemy enemySource, EnemyType enemyType, float previousHealth )
{
base.OnHit( amount, damageType, isSelfInflicted, dir, force, enemySource, enemyType, previousHealth );
if ( damageType != DamageType.Self )
return;
_dmgAccum += amount;
if ( _dmgAccum > GetValue( Level, Mod.DmgReq ) )
{
Player.GiveItemRpc( "health_pack", Utils.GetRandomVectorInCone( -Player.FacingDir ) );
_dmgAccum -= GetValue( Level, Mod.DmgReq );
}
DisplayText = $"{MathX.CeilToInt( GetValue( Level, Mod.DmgReq ) - _dmgAccum )}";
DisplayCooldown = 1f - Utils.Map( _dmgAccum, 0f, GetValue( Level, Mod.DmgReq ), 1f, 0f );
}
}