Exemple #1
0
        public static void SetLevel()
        {
            byte gridX = (byte)ConsoleTrack.GetArgAsInt();

            ConsoleTrack.possibleTabs = "Example: setLevel 10 10 MyLevelID";

            // If gridX is assigned:
            if (ConsoleTrack.instructionList.Count >= 2)
            {
                byte gridY = (byte)ConsoleTrack.GetArgAsInt();

                // If gridY is assigned:
                if (ConsoleTrack.instructionList.Count >= 3)
                {
                    // Check if this X, Y grid is valid (has a node at it).
                    WEScene         scene  = (WEScene)Systems.scene;
                    WorldZoneFormat zone   = scene.currentZone;
                    byte[]          wtData = scene.worldContent.GetWorldTileData(zone, gridX, gridY);

                    // If the location is a valid node, we can attempt to add a level ID.
                    if (NodeData.IsObjectANode(wtData[5], false, false, true))
                    {
                        string coordStr = Coords.MapToInt(gridX, gridY).ToString();
                        string levelId  = ConsoleTrack.GetArg();
                        ConsoleTrack.helpText = "Assign a level ID to the specified node.";

                        if (zone.nodes.ContainsKey(coordStr))
                        {
                            ConsoleTrack.helpText += " Current level ID is: " + zone.nodes[coordStr];
                        }

                        // If the console was activated:
                        if (ConsoleTrack.activate)
                        {
                            zone.nodes[coordStr] = levelId;
                            return;
                        }
                    }

                    // If the location is invalid:
                    else
                    {
                        ConsoleTrack.helpText = "WARNING! There is not a level node at " + gridX.ToString() + ", " + gridY.ToString();
                    }
                }

                // If gridY has not been assigned:
                else
                {
                    ConsoleTrack.helpText = "Assign a level ID to a node at the specified X, Y coordinate. Enter the Y position.";
                }
            }

            // If gridX has not been assigned:
            else
            {
                ConsoleTrack.helpText = "Assign a level ID to a node at the specified X, Y coordinate. Enter the X position.";
            }
        }
Exemple #2
0
        // ---------------------- //
        // --- Node Detection --- //
        // ---------------------- //

        public static bool IsNodeAtLocation(WorldContent worldContent, WorldZoneFormat zone, byte gridX, byte gridY, bool dotsCount = true, bool invisibleDotsCount = true, bool playableOnly = false)
        {
            // Check if a node is located here:
            byte[] wtData = worldContent.GetWorldTileData(zone, (byte)gridX, (byte)gridY);

            // If a node is not located here, continue.
            return(NodeData.IsObjectANode(wtData[5], dotsCount, invisibleDotsCount, playableOnly));
        }
