Yes, of course you post here!
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.