Files
AceField-New-Horizon/Scripts/System/BuildingRegistry.cs
2025-08-27 02:42:13 +08:00

132 lines
3.3 KiB
C#

using System.Collections.Generic;
using Godot;
namespace AceFieldNewHorizon.Scripts.System;
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";
public override void _Ready()
{
LoadFromJson(JsonPath);
}
public void LoadFromJson(string path)
{
var file = FileAccess.Open(path, FileAccess.ModeFlags.Read);
if (file == null)
{
GD.PrintErr($"[BuildingRegistry] Failed to open {path}");
return;
}
var text = file.GetAsText();
file.Close();
var json = new Json();
var error = json.Parse(text);
if (error != Error.Ok)
{
GD.PrintErr($"[BuildingRegistry] Failed to parse JSON: {json.GetErrorMessage()}");
return;
}
var dict = (Godot.Collections.Dictionary)json.Data;
foreach (string key in dict.Keys)
{
// Each entry is a Dictionary with keys: "scene", "cost", "durability", "buildTime"
var buildingDict = dict[key].AsGodotDictionary();
// Parse scene
var scenePath = buildingDict.ContainsKey("scene") ? buildingDict["scene"].AsString() : null;
if (string.IsNullOrEmpty(scenePath))
{
GD.PrintErr($"[BuildingRegistry] No scene path for '{key}'");
continue;
}
var scene = GD.Load<PackedScene>(scenePath);
if (scene == null)
{
GD.PrintErr($"[BuildingRegistry] Failed to load scene for '{key}' at {scenePath}");
continue;
}
// Parse cost
Dictionary<string, int> cost = new();
if (buildingDict.TryGetValue("cost", out var value))
{
var costDict = value.AsGodotDictionary();
foreach (string mat in costDict.Keys)
{
int val;
var obj = costDict[mat];
if (obj.VariantType == Variant.Type.PackedInt64Array)
val = (int)obj.AsInt64();
else if (obj.VariantType == Variant.Type.PackedInt32Array)
val = obj.AsInt32();
else
int.TryParse(obj.ToString(), out val);
cost[mat] = val;
}
}
// Parse durability
var durability = 0;
if (buildingDict.TryGetValue("durability", out var dObj))
{
if (dObj.VariantType == Variant.Type.PackedInt64Array)
durability = (int)dObj.AsInt64();
else if (dObj.VariantType == Variant.Type.PackedInt32Array)
durability = dObj.AsInt32();
else
int.TryParse(dObj.ToString(), out durability);
}
// Parse buildTime
var buildTime = 0f;
if (buildingDict.TryGetValue("buildTime", out var bObj))
{
switch (bObj.VariantType)
{
case Variant.Type.PackedFloat32Array or Variant.Type.PackedFloat64Array:
buildTime = (float)bObj.AsDouble();
break;
case Variant.Type.PackedInt64Array:
buildTime = bObj.AsInt64();
break;
case Variant.Type.PackedInt32Array:
buildTime = bObj.AsInt32();
break;
default:
float.TryParse(bObj.ToString(), out buildTime);
break;
}
}
var buildingData = new BuildingData(scene, cost, durability, buildTime);
_registry[key] = buildingData;
GD.Print($"[BuildingRegistry] Loaded building '{key}' from {scenePath}");
}
GD.Print($"[BuildingRegistry] Loaded {_registry.Count} buildings");
}
public BuildingData GetBuilding(string id)
{
_registry.TryGetValue(id, out var data);
return data;
}
}