Grid/Base/GridSpawner.cs
using Sandbox;
using Sandbox.Grid.Base;
using Sandbox.Sboku;
using Sandbox.Sboku.Arena;
using System;
using System.Collections.Generic;
using System.Net.NetworkInformation;
using System.Numerics;
using System.Runtime.CompilerServices;
// =========================
// GRID SPAWNER
//Stone trim
//Stone altar, stone pickaxe, ´stone fire pit, stone spear, medieval wood door, wooden chair re4, wood market stand, short sword, gmod skeleton
//ceramic column, torch 2
// =========================
/// <summary>
/// GridSpawner – pääluokka, joka orkestroi gridin spawnaamisen s&box-maailmaan.
/// Säilyttää yhteiset propertyt ja kentät, delegoi varsinaisen spawnauksen
/// WallSpawner-, FloorSpawner- ja GridObjectSpawner-luokille.
/// </summary>
public sealed class GridSpawner : Component
{
// talo-id per grid-ruutu
internal int[,] HouseIds;
// talokohtainen materiaali
internal Dictionary<int, Material> HouseWallMaterials = new();
[Property] public DebrisVisualPool DebrisPool { get; set; }
[Property] public GameObject DustPrefab { get; set; }
[Property] public List<string> WallMaterials { get; set; }
[Property] public List<string> FloorOutdoorMaterials { get; set; }
[Property] public List<string> FloorIndoorMaterials { get; set; }
[Property] public List<string> IndoorModels { get; set; }
[Property] public List<string> OutdoorModels { get; set; }
private const int itemsPerRoom = 5;
private string SnowCapModelPath { get; set; } = "models/dev/box.vmdl";
private const float BorderUVFactor = 2.5f;
private string SnowCapMaterialPath { get; set; } = "materials/snow1.vmat";
[Sync] public int WallMaterialOuterIndex { get; private set; }
[Sync] public int WallMaterialHouseIndex { get; private set; }
[Sync] public int FloorIndoorMaterialIndex { get; private set; }
[Sync] public int FloorOutdoorMaterialIndex { get; private set; }
[Property] public GameObject InteriorFog { get; set; }
[Property] public int WallHeight { get; set; } = 3;
internal string WallModelPath { get; set; } = "models/dev/box.vmdl";
private string FloorModelPath { get; set; } = "models/floorplane.vmdl";
internal string ButtonModelPath { get; set; } = "models/buildings/stone/floor_128_a.vmdl";
internal string TrapModelEmptyPath { get; set; } = "deggassets/models/fantasy/map/trap_empty.vmdl";
internal string TrapModelPath { get; set; } = "deggassets/models/fantasy/map/trap_spikes.vmdl";
internal string DoorModelPath { get; set; } = "materials/zombieworld/woodendoor01_pixel.vmat";
[Property] public float SpawnHeight { get; set; } = 32f;
//lattian YLÄPINTA maailmassa
internal float FloorZ => SpawnHeight;
public string gridText { get; set; } =
"####\n#0+0#\n####";
public GridMap Map { get; private set; }
internal Model BoxModel;
internal Material WallMaterialHouse;
internal Material WallMaterialOuter;
internal Material FloorIndoorMaterial;
internal Material FloorOutdoorMaterial;
private int ChunkSize { get; set; } = 16;
private WallSpawner wallSpawner;
private FloorSpawner floorSpawner;
private GridObjectSpawner objectSpawner;
/// <summary>
/// Käytetäänkö vankila-generaattoria (true) vai tavallista talogeneraattoria (false).
/// </summary>
[Property] public bool UsePrisonLayout { get; set; } = false;
protected override void OnStart()
{
if (IsProxy)
return; // ❗ Client EI saa spawnaa gridin maailmaa
if (UsePrisonLayout)
{
var prisonGen = new PrisonGenerator();
prisonGen.Generate();
gridText = prisonGen.Serialize();
}
else
{
var gridGenerator = new GridGenerator();
gridGenerator.Generate();
gridText = gridGenerator.Serialize();
}
if (string.IsNullOrEmpty(gridText))
{
Log.Error("[GridSpawner] GridText not set!");
Enabled = false;
return;
}
Map = new GridMap(gridText);
if (UsePrisonLayout)
{
Log.Info("[GridSpawner] Prison layout active - skipping procedural wall/floor/object spawn.");
return;
}
BoxModel = Model.Load(WallModelPath);
WallMaterialOuterIndex = 0;
WallMaterialHouseIndex = 1;
WallMaterialOuter = Material.Load(WallMaterials[WallMaterialOuterIndex]);
WallMaterialHouse = Material.Load(WallMaterials[WallMaterialHouseIndex]);
// Luodaan helper-luokat
wallSpawner = new WallSpawner(this);
floorSpawner = new FloorSpawner(this);
objectSpawner = new GridObjectSpawner(this);
// 🔑 RAKENNA TALOT
wallSpawner.BuildHouseIds();
// Spawn seinät ja ovet
for (int y = 0; y < Map.Height; y++)
{
for (int x = 0; x < Map.Width; x++)
{
if (Map.IsWallLike(x, y))
wallSpawner.SpawnWallsAndDoors(x, y);
}
}
wallSpawner.SpawnBorderWalls();
FloorIndoorMaterialIndex = Game.Random.Int(0, FloorIndoorMaterials.Count - 1);
FloorIndoorMaterial = Material.Load(FloorIndoorMaterials[FloorIndoorMaterialIndex]);
FloorOutdoorMaterialIndex = Game.Random.Int(0, FloorOutdoorMaterials.Count - 1);
FloorOutdoorMaterial = Material.Load(FloorOutdoorMaterials[FloorOutdoorMaterialIndex]);
floorSpawner.SpawnFloorSingle();
/*for (int y = 0; y < Map.Height; y++)
{
for (int x = 0; x < Map.Width; x++)
{
floorSpawner.SpawnFloorTile(x, y);
}
}*/
floorSpawner.SpawnSingleFloorCollider();
// Spawn painikkeet
objectSpawner.SpawnButtons();
objectSpawner.SpawnTraps();
// Props disabled — no random indoor/outdoor item spawning
// var rooms = Map.FindRooms();
// objectSpawner.SpawnIndoorItems(this.Map);
// objectSpawner.SpawnOutdoorItems(this.Map,20);
}
}