Oh noes, I'm making something for HB!?!?!? HIT THE DECK! On a serious note; I plan on making a druid routine (mostly for myself) publicly available, so I figured some input from the people who may be using it, would be helpful. Current slated features (yes, I just started working on it in the last 2hrs or so): Full OOC Party/Raid/Solo Buff Support - Done Raid support will allow you to choose whether to use Gift, or Mark of the wild. - Done 'Squishie' party members will not receive the thorns buff - Done (they don't need any more aggro!) Full spec support (Feral/Resto/Oomkin) Feral - Include both DPS for party (staying under threat of the MT), main-tank, and off-tank logic. (Also obviously solo support via Kitty form) DPS/Tanking roles will be chosen automatically. (MT and OT will be a setting you need to switch for fairly obvious reasons) Resto - Solo will rely mainly on feral (resto druids suck when solo'ing) - Full raid/party heal support, with 'clever' logic to handle specific heals. Will include target prioritization, and tank priorities. Lots of stuff will be added for healing. It's one of my favorite things in the game. Oomkin - Well... not much to say really. Oomkin combat is mostly the same regardless of what situation you're in. It will be able to fall back as a healer if required though. Automatic 'Danger' Switching - It will be able to automatically switch forms depending on how high the danger is in the current fight. Danger will be ignored when fighting bosses. Forms to use on each danger level will be configurable. (And the combat will change appropriately.) Full bandage/potion/healing/etc support - Yep. It'll support it all, and do it properly. I may even add item enchants and other such things. Trinket support - They'll be added, just unsure of how I want to handle them at the moment. (Some item parsing will be required to determine the type of trinket, so I can decide when to use it) When the danger is high; RUN AWAY - Yep. It will be able to run as fast as possible in the opposite direction (following the path you took, which is assumed to be 'clear and safe') to exit combat and rest up. Very useful for when you manage to pull a pack of 20 mobs by accident. Full PVP support - The combat logic will change drastically depending on whether your target is a player, or just another mob. The combat will also change based on the targets class, and may (in the far future) be influenced by other party member's classes. (So if you go up against a priest/rogue, we know to cyclone the priest, and feral charge the rogue ASAP. Yet we skip cycloning the warrior ) Other stuff as I come up with it... So yea, if you have any questions/request, let me know. I hope to be finished with at least the feral support by the end of tomorrow or the day after. Then I'll work on oomkin support (since it's the simplest). Then lastly will come the giant healing integration. Note: Healing will take the longest, since I feel it is one of the most important aspects of botting. If you're healer is shitty, then everyone knows. I love watching my bots heal better than I ever could. EDIT: I've setup an SVN so you guys can grab the code as I'm coding it. (Redundancy ftw!) It's also easier for me to maintain changesets and whatnot this way. If you are planning to make edits to the CC, you'll need MSBuildCommunityTasks installed. I use this for some auto-versioning stuff and other minor things. It is coded using VS2010, so if you don't have it, tough shit. I don't plan on using 2k8 any time soon. If you are NOT planning to make any changes (and just want to keep it up to date for builds), simply check out the 'trunk' folder and you'll be all set. The links for both checkouts are below; http://svn.apocdev.com/duridcc/trunk/ (Please copy the entire Durid directory to your Honorbuddy/CustomClasses directory) If the mods have issues with how I'm doing this, I'll happily keep versions uploaded here to make sure there's some form of redundancy, however I'd like to keep this SVN open to the public to allow very fast updates (since only certain files may need updates depending on the changes). If you don't already, I suggest grabbing TortoiseSvn to handle the subversion protocol. (http://tortoisesvn.tigris.org/) How to check out the source: Create a directory named 'Durid' in the CustomClasses folder of your Honorbuddy installation. Right click -> SVN Checkout Enter one of the two URLs from above and hit OK. TortoiseSVN will then download all the required files. How to update to a new revision (version): Right click in your Durid folder (wherever you 'Checked out' to) and click SVN Update. TortoiseSVN will automatically update changed files, and merge them with any changes you may have made. (I suggest reverting your changes!)
Sad note of the day: It took me longer to find out HB doesn't have an 'IsInParty' or 'IsInRaid' type property, than it took to code the danger algorithm.
It's mostly done. Gotta port the API over and rewrite some things. It shouldn't take too long to have most of it working properly.
Can always do it ghetto style... LocalPlayer.RaidMembers should return an empty list if you aren't in a raid, and LocalPlayer.PartyMember1.Guid should return null if you aren't in a party. I swear there used to be an IsInParty/Raid before, but I've also been awake for like 30 hours and am a little crazy at the moment.
I'm using LocalPlayer.PartyMember1GUID to check for parties (1 read) Checking for raids is very inefficient if you're using the RaidMembers list. (HB will check all 40 slots then return the list) Definitely not friendly for CPUs and performance.
You popped in just the right time. Just as I started a Druid. Great to see you here Apoc. And thanks for helping the community also.
I did my first druid with Openbot, sold that one by now. Will start a new one, just for the heck of it, once this is out.
Quick update; I tossed in my own Behavior Tree engine until the devs fix the issue with the one in HB2. (It's not publicly accessible due to some screwy obfuscation settings) Rewrote the OOC buff mechanics (Excluding raid support at the moment, but that's mostly just checking for GotW casts) The code looks like this (most likely a tad buggy, didn't test it yet): Code: using System.Linq; using Durid.BehaviorTree; using Styx; using Styx.WoWInternals.WoWObjects; namespace Durid { public partial class DuridCombat { private static Composite _preCombatBuffBehavior; private static Composite _needPreCombatBuffBehavior; public override bool NeedPreCombatBuffs { get { if (_needPreCombatBuffBehavior == null) { _needPreCombatBuffBehavior = CreatePreCombatBuffComposite(true); } bool ret = false; try { _needPreCombatBuffBehavior.Start(null); if (_needPreCombatBuffBehavior.Tick(null) == RunStatus.Success) { ret = true; } } finally { _needPreCombatBuffBehavior.Stop(null); } return ret; } } public override void PreCombatBuff() { if (_preCombatBuffBehavior == null) { _preCombatBuffBehavior = CreatePreCombatBuffComposite(false); } try { _preCombatBuffBehavior.Start(null); _preCombatBuffBehavior.Tick(null); } finally { _preCombatBuffBehavior.Stop(null); } } /// <summary> /// Creates the behavior for handling pre-combat buffs. (MotW/Thorns/Etc) /// </summary> /// <param name = "isCheck">Whether this composite is going in the NeedPreCombatBuffs property or the actual PreCombatBuff function</param> /// <returns></returns> public Composite CreatePreCombatBuffComposite(bool isCheck) { return new PrioritySelector( // Handle party situations new Decorator(ret => DuridSettings.Instance.BuffParty && IsInParty, new PrioritySelector(delegate { // CONTEXT CHANGE! return (from u in StyxWoW.Me.PartyMembers let motw = Spells.Instance.CanBuff("Mark of the Wild", u) && !u.Buffs.ContainsKey("Gift of the Wild") let thorns = (DuridSettings.Instance.UseThornsOnParty && !DuridUtils.IsSquishy(u) && Spells.Instance.CanBuff("Thorns", u)) where u.IsAlive && u.Distance < 30 && (motw || thorns) select new BuffReqs {Unit = u, Motw = motw, Thorns = thorns}).First(); }, new Decorator(context => context != null, new PrioritySelector( new Decorator(ret => isCheck, new Action(delegate { })), new Action(delegate(object context) { var req = (BuffReqs) context; bool targetLast = !req.Motw || !req.Thorns; if (req.Motw) Spells.Instance.Buff("Mark of the Wild", req.Unit, targetLast); // We can jump back to the old target from thorns. There's nothing left to do here. if (req.Thorns) Spells.Instance.Buff("Thorns", req.Unit, true); }) ) ))), // Solo support CreateBuffCheckComposite(isCheck, "Nature's Grasp", ret => DuridSettings.Instance.UseNaturesGrasp && Spells.Instance.CanBuff("Nature's Grasp")), CreateBuffCheckComposite(isCheck, "Omen of Clarity", ret => DuridSettings.Instance.UseNaturesGrasp && Spells.Instance.CanBuff("Omen of Clarity")), CreateBuffCheckComposite(isCheck, "Thorns", ret => DuridSettings.Instance.UseNaturesGrasp && Spells.Instance.CanBuff("Thorns")), CreateBuffCheckComposite(isCheck, "Mark of the Wild", ret => DuridSettings.Instance.UseMarkOfTheWild && Spells.Instance.CanBuff("Mark of the Wild") && !StyxWoW.Me.Buffs.ContainsKey("Gift of the Wild")) ); } private static Composite CreateBuffCheckComposite(bool isCheck, string name, CanRunDecoratorDelegate canRunFunc) { return new Decorator(canRunFunc, new PrioritySelector( new Decorator(ret => isCheck, new Action(delegate { })), new Action(act => Spells.Instance.Buff(name)))); } #region Nested type: BuffReqs private class BuffReqs { public bool Motw; public bool Thorns; public WoWPlayer Unit; } #endregion } }