• Visit Rebornbuddy
  • [Official] Default Combat Routine

    Discussion in 'Combat Routines' started by Apoc, Dec 11, 2014.

    1. Apoc

      Apoc Moderator Staff Member Moderator

      Joined:
      Jan 16, 2010
      Messages:
      2,790
      Likes Received:
      94
      Trophy Points:
      48
      So, there was a massive rewrite of the combat routine that is patched with Wildbuddy.

      This thread is for discussions, bug reports, and feature requests. Please note that I may not always respond to every message left here. If it is a bug report, please follow the standard bug reporting guidelines.

      Please include the following information in your bug reports:

      Please note, that reports without log files, may (and probably will) be ignored.
       
    2. HeroXx

      HeroXx New Member

      Joined:
      Jan 15, 2010
      Messages:
      106
      Likes Received:
      0
      Trophy Points:
      0
      Just ran it quickly on my Stalker and the difference is like night and day. I'll give it a good run through on all the classes but so far it looks great, good work.

      Edit: just got an exception on the stalker:

      Code:
      Unhandled exception!Buddy.Coroutines.CoroutineUnhandledException: Exception was thrown by coroutine ---> System.Exception: Only part of a ReadProcessMemory or WriteProcessMemory request was completed, at addr: 0, Size: 38C0
         at GreyMagic.ExternalProcessMemory.ReadByteBuffer(IntPtr addr, Void* buffer, Int32 count)
         at GreyMagic.MemoryBase.Read[T](IntPtr addr)
         at Buddy.Wildstar.Engine.PerCachedValue`1.get_Value()
         at Buddy.Wildstar.Game.Actors.Actor.get_Guid()
         at Buddy.DefaultRoutine.Targeting.Weigh(Actor actor) in d:\Jamie\User\Documents\Wildbuddy\Routines\Default Routine\Targeting.cs:line 137
         at System.Linq.EnumerableSorter`2.ComputeKeys(TElement[] elements, Int32 count)
         at System.Linq.EnumerableSorter`1.Sort(TElement[] elements, Int32 count)
         at System.Linq.OrderedEnumerable`1.<GetEnumerator>d__0.MoveNext()
         at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
         at Buddy.DefaultRoutine.Targeting.<.cctor>b__0() in d:\Jamie\User\Documents\Wildbuddy\Routines\Default Routine\Targeting.cs:line 19
         at Buddy.Wildstar.Engine.PerCachedValue`1.get_Value()
         at Buddy.DefaultRoutine.Targeting.get_BestTarget() in d:\Jamie\User\Documents\Wildbuddy\Routines\Default Routine\Targeting.cs:line 102
         at Buddy.DefaultRoutine.DefaultRoutine.<Combat>d__0.MoveNext() in d:\Jamie\User\Documents\Wildbuddy\Routines\Default Routine\DefaultRoutine.cs:line 101
      --- End of stack trace from previous location where exception was thrown ---
         at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
         at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
         at Buddy.Wildstar.BotCommon.CombatRoutineBase.fN_=Bn-)3P-gKO69D\[!}HYPK.()
      --- End of stack trace from previous location where exception was thrown ---
         at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
         at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
         at Buddy.Coroutines.Coroutine.‬**​
​**​*​*‬‬‎**‬


      
      Log attached. It's a slightly odd one to reproduce as I've just started running it again fine and it hasn't thrown an exception, there was nothing special about the fight that could help you reproduce it from what I can tell. I'll keep an eye out if something becomes a bit more apparent.
       

      Attached Files:

      Last edited: Dec 11, 2014
    3. Apoc

      Apoc Moderator Staff Member Moderator

      Joined:
      Jan 16, 2010
      Messages:
      2,790
      Likes Received:
      94
      Trophy Points:
      48
      I've noticed it doing that, but it should just continue afterwards. (It happens the frame of a mob death usually, or a mob going out of object manager range)

      Did it not continue afterwards?
       
    4. Angully

      Angully Member

      Joined:
      Sep 19, 2010
      Messages:
      764
      Likes Received:
      1
      Trophy Points:
      18
      Stalker is working pretty flawlessly also the occurrence of overrunning targets has been reduced however it still happens occasionally.
       
    5. HeroXx

      HeroXx New Member

      Joined:
      Jan 15, 2010
      Messages:
      106
      Likes Received:
      0
      Trophy Points:
      0
      It seems as if the class can fight (facing the right direction and close enough) it'll continue after this error, if not it'll just stand still spamming the exception.
       
    6. Apoc

      Apoc Moderator Staff Member Moderator

      Joined:
      Jan 16, 2010
      Messages:
      2,790
      Likes Received:
      94
      Trophy Points:
      48
    7. walter

      walter Active Member

      Joined:
      Jun 25, 2012
      Messages:
      1,112
      Likes Received:
      10
      Trophy Points:
      38
      If I have updated combat for this routine for certain classes do I post here?
       
    8. anonbuddy1

      anonbuddy1 Member

      Joined:
      Feb 20, 2013
      Messages:
      59
      Likes Received:
      5
      Trophy Points:
      8
      !!!!
       
    9. Apoc

      Apoc Moderator Staff Member Moderator

      Joined:
      Jan 16, 2010
      Messages:
      2,790
      Likes Received:
      94
      Trophy Points:
      48
      Yes, of course you post here!
       
    10. walter

      walter Active Member

      Joined:
      Jun 25, 2012
      Messages:
      1,112
      Likes Received:
      10
      Trophy Points:
      38

      I am not going to take credit for this but its some one else I am doing work with on this routine. Im going to just add tons of stuff as time goes on just have a few other routines working on. That with my awesome real life and holidays should get more up now. Things are smoothing out.

      This is engineer.

      [HIDE]using Buddy.Wildstar.Game.Actors;
      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Threading.Tasks;

      using Buddy.Wildstar.Game;

      namespace Buddy.DefaultRoutine.Classes
      {
      /*
      Engineer Ability Breakdown - (V = Volatility)

      Mode: Provoke - 60s CD - Instant - +10V/s for 10s (Defensive CD)
      Mode: Eradicate - 60s CD - Instant - +10V/s for 10s (DPS CD)

      Obstruct Vision - 30s CD - Instant - Interrupt + Blind
      Zap - 30s CD - Instant - Stun/Interrupt

      Recursive Matrix - 30s CD - Instant - Applies Defense/Stalwart around self for 10s (Defensive CD)
      Shatter Impairment - 20s CD - Instant - Removes all CCs and gives absorb [T4 - grants Empower, T8 - cleanses 2 debuffs]
      Personal Defense Unit - 45s CD - Instant - Grants Defense for it's duration, shield absorb when it dies [T4 causes it to last 60s instead of 30, T8 - restores health as well]
      Unstable Anomaly - 10s CD - Instant - Applies Wound

      Urgent Withdrawl - 1s CD - Instant - Snares targets [T4 gives Snare CC break, T8 grants CC immunity for 1.5s]

      Artillerybot - No CD[15s bot]- Instant - Summons Pet, grants Barrage
      Bruiserbot - No CD[15s bot]- Instant - Summons Pet, grants Blitz (taunt)
      Diminisherbot - No CD[15s bot]- Instant - Just a damage/snare bot. [T4 - Grants 5% max health when active] (Tank bot)
      Repairbot - No CD[15s bot]- Instant - Shield repair bot [T4 grants 15% shield mitigation] (Tank bot)

      Quick Burst - 8s CD - Instant - [Spell Proc] (T8 best used above 80V)
      Feedback - 8s CD - Instant - [Spell Proc]

      Mortar Strike - 10s CD - Instant - -25V
      Electrocute - No CD - 3s Channel - -8V/tick (0.5s tick) [T4 grants Empower (6 stacks total)]
      Unsteady Miasma - No CD - Instant - -40V, Applies Blunder
      Bolt Caster - No CD - Instant - -25V
      Particle Ejector - No CD - 3s Channel - -5V/tick (0.5s tick) 135% threat
      Thresher - No CD - Instant - -50V

      Volatile Injection - 20s CD - Instant - +5V/tick (1s tick for 10s) [50V total] Applies Defense and Empower
      Disruptive Module - 12s CD - 2s Cast - +5V/tick (1s tick for 6s) [30V total] Restores shield to self +4 allies [T4 increases shield mitigation, T8 30-70V restores shield per tick]
      Shock Pulse - 10s CD - 1.25s Cast - +10V Applies Snare
      Bio Shell - 10s CD - 1.9s Cast - +30V (T4 instant cast between 30-70V) Applies Expose for 11s
      Target Acquisition - 10s CD - 3s Channel - +3V every 0.25s (per tick on the mob) [36V total] consumes applied "marks" at the end of channel
      Ricochet - 6s CD - 1.25s Cast - +20V, Applies Exhaust, +110% threat
      Energy Auger - 6s CD - 1.75s Cast - +30V
      Flak Cannon - No CD - 2.5s Channel - +5V per tick (0.5s tick) [25V total] +110% threat
      Pulse Blast - No CD - 1.25s Cast - +15V


      Code Red - 45s CD - Instant - AoE Taunt
      Hyper Wave - 15s CD - Instant - Taunt
      */
      public class Engineer : BaseCombatClass
      {
      internal override async Task<bool> Pull(Actor target)
      {
      return await Combat();


      }

      internal async Task<bool> TryCastBots()
      {
      // Do some pet management here...
      // Ensure the pets are actually in "Assist" mode. This is most useful for us.
      await EnsurePetStances();

      // Now keep up all the bots, and more or less just spam their abilities whenever we can.
      // NOTE: The spell tooltip in-game changes when you summon a pet. However, the ability internally doesn't change names.
      // So this will not only summon the bots, but also "spam" their abilities whenever they're off CD
      if (await SelfCast("Artillerybot"))
      return true;
      if (await SelfCast("Bruiserbot"))
      return true;
      if (await SelfCast("Diminisherbot"))
      return true;
      if (await SelfCast("Repairbot"))
      return true;




      return false;
      }

      internal override async Task<bool> Combat()
      {
      // Cast Interrupts
      if (Target.IsCasting && await CastAny("Zap", "Obstruct Vision"))
      return true;

      // Pop our DPS innate.
      if (Me.InnateResource <= 30 && await SelfCast("Mode: Eradicate"))
      return true;

      // If we're in trouble, pop our defensive innate.
      if (Me.HealthPercent < 30 && await SelfCast("Mode: Provoke"))
      return true;

      // Shatter Impairment is a CC cleanse, and at T8 also a debuff cleanse
      if ((Me.GetActiveCCs().Count > 0 || (IsSpellTier("Shatter Impairment", 8) && Me.Buffs.Any(b => b.IsHarmful))) && await SelfCast("Shatter Impairment"))
      return true;

      // A defensive CD
      if (Me.HealthPercent < 50 && await Cast("Recursive Matrix"))
      return true;

      // Buffs/Debuffs
      if (await CastAny("Personal Defense Unit", "Unstable Anomaly"))
      return true;

      // T4 UW gives us a snare break
      if (IsSpellTier("Urgent Withdrawl", 4) && Me.GetActiveCCs().Any(c => c == CCStateType.Snare) && await Cast("Urgent Withdrawl"))
      return true;

      // TODO: Taunts!
      //if (await CastAny("Hyper Wave", "Code Red"))
      // return true;

      if (Me.HasBuff("Dealt Critical Damage"))
      {
      // QB T8 does a ton more damage at 80+ Volatility.
      // So lets include that logic.
      if (IsSpellTier("Quick Burst", 8))
      {
      if (Me.InnateResource > 80 && await Cast("Quick Burst"))
      return true;
      }
      else
      {
      // Non-T8, just cast as soon as it's up
      if (await Cast("Quick Burst"))
      return true;
      }
      }

      if (IsSpellProcReady("Feedback") && await Cast("Feedback"))
      return true;


      //Activates our Volatility Generator/Critical Buff first before attacking
      if (await SelfCast("Volatile Injection"))
      return true;



      // Increased priority for Tier 4 Bioshell and Ricochet, if you are in "The Zone" (30-70 volatility)
      // NOTE*** Add in 'IsSpellTier("Bio Shell", 4) && ' Once IsSpellTier is fixed. (Currently Assumes you have tier 4 Bio Shell)
      if (Me.InnateResource >= 30 && Me.InnateResource <= 70 && await Cast("Bio Shell"))
      return true;
      if (IsSpellTier("Ricochet", 4) && Me.InnateResource >= 30 && Me.InnateResource <= 70 && await Cast("Ricochet"))
      return true;


      // The following are all going to be "cast when high Volatility"
      // TODO: Engineer spenders are quite clunky. Only 1 has a cooldown. So you need to manage Volatility pretty well.
      // Mortar Strike is the only with a CD, so cast it whenever it's up.

      // NOTE IsSpellProcReady (not used for procs in this context) is used to prevent unnecessary spamming of abilities,
      // and instead used to increase the responsiveness of bot abilities (bottom of rotation)

      if (await CastAny("Mortar Strike"))
      return true;

      if (Me.InnateResource > 80 && await Cast("Thresher"))
      return true;
      if (Me.InnateResource > 80 && await Cast("Unsteady Miasma"))
      return true;
      if (Me.InnateResource >= 38 && IsSpellProcReady("Electrocute") && await Cast("Electrocute"))
      return true;
      if (Me.InnateResource > 80 && IsSpellProcReady("Particle Ejector") && await Cast("Particle Ejector"))
      return true;
      if (Me.InnateResource > 35 && await Cast("Bolt Caster"))
      return true;


      // These are all volatility builders, ordered by CD and "usefulness"
      // IsSpellProcReady prevents builders below from interrupting spenders.
      // Only applies this logic if either particle ejector or electrocute are slotted however.
      if (((IsSpellProcReady("Particle Ejector") || IsSpellProcReady("Electrocute"))
      || (!HasSpell("Particle Ejector") && !HasSpell("Electrocute"))) && await Cast("Disruptive Module"))
      return true;
      if (((IsSpellProcReady("Particle Ejector") || IsSpellProcReady("Electrocute"))
      || (!HasSpell("Particle Ejector") && !HasSpell("Electrocute"))) && await Cast("Shock Pulse"))
      return true;
      if (((IsSpellProcReady("Particle Ejector") || IsSpellProcReady("Electrocute"))
      || (!HasSpell("Particle Ejector") && !HasSpell("Electrocute"))) && await Cast("Target Acquisition"))
      return true;
      if (((IsSpellProcReady("Particle Ejector") || IsSpellProcReady("Electrocute"))
      || (!HasSpell("Particle Ejector") && !HasSpell("Electrocute"))) && await Cast("Energy Auger"))
      return true;
      if (((IsSpellProcReady("Particle Ejector") || IsSpellProcReady("Electrocute"))
      || (!HasSpell("Particle Ejector") && !HasSpell("Electrocute"))) && await Cast("Ricochet"))
      return true;
      if (((IsSpellProcReady("Particle Ejector") || IsSpellProcReady("Electrocute"))
      || (!HasSpell("Particle Ejector") && !HasSpell("Electrocute"))) && await Cast("Bio Shell"))
      return true;
      if (((IsSpellProcReady("Particle Ejector") || IsSpellProcReady("Electrocute"))
      || (!HasSpell("Particle Ejector") && !HasSpell("Electrocute"))) && await Cast("Flak Cannon"))
      return true;
      if (((IsSpellProcReady("Particle Ejector") || IsSpellProcReady("Electrocute"))
      || (!HasSpell("Particle Ejector") && !HasSpell("Electrocute"))) && await Cast("Pulse Blast"))
      return true;


      if (await TryCastBots())
      return true;


      return false;
      }

      private async Task EnsurePetStances()
      {
      foreach (var pet in GameManager.CurrentPets)
      {
      if (pet.Stance != PetStance.Assist)
      {
      GameManager.Lua.DoString("Pet_SetStance(0, 4)");
      // Only need to set it once. This changes it for all pets, so... yeah
      return;
      }
      }
      }
      }
      }[/HIDE]

      // NOTE*** Add in 'IsSpellTier("Bio Shell", 4) && ' Once IsSpellTier is fixed. (Currently Assumes you have tier 4 Bio Not working correctly.


      Esper Build


      [HIDE]using Buddy.Wildstar.Game.Actors;
      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Threading.Tasks;

      namespace Buddy.DefaultRoutine.Classes
      {
      public class Esper : BaseCombatClass
      {
      internal override async Task<bool> Pull(Actor target)
      {
      return await Combat();
      }


      internal override async Task<bool> Heal()
      {
      if (Me.Buffs.Count(c => c.IsHarmful) > 0 && await Cast("Catharsis"))
      return true;

      if (await HandleHealSpender())
      return true;

      if (Me.InnateResource < 3 && await SelfCast("Fixation"))
      return true;

      var lowestAlly = PartyMembers.OrderBy(p => p.HealthPercent).FirstOrDefault();

      if (lowestAlly != null)
      {
      if (lowestAlly.HealthPercent < 80 && await CastOn("Phantasmal Armor", () => lowestAlly))
      return true;
      if (lowestAlly.HealthPercent < 80 && await CastOn("Projected Spirit", () => lowestAlly))
      return true;
      if (lowestAlly.HealthPercent < 80 && await CastOn("Pyrokinetic Flame", () => lowestAlly))
      return true;
      if (lowestAlly.HealthPercent < 80 && await CastOn("Mirage", () => lowestAlly))
      return true;
      if (lowestAlly.HealthPercent < 80 && await Cast("Soothe"))
      return true;
      if (lowestAlly.HealthPercent < 80 && await Cast("Warden"))
      return true;
      if (lowestAlly.HealthPercent < 80 && await Cast("Bolster"))
      return true;
      if (lowestAlly.HealthPercent < 80 && await Cast("Mind Over Body"))
      return true;
      if ((lowestAlly.HealthPercent < 80 || Me.ManaPercent < 30) && await SelfCast("Meditate"))
      return true;
      }

      return false;
      }

      internal override async Task<bool> Combat()
      {


      if (Me.GetActiveCCs().Count > 0 && await Cast("Fade Out"))
      return true;

      if (Target.IsCasting && await CastAny("Shockwave", "Crush", "Incapacitate"))
      return true;

      if (await EnsureCombatBuffs())
      return true;

      if (await HandleCombatSpender())
      return true;

      if (Me.HealthPercent < 85 && await SelfCast("Phantasmal Armor"))
      return true;

      if (await CastAny("Spectral Swarm", "Restraint", "Geist", "Psychic Frenzy", "Blade Dance"))
      return true;

      if (await SelfCast("Spectral Form"))
      return true;




      //TODO: Illusionary Blades

      //if (await CastAny("Concentrated Blade", "Telekinetic Strike")) //Concentrated Blade bugged
      // return true;

      return false;
      }

      private async Task<bool> EnsureCombatBuffs()
      {
      if (!Target.HasBuff("Expose") && await Cast("Haunt"))
      return true;

      return false;
      }

      private async Task<bool> HandleCombatSpender()
      {
      // Best to cast @ 5 resource for maximum impact
      var resource = Me.InnateResource;

      // Now combat spenders
      if (resource >= 3 && await Cast("Reap"))
      return true;
      if (resource >= 5 && await Cast("Mind Burst"))
      return true;
      if (resource >= 5 && await Cast("Telekinetic Storm"))
      return true;

      return false;
      }


      private async Task<bool> HandleHealSpender()
      {
      var resource = Me.InnateResource;
      var hpAverage = PartyMembers.Average(p => p.HealthPercent);

      // Heal before Combat
      if (resource >= 5 && Me.HealthPercent < 80 && await Cast("Mental Boon"))
      return true;
      if (resource >= 5 && hpAverage < 70 && await Cast("Reverie"))
      return true;
      if (resource >= 5 && hpAverage < 70 && await Cast("Mending Banner"))
      return true;

      return false;
      }
      }
      }



      <Profile Name="Badland Test" Author="Dr. Kid" Version="1.0">
      <Grind>
      <Repair PreferClosest="true" PreferFirst="false">
      <RepairNPCs>
      <RepairNPC Name="Quartermaster Klazrak" CreatureId="36576" X="-22480.97" Y="-942.832" Z="-27820.3" MapId="2997"/>
      </RepairNPCs>
      </Repair>
      <Vendor>
      <VendorNPC Name="Quartermaster Klazrak" CreatureId="36576" X="-22480.97" Y="-942.832" Z="-27820.3" MapId="2997"/>
      </Vendor>
      <GrindArea>
      <Hotspot X="-22469.0781" Y="-975.8047" Z="-27239.8047" Timeout="60" Range="40"/>
      <Hotspot X="-22567.3379" Y="-988.9558" Z="-27140.877" Timeout="60" Range="40"/>
      <Hotspot X="-22530.3633" Y="-995.952637" Z="-26998.3047" Timeout="60" Range="40"/>
      <Hotspot X="-22409.625" Y="-988.459" Z="-27111.0547" Timeout="60" Range="40"/>
      </GrindArea>
      </Grind>
      </Profile>
      [/HIDE]


      I will post updated spellslinger but spellsurge resource doesn't work correctly. It always puts the value at 0 no matter what I do.

      if (IsSpellTier("Bio Shell", 4) && Me.InnateResource >= 30 && Me.InnateResource <= 70 && await Cast("Bio Shell"))
      return true;



      Once I tweak a few things Im going to add in support for health pots to using items in inventory like xp flasks etc. I just want to clean up everything make sure its going smooth before I start adding nonsense.
       
    11. Apoc

      Apoc Moderator Staff Member Moderator

      Joined:
      Jan 16, 2010
      Messages:
      2,790
      Likes Received:
      94
      Trophy Points:
      48
      IsSpellTier doesn't work properly?

      On all the things I tested, it was working correctly. Do you mind printing out what is wrong with it?
       
    12. Apoc

      Apoc Moderator Staff Member Moderator

      Joined:
      Jan 16, 2010
      Messages:
      2,790
      Likes Received:
      94
      Trophy Points:
      48
      Also, some things either don't make sense (excuse my lack of high-level rotation knowledge), and others can be condensed.

      Code:
      [COLOR=#333333]if (((IsSpellProcReady("Particle Ejector") || IsSpellProcReady("Electrocute"))[/COLOR]
      [COLOR=#333333]|| (!HasSpell("Particle Ejector") && !HasSpell("Electrocute"))) && await Cast("Disruptive Module"))[/COLOR]
      [COLOR=#333333]return true;[/COLOR]
      [COLOR=#333333]if (((IsSpellProcReady("Particle Ejector") || IsSpellProcReady("Electrocute"))[/COLOR]
      [COLOR=#333333]|| (!HasSpell("Particle Ejector") && !HasSpell("Electrocute"))) && await Cast("Shock Pulse"))[/COLOR]
      [COLOR=#333333]return true; [/COLOR]
      [COLOR=#333333]if (((IsSpellProcReady("Particle Ejector") || IsSpellProcReady("Electrocute"))[/COLOR]
      [COLOR=#333333]|| (!HasSpell("Particle Ejector") && !HasSpell("Electrocute"))) && await Cast("Target Acquisition"))[/COLOR]
      [COLOR=#333333]return true; [/COLOR]
      [COLOR=#333333]if (((IsSpellProcReady("Particle Ejector") || IsSpellProcReady("Electrocute"))[/COLOR]
      [COLOR=#333333]|| (!HasSpell("Particle Ejector") && !HasSpell("Electrocute"))) && await Cast("Energy Auger"))[/COLOR]
      [COLOR=#333333]return true; [/COLOR]
      [COLOR=#333333]if (((IsSpellProcReady("Particle Ejector") || IsSpellProcReady("Electrocute"))[/COLOR]
      [COLOR=#333333]|| (!HasSpell("Particle Ejector") && !HasSpell("Electrocute"))) && await Cast("Ricochet"))[/COLOR]
      [COLOR=#333333]return true; [/COLOR]
      [COLOR=#333333]if (((IsSpellProcReady("Particle Ejector") || IsSpellProcReady("Electrocute"))[/COLOR]
      [COLOR=#333333]|| (!HasSpell("Particle Ejector") && !HasSpell("Electrocute"))) && await Cast("Bio Shell"))[/COLOR]
      [COLOR=#333333]return true; [/COLOR]
      [COLOR=#333333]if (((IsSpellProcReady("Particle Ejector") || IsSpellProcReady("Electrocute"))[/COLOR]
      [COLOR=#333333]|| (!HasSpell("Particle Ejector") && !HasSpell("Electrocute"))) && await Cast("Flak Cannon"))[/COLOR]
      [COLOR=#333333]return true; [/COLOR]
      [COLOR=#333333]if (((IsSpellProcReady("Particle Ejector") || IsSpellProcReady("Electrocute"))[/COLOR]
      [COLOR=#333333]|| (!HasSpell("Particle Ejector") && !HasSpell("Electrocute"))) && await Cast("Pulse Blast"))[/COLOR]
      [COLOR=#333333]return true; 
      Can easily be condensed into

      Code:
      [/COLOR]			var procsReady = ((IsSpellProcReady("Particle Ejector") || IsSpellProcReady("Electrocute")) || (!HasSpell("Particle Ejector") && !HasSpell("Electrocute")));			if (procsReady && await CastAny("Disruptive Module","Shock Pulse", "Target Acquisition", "Energy Auger", "Ricochet", "Bio Shell", "Flak Cannon", "Pulse Blast"))
      				return true;
      Is there a reason to cast bots after your normal filler? Last I checked, they weren't on the GCD, and could be cast at any time.
       
    13. walter

      walter Active Member

      Joined:
      Jun 25, 2012
      Messages:
      1,112
      Likes Received:
      10
      Trophy Points:
      38
      Spellslinger


      [HIDE]using Buddy.Wildstar.Game.Actors;
      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Threading.Tasks;

      namespace Buddy.DefaultRoutine.Classes
      {
      public class SpellSlinger : BaseCombatClass
      {
      internal override async Task<bool> Pull(Actor target)
      {
      return await Combat();
      }

      internal override async Task<bool> Heal()
      {

      var lowestPercent = PartyMembers.OrderBy(p => p.HealthPercent).FirstOrDefault();

      if (!Me.HasBuff("Healing Salve") && await Cast("Healing Salve"))
      return true;
      if (!Me.HasBuff("Beacon") && await Cast("Affinity"))
      return true;

      if (lowestPercent == null)
      return false;

      var hPercent = lowestPercent.HealthPercent;

      if (hPercent < 90 && await CastOn("Runes of Protection", () => lowestPercent))
      return true;
      if (hPercent < 70 && await CastOn("Vitality Burst", () => lowestPercent))
      return true;
      if (hPercent < 90 && await CastOn("Astral Infusion", () => lowestPercent))
      return true;
      if (hPercent < 80 && await CastOn("Dual Fire", () => lowestPercent))
      return true;
      if (hPercent < 80 && await CastOn("Healing Torrent", () => lowestPercent))
      return true;
      if (hPercent < 30 && await CastOn("Voidspring", () => lowestPercent))
      return true;
      if (hPercent < 90 && await CastOn("Regenerative Pulse", () => lowestPercent))
      return true;
      if (hPercent < 70 && await CastOn("Sustain", () => lowestPercent))
      return true;


      return false;
      }

      internal override async Task<bool> Combat()
      {
      // Interrupt
      if (Target.IsCasting && await CastAny("Arcane Shock", "Gate"))
      return true;

      // Cleanse CC
      if (Me.HasCleansableCC() && await SelfCast("Void Slip"))
      return true;

      // Cleanse buffs
      if (Me.Buffs.Count(c => c.IsHarmful) > 0 && await Cast("Purify"))
      return true;

      // Maintain Target & self buffs
      if (await EnsureBuffs())
      return true;

      // Handle innate ability
      //if (await HandleInnate())
      // return true;

      if (Target.HealthPercent < 30 && await Cast("Assassinate"))
      return true;

      if (Me.HasBuff("Dealt Critical Damage") && await Cast("Flame Burst"))
      return true;

      if (!Target.HasBuff("Ignite") && await Cast("Ignite"))
      return true;

      if (await Cast("Flash Freeze"))
      return true;

      //TODO: Charged Shot

      //If spell surge is down, and there exists a special available to use. -> Turns spell surge on
      if (!Me.HasBuff("Spell Surge") && (IsSpellProcReady("Arcane Missiles") || IsSpellProcReady("Chill") || IsSpellProcReady("True Shot") || IsSpellProcReady("Rapid Fire") || IsSpellProcReady("Wild Barrage") ) && await SelfCast("Spell Surge") )
      return true;


      //use a "special" attack.
      if (await CastAny("Arcane Missiles", "Chill", "True Shot", "Rapid Fire", "Wild Barrage"))
      return true;

      //if spell surge is up, and quick draw is usable (not mid animation for a special for example), toggles it off
      //However, it will remain on if we have a excess amount of spell surge available
      //Me.InnateResource currently does nothing
      if ((Me.HasBuff("Spell Surge") && IsSpellProcReady("Quick Draw")) && (Me.InnateResource > 75) && await SelfCast("Spell Surge"))
      return true;


      //Uses a non-surged quick draw if no specials are available.
      if (await CastAny("Quick Draw"))
      return true;

      return false;
      }

      private async Task<bool> EnsureBuffs()
      {


      if (!Me.HasBuff("Empower") && await Cast("Void Pact"))
      return true;
      if (Me.HealthPercent < 85 && await SelfCast("Phase Shift"))
      return true;

      return false;
      }

      private async Task<bool> HandleInnate()
      {
      // Turn on or maintain Spell Surge
      if (!Me.HasBuff("Spell Surge") && await SelfCast("Spell Surge"))
      return true;

      return false;
      }
      }
      }[/HIDE]


      I will adjust engineer some. but its set that way so it using resources correctly. Otherwise it will not use volatility correctly. Here I changed it up some.

      [HIDE]using Buddy.Wildstar.Game.Actors;
      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Threading.Tasks;

      using Buddy.Wildstar.Game;

      namespace Buddy.DefaultRoutine.Classes
      {
      /*
      Engineer Ability Breakdown - (V = Volatility)

      Mode: Provoke - 60s CD - Instant - +10V/s for 10s (Defensive CD)
      Mode: Eradicate - 60s CD - Instant - +10V/s for 10s (DPS CD)

      Obstruct Vision - 30s CD - Instant - Interrupt + Blind
      Zap - 30s CD - Instant - Stun/Interrupt

      Recursive Matrix - 30s CD - Instant - Applies Defense/Stalwart around self for 10s (Defensive CD)
      Shatter Impairment - 20s CD - Instant - Removes all CCs and gives absorb [T4 - grants Empower, T8 - cleanses 2 debuffs]
      Personal Defense Unit - 45s CD - Instant - Grants Defense for it's duration, shield absorb when it dies [T4 causes it to last 60s instead of 30, T8 - restores health as well]
      Unstable Anomaly - 10s CD - Instant - Applies Wound

      Urgent Withdrawl - 1s CD - Instant - Snares targets [T4 gives Snare CC break, T8 grants CC immunity for 1.5s]

      Artillerybot - No CD[15s bot]- Instant - Summons Pet, grants Barrage
      Bruiserbot - No CD[15s bot]- Instant - Summons Pet, grants Blitz (taunt)
      Diminisherbot - No CD[15s bot]- Instant - Just a damage/snare bot. [T4 - Grants 5% max health when active] (Tank bot)
      Repairbot - No CD[15s bot]- Instant - Shield repair bot [T4 grants 15% shield mitigation] (Tank bot)

      Quick Burst - 8s CD - Instant - [Spell Proc] (T8 best used above 80V)
      Feedback - 8s CD - Instant - [Spell Proc]

      Mortar Strike - 10s CD - Instant - -25V
      Electrocute - No CD - 3s Channel - -8V/tick (0.5s tick) [T4 grants Empower (6 stacks total)]
      Unsteady Miasma - No CD - Instant - -40V, Applies Blunder
      Bolt Caster - No CD - Instant - -25V
      Particle Ejector - No CD - 3s Channel - -5V/tick (0.5s tick) 135% threat
      Thresher - No CD - Instant - -50V

      Volatile Injection - 20s CD - Instant - +5V/tick (1s tick for 10s) [50V total] Applies Defense and Empower
      Disruptive Module - 12s CD - 2s Cast - +5V/tick (1s tick for 6s) [30V total] Restores shield to self +4 allies [T4 increases shield mitigation, T8 30-70V restores shield per tick]
      Shock Pulse - 10s CD - 1.25s Cast - +10V Applies Snare
      Bio Shell - 10s CD - 1.9s Cast - +30V (T4 instant cast between 30-70V) Applies Expose for 11s
      Target Acquisition - 10s CD - 3s Channel - +3V every 0.25s (per tick on the mob) [36V total] consumes applied "marks" at the end of channel
      Ricochet - 6s CD - 1.25s Cast - +20V, Applies Exhaust, +110% threat
      Energy Auger - 6s CD - 1.75s Cast - +30V
      Flak Cannon - No CD - 2.5s Channel - +5V per tick (0.5s tick) [25V total] +110% threat
      Pulse Blast - No CD - 1.25s Cast - +15V


      Code Red - 45s CD - Instant - AoE Taunt
      Hyper Wave - 15s CD - Instant - Taunt
      */
      public class Engineer : BaseCombatClass
      {
      internal override async Task<bool> Pull(Actor target)
      {
      return await Combat();


      }

      internal async Task<bool> TryCastBots()
      {
      // Do some pet management here...
      // Ensure the pets are actually in "Assist" mode. This is most useful for us.
      await EnsurePetStances();

      // Now keep up all the bots, and more or less just spam their abilities whenever we can.
      // NOTE: The spell tooltip in-game changes when you summon a pet. However, the ability internally doesn't change names.
      // So this will not only summon the bots, but also "spam" their abilities whenever they're off CD
      if (await SelfCast("Artillerybot"))
      return true;
      if (await SelfCast("Bruiserbot"))
      return true;
      if (await SelfCast("Diminisherbot"))
      return true;
      if (await SelfCast("Repairbot"))
      return true;




      return false;
      }

      internal override async Task<bool> Combat()
      {
      // Cast Interrupts
      if (Target.IsCasting && await CastAny("Zap", "Obstruct Vision"))
      return true;

      // Pop our DPS innate.
      if (Me.InnateResource <= 30 && await SelfCast("Mode: Eradicate"))
      return true;

      // If we're in trouble, pop our defensive innate.
      if (Me.HealthPercent < 30 && await SelfCast("Mode: Provoke"))
      return true;

      // Shatter Impairment is a CC cleanse, and at T8 also a debuff cleanse
      if ((Me.GetActiveCCs().Count > 0 || (IsSpellTier("Shatter Impairment", 8) && Me.Buffs.Any(b => b.IsHarmful))) && await SelfCast("Shatter Impairment"))
      return true;

      // A defensive CD
      if (Me.HealthPercent < 50 && await Cast("Recursive Matrix"))
      return true;

      // Buffs/Debuffs
      if (await CastAny("Personal Defense Unit", "Unstable Anomaly"))
      return true;

      // T4 UW gives us a snare break
      if (IsSpellTier("Urgent Withdrawl", 4) && Me.GetActiveCCs().Any(c => c == CCStateType.Snare) && await Cast("Urgent Withdrawl"))
      return true;

      // TODO: Taunts!
      //if (await CastAny("Hyper Wave", "Code Red"))
      // return true;

      if (Me.HasBuff("Dealt Critical Damage"))
      {
      // QB T8 does a ton more damage at 80+ Volatility.
      // So lets include that logic.
      if (IsSpellTier("Quick Burst", 8))
      {
      if (Me.InnateResource > 80 && await Cast("Quick Burst"))
      return true;
      }
      else
      {
      // Non-T8, just cast as soon as it's up
      if (await Cast("Quick Burst"))
      return true;
      }
      }

      if (IsSpellProcReady("Feedback") && await Cast("Feedback"))
      return true;


      //Activates our Volatility Generator/Critical Buff first before attacking
      if (await SelfCast("Volatile Injection"))
      return true;

      //Uses a DPS gadget
      if (await SelfCast("Power"))
      return true;



      // Increased priority for Tier 4 Bioshell and Ricochet, if you are in "The Zone" (30-70 volatility)
      // NOTE*** Add in 'IsSpellTier("Bio Shell", 4) && ' Once IsSpellTier is fixed. (Currently Assumes you have tier 4 Bio Shell)
      if (Me.InnateResource >= 30 && Me.InnateResource <= 70 && await Cast("Bio Shell"))
      return true;
      if (IsSpellTier("Ricochet", 4) && Me.InnateResource >= 30 && Me.InnateResource <= 70 && await Cast("Ricochet"))
      return true;


      // The following are all going to be "cast when high Volatility"
      // TODO: Engineer spenders are quite clunky. Only 1 has a cooldown. So you need to manage Volatility pretty well.
      // Mortar Strike is the only with a CD, so cast it whenever it's up.

      // NOTE IsSpellProcReady (not used for procs in this context) is used to prevent unnecessary spamming of abilities,
      // and instead used to increase the responsiveness of bot abilities (bottom of rotation)

      if (await CastAny("Mortar Strike"))
      return true;

      if (Me.InnateResource > 80 && await Cast("Thresher"))
      return true;
      if (Me.InnateResource > 80 && await Cast("Unsteady Miasma"))
      return true;
      if (Me.InnateResource >= 38 && IsSpellProcReady("Electrocute") && await Cast("Electrocute"))
      return true;
      if (Me.InnateResource > 80 && IsSpellProcReady("Particle Ejector") && await Cast("Particle Ejector"))
      return true;
      if (Me.InnateResource > 35 && await Cast("Bolt Caster"))
      return true;


      // These are all volatility builders, ordered by CD and "usefulness"
      // IsSpellProcReady prevents builders below from interrupting spenders.
      // Only applies this logic if either particle ejector or electrocute are slotted however.
      if (((IsSpellProcReady("Particle Ejector") || IsSpellProcReady("Electrocute"))
      || (!HasSpell("Particle Ejector") && !HasSpell("Electrocute")))
      && await CastAny("Disruptive Module", "Shock Pulse", "Target Acquisition", "Energy Auger", "Ricochet", "Bio Shell", "Flak Cannon", "Pulse Blast"))
      return true;


      if (await TryCastBots())
      return true;



      return false;
      }

      private async Task EnsurePetStances()
      {
      foreach (var pet in GameManager.CurrentPets)
      {
      if (pet.Stance != PetStance.Assist)
      {
      GameManager.Lua.DoString("Pet_SetStance(0, 4)");
      // Only need to set it once. This changes it for all pets, so... yeah
      return;
      }
      }
      }
      }
      }[/HIDE]


      isspelltier doesn't work for bioshell. T4 doesn't seem to work correctly when I call it up. Line 157 you can see how I have stuff commented out.



      Reason for spamming bot is because the bots get out of range. Then they stop working and etc. This way it allows them to trail you at all times.
       
      Last edited: Dec 23, 2014
    14. charliex

      charliex Member

      Joined:
      Jun 25, 2012
      Messages:
      78
      Likes Received:
      0
      Trophy Points:
      6
      Low level warrior seems to be trying to spam Rampage while having low/no KE, any ideas?

      Code:
      2014-12-27 04:40:19,852 [Pulsator Thread] INFO  SpellManager - Down: 1669148952
      2014-12-27 04:40:19,853 [Pulsator Thread] INFO  SpellManager - Up: 1417084944
      2014-12-27 04:40:19,947 [Pulsator Thread] INFO  SpellManager - Down: 1669148952
      2014-12-27 04:40:19,948 [Pulsator Thread] INFO  SpellManager - Up: 1417084944
      2014-12-27 04:40:20,042 [Pulsator Thread] INFO  SpellManager - Down: 1669148952
      2014-12-27 04:40:20,043 [Pulsator Thread] INFO  SpellManager - Up: 1417084944
      2014-12-27 04:40:20,140 [Pulsator Thread] INFO  SpellManager - Down: 1669148952
      2014-12-27 04:40:20,140 [Pulsator Thread] INFO  SpellManager - Up: 1417084944
      2014-12-27 04:40:20,235 [Pulsator Thread] INFO  SpellManager - Down: 1669148952
      2014-12-27 04:40:20,235 [Pulsator Thread] INFO  SpellManager - Up: 1417084944
      2014-12-27 04:40:20,324 [Pulsator Thread] INFO  SpellManager - Down: 1669148952
      2014-12-27 04:40:20,324 [Pulsator Thread] INFO  SpellManager - Up: 1417084944
      2014-12-27 04:40:20,409 [Pulsator Thread] INFO  SpellManager - Down: 1669148952
      2014-12-27 04:40:20,409 [Pulsator Thread] INFO  SpellManager - Up: 1417084944
      2014-12-27 04:40:20,501 [Pulsator Thread] INFO  SpellManager - Down: 1669148952
      2014-12-27 04:40:20,501 [Pulsator Thread] INFO  SpellManager - Up: 1417084944
      2014-12-27 04:40:20,614 [Pulsator Thread] INFO  SpellManager - Down: 1669148952
      2014-12-27 04:40:20,614 [Pulsator Thread] INFO  SpellManager - Up: 1417084944
      2014-12-27 04:40:20,714 [Pulsator Thread] INFO  SpellManager - Down: 1669148952
      2014-12-27 04:40:20,715 [Pulsator Thread] INFO  SpellManager - Up: 1417084944
      2014-12-27 04:40:20,805 [Pulsator Thread] INFO  SpellManager - Down: 1669148952
      2014-12-27 04:40:20,805 [Pulsator Thread] INFO  SpellManager - Up: 1417084944
      2014-12-27 04:40:20,905 [Pulsator Thread] INFO  SpellManager - Down: 1669148952
      2014-12-27 04:40:20,905 [Pulsator Thread] INFO  SpellManager - Up: 1417084944
      2014-12-27 04:40:21,015 [Pulsator Thread] INFO  SpellManager - Down: 1669148952
      i get that spammed in the logs when it happens it seems
       
      Last edited: Dec 27, 2014
    15. walter

      walter Active Member

      Joined:
      Jun 25, 2012
      Messages:
      1,112
      Likes Received:
      10
      Trophy Points:
      38
      Having some issues being thrown from targeting.cs. Here is the log. Constantly throwing coroutine errors.

      It happens once the routine thinks you are falling. View attachment Targetinglog.zip
       
    16. Apoc

      Apoc Moderator Staff Member Moderator

      Joined:
      Jan 16, 2010
      Messages:
      2,790
      Likes Received:
      94
      Trophy Points:
      48
      Inside Targeting.cs, at line 97 you'll find the following:

      Code:
      if (!_pullTarget.IsValid)
      Change it to

      Code:
      if (_pullTarget != null && !_pullTarget.IsValid)
      I'll commit this as well to the SVN repo.
       
    17. puck

      puck New Member

      Joined:
      Oct 26, 2014
      Messages:
      10
      Likes Received:
      0
      Trophy Points:
      0
      I'm sometimes seeing issues with warriors that makes me wonder if there's some bugginess around reading kinetic energy - upon initiating combat, the bot will try to spam Rampage - which requires kinetic energy (rage) - if none is present from previous battles, it will just stand there attempting to spam the button.

      You can see this with a fairly new character, as rampage is the default second skill unlock for the class.

      Thanks!
       
    18. walter

      walter Active Member

      Joined:
      Jun 25, 2012
      Messages:
      1,112
      Likes Received:
      10
      Trophy Points:
      38

      I updated warrior but I haven't posted it here yet. Was doing some rework for melee and will post asap. Also gadgets will be added.
       
    19. daQuist

      daQuist New Member

      Joined:
      Aug 16, 2014
      Messages:
      30
      Likes Received:
      0
      Trophy Points:
      0
      Hey there,

      is this CR or any CR here for the Wildstar bot still supported? Because I'm thinking about to buy this bot but when there are no CR's then it's wasting my money.

      All of the threads here are from last year so I'm not very enthusiastic.
       
    20. Apoc

      Apoc Moderator Staff Member Moderator

      Joined:
      Jan 16, 2010
      Messages:
      2,790
      Likes Received:
      94
      Trophy Points:
      48
      Forums have just been slow :)

      This CR is very much still supported, as it's packaged with the bot.
       

    Share This Page