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

FelMaster - static PVE destruction CC based on SimCraft's script

cowdude

Active Member
Joined
Feb 17, 2010
Messages
337
Reaction score
27
Hi guys,

8.22.2011: New version! Read end of this post for details.

Been a long time I didn't post anything here. Anyway, I'd like to share with you a quite simple proof of concept here.

The goal: beat Simcraft average DPS in game on a training dummy while putting all the nasty, monkey-spaghetti-WTF code in a backend class, and hopefully ending up with a very simple and readable main source code.

For those of you who don't know about Simcraft, this is a quite advanced tool that simulates boss fights according to your template, gear, glyphs, etc.


Results: Well, I was quite disappointed to output roughly 1500 dps less than Simcraft numbers first. I eventually removed all potions/elixirs routines from the simulation and... I'm now outputting more than 16.5k DPS, whereas Simcraft is around 15.5k. Great.

I guess I'll get down to 15-15.5k if I let the combat bot running for two days, resulting in getting OOM quite often. Anyway, that's fine.

Simcraft's destruction actions priority list looks like this:
Code:
actions=flask,type=draconic_mind
actions+=/food,type=seafood_magnifique_feast
actions+=/fel_armor
actions+=/summon_imp
actions+=/dark_intent
actions+=/snapshot_stats
actions+=/blood_fury
actions+=/volcanic_potion,if=buff.bloodlust.react|!in_combat|target.health_pct<=20
actions+=/demon_soul
actions+=/soulburn,if=buff.bloodlust.down
actions+=/soul_fire,if=buff.soulburn.up
actions+=/fel_flame,if=buff.tier11_4pc_caster.react&dot.immolate.remains<8
actions+=/immolate,if=(remains<cast_time+gcd|!ticking)&target.time_to_die>=4&miss_react
actions+=/conflagrate
actions+=/bane_of_doom,if=!ticking&target.time_to_die>=15&miss_react
actions+=/corruption,if=(!ticking|dot.corruption.remains<tick_time)&miss_react
actions+=/shadowflame
actions+=/soul_fire,if=buff.empowered_imp.react&buff.empowered_imp.remains<(buff.improved_soul_fire.remains+action.soul_fire.travel_time)
actions+=/chaos_bolt
actions+=/summon_doomguard
actions+=/soul_fire,if=buff.improved_soul_fire.remains<(cast_time+travel_time+action.incinerate.cast_time+gcd)&!in_flight
actions+=/shadowburn
actions+=/incinerate
actions+=/life_tap,moving=1,if=mana_pct<80&mana_pct<target.health_pct
actions+=/fel_flame,moving=1
actions+=/life_tap

Compare it to my combat behavior tree:
Code:
/**********************************************
                     * Small documentation:
                     **********************************************
                     * CastBuff:            casts a buff on player if we don't already have it
                     * CastSpell:           basic casting whenever the spell is ready
                     * CastDebuff:          cast spell if its debuff has faded on target. Useful for handling DoTs
                     * CastOffensiveBuff:   cast a spell that buffs the player if its buff is going to expire or is expired. 
                     *                      Used for Destruction Soul Fire buff.
                     * 
                     * 1st arg is spell name
                     * 2nd arg (a => ...) is an additional condition to cast the given spell. "a => true" means "no additional condition"
                     * last arg is a string to print each time this spell is going to be cast
                     */
                        _combat = new PrioritySelector(
                        SC.CastBuff("Fel Armor", a => true, "Fel Armor"),
                        SC.CastSpell("Summon Imp", a => SimCraftBase.Me.Pet == null || SimCraftBase.Me.Pet.Dead, "Summon new imp"),
                        SC.CastSpell("Demon Soul", a => !SimCraftBase.Me.IsMoving, "Demon Soul while not moving"),
                        SC.CastSpell("Soulburn", a => true, "Soulburn"),
                        SC.CastSpell("Soul Fire", a => SC.PlayerHasBuff("Soulburn"), "SF on soulburn"),
                        SC.CastDebuff("Immolate", a => true, "Immolate"),
                        SC.CastSpell("Conflagrate", a => SC.TargetHasDebuff("Immolate"), "Conflagrate"),
                        SC.CastDebuff("Bane of Doom", a => SimCraftBase.Me.CurrentTarget.CurrentHealth > 100000 || SimCraftBase.Me.CurrentTarget.MaxHealth == 1, "Bane of Doom"),
                        SC.CastDebuff("Corruption", a => true, "Corruption"),
                        SC.CastSpell("Soul Fire", a => SC.PlayerHasBuff("Empowered Imp"), "SF on imp buff"),
                        SC.CastSpell("Chaos Bolt", a => true, "Chaos Bolt"),
                        SC.CastSpell("Summon Doomguard", a => true, "Doomguard"),
                        SC.CastOffensiveBuff("Soul Fire", "Improved Soul Fire", SC.CastTime("Incinerate") + 0.5, "SF to refresh buff... (Incinerate+GCD=" + (SC.CastTime("Incinerate") + 0.5) + ")"),
                        SC.CastSpell("Shadowburn", a => SimCraftBase.Me.CurrentTarget.HealthPercent < 20, "Shadowburn"),
                        SC.CastSpell("Incinerate", a => SC.TargetHasDebuff("Immolate"), "Incinerate"),
                        SC.CastSpell("Life Tap", a => SimCraftBase.Me.IsMoving && SimCraftBase.Me.HealthPercent > SimCraftBase.Me.ManaPercent && SimCraftBase.Me.ManaPercent < 80, "Life tap while moving"),
                        SC.CastSpell("Fel Flame", a => SimCraftBase.Me.IsMoving, "Fel flame while moving"),
                        //can only be cast if every other actions failed (=OOM)
                        SC.CastSpell("Life Tap", a => true, "Life tap - default action")
                    );

