|
|
@ -12,7 +12,15 @@ local Spell = { |
|
|
|
lastCastAt = false, |
|
|
|
lastCastAt = false, |
|
|
|
conditions = {}, |
|
|
|
conditions = {}, |
|
|
|
target = false, |
|
|
|
target = false, |
|
|
|
release_at = false |
|
|
|
release_at = false, |
|
|
|
|
|
|
|
traits = { |
|
|
|
|
|
|
|
ignoreChanneling = false, |
|
|
|
|
|
|
|
ignoreFacing = false, |
|
|
|
|
|
|
|
ignoreLoS = false, |
|
|
|
|
|
|
|
ignoreGCD = false, |
|
|
|
|
|
|
|
ignoreMoving = false, |
|
|
|
|
|
|
|
targeted = false |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
local usableExcludes = { |
|
|
|
local usableExcludes = { |
|
|
@ -48,12 +56,20 @@ end |
|
|
|
|
|
|
|
|
|
|
|
-- Constructor |
|
|
|
-- Constructor |
|
|
|
---@param id number |
|
|
|
---@param id number |
|
|
|
|
|
|
|
---@param traits? table |
|
|
|
---@return Spell |
|
|
|
---@return Spell |
|
|
|
function Spell:New(id) |
|
|
|
function Spell:New(id, traits) |
|
|
|
local self = setmetatable({}, Spell) |
|
|
|
local self = setmetatable({}, Spell) |
|
|
|
|
|
|
|
|
|
|
|
self.spellID = id |
|
|
|
self.spellID = id |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if traits == nil then traits = {} end |
|
|
|
|
|
|
|
for k in pairs(traits) do |
|
|
|
|
|
|
|
if self.traits[k] ~= nil and traits[k] ~= nil then |
|
|
|
|
|
|
|
self.traits[k] = traits[k] |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
return self |
|
|
|
return self |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
@ -80,24 +96,53 @@ end |
|
|
|
-- Get the spells name |
|
|
|
-- Get the spells name |
|
|
|
---@return string |
|
|
|
---@return string |
|
|
|
function Spell:GetName() |
|
|
|
function Spell:GetName() |
|
|
|
|
|
|
|
if C_Spell.GetSpellInfo then |
|
|
|
|
|
|
|
local info = C_Spell.GetSpellInfo(self:GetID()) |
|
|
|
|
|
|
|
return info and info.name or nil |
|
|
|
|
|
|
|
end |
|
|
|
return GetSpellInfo(self:GetID()) |
|
|
|
return GetSpellInfo(self:GetID()) |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
-- Get the spells icon |
|
|
|
-- Get the spells icon |
|
|
|
---@return number |
|
|
|
---@return number |
|
|
|
function Spell:GetIcon() |
|
|
|
function Spell:GetIcon() |
|
|
|
|
|
|
|
if C_Spell.GetSpellInfo then |
|
|
|
|
|
|
|
local info = C_Spell.GetSpellInfo(self:GetID()) |
|
|
|
|
|
|
|
return info and info.iconID or nil |
|
|
|
|
|
|
|
end |
|
|
|
return select(3, GetSpellInfo(self:GetID())) |
|
|
|
return select(3, GetSpellInfo(self:GetID())) |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
-- Get the spells cooldown |
|
|
|
-- Get the spells cooldown |
|
|
|
---@return number |
|
|
|
---@return number |
|
|
|
function Spell:GetCooldown() |
|
|
|
function Spell:GetCooldown() |
|
|
|
|
|
|
|
if C_Spell.GetSpellCooldown then |
|
|
|
|
|
|
|
local info = C_Spell.GetSpellCooldown(self:GetID()) |
|
|
|
|
|
|
|
return info and info.duration or nil |
|
|
|
|
|
|
|
end |
|
|
|
return select(2, GetSpellCooldown(self:GetID())) |
|
|
|
return select(2, GetSpellCooldown(self:GetID())) |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
-- Get the full cooldown (time until all charges are available) |
|
|
|
-- Get the full cooldown (time until all charges are available) |
|
|
|
---@return number |
|
|
|
---@return number |
|
|
|
function Spell:GetFullRechargeTime() |
|
|
|
function Spell:GetFullRechargeTime() |
|
|
|
|
|
|
|
if C_Spell.GetSpellCooldown then |
|
|
|
|
|
|
|
local info = C_Spell.GetSpellCooldown(self:GetID()) |
|
|
|
|
|
|
|
if info.isEnabled == 0 then |
|
|
|
|
|
|
|
return 0 |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local chargeInfo = C_Spell.GetSpellCharges(self:GetID()) |
|
|
|
|
|
|
|
if chargeInfo.currentCharges == chargeInfo.maxCharges then |
|
|
|
|
|
|
|
return 0 |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if chargeInfo.currentCharges == 0 then |
|
|
|
|
|
|
|
return info.startTime + info.duration - GetTime() |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return chargeInfo.cooldownStartTime + chargeInfo.cooldownDuration - GetTime() |
|
|
|
|
|
|
|
end |
|
|
|
local start, duration, enabled = GetSpellCooldown(self:GetID()) |
|
|
|
local start, duration, enabled = GetSpellCooldown(self:GetID()) |
|
|
|
if enabled == 0 then |
|
|
|
if enabled == 0 then |
|
|
|
return 0 |
|
|
|
return 0 |
|
|
@ -136,6 +181,10 @@ end |
|
|
|
-- Get the spells cooldown remaining |
|
|
|
-- Get the spells cooldown remaining |
|
|
|
---@return number |
|
|
|
---@return number |
|
|
|
function Spell:GetCooldownRemaining() |
|
|
|
function Spell:GetCooldownRemaining() |
|
|
|
|
|
|
|
if C_Spell.GetSpellCooldown then |
|
|
|
|
|
|
|
local info = C_Spell.GetSpellCooldown(self:GetID()) |
|
|
|
|
|
|
|
return info and info.startTime + info.duration - GetTime() or nil |
|
|
|
|
|
|
|
end |
|
|
|
local start, duration = GetSpellCooldown(self:GetID()) |
|
|
|
local start, duration = GetSpellCooldown(self:GetID()) |
|
|
|
return start + duration - GetTime() |
|
|
|
return start + duration - GetTime() |
|
|
|
end |
|
|
|
end |
|
|
@ -143,6 +192,9 @@ end |
|
|
|
-- Get the spell count |
|
|
|
-- Get the spell count |
|
|
|
---@return number |
|
|
|
---@return number |
|
|
|
function Spell:GetCount() |
|
|
|
function Spell:GetCount() |
|
|
|
|
|
|
|
if C_Spell.GetSpellCastCount then |
|
|
|
|
|
|
|
return C_Spell.GetSpellCastCount(self:GetID()) |
|
|
|
|
|
|
|
end |
|
|
|
return GetSpellCount(self:GetID()) |
|
|
|
return GetSpellCount(self:GetID()) |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
@ -252,6 +304,8 @@ end |
|
|
|
-- Check if the spell is known |
|
|
|
-- Check if the spell is known |
|
|
|
---@return boolean |
|
|
|
---@return boolean |
|
|
|
function Spell:IsKnown() |
|
|
|
function Spell:IsKnown() |
|
|
|
|
|
|
|
local IsSpellKnown = C_Spell.IsSpellKnown and C_Spell.IsSpellKnown or IsSpellKnown |
|
|
|
|
|
|
|
local IsPlayerSpell = C_Spell.IsPlayerSpell and C_Spell.IsPlayerSpell or IsPlayerSpell |
|
|
|
local isKnown = IsSpellKnown(self:GetID()) |
|
|
|
local isKnown = IsSpellKnown(self:GetID()) |
|
|
|
local isPlayerSpell = IsPlayerSpell(self:GetID()) |
|
|
|
local isPlayerSpell = IsPlayerSpell(self:GetID()) |
|
|
|
return isKnown or isPlayerSpell |
|
|
|
return isKnown or isPlayerSpell |
|
|
@ -260,12 +314,20 @@ end |
|
|
|
-- Check if the spell is on cooldown |
|
|
|
-- Check if the spell is on cooldown |
|
|
|
---@return boolean |
|
|
|
---@return boolean |
|
|
|
function Spell:IsOnCooldown() |
|
|
|
function Spell:IsOnCooldown() |
|
|
|
|
|
|
|
if C_Spell.GetSpellCooldown then |
|
|
|
|
|
|
|
local info = C_Spell.GetSpellCooldown(self:GetID()) |
|
|
|
|
|
|
|
return info and info.duration > 0 |
|
|
|
|
|
|
|
end |
|
|
|
return select(2, GetSpellCooldown(self:GetID())) > 0 |
|
|
|
return select(2, GetSpellCooldown(self:GetID())) > 0 |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
-- Check if the spell is usable |
|
|
|
-- Check if the spell is usable |
|
|
|
---@return boolean |
|
|
|
---@return boolean |
|
|
|
function Spell:IsUsable() |
|
|
|
function Spell:IsUsable() |
|
|
|
|
|
|
|
if C_Spell.IsSpellUsable then |
|
|
|
|
|
|
|
local usable, noMana = C_Spell.IsSpellUsable(self:GetID()) |
|
|
|
|
|
|
|
return usable or usableExcludes[self:GetID()] and not noMana |
|
|
|
|
|
|
|
end |
|
|
|
local usable, noMana = IsUsableSpell(self:GetID()) |
|
|
|
local usable, noMana = IsUsableSpell(self:GetID()) |
|
|
|
return usable or usableExcludes[self:GetID()] and not noMana |
|
|
|
return usable or usableExcludes[self:GetID()] and not noMana |
|
|
|
end |
|
|
|
end |
|
|
@ -283,7 +345,44 @@ function Spell:Castable() |
|
|
|
return self:GetCastableFunction()(self) |
|
|
|
return self:GetCastableFunction()(self) |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
return self:IsKnownAndUsable() |
|
|
|
if not self:IsKnownAndUsable() then return false end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local player = Bastion.UnitManager:Get("player") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if self.traits.targeted then |
|
|
|
|
|
|
|
local target = self:GetTarget() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if not target or |
|
|
|
|
|
|
|
not target:Exists() then return false end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if not self:IsInRange(target) then return false end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if not self.traits.ignoreFacing then |
|
|
|
|
|
|
|
if not player:IsFacing(target) then return false end |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if not self.traits.ignoreLoS then |
|
|
|
|
|
|
|
if not player:CanSee(target) then return false end |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if not self.traits.ignoreCasting then |
|
|
|
|
|
|
|
if player:IsCasting() then return false end |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if not self.traits.ignoreChanneling then |
|
|
|
|
|
|
|
if player:IsChanneling() then return false end |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if not self.traits.ignoreGCD then |
|
|
|
|
|
|
|
if player:GetGCD() > C_Spell.GetSpellQueueWindow() then return false end |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if not self.traits.ignoreMoving then |
|
|
|
|
|
|
|
if self:GetCastLength() > 0 and player:IsMoving() then return false end |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return true |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
-- Set a script to check if the spell is castable |
|
|
|
-- Set a script to check if the spell is castable |
|
|
@ -350,6 +449,9 @@ end |
|
|
|
-- Check if the spell is castable and cast it |
|
|
|
-- Check if the spell is castable and cast it |
|
|
|
---@return boolean |
|
|
|
---@return boolean |
|
|
|
function Spell:HasRange() |
|
|
|
function Spell:HasRange() |
|
|
|
|
|
|
|
if C_Spell.SpellHasRange then |
|
|
|
|
|
|
|
return C_Spell.SpellHasRange(self:GetID()) |
|
|
|
|
|
|
|
end |
|
|
|
return SpellHasRange(self:GetName()) |
|
|
|
return SpellHasRange(self:GetName()) |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
@ -357,6 +459,10 @@ end |
|
|
|
---@return number |
|
|
|
---@return number |
|
|
|
---@return number |
|
|
|
---@return number |
|
|
|
function Spell:GetRange() |
|
|
|
function Spell:GetRange() |
|
|
|
|
|
|
|
if C_Spell.GetSpellInfo then |
|
|
|
|
|
|
|
local info = C_Spell.GetSpellInfo(self:GetID()) |
|
|
|
|
|
|
|
return info and info.minRange or nil, info and info.maxRange or nil |
|
|
|
|
|
|
|
end |
|
|
|
local name, rank, icon, castTime, minRange, maxRange, spellID, originalIcon = GetSpellInfo(self:GetID()) |
|
|
|
local name, rank, icon, castTime, minRange, maxRange, spellID, originalIcon = GetSpellInfo(self:GetID()) |
|
|
|
return maxRange, minRange |
|
|
|
return maxRange, minRange |
|
|
|
end |
|
|
|
end |
|
|
@ -365,6 +471,7 @@ end |
|
|
|
---@param unit Unit |
|
|
|
---@param unit Unit |
|
|
|
---@return boolean |
|
|
|
---@return boolean |
|
|
|
function Spell:IsInRange(unit) |
|
|
|
function Spell:IsInRange(unit) |
|
|
|
|
|
|
|
local IsSpellInRange = C_Spell.IsSpellInRange and C_Spell.IsSpellInRange or IsSpellInRange |
|
|
|
local hasRange = self:HasRange() |
|
|
|
local hasRange = self:HasRange() |
|
|
|
local inRange = IsSpellInRange(self:GetName(), unit:GetOMToken()) |
|
|
|
local inRange = IsSpellInRange(self:GetName(), unit:GetOMToken()) |
|
|
|
|
|
|
|
|
|
|
@ -406,20 +513,50 @@ end |
|
|
|
-- Get the spells charges |
|
|
|
-- Get the spells charges |
|
|
|
---@return number |
|
|
|
---@return number |
|
|
|
function Spell:GetCharges() |
|
|
|
function Spell:GetCharges() |
|
|
|
|
|
|
|
if C_Spell.GetSpellCharges then |
|
|
|
|
|
|
|
local info = C_Spell.GetSpellCharges(self:GetID()) |
|
|
|
|
|
|
|
return info and info.currentCharges or nil |
|
|
|
|
|
|
|
end |
|
|
|
return GetSpellCharges(self:GetID()) |
|
|
|
return GetSpellCharges(self:GetID()) |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
function Spell:GetMaxCharges() |
|
|
|
function Spell:GetMaxCharges() |
|
|
|
|
|
|
|
if C_Spell.GetSpellCharges then |
|
|
|
|
|
|
|
local info = C_Spell.GetSpellCharges(self:GetID()) |
|
|
|
|
|
|
|
return info and info.maxCharges or nil |
|
|
|
|
|
|
|
end |
|
|
|
return select(2, GetSpellCharges(self:GetID())) |
|
|
|
return select(2, GetSpellCharges(self:GetID())) |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
function Spell:GetCastLength() |
|
|
|
function Spell:GetCastLength() |
|
|
|
|
|
|
|
if C_Spell.GetSpellInfo then |
|
|
|
|
|
|
|
local info = C_Spell.GetSpellInfo(self:GetID()) |
|
|
|
|
|
|
|
return info and info.castTime or nil |
|
|
|
|
|
|
|
end |
|
|
|
return select(4, GetSpellInfo(self:GetID())) |
|
|
|
return select(4, GetSpellInfo(self:GetID())) |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
-- Get the spells charges |
|
|
|
-- Get the spells charges |
|
|
|
---@return number |
|
|
|
---@return number |
|
|
|
function Spell:GetChargesFractional() |
|
|
|
function Spell:GetChargesFractional() |
|
|
|
|
|
|
|
if C_Spell.GetSpellCharges then |
|
|
|
|
|
|
|
local info = C_Spell.GetSpellCharges(self:GetID()) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if info.currentCharges == info.maxCharges then |
|
|
|
|
|
|
|
return info.maxCharges |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if info.currentCharges == 0 then |
|
|
|
|
|
|
|
return 0 |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local timeSinceStart = GetTime() - info.cooldownStartTime |
|
|
|
|
|
|
|
local timeLeft = info.cooldownDuration - timeSinceStart |
|
|
|
|
|
|
|
local timePerCharge = info.cooldownDuration / info.maxCharges |
|
|
|
|
|
|
|
local chargesFractional = info.currentCharges + (timeLeft / timePerCharge) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return chargesFractional |
|
|
|
|
|
|
|
end |
|
|
|
local charges, maxCharges, start, duration = GetSpellCharges(self:GetID()) |
|
|
|
local charges, maxCharges, start, duration = GetSpellCharges(self:GetID()) |
|
|
|
|
|
|
|
|
|
|
|
if charges == maxCharges then |
|
|
|
if charges == maxCharges then |
|
|
@ -441,6 +578,10 @@ end |
|
|
|
-- Get the spells charges remaining |
|
|
|
-- Get the spells charges remaining |
|
|
|
---@return number |
|
|
|
---@return number |
|
|
|
function Spell:GetChargesRemaining() |
|
|
|
function Spell:GetChargesRemaining() |
|
|
|
|
|
|
|
if C_Spell.GetSpellCharges then |
|
|
|
|
|
|
|
local info = C_Spell.GetSpellCharges(self:GetID()) |
|
|
|
|
|
|
|
return info and info.currentCharges or nil |
|
|
|
|
|
|
|
end |
|
|
|
local charges, maxCharges, start, duration = GetSpellCharges(self:GetID()) |
|
|
|
local charges, maxCharges, start, duration = GetSpellCharges(self:GetID()) |
|
|
|
return charges |
|
|
|
return charges |
|
|
|
end |
|
|
|
end |
|
|
@ -546,6 +687,10 @@ end |
|
|
|
-- GetCost |
|
|
|
-- GetCost |
|
|
|
---@return number |
|
|
|
---@return number |
|
|
|
function Spell:GetCost() |
|
|
|
function Spell:GetCost() |
|
|
|
|
|
|
|
if C_Spell.GetSpellPowerCost then |
|
|
|
|
|
|
|
local info = C_Spell.GetSpellPowerCost(self:GetID()) |
|
|
|
|
|
|
|
return info and info.cost or 0 |
|
|
|
|
|
|
|
end |
|
|
|
local cost = GetSpellPowerCost(self:GetID()) |
|
|
|
local cost = GetSpellPowerCost(self:GetID()) |
|
|
|
return cost and cost.cost or 0 |
|
|
|
return cost and cost.cost or 0 |
|
|
|
end |
|
|
|
end |
|
|
|