vanilla-wow-addons – Rev 1
?pathlinks?
--[[---------------------------------------------------------------------------------
locals
------------------------------------------------------------------------------------]]
BINDING_HEADER_SMARTRES = "SmartRes"
BINDING_NAME_RES = "Resurrect"
local resTable = {}
local resAttempt = {}
local enabled = {}
local isCasting = nil
local resSpell = ""
local corpseCount = 0
local class = ""
local BS = AceLibrary("Babble-Spell-2.2")
local resSpell = {
PRIEST = BS["Resurrection"],
SHAMAN = BS["Ancestral Spirit"],
PALADIN = BS["Redemption"]
}
local locals = {
NotGrouped = "You're not in a group.",
NotInRange = "No one in range to res or you're out of mana.",
NoDeadUnits = "Coudnt't find any dead (non-released) units.",
AllDeadRessed = "All dead units are already being ressed.",
}
--[[---------------------------------------------------------------------------------
defaults and AceOptions table
------------------------------------------------------------------------------------]]
local defaults = {
ResMessage = "Ressing: %s",
ChannelType = "SAY",
CustomChannel = "OFF",
CustomChannelName = nil
}
local options = {
type = 'group',
args = {
res = {
type = 'execute',
name = "Resurrect",
desc = "Will attempt to resurrect a grouped player",
func = function()
SmartRes:Resurrect()
end
},
msgtype = {
type = 'text',
name = "Message Type",
desc = "Set the Res Message output channel type. (Valid Types: SAY, YELL, PARTY, RAID, GUILD, OFFICER) Setting the channel type to 'OFF' will disable this feature.",
validate = {"SAY", "YELL", "PARTY", "RAID", "GUILD", "OFFICER", "OFF"},
get = function() return SmartRes.db.profile.ChannelType end,
set = function(text)
SmartRes.db.profile.ChannelType = text
end
},
msg = {
type = 'text',
name = "Res Message",
desc = "Change the Res Message.",
get = function()
return string.format(SmartRes.db.profile.ResMessage, "%s")
end,
set = function(text)
SmartRes.db.profile.ResMessage = text
end,
usage = "<msg> (Example: Ressing: %s) **Be sure to include %s where you want the target's name to be**"
},
chan = {
type = 'text',
name = "Custom Channel",
desc = "Send the Res Message to a custom chat channel.",
validate = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "OFF"},
get = function()
if SmartRes.db.profile.CustomChannel ~= "OFF" then
return SmartRes.db.profile.CustomChannel..". "..SmartRes.db.profile.CustomChannelName
end
end,
set = function(num)
SmartRes:SetCustomChan(num)
end
},
reset = {
type = 'execute',
name = "Reset",
desc = "Resets SmartRes to the default settings",
func = function()
SmartRes:ResetDB("profile")
SmartRes:Print("All options have been reset to default.")
end
}
}
}
--[[---------------------------------------------------------------------------------
Initialization
------------------------------------------------------------------------------------]]
SmartRes = AceLibrary("AceAddon-2.0"):new("AceEvent-2.0", "AceDB-2.0", "AceConsole-2.0")
function SmartRes:OnInitialize()
self:RegisterDB("SmartResDB")
self:RegisterDefaults('profile', defaults )
self:RegisterChatCommand({ "/smartres", "/sr" }, options )
end
function SmartRes:OnEnable()
_,class = UnitClass("player")
if not resSpell[class] then return end
enabled = true
self:RegisterEvent("SPELLCAST_START", function() isCasting = true end )
self:RegisterEvent("SPELLCAST_STOP", function() isCasting = false end )
self:RegisterEvent("SPELLCAST_FAILED", function() isCasting = false end )
self:RegisterEvent("SPELLCAST_INTERRUPTED", function() isCasting = false end )
end
function SmartRes:OnDisable()
enabled = nil
end
--[[---------------------------------------------------------------------------------
The real stuff
------------------------------------------------------------------------------------]]
function SmartRes:SetCustomChan(num)
if num == "OFF" then
self.db.profile.CustomChannel = "OFF"
self.db.profile.CustomChannelName = nil
return
end
local id, channame = GetChannelName(num)
if id ~= 0 then
self.db.profile.CustomChannel = id
self.db.profile.CustomChannelName = channame
end
end
function SmartRes:Resurrect()
if not enabled then
self:Print("Mod not 'enabled', bypassing function")
return
end
if isCasting then return end
if GetNumPartyMembers() == 0 then
self:Print(locals.NotGrouped)
return
end
resTable = {}
if UnitInRaid("player") then
self:BuildResTable("raid")
else
self:BuildResTable("party")
end
if corpseCount == 0 then
self:Print(locals.NoDeadUnits)
return
end
if corpseCount - corpseCountRessed == 0 then
self:Print(locals.AllDeadRessed)
return
end
table.sort( resTable, function(a,b) return a[2] < b[2] end )
CastSpellByName(resSpell[class],0)
local corpse = self:ChooseDeadUnitInRange()
if corpse then
SpellTargetUnit(corpse)
resAttempt[UnitName(corpse)] = GetTime()
if not SpellIsTargeting() then
if self.db.profile.ChannelType ~= "OFF" then
SendChatMessage(string.format(self.db.profile.ResMessage, UnitName(corpse)), self.db.profile.ChannelType)
end
if self.db.profile.CustomChannel ~= "OFF" then
local chanid, channame = GetChannelName(self.db.profile.CustomChannel)
if (chanid == self.db.profile.CustomChannel and channame == self.db.profile.CustomChannelName) then
SendChatMessage(string.format(self.db.profile.ResMessage, UnitName(corpse)), "CHANNEL", nil, self.db.profile.CustomChannel)
end
end
else
SpellStopTargeting()
end
else
SpellStopTargeting()
self:Print(locals.NotInRange)
end
end
function SmartRes:BuildResTable(type)
local x
if type == "raid" then x = GetNumRaidMembers()
elseif type == "party" then x = GetNumPartyMembers()
end
corpseCount = 0
corpseCountRessed = 0
for i = 1, x do
if UnitIsConnected(type..i) then
if UnitIsDead(type..i) then
corpseCount = corpseCount + 1
if not self:UnitDoesntNeedRes(UnitName(type..i)) then
tinsert(resTable, { type..i, self:GetResModifier(type..i) })
else
corpseCountRessed = corpseCountRessed + 1
end
else
local name = UnitName(type..i)
if resAttempt[name] then
resAttempt[name] = nil
end
end
end
end
end
function SmartRes:GetResModifier(unit)
local m = 0
local _,c = UnitClass(unit)
if c == "PRIEST" then m = 0
elseif c == "SHAMAN" then m = 5
elseif c == "PALADIN" then m = 5
elseif c == "DRUID" then m = 10
elseif c == "MAGE" then m = 15
elseif c == "WARRIOR" then m = 20
elseif c == "WARLOCK" then m = 25
elseif c == "HUNTER" then m = 30
elseif c == "ROGUE" then m = 35
end
if UnitInParty(unit) then m = m - 1 end
-- we don't want to get stuck on someone out of LOS
m = m + math.random(5)
return m
end
function SmartRes:UnitDoesntNeedRes(name)
-- check who we attempted to res in the past minute:
if resAttempt[name] then
if GetTime() - resAttempt[name] < 60 then
return true
end
end
-- see who is being ressed by others this moment
if CT_RA_Ressers then
for key, val in CT_RA_Ressers do
if val == name then
return true
end
end
end
if oRA_Resurrection and oRA_Resurrection.ressers then
for key, val in oRA_Resurrection.ressers do
if val == name then
return true
end
end
end
if oRAOResurrection and oRAOResurrection.ressers then
for key, val in oRAOResurrection.ressers do
if val == name then
return true
end
end
end
-- see who's ressed already
if CT_RA_Stats and
CT_RA_Stats[name] and
CT_RA_Stats[name]["Ressed"] and
CT_RA_Stats[name]["Ressed"] == 1 then
return true
end
return false
end
function SmartRes:ChooseDeadUnitInRange()
for key, val in resTable do
if SpellCanTargetUnit(val[1]) then
return val[1]
end
end
return nil
end