Game component that manages lobby and round lifecycle for a simple SCP-style game. It creates a lobby on host start, tracks connections and scene objects tagged as humans, scps, and spectators, assigns one random player as SCP_173 at round start, spawns DBoi for others, and cleans up objects when round ends.
using Sandbox;
using Sandbox.Network;
using System.Collections.Generic;
using System.Linq;
using System;
using Sandbox.Platform;
public class game : Component, Component.INetworkListener
{
[Property] public GameObject DBoi {get;set;}
[Property] public GameObject SCP_173 {get;set;}
[Property] public GameObject Spectator {get;set;}
[Property] public GameObject Map {get;set;}
List<GameObject> Humans = new List<GameObject>();
List<GameObject> SCPs = new List<GameObject>();
List<GameObject> Spectators = new List<GameObject>();
List<Connection> Players = new List<Connection>();
bool IsActive;
bool Can_Start_OR_Stop = true;
Random random;
protected override async void OnStart()
{if (!Networking.IsHost) return; random = new Random();
Networking.CreateLobby(new LobbyConfig());
await Task.Delay(50); Chat.AddText("You need at least 2 players");}
protected override void OnUpdate()
{ if (!Networking.IsHost) return;
Lists(); Starting(); Stopping();
}
void Lists()
{
Humans = new List<GameObject>(Scene.FindAllWithTag("human"));
SCPs = new List<GameObject>(Scene.FindAllWithTag("scp"));
Spectators = new List<GameObject>(Scene.FindAllWithTag("spectator"));
Players = Connection.All.ToList();
for (int i = Players.Count - 1; i >= 0; i--)
{if (!Players[i].IsActive)
{Players.RemoveAt(i); continue;}}
}
void Starting()
{
if (Players.Count >= 2 && !IsActive && Can_Start_OR_Stop)
{ Grace(); IsActive = true;
var Spawnpoints = new List<GameObject>(Map.Children);
for (int i = Spawnpoints.Count - 1; i >= 0; i--)
{if (Spawnpoints[i].Name != "info_player_start")
{Spawnpoints.RemoveAt(i); continue;}}
var SCP = Players[random.Next(Players.Count)];
var SCP_Spawnpoint = Spawnpoints[random.Next(Spawnpoints.Count)];
foreach (var Player in Players)
{
if (Player == SCP)
{
var scp173 = SCP_173.Clone(SCP_Spawnpoint.WorldPosition);
Spawnpoints.Remove(SCP_Spawnpoint);
scp173.NetworkSpawn(Player);
continue; }
var dboi = DBoi.Clone(Spawnpoints[random.Next(Spawnpoints.Count)].WorldPosition);
dboi.NetworkSpawn(Player);
}
foreach (var spectator in Spectators)
spectator.Destroy();
}
}
void Stopping()
{
if ((Humans.Count <= 0 || SCPs.Count <= 0) && IsActive && Can_Start_OR_Stop)
{ Grace(); IsActive = false;
foreach (var SCP in SCPs)
SCP.Destroy();
foreach (var Human in Humans)
Human.Destroy();
foreach (var spectator in Spectators)
spectator.Destroy();
}
}
async void Grace()
{
Can_Start_OR_Stop = false;
await Task.Delay(50);
Can_Start_OR_Stop = true;
}
public void OnActive(Connection c)
{
if (!IsActive || Players.Count < 2)
{
var spectator = Spectator.Clone();
spectator.NetworkSpawn(c);
}
}
}