Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
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);
        }