I had to rewrite most of the SpellManager methods to do stuff on my own in order to use WoW's casting buffer (you can enable it somwhere in your game settings). This means that the CC loves to spam spells in order to keep casting as fast as possible, resulting in a quite surprising boost of DPS.

The only downside is that this CC relies a LOT on Lua and Lua events to keep tracking cooldowns and cast spells. Might not be the most efficient way to run 20 bots on one machine, but at least it gives kick-ass reactivity.

This CC should only be used while running the Combat/Heal bot as it doesn't care about moving, checking range nor LoS.


Latest updates
8/22/2011
Removed SC.UseItem
Added SC.UseTrinket
Added SC.Trinkets (list of equipped trinkets id's)
Now supports moving, facing, LoS and pull on demand if you enable it on the class settings popup, allowing you to run it on any kind of HB botbases.
Added SC.CastConicSpell (shadowflame, cone of cold, etc.). It will take care of distance & target facing delta checks.
Added Min/Max combat range for any rotation. Default 1y and 40y (caster)
Warlock: The demonology 'pet swap' rotation will now check distance to target before casting shadowflame and immolation aura

8/20/2011Loads of new composites to implement your rotation
Fixed channeled spells being cast over and over
Improved a lot buff/debuff handling
Handling spell misses/dodge/parry/etc.
Implemented the 'demonology 2.0' rotation (fucking full mastery specced with moonwell chalice) (hell yeah).
Completly rewrote the main structure s.t. FelMaster is now an 'all in one' CC. Feel free to attach your custom rotations here and I'll add them to the project.
Should now run better on non-english clients (localizing spell names, buffs/debuffs, auras).
Loads of minor updates/fixes here and there...
Removed the 'life tap - default action'... it should do nothing if no spells are available, not pre-casting life tap.


Ch.eat sheet for devs
http://www.thebuddyforum.com/honorb...n-cc-based-simcrafts-script-7.html#post344029


Quick install guide
Extract the zip file content into your CustomClass folder.
(re)start HB
Select FelMaster as your CC.
Open the class settings. Select the desired class rotation.
Start your combat bot, select a target and engage combat.

This thread is deprecated!
Please download latest releases and drop your comments/questions on this thread:
http://www.thebuddyforum.com/honorb...ing-cc-lazyraider-combat-bots.html#post344038
 

Attachments

Last edited:
Holy fucking shit dude....after i got it running im doing like 16k on dummy ....any plans on writing other classes like this? PM me and Ill gladly donate to develop them =)

Also an Affliction one like this would be amazing in a raid...it should be averaging out to be a higher dps spec....just to put another bug in your ear =P
 
Last edited:
Great CC, doning some awesome DPS on the dummies!

