Grid/Base/FloorSpawner.cs
using Sandbox;
using Sandbox.Sboku;
using Sandbox.Sboku.Arena;
using System;
using System.Collections.Generic;
using System.Numerics;
/// <summary>
/// FloorSpawner – vastaa lattian spawnaamisesta maailmaan.
/// Sisältää yhtenäisen lattian spawnauksen (ulko- ja sisäosa),
/// lattiacolliderin luomisen sekä yksittäisten lattiaruutujen spawnauksen (ei käytössä).
/// </summary>
internal class FloorSpawner
{
private readonly GridSpawner owner;
private GridMap Map => owner.Map;
private Model BoxModel => owner.BoxModel;
private Material FloorIndoorMaterial => owner.FloorIndoorMaterial;
private Material FloorOutdoorMaterial => owner.FloorOutdoorMaterial;
private float FloorZ => owner.FloorZ;
public FloorSpawner(GridSpawner owner)
{
this.owner = owner;
}
/// <summary>
/// Spawnaa yhden ison ulkolattian ja erilliset sisälattiat jokaiselle huoneelle.
/// </summary>
public void SpawnFloorSingle()
{
if (!Networking.IsHost)
return;
float thickness = 4f;
// =========================
// OUTDOOR FLOOR
// =========================
{
var go = new GameObject("Floor_Outdoor");
float width = Map.Width * Map.GridSize;
float height = Map.Height * Map.GridSize;
float scaleX = width / BoxModel.Bounds.Size.x;
float scaleY = height / BoxModel.Bounds.Size.y;
float scaleZ = thickness / BoxModel.Bounds.Size.z;
var floorMat = FloorOutdoorMaterial.CreateCopy();
floorMat.Set("g_vTexCoordScale", new Vector2(Map.Width, Map.Height));
var renderer = go.Components.Create<ModelRenderer>();
renderer.Model = BoxModel;
renderer.MaterialOverride = floorMat;
go.Transform.Scale = new Vector3(scaleX, scaleY, scaleZ);
Vector3 min = Map.GridToWorld(0, 0, 0f);
Vector3 max = Map.GridToWorld(Map.Width - 1, Map.Height - 1, 0f);
Vector3 center = (min + max) * 0.5f;
center.z = FloorZ - thickness * 0.5f;
go.Transform.Position = center;
go.NetworkSpawn();
}
// =========================
// INDOOR FLOORS (korjattu keskitys)
// =========================
var rooms = Map.FindRooms();
foreach (var room in rooms)
{
var go = new GameObject("Floor_Indoor");
int roomWidth = room.maxX - room.minX + 1;
int roomHeight = room.maxY - room.minY + 1;
float width = roomWidth * Map.GridSize;
float height = roomHeight * Map.GridSize;
float scaleX = width / BoxModel.Bounds.Size.x;
float scaleY = height / BoxModel.Bounds.Size.y;
float scaleZ = thickness / BoxModel.Bounds.Size.z;
var floorMat = FloorIndoorMaterial.CreateCopy();
floorMat.Set("g_vTexCoordScale", new Vector2(roomWidth, roomHeight));
var renderer = go.Components.Create<ModelRenderer>();
renderer.Model = BoxModel;
renderer.MaterialOverride = floorMat;
go.Transform.Scale = new Vector3(scaleX, scaleY, scaleZ);
// 🔥 Lasketaan world min/max huoneelle
Vector3 min = Map.GridToWorld(room.minX, room.minY, 0f);
Vector3 max = Map.GridToWorld(room.maxX, room.maxY, 0f);
Vector3 center = (min + max) * 0.5f;
// 🔥 pieni sisäänveto ettei osu seinän sisään
float inset = Map.GridSize * 0.02f;
width -= inset * 2f;
height -= inset * 2f;
scaleX = width / BoxModel.Bounds.Size.x;
scaleY = height / BoxModel.Bounds.Size.y;
go.Transform.Scale = new Vector3(scaleX, scaleY, scaleZ);
center.z = FloorZ - thickness * 0.5f + 2f;
go.Transform.Position = center;
go.NetworkSpawn();
}
}
/// <summary>
/// Spawnaa yhden ison staattisen colliderin koko lattian alle.
/// </summary>
public void SpawnSingleFloorCollider()
{
var go = new GameObject("FloorCollider");
var collider = go.AddComponent<BoxCollider>();
collider.Static = true;
float sizeX = Map.Width * Map.GridSize;
float sizeY = Map.Height * Map.GridSize;
float floorThickness = 32f;
collider.Scale = new Vector3(sizeX, sizeY, floorThickness);
var center = Map.GridToWorld(
Map.Width / 2,
Map.Height / 2,
0f
);
// 🔑 keskikohta = FloorZ - puolet paksuudesta
go.Transform.Position = new Vector3(
center.x,
center.y,
FloorZ - floorThickness * 0.5f);
}
/// <summary>
/// Spawnaa yksittäisen lattiaruudun annettuun koordinaattiin (ei käytössä, säilytetään).
/// </summary>
public void SpawnFloorTile(int x, int y)
{
var go = new GameObject($"Floor_{x}_{y}");
var renderer = go.AddComponent<ModelRenderer>();
renderer.MaterialOverride = FloorIndoorMaterial;
var visual = go.AddComponent<MaterialVisual>();
visual.MaterialPath = owner.FloorIndoorMaterials[owner.FloorIndoorMaterialIndex];
float scaleXY = Map.GridSize / BoxModel.Bounds.Size.x;
float scaleZ = 0.05f;
go.Transform.LocalScale = new Vector3(scaleXY, scaleXY, scaleZ);
Vector3 pos = Map.GridToWorld(x, y, FloorZ);
go.Transform.Position = pos;
//go.NetworkSpawn();
}
}