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); } } } } }
protected sealed override bool GetTime(IBuildingNode source, ITileNode target, MovementType movementType, out float time) { switch (movementType) { case MovementType.Linear: if (!CanPass(source, target)) { time = -1; return(false); } time = GetLinearTime(source.Position, target.Position); return(true); case MovementType.Teleport: if (!CanTeleport(source, target)) { time = -1; return(false); } time = GetTeleportTime(source, target); return(true); default: time = -1; return(false); } }
Wall(ILevelManager level, IBuilding building) : base(level, building) { Vector3 topPosition = building.Center; topPosition = topPosition.WithY(GetHeightAt(topPosition.X, topPosition.Z).Value); pathNode = level.Map.PathFinding.CreateBuildingNode(building, topPosition, WallTag); }
bool CanPassToBuilding(IBuildingNode target) { if (Instance.Unit.Player.IsFriend(target.Building.Player)) { return(false); } return(true); }
public BFSRoofFormationController(LevelInstancePluginBase levelPlugin, IBuildingNode startNode) { level = levelPlugin; buildingNodes = new Queue <INode>(); lowPrioNodes = new Queue <INode>(); enqueuedNodes = new HashSet <INode>(startNode.Algorithm.NodeEqualityComparer); failedTypes = new HashSet <UnitType>(); buildingNodes.Enqueue(startNode); enqueuedNodes.Add(startNode); }
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); } } } }
protected override bool CanPass(IBuildingNode source, ITileNode target) { if (base.CanPass(source, target)) { return(true); } if (!CanPassToTile(target)) { return(false); } CanBreakThrough.Add(target.Tile); return(true); }
protected override bool CanTeleport(IBuildingNode source, ITileNode target) { if (base.CanTeleport(source, target)) { return(true); } if (!Instance.myType.PassableTileTypes.Contains(target.Tile.Type)) { return(false); } CanBreakThrough.Add(target.Tile); return(true); }
protected override bool CanTeleport(IBuildingNode source, IBuildingNode target) { if (base.CanPass(source, target)) { return(true); } if (!CanPassToBuilding(target)) { return(false); } CanBreakThrough.Add(Map.GetContainingTile(target.Position)); return(true); }
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 INodeVisitor.Visit(ITempNode source, IBuildingNode target, MovementType movementType) { canPass = GetTime(source, target, movementType, out resTime); }
protected abstract bool CanTeleport(IBuildingNode source, IBuildingNode target);
public void Accept(INodeVisitor visitor, IBuildingNode source, MovementType movementType) { visitor.Visit(source, this, movementType); }
/// <summary> /// Gets if it is possible to get from <paramref name="source"/> TEMP node to <paramref name="target"/> BUILDING node, /// if true, then returns the time needed in <paramref name="time"/> /// </summary> /// <param name="source">Source node</param> /// <param name="target">Target node</param> /// <param name="time">Result time it will take to get from <paramref name="source"/> to <paramref name="target"/></param> /// <returns>If it is possible to get to the</returns> protected virtual bool GetTime(ITempNode source, IBuildingNode target, MovementType movementType, out float time) { time = -1; return(false); }
protected override bool CanTeleport(IBuildingNode source, IBuildingNode target) { return(CanPassToBuildingNode(target)); }
bool CanPassToBuildingNode(IBuildingNode target) { //Is not closed gate door return(target.Tag != Gate.GateDoorTag || ((Gate)target.Building.Plugin).IsOpen); }
public abstract void Accept(INodeVisitor visitor, IBuildingNode source, MovementType movementType);
protected override bool CanPass(IBuildingNode source, ITileNode target) { return(CanPassToTileNode(target)); }
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); }
public override IFormationController GetFormationController(Vector3 centerPosition) { IBuildingNode startNode = pathNode; return(new BFSRoofFormationController((LevelInstancePluginBase)Level.Plugin, startNode)); }
bool CanPassToBuildingNode(IBuildingNode target) { //Is not closed gate door and is not roof return((target.Tag != Gate.GateDoorTag || ((Gate)target.Building.Plugin).IsOpen) && !((LevelInstancePluginBase)Level.Plugin).IsRoofNode(target)); }
public bool IsRoofNode(IBuildingNode node) { return(node.Tag == Gate.GateRoofTag || node.Tag == Wall.WallTag || node.Tag == Tower.TowerTag); }
protected abstract bool CanPass(IBuildingNode source, IBuildingNode target);