Exemple #3
0
        public override void RunTick(WEScene scene)
        {
            if (UIComponent.ComponentWithFocus != null)
            {
                return;
            }

            // Left Mouse Button
            if (Cursor.LeftMouseState == Cursor.MouseDownState.Clicked)
            {
                WorldZoneFormat zone  = scene.currentZone;
                byte            gridX = (byte)Cursor.MiniGridX;
                byte            gridY = (byte)Cursor.MiniGridY;

                byte[] wtData = scene.worldContent.GetWorldTileData(zone, gridX, gridY);

                // If the wand clicked on a warp, then we can attempt to assign a warp link ID.
                if (NodeData.IsObjectAWarp(wtData[5]))
                {
                    UIHandler.SetMenu(UIHandler.worldEditConsole, true);
                    UIHandler.worldEditConsole.Open();
                    UIHandler.worldEditConsole.SendCommand("setWarp " + gridX.ToString() + " " + gridY.ToString() + " ", false);
                    ChatConsole.SendMessage("--------------------", Color.White);
                    ChatConsole.SendMessage("Assign a Link ID to this Warp Node. Must be a number between 1 and 20. Warps that share the same ID will link to each other. ", Color.Red);
                    ChatConsole.SendMessage("--------------------", Color.White);
                    ChatConsole.SendMessage("Example: setWarp " + gridX.ToString() + " " + gridY.ToString() + " 1", Color.Green);
                    ChatConsole.SendMessage("--------------------", Color.White);
                }

                // If the wand clicked on a node, then we can attempt to assign a level.
                if (NodeData.IsObjectANode(wtData[5], false, false, true))
                {
                    UIHandler.SetMenu(UIHandler.worldEditConsole, true);
                    UIHandler.worldEditConsole.Open();
                    UIHandler.worldEditConsole.SendCommand("setLevel " + gridX.ToString() + " " + gridY.ToString() + " ", false);
                    ChatConsole.SendMessage("--------------------", Color.White);
                    ChatConsole.SendMessage("Assign a Level ID to this Node. It can be any valid level, including official levels or levels created by other players. The original author will be credited with the level design.", Color.Red);
                    ChatConsole.SendMessage("--------------------", Color.White);
                    ChatConsole.SendMessage("Example: setLevel " + gridX.ToString() + " " + gridY.ToString() + " TUTORIAL_1", Color.Green);
                    ChatConsole.SendMessage("--------------------", Color.White);
                }
            }

            // Right Mouse Button (Clone Current Tile)
            else if (Cursor.RightMouseState == Cursor.MouseDownState.Clicked)
            {
                scene.CloneTile((byte)Cursor.MiniGridX, (byte)Cursor.MiniGridY);
            }
        }
Exemple #4
0
        public override void RunTick(WEScene scene)
        {
            if (UIComponent.ComponentWithFocus != null)
            {
                return;
            }

            // Left Mouse Button Down (Delete Current Tile)
            if (Cursor.mouseState.LeftButton == ButtonState.Pressed)
            {
                WorldZoneFormat zone  = scene.currentZone;
                byte            gridX = (byte)Cursor.MiniGridX;
                byte            gridY = (byte)Cursor.MiniGridY;

                byte[] wtData = scene.worldContent.GetWorldTileData(zone, gridX, gridY);

                // Delete Tile Top if the base is not water.
                if (wtData[0] != (byte)OTerrain.Water)
                {
                    scene.worldContent.DeleteTileTop(zone, gridX, gridY);
                }

                // Delete Tile Cover
                scene.worldContent.DeleteTileCover(zone, gridX, gridY);

                // Handle Special Deletes for Nodes
                if (scene.DeleteNodeIfPresent(gridX, gridY))
                {
                    return;
                }

                // Delete Objects (unless node was already deleted)
                scene.worldContent.DeleteTileObject(zone, gridX, gridY);
            }

            // Right Mouse Button Clicked (Clone Current Tile)
            else if (Cursor.RightMouseState == Cursor.MouseDownState.Clicked)
            {
                scene.CloneTile((byte)Cursor.MiniGridX, (byte)Cursor.MiniGridY);
            }
        }
