Perk class that triggers when the player is at full health. It costs the player 50% of max HP, spawns a visual ring, and deals configurable area damage and repulsion to nearby enemies based on perk level and player stats.
using System;
using Sandbox;
using Sandbox.UI;
[Perk( Rarity.Mythic, locked: true, minUnlocksReq: 1, alwaysOfferDebug: false, IncludedCategories = new[] { PerkCategory.Aoe, PerkCategory.SelfDmg })]
public class PerkFullHealthAoe : Perk
{
private const float DAMAGE_RADIUS = 165f;
private enum Mod { DamageAmount };
static PerkFullHealthAoe()
{
Register<PerkFullHealthAoe>(
name: "Perfect Fury",
imagePath: "textures/icons/vector/full_hp_aoe.png",
description: level => $"When at full hp, get -50% hp and do {(int)GetValue( level, Mod.DamageAmount )} dmg to nearby enemies",
upgradeDescription: level => $"When at full hp, get -50% hp and do {(int)GetValue( level - 1, Mod.DamageAmount, true )}→{(int)GetValue( level, Mod.DamageAmount )} dmg to nearby enemies"
);
}
public override void Start()
{
base.Start();
ShouldUpdate = true;
HighlightColor = new Color( 0.8f, 0f, 1f );
HighlightDuration = 0.4f;
HighlightOpacity = 4.5f;
}
public override void Refresh()
{
base.Refresh();
}
private static float GetValue( int level, Mod mod, bool isPercent = false )
{
switch ( mod )
{
case Mod.DamageAmount:
default:
return 10f + 20f * level;
}
}
public override void Update( float dt )
{
base.Update( dt );
if ( !(Player.Health < Player.Stats[PlayerStat.MaxHp]) )
{
Player.Damage( Player.Stats[PlayerStat.MaxHp] * 0.5f, DamageType.Self, hitPos: Player.Position2D, Utils.GetRandomVector(), upwardAmount: 0f, force: 0f, ragdollForce: 1f, enemySource: null, enemyType: EnemyType.None );
Vector2 pos = Player.Position2D;
float dmg = GetValue( Level, Mod.DamageAmount );
float radius = DAMAGE_RADIUS * Player.Stats[PlayerStat.RadiusMultiplier];
var force = dmg * 10f;
// todo: better sfx
// todo: prevent explosion from playing so many death sfx
// todo better vfx
Manager.Instance.SpawnRingRpc( pos, radius, new Color( 1f, 0.7f, 1f, 0.2f ), lifetime: Game.Random.Float( 0.15f, 0.2f ), path: "ring_spiky_2_b" );
//Manager.Instance.DamageInRadiusHost( pos, radius, dmg, radius * 1.1f, force, Player, DamageType.Aoe, damagePlayers: false );
Manager.Instance.AffectInRadiusHost( Player.Position2D, radius * 1.1f, dmg, repelRadius: radius * 1.2f, force, Player, enemySource: null, enemyType: EnemyType.None, DamageType.Aoe, options: RepelOptions.DamageEnemies | RepelOptions.RepelEnemies | RepelOptions.RepelItems );
Highlight();
}
}
}