things/HealthPack.cs
using Sandbox;
using static Manager;
public class HealthPack : Thing
{
public TimeSince SpawnTime { get; private set; }
public float Lifetime { get; set; }
private TimeSince _timeSinceBlink;
protected override void OnAwake()
{
base.OnAwake();
//OffsetY = -0.16f;
Scale = 0.6f;
ShadowOpacity = 0.8f;
ShadowScale = 0.8f;
SpawnShadow( ShadowScale, ShadowOpacity );
Sprite.LocalScale = new Vector3( 1f ) * Scale * Globals.SPRITE_SCALE;
if ( IsProxy )
return;
//BasePivotY = 0.225f;
SpawnTime = 0f;
Lifetime = 60f;
if ( Manager.Instance.Difficulty < 0 )
Lifetime *= 1.5f;
Radius = 0.175f;
CollideWith.Add( typeof( Enemy ) );
CollideWith.Add( typeof( Player ) );
CollideWith.Add( typeof( HealthPack ) );
CollideWith.Add( typeof( RerollPickup ) );
}
protected override void OnUpdate()
{
base.OnUpdate();
//Gizmo.Draw.Color = Color.White;
//Gizmo.Draw.Text( $"Stats[BulletStat.Damage]: {Stats[BulletStat.Damage]}\nStats[BulletStat.Lifetime]: {Stats[BulletStat.Lifetime]}", new global::Transform( (Vector3)Position2D + new Vector3( 0f, -0.4f, 0f ) ) );
//Gizmo.Draw.Color = Color.White.WithAlpha( 0.05f );
//Gizmo.Draw.LineSphere( (Vector3)Position2D, Radius );
if ( !Manager.Instance.ShouldUpdateThings )
return;
Sprite.LocalScale = new Vector3( Scale + MathF.Cos( SpawnTime * 8f ) * 0.025f, Scale + Utils.FastSin( SpawnTime * 8f ) * 0.025f, 1f ) * Globals.SPRITE_SCALE;
ShadowScale = 0.8f + Utils.FastSin( SpawnTime * 8f ) * 0.035f;
ShadowSpriteDirty = true;
if ( IsProxy )
return;
float dt = Time.Delta;
Position2D += Velocity * dt;
Position2D = new Vector2( MathX.Clamp( Position2D.x, Manager.Instance.BOUNDS_MIN.x + Radius, Manager.Instance.BOUNDS_MAX.x - Radius ), MathX.Clamp( Position2D.y, Manager.Instance.BOUNDS_MIN.y + Radius, Manager.Instance.BOUNDS_MAX.y - Radius ) );
WorldPosition = WorldPosition.WithZ( Globals.GetZPos( Position2D.y ) );
Velocity *= (1f - dt * 3.5f);
if ( SpawnTime > Lifetime - 7f )
{
if ( _timeSinceBlink > Utils.Map( SpawnTime, Lifetime - 7f, Lifetime, 0.25f, 0.03f, EasingType.SineIn ) )
{
_timeSinceBlink = 0f;
Sprite.Enabled = !Sprite.Enabled;
}
if ( SpawnTime > Lifetime )
{
var cloud = Manager.Instance.SpawnCloud( Position2D );
cloud.Velocity = new Vector2( Game.Random.Float( -1f, 1f ), Game.Random.Float( -1f, 1f ) ).Normal * Game.Random.Float( 0.2f, 0.6f );
Remove();
return;
}
}
if ( SpawnTime > 0.1f )
{
foreach ( Player player in Manager.Instance.GetPlayers() )
{
var dist_sqr = (Position2D - player.Position2D).LengthSquared;
var req_dist_sqr = MathF.Pow( player.Stats[PlayerStat.CoinAttractRange], 2f );
if ( dist_sqr < req_dist_sqr )
{
Velocity += (player.Position2D - Position2D).Normal * Utils.Map( dist_sqr, req_dist_sqr, 0f, 0f, 1f, EasingType.Linear ) * player.Stats[PlayerStat.CoinAttractStrength] * dt;
}
}
}
for ( int dx = -1; dx <= 1; dx++ )
{
for ( int dy = -1; dy <= 1; dy++ )
{
Manager.Instance.HandleThingCollisionForGridSquare( this, new GridSquare( GridPos.x + dx, GridPos.y + dy ), dt );
if ( IsRemoved )
return;
}
}
}
public override void Colliding( Thing other, float percent, float dt )
{
base.Colliding( other, percent, dt );
if ( other is Enemy enemy && !enemy.IsDying )
{
Velocity += (Position2D - other.Position2D).Normal * Utils.Map( percent, 0f, 1f, 0f, 1f ) * 20f * (1f + other.TempWeight) * dt;
}
else if ( other is Player player )
{
if ( !player.IsDead && SpawnTime > 0.1f )
{
var amount = player.Stats[PlayerStat.HealthPackAmount];
if ( amount > 0f )
{
player.Heal( amount, 0.2f );
Manager.Instance.PlaySfxNearby( "heal", Position2D, pitch: Utils.Map( player.Health / player.Stats[PlayerStat.MaxHp], 0f, 1f, 1.5f, 1f ), volume: 1.5f, maxDist: 5f );
//var particle = DamageNumbersLegacy.Create( amount, player.Position2D + new Vector2( 0.2f + Game.Random.Float( -0.1f, 0.1f ), player.Radius * 3f + Game.Random.Float( -0.2f, 0.3f ) ), color: Color.Green, sizeMultiplier: 1f );
//Vector3 velocity = new Vector3( 0f, 0f, 0f );
//Vector3 gravity = new Vector3( 0f, 1f, 0f );
//particle.SetVector( 1, velocity );
//particle.SetNamedValue( "Gravity", gravity );
var pos = Position2D + new Vector2( Game.Random.Float( -0.1f, 0.1f ), Radius * 3f + Game.Random.Float( -0.2f, 0.3f ) );
float size = Utils.Map( amount, 1, 30, 1.2f, 1.6f, EasingType.QuadOut );
Manager.Instance.SpawnDamageNumber( pos, amount, Color.Green, size, FloaterType.Heal );
}
else
{
player.Damage( Math.Abs(amount), PlayerDamageType.Self );
Manager.Instance.PlaySfxNearby( "zombie.attack.player", player.Position2D, pitch: Game.Random.Float( 1.45f, 1.55f ), volume: 0.9f, maxDist: 3f );
}
Remove();
}
}
else if ( other is HealthPack healthPack || other is RerollPickup rerollPickup )
{
Velocity += (Position2D - other.Position2D).Normal * Utils.Map( percent, 0f, 1f, 0f, 1f ) * 20f * dt;
}
}
}