Exemple #5
0
        public static (byte objectId, byte gridX, byte gridY) LocateNearestNode(WorldContent worldContent, WorldZoneFormat zone, byte gridX, byte gridY, DirCardinal dir, byte range = 5)
        {
            (byte objectId, byte gridX, byte gridY)tuple = (objectId : 0, gridX : 0, gridY : 0);

            // Vertical UP Node Scan - Scans for any nodes above this location.
            if (dir == DirCardinal.Up)
            {
                byte xRange = 1;

                // Do a first scan for vertical line:
                for (int y = gridY - 1; y >= gridY - range; y--)
                {
                    byte objectId = NodeData.GetNodeAtLocation(worldContent, zone, gridX, (byte)y);
                    if (objectId == 0)
                    {
                        continue;
                    }
                    return(objectId, gridX, (byte)y);
                }

                // Do a scan for angled versions:
                for (int y = gridY - 1; y >= gridY - range; y--)
                {
                    for (int x = gridX - xRange; x <= gridX + xRange; x++)
                    {
                        // If a node is located, track it, and make sure it's more centered than any other by looping through X values again.
                        byte objectId = NodeData.GetNodeAtLocation(worldContent, zone, (byte)x, (byte)y);
                        if (objectId == 0)
                        {
                            continue;
                        }

                        // Keep the node closest to center:
                        if (tuple.objectId != 0)
                        {
                            int dist1 = Math.Abs(gridX - tuple.gridX);
                            int dist2 = Math.Abs(gridX - x);
                            if (dist1 < dist2)
                            {
                                continue;
                            }
                        }

                        tuple.objectId = objectId;
                        tuple.gridX    = (byte)x;
                        tuple.gridY    = (byte)y;
                    }

                    xRange++;

                    // If a node is located, end test.
                    if (tuple.objectId > 0)
                    {
                        return(tuple);
                    }
                }
            }

            // Vertical DOWN Node Scan - Scans for any nodes below this location.
            else if (dir == DirCardinal.Down)
            {
                byte xRange = 1;

                // Do a first scan for vertical line:
                for (int y = gridY + 1; y <= gridY + range; y++)
                {
                    byte objectId = NodeData.GetNodeAtLocation(worldContent, zone, gridX, (byte)y);
                    if (objectId == 0)
                    {
                        continue;
                    }
                    return(objectId, gridX, (byte)y);
                }

                // Do a scan for angled versions:
                for (int y = gridY + 1; y <= gridY + range; y++)
                {
                    for (int x = gridX - xRange; x <= gridX + xRange; x++)
                    {
                        // If a node is located, track it, and make sure it's more centered than any other by looping through X values again.
                        byte objectId = NodeData.GetNodeAtLocation(worldContent, zone, (byte)x, (byte)y);
                        if (objectId == 0)
                        {
                            continue;
                        }

                        // Keep the node closest to center:
                        if (tuple.objectId != 0)
                        {
                            int dist1 = Math.Abs(gridX - tuple.gridX);
                            int dist2 = Math.Abs(gridX - x);
                            if (dist1 < dist2)
                            {
                                continue;
                            }
                        }

                        tuple.objectId = objectId;
                        tuple.gridX    = (byte)x;
                        tuple.gridY    = (byte)y;
                    }

                    xRange++;

                    // If a node is located, end test.
                    if (tuple.objectId > 0)
                    {
                        return(tuple);
                    }
                }
            }

            // Horizontal LEFT Node Scan - scans for any nodes left of this location.
            else if (dir == DirCardinal.Left)
            {
                byte yRange = 0;

                // Do a first scan for horizontal line:
                for (int x = gridX - 1; x >= gridX - range; x--)
                {
                    byte objectId = NodeData.GetNodeAtLocation(worldContent, zone, (byte)x, gridY);
                    if (objectId == 0)
                    {
                        continue;
                    }
                    return(objectId, (byte)x, gridY);
                }

                // Do a scan for angled versions:
                for (int x = gridX - 1; x >= gridX - range; x--)
                {
                    for (int y = gridY - yRange; y <= gridY + yRange; y++)
                    {
                        // If a node was located, track it, then make sure it's more centered than any other by looping through Y values again.
                        byte objectId = NodeData.GetNodeAtLocation(worldContent, zone, (byte)x, (byte)y);
                        if (objectId == 0)
                        {
                            continue;
                        }

                        // Keep the node closest to center:
                        if (tuple.objectId != 0)
                        {
                            int dist1 = Math.Abs(gridY - tuple.gridY);
                            int dist2 = Math.Abs(gridY - y);
                            if (dist1 < dist2)
                            {
                                continue;
                            }
                        }

                        tuple.objectId = objectId;
                        tuple.gridX    = (byte)x;
                        tuple.gridY    = (byte)y;
                    }

                    yRange++;

                    // If a node is located, end test.
                    if (tuple.objectId > 0)
                    {
                        return(tuple);
                    }
                }
            }

            // Horizontal RIGHT Node Scan - scans for any nodes right of this location.
            else if (dir == DirCardinal.Right)
            {
                byte yRange = 0;

                // Do a first scan for horizontal line:
                for (int x = gridX + 1; x <= gridX + range; x++)
                {
                    byte objectId = NodeData.GetNodeAtLocation(worldContent, zone, (byte)x, gridY);
                    if (objectId == 0)
                    {
                        continue;
                    }
                    return(objectId, (byte)x, gridY);
                }

                // Do a scan for angled versions:
                for (int x = gridX + 1; x <= gridX + range; x++)
                {
                    for (int y = gridY - yRange; y <= gridY + yRange; y++)
                    {
                        // If a node was located, track it, then make sure it's more centered than any other by looping through Y values again.
                        byte objectId = NodeData.GetNodeAtLocation(worldContent, zone, (byte)x, (byte)y);
                        if (objectId == 0)
                        {
                            continue;
                        }

                        // Keep the node closest to center:
                        if (tuple.objectId != 0)
                        {
                            int dist1 = Math.Abs(gridY - tuple.gridY);
                            int dist2 = Math.Abs(gridY - y);
                            if (dist1 < dist2)
                            {
                                continue;
                            }
                        }

                        tuple.objectId = objectId;
                        tuple.gridX    = (byte)x;
                        tuple.gridY    = (byte)y;
                    }

                    yRange++;

                    // If a node is located, end test.
                    if (tuple.objectId > 0)
                    {
                        return(tuple);
                    }
                }
            }

            // Return No Results
            return(tuple);
        }
