Better placement and data modeling

This commit is contained in:
2025-08-27 22:09:38 +08:00
parent e54215423d
commit d3b19aa104
4 changed files with 287 additions and 87 deletions

View File

@@ -1,17 +1,46 @@
using System.Collections.Generic;
using System.Linq;
using Godot;
namespace AceFieldNewHorizon.Scripts.System;
public enum RotationDirection
{
Up, // 0 degrees
Right, // 90 degrees
Down, // 180 degrees
Left // 270 degrees
}
public record BuildingData(
PackedScene Scene,
Dictionary<string, int> Cost,
int Durability,
GridLayer Layer,
float BuildTime,
Vector2I Size = default,
RotationDirection[] AllowedRotations = null
)
{
public Vector2I Size { get; } = Size == default ? Vector2I.One : Size;
public RotationDirection[] AllowedRotations { get; } =
AllowedRotations ?? [RotationDirection.Up, RotationDirection.Right, RotationDirection.Down, RotationDirection.Left
];
public bool IsRotationAllowed(float degrees)
{
var direction = (RotationDirection)((Mathf.RoundToInt(degrees / 90f) % 4 + 4) % 4);
return AllowedRotations.Contains(direction);
}
public Vector2I GetRotatedSize(float degrees)
{
return (Mathf.RoundToInt(degrees / 90f) % 2) == 0 ? Size : new Vector2I(Size.Y, Size.X);
}
}
public partial class BuildingRegistry : Node
{
public record BuildingData(
PackedScene Scene,
Dictionary<string, int> Cost,
int Durability,
float BuildTime
);
private Dictionary<string, BuildingData> _registry = new();
[Export] public string JsonPath { get; set; } = "res://Data/Buildings.json";
@@ -45,7 +74,7 @@ public partial class BuildingRegistry : Node
foreach (string key in dict.Keys)
{
// Each entry is a Dictionary with keys: "scene", "cost", "durability", "buildTime"
// Each entry is a Dictionary with keys: "scene", "cost", "durability", "buildTime", "size", "allowedRotations"
var buildingDict = dict[key].AsGodotDictionary();
// Parse scene
@@ -115,7 +144,36 @@ public partial class BuildingRegistry : Node
}
}
var buildingData = new BuildingData(scene, cost, durability, buildTime);
// Parse size
var size = Vector2I.One;
if (buildingDict.TryGetValue("size", out var sObj))
{
var sizeArray = sObj.AsGodotArray();
if (sizeArray.Count == 2)
{
size = new Vector2I((int)sizeArray[0].AsInt64(), (int)sizeArray[1].AsInt64());
}
}
// Parse allowedRotations
RotationDirection[] allowedRotations = null;
if (buildingDict.TryGetValue("allowedRotations", out var arObj))
{
var arArray = arObj.AsGodotArray();
allowedRotations = new RotationDirection[arArray.Count];
for (var i = 0; i < arArray.Count; i++)
{
allowedRotations[i] = (RotationDirection)arArray[i].AsInt32();
}
}
var layer = GridLayer.Building;
if (buildingDict.TryGetValue("layer", out var lObj))
{
layer = (GridLayer)lObj.AsInt32();
}
var buildingData = new BuildingData(scene, cost, durability, layer, buildTime, size, allowedRotations);
_registry[key] = buildingData;
GD.Print($"[BuildingRegistry] Loaded building '{key}' from {scenePath}");
}