✨ Better placement and data modeling
This commit is contained in:
		| @@ -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}"); | ||||
| 		} | ||||
|   | ||||
| @@ -7,43 +7,60 @@ namespace AceFieldNewHorizon.Scripts.System; | ||||
|  | ||||
| public enum GridLayer | ||||
| { | ||||
|     Ground,    // Base layer (e.g., terrain, floors) | ||||
|     Building,  // Main building layer | ||||
|     Ground, // Base layer (e.g., terrain, floors) | ||||
|     Building, // Main building layer | ||||
|     Decoration // Additional layer for decorations, effects, etc. | ||||
| } | ||||
|  | ||||
| public partial class GridManager : Node | ||||
| { | ||||
|     private Dictionary<GridLayer, Dictionary<Vector2I, Node2D>> _layers = new(); | ||||
|     private Dictionary<GridLayer, Dictionary<Vector2I, (Node2D Building, Vector2I Size, float Rotation)>> _layers = | ||||
|         new(); | ||||
|  | ||||
|     public GridManager() | ||||
|     { | ||||
|         // Initialize all layers | ||||
|         foreach (GridLayer layer in Enum.GetValues(typeof(GridLayer))) | ||||
|         { | ||||
|             _layers[layer] = new Dictionary<Vector2I, Node2D>(); | ||||
|             _layers[layer] = new Dictionary<Vector2I, (Node2D, Vector2I, float)>(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public bool IsCellFree(Vector2I cell, GridLayer layer = GridLayer.Building) | ||||
|     public bool IsAreaFree(Vector2I topLeft, Vector2I size, float rotation, GridLayer layer = GridLayer.Building) | ||||
|     { | ||||
|         return !_layers[layer].ContainsKey(cell); | ||||
|         var occupiedCells = GridUtils.GetOccupiedCells(topLeft, size, rotation); | ||||
|         foreach (var cell in occupiedCells) | ||||
|         { | ||||
|             if (_layers[layer].ContainsKey(cell)) | ||||
|                 return false; | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     public void OccupyCell(Vector2I cell, Node2D building, GridLayer layer = GridLayer.Building) | ||||
|     public void OccupyArea(Vector2I topLeft, Node2D building, Vector2I size, float rotation, | ||||
|         GridLayer layer = GridLayer.Building) | ||||
|     { | ||||
|         _layers[layer][cell] = building; | ||||
|         var occupiedCells = GridUtils.GetOccupiedCells(topLeft, size, rotation); | ||||
|         foreach (var cell in occupiedCells) | ||||
|         { | ||||
|             _layers[layer][cell] = (building, size, rotation); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void FreeCell(Vector2I cell, GridLayer layer = GridLayer.Building) | ||||
|     public void FreeArea(Vector2I topLeft, Vector2I size, float rotation, GridLayer layer = GridLayer.Building) | ||||
|     { | ||||
|         if (_layers[layer].ContainsKey(cell)) | ||||
|             _layers[layer].Remove(cell); | ||||
|         var occupiedCells = GridUtils.GetOccupiedCells(topLeft, size, rotation); | ||||
|         foreach (var cell in occupiedCells) | ||||
|         { | ||||
|             if (_layers[layer].ContainsKey(cell)) | ||||
|                 _layers[layer].Remove(cell); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public Node2D? GetBuildingAtCell(Vector2I cell, GridLayer layer = GridLayer.Building) | ||||
|     { | ||||
|         return _layers[layer].GetValueOrDefault(cell); | ||||
|         return _layers[layer].TryGetValue(cell, out var data) ? data.Building : null; | ||||
|     } | ||||
|  | ||||
|     public bool IsAnyCellOccupied(Vector2I cell, params GridLayer[] layers) | ||||
| @@ -55,6 +72,7 @@ public partial class GridManager : Node | ||||
|             { | ||||
|                 if (layer.ContainsKey(cell)) return true; | ||||
|             } | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
| @@ -62,6 +80,34 @@ public partial class GridManager : Node | ||||
|         { | ||||
|             if (_layers[layer].ContainsKey(cell)) return true; | ||||
|         } | ||||
|  | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     public bool IsAreaOccupied(Vector2I topLeft, Vector2I size, float rotation, params GridLayer[] layers) | ||||
|     { | ||||
|         var occupiedCells = GridUtils.GetOccupiedCells(topLeft, size, rotation); | ||||
|  | ||||
|         if (layers.Length == 0) | ||||
|         { | ||||
|             // Check all layers if none specified | ||||
|             foreach (var cell in occupiedCells) | ||||
|             { | ||||
|                 foreach (var layer in _layers.Values) | ||||
|                     if (layer.ContainsKey(cell)) | ||||
|                         return true; | ||||
|             } | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         foreach (var cell in occupiedCells) | ||||
|         { | ||||
|             foreach (var layer in layers) | ||||
|                 if (_layers[layer].ContainsKey(cell)) | ||||
|                     return true; | ||||
|         } | ||||
|  | ||||
|         return false; | ||||
|     } | ||||
| } | ||||
| @@ -85,4 +131,26 @@ public static class GridUtils | ||||
|             cell.Y * TileSize | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     public static Vector2 GetCenterOffset(Vector2I size, float rotation) | ||||
|     { | ||||
|         var rotatedSize = (Mathf.RoundToInt(rotation / 90f) % 2) == 0 ? size : new Vector2I(size.Y, size.X); | ||||
|         return new Vector2(rotatedSize.X * TileSize / 2f, rotatedSize.Y * TileSize / 2f); | ||||
|     } | ||||
|  | ||||
|     public static List<Vector2I> GetOccupiedCells(Vector2I topLeft, Vector2I size, float rotation) | ||||
|     { | ||||
|         var occupiedCells = new List<Vector2I>(); | ||||
|         var rotatedSize = (Mathf.RoundToInt(rotation / 90f) % 2) == 0 ? size : new Vector2I(size.Y, size.X); | ||||
|  | ||||
|         for (int x = 0; x < rotatedSize.X; x++) | ||||
|         { | ||||
|             for (int y = 0; y < rotatedSize.Y; y++) | ||||
|             { | ||||
|                 occupiedCells.Add(new Vector2I(topLeft.X + x, topLeft.Y + y)); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return occupiedCells; | ||||
|     } | ||||
| } | ||||
| @@ -1,6 +1,7 @@ | ||||
| using System; | ||||
| using AceFieldNewHorizon.Scripts.Tiles; | ||||
| using Godot; | ||||
| using System.Linq; | ||||
|  | ||||
| namespace AceFieldNewHorizon.Scripts.System; | ||||
|  | ||||
| @@ -10,26 +11,26 @@ public partial class PlacementManager : Node2D | ||||
|     [Export] public BuildingRegistry Registry { get; set; } | ||||
|  | ||||
|     private string _currentBuildingId = "wall"; | ||||
|     private GridLayer _currentLayer = GridLayer.Building; // Default layer | ||||
|     private Vector2I _hoveredCell; | ||||
|     private BaseTile _ghostBuilding; | ||||
|     private float _currentRotation = 0f; | ||||
|     private float _currentRotation; | ||||
|     private Vector2I _currentBuildingSize = Vector2I.One; | ||||
|  | ||||
|     public void SetCurrentBuilding(string buildingId, GridLayer layer = GridLayer.Building) | ||||
|     public void SetCurrentBuilding(string buildingId) | ||||
|     { | ||||
|         _currentBuildingId = buildingId; | ||||
|         _currentLayer = layer; | ||||
|         var buildingData = Registry.GetBuilding(buildingId); | ||||
|         if (buildingData != null) | ||||
|         { | ||||
|             _currentBuildingSize = buildingData.Size; | ||||
|             // Reset rotation to nearest allowed rotation | ||||
|             if (!buildingData.IsRotationAllowed(_currentRotation)) | ||||
|             { | ||||
|                 _currentRotation = (int)buildingData.AllowedRotations[0] * 90f; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Replace ghost immediately | ||||
|         if (_ghostBuilding == null) return; | ||||
|         _ghostBuilding.QueueFree(); | ||||
|         _ghostBuilding = null; | ||||
|     } | ||||
|  | ||||
|     public void SetCurrentLayer(GridLayer layer) | ||||
|     { | ||||
|         _currentLayer = layer; | ||||
|         // Update ghost building if needed | ||||
|         if (_ghostBuilding != null) | ||||
|         { | ||||
|             _ghostBuilding.QueueFree(); | ||||
| @@ -40,18 +41,54 @@ public partial class PlacementManager : Node2D | ||||
|     private void RotateGhost(bool reverse = false) | ||||
|     { | ||||
|         if (_ghostBuilding == null) return; | ||||
|  | ||||
|         var buildingData = Registry.GetBuilding(_currentBuildingId); | ||||
|         if (buildingData == null) return; | ||||
|  | ||||
|         // Calculate next rotation | ||||
|         var currentDirection = (RotationDirection)((Mathf.RoundToInt(_currentRotation / 90f) % 4 + 4) % 4); | ||||
|         var currentIndex = Array.IndexOf(buildingData.AllowedRotations.ToArray(), currentDirection); | ||||
|  | ||||
|         if (reverse) | ||||
|             _currentRotation = (_currentRotation - 90f) % 360f; | ||||
|             currentIndex = (currentIndex - 1 + buildingData.AllowedRotations.Length) % | ||||
|                            buildingData.AllowedRotations.Length; | ||||
|         else | ||||
|             _currentRotation = (_currentRotation + 90f) % 360f; | ||||
|             currentIndex = (currentIndex + 1) % buildingData.AllowedRotations.Length; | ||||
|  | ||||
|         _currentRotation = (int)buildingData.AllowedRotations[currentIndex] * 90f; | ||||
|         _ghostBuilding.RotationDegrees = _currentRotation; | ||||
|  | ||||
|         // Update ghost position to keep the same cell under cursor | ||||
|         UpdateGhostPosition(); | ||||
|     } | ||||
|  | ||||
|     private void UpdateGhostPosition() | ||||
|     { | ||||
|         if (_ghostBuilding == null) return; | ||||
|  | ||||
|         var buildingData = Registry.GetBuilding(_currentBuildingId); | ||||
|         if (buildingData == null) return; | ||||
|  | ||||
|         var rotatedSize = buildingData.GetRotatedSize(_currentRotation); | ||||
|         var offset = GridUtils.GetCenterOffset(rotatedSize, _currentRotation); | ||||
|         _ghostBuilding.Position = GridUtils.GridToWorld(_hoveredCell) + offset; | ||||
|  | ||||
|         // Update occupied cells | ||||
|         GridUtils.GetOccupiedCells(_hoveredCell, rotatedSize, _currentRotation); | ||||
|     } | ||||
|  | ||||
|     public override void _Process(double delta) | ||||
|     { | ||||
|         // Snap mouse to grid | ||||
|         var mousePos = GetGlobalMousePosition(); | ||||
|         _hoveredCell = GridUtils.WorldToGrid(mousePos); | ||||
|         var newHoveredCell = GridUtils.WorldToGrid(mousePos); | ||||
|  | ||||
|         // Only update if cell changed | ||||
|         if (newHoveredCell != _hoveredCell) | ||||
|         { | ||||
|             _hoveredCell = newHoveredCell; | ||||
|             UpdateGhostPosition(); | ||||
|         } | ||||
|  | ||||
|         if (Input.IsActionJustPressed("rotate_tile_reverse")) | ||||
|             RotateGhost(reverse: true); | ||||
| @@ -60,82 +97,115 @@ public partial class PlacementManager : Node2D | ||||
|  | ||||
|         if (_ghostBuilding == null) | ||||
|         { | ||||
|             var scene = Registry.GetBuilding(_currentBuildingId)?.Scene; | ||||
|             if (scene == null) return; | ||||
|             var building = Registry.GetBuilding(_currentBuildingId); | ||||
|             if (building == null) return; | ||||
|             var scene = building.Scene; | ||||
|  | ||||
|             _ghostBuilding = (BaseTile)scene.Instantiate(); | ||||
|             _ghostBuilding.SetGhostMode(true); | ||||
|             _ghostBuilding.RotationDegrees = _currentRotation; | ||||
|             _ghostBuilding.ZAsRelative = false; | ||||
|             _ghostBuilding.ZIndex = (int)_currentLayer; // Use layer as Z-index | ||||
|             _ghostBuilding.ZIndex = (int)building.Layer; | ||||
|             UpdateGhostPosition(); | ||||
|             AddChild(_ghostBuilding); | ||||
|         } | ||||
|  | ||||
|         var placementPos = GridUtils.GridToWorld(_hoveredCell); | ||||
|         var spaceState = GetWorld2D().DirectSpaceState; | ||||
|         var centerPos = placementPos + new Vector2(GridUtils.TileSize / 2f, GridUtils.TileSize / 2f); | ||||
|  | ||||
|         var query = new PhysicsPointQueryParameters2D | ||||
|         { | ||||
|             Position = centerPos, | ||||
|             CollideWithBodies = true, | ||||
|             CollideWithAreas = true, | ||||
|             CollisionMask = uint.MaxValue | ||||
|         }; | ||||
|  | ||||
|         var collision = spaceState.IntersectPoint(query, 8); | ||||
|          | ||||
|         // Check if the current cell is free in the current layer | ||||
|         var canPlace = Grid.IsCellFree(_hoveredCell, _currentLayer) &&  | ||||
|                       !Grid.IsAnyCellOccupied(_hoveredCell, GetBlockingLayers()); | ||||
|  | ||||
|         _ghostBuilding.Position = placementPos; | ||||
|         var canPlace = CanPlaceBuilding(); | ||||
|         _ghostBuilding.SetGhostMode(canPlace); | ||||
|  | ||||
|         // Left click to place | ||||
|         if (Input.IsActionPressed("build_tile") && canPlace) | ||||
|         { | ||||
|             var scene = Registry.GetBuilding(_currentBuildingId)?.Scene; | ||||
|             if (scene == null) return; | ||||
|             var building = Registry.GetBuilding(_currentBuildingId); | ||||
|             if (building == null) return; | ||||
|  | ||||
|             _ghostBuilding.FinalizePlacement(); | ||||
|             _ghostBuilding.RotationDegrees = _currentRotation; | ||||
|             _ghostBuilding.ZIndex = (int)_currentLayer; | ||||
|             var scene = building.Scene; | ||||
|             var buildingInstance = (BaseTile)scene.Instantiate(); | ||||
|             buildingInstance.RotationDegrees = _currentRotation; | ||||
|             buildingInstance.ZIndex = (int)building.Layer; | ||||
|             buildingInstance.Position = _ghostBuilding.Position; | ||||
|             AddChild(buildingInstance); | ||||
|  | ||||
|             var buildingData = Registry.GetBuilding(_currentBuildingId); | ||||
|             Grid.OccupyCell(_hoveredCell, _ghostBuilding, _currentLayer); | ||||
|             Grid.OccupyArea(_hoveredCell, buildingInstance, building.Size, _currentRotation, building.Layer); | ||||
|  | ||||
|             if (buildingData is { BuildTime: > 0f }) | ||||
|                 _ghostBuilding.StartConstruction(buildingData.BuildTime); | ||||
|  | ||||
|             // Create new ghost for next placement | ||||
|             _ghostBuilding = (BaseTile)scene.Instantiate(); | ||||
|             _ghostBuilding.SetGhostMode(true); | ||||
|             _ghostBuilding.RotationDegrees = _currentRotation; | ||||
|             _ghostBuilding.ZAsRelative = false; | ||||
|             _ghostBuilding.ZIndex = (int)_currentLayer; | ||||
|             AddChild(_ghostBuilding); | ||||
|             if (building.BuildTime > 0f) | ||||
|                 buildingInstance.StartConstruction(building.BuildTime); | ||||
|         } | ||||
|  | ||||
|         if (Input.IsActionPressed("destroy_tile") && !Grid.IsCellFree(_hoveredCell, _currentLayer)) | ||||
|         if (Input.IsActionPressed("destroy_tile") && | ||||
|             !Grid.IsAreaFree(_hoveredCell, Vector2I.One, 0f)) | ||||
|         { | ||||
|             // Right click to destroy from current layer | ||||
|             var building = Grid.GetBuildingAtCell(_hoveredCell, _currentLayer); | ||||
|             var building = Grid.GetBuildingAtCell(_hoveredCell); | ||||
|             if (building == null) return; | ||||
|             // Find all cells occupied by this building | ||||
|             var buildingInfo = Grid.GetBuildingInfoAtCell(_hoveredCell, GridLayer.Building); | ||||
|             if (buildingInfo == null) return; | ||||
|             building.QueueFree(); | ||||
|             Grid.FreeCell(_hoveredCell, _currentLayer); | ||||
|             Grid.FreeArea(buildingInfo.Value.Position, buildingInfo.Value.Size, buildingInfo.Value.Rotation); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Define which layers should block placement | ||||
|     private GridLayer[] GetBlockingLayers() | ||||
|     private bool CanPlaceBuilding() | ||||
|     { | ||||
|         return _currentLayer switch | ||||
|         var buildingData = Registry.GetBuilding(_currentBuildingId); | ||||
|         if (buildingData == null) return false; | ||||
|  | ||||
|         // Check if rotation is allowed | ||||
|         if (!buildingData.IsRotationAllowed(_currentRotation)) | ||||
|             return false; | ||||
|  | ||||
|         // Check if area is free | ||||
|         var rotatedSize = buildingData.GetRotatedSize(_currentRotation); | ||||
|         return !Grid.IsAreaOccupied(_hoveredCell, rotatedSize, _currentRotation, GetBlockingLayers(buildingData.Layer)); | ||||
|     } | ||||
|  | ||||
|     private GridLayer[] GetBlockingLayers(GridLayer layer) | ||||
|     { | ||||
|         return layer switch | ||||
|         { | ||||
|             GridLayer.Ground => new[] { GridLayer.Ground }, | ||||
|             GridLayer.Building => new[] { GridLayer.Ground, GridLayer.Building }, | ||||
|             GridLayer.Decoration => new[] { GridLayer.Ground, GridLayer.Building, GridLayer.Decoration }, | ||||
|             GridLayer.Ground => [GridLayer.Ground], | ||||
|             GridLayer.Building => [GridLayer.Ground, GridLayer.Building], | ||||
|             GridLayer.Decoration => [GridLayer.Ground, GridLayer.Building, GridLayer.Decoration], | ||||
|             _ => [] | ||||
|         }; | ||||
|     } | ||||
| } | ||||
|  | ||||
| public static class GridManagerExtensions | ||||
| { | ||||
|     public static (Vector2I Position, Vector2I Size, float Rotation)? GetBuildingInfoAtCell(this GridManager grid, | ||||
|         Vector2I cell, GridLayer layer) | ||||
|     { | ||||
|         if (grid.GetBuildingAtCell(cell, layer) is { } building) | ||||
|         { | ||||
|             // Find the top-left position of the building | ||||
|             for (int x = 0; x < 100; x++) // Arbitrary max size | ||||
|             { | ||||
|                 for (int y = 0; y < 100; y++) | ||||
|                 { | ||||
|                     var checkCell = new Vector2I(cell.X - x, cell.Y - y); | ||||
|                     if (grid.GetBuildingAtCell(checkCell, layer) == building) | ||||
|                     { | ||||
|                         // Found the top-left corner, now find the size | ||||
|                         var size = Vector2I.One; | ||||
|                         // Search right | ||||
|                         while (grid.GetBuildingAtCell(new Vector2I(checkCell.X + size.X, checkCell.Y), layer) == | ||||
|                                building) | ||||
|                             size.X++; | ||||
|                         // Search down | ||||
|                         while (grid.GetBuildingAtCell(new Vector2I(checkCell.X, checkCell.Y + size.Y), layer) == | ||||
|                                building) | ||||
|                             size.Y++; | ||||
|  | ||||
|                         // Get rotation from the first cell | ||||
|                         var rotation = 0f; // You'll need to store rotation in GridManager to make this work | ||||
|                         return (checkCell, size, rotation); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return null; | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user