What's new
  • Visit Rebornbuddy
  • Visit Panda Profiles
  • Visit LLamamMagic
  • Visit Resources
  • Visit Downloads
  • Visit Portal

[IDEA] New Quest Bot

As bft3912 pointed out; JSON is a double-edged sword. If all you're doing is representing raw data, JSON *may* be more useful. (Also; you specifically included the CDATA stuff to make it seem more complicated than it actually is. Nothing in HB's profile structure requires you to use CDATA)

JSON is not a great idea to use if you're trying to represent a logical flow of actions, as it becomes incredibly difficult to work with, the more complex the "logic" gets. While XML doesn't suffer from that sort of drawback (assuming the XML schema isn't completely ass backwards)


Also, from a programming point of view (.NET programming), XML has far superior support to JSON in client applications. (We're not building a web application, so javascript won't see much use unless we completely abuse it.)
 
I'd do this way (and there may be a simplier solution)
Code:
{
    "While": {
        "Condition": "Me.Class == WoWClass.Hunter && !IsQuestCompleted(25139)",
        "CustomBehavior": [
            {
                "If": "!HasSpell(56641)",
                "File": "ForceSetVendor",
                "DoTrain": true
            },
            {
                "File": "WaitTimer",
                "WaitTime": 1000
            },
            {
                "File": "CastSpellOn",
                "QuestId": 25139,
                "NumOfTimes": 5,
                "SpellId": 56641,
                "MobId": 44820,
                "X": -579.9462,
                "Y": -4240.132,
                "Z": 38.17958
            }
        ],
        "TurnIn": {
            "QuestName": "Steady Shot",
            "QuestId": 25139,
            "TurnInName": "Karranisha",
            "TurnInId": 39214
        }
    }
}

A little compressed version:
Code:
{
    "While": {
        "Condition": "Me.Class == WoWClass.Hunter && !IsQuestCompleted(25139)",
        "CustomBehavior": [
            { "If": "!HasSpell(56641)", "File": "ForceSetVendor", "DoTrain": true },
            { "File": "WaitTimer", "WaitTime": 1000 },
            { "File": "CastSpellOn", "QuestId": 25139, "NumOfTimes": 5, "SpellId": 56641, "MobId": 44820, "X": -579.9462, "Y": -4240.132, "Z": 38.17958 }
        ],
        "TurnIn": { "QuestName": "Steady Shot", "QuestId": 25139, "TurnInName": "Karranisha", "TurnInId": 39214 }
    }
}

EDIT: BTW I wrote "The only alternative to XML I see here is JSON [...]", meaning that if we were to choose a different language, I'd personally choose JSON as it's less taggous and is not more complicated than XML (assuming you're using the right logic), which makes it more human readable than a raw XML file (you may insert an XSL file to view it making it way more human readable). BTW there is actually a JSON serializer in .NET 3.5 (and thus I assume a deserializer too), even if I prefere the external newtonsoft one, which is able to create a JSON object starting from a JSON string (or file), making navigation within JSON just like using an array...

EDIT2: you should use CDATA in case you have to point an NPC or any name containing UTF8 characters (think about non-english servers)
 
Last edited:
I'd do this way (and there may be a simplier solution)
Code:
{
    "While": {
        "Condition": "Me.Class == WoWClass.Hunter && !IsQuestCompleted(25139)",
        "CustomBehavior": [
            {
                "If": "!HasSpell(56641)",
                "File": "ForceSetVendor",
                "DoTrain": true
            },
            {
                "File": "WaitTimer",
                "WaitTime": 1000
            },
            {
                "File": "CastSpellOn",
                "QuestId": 25139,
                "NumOfTimes": 5,
                "SpellId": 56641,
                "MobId": 44820,
                "X": -579.9462,
                "Y": -4240.132,
                "Z": 38.17958
            }
        ],
        "TurnIn": {
            "QuestName": "Steady Shot",
            "QuestId": 25139,
            "TurnInName": "Karranisha",
            "TurnInId": 39214
        }
    }
}

A little compressed version:
Code:
{
    "While": {
        "Condition": "Me.Class == WoWClass.Hunter && !IsQuestCompleted(25139)",
        "CustomBehavior": [
            { "If": "!HasSpell(56641)", "File": "ForceSetVendor", "DoTrain": true },
            { "File": "WaitTimer", "WaitTime": 1000 },
            { "File": "CastSpellOn", "QuestId": 25139, "NumOfTimes": 5, "SpellId": 56641, "MobId": 44820, "X": -579.9462, "Y": -4240.132, "Z": 38.17958 }
        ],
        "TurnIn": { "QuestName": "Steady Shot", "QuestId": 25139, "TurnInName": "Karranisha", "TurnInId": 39214 }
    }
}

EDIT: BTW I wrote "The only alternative to XML I see here is JSON [...]", meaning that if we were to choose a different language, I'd personally choose JSON as it's less taggous and is not more complicated than XML (assuming you're using the right logic), which makes it more human readable than a raw XML file (you may insert an XSL file to view it making it way more human readable). BTW there is actually a JSON serializer in .NET 3.5 (and thus I assume a deserializer too), even if I prefere the external newtonsoft one, which is able to create a JSON object starting from a JSON string (or file), making navigation within JSON just like using an array...

EDIT2: you should use CDATA in case you have to point an NPC or any name containing UTF8 characters (think about non-english servers)

Thats why the "Name" properties are for display only. (All code/profiles are assumed to be english, and do not rely on any localizable factors)


And yes, the JSON deserializer works, but our profile structure doesn't allow it as we provide a lot of optional, and recursive options (which the deserializers have issues processing from my tests).


Please don't bring XSL's into the conversation, as nobody here is talking about them, nor are they a concern.
 
Maybe a profile creator may stop our talking at all. XML is not human friendly, but it's machine friendly, and it's easily handable in programming languages. Even an AJAX web app should be able to do that... I think I'm gonna sketch up something about it.
 
I like the idea. But isnt it better to use the functions of the Questingbot? We need profiles with all Quest (in an IF-TAG​​) in an area. Then you can manually pickup the quest you want and the bot play them (and turn in).
 
I like the idea. But isnt it better to use the functions of the Questingbot? We need profiles with all Quest (in an IF-TAG​​) in an area. Then you can manually pickup the quest you want and the bot play them (and turn in).

Why should I stop my bot every 25 quests to pick up a new set?

I just started a new Orc hunter with this quest bot. He's automatically doing all nearby quests with an empty profile. He just collected 3/6 Cactus Apples, then killed a bunch of Scorpid for their tails, then picked some more apples and then talked to Hana'zua to pick up that quest just because it was nearby. All of this is without any explicit quest order or IDs or anything.

There WILL have to be some custom code at some point (Lazy Peons for example), but that's like creating a profile that only contains the 'weird' quests and having it do everything.

I think what you're getting at is a problem with Profiles... they need everything done in a particular order and throw up if you manually do something out of order or the game client changes. Behavior Trees are supposed to fix this, but the Profile puts us right back in that situation and no amount of If/Then/While wrapping is going to change the fact that the QuestOrder tag is inherently a sequential order of steps.

The idea behind the new quest bot is to move the questing behavior from a sequential series of steps back to a very fluid Behavior Tree. The orc hunter I created couldn't figure out how to do the Steady Shot quest (partially because the mob ID in the quest database is wrong). Instead of failing and stopping the 'profile' it simply skipped that quest and kept on doing other stuff.
 
Alright, I take it some of you haven't been here for very long.

The original quest bot automatically picked up quests nearby (and handed them in). This turned out to be a giant pain to deal with, since it wasn't nearly optimal after level 20ish (when you have quite a few choices of where to go).


If any of you remember; we used to have "ForcedQuestList" and stuff like that. (The functionality has been removed in favor of something more "easily" worked with. I.e. quest orders)


You cannot rely on Blizzard's in-game quest helper, nor their game object/unit flags determining the quest viability. (We have a few hard-coded workarounds to a few quests to resolve the issue)


I'm nearly done with my editor's rewrite and quest support. However, since we provide "custom behaviors", the code to handle such is a bit complex (and right now, quite buggy). So that should solve any problems with people somehow not being able to understand XML.


At any rate; you won't find any "easy" way to deal with profiles without them becoming complex. (No matter what markup language you decide to use. XML just has the most support, and is easiest to work with as a 3rd party. Not many people know javascript/JSON, but nearly everyone has at least some form of XML knowledge [Remember; HTML *is* XML when you think about it... in an odd sort of way at least])
 
Other ideas:

1. Gather hotspots directly from the game (i.e. from the map) instead of bloating useless ones in the quests profile (can be overridden in any case if only you put one or more in it)

2. Use nodes when possible (actually this works 1/10 of the times (no idea why) and the bot turns back after 1 second or two, i.e. non-responsive (un-optimized behavior tree actions?))

3. Avoid aggroing lots of mobs just to fall when one of them knock you out of the mount => death when dense-populated, also the "flee" behavior is plugin-dull, this means that the bot will run untill out of combat, preventing any plugin to override this action.

4. Support for quest scripts way slimmer and easy in form of simple TreeSharp Action, parameters passed as a single string, i.e.
PHP:
<CustomBehavior Name="MyCustomBehaviorAction" Params="My arg one|My arg 2|3|true" />
Eventually parsed, making scripts trivial
PHP:
namespace QuestBotNamespace {
    public class MyCustomBehaviorAction : Action {
        protected override RunStatus Run(object context) {
            List<string> paramList = QuestBotObjectAwsomeHandler.GetParameters();
            ...
            return RunStatus.Success;
        }
    }
}

I know specially the script part would be a major lifting of the bot, this is why I doubt it will be done that way, but it'd be interesting to do it though ^^

By the way, I've started building it (and no, not for better botting, but for learning :) )... for now it fights using the CC, it does the corpse run, it rests and it's even able to send items via mail and repair :)

that would be a bad idea, how many times have you looked at your map, been standing on the spot or in the area the map says according to their quest helper and there is nothing in sight? I have plenty of times just to discover it was wrong. I do like the idea of what apoc said as his new feature list and doing those after major bug fixes.
 
Meh, if they switched coding language I'd most likely not CBA to learn it and it would just be a major pain in my ass, for every profile writer (that's a dangerous assumption). I didn't have ANY XML knowledge at all when I started writing profiles, I hadn't worked with code AT ALL in the past. Now it's easy as something something. So XML can't be that hard to understand nor learn.
 
Back
Top