Game component that manages player roles and round lifecycle for a hide-and-seek style game. It tracks players, finds spawnpoints from the selected map, assigns one random seeker and the rest hiders at round start, spawns/destroys role entities and ragdolls/spectators, and handles simple lobby/start logic.
using Sandbox;
using Sandbox.Network;
using System.Collections.Generic;
using System;
using Sandbox.Platform;
public class game : Component, Component.INetworkListener
{
[Property] public GameObject Hider {get;set;}
[Property] public GameObject Seeker {get;set;}
[Property] public GameObject Spectator {get;set;}
[Property] public MapInstance Map {get;set;}
List<GameObject> Hiders = new();
List<GameObject> Seekers = new();
List<Connection> Players = new();
List<GameObject> Ragdolls = new();
List<GameObject> Spectators = new();
[Sync] public bool IsActive {get;set;}
Random random = new(); TimeUntil Grace;
[Sync] public TimeUntil Time {get;set;}
protected override void OnUpdate()
{ if (!Networking.IsHost) return;
Players = new(Connection.All);
for (int i = Players.Count - 1; i >= 0; i--)
if (!Players[i].IsActive)
Players.RemoveAt(i);
Hiders = new(Scene.FindAllWithTag("hider"));
Seekers = new(Scene.FindAllWithTag("seeker"));
Ragdolls = new(Scene.FindAllWithTag("ragdoll"));
Spectators = new(Scene.FindAllWithTag("spectator"));
if (Players.Count >= 2 && !IsActive && Grace)
{ IsActive = true; Grace = 1f; Time = 180f;
var Spawnpoints = new List<GameObject>(Map.GameObject.Children);
for (int i = Spawnpoints.Count - 1; i >= 0; i--)
if (Spawnpoints[i].Name != "info_player_start")
Spawnpoints.RemoveAt(i);
var seeker = Players[random.Next(Players.Count)];
var Seeker_Spawnpoint = Spawnpoints[random.Next(Spawnpoints.Count)];
foreach (var Player in Players)
{
if (Player == seeker)
{
var skr = Seeker.Clone(Seeker_Spawnpoint.WorldPosition);
skr.NetworkSpawn(Player); Spawnpoints.Remove(Seeker_Spawnpoint);
continue; }
var hider = Hider.Clone(Spawnpoints[random.Next(Spawnpoints.Count)].WorldPosition);
hider.NetworkSpawn(Player);
}
foreach (var Ragdoll in Ragdolls) Ragdoll.Destroy();
foreach (var spectator in Spectators) spectator.Destroy();
}
if ((Hiders.Count <= 0 || Seekers.Count <= 0 || Time) && IsActive && Grace)
{ IsActive = false; Grace = 1f; Time = 180f;
foreach (var hider in Hiders) hider.Destroy();
foreach (var seeker in Seekers) seeker.Destroy();
foreach (var Ragdoll in Ragdolls) Ragdoll.Destroy();
foreach (var spectator in Spectators) spectator.Destroy();
}
}
public void OnActive(Connection connection)
{
if (!IsActive && Players.Count < 2)
{
var _ = Spectator.Clone();
_.NetworkSpawn(connection);
}
}
protected override async void OnStart() {
Networking.CreateLobby(new LobbyConfig());
Map.MapName = _game.CurrentlySelectedMap;
while (LoadingScreen.IsVisible)
await Task.Delay(100);
Chat.AddText("You need at least 2 players.");
}
}