using System.Collections.Generic; using JetBrains.Annotations; using UnityEngine.Scripting; using UnityEngine; using System; using System.IO; using System.Linq; namespace Fruitomation.Game { public class BuildingManager : MonoBehaviour { [SerializeField] private BuildingRegistry Registry; private class BuildingInfo { public BuildingInfo(Building b, RectTransform rt) { Building = b; Rect = rt; } public Building Building { get; } public RectTransform Rect { get; } } [Serializable] private class SerializedBuilding { [SerializeField, Preserve, UsedImplicitly] public Vector2Int GridPosition; [SerializeField, Preserve, UsedImplicitly] public Vector2Int Position; [SerializeField, Preserve, UsedImplicitly] public string PrefabName; [SerializeField, Preserve, UsedImplicitly] public bool IsFlipped; public SerializedBuilding(Vector2Int gridPosition, Vector2Int pos, string name, bool flipped) { GridPosition = gridPosition; IsFlipped = flipped; PrefabName = name; Position = pos; } } [Serializable] private class SerializedBuildings { [SerializeField, Preserve, UsedImplicitly] private SerializedBuilding[] Buildings; public SerializedBuilding[] Get() => Buildings; public SerializedBuildings(List buildings) => Buildings = buildings.ToArray(); } private static string Filepath => Path.Combine(Application.persistentDataPath, "buildings.json"); private bool[,] InhabitedCells { get; } = new bool[96, 49]; private List Buildings { get; } = new(); private void Start() { if (!File.Exists(Filepath)) { return; } string json = File.ReadAllText(Filepath); SerializedBuilding[] buildings = JsonUtility.FromJson(json).Get(); foreach (SerializedBuilding building in buildings) { GameObject prefab = Registry.GetBuildingOf(building.PrefabName); GameObject go = Instantiate(prefab, transform); BuildingInfo info = new ( go.GetComponent(), go.GetComponent() ); info.Rect.transform.localScale = new Vector3(building.IsFlipped ? -1f : 1f, 1f, 1f); info.Rect.sizeDelta = info.Building.SizeOnGrid * 40; info.Rect.anchoredPosition = building.Position; go.name = $"{building.PrefabName}"; info.Building.Init(this, building.GridPosition, building.Position, building.IsFlipped); Buildings.Add(info.Building); for (int x = building.GridPosition.x; x < building.GridPosition.x + info.Building.SizeOnGrid.x; x++) for (int y = building.GridPosition.y; y < building.GridPosition.y + info.Building.SizeOnGrid.y; y++) { InhabitedCells[x, y] = true; } } } private void OnDestroy() { Debug.Log($"Buildings: [{Buildings.Count}]"); List serialized = Buildings.Select(building => new SerializedBuilding ( building.GridPosition, building.Position, building.name, building.IsFlipped ) ).ToList(); string json = JsonUtility.ToJson(new SerializedBuildings(serialized), true); File.WriteAllText(Filepath, json); } public void RemoveBuilding(Building building) => Buildings.Remove(building); public bool AddBuildingAt(Vector2Int position, BuildingRegistry.BuildingInfo building, bool isFlipped) { // GameObject go = Instantiate(building.Prefab, transform); BuildingInfo info = new ( go.GetComponent(), go.GetComponent() ); go.name = $"{building.Name}"; Vector2Int p0 = position * 40; Vector2Int p1 = p0 + new Vector2Int(20, 100); Vector2Int g0 = position + new Vector2Int(48, 24); Vector2Int off0 = info.Building.SizeOnGrid - Vector2Int.one; Vector2Int off1 = off0 * 20; Vector2Int p2 = p1 + off1; info.Rect.sizeDelta = info.Building.SizeOnGrid * 40; info.Rect.anchoredPosition = p2; info.Rect.transform.localScale = new Vector3(isFlipped ? -1f : 1f, 1f, 1f); // for (int x = g0.x; x < g0.x + info.Building.SizeOnGrid.x; x++) for (int y = g0.y; y < g0.y + info.Building.SizeOnGrid.y; y++) { if (InhabitedCells[x, y]) { DestroyImmediate(go); return false; } } // for (int x = g0.x; x < g0.x + info.Building.SizeOnGrid.x; x++) for (int y = g0.y; y < g0.y + info.Building.SizeOnGrid.y; y++) { InhabitedCells[x, y] = true; } info.Building.Init(this, g0, p2, isFlipped); Buildings.Add(info.Building); return true; } } }