P.S. Do you have any plans to update Prince of Darkness? Mainly the PvP part as there isn't a good PvP CC for warlocks out there for months!
 
Really nice, I proposed this on Singular topic but no one seemed to care about it, its nice that you did this :)
 
So what would it take to do this for other classes?
 
You can basically use this with LazyRaider in heriocs and raids correct?
 
it really casts fast dont know how you did it great job
btw i made an affliction version if anyone wants it
 

Attachments

The only problem i found was that my character keeps spamming life tap. Its doing it until i am fizzled, and even then it keeps on doing it.

Edit: Also it seems that it doesnt cast curse of elements, which is an absolute must
 
Last edited:
Hi Cowdude,

i think what you miss when i look at your code is the check if the debuff on the target is from you.

Without checking this, everything is fine on a test dummy but sucks when you have another warlock in your group.
Since you wouldn't cast debuffs on the target when the other wl has allready done. This gimps your dps alot.


Or did i missed a check?!

Didn't tested your work, but maybe adept it to my DK keybot base.

Kind regards,

Spud
 
Hi,

It does check debuffs applied by you only. Have a look at the wow lua api about it.

Yes, it lacks some buffs (CoE, Dark Intent, Bane of Havok, potions, etc.); this is more a proof of concept than a usable CC.

I'm more likely to think about adding some moving logic to it than adding new specs/classes support yet... I'd love to create a human-looking PvP class based on this.

And yes, I suppose you can use it with LazyRaider etc. I played with it during a ZG run on combat/heal bot and targeting mobs by myself. Looking quite cool.

About AoE dmg: you should not even think about using these spells if you're destruction specced; they truly suck.
 
Some minor tweaks and instance/raid wise this could be better than a human casting lol...once again awesome job Cowdude
 
Yeah, then sry!

Could you post me the part where you do it, just for learning purpose.

thank you!
 
Cowdude is it ok to borrow your amazing work to a MM Hunter rotation, and publishing it with ofc a a thx to you info?
 
Yeah, then sry!

Could you post me the part where you do it, just for learning purpose.

thank you!

public double TargetDebuffTimeLeft(string name)
{
try
{
var lua = string.Format("local x=select(7, UnitDebuff(\"target\", \"{0}\", nil, 'PLAYER')); if x==nil then return 0 else return x-GetTime() end", Lua.Escape(name));
var t = double.Parse(Lua.GetReturnValues(lua)[0]);
return t;
}
catch
{
Log("Lua failed in TargetAuraTimeLeft");
return 999999;
}
}


Sure Mazzyr, do as you wish.
 
Cowdude is it ok to borrow your amazing work to a MM Hunter rotation, and publishing it with ofc a a thx to you info?

Sir I will love you forever when you get this posted =)
 
You should definitively do a arcane/fire mage CC like this, would be awesome.
 
gave this a go today, it kept spamming life tap while fighting stuff, the healer said something to me about it. asked why i was trying to kill myself during fights.
 
I wish you could clean your PM's abit, I'm trying to add a Retri DPS rotation. But i'm stuck on how it will detect the remaining secs on a buff. If you could help me, that'd be great :D

Code:
//cast a spell if target's debuff X will fade in less than 2s
SC.CastSpell("something", a => SC.TargetDebuffTimeLeft("the debuff name") < 2, "something"),

//keep a debuff on target (spell name must be the same as debuff name)
SC.CastDebuff("some debuff", a => true, "some debuff"),

//cast a spell if player's buff X will fade in more than 2s
SC.CastSpell("something", a => SC.PlayerBuffTimeLeft("the buff name") > 2, "something"),

//cast a offensive spell that will buff player
//in this case, it will cast it if buff X will fade in less than 2s on player
SC.CastOffensiveBuff("something", "the buff name", 2, "something"),

CastDebuff and CastOffensiveBuff are shortcuts relying on CastSpell + buff/debuff checks, making the code a bit easier to read.


I never had any life tap spam issue with that, sorry. I used it on a full BoT 10N run, worked great. I had to manually cast Bane of Havoc, trinket and CoE on bosses though.
 
Mine did the life tap thing too. Other than that it was great. Was doing 1k less than I can do by hand. Pretty impressive.
 
Back
Top