Exemple #6
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);
        }
Exemple #7
0
        // Run this method when the character has arrived at a new location:
        public void ArriveAtLocation(byte gridX, byte gridY)
        {
            // Get Current Tile Data
            byte[] wtData = this.worldContent.GetWorldTileData(this.currentZone, gridX, gridY);

            bool isNode    = NodeData.IsObjectANode(wtData[5]);
            bool isAutoDot = NodeData.IsObjectAnAutoTravelDot(wtData[5]);

            // If a node is not located here, something is wrong.
            if (!isNode)
            {
                throw new Exception("Arrived at a destination that was not indicated as a node. That should not be possible.");
            }

            // Update the Campaign's Position
            this.campaign.SetPosition(gridX, gridY, (byte)this.campaign.lastDir);
            this.campaign.SaveCampaign();

            // Check if Node type is Automatic Travel Dot.
            if (isAutoDot)
            {
                // We need to automatically travel. Take the route that wasn't taken last time:
                byte        lastDir = this.campaign.lastDir;
                DirCardinal nextDir = DirCardinal.None;

                // Determine the next intended route:
                var nodeDirs = NodeData.GetDotDirections(wtData[5]);

                if (nodeDirs.up && lastDir != (byte)DirCardinal.Down)
                {
                    nextDir = DirCardinal.Up;
                }
                else if (nodeDirs.down && lastDir != (byte)DirCardinal.Up)
                {
                    nextDir = DirCardinal.Down;
                }
                else if (nodeDirs.right && lastDir != (byte)DirCardinal.Left)
                {
                    nextDir = DirCardinal.Right;
                }
                else if (nodeDirs.left && lastDir != (byte)DirCardinal.Right)
                {
                    nextDir = DirCardinal.Left;
                }

                // Attempt to travel in that direction:
                bool success = this.TryTravel(nextDir);

                // If the Auto-Travel fails, we need to return back.
                if (!success)
                {
                    if (lastDir == (byte)DirCardinal.Left)
                    {
                        this.TryTravel(DirCardinal.Right);
                    }
                    else if (lastDir == (byte)DirCardinal.Right)
                    {
                        this.TryTravel(DirCardinal.Left);
                    }
                    else if (lastDir == (byte)DirCardinal.Up)
                    {
                        this.TryTravel(DirCardinal.Down);
                    }
                    else if (lastDir == (byte)DirCardinal.Down)
                    {
                        this.TryTravel(DirCardinal.Up);
                    }
                }

                return;
            }

            bool isWarp = NodeData.IsObjectAWarp(wtData[5]);

            // Check for Auto-Warps (to new World Zones)
            if (isWarp)
            {
                string curStr      = Coords.MapToInt(gridX, gridY).ToString();
                string origNodeVal = this.currentZone.nodes[curStr];

                // Scan for any warp that has the same warp link:
                for (byte zoneID = 0; zoneID < this.worldData.zones.Count; zoneID++)
                {
                    WorldZoneFormat zone  = this.worldData.zones[zoneID];
                    var             nodes = zone.nodes;

                    foreach (var node in nodes)
                    {
                        // If we have a warp that matches the current warp link ID:
                        if (node.Value == origNodeVal)
                        {
                            var grid = Coords.GetFromInt(int.Parse(node.Key));

                            // Make sure the warp we found isn't referencing itself:
                            if (grid.x == gridX && grid.y == gridY)
                            {
                                continue;
                            }

                            // We located a separate node to link to:
                            this.ActivateWarp(zoneID, (byte)grid.x, (byte)grid.y);
                        }
                    }
                }

                return;
            }

            // Check for Level Presence
            if (NodeData.IsObjectANode(wtData[5], false, false, true))
            {
                _ = DisplayLevelInfo();
            }
        }
