status/ShieldCharmStatus.cs
using System;
using System.Collections.Generic;
using System.Linq;
using Sandbox;
[Status(5, 0, 1f, 0, false, typeof( ShieldStatus ) )]
public class ShieldCharmStatus : Status
{
public ShieldCharmStatus()
{
Title = "Charming Shield";
IconPath = "textures/icons/shield_charm.png";
}
public override void Init(Player player)
{
base.Init(player);
}
public override void Refresh()
{
Description = GetDescription(Level);
}
public override void OnGainShield()
{
base.OnGainShield();
List<Thing> nearbyThings = new List<Thing>();
for ( int dx = -2; dx <= 2; dx++ )
for ( int dy = -2; dy <= 2; dy++ )
Manager.Instance.AddThingsInGridSquare( new Manager.GridSquare( Player.GridPos.x + dx, Player.GridPos.y + dy ), nearbyThings );
float radius = GetRadiusForLevel(Level) * Player.Stats[PlayerStat.RadiusMultiplier];
bool didCharm = false;
foreach ( Thing thing in nearbyThings )
{
if ( thing is Enemy enemy && !enemy.IsDying && (!enemy.IsSpawning || enemy.TimeSinceSpawn > 0.75f) && !enemy.IgnoreCollision && !enemy.IsCharmed )
{
var dist_sqr = (enemy.Position2D - Player.Position2D).LengthSquared;
if ( dist_sqr < MathF.Pow( radius, 2f ) )
{
enemy.Velocity += (thing.Position2D - Player.Position2D).Normal * Game.Random.Float(1f, 2f);
enemy.Charm();
didCharm = true;
}
}
}
if(didCharm)
Manager.Instance.PlaySfxNearby( "charm", Player.Position2D, pitch: Game.Random.Float( 0.9f, 1.1f ), volume: 1.3f, maxDist: 5f );
var explosion = Manager.Instance.SpawnExplosionEffect( Player.Position2D, Color.Magenta, Color.Magenta, opacity: 0.2f, scaleModifier: 0.75f * radius );
explosion.Sprite.PlaybackSpeed = 3f;
explosion.Lifetime = 0.4f;
}
public override string GetDescription(int newLevel)
{
return string.Format("When you gain a shield, charm enemies within {0} meters", GetRadiusForLevel(Level).ToString("F1"));
}
public override string GetUpgradeDescription(int newLevel)
{
return newLevel > 1 ? string.Format( "When you gain a shield, charm enemies within {0}→{1} meters", GetRadiusForLevel( newLevel - 1).ToString( "F1" ), GetRadiusForLevel( newLevel).ToString( "F1" ) ) : GetDescription(newLevel);
}
public float GetRadiusForLevel(int level)
{
return 0.9f + 0.2f * level;
}
}