StageEventIcyGround is a stage event class that spawns a snow particle prefab, adjusts global movespeed and friction modifiers, and fades an icy fog in and out over the event lifetime. It also posts a local chat message when started and stops particle emission near the end.
using System;
using System.Reflection;
using Sandbox;
public class StageEventIcyGround : StageEvent
{
private GameObject _particleObj;
private ParticleEffect _particleEffect;
private ParticleEmitter _emitter;
//GameObject _groundObj;
//ModelRenderer _groundRenderer;
//Color _originalGroundTint;
// todo: sometimes last for 2 minutes+
private const float LERP_TIME = 5f;
private const float REDUCED_FRICTION = 0.1f;
private const float REDUCED_MOVESPEED = 0.25f;
//private Color _groundColorIcy;
// todo: change player dash so it adds normal velocity?
// todo: change movespeed factor to work better with sliding
private bool _hasStoppedSpawning;
GradientFog _fog;
public override void Start( int randSeed )
{
base.Start( randSeed );
// sfx
Manager.Instance.Chat.AddLocalChatMessage( "The ground's getting icy!", from: "" );
Lifetime = 60f;
_particleObj = GameObject.Clone( "prefabs/effects/snow_effect.prefab", new CloneConfig { StartEnabled = true, Transform = new Transform( new Vector3( 0f, 0f, 250f ) ) } );
_particleEffect = _particleObj.GetComponent<ParticleEffect>();
_emitter = _particleObj.GetComponent<ParticleEmitter>();
//_groundObj = Manager.Instance.Scene.Directory.FindByName( "ground" ).FirstOrDefault();
//_groundObj.Enabled = true;
//_groundRenderer = _groundObj.GetComponent<ModelRenderer>();
//_originalGroundTint = _groundRenderer.Tint;
//_groundColorIcy = new Color( 0.05f, 0.1f, 0.2f, 0.55f );
_fog = Manager.Instance.IcyGroundFog.GetComponent<GradientFog>( includeDisabled: true );
_fog.Color = _fog.Color.WithAlpha( 0f );
Manager.Instance.IcyGroundFog.Enabled = true;
}
public override void Update()
{
base.Update();
var FOG_FULL_OPACITY = 0.15f;
if( TimeSinceStart < LERP_TIME )
{
Manager.Instance.GlobalMovespeedModifier = Utils.Map( TimeSinceStart, 0f, LERP_TIME, 1f, REDUCED_MOVESPEED );
Manager.Instance.GlobalFrictionModifier = Utils.Map( TimeSinceStart, 0f, LERP_TIME, 1f, REDUCED_FRICTION );
_fog.Color = _fog.Color.WithAlpha( Utils.Map( TimeSinceStart, 0f, LERP_TIME, 0f, FOG_FULL_OPACITY ) );
//_groundRenderer.Tint = Color.Lerp( _originalGroundTint, _groundColorIcy, Utils.Map( TimeSinceStart, 0f, LERP_TIME, 0f, 1f ) );
}
else if(TimeSinceStart > Lifetime - LERP_TIME )
{
if ( !_hasStoppedSpawning )
{
_emitter.Rate = 0f;
_hasStoppedSpawning = true;
}
Manager.Instance.GlobalMovespeedModifier = Utils.Map( TimeSinceStart, Lifetime - LERP_TIME, Lifetime, REDUCED_MOVESPEED, 1f );
Manager.Instance.GlobalFrictionModifier = Utils.Map( TimeSinceStart, Lifetime - LERP_TIME, Lifetime, REDUCED_FRICTION, 1f );
_fog.Color = _fog.Color.WithAlpha( Utils.Map( TimeSinceStart, Lifetime - LERP_TIME, Lifetime, FOG_FULL_OPACITY, 0f ) );
//_groundRenderer.Tint = Color.Lerp( _groundColorIcy, _originalGroundTint, Utils.Map( TimeSinceStart, Lifetime - LERP_TIME, Lifetime, 0f, 1f ) );
}
var windForce = Manager.Instance.GlobalWindForce;
float particleStrengthFactor = 2f;
_particleEffect.ForceDirection = new Vector3( windForce.x * particleStrengthFactor, windForce.y * particleStrengthFactor, -100f );
if ( TimeSinceStart > Lifetime )
{
Manager.Instance.RemoveEvent( EventType );
}
if ( !Networking.IsHost )
return;
}
public override void Remove()
{
base.Remove();
//_groundRenderer.Tint = _originalGroundTint;
//_groundObj.Enabled = false;
Manager.Instance.GlobalMovespeedModifier = 1f;
Manager.Instance.GlobalFrictionModifier = 1f;
Manager.Instance.IcyGroundFog.Enabled = false;
_particleObj?.Destroy();
}
}