[Help] Improved waypoint mgmt menu

Shout-Out

User Tag List

Results 1 to 6 of 6
  1. #1
    Learner's Avatar Member
    Reputation
    1
    Join Date
    May 2007
    Posts
    5
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [Help] Improved waypoint mgmt

    First, let me thank Apoc for his helpful (and humbling) informational posts - the waypoint one has been particularly relevant for what I am working on atm.

    I am a c# n00b, but very much enjoy learning & playing around with new technology stuff. My current project is to build a full-fledged bot for use in Aion - it is a pretty far-reaching bot, at least at the current high-level design stage This is not a commercial effort, and really is just for me, guildies & friends if they are interested.

    The first part of the bot that I have actually tackled is the path creation function. The app if fully functional with several key features...

    Path Header Items (apply to all waypoints):
    Path name
    Path type (loop versus back/forth)
    Ignore named mob(s) option
    Min mob lvl to engage option
    Max mob lvl to engage option

    Path Body Items:
    Add waypoint
    Add pause waypoint
    Add gather waypoint (for resource gathering)
    Add ignore all waypoint (true/false)

    Other key functionality includes
    Step(s) delete
    Clear all
    Record
    Save path
    Load path
    A continuously updated path drawn in a picturebox, with start and end point shown

    Here is a screeny of it:


    Yeah, it may be a little over the top, but it has been great for me to work on in order learn all the various things I can do with C# and .NET and forms and... yeah.

    Now, I was pretty proud of it... until I read the much improved way to manage waypoints from Apoc.

    Here is my main class as a reference:
    Code:
        public class PathEntry
        {
            // Elements to put it all in
            // This field is used for both headers and body elements
            public string strQualifier;
    
            // Path header elements
            public string strName;
            public string strType;
            public ArrayList arlNamedIgnore;
            public short shoMinMobLvl;
            public short shoMaxMobLvl;
    
            // Path body elements
            public double dblX;
            public double dblY;
            public int intDelay;
            public bool isIgnoreAll;
    
            // Constructor
            public PathEntry()
            {
                this.strQualifier = "";
                this.strName = "";
                this.strType = "";
                this.arlNamedIgnore = new ArrayList();
                this.shoMaxMobLvl = (short)100;
                this.shoMinMobLvl = (short)0;
                this.dblX = (double)0;
                this.dblY = (double)0;
                this.intDelay = 0;
                this.isIgnoreAll = false;
            }
    
            // Here we parse the PathEntry text as appropriate - am I using "this." appropriately??
            public void ParseIt(string str)
            {
                char[] delimiter = {';'};
                string[] entries = str.Split(delimiter);
                this.strQualifier = entries[0]; // The first Field[0] will ALWAYS have the Qualifier
                switch (this.strQualifier)
                {
                    case "Name":
                        this.strName = entries[1];
                        break;
                    case "Cycle":
                        this.strType = entries[1];
                        break;
                    case "IgnoreNamed":
                        this.arlNamedIgnore.Add(entries[1]);
                        break;
                    case "MinMobLvl":
                        this.shoMinMobLvl = Convert.ToInt16(entries[1]);
                        break;
                    case "MaxMobLvl":
                        this.shoMaxMobLvl = Convert.ToInt16(entries[1]);
                        break;
                    case "Waypoint":
                        this.dblX = Convert.ToDouble(entries[1]);
                        this.dblY = Convert.ToDouble(entries[2]);
                        break;
                    case "Pause":
                        this.intDelay = Convert.ToInt32(entries[1]);
                        break;
                    case "IgnoreAll":
                        this.isIgnoreAll = Convert.ToBoolean(entries[1]);
                        break;
                    case "Gather":
                        //nothing needs to be done here
                        break;
                }
            }
        }


    So, I have a few pointed questions, and am hoping someone can help me improve my underlying coding practices (I really would like to move towards a more sophisticated / flexible solution):

    Q1. Given that my path definition allows more than just simple waypoints (e.g. gathering, pauses, ignore all mobs option, etc.), how can I improve my class definition to more closely resemble what Apoc had in his thread?

    Q2. Given that I also have header type entries in my path definition (and these become very important later in the actual bot mgmt), can I still use XMLElement stuff to manage & store it all? If so, I would very much appreciate any insights.

    As a first post on these boards, I realize it may be a little long... but I wanted to actually have something of substance to contribute before posting.

    [Help] Improved waypoint mgmt
  2. #2
    abuckau907's Avatar Active Member
    Reputation
    49
    Join Date
    May 2009
    Posts
    225
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Silly Question, but, so what if Mob.Level > MaxLevelMobToAttack : do you just ignore the mob? What if it's on the path..you just ignore it and run past it? (And possibly take aggro?)

    Personally I have a class called "SETTINGS" to store things like this and don't store any info for each pp except for x,y,z -->
    Settings.MobMaxLevelToAttack
    Settings.MobMinLevelToAttack
    Settings.ShouldISkin
    Settings.MinHealthToSit, etc etc (basically anything I ask a user, I store in Settings.)

    Code:
    Sub Combat.RunToPoint(Byval pp as wowPoint, Byval isAlive as bool, Byval killAll as bool, Byval stopAtPoint as Bool)
    ...
    End Sub
    maybe you could describe in more detail exactly how you want your path files to work...the end result you expect?

    I know it's a lot less...specific, but I do it this way...

    Path.RunThisPath(Byval direction as pathDirection, Byval isAlive as Bool, Byval killAll as bool)
    then, lets say you have 2 paths:
    MainPath (used for hunting, looting etc) then..
    VendorPath (used to run from main path, to vendor, and then back again)

    Code:
    Public Class GPS
    Public Sub RunMainPath()
    MainPath.RunThisPath(direction.ToEnd, True, True)
    ' Alive = True (ie. watch for attackers) KillAll = True (ie. kill mobs in close range)
    End Sub
    
    Public Sub RunToVendor
    VendorPath.RunThisPath(direction.ToEnd, true, false)
    alive = true (watch for attackers) killall = false (dont attack unless being attacked)
    End Sub
    
    Public sub RunFromVendor
    VendorPath.RunThisPath(direction.ToBeginning, true, false)
    End Sub
    Last edited by abuckau907; 01-16-2010 at 10:02 PM.

  3. #3
    Mirror's Avatar Contributor
    Reputation
    259
    Join Date
    Nov 2006
    Posts
    2,602
    Thanks G/R
    0/0
    Trade Feedback
    2 (100%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The waypoints make a picture of a *****, in-complete I might add.

    But on-topic: Great program and thank you for posting the main class, that was good looking at for me.
    THIS SIGNATURE IS IN VIALOATION OF SITE RULES, PLEASE FIX ME!
    -Fault

  4. #4
    Learner's Avatar Member
    Reputation
    1
    Join Date
    May 2007
    Posts
    5
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I am in the middle of revamping this quite a bit - through careful study of Apoc's post... will definitely post it here when I get it done (for some additional critique). Hopefully, I am not getting in too deep. Regardless, having a good time doing it, and definitely think I am learning a lot.

    As far as the main objective of the body elements, and the reason I have multiple types of possible body elements, is to give max flexibility for my path definition. In Aion, there is no skinning, but as in WoW, there are lots of gathering nodes - something you definitely want to have in the path as an option. For the ignore all option, this is a great option to have during certain points in a path. For example, perhaps there is a stretch where there are mobs you plan to just run through because of their BAF behavior, or because they are non-aggro and you just don't wanna deal with them.

    The header elements (named and lvl stuff) are really good to have with the path overall for max flexibility and efficiency. There are sometimes low lvl mobs you just don't want to engage - either they are pathing pains, or too low a lvl to worry about. Also, sometimes you just wanna gather... And finally, if you are fighting borderline too tough mobs for your level, being able to refine that further can mean the diff between success and too many deaths.

    Finally, being able to save ALL these things with the path (and embedded at key waypoints), gives me awesome options - sharing really good paths with a guildie, or saving for an alt, etc.

    Thanks for taking the time to look at what I have so far... Your vendor path has DEFINITELY given me another idea too, which will prolly get incorporated into specific points on my path :P Anyhoo, once I get this part nailed and tested, having the option to add these things at whatever level (waypoint, path, overall) will be nice to have IMO.


    NOTE: because I have these path "header" and "body" entries, my first refinement is actually to split these into TWO classes - again, will post them when I have it working. Oh, and these are both being developed trying to leverage XML stuff (my focus du jour for learning).

  5. #5
    Apoc's Avatar Angry Penguin
    Reputation
    1388
    Join Date
    Jan 2008
    Posts
    2,750
    Thanks G/R
    0/13
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    First things first; I suggest you use XML.

    Also; for your 'waypoint' pieces, you can simply create a struct/class that holds information about each specific waypoint, and then a 'path' class that holds all the waypoints (in order).

    Eg; something like so (excuse the formatting, writing in the browser):

    Code:
    class Waypoint
    {
        public WaypointFlags Flags;
        public Point Location;    
    }
    
    [Flags]
    enum WaypointFlags : uint
    {
        Move = 0x1,
        Gather = 0x2,
        IgnoreMobsStart = 0x4,
        IgnoreMobsEnd = 0x8,
    }
    Etc.

    It's actually fairly simple. Just split it up into logical classes, and make your life easier.

  6. #6
    Learner's Avatar Member
    Reputation
    1
    Join Date
    May 2007
    Posts
    5
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Great idea Apoc... let me share my revamp of the pathbody stuff (still doing pathheader - was outta town for a week).

    Obviously, this does not reflect your above suggestion, but it HEAVILY leverages what your other post about pathing covers, as you will see. I have yet to test this, so not sure if it works yet. That said, I feel pretty good about understanding the concepts.

    As an aside, given that I really do have two very distinct entries in my path (headers with no waypoints that are really enabling the setting of flags later, and then the body elements with waypoints), doesn't it make sense to actually set up two classes to manage it??

    Code:
    /*
     * This struct is used to track all of the body entries for
     * the path. The PathHeader class is used for the header
     * entries.
     * 
     * Command words that indicate the entry is a body row are:
     *      Goto
     *      PauseAt
     *      GatherAt
     *      IgnoreAll
     *
    */
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;
    using System.Xml.Linq;
    using System.Windows.Forms;
    using System.IO;
    
    namespace ROXBotD1
    {
        public struct PathBody : IEquatable<PathBody>
        {
            public string COMMAND { get; set; }
            public float X { get; set; }
            public float Y { get; set; }
            public string COMPARAM { get; set; }
            
            public PathBody(string command, float x, float y, string comparam):this()
            {
                COMMAND = command;
                X = x;
                Y = y;
                COMPARAM = comparam;
            }
    
            public PathBody(XElement xml)
                : this(Convert.ToString(xml.Name),
                        Convert.ToSingle(xml.Attribute("X").Value), 
                        Convert.ToSingle(xml.Attribute("Y").Value),
                        Convert.ToString(xml.Attribute("Param").Value))
            {}
    
            public double Distance(PathBody to)
            {
                return Distance(to.X, to.Y);
            }
    
            public double Distance(float toX, float toY)
            {
                float dX = X - toX;
                float dY = Y - toY;
                return Math.Sqrt(dX * dX + dY * dY);
            }
    
            public XElement GetXml()
            {
                return new XElement(COMMAND, new XAttribute("X", X), new XAttribute("Y", Y), new XAttribute("Param", COMPARAM));
            }
    
            public static List<PathBody> LoadObject(ListBox lbname)
            {
                var ret = new List<PathBody>();
                XElement lbxml = XElement.Parse("");
                for (int i = 0; i < lbname.Items.Count; i++)
                {
                    lbxml.AddAfterSelf(XElement.Parse(lbname.Items[i].ToString()));
                }
                foreach (XElement pb in lbxml.Elements())
                {
                    if (pb.Name == "Goto" || pb.Name == "PauseAt" || pb.Name == "GatherAt" || pb.Name == "IgnoreAll")
                        ret.Add(new PathBody(pb));
                }
                return ret;
            }
            public static List<PathBody> LoadFile(string filePath)
            {
                if (!File.Exists(filePath))
                {
                    throw new FileNotFoundException("Could not find the specified file!", filePath);
                }
    
                var ret = new List<PathBody>();
                XElement file = XElement.Load(filePath);
                foreach (XElement pb in file.Elements())
                {
                    if (pb.Name == "Goto" || pb.Name == "PauseAt" || pb.Name == "GatherAt" || pb.Name == "IgnoreAll")
                        ret.Add(new PathBody(pb));
                }
                return ret;
            }
    
    
            #region IEquatable<PathBody> Members
    
            public bool Equals(PathBody other)
            {
                return other.COMMAND == COMMAND && other.X == X && other.Y == Y && other.COMPARAM == COMPARAM;
            }
    
            public override bool Equals(object obj)
            {
                if (ReferenceEquals(null, obj))
                {
                    return false;
                }
                if (obj.GetType() != typeof(PathBody))
                {
                    return false;
                }
                return Equals((PathBody)obj);
            }
    
            public override int GetHashCode()
            {
                unchecked
                {
                    int result = COMMAND.ToString().GetHashCode();
                    result = (result * 397) ^ X.GetHashCode();
                    result = (result * 397) ^ Y.GetHashCode();
                    result = (result * 397) ^ COMPARAM.ToString().GetHashCode();
                    return result;
                }
            }
    
            public static bool operator ==(PathBody left, PathBody right)
            {
                return left.Equals(right);
            }
    
            public static bool operator !=(PathBody left, PathBody right)
            {
                return !left.Equals(right);
            }
    
            #endregion
    
            
        }
    }

Similar Threads

  1. [Help] Help with Waypoint Skinning
    By Sheafie in forum WoW EMU Questions & Requests
    Replies: 0
    Last Post: 02-12-2010, 12:14 PM
  2. [HELP] Skipping waypoint that are on South-East
    By Mr.Zunz in forum WoW Memory Editing
    Replies: 7
    Last Post: 07-05-2009, 01:05 PM
  3. [Help] Waypoints starts to bug
    By Power of Illuminati in forum World of Warcraft Emulator Servers
    Replies: 4
    Last Post: 05-29-2008, 04:06 PM
  4. [Help] Waypoints
    By Kasilopana in forum World of Warcraft Emulator Servers
    Replies: 0
    Last Post: 01-09-2008, 08:01 PM
All times are GMT -5. The time now is 12:46 PM. Powered by vBulletin® Version 4.2.3
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Google Authenticator verification provided by Two-Factor Authentication (Free) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search