An Epic rarity perk class named Scar Tissue that grants extra perk choice(s) after the player takes a certain number of hits. It counts hits, converts every N hits (dependent on level) into an available extra choice until the player picks a perk, updates display icon/cooldown and applies/removes a numerical modifier to the player's NumChoicesHurt stat.
using System;
using Sandbox;
[Perk( Rarity.Epic, locked: true, minUnlocksReq: 2, alwaysOfferDebug: false )]
public class PerkNumChoicesHurt : Perk
{
private enum Mod { ReqHits };
private int _hits;
private int _numChoices;
static PerkNumChoicesHurt()
{
Register<PerkNumChoicesHurt>(
name: "Scar Tissue",
imagePath: "textures/icons/vector/num_choices_hurt.png",
description: level => $"Every {(int)GetValue( level, Mod.ReqHits )} times you take dmg,\nsee +1 perk choice (until you choose)",
upgradeDescription: level => $"Every {(int)GetValue( level - 1, Mod.ReqHits )}→{(int)GetValue( level, Mod.ReqHits )} times you take dmg,\nsee +1 perk choice (until you choose)"
);
}
public override void Start()
{
base.Start();
DisplayCooldownColor = new Color( 0.5f, 0.75f, 1f, 0.5f );
}
public override void Refresh()
{
base.Refresh();
CheckHits();
RefreshIcon();
}
void CheckHits()
{
var hitsReq = (int)GetValue( Level, Mod.ReqHits );
if ( _hits >= hitsReq )
{
_hits -= hitsReq;
_numChoices++;
Player.Modify( this, PlayerStat.NumChoicesHurt, _numChoices, ModifierType.Add );
HighlightColor = new Color( 0.5f, 0.5f, 1f );
HighlightDuration = 0.5f;
HighlightOpacity = 4f;
Highlight();
// todo: sfx
}
}
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 );
_hits++;
CheckHits();
RefreshIcon();
}
void RefreshIcon()
{
DisplayText = _numChoices > 0 ? $"+{_numChoices}" : "";
DisplayCooldown = Utils.Map( _hits, 0f, GetValue( Level, Mod.ReqHits ), 0f, 1f );
}
public override void OnChoosePerk( TypeDescription type )
{
base.OnChoosePerk( type );
_numChoices = 0;
Player.StopModifying( this, PlayerStat.NumChoicesHurt );
HighlightColor = new Color( 1f, 0.5f, 0.5f );
HighlightDuration = 0.75f;
HighlightOpacity = 4f;
Highlight();
RefreshIcon();
}
private static float GetValue( int level, Mod mod, bool isPercent = false )
{
switch ( mod )
{
case Mod.ReqHits:
default:
return 16 - level * 2;
}
}
}