using System.Collections; using System.Collections.Generic; using UnityEngine; using Sirenix.OdinInspector; namespace KairoEngine.Grids { [System.Serializable] public class PlaceableObjectRule { public enum Rule { EmptyCell, Connection, CellOcupied, AdjacentCellOcupied, AdjacentEmptyCell, CellInRadius, EmptyArea } private string title { get { switch (rule) { case Rule.EmptyCell: return $"Empty cell"; case Rule.Connection: return $"Has connector"; case Rule.CellOcupied: if(targetObject != null) return $"Cell ocupied by \"{targetObject?.title}\""; else return $"Cell ocupied (ERROR)"; case Rule.AdjacentCellOcupied: if(targetObject != null) return $"{objDir.ToString()} cell ocupied by \"{targetObject?.title}\""; else return $"{objDir.ToString()} cell ocupied (ERROR)"; case Rule.AdjacentEmptyCell: return $"{objDir.ToString()} cell is empty"; case Rule.CellInRadius: if(targetObject != null) return $"\"{targetObject?.title}\" is in a {radius} cell radius"; else return $"Cell in radius (ERROR)"; case Rule.EmptyArea: return $"Empty cells in a {radius} cell radius"; default: return "?"; } } } [SerializeField, FoldoutGroup("@title")] private Rule rule = Rule.EmptyCell; [ShowIf("@rule == Rule.CellOcupied || rule == Rule.AdjacentCellOcupied || rule == Rule.CellInRadius")] [SerializeField, FoldoutGroup("@title")] private PlacedObjectType targetObject; [ShowIf("@rule == Rule.AdjacentCellOcupied || rule == Rule.AdjacentEmptyCell")] [SerializeField, FoldoutGroup("@title")] private PlacedObjectType.Dir objDir; [ShowIf("@rule == Rule.CellInRadius || rule == Rule.EmptyArea")] [SerializeField, FoldoutGroup("@title")] private int radius = 3; [ShowIf("@rule == Rule.Connection")] [SerializeField, FoldoutGroup("@title")] private string connector = "connector name"; public bool Evaluate(Grid grid, PlacedObjectType placedObjectType, int x, int y, PlacedObjectType.Dir dir) { switch (rule) { case Rule.EmptyCell: return IsEmptyCells(grid, placedObjectType, x, y, dir); case Rule.Connection: return HasConnection(grid, placedObjectType, x, y, dir); case Rule.CellOcupied: break; case Rule.AdjacentCellOcupied: break; case Rule.AdjacentEmptyCell: break; case Rule.CellInRadius: break; case Rule.EmptyArea: break; default: break; } return false; } public Rule GetRule() => rule; public PlacedObjectType GetTargetObject() => targetObject; public int GetRadius() => radius; public string GetConnector() => connector; public bool IsEmptyCells(Grid grid, PlacedObjectType placedObjectType, int x, int z, PlacedObjectType.Dir dir) { GridObject gridObject = grid.GetObject(x, z); if(gridObject == null) return false; List gridPositionList = placedObjectType.GetGridPositionList(new Vector2Int(x, z), dir); bool canBuild = true; foreach (var gridPosition in gridPositionList) { var obj = grid.GetObject(gridPosition.x, gridPosition.y); if(obj != null) { if(!grid.GetObject(gridPosition.x, gridPosition.y).CanBuild()) canBuild = false; } else canBuild = false; } return canBuild; } public bool HasConnection(Grid grid, PlacedObjectType placedObjectType, int x, int z, PlacedObjectType.Dir dir) { for (int i = 0; i < placedObjectType.connectors.Count; i++) { Vector2Int pos = new Vector2Int(x, z); pos = pos + placedObjectType.GetConnectorPositionOffset(i, dir); Vector2Int targetPos = pos + placedObjectType.GetConnectorTargetPositionOffset(i, dir); GridObject gridObject = grid.GetObject(targetPos.x, targetPos.y); if(gridObject == null) continue; if(gridObject.GetPlacedObject() == null) continue; if(gridObject.GetPlacedObject().HasConnection(placedObjectType.connectors[i].title, pos.x, pos.y)) { //Debug.Log($"Connector found from {pos} to {targetPos}"); return true; } else { //Debug.Log($"No connector found from {pos} to {targetPos}"); } } return false; } } }