255 lines
8.5 KiB
C#
255 lines
8.5 KiB
C#
using System.Collections.Generic;
|
|
using JetBrains.Annotations;
|
|
using UnityEngine.Scripting;
|
|
using UnityEngine;
|
|
using System.Linq;
|
|
using System.IO;
|
|
using System;
|
|
using Random = UnityEngine.Random;
|
|
|
|
#if UNITY_EDITOR
|
|
using UnityEditor;
|
|
using UnityEngine.UI;
|
|
#endif // UNITY_EDITOR
|
|
|
|
namespace Fruitomation.Game
|
|
{
|
|
public class BuildingManager : MonoBehaviour
|
|
{
|
|
[Header("References")]
|
|
[SerializeField] private BuildingRegistry Registry;
|
|
[SerializeField] private GameObject HeatGrid;
|
|
|
|
[Header("Colors")]
|
|
[SerializeField] private Color FreezingColor;
|
|
[SerializeField] private Color ColdColor;
|
|
[SerializeField] private Color RoomColor;
|
|
[SerializeField] private Color WarmColor;
|
|
[SerializeField] private Color BoilingColor;
|
|
|
|
private enum HeatingLevel
|
|
{
|
|
Freezing,
|
|
Cold,
|
|
Room,
|
|
Warm,
|
|
Boiling
|
|
}
|
|
|
|
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<SerializedBuilding> buildings) =>
|
|
Buildings = buildings.ToArray();
|
|
}
|
|
|
|
private static string Filepath => Path.Combine(Application.persistentDataPath, "buildings.json");
|
|
|
|
private (HeatingLevel, Image)[,] HeatingLevels { get; } = new (HeatingLevel, Image)[96, 49];
|
|
private bool[,] InhabitedCells { get; } = new bool[96, 49];
|
|
|
|
private List<Building> Buildings { get; } = new();
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
private static BuildingManager Instance;
|
|
|
|
public void ToggleGrid() => HeatGrid.SetActive(!HeatGrid.activeSelf);
|
|
|
|
private Color LevelToColor(HeatingLevel level)
|
|
{
|
|
return level switch
|
|
{
|
|
HeatingLevel.Room => RoomColor,
|
|
HeatingLevel.Boiling => BoilingColor,
|
|
HeatingLevel.Cold => ColdColor,
|
|
HeatingLevel.Freezing => FreezingColor,
|
|
HeatingLevel.Warm => WarmColor,
|
|
var _ => new Color()
|
|
};
|
|
}
|
|
|
|
private void Awake()
|
|
{
|
|
HeatGrid.SetActive(false);
|
|
Instance = this;
|
|
|
|
for (int x = 0; x < HeatingLevels.GetLength(0); x++)
|
|
{
|
|
for (int y = 0; y < HeatingLevels.GetLength(1); y++)
|
|
{
|
|
GameObject go = new($"Grid_{x}_{y}");
|
|
go.transform.SetParent(HeatGrid.transform);
|
|
|
|
RectTransform rt = go.AddComponent<RectTransform>();
|
|
Image img = go.AddComponent<Image>();
|
|
|
|
HeatingLevels[x, y].Item1 = (HeatingLevel)Random.Range(0, 5);
|
|
HeatingLevels[x, y].Item2 = img;
|
|
|
|
img.color = LevelToColor(HeatingLevels[x, y].Item1);
|
|
|
|
rt.localScale = Vector3.one;
|
|
img.raycastTarget = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
[MenuItem("Fruitomation/Clear Buildings")]
|
|
public static void ClearBuildings()
|
|
{
|
|
foreach (Building b in Instance.Buildings)
|
|
{
|
|
Destroy(b.gameObject);
|
|
}
|
|
|
|
Instance.Buildings.Clear();
|
|
}
|
|
|
|
#endif // UNITY_EDITOR
|
|
|
|
private void Start()
|
|
{
|
|
if (!File.Exists(Filepath))
|
|
{
|
|
return;
|
|
}
|
|
|
|
string json = File.ReadAllText(Filepath);
|
|
SerializedBuilding[] buildings = JsonUtility.FromJson<SerializedBuildings>(json).Get();
|
|
|
|
foreach (SerializedBuilding building in buildings)
|
|
{
|
|
GameObject prefab = Registry.GetBuildingOf(building.PrefabName);
|
|
GameObject go = Instantiate(prefab, transform);
|
|
|
|
BuildingInfo info = new
|
|
(
|
|
go.GetComponent<Building>(),
|
|
go.GetComponent<RectTransform>()
|
|
);
|
|
|
|
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<SerializedBuilding> 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);
|
|
|
|
for (int x = building.GridPosition.x; x < building.GridPosition.x + building.SizeOnGrid.x; x++)
|
|
for (int y = building.GridPosition.y; y < building.GridPosition.y + building.SizeOnGrid.y; y++)
|
|
{
|
|
InhabitedCells[x, y] = false;
|
|
}
|
|
}
|
|
|
|
public bool AddBuildingAt(Vector2Int position, BuildingRegistry.BuildingInfo building, bool isFlipped)
|
|
{
|
|
//
|
|
GameObject go = Instantiate(building.Prefab, transform);
|
|
BuildingInfo info = new
|
|
(
|
|
go.GetComponent<Building>(),
|
|
go.GetComponent<RectTransform>()
|
|
);
|
|
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;
|
|
}
|
|
}
|
|
} |