A Perk class for the game named PerkStillDamageReduction, called "Iron Stance". It reduces damage taken while the player is not moving, updates UI display values and visuals, and applies a stat modifier for still-damage reduction.
using System;
using System.Reflection.Emit;
using Sandbox;
using Sandbox.UI;
[Perk( Rarity.Epic, locked: true, alwaysOfferDebug: false )]
public class PerkStillDamageReduction : Perk
{
private enum Mod { Percent };
static PerkStillDamageReduction()
{
Register<PerkStillDamageReduction>(
name: "Iron Stance",
imagePath: "textures/icons/vector/still_damage_reduction.png",
description: level => $"[+]-{(int)GetValue( level, Mod.Percent, true )}%[/+] dmg taken while not moving",
upgradeDescription: level => $"[+]-{(int)GetValue( level - 1, Mod.Percent, true )}%→-{(int)GetValue( level, Mod.Percent, true )}%[/+] dmg taken\nwhile not moving"
);
}
public override void Start()
{
base.Start();
HighlightColor = new Color( 0.9f, 0.95f, 1f );
HighlightDuration = 0.25f;
HighlightOpacity = 1.5f;
ShouldUpdate = true;
DisplayCooldownColor = new Color( 0.5f, 0.6f, 0.8f, 1f );
}
public override void Refresh()
{
base.Refresh();
Player.Modify( this, PlayerStat.StillDamageReductionPercent, GetValue( Level, Mod.Percent ), ModifierType.Add );
}
public override void Update( float dt )
{
base.Update( dt );
DisplayText = Player.IsMoving ? " " : $"-{(int)GetValue( Level, Mod.Percent, true )}%";
DisplayCooldown = Player.IsMoving ? 0f : 1f;
if ( IconScale > 0.975f )
IconScale = 1f + (Utils.FastSin( RealTime.Now * 18f ) * 0.025f) * (Player.IsMoving ? 0f : 1f);
}
private static float GetValue( int level, Mod mod, bool isPercent = false )
{
switch ( mod )
{
case Mod.Percent:
default:
return isPercent
? 6f + 6f * level
: 0.06f + 0.06f * 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 ( Player.IsMoving )
return;
Highlight();
IconScale = Game.Random.Float( 0.75f, 0.8f);
IconAngleOffset = Game.Random.Float( 2f, 5f ) * (Game.Random.Int( 0, 1 ) == 0 ? -1f : 1f);
}
}