stageEvents/StageEventDark.cs

A StageEvent that darkens the scene for a timed duration. On Start it finds the Sun directional light, stores original sky and light colors, spawns per-player light prefabs attached to player models, and fades the global light to black and the player lights to a dim color over LERP_TIME, then reverses the fade before ending and cleans up.

File Access
using System;
using System.Drawing;
using System.Reflection;
using Sandbox;

public class StageEventDark : StageEvent
{
	private DirectionalLight _sunLight;

	private const float LERP_TIME = 5f;

	private Color _originalSkyColor;
	private Color _originalLightColor;

	List<PlayerLights> _playerLights = new();

	private Color _playerLightColor;

	public override void Start( int randSeed )
	{
		base.Start( randSeed );

		// sfx
		Manager.Instance.Chat.AddLocalChatMessage( "It's getting dark!", from: "" );

		Lifetime = 60f;

		_sunLight = Manager.Instance.Scene.Directory.FindByName("Sun").First().GetComponent<DirectionalLight>();
		_originalSkyColor = _sunLight.SkyColor;
		_originalLightColor = _sunLight.LightColor;

		_playerLightColor = new Color( 0.91f, 0.98f, 1.00f );

		foreach ( var player in Manager.Instance.Scene.GetAllComponents<Player>() )
		{
			var lightsObj = GameObject.Clone( "prefabs/dark_player_lights.prefab" );
			lightsObj.SetParent( player.Model );
			lightsObj.LocalPosition = new Vector3( player.Radius + 10f, 0f, player.Height + 50f );
			lightsObj.LocalRotation = Rotation.Identity;

			var playerLights = lightsObj.GetComponent<PlayerLights>();
			_playerLights.Add( playerLights );
			playerLights.SetLightColor( Color.Black );
		}
	}

	public override void Update()
	{
		base.Update();

		if( TimeSinceStart < LERP_TIME )
		{
			_sunLight.SkyColor = Color.Lerp( _originalSkyColor, Color.Black, Utils.Map( TimeSinceStart, 0f, LERP_TIME, 0f, 1f ) );
			_sunLight.LightColor = Color.Lerp( _originalLightColor, Color.Black, Utils.Map( TimeSinceStart, 0f, LERP_TIME, 0f, 1f ) );

			foreach (var playerLights in _playerLights)
			{
				if ( playerLights.IsValid() )
					playerLights.SetLightColor( Color.Lerp( Color.Black, _playerLightColor, Utils.Map( TimeSinceStart, 0f, LERP_TIME, 0f, 1f ) ) );
			}
		}
		else if(TimeSinceStart > Lifetime - LERP_TIME )
		{
			_sunLight.SkyColor = Color.Lerp( Color.Black, _originalSkyColor, Utils.Map( TimeSinceStart, Lifetime - LERP_TIME, Lifetime, 0f, 1f ) );
			_sunLight.LightColor = Color.Lerp( Color.Black, _originalLightColor, Utils.Map( TimeSinceStart, Lifetime - LERP_TIME, Lifetime, 0f, 1f ) );

			foreach ( var playerLights in _playerLights )
			{
				if ( playerLights.IsValid() )
					playerLights.SetLightColor( Color.Lerp( _playerLightColor, Color.Black, Utils.Map( TimeSinceStart, Lifetime - LERP_TIME, Lifetime, 0f, 1f ) ) );
			}
		}

		if( TimeSinceStart > Lifetime )
		{
			Manager.Instance.RemoveEvent( EventType );
			return;
		}
	}

	public override void Remove()
	{
		base.Remove();

		_sunLight.SkyColor = _originalSkyColor;
		_sunLight.LightColor = _originalLightColor;

		for(int i = _playerLights.Count - 1; i >= 0; i--)
		{
			var lights = _playerLights[i];
			if ( lights.IsValid() )
				lights.GameObject.Destroy();
		}
	}
}