Park/Events/BaseEvent.cs
using Sandbox.Rendering;
using System;

[Icon( "❗" )]
public class BaseEvent : Component, ISceneMetadata
{
	/// <summary>
	/// The name of the event. This is what will be displayed in the UI.
	/// </summary>
	[Property, Group( "Display" )] public string Title { get; set; } = "Event";
	/// <summary>
	/// The description of the event. This is what will be displayed in the UI.
	/// </summary>
	[Property, Group( "Display" )] public string Description { get; set; } = "Event description";
	/// <summary>
	/// The probability of this event happening.
	/// </summary>
	[Property, Group( " Stats " ), Range( 0, 1 )] public float Probability { get; set; }
	[Property, Group( " Stats " )] public RangedFloat Duration { get; set; } = new( 0.0f, 10.0f );

	[Sync( SyncFlags.FromHost )] protected TimeSince _timeSinceStart { get; set; }
	[Sync( SyncFlags.FromHost )] protected float _duration { get; set; }

	public EventManager EventManager => EventManager.Instance;

	Dictionary<string, string> ISceneMetadata.GetMetadata()
	{
		return new()
		{
			{ "Type", "Events" }
		};
	}

	protected override void OnStart()
	{
		_timeSinceStart = 0.0f;
		_duration = Random.Shared.Float( Duration.Min, Duration.Max );
		EventManager.ActiveEvents.Add( GameObject );
	}

	protected override void OnUpdate()
	{
		base.OnUpdate();

		DrawHud( Scene.Camera.Hud );

		if ( !Networking.IsHost )
			return;

		if ( _timeSinceStart < _duration )
			return;

		// End the event
		OnEventEnd();
		GameObject.Destroy();
	}

	protected override void OnDestroy()
	{
		EventManager?.ActiveEvents.Remove( GameObject );
		base.OnDestroy();
	}
	protected virtual void OnEventEnd() { }
	protected virtual void DrawHud( HudPainter hud ) { }
}