You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

248 lines
8.3 KiB

--- ============================ HEADER ============================
--- ======= LOCALIZE =======
-- Addon
local addonName, HR = ...;
-- HeroLib
local HL = HeroLib;
local Cache, Utils = HeroCache, HL.Utils;
local Unit = HL.Unit;
local Player = Unit.Player;
local Target = Unit.Target;
local Spell = HL.Spell;
local Item = HL.Item;
-- Lua
local pairs = pairs;
local gsub = string.gsub;
-- API
local UnitInParty = UnitInParty
local UnitInRaid = UnitInRaid
-- File Locals
HR.Commons = {};
local Commons = {};
HR.Commons.Everyone = Commons;
local Settings = HR.GUISettings.General;
local AbilitySettings = HR.GUISettings.Abilities;
--- ============================ CONTENT ============================
-- Num/Bool helper functions
function Commons.num(val)
if val then return 1 else return 0 end
end
function Commons.bool(val)
return val ~= 0
end
-- Is the current target valid?
function Commons.TargetIsValid()
return Target:Exists() and Player:CanAttack(Target) and not Target:IsDeadOrGhost();
end
-- Is the current unit valid during cycle?
function Commons.UnitIsCycleValid(Unit, BestUnitTTD, TimeToDieOffset)
return not Unit:IsFacingBlacklisted() and not Unit:IsUserCycleBlacklisted() and (not BestUnitTTD or Unit:FilteredTimeToDie(">", BestUnitTTD, TimeToDieOffset));
end
-- Is it worth to DoT the unit?
function Commons.CanDoTUnit(Unit, HealthThreshold)
return Unit:Health() >= HealthThreshold or Unit:IsDummy();
end
-- Interrupt
function Commons.Interrupt(Range, Spell, Setting, StunSpells)
if Settings.InterruptEnabled and Target:IsInterruptible() and Target:IsInRange(Range) then
if Spell:IsCastable(true) then
if HR.Cast(Spell, Setting) then return "Cast " .. Spell:Name() .. " (Interrupt)"; end
elseif Settings.InterruptWithStun and Target:CanBeStunned() then
if StunSpells then
for i = 1, #StunSpells do
if StunSpells[i][1]:IsCastable() and StunSpells[i][3]() then
if HR.Cast(StunSpells[i][1]) then return StunSpells[i][2]; end
end
end
end
end
end
end
-- Is in Solo Mode?
function Commons.IsSoloMode()
return Settings.SoloMode and not Player:IsInRaidArea() and not Player:IsInDungeonArea();
end
-- Cycle Unit Helper
function Commons.CastCycle(Object, Enemies, Condition, OutofRange, OffGCD, DisplayStyle)
if Condition(Target) then
return HR.Cast(Object, OffGCD, DisplayStyle, OutofRange)
end
if HR.AoEON() then
local TargetGUID = Target:GUID()
for _, CycleUnit in pairs(Enemies) do
if CycleUnit:GUID() ~= TargetGUID and not CycleUnit:IsFacingBlacklisted() and not CycleUnit:IsUserCycleBlacklisted() and Condition(CycleUnit) then
HR.CastLeftNameplate(CycleUnit, Object)
break
end
end
end
end
-- Target If Helper
function Commons.CastTargetIf(Object, Enemies, TargetIfMode, TargetIfCondition, Condition, OutofRange, OffGCD, DisplayStyle)
local TargetCondition = (not Condition or (Condition and Condition(Target)))
if not HR.AoEON() and TargetCondition then
return HR.Cast(Object, OffGCD, DisplayStyle, OutofRange)
end
if HR.AoEON() then
local BestUnit, BestConditionValue = nil, nil
for _, CycleUnit in pairs(Enemies) do
if not CycleUnit:IsFacingBlacklisted() and not CycleUnit:IsUserCycleBlacklisted() and (CycleUnit:AffectingCombat() or CycleUnit:IsDummy())
and (not BestConditionValue or Utils.CompareThis(TargetIfMode, TargetIfCondition(CycleUnit), BestConditionValue)) then
BestUnit, BestConditionValue = CycleUnit, TargetIfCondition(CycleUnit)
end
end
if BestUnit then
if TargetCondition and (BestUnit:GUID() == Target:GUID() or BestConditionValue == TargetIfCondition(Target)) then
return HR.Cast(Object, OffGCD, DisplayStyle, OutofRange)
elseif ((Condition and Condition(BestUnit)) or not Condition) then
HR.CastLeftNameplate(BestUnit, Object)
end
end
end
end
function Commons.GroupBuffMissing(spell)
local range = 40
local buffIDs = { 381732, 381741, 381746, 381748, 381749, 381750, 381751, 381752, 381753, 381754, 381756, 381757, 381758 }
if spell:Name() == "Battle Shout" then range = 100 end
local Group
if UnitInRaid("player") then
Group = Unit.Raid
elseif UnitInParty("player") then
Group = Unit.Party
else
return false
end
for _, Char in pairs(Group) do
if spell:Name() == "Blessing of the Bronze" then
if Char:Exists() and Char:IsInRange(range) then
for _, v in pairs(buffIDs) do
if Char:BuffUp(HL.Spell(v), true) then return false end
end
return true
end
else
if Char:Exists() and Char:IsInRange(range) and Char:BuffDown(spell, true) then
return true
end
end
end
return false
end
function Commons.GetCurrentEmpowerData(stage)
local CurrentStage = 0
local StagesData = {}
_, _, _, StartTimeMS, EndTimeMS, _, _, _, _, StageTotal = UnitChannelInfo("player")
if StageTotal and StageTotal > 0 then
local LastFinish = 0
for i = 1, StageTotal do
StagesData[i] = {
Start = LastFinish,
Finish = LastFinish + GetUnitEmpowerStageDuration("player", i - 1) / 1000
}
HR.Print(" Start"..i..": "..StagesData[i].Start)
HR.Print("Finish"..i..": "..StagesData[i].Finish)
LastFinish = StagesData[i].Finish
if StartTimeMS / 1000 + LastFinish <= GetTime() then
CurrentStage = i
end
end
end
if stage then
return CurrentStage
else
return StagesData
end
end
-- Check if player's selected potion type is ready
function Commons.PotionSelected()
local Classes = { "Warrior", "Paladin", "Hunter", "Rogue", "Priest", "DeathKnight", "Shaman", "Mage", "Warlock", "Monk", "Druid", "DemonHunter", "Evoker" }
local ClassNum = Cache.Persistent.Player.Class[3]
local Class = Classes[ClassNum]
local Specs = {
-- DeathKnight
[250] = "Blood", [251] = "Frost", [252] = "Unholy",
-- DemonHunter
[577] = "Havoc", [581] = "Vengeance",
-- Druid
[102] = "Balance", [103] = "Feral", [104] = "Guardian", [105] = "Restoration",
-- Evoker
[1467] = "Devastation", [1468] = "Preservation", [1473] = "Augmentation",
-- Hunter
[253] = "BeastMastery", [254] = "Marksmanship", [255] = "Survival",
-- Mage
[62] = "Arcane", [63] = "Fire", [64] = "Frost",
-- Monk
[268] = "Brewmaster", [269] = "Windwalker", [270] = "Mistweaver",
-- Paladin
[65] = "Holy", [66] = "Protection", [70] = "Retribution",
--Priest
[256] = "Discipline", [257] = "Holy", [258] = "Shadow",
-- Rogue
[259] = "Assassination", [260] = "Outlaw", [261] = "Subtlety",
-- Shaman
[262] = "Elemental", [263] = "Enhancement", [264] = "Restoration",
-- Warlock
[265] = "Affliction", [266] = "Demonology", [267] = "Destruction",
-- Warrior
[71] = "Arms", [72] = "Fury", [73] = "Protection",
}
local SpecNum = Cache.Persistent.Player.Spec[1]
local Spec = Specs[SpecNum]
local PotionType = HR.GUISettings.APL[Class][Spec].PotionType.Selected
local PowerPotionIDs = {
-- Fleeting Ultimate Power
191914, 191913, 191912,
-- Fleeting Power
191907, 191906, 191905,
-- Ultimate Power
191383, 191382, 191381,
-- Power
191389, 191388, 191387
}
local FrozenFocusIDs = { 191365, 191364, 191363 }
local ChilledClarityIDs = { 191368, 191367, 191366 }
local ShockingDisclosureIDs = { 191401, 191400, 191399 }
if PotionType == "Power" then
for _, PotionID in ipairs(PowerPotionIDs) do
if Item(PotionID):IsUsable() then
return Item(PotionID)
end
end
elseif PotionType == "Frozen Focus" then
for _, PotionID in ipairs(FrozenFocusIDs) do
if Item(PotionID):IsUsable() then
return Item(PotionID)
end
end
elseif PotionType == "Chilled Clarity" then
for _, PotionID in ipairs(ChilledClarityIDs) do
if Item(PotionID):IsUsable() then
return Item(PotionID)
end
end
elseif PotionType == "Shocking Disclosure" then
for _, PotionID in ipairs(ShockingDisclosureIDs) do
if Item(PotionID):IsUsable() then
return Item(PotionID)
end
end
else
return nil
end
end