A unique curse perk that reverses player move and aim controls when they pick up a healthpack. It applies modifiers on healthpack pickup, shows UI text/cooldown while active, toggles an overlay effect, and clears the modifiers when the reverse time elapses or on death/remove.
using System;
using Sandbox;
[Perk( Rarity.Unique, curse: true, alwaysOfferDebug: false )]
public class CurseHealthPackReverseControls : Perk
{
private enum Mod { ReverseTime };
private TimeSince _timeSince;
static CurseHealthPackReverseControls()
{
Register<CurseHealthPackReverseControls>(
name: "Wacky Packs",
imagePath: "textures/icons/vector/curse_health_pack_reverse_controls.png",
description: level => $"Healthpacks reverses your controls for [-]{GetValue( level, Mod.ReverseTime )}s[/-]"
);
}
public override void Start()
{
base.Start();
}
public override void Refresh()
{
base.Refresh();
}
public override void Update( float dt )
{
base.Update( dt );
var reverseTime = GetValue( Level, Mod.ReverseTime );
if ( _timeSince > reverseTime )
{
Player.StopModifying( this, PlayerStat.ReverseMoveControls );
Player.StopModifying( this, PlayerStat.ReverseAimControls );
ShouldUpdate = false;
DisplayText = " ";
DisplayCooldown = 0f;
Manager.Instance.PlaySfxNearby( "player.dash", Player.Position2D, pitch: Game.Random.Float( 2.1f, 2.2f ), volume: 0.5f, maxDist: 200f );
HighlightColor = new Color( 0.2f, 0.4f, 0.7f );
HighlightDuration = 0.35f;
HighlightOpacity = 3f;
Highlight();
IconScale = Game.Random.Float( 1.1f, 1.15f );
IconAngleOffset = Game.Random.Float( 5f, 8f ) * (Game.Random.Int( 0, 1 ) == 0 ? -1f : 1f);
Manager.Instance.OverlayEffects[OverlayEffectsType.HealthPackReverseControls].Enabled = false;
}
else
{
DisplayText = $"{MathX.CeilToInt( reverseTime - _timeSince )}";
DisplayCooldown = Utils.Map( _timeSince, 0f, reverseTime, 1f, 0f );
}
}
private static float GetValue( int level, Mod mod, bool isPercent = false )
{
switch ( mod )
{
case Mod.ReverseTime:
default:
return 10f;
//switch(level)
//{
// case 1: default: return 2f;
// case 2: return 10f;
// case 3: return 30f;
//}
}
}
public override void OnGainHealthpack( float amount )
{
base.OnGainHealthpack( amount );
Player.Modify( this, PlayerStat.ReverseMoveControls, 1f, ModifierType.Add );
Player.Modify( this, PlayerStat.ReverseAimControls, 1f, ModifierType.Add );
ShouldUpdate = true;
_timeSince = 0f;
HighlightColor = new Color( 0.7f, 0.4f, 0.2f );
HighlightDuration = 0.35f;
HighlightOpacity = 3f;
Highlight();
IconScale = Game.Random.Float( 1.2f, 1.3f );
IconAngleOffset = Game.Random.Float( 10f, 20f ) * (Game.Random.Int( 0, 1 ) == 0 ? -1f : 1f);
Manager.Instance.PlaySfxNearby( "player.dash", Player.Position2D, pitch: Game.Random.Float( 2.1f, 2.2f ), volume: 0.5f, maxDist: 200f );
DisplayText = $"{MathX.CeilToInt( GetValue( Level, Mod.ReverseTime ) )}";
DisplayCooldown = 1f;
Manager.Instance.OverlayEffects[OverlayEffectsType.HealthPackReverseControls].Enabled = true;
}
public override void OnDie()
{
base.OnDie();
Manager.Instance.OverlayEffects[OverlayEffectsType.HealthPackReverseControls].Enabled = false;
}
public override void Remove( bool restart = false )
{
base.Remove( restart );
Manager.Instance.OverlayEffects[OverlayEffectsType.HealthPackReverseControls].Enabled = false;
}
}