Exemple #8
0
        public static void SetWarp()
        {
            byte gridX = (byte)ConsoleTrack.GetArgAsInt();

            ConsoleTrack.possibleTabs = "Example: setWarp 10 10 1";

            // If gridX is assigned:
            if (ConsoleTrack.instructionList.Count >= 2)
            {
                byte gridY = (byte)ConsoleTrack.GetArgAsInt();

                // If gridY is assigned:
                if (ConsoleTrack.instructionList.Count >= 3)
                {
                    // Check if this X, Y grid is a valid warp.
                    WEScene         scene  = (WEScene)Systems.scene;
                    WorldZoneFormat zone   = scene.currentZone;
                    byte[]          wtData = scene.worldContent.GetWorldTileData(zone, gridX, gridY);

                    // If the location is a valid node, we can attempt to add a level ID.
                    if (NodeData.IsObjectAWarp(wtData[5]))
                    {
                        string coordStr = Coords.MapToInt(gridX, gridY).ToString();
                        byte   linkID   = (byte)ConsoleTrack.GetArgAsInt();
                        ConsoleTrack.helpText = "Assign a warp link ID (1-20). Teleports to a warp with the same warp link ID.";

                        if (zone.nodes.ContainsKey(coordStr))
                        {
                            byte getLinkId;
                            byte.TryParse(zone.nodes[coordStr].Replace("_warp", ""), out getLinkId);
                            ConsoleTrack.helpText += " Currently: " + getLinkId;
                        }

                        // If the console was activated:
                        if (ConsoleTrack.activate)
                        {
                            // Error if the values aren't allowed:
                            if (linkID < 1 || linkID > 20)
                            {
                                UIHandler.AddNotification(UIAlertType.Error, "Invalid Warp Link", "Warp Link ID must be set between 1 and 20.", 240);
                                return;
                            }

                            UIHandler.AddNotification(UIAlertType.Success, "Warp Set", "Warp Link ID assigned as " + linkID.ToString() + ".", 240);
                            zone.nodes[coordStr] = "_warp" + linkID.ToString();
                            return;
                        }
                    }

                    // If the location is invalid:
                    else
                    {
                        ConsoleTrack.helpText = "WARNING! There is not a warp at " + gridX.ToString() + ", " + gridY.ToString();
                    }
                }

                // If gridY has not been assigned:
                else
                {
                    ConsoleTrack.helpText = "Assign a link ID to a warp at the specified X, Y coordinate. Enter the Y position.";
                }
            }

            // If gridX has not been assigned:
            else
            {
                ConsoleTrack.helpText = "Assign a link ID to a warp at the specified X, Y coordinate. Enter the X position.";
            }
        }