GameLoop/ArenaGameManager.cs
/// <summary>
/// Arena game manager — gives every spawning player a Peach Launcher instead
/// of the default sandbox loadout (physgun, toolgun, camera).
///
/// SETUP
/// ──────
/// Add this component to the same GameObject as GameManager in your arena scene,
/// or place it anywhere in the scene as a standalone component.
///
/// Assign PeachLauncherPrefab in the inspector:
/// → weapons/peach_launcher/peach_launcher.prefab
///
/// Make sure your scene has SpawnPoint components so FindSpawnLocation() works.
/// </summary>
[Title( "Arena Game Manager" )]
[Category( "Game / Peach" )]
public sealed class ArenaGameManager : Component, Global.IPlayerEvents
{
[Property] public GameObject PeachLauncherPrefab { get; set; }
// ── IPlayerEvents ──────────────────────────────────────────────────────────
void Global.IPlayerEvents.OnPlayerSpawned( Player player )
{
if ( !Networking.IsHost ) return;
if ( !player.IsValid() ) return;
GivePeachLauncher( player );
}
// ── Loadout ────────────────────────────────────────────────────────────────
private void GivePeachLauncher( Player player )
{
var inventory = player.Components.Get<PlayerInventory>();
if ( !inventory.IsValid() )
{
Log.Warning( "ArenaGameManager: Player has no PlayerInventory!" );
return;
}
if ( !PeachLauncherPrefab.IsValid() )
{
Log.Warning( "ArenaGameManager: PeachLauncherPrefab is not assigned!" );
return;
}
// Clear whatever the loadout system restored (physgun, toolgun etc.)
// Give a frame for PlayerLoadout.OnPlayerSpawned to have run first,
// then we override it.
_ = GivePeachLauncherAsync( player, inventory );
}
private async Task GivePeachLauncherAsync( Player player, PlayerInventory inventory )
{
// Yield so PlayerLoadout's OnPlayerSpawned (which also listens to
// Global.IPlayerEvents.OnPlayerSpawned) can run first and give its
// weapons — then we clear and replace.
await Task.Yield();
if ( !player.IsValid() || !inventory.IsValid() ) return;
// Remove whatever the loadout gave
foreach ( var weapon in inventory.Weapons.ToList() )
weapon.DestroyGameObject();
await Task.Yield();
// Give the peach launcher in slot 0
inventory.Pickup( PeachLauncherPrefab, 0, false );
inventory.SwitchWeapon( inventory.GetSlot( 0 ) );
}
}