A unique curse perk class that hurts the player when they quickly reverse movement direction. It tracks recent movement, checks dot product against previous movement, and applies self-damage plus a visual highlight and icon effects.
using System;
using Sandbox;
[Perk( Rarity.Unique, curse: true, alwaysOfferDebug: false, IncludedCategories = new[] { PerkCategory.SelfDmg })]
public class CurseHurtChangeDirection : Perk
{
private enum Mod { HpLoss };
private TimeSince _timeSinceHurt;
private Vector2 _movementVector;
static CurseHurtChangeDirection()
{
Register<CurseHurtChangeDirection>(
name: "Shin Splints",
imagePath: "textures/icons/vector/curse_hurt_change_direction.png",
description: level => $"-{(int)GetValue( level, Mod.HpLoss )} hp when quickly moving\nin the opposite direction"
);
}
public override void Start()
{
base.Start();
ShouldUpdate = true;
HighlightColor = new Color( 1f, 0.2f, 0.3f );
HighlightDuration = 0.55f;
HighlightOpacity = 6f;
}
public override void Refresh()
{
base.Refresh();
}
public override void Update( float dt )
{
base.Update( dt );
if ( _movementVector.Length > 0.05f && Player.MoveInputPercent > 0f && _timeSinceHurt > 0.4f )
{
var dot = Vector2.Dot( _movementVector.Normal, Player.MoveVector );
if( dot < -0.7f )
{
Player.Damage( GetValue( Level, Mod.HpLoss ), DamageType.Self, Player.Position2D, _movementVector, upwardAmount: 0f, ragdollForce: 1f, force: 0f, enemySource: null, enemyType: EnemyType.None );
Highlight();
IconScale = Game.Random.Float( 1.1f, 1.2f );
IconAngleOffset = Game.Random.Float( 8f, 15f ) * (Game.Random.Int( 0, 1 ) == 0 ? -1f : 1f);
_timeSinceHurt = 0f;
}
}
_movementVector = Vector2.Lerp( _movementVector, Player.MoveVector, dt * 25f );
}
private static float GetValue( int level, Mod mod, bool isPercent = false )
{
switch ( mod )
{
case Mod.HpLoss:
default:
return 7;
//switch( level )
//{
// case 1: default: return 4;
// case 2: return 8;
// case 3: return 16;
// case 4: return 30;
//}
}
}
}