local MH_CONSTANTS = { MH_TARG_ME = "player", MH_TARG_TARGET = "target", MH_TARG_TANK1 = "tank1", MH_CLASS_UNCNOWN = 0, MH_CLASS_WARRIOR_ARMS = 101, MH_CLASS_WARRIOR_FURY = 102, MH_CLASS_WARRIOR_PROTECTION = 103, MH_CLASS_PALADIN_HOLY = 201, MH_CLASS_PALADIN_PROTECTION = 202, MH_CLASS_PALADIN_RETRIBUTION = 203, MH_CLASS_HUNTER_BEAST_MASTERY = 301, MH_CLASS_HUNTER_MARKSMANSHIP = 302, MH_CLASS_HUNTER_SURVIVAL = 303, MH_CLASS_ROGUE_ASSASSINATION = 401, MH_CLASS_ROGUE_COMBAT = 402, MH_CLASS_ROGUE_SUBTLETY = 403, MH_CLASS_PRIEST_DISCIPLINE = 501, MH_CLASS_PRIEST_HOLY = 502, MH_CLASS_PRIEST_SHADOW = 503, MH_CLASS_DEATH_KNIGHT_BLOOD = 601, MH_CLASS_DEATH_KNIGHT_FROST = 602, MH_CLASS_DEATH_KNIGHT_UNHOLY = 603, MH_CLASS_SHAMAN_ELEMENTAL = 701, MH_CLASS_SHAMAN_ENHANCEMENT = 702, MH_CLASS_SHAMAN_RESTORATION = 703, MH_CLASS_MAGE_ARCANE = 801, MH_CLASS_MAGE_FIRE = 802, MH_CLASS_MAGE_FROST = 803, MH_CLASS_WARLOCK_AFFLICTION = 901, MH_CLASS_WARLOCK_DEMONOLOGY = 902, MH_CLASS_WARLOCK_DESTRUCTION = 903, MH_CLASS_MONK_BREWMASTER = 1001, MH_CLASS_MONK_MISTWEAVER = 1002, MH_CLASS_MONK_WINDWALKER = 1003, MH_CLASS_DRUID_BALANCE = 1101, MH_CLASS_DRUID_FERAL = 1102, MH_CLASS_DRUID_GUARDIAN = 1103, MH_CLASS_DRUID_RESTORATION = 1104 } for k,v in pairs(MH_CONSTANTS) do loadstring(k .. " = " .. v)() end local mh = {} mh.helpers = { warlock = { -- Количество раскалённых угольков у дестро лока burningEmbers = function() return UnitPower("player", SPELL_POWER_BURNING_EMBERS, true) / 10 end }, druid = { -- Количеств серий приёмов у ферала / роги comboPoints = function() return UnitPower("player", 4) end }, paladin = { -- Проверка состояния заклинания серафим -- 0 : Сейчас идёт КД -- 1 : Нехватает силы света -- 2 : Можно кастовать seraphim = function() local start, duration, enabled = GetSpellCooldown("Серафим") local isUsable, notEnoughMana = IsUsableSpell("Серафим") if start ~= 0 or duration ~= 0 then return 0 elseif isUsable==true then return 2 else return 1 end end } } -- Other fastcall helper functions function mh.getMyClass() local class_id = select(3, UnitClass("player")); local spec_id = GetSpecialization() if (( class_id == 0 ) or ( spec_id == 0 )) then return MH_CLASS_UNCNOWN end return class_id * 100 + spec_id end function mh.canCast(SpellName) local start, duration, enabled = GetSpellCooldown(SpellName) -- cooldown local isUsable, notEnoughMana = IsUsableSpell(SpellName) -- usable if start == 0 and duration == 0 and enabled == 1 and isUsable==true and notEnoughMana==false then return true else return false end end function mh.UnitHp(target) local hpnow , hpmax = UnitHealth(target) , UnitHealthMax(target) return ceil((hpnow / hpmax) * 100) , hpnow end function mh.haveBuff(Target, BuffName) local i = 0 local name, count, expiration repeat -- from 1 to 40 i = i + 1 name, _, _, count, _, _, expiration = UnitBuff(Target, i) if ( name == BuffName ) then if ( expiration > 0 ) then expiration = format("%.2f", -1 * (GetTime()-expiration)) * 1 end return true, expiration, count end if ( i >= 40 ) then -- if i = 40 & not true then false return false end until not name end function mh.haveDebuff(Target, DebuffName, CollectMyDebufs) local i = 0 local name, count, expiration repeat -- from 1 to 40 i = i + 1 name, _, _, count, _, _, expiration, unitCaster = UnitDebuff(Target, i) if (( CollectMyDebufs ) and ( unitCaster == "player")) then if ( name == DebuffName ) then if ( expiration > 0 ) then expiration = format("%.2f", -1 * (GetTime()-expiration)) * 1 end return true, expiration, count end end if ( i >= 40 ) then -- if i = 40 & not true then false return false end until not name end function mh.unitCastingOrTunelling(Target, SpellName) spell, _, _, _, _, endTime, _, _, interrupt = UnitCastingInfo(Target) if ( spell ~= SpellName ) then return false end if ( endTime > 0 ) then endTime = format("%.2f", endTime / 1000 - GetTime()) * 1 end return spell, endTime, interrupt end function mh.getMyCurrentCasting() spell, _, _, _, _, endTime = UnitCastingInfo("player") if ( spell == nil ) then return false end if ( endTime > 0 ) then endTime = format("%.2f", endTime / 1000 - GetTime()) * 1 end return spell, endTime end function mh.SelectRotation() local myhpprc, myhpval = mh.UnitHp("player") local class = mh.getMyClass() if ( class == MH_CONSTANTS["MH_CLASS_PALADIN_RETRIBUTION"] ) then return function() if mh.canCast("Молот гнева") then return "Молот гнева" end if mh.canCast("Смертный приговор") then return "Смертный приговор" end if IsShiftKeyDown() and mh.canCast("Гнев карателя") then return "Гнев карателя" end --if myhpprc < 20 then --if mh.canCast -- if mh.canCast("Вердикт храмовника") then -- return "Торжество" -- end if mh.canCast("Вердикт храмовника") then return "Вердикт храмовника" end if mh.haveBuff("player", "Воин богов") and mh.canCast("Божественная буря") then return "Божественная буря" end if mh.canCast("Удар воина Света") then return "Удар воина Света" end if mh.canCast("Правосудие") then return "Правосудие" end if mh.canCast("Экзорцизм") then return "Экзорцизм" end return nil end end if ( class == MH_CONSTANTS["MH_CLASS_WARLOCK_DESTRUCTION"] ) then return function() local embers = mh.helpers["warlock"]["burningEmbers"]() local burn, burnExp = mh.haveDebuff("target", "Жертвенный огонь", true) local castingSpell, castingDuration = mh.getMyCurrentCasting() if ( castingDuration ~= nil ) and ( castingDuration > 0.2 ) then return nil end -- CastSpellByName flood protection if ( not burn ) or ( burnExp < 1.5 ) then if mh.canCast("Жертвенный Огонь") and (castingSpell ~= "Жертвенный огонь") then return "Жертвенный Огонь" end end if ( embers > 2 ) and mh.canCast("Стрела Хаоса") then return "Стрела Хаоса" end return "Испепеление" end end if ( class == MH_CONSTANTS["MH_CLASS_DRUID_FERAL"] ) then return function() local myhpprc = mh.UnitHp("player") local combop = mh.helpers["druid"]["comboPoints"]() -- Защита if myhpprc < 75 then if ( myhpprc < 25 and (not mh.haveBuff("player", "Инстинкты выживания"))) then if mh.canCast("Инстинкты выживания") then return "Инстинкты выживания" end end if mh.haveBuff("player", "Стремительность хищника") then if mh.canCast("Целительное прикосновение") then return "Целительное прикосновение" end end end if IsShiftKeyDown() and mh.canCast("Тигриное неистовство") then return "Тигриное неистовство" end -- Дикий рёв постоянно придерживать if ( not mh.haveBuff("player", "Дикий рев") and combop > 2 ) then if mh.canCast("Дикий рев") then return "Дикий рев" else return nil end end -- Драть как суку if combop == 5 then if not mh.haveDebuff("target", "Разорвать", true) then if mh.canCast("Разорвать") then return "Разорвать" else return nil end else if mh.canCast("Свирепый укус") then return "Свирепый укус" else return nil end end end -- На противнике придерживать рану if (not mh.haveDebuff("target", "Глубокая рана", true) and mh.canCast("Глубокая рана")) then return "Глубокая рана" end -- Набор кровожадности if mh.canCast("Полоснуть") then return "Полоснуть" end end end end function SlashCmdList.HELLOWORLD(msg, editbox) RottorMain() end SLASH_HELLOWORLD1, SLASH_HELLOWORLD2 = '/xxx', '/xxxgo' -- Основной роттор function RottorMain() local rottorPtr = mh.SelectRotation() if ( rottorPtr == nil ) then print("Rotation for this spec not found!") return end local spellNext = rottorPtr() if spellNext ~= nil then print(spellNext) CastSpellByName(spellNext) end end function main() SlashCmdList["HELLOWORLD"] = RottorMain end main()