public static (byte objectId, byte gridX, byte gridY) LocateNodeConnection(WorldContent worldContent, WorldZoneFormat zone, byte gridX, byte gridY, DirCardinal dir) { var matchNode = NodeData.LocateNearestNode(worldContent, zone, gridX, gridY, dir); if (dir == DirCardinal.Up) { // If the matching node cannot connect in this direction, it doesn't. Return early. if (!NodeData.IsDirectionAllowed(matchNode.objectId, DirCardinal.Down)) { return(0, 0, 0); } if (matchNode.objectId > 0) { var revNode = NodeData.LocateNearestNode(worldContent, zone, matchNode.gridX, matchNode.gridY, DirCardinal.Down); // If the discovered node has no alternative to connect to, it matches with this one. if (revNode.objectId == 0) { return(matchNode); } // If the Matching Node's Connection connects back, it matches. if (revNode.gridX == gridX && revNode.gridY == gridY) { return(matchNode); } // If alternative node is on the same X level, it matches this one. if (matchNode.gridX == gridX) { return(matchNode); } // If matching node is NOT on the same X level, but its reverse is, the reverse is chosen. else if (matchNode.gridX == revNode.gridX) { return(0, 0, 0); } // If alternative node is further away than this one, it matches this one. if (revNode.gridY > gridY) { return(matchNode); } } } else if (dir == DirCardinal.Left) { // If the matching node cannot connect in this direction, it doesn't. Return early. if (!NodeData.IsDirectionAllowed(matchNode.objectId, DirCardinal.Right)) { return(0, 0, 0); } if (matchNode.objectId > 0) { var revNode = NodeData.LocateNearestNode(worldContent, zone, matchNode.gridX, matchNode.gridY, DirCardinal.Right); // If the discovered node has no alternative to connect to, it matches with this one. if (revNode.objectId == 0) { return(matchNode); } // If the Matching Node's Connection connects back, it matches. if (revNode.gridX == gridX && revNode.gridY == gridY) { return(matchNode); } // If alternative node is on the same Y level, it matches this one. if (matchNode.gridY == gridY) { return(matchNode); } // If matching node is NOT on the same Y level, but its reverse is, the reverse is chosen. else if (matchNode.gridY == revNode.gridY) { return(0, 0, 0); } // If alternative node is further away than this one, it matches this one. if (revNode.gridX > gridX) { return(matchNode); } } } else if (dir == DirCardinal.Right) { // If the matching node cannot connect in this direction, it doesn't. Return early. if (!NodeData.IsDirectionAllowed(matchNode.objectId, DirCardinal.Left)) { return(0, 0, 0); } if (matchNode.objectId > 0) { var revNode = NodeData.LocateNearestNode(worldContent, zone, matchNode.gridX, matchNode.gridY, DirCardinal.Left); // If the discovered node has no alternative to connect to, it matches with this one. if (revNode.objectId == 0) { return(matchNode); } // If the Matching Node's Connection connects back, it matches. if (revNode.gridX == gridX && revNode.gridY == gridY) { return(matchNode); } // If alternative node is on the same Y level, it matches this one. if (matchNode.gridY == gridY) { return(matchNode); } // If matching node is NOT on the same Y level, but its reverse is, the reverse is chosen. else if (matchNode.gridY == revNode.gridY) { return(0, 0, 0); } // If alternative node is further away than this one, it matches this one. if (revNode.gridX < gridX) { return(matchNode); } } } else if (dir == DirCardinal.Down) { // If the matching node cannot connect in this direction, it doesn't. Return early. if (!NodeData.IsDirectionAllowed(matchNode.objectId, DirCardinal.Up)) { return(0, 0, 0); } if (matchNode.objectId > 0) { var revNode = NodeData.LocateNearestNode(worldContent, zone, matchNode.gridX, matchNode.gridY, DirCardinal.Up); // If the discovered node has no alternative to connect to, it matches with this one. if (revNode.objectId == 0) { return(matchNode); } // If the Matching Node's Connection connects back, it matches. if (revNode.gridX == gridX && revNode.gridY == gridY) { return(matchNode); } // If alternative node is on the same X level, it matches this one. if (matchNode.gridX == gridX) { return(matchNode); } // If matching node is NOT on the same X level, but its reverse is, the reverse is chosen. else if (matchNode.gridX == revNode.gridX) { return(0, 0, 0); } // If alternative node is further away than this one, it matches this one. if (revNode.gridY < gridY) { return(matchNode); } } } return(0, 0, 0); }
public bool TryTravel(DirCardinal dir = DirCardinal.None) { // Can only move if the character is at a Node. if (!this.character.IsAtNode) { return(false); } // Get Current Tile Data byte[] wtData = this.worldContent.GetWorldTileData(this.currentZone, this.character.curX, this.character.curY); bool isNode = NodeData.IsObjectANode(wtData[5]); bool isBlocking = NodeData.IsObjectABlockingNode(wtData[5]); // If a node is not located here, continue. if (!isNode) { return(false); } // If the node is blocking (level unfinished), only the path back is allowed: if (isBlocking) { // Identify Level Data at this node: int coordId = Coords.MapToInt(this.character.curX, this.character.curY); string levelId = this.currentZone.nodes.ContainsKey(coordId.ToString()) ? this.currentZone.nodes[coordId.ToString()] : ""; // Check if this level has been completed (or isn't marked as one) if (levelId != "" && !this.campaign.IsLevelWon(this.campaign.zoneId, levelId)) { // The level hasn't been completed, so it is restricted in all directions except from where you came. var lastDir = this.campaign.lastDir; if (lastDir == (byte)DirCardinal.Left && dir != DirCardinal.Right) { return(false); } if (lastDir == (byte)DirCardinal.Right && dir != DirCardinal.Left) { return(false); } if (lastDir == (byte)DirCardinal.Up && dir != DirCardinal.Down) { return(false); } if (lastDir == (byte)DirCardinal.Down && dir != DirCardinal.Up) { return(false); } } } // Make sure that direction is allowed from current Node. if (!NodeData.IsDirectionAllowed(wtData[5], dir)) { return(false); } // Check for a connecting Node (one with a return connection). var connectNode = NodeData.LocateNodeConnection(this.worldContent, this.currentZone, this.character.curX, this.character.curY, dir); // Verify that a connection node exists: if (connectNode.objectId == 0) { return(false); } // Perform Movement this.character.TravelPath(connectNode.gridX, connectNode.gridY); this.campaign.lastDir = (byte)dir; return(true); }