notifications
4n0n 2 years ago
parent 13f0c93767
commit 9f77df0da4
  1. 65
      scripts/outlaw.lua
  2. 676
      scripts/subtlety.lua
  3. 6
      src/Item/Item.lua
  4. 16
      src/Spell/Spell.lua
  5. 41
      src/Unit/Unit.lua

@ -40,9 +40,12 @@ local AtrophicPosion = Bastion.SpellBook:GetSpell(381637)
local Evasion = Bastion.SpellBook:GetSpell(5277) local Evasion = Bastion.SpellBook:GetSpell(5277)
local TricksOfTheTrade = Bastion.SpellBook:GetSpell(57934) local TricksOfTheTrade = Bastion.SpellBook:GetSpell(57934)
local CheapShot = Bastion.SpellBook:GetSpell(1833) local CheapShot = Bastion.SpellBook:GetSpell(1833)
local BagOfTricks = Bastion.SpellBook:GetSpell(312411)
local AutoAttack = Bastion.SpellBook:GetSpell(6603)
local IrideusFragment = Bastion.ItemBook:GetItem(193743) local IrideusFragment = Bastion.ItemBook:GetItem(193743)
local Healthstone = Bastion.ItemBook:GetItem(5512) local Healthstone = Bastion.ItemBook:GetItem(5512)
local WindscarWhetstone = Bastion.ItemBook:GetItem(137486)
local PurgeTarget = Bastion.UnitManager:CreateCustomUnit('purge', function(unit) local PurgeTarget = Bastion.UnitManager:CreateCustomUnit('purge', function(unit)
local purge = nil local purge = nil
@ -133,6 +136,36 @@ local Tank = Bastion.UnitManager:CreateCustomUnit('tank', function(unit)
return tank return tank
end) end)
local Explosive = Bastion.UnitManager:CreateCustomUnit('explosive', function(unit)
local explosive = nil
Bastion.UnitManager:EnumNameplates(function(unit)
if unit:IsDead() then
return false
end
if not Player:CanSee(unit) then
return false
end
if Player:GetDistance(unit) > 40 then
return false
end
if Player:InMelee(unit) and unit:GetID() == 120651 and Player:IsFacing(unit) then
explosive = unit
return true
end
end)
if explosive == nil then
explosive = None
end
return explosive
end)
local DefaultAPL = Bastion.APL:New('default') local DefaultAPL = Bastion.APL:New('default')
local AOEAPL = Bastion.APL:New('aoe') local AOEAPL = Bastion.APL:New('aoe')
local SpecialAPL = Bastion.APL:New('special') local SpecialAPL = Bastion.APL:New('special')
@ -145,11 +178,22 @@ SpecialAPL:AddSpell(
end):SetTarget(KickTarget) end):SetTarget(KickTarget)
) )
SpecialAPL:AddSpell(
SinisterStrike:CastableIf(function(self)
return Explosive:Exists() and not Player:IsCastingOrChanneling()
end):SetTarget(Explosive)
)
SpecialAPL:AddSpell( SpecialAPL:AddSpell(
KidneyShot:CastableIf(function(self) KidneyShot:CastableIf(function(self)
return KickTarget:Exists() and Player:InMelee(KickTarget) and return KickTarget:Exists() and Player:InMelee(KickTarget) and
self:IsKnownAndUsable() and self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and Player:GetComboPoints(KickTarget) <= 2 not Player:IsCastingOrChanneling() and
(Player:GetComboPoints(Target) >= 5 or
(
Player:GetComboPoints(Target) >= 4 and
(Player:GetAuras():FindMy(Broadside):IsUp() or Player:GetAuras():FindMy(Opportunity):IsUp())))
end):SetTarget(KickTarget) end):SetTarget(KickTarget)
) )
@ -232,6 +276,21 @@ SpecialAPL:AddItem(
end):SetTarget(Player) end):SetTarget(Player)
) )
SpecialAPL:AddItem(
WindscarWhetstone:UsableIf(function(self)
return self:IsEquippedAndUsable() and
not Player:IsCastingOrChanneling() and (Player:GetMeleeAttackers() > 2 or Target:IsBoss())
end):SetTarget(Player)
)
SpecialAPL:AddSpell(
BagOfTricks:CastableIf(function(self)
return Target:Exists() and Player:InMelee(Target) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling()
end):SetTarget(Target)
)
-- Adrenaline Rush on cooldown. -- Adrenaline Rush on cooldown.
DefaultAPL:AddSpell( DefaultAPL:AddSpell(
AdrenalineRush:CastableIf(function(self) AdrenalineRush:CastableIf(function(self)
@ -341,7 +400,7 @@ DefaultAPL:AddSpell(
-- Vanish followed by Ambush if you won't overcap combo points and wait until you have at least 50 energy. -- Vanish followed by Ambush if you won't overcap combo points and wait until you have at least 50 energy.
DefaultAPL:AddSpell( DefaultAPL:AddSpell(
Vanish:CastableIf(function(self) Vanish:CastableIf(function(self)
return Target:Exists() and Player:InMelee(Target) and return Tank:Exists() and Target:Exists() and Player:InMelee(Target) and
self:IsKnownAndUsable() and self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and not Player:IsCastingOrChanneling() and
Player:GetComboPoints(Target) <= 4 and Player:GetComboPoints(Target) <= 4 and
@ -500,7 +559,7 @@ AOEAPL:AddSpell(
-- Vanish followed by Ambush if you won't overcap combo points and wait until you have at least 50 energy. -- Vanish followed by Ambush if you won't overcap combo points and wait until you have at least 50 energy.
AOEAPL:AddSpell( AOEAPL:AddSpell(
Vanish:CastableIf(function(self) Vanish:CastableIf(function(self)
return Target:Exists() and Player:InMelee(Target) and return Tank:Exists() and Target:Exists() and Player:InMelee(Target) and
self:IsKnownAndUsable() and self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and not Player:IsCastingOrChanneling() and
Player:GetComboPoints(Target) < 5 and Player:GetComboPoints(Target) < 5 and

@ -0,0 +1,676 @@
local Tinkr, Bastion = ...
local SubModulue = Bastion.Module:New('sub')
local Evaluator = Tinkr.Util.Evaluator
local Player = Bastion.UnitManager:Get('player')
local None = Bastion.UnitManager:Get('none')
local Target = Bastion.UnitManager:Get('target')
local RollTheBones = Bastion.SpellBook:GetSpell(315508)
local SliceAndDice = Bastion.SpellBook:GetSpell(315496)
local BetweenTheEyes = Bastion.SpellBook:GetSpell(315341)
local BladeRush = Bastion.SpellBook:GetSpell(271877)
local Vanish = Bastion.SpellBook:GetSpell(1856)
local Dispatch = Bastion.SpellBook:GetSpell(2098)
local Ambush = Bastion.SpellBook:GetSpell(8676)
local Stealth = Bastion.SpellBook:GetSpell(1784)
local PistolShot = Bastion.SpellBook:GetSpell(185763)
local Opportunity = Bastion.SpellBook:GetSpell(195627)
local SinisterStrike = Bastion.SpellBook:GetSpell(193315)
local GrandMelee = Bastion.SpellBook:GetSpell(193358)
local Broadside = Bastion.SpellBook:GetSpell(193356)
local TrueBearing = Bastion.SpellBook:GetSpell(193359)
local RuthlessPrecision = Bastion.SpellBook:GetSpell(193357)
local SkullAndCrossbones = Bastion.SpellBook:GetSpell(199603)
local BuriedTreasure = Bastion.SpellBook:GetSpell(199600)
local AdrenalineRush = Bastion.SpellBook:GetSpell(13750)
local ShadowDance = Bastion.SpellBook:GetSpell(185313)
local ShadowDanceAura = Bastion.SpellBook:GetSpell(185422)
local Audacity = Bastion.SpellBook:GetSpell(381845)
local Flagellation = Bastion.SpellBook:GetSpell(323654)
local Dreadblades = Bastion.SpellBook:GetSpell(343142)
local JollyRoger = Bastion.SpellBook:GetSpell(199603)
local BladeFlurry = Bastion.SpellBook:GetSpell(13877)
local Kick = Bastion.SpellBook:GetSpell(1766)
local MarkedForDeath = Bastion.SpellBook:GetSpell(137619)
local CrimsonVial = Bastion.SpellBook:GetSpell(185311)
local Shiv = Bastion.SpellBook:GetSpell(5938)
local KidneyShot = Bastion.SpellBook:GetSpell(408)
local InstantPoison = Bastion.SpellBook:GetSpell(315584)
local AtrophicPosion = Bastion.SpellBook:GetSpell(381637)
local Evasion = Bastion.SpellBook:GetSpell(5277)
local TricksOfTheTrade = Bastion.SpellBook:GetSpell(57934)
local CheapShot = Bastion.SpellBook:GetSpell(1833)
local BagOfTricks = Bastion.SpellBook:GetSpell(312411)
local AutoAttack = Bastion.SpellBook:GetSpell(6603)
local SymbolsOfDeath = Bastion.SpellBook:GetSpell(212283)
local ShadowBlades = Bastion.SpellBook:GetSpell(121471)
local ColdBlood = Bastion.SpellBook:GetSpell(382245)
local ShurikenTornado = Bastion.SpellBook:GetSpell(277925)
local ThistleTea = Bastion.SpellBook:GetSpell(381623)
local Gloomblade = Bastion.SpellBook:GetSpell(200758)
local Shadowstrike = Bastion.SpellBook:GetSpell(185438)
local Rupture = Bastion.SpellBook:GetSpell(1943)
local Eviscerate = Bastion.SpellBook:GetSpell(196819)
local NumbingPoison = Bastion.SpellBook:GetSpell(5761)
local ShurikenStorm = Bastion.SpellBook:GetSpell(197835)
local BlackPowder = Bastion.SpellBook:GetSpell(319175)
local SecretTechnique = Bastion.SpellBook:GetSpell(280719)
local DarkBrew = Bastion.SpellBook:GetSpell(310454)
local IrideusFragment = Bastion.ItemBook:GetItem(193743)
local Healthstone = Bastion.ItemBook:GetItem(5512)
local WindscarWhetstone = Bastion.ItemBook:GetItem(137486)
local PurgeTarget = Bastion.UnitManager:CreateCustomUnit('purge', function(unit)
local purge = nil
Bastion.UnitManager:EnumNameplates(function(unit)
if unit:IsDead() then
return false
end
if not Player:CanSee(unit) then
return false
end
if Player:GetDistance(unit) > 40 then
return false
end
if unit:GetAuras():HasAnyStealableAura() then
purge = unit
return true
end
end)
if purge == nil then
purge = None
end
return purge
end)
local KickTarget = Bastion.UnitManager:CreateCustomUnit('kick', function(unit)
local purge = nil
Bastion.UnitManager:EnumNameplates(function(unit)
if unit:IsDead() then
return false
end
if not Player:CanSee(unit) then
return false
end
if Player:GetDistance(unit) > 40 then
return false
end
if Player:InMelee(unit) and unit:IsInterruptible(5) and Player:IsFacing(unit) then
purge = unit
return true
end
end)
if purge == nil then
purge = None
end
return purge
end)
local Tank = Bastion.UnitManager:CreateCustomUnit('tank', function(unit)
local tank = nil
Bastion.UnitManager:EnumFriends(function(unit)
if Player:GetDistance(unit) > 40 then
return false
end
if not Player:CanSee(unit) then
return false
end
if unit:IsDead() then
return false
end
if unit:IsTank() then
tank = unit
return true
end
return false
end)
if tank == nil then
tank = None
end
return tank
end)
local RuptureTarget = Bastion.UnitManager:CreateCustomUnit('rupture', function()
local target = nil
Bastion.UnitManager:EnumNameplates(function(unit)
if unit:IsDead() then
return false
end
if not Player:CanSee(unit) then
return false
end
if not Player:InMelee(unit) then
return false
end
if not unit:IsAffectingCombat() then
return false
end
if not Player:IsFacing(unit) then
return false
end
if (
not unit:GetAuras():FindMy(Rupture):IsUp() or
unit:GetAuras():FindMy(Rupture):GetRemainingTime() < 6
)
then
target = unit
return true
end
end)
if target == nil then
target = None
end
return target
end)
local DefaultAPL = Bastion.APL:New('default')
local AOEAPL = Bastion.APL:New('aoe')
local SpecialAPL = Bastion.APL:New('special')
local RacialsAPL = Bastion.APL:New('racials')
SpecialAPL:AddSpell(
Kick:CastableIf(function(self)
return KickTarget:Exists() and Player:InMelee(KickTarget) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling()
end):SetTarget(KickTarget)
)
SpecialAPL:AddSpell(
KidneyShot:CastableIf(function(self)
return KickTarget:Exists() and Player:InMelee(KickTarget) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and
Kick:GetTimeSinceLastCast() > 2 and
(Player:GetComboPoints(Target) >= 5 or
(
Player:GetComboPoints(Target) >= 4 and
(Player:GetAuras():FindMy(Broadside):IsUp() or Player:GetAuras():FindMy(Opportunity):IsUp())))
end):SetTarget(KickTarget)
)
SpecialAPL:AddSpell(
CheapShot:CastableIf(function(self)
return KickTarget:Exists() and Player:InMelee(KickTarget) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and Player:GetAuras():FindMy(Stealth):IsUp()
end):SetTarget(KickTarget)
)
SpecialAPL:AddSpell(
Stealth:CastableIf(function(self)
return self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and not Player:IsAffectingCombat() and
not Player:GetAuras():FindMy(Stealth):IsUp() and not IsMounted()
end):SetTarget(Player)
)
SpecialAPL:AddSpell(
CrimsonVial:CastableIf(function(self)
return self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and
Player:GetHealthPercent() < 70
end):SetTarget(Player)
)
SpecialAPL:AddSpell(
Shiv:CastableIf(function(self)
return PurgeTarget:Exists() and Player:InMelee(PurgeTarget) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and PurgeTarget:GetAuras():HasAnyStealableAura()
end):SetTarget(PurgeTarget)
)
SpecialAPL:AddSpell(
InstantPoison:CastableIf(function(self)
return self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and
not Player:GetAuras():FindMy(InstantPoison):IsUp() and not Player:IsMoving()
end):SetTarget(Player)
)
SpecialAPL:AddSpell(
AtrophicPosion:CastableIf(function(self)
return self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and
not Player:GetAuras():FindMy(AtrophicPosion):IsUp() and not Player:IsMoving()
end):SetTarget(Player)
)
SpecialAPL:AddSpell(
NumbingPoison:CastableIf(function(self)
return self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and
not Player:GetAuras():FindMy(NumbingPoison):IsUp() and not Player:IsMoving()
end):SetTarget(Player)
)
SpecialAPL:AddItem(
Healthstone:UsableIf(function(self)
return self:IsEquippedAndUsable() and
not Player:IsCastingOrChanneling() and
Player:GetHealthPercent() < 40
end):SetTarget(Player)
)
SpecialAPL:AddSpell(
TricksOfTheTrade:CastableIf(function(self)
return Tank:Exists() and self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and
Player:IsTanking(Target)
end):SetTarget(Tank)
)
SpecialAPL:AddSpell(
Evasion:CastableIf(function(self)
return self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and
Player:GetHealthPercent() < 40
end):SetTarget(Player)
)
SpecialAPL:AddItem(
IrideusFragment:UsableIf(function(self)
return self:IsEquippedAndUsable() and
not Player:IsCastingOrChanneling() and (Player:GetMeleeAttackers() > 2 or Target:IsBoss())
end):SetTarget(Player)
)
SpecialAPL:AddItem(
WindscarWhetstone:UsableIf(function(self)
return self:IsEquippedAndUsable() and
not Player:IsCastingOrChanneling() and (Player:GetMeleeAttackers() > 2 or Target:IsBoss())
end):SetTarget(Player)
)
-- Use Shadowstrike during Shadow Dance.
SpecialAPL:AddSpell(
Shadowstrike:CastableIf(function(self)
return Target:Exists() and Player:InMelee(Target) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and Vanish:GetTimeSinceLastCast() <= 3
end):SetTarget(Target)
)
RacialsAPL:AddSpell(
BagOfTricks:CastableIf(function(self)
return Target:Exists() and Player:InMelee(Target) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling()
end):SetTarget(Target)
)
-- Use Symbols of Death on cooldown as much as possible.
DefaultAPL:AddSpell(
SymbolsOfDeath:CastableIf(function(self)
return Target:Exists() and Player:InMelee(Target) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling()
end):SetTarget(Player)
)
-- Use Shadow Blades on cooldown.
DefaultAPL:AddSpell(
ShadowBlades:CastableIf(function(self)
return Target:Exists() and Player:InMelee(Target) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling()
end):SetTarget(Player)
)
-- Use Cold Blood before a finishing move, ideally before Secret Technique.
DefaultAPL:AddSpell(
ColdBlood:CastableIf(function(self)
return Target:Exists() and Player:InMelee(Target) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and
Player:GetComboPoints(Target) >= 5 and SecretTechnique:GetCooldownRemaining() <= 2 and
Player:GetAuras():FindMy(SliceAndDice):IsUp() and
Target:GetAuras():FindMy(Rupture):IsUp()
end):SetTarget(Player)
)
-- Line up Shuriken Tornado with Symbols of Death.
DefaultAPL:AddSpell(
ShurikenTornado:CastableIf(function(self)
return Target:Exists() and Player:InMelee(Target) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and
Player:GetAuras():FindMy(SymbolsOfDeath):IsUp()
end):SetTarget(Player)
)
-- Use Shadow Dance on cooldown as much as possible.
DefaultAPL:AddSpell(
ShadowDance:CastableIf(function(self)
return Target:Exists() and Player:InMelee(Target) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling()
end):SetTarget(Player)
)
-- Use Thistle Tea when low on energy.
DefaultAPL:AddSpell(
ThistleTea:CastableIf(function(self)
return Target:Exists() and Player:InMelee(Target) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and
Player:GetPowerDeficit() >= 100 and
ThistleTea:GetTimeSinceLastCast() >= 3
end):SetTarget(Player)
)
-- Use Finishing moves with 6 or more combo points (5 or more during Shadow Dance) with the following priority:
-- Cast Slice and Dice if it needs to be refreshed for maintenance or if it is not up.
DefaultAPL:AddSpell(
SliceAndDice:CastableIf(function(self)
return Target:Exists() and Player:InMelee(Target) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and
(Player:GetComboPoints(Target) >= 6 or
(Player:GetComboPoints(Target) >= 5 and
Player:GetAuras():FindMy(ShadowDanceAura):IsUp())) and
(
not Player:GetAuras():FindMy(SliceAndDice):IsUp() or
Player:GetAuras():FindMy(SliceAndDice):GetRemainingTime() < 12
)
end):SetTarget(Player)
)
-- Cast Rupture if it needs to be refreshed for maintenance or if it is not up.
DefaultAPL:AddSpell(
Rupture:CastableIf(function(self)
return Target:Exists() and Player:InMelee(Target) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and
(Player:GetComboPoints(Target) >= 6 or
(Player:GetComboPoints(Target) >= 5 and
Player:GetAuras():FindMy(ShadowDanceAura):IsUp())) and (
not Target:GetAuras():FindMy(Rupture):IsUp() or
Target:GetAuras():FindMy(Rupture):GetRemainingTime() < 12
)
end):SetTarget(Target)
)
-- Secret Technique - Best is to use it during Shadow Dance.
DefaultAPL:AddSpell(
SecretTechnique:CastableIf(function(self)
return Target:Exists() and Player:InMelee(Target) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and
(Player:GetComboPoints(Target) >= 6 or
(Player:GetComboPoints(Target) >= 5 and
Player:GetAuras():FindMy(ShadowDanceAura):IsUp()))
end):SetTarget(Target)
)
-- Cast Eviscerate.
DefaultAPL:AddSpell(
Eviscerate:CastableIf(function(self)
return Target:Exists() and Player:InMelee(Target) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and
(Player:GetComboPoints(Target) >= 6 or
(Player:GetComboPoints(Target) >= 5 and
Player:GetAuras():FindMy(ShadowDanceAura):IsUp()))
end):SetTarget(Target)
)
-- Vanish - Is a fairly weak cooldown. It is best to use on low combo points for a Shadowstrike cast. Use it after Secret Technique in Shadow Dance when playing with Danse Macabre.
DefaultAPL:AddSpell(
Vanish:CastableIf(function(self)
return Tank:Exists() and Target:Exists() and Player:InMelee(Target) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and
Player:GetComboPoints(Target) < 4
end):SetTarget(Player)
)
-- Use Combo Point builder with the following priority:
-- Use Gloomblade outside of Shadow Dance.
DefaultAPL:AddSpell(
Gloomblade:CastableIf(function(self)
return Target:Exists() and Player:InMelee(Target) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and
not Player:GetAuras():FindMy(ShadowDanceAura):IsUp()
end):SetTarget(Target)
)
-- Use Shadowstrike during Shadow Dance.
DefaultAPL:AddSpell(
Shadowstrike:CastableIf(function(self)
return Target:Exists() and Player:InMelee(Target) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and
Player:GetAuras():FindMy(ShadowDanceAura):IsUp()
end):SetTarget(Target)
)
-- AOE
-- Use Symbols of Death on cooldown as much as possible.
AOEAPL:AddSpell(
SymbolsOfDeath:CastableIf(function(self)
return Target:Exists() and Player:InMelee(Target) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling()
end):SetTarget(Player)
)
-- Use Shadow Blades on cooldown.
AOEAPL:AddSpell(
ShadowBlades:CastableIf(function(self)
return Target:Exists() and Player:InMelee(Target) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling()
end):SetTarget(Player)
)
-- Use Cold Blood before a finishing move.
AOEAPL:AddSpell(
ColdBlood:CastableIf(function(self)
return Target:Exists() and Player:InMelee(Target) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and
Player:GetComboPoints(Target) >= 5 and SecretTechnique:GetCooldownRemaining() <= 2 and
Player:GetAuras():FindMy(SliceAndDice):IsUp() and
Target:GetAuras():FindMy(Rupture):IsUp()
end):SetTarget(Player)
)
-- Line up Shuriken Tornado with Symbols of Death.
AOEAPL:AddSpell(
ShurikenTornado:CastableIf(function(self)
return Target:Exists() and Player:InMelee(Target) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and
Player:GetAuras():FindMy(SymbolsOfDeath):IsUp()
end):SetTarget(Target)
)
-- Use Shadow Dance on cooldown as much as possible.
AOEAPL:AddSpell(
ShadowDance:CastableIf(function(self)
return Target:Exists() and Player:InMelee(Target) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling()
end):SetTarget(Player)
)
-- Use Thistle Tea with Shadow Dance.
AOEAPL:AddSpell(
ThistleTea:CastableIf(function(self)
return Target:Exists() and Player:InMelee(Target) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and
Player:GetAuras():FindMy(ShadowDanceAura):IsUp() and Player:GetPowerDeficit() >= 70 and
ThistleTea:GetTimeSinceLastCast() >= 3
end):SetTarget(Player)
)
-- Use Finishing moves with 5 or more combo points with the following priority:
-- Cast Slice and Dice if it needs to be refreshed for maintenance or if it is not up.
AOEAPL:AddSpell(
SliceAndDice:CastableIf(function(self)
return Target:Exists() and Player:InMelee(Target) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and
(Player:GetComboPoints(Target) >= 6 or
(Player:GetComboPoints(Target) >= 5 and
Player:GetAuras():FindMy(ShadowDanceAura):IsUp())) and
(
not Player:GetAuras():FindMy(SliceAndDice):IsUp() or
Player:GetAuras():FindMy(SliceAndDice):GetRemainingTime() < 6
)
end):SetTarget(Target)
)
-- Cast Rupture if it needs to be refreshed for maintenance or if it is not up.
AOEAPL:AddSpell(
Rupture:CastableIf(function(self)
return Target:Exists() and Player:InMelee(Target) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and
(Player:GetComboPoints(Target) >= 6 or
(Player:GetComboPoints(Target) >= 5 and
Player:GetAuras():FindMy(ShadowDanceAura):IsUp())) and (
not Target:GetAuras():FindMy(Rupture):IsUp() or
Target:GetAuras():FindMy(Rupture):GetRemainingTime() < 12
)
end):SetTarget(Target)
)
-- Cast Rupture on all targets. (scam??)
-- AOEAPL:AddSpell(
-- Rupture:CastableIf(function(self)
-- return RuptureTarget:Exists() and Player:InMelee(RuptureTarget) and
-- self:IsKnownAndUsable() and
-- not Player:IsCastingOrChanneling() and
-- (Player:GetComboPoints(RuptureTarget) >= 6 or
-- (Player:GetComboPoints(RuptureTarget) >= 5 and
-- Player:GetAuras():FindMy(ShadowDanceAura):IsUp())) and (
-- not RuptureTarget:GetAuras():FindMy(Rupture):IsUp() or
-- RuptureTarget:GetAuras():FindMy(Rupture):GetRemainingTime() < 6
-- )
-- end):SetTarget(RuptureTarget)
-- )
AOEAPL:AddSpell(
SecretTechnique:CastableIf(function(self)
return Target:Exists() and Player:InMelee(Target) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and
(Player:GetComboPoints(Target) >= 6 or
(Player:GetComboPoints(Target) >= 5 and
Player:GetAuras():FindMy(ShadowDanceAura):IsUp()))
end):SetTarget(Target)
)
-- Cast Black Powder with 3 or more targets, 2 or more when talented into Dark Brew.
AOEAPL:AddSpell(
BlackPowder:CastableIf(function(self)
return Target:Exists() and Player:InMelee(Target) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and
(Player:GetMeleeAttackers() >= 3 or
(Player:GetMeleeAttackers() >= 2 and
DarkBrew:IsKnown()))
end):SetTarget(Target)
)
-- Cast Eviscerate.
AOEAPL:AddSpell(
Eviscerate:CastableIf(function(self)
return Target:Exists() and Player:InMelee(Target) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and
Player:GetComboPoints(Target) >= 5
end):SetTarget(Target)
)
-- Vanish - Is a fairly weak cooldown. It is best to use on low combo points for a Shadowstrike cast. Use it after Secret Technique in Shadow Dance when playing with Danse Macabre.
AOEAPL:AddSpell(
Vanish:CastableIf(function(self)
return Tank:Exists() and Target:Exists() and Player:InMelee(Target) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and
Player:GetComboPoints(Target) < 4
end):SetTarget(Player)
)
-- Use Combo Point builder with the following priority:
-- Use Shuriken Storm on 2 targets outside of Shadow Dance.
AOEAPL:AddSpell(
ShurikenStorm:CastableIf(function(self)
return Target:Exists() and Player:InMelee(Target) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and
Player:GetMeleeAttackers() >= 2 and
not Player:GetAuras():FindMy(ShadowDanceAura):IsUp()
end):SetTarget(Target)
)
-- Use Shadowstrike on 2 and 3 targets during Shadow Dance or to proc Premeditation.
AOEAPL:AddSpell(
Shadowstrike:CastableIf(function(self)
return Target:Exists() and Player:InMelee(Target) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and
Player:GetMeleeAttackers() >= 2 and
Player:GetAuras():FindMy(ShadowDanceAura):IsUp()
end):SetTarget(Target)
)
-- Use Shuriken Storm
AOEAPL:AddSpell(
ShurikenStorm:CastableIf(function(self)
return Target:Exists() and Player:InMelee(Target) and
self:IsKnownAndUsable() and
not Player:IsCastingOrChanneling() and
Player:GetMeleeAttackers() >= 4
end):SetTarget(Target)
)
SubModulue:Sync(function()
SpecialAPL:Execute()
if Player:GetMeleeAttackers() > 1 then
AOEAPL:Execute()
else
DefaultAPL:Execute()
end
RacialsAPL:Execute()
end)
Bastion:Register(SubModulue)

@ -60,7 +60,7 @@ end
-- Get the Items cooldown -- Get the Items cooldown
function Item:GetCooldown() function Item:GetCooldown()
return select(2, GetItemCooldown(self:GetID())) return select(2, C_Container.GetItemCooldown(self:GetID()))
end end
-- Return the Usable function -- Return the Usable function
@ -80,7 +80,7 @@ end
-- Get the Items cooldown remaining -- Get the Items cooldown remaining
function Item:GetCooldownRemaining() function Item:GetCooldownRemaining()
local start, duration = GetItemCooldown(self:GetID()) local start, duration = C_Container.GetItemCooldown(self:GetID())
return start + duration - GetTime() return start + duration - GetTime()
end end
@ -123,7 +123,7 @@ end
-- Check if the Item is on cooldown -- Check if the Item is on cooldown
function Item:IsOnCooldown() function Item:IsOnCooldown()
return select(2, GetItemCooldown(self:GetID())) > 0 return select(2, C_Container.GetItemCooldown(self:GetID())) > 0
end end
-- Check if the Item is usable -- Check if the Item is usable

@ -5,6 +5,7 @@ local Spell = {
CastableIfFunc = false, CastableIfFunc = false,
PreCastFunc = false, PreCastFunc = false,
OnCastFunc = false, OnCastFunc = false,
PostCastFunc = false,
wasLooking = false, wasLooking = false,
lastCastAt = 0, lastCastAt = 0,
conditions = {}, conditions = {},
@ -44,6 +45,10 @@ function Spell:New(id)
local unit, castGUID, spellID = ... local unit, castGUID, spellID = ...
if unit == "player" and spellID == self:GetID() then if unit == "player" and spellID == self:GetID() then
self.lastCastAt = GetTime() self.lastCastAt = GetTime()
if self:GetPostCastFunction() then
self:GetPostCastFunction()(self)
end
end end
end) end)
@ -55,6 +60,12 @@ function Spell:GetID()
return self.spellID return self.spellID
end end
-- Add post cast func
function Spell:PostCast(func)
self.PostCastFunc = func
return self
end
-- Get the spells name -- Get the spells name
function Spell:GetName() function Spell:GetName()
return GetSpellInfo(self:GetID()) return GetSpellInfo(self:GetID())
@ -129,6 +140,11 @@ function Spell:Cast(unit, condition)
end end
end end
-- Get post cast func
function Spell:GetPostCastFunction()
return self.PostCastFunc
end
-- Check if the spell is known -- Check if the spell is known
function Spell:IsKnown() function Spell:IsKnown()
local isKnown = IsSpellKnown(self:GetID()) local isKnown = IsSpellKnown(self:GetID())

@ -233,9 +233,9 @@ end
local isClassicWow = select(4, GetBuildInfo()) < 40000 local isClassicWow = select(4, GetBuildInfo()) < 40000
-- Check if two units are in melee -- Check if two units are in melee
function Unit:InMelee(unit) -- function Unit:InMelee(unit)
return UnitInMelee(self.unit, unit.unit) -- return UnitInMelee(self.unit, unit.unit)
end -- end
local losFlag = bit.bor(0x1, 0x10, 0x100000) local losFlag = bit.bor(0x1, 0x10, 0x100000)
@ -425,4 +425,39 @@ function Unit:IsBehind(unit)
return math.abs(angle) > 90 return math.abs(angle) > 90
end end
function Unit:GetMeleeBoost()
if IsPlayerSpell(196924) then
return 3
end
return 0
end
-- Melee calculation
-- float fMaxDist = fmaxf((float)(*(float*)((uintptr_t)this + 0x1BF8) + 1.3333) + *(float*)((uintptr_t)target + 0x1BF8), 5.0);
-- fMaxDist = fMaxDist + 1.0;
-- Vector3 myPos = ((WoWGameObject*)this)->GetPosition();
-- Vector3 targetPos = ((WoWGameObject*)target)->GetPosition();
-- return ((myPos.x - targetPos.x) * (myPos.x - targetPos.x)) + ((myPos.y - targetPos.y) * (myPos.y - targetPos.y)) + ((myPos.z - targetPos.z) * (myPos.z - targetPos.z)) <= (float)(fMaxDist * fMaxDist);
-- InMelee
function Unit:InMelee(unit)
local x, y, z = ObjectPosition(self.unit)
local x2, y2, z2 = ObjectPosition(unit.unit)
if not x or not x2 then
return false
end
local dist = math.sqrt((x - x2) ^ 2 + (y - y2) ^ 2 + (z - z2) ^ 2)
local maxDist = math.max((ObjectCombatReach(self.unit) + 1.3333) + ObjectCombatReach(unit.unit), 5.0)
maxDist = maxDist + 1.0 + self:GetMeleeBoost()
return dist <= maxDist
end
-- Get object id
function Unit:GetID()
return ObjectID(self.unit)
end
return Unit return Unit

Loading…
Cancel
Save