void CreatePathfindingNodes() { for (int y = Building.Rectangle.Top; y < Building.Rectangle.Bottom; y++) { for (int x = Building.Rectangle.Left; x < Building.Rectangle.Right; x++) { ITile tile = Level.Map.GetTileByTopLeftCorner(x, y); Vector3 position = new Vector3(tile.Center.X, GetHeightAt(tile.Center.X, tile.Center.Y).Value, tile.Center.Y); IBuildingNode node = Level.Map.PathFinding.CreateBuildingNode(Building, position, TowerTag); nodes.Add(tile, node); } } //Connect roof edges foreach (var tileAndNode in nodes) { ITile tile = tileAndNode.Key; IBuildingNode node = tileAndNode.Value; foreach (var neighbour in tile.GetNeighbours()) { if (neighbour == null) { continue; } //Connect to neighbor roof nodes if (nodes.TryGetValue(neighbour, out IBuildingNode neighbourNode)) { node.CreateEdge(neighbourNode, MovementType.Linear); } else if (neighbour.Building != null && neighbour.Building.BuildingPlugin is WalkableBuildingPlugin plugin) { IBuildingNode foreighNode = plugin.TryGetNodeAt(neighbour); //Either is not loaded yet, will connect from the other side // or does not contain a node (impossible in the current version) if (foreighNode == null) { continue; } //Do not connect to keep if (foreighNode.Tag == Keep.KeepTag) { continue; } if (!foreighNode.HasEdgeTo(node)) { foreighNode.CreateEdge(node, MovementType.Teleport); } if (!node.HasEdgeTo(foreighNode)) { node.CreateEdge(foreighNode, MovementType.Teleport); } } } } }
void ConnectNeighbours() { ITile myTile = Level.Map.GetContainingTile(Building.Center); foreach (var neighbor in myTile.GetNeighbours()) { if (neighbor?.Building == null) { continue; } if (neighbor.Building.BuildingPlugin is WalkableBuildingPlugin plugin) { IBuildingNode node = plugin.TryGetNodeAt(neighbor); //Either is not loaded yet, will connect from the other side // or does not contain a node (impossible in the current version) if (node == null) { continue; } MovementType movementType; if (node.Tag == WallTag) { movementType = MovementType.Linear; } else if (node.Tag == Gate.GateRoofTag || node.Tag == Tower.TowerTag) { movementType = MovementType.Teleport; } else { continue; } if (!pathNode.HasEdgeTo(node)) { pathNode.CreateEdge(node, movementType); } if (!node.HasEdgeTo(pathNode)) { node.CreateEdge(pathNode, movementType); } } } }
void CreatePathfindingNodes() { for (int y = Building.Rectangle.Top; y < Building.Rectangle.Bottom; y++) { for (int x = Building.Rectangle.Left; x < Building.Rectangle.Right; x++) { ITile tile = Level.Map.GetTileByTopLeftCorner(x, y); Vector3 position = new Vector3(tile.Center.X, GetHeightAt(tile.Center.X, tile.Center.Y).Value, tile.Center.Y); IBuildingNode node = Level.Map.PathFinding.CreateBuildingNode(Building, position, KeepTag); nodes.Add(tile, node); } } //Connect roof edges foreach (var tileAndNode in nodes) { ITile tile = tileAndNode.Key; IBuildingNode node = tileAndNode.Value; foreach (var neighbour in tile.GetNeighbours()) { if (neighbour == null) { continue; } //Connect to neighbor roof nodes if (nodes.TryGetValue(neighbour, out IBuildingNode neighbourNode)) { node.CreateEdge(neighbourNode, MovementType.Linear); } //Connects just to own nodes, does not connect to other buildings. } } //Connect to tile in front var buildingFrontTile = Level.Map.GetContainingTile(Building.Center + Building.Forward * 2); ITileNode tileNode = Level.Map.PathFinding.GetTileNode(TileInFront); IBuildingNode buildingNode = nodes[buildingFrontTile]; tileNode.CreateEdge(buildingNode, MovementType.Teleport); buildingNode.CreateEdge(tileNode, MovementType.Teleport); }
void CreatePathfindingNodes() { //Roof nodes for (int y = Building.Rectangle.Top; y < Building.Rectangle.Bottom; y++) { for (int x = Building.Rectangle.Left; x < Building.Rectangle.Right; x++) { ITile tile = Level.Map.GetTileByTopLeftCorner(x, y); Vector3 position = new Vector3(tile.Center.X, GetHeightAt(tile.Center.X, tile.Center.Y).Value, tile.Center.Y); IBuildingNode node = Level.Map.PathFinding.CreateBuildingNode(Building, position, GateRoofTag); roofNodes.Add(tile, node); } } //Connect roof edges foreach (var tileAndNode in roofNodes) { ITile tile = tileAndNode.Key; IBuildingNode node = tileAndNode.Value; foreach (var neighbour in tile.GetNeighbours()) { if (neighbour == null) { continue; } //Connect to neighbor roof nodes if (roofNodes.TryGetValue(neighbour, out IBuildingNode neighbourNode)) { node.CreateEdge(neighbourNode, MovementType.Linear); } else if (neighbour.Building != null && neighbour.Building.BuildingPlugin is WalkableBuildingPlugin plugin) { IBuildingNode foreighNode = plugin.TryGetNodeAt(neighbour); //Either is not loaded yet, will connect from the other side // or does not contain a node (impossible in the current version) if (foreighNode == null) { continue; } if (foreighNode.Tag == Keep.KeepTag) { continue; } if (!foreighNode.HasEdgeTo(node)) { foreighNode.CreateEdge(node, MovementType.Teleport); } if (!node.HasEdgeTo(foreighNode)) { node.CreateEdge(foreighNode, MovementType.Teleport); } } } } //Gate nodes Vector3 centerPosition = Building.Center; //Goes through the strip of tiles at the center of the Gate, withY 0 because nodes have to follow // the flat base of the building List <IBuildingNode> newTunnelNodes = new List <IBuildingNode>(); for (int i = -2; i < 2; i++) { Vector3 position = centerPosition + i * Building.Forward.WithY(0); ITile tile = Level.Map.GetContainingTile(position); IBuildingNode node = Level.Map.PathFinding.CreateBuildingNode(Building, position, GateTunnelTag); tunnelNodes.Add(tile, node); newTunnelNodes.Add(node); } Vector3 doorPosition = centerPosition + 2 * Building.Forward.WithY(0); ITile doorInnerTile = Level.Map.GetContainingTile(doorPosition); IBuildingNode doorNode = Level.Map.PathFinding.CreateBuildingNode(Building, doorPosition, GateDoorTag); tunnelNodes.Add(doorInnerTile, doorNode); newTunnelNodes.Add(doorNode); //Connect tunnel edges for (int i = 1; i < newTunnelNodes.Count; i++) { newTunnelNodes[i - 1].CreateEdge(newTunnelNodes[i], MovementType.Linear); newTunnelNodes[i].CreateEdge(newTunnelNodes[i - 1], MovementType.Linear); } //Connect front node and back node to outside tiles ITile backTile = Level.Map.GetContainingTile(centerPosition - 3 * Building.Forward); ITile frontTile = Level.Map.GetContainingTile(centerPosition + 3 * Building.Forward); if (backTile != null) { INode backNode = Level.Map.PathFinding.GetTileNode(backTile); backNode.CreateEdge(newTunnelNodes[0], MovementType.Linear); newTunnelNodes[0].CreateEdge(backNode, MovementType.Linear); } if (frontTile != null) { INode frontNode = Level.Map.PathFinding.GetTileNode(frontTile); frontNode.CreateEdge(newTunnelNodes[newTunnelNodes.Count - 1], MovementType.Linear); newTunnelNodes[newTunnelNodes.Count - 1].CreateEdge(frontNode, MovementType.Linear); } //Connect roof with the tunnel ITile centerTile = Level.Map.GetContainingTile(Building.Center); tunnelNodes[centerTile].CreateEdge(roofNodes[centerTile], MovementType.Teleport); roofNodes[centerTile].CreateEdge(tunnelNodes[centerTile], MovementType.Teleport); }