diff --git a/ChatManager.lua b/ChatManager.lua
index f9d92f9..0a0bb08 100644
--- a/ChatManager.lua
+++ b/ChatManager.lua
@@ -108,8 +108,10 @@ end
-- @param msg The message to send.
-- @param channel The channel to send to.
-- @param target Player or channel index to send message to.
+-- @param isBN Is this message targeted to a BNet friend?
+-- @param smartSay Fallback to SAY instead of local logging if not in group
--
-function CM:SendMessage(msg, channel, target, isBN)
+function CM:SendMessage(msg, channel, target, isBN, smartSay)
isBN = isBN or false
if not self.Settings.LOCAL_ONLY then
-- Sanitize message
@@ -122,8 +124,12 @@ function CM:SendMessage(msg, channel, target, isBN)
elseif GT:IsGroup() then
channel = "PARTY"
else
- C.Logger:Normal(msg)
- return
+ if smartSay then
+ channel = "SAY"
+ else
+ C.Logger:Normal(msg)
+ return
+ end
end
elseif channel == "RAID_WARNING" then
if not GT:IsRaidLeaderOrAssistant() then
diff --git a/Command.lua b/Command.lua
index 719df1f..d6206b0 100644
--- a/Command.lua
+++ b/Command.lua
@@ -54,6 +54,7 @@ local CM
local PM
local RM
local AC
+local DM
local log
--- Initialize Command.
@@ -68,6 +69,7 @@ function C:Init()
PM = self.PlayerManager
RM = self.RollManager
AC = self.AddonComm
+ DM = self.DeathManager
log = self.Logger
self:LoadSavedVars()
log:Normal(L("ADDON_LOAD"))
@@ -109,6 +111,7 @@ function C:LoadSavedVars()
PM:Init()
RM:Init()
AC:Init()
+ DM:Init()
Cmd:Init()
log:SetDebug(self.Settings.DEBUG)
self.Global.VERSION = self.VarVersion
diff --git a/CommandManager.lua b/CommandManager.lua
index e5b157e..f866d71 100644
--- a/CommandManager.lua
+++ b/CommandManager.lua
@@ -66,6 +66,7 @@ local RM = C.RollManager
local LM = C.LootManager
local GT = C.GroupTools
local AM = C.AuthManager
+local DM = C.DeathManager
local Chat
local CES = C.Extensions.String
local CET = C.Extensions.Table
@@ -257,6 +258,26 @@ CM:Register({"set", "s"}, PM.Access.Groups.Admin.Level, function(args, sender, i
return C:DisableGroupInvite()
end
return false, "CM_SET_GROUPINVITE_USAGE"
+ elseif args[1]:match("^d") then -- DeathManager
+ if #args < 2 then
+ if C.DeathManager:IsEnabled() then
+ return "CM_SET_DM_ISENABLED"
+ else
+ return "CM_SET_DM_ISDISABLED"
+ end
+ end
+ if isChat then -- Players are only allowed to check status of DeathManager
+ return false, "CM_ERR_NOCHAT"
+ end
+ args[2] = args[2]:lower()
+ if args[2]:match("^[eay]") then -- Enable
+ return C.DeathManager:Enable()
+ elseif args[2]:match("^[dn]") then -- Disable
+ return C.DeathManager:Disable()
+ elseif args[2]:match("^t") then -- Toggle
+ return C.DeathManager:Toggle()
+ end
+ return false, "CM_SET_DM_USAGE"
end
return false, "CM_SET_USAGE"
end, "CM_SET_HELP")
@@ -552,7 +573,7 @@ end, "CM_LEAVELFG_HELP")
-- I'm keeping this command here for the future, if there will ever be a way to make this work.
CM:Register({"acceptlfg", "acceptlfd", "joinlfg", "joinlfd"}, PM.Access.Groups.User.Level, function(args, sender, isChat)
if not C.Settings.DEBUG then
- return false, "CM_ERR_DISABLED"
+ return false, "CM_ERR_PERMDISABLED"
end
local exists = (select(1, GetLFGProposal()))
if not QM.QueuedByCommand then
@@ -875,6 +896,20 @@ CM:Register({"raiddifficulty", "raiddiff", "rd", "raidmode", "rm"}, PM.Access.Gr
return GT:SetRaidDifficulty(diff)
end, "CM_RAIDMODE_HELP")
+CM:Register({"release", "rel"}, PM.Access.Groups.Op.Level, function(args, sender, isChat)
+ if not DM:IsEnabled() then
+ return false, "CM_ERR_DISABLED"
+ end
+ return DM:Release()
+end, "CM_RELEASE_HELP")
+
+CM:Register({"resurrect", "ressurrect", "ress", "res"}, PM.Access.Groups.User.Level, function(args, sender, isChat)
+ if not DM:IsEnabled() then
+ return false, "CM_ERR_DISABLED"
+ end
+ return DM:Resurrect()
+end, "CM_RESURRECT_HELP")
+
for i,v in ipairs(CM.Slash) do
_G["SLASH_" .. C.Name:upper() .. i] = "/" .. v
end
diff --git a/DeathManager.lua b/DeathManager.lua
new file mode 100644
index 0000000..c692136
--- /dev/null
+++ b/DeathManager.lua
@@ -0,0 +1,173 @@
+--[[
+ * Copyright (c) 2011-2012 by Adam Hellberg.
+ *
+ * This file is part of Command.
+ *
+ * Command is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Command is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Command. If not, see <http://www.gnu.org/licenses/>.
+--]]
+
+-- Manages player death and resurrection
+-- Disabled by default to prevent abuse
+-- Enabled with /command set deathmanager enabled
+
+-- Upvalues
+local type = type
+
+-- API Upvalues
+local RepopMe = RepopMe
+local HasSoulstone = HasSoulstone
+local UseSoulstone = UseSoulstone
+local AcceptResurrect = AcceptResurrect
+local StaticPopup_Hide = StaticPopup_Hide
+local StaticPopup_Visible = StaticPopup_Visible
+local ResurrectGetOfferer = ResurrectGetOfferer
+
+local C = Command
+
+C.DeathManager = {}
+
+local L = C.LocaleManager
+local DM = C.DeathManager
+local CM
+
+local SelfRessType = {
+ None = 0,
+ Soulstone = 1,
+ Reincarnate = 2,
+ Card = 3 -- Darkmoon Card: Twisting Nether
+}
+
+function DM:Init()
+ CM = C.ChatManager
+ self:LoadSavedVars()
+end
+
+function DM:LoadSavedVars()
+ if type(C.Global["DEATH_MANAGER"]) ~= "table" then
+ C.Global["DEATH_MANAGER"] = {}
+ end
+ self.Settings = C.Global["DEATH_MANAGER"]
+ if type(self.Settings.ENABLED) ~= "boolean" then
+ self.Settings.ENABLED = false
+ end
+end
+
+function DM:OnDeath()
+ if not self.Settings.ENABLED then return end
+ self.Dead = true
+ local t = self:HasSelfRess()
+ if t == SelfRessType.SoulStone then
+ CM:SendMessage(L("DM_ONDEATH_SOULSTONE"), "SMART")
+ elseif t == SelfRessType.Reincarnate then
+ CM:SendMessage(L("DM_ONDEATH_REINCARNATE"), "SMART")
+ elseif t == SelfRessType.Card then
+ CM:SendMessage(L("DM_ONDEATH_CARD"), "SMART")
+ else
+ CM:SendMessage(L("DM_ONDEATH"), "SMART")
+ end
+end
+
+function DM:OnResurrect(resser)
+ if not self.Settings.ENABLED then return end
+ self.Resurrection = true
+ CM:SendMessage(L("DM_ONRESS"):format(resser), "SMART")
+end
+
+-- Returns appropriate SelfRessType
+function DM:HasSelfRess()
+ local t = HasSoulstone()
+
+ if not t then
+ return SelfRessType.None
+ elseif t:lower() == L("USE_SOULSTONE"):lower() then -- soulstone ("Use Soulstone")
+ return SelfRessType.Soulstone
+ elseif t:lower() == L("REINCARNATION"):lower() then -- Reincarnate
+ return SelfRessType.Reincarnate
+ elseif t:lower() == L("TWISTING_NETHER"):lower() then -- Darkmoon Card: Twisting Nether
+ return SelfRessType.Card
+ end
+
+ return SelfRessType.None
+end
+
+function DM:Release()
+ if not UnitIsDead("player") then
+ return false, "DM_RELEASE_NOTDEAD"
+ end
+
+ RepopMe()
+
+ if StaticPopup_Visible("DEATH") then
+ StaticPopup_Hide("DEATH")
+ end
+
+ return "DM_RELEASED"
+end
+
+function DM:Resurrect()
+ if not UnitIsDeadOrGhost("player") then
+ return false, "DM_ERR_NOTDEAD"
+ end
+
+ local result = "DM_RESURRECTED"
+ local selfRess = DM:HasSelfRess()
+ local resser = ResurrectGetOfferer()
+ if selfRess ~= SelfRessType.None then
+ UseSoulstone()
+ if selfRess == SelfRessType.Soulstone then
+ result = "DM_RESURRECTED_SOULSTONE"
+ elseif selfRess == SelfRessType.Reincarnate then
+ result = "DM_RESURRECTED_REINCARNATE"
+ elseif selfRess == SelfRessType.Card then
+ result = "DM_RESURRECTED_CARD"
+ end
+ else
+ if not resser then
+ return false, "DM_RESURRECT_NOTACTIVE"
+ end
+ AcceptResurrect()
+ result = "DM_RESURRECTED_PLAYER"
+ end
+
+ if StaticPopup_Visible("RESURRECT") then -- Never seems to show, but just in case
+ StaticPopup_Hide("RESURRECT")
+ elseif StaticPopup_Visible("RESURRECT_NO_TIMER") then
+ StaticPopup_Hide("RESURRECT_NO_TIMER")
+ elseif StaticPopup_Visible("RESURRECT_NO_SICKNESS") then
+ StaticPopup_Hide("RESURRECT_NO_SICKNESS")
+ end
+
+ return result, {resser}
+end
+
+function DM:IsEnabled()
+ return self.Settings.ENABLED
+end
+
+function DM:Enable()
+ self.Settings.ENABLED = true
+ return "DM_ENABLED"
+end
+
+function DM:Disable()
+ self.Settings.ENABLED = false
+ return "DM_DISABLED"
+end
+
+function DM:Toggle()
+ if self:IsEnabled() then
+ return self:Disable()
+ end
+ return self:Enable()
+end
diff --git a/Events.lua b/Events.lua
index b033745..f65fbf0 100644
--- a/Events.lua
+++ b/Events.lua
@@ -33,6 +33,7 @@ local L = C.LocaleManager
local CM = C.ChatManager
local QM = C.QueueManager
local AC = C.AddonComm
+local DM = C.DeathManager
--- Event handler for ADDON_LOADED
-- @name Command.Events.ADDON_LOADED
@@ -129,3 +130,23 @@ function C.Events.GUILD_ROSTER_UPDATE(self, ...)
AC:UpdateGuild()
end
end
+
+function C.Events.PLAYER_DEAD(self, ...)
+ DM:OnDeath()
+end
+
+function C.Events.RESURRECT_REQUEST(self, ...)
+ DM:OnResurrect(select(1, ...))
+end
+
+function C.Events.PLAYER_ALIVE(self, ...)
+ if not UnitIsDeadOrGhost("player") then return end -- Return if player released to graveyard
+ -- Player has accepted a ress before releasing spirit
+ DM.Dead = false
+ DM.Resurrection = false
+end
+
+function C.Events.PLAYER_UNGHOST(self, ...)
+ DM.Dead = false
+ DM.Resurrection = false
+end
diff --git a/load.xml b/load.xml
index 0c197c8..0bb4fa8 100644
--- a/load.xml
+++ b/load.xml
@@ -32,6 +32,7 @@
<Script file="RollManager.lua" />
<Script file="LootManager.lua" />
<Script file="AddonComm.lua" />
+ <Script file="DeathManager.lua" />
<Script file="CommandManager.lua" />
<Script file="ChatManager.lua" />
<Script file="Events.lua" />
diff --git a/locales/enUS.lua b/locales/enUS.lua
index 2d16a6d..7fb1c93 100644
--- a/locales/enUS.lua
+++ b/locales/enUS.lua
@@ -34,6 +34,16 @@ local L = {
YES = "Yes",
NO = "No",
+ ------------------
+ -- WoW Specific --
+ ---------------------------------------------------------------------------
+ -- ONLY translate these if the locale has official support on the client --
+ ---------------------------------------------------------------------------
+
+ USE_SOULSTONE = "Use Soulstone",
+ REINCARNATION = "Reincarnation",
+ TWISTING_NETHER = "Twisting Nether",
+
----------
-- Core --
----------
@@ -84,7 +94,9 @@ local L = {
CM_ERR_NOCMDCHAR = "No command character specified.",
CM_ERR_NOCHAT = "This command is not allowed to be used from the chat.",
CM_ERR_CHATONLY = "This command can only be used from the chat.",
- CM_ERR_DISABLED = "This command has been permanently disabled.",
+ CM_ERR_DISABLED = "This command has been disabled.",
+ CM_ERR_PERMDISABLED = "This command has been permanently disabled.",
+ CM_ERR_TEMPDISABLED = "This command has been temporarily disabled.",
CM_NO_HELP = "No help available.",
@@ -104,6 +116,9 @@ local L = {
CM_SET_HELP = "Control the settings of Command.",
CM_SET_USAGE = "Usage: set cmdchar|groupinvite",
CM_SET_GROUPINVITE_USAGE = "Usage: set groupinvite enable|disable|<time>",
+ CM_SET_DM_ISENABLED = "DeathManager is enabled.",
+ CM_SET_DM_ISDISABLED = "DeathManager is disabled.",
+ CM_SET_DM_USAGE = "Usage: set dm [enable|disable]",
CM_LOCALE_HELP = "Change locale settings.",
CM_LOCALE_USAGE ="Usage: locale [set|reset|usemaster|playerindependent]",
@@ -255,6 +270,10 @@ local L = {
CM_RAIDMODE_HELP = "Set the raid difficulty.",
CM_RAIDMODE_USAGE = "Usage: raiddifficulty <difficulty>",
+ CM_RELEASE_HELP = "Player will release corpse.",
+
+ CM_RESURRECT_HELP = "Player will accept pending resurrect request.",
+
------------
-- Events --
------------
@@ -420,6 +439,32 @@ local L = {
PM_LIST_SETWHITE = "Now using list as whitelist.",
PM_LIST_SETBLACK = "Now using list as blacklist.",
+ ------------------
+ -- DeathManager --
+ ------------------
+
+ DM_ERR_NOTDEAD = "I am not dead.",
+
+ DM_ENABLED = "DeathManager has been enabled.",
+ DM_DISABLED = "DeathManager has been disabled.",
+
+ DM_ONDEATH = "I have died! Type !release to make me release spirit.",
+ DM_ONDEATH_SOULSTONE = "Died with active soulstone, type !ress to make me ress!",
+ DM_ONDEATH_REINCARNATE = "Died with reincarnate off cooldown, type !ress to make me ress!",
+ DM_ONDEATH_CARD = "Died with proc from Twisted Nether active, type !ress to make me ress!",
+
+ DM_ONRESS = "I have received a ress from %s! Type !ress to make me accept it.",
+
+ DM_RELEASE_NOTDEAD = "I am not dead or have already released.",
+ DM_RELEASED = "Released corpse!",
+
+ DM_RESURRECT_NOTACTIVE = "I have no pending resurrection request or it has expired.",
+ DM_RESURRECTED = "Successfully resurrected!",
+ DM_RESURRECTED_SOULSTONE = "Resurrected with soulstone!",
+ DM_RESURRECTED_REINCARNATE = "Resurrected with reincarnate!",
+ DM_RESURRECTED_CARD = "Resurrected with Darkmoon Card: Twisting Nether proc!",
+ DM_RESURRECTED_PLAYER = "Accepted resurrect from %s!",
+
-----------------
-- AuthManager --
-----------------
diff --git a/locales/svSE.lua b/locales/svSE.lua
index 3d9df87..e2d6642 100644
--- a/locales/svSE.lua
+++ b/locales/svSE.lua
@@ -34,6 +34,16 @@ local L = {
YES = "Ja",
NO = "Nej",
+ ------------------
+ -- WoW Specific --
+ ---------------------------------------------------------------------------
+ -- ONLY translate these if the locale has official support on the client --
+ ---------------------------------------------------------------------------
+
+ USE_SOULSTONE = "Use Soulstone",
+ REINCARNATION = "Reincarnation",
+ TWISTING_NETHER = "Twisting Nether",
+
----------
-- Core --
----------
@@ -84,7 +94,9 @@ local L = {
CM_ERR_NOCMDCHAR = "Inget kommandotecken angivet.",
CM_ERR_NOCHAT = "Det här kommandot kan inte användas från chatten.",
CM_ERR_CHATONLY = "Det här kommandot kan endast användas från chatten.",
- CM_ERR_DISABLED = "Det här kommandot har blivit permanent avstängt.",
+ CM_ERR_DISABLED = "Det här kommandot har blivit avstängt.",
+ CM_ERR_PERMDISABLED = "Det här kommandot har blivit permanent avstängt.",
+ CM_ERR_TEMPDISABLED = "Det här kommandot har blivit temporärt avstängt.",
CM_NO_HELP = "Ingen hjälp tillgänglig.",
@@ -104,6 +116,9 @@ local L = {
CM_SET_HELP = "Ändra inställningarna i Command.",
CM_SET_USAGE = "Användning: set cmdchar|groupinvite",
CM_SET_GROUPINVITE_USAGE = "Användning: set groupinvite enable|disable|<tid>",
+ CM_SET_DM_ISENABLED = "DeathManager is enabled.",
+ CM_SET_DM_ISDISABLED = "DeathManager is disabled.",
+ CM_SET_DM_USAGE = "Usage: set dm [enable|disable]",
CM_LOCALE_HELP = "Change locale settings.",
CM_LOCALE_USAGE ="Användning: locale [set|reset|usemaster|playerindependent]",
@@ -255,6 +270,10 @@ local L = {
CM_RAIDMODE_HELP = "Set the raid difficulty.",
CM_RAIDMODE_USAGE = "Användning: raiddifficulty <difficulty>",
+ CM_RELEASE_HELP = "Player will release corpse.",
+
+ CM_RESURRECT_HELP = "Player will accept pending resurrect request.",
+
------------
-- Events --
------------
@@ -420,6 +439,32 @@ local L = {
PM_LIST_SETWHITE = "Now using list as whitelist.",
PM_LIST_SETBLACK = "Now using list as blacklist.",
+ ------------------
+ -- DeathManager --
+ ------------------
+
+ DM_ERR_NOTDEAD = "I am not dead.",
+
+ DM_ENABLED = "DeathManager has been enabled.",
+ DM_DISABLED = "DeathManager has been disabled.",
+
+ DM_ONDEATH = "I have died! Type !release to make me release spirit.",
+ DM_ONDEATH_SOULSTONE = "Died with active soulstone, type !ress to make me ress!",
+ DM_ONDEATH_REINCARNATE = "Died with reincarnate off cooldown, type !ress to make me ress!",
+ DM_ONDEATH_CARD = "Died with proc from Twisted Nether active, type !ress to make me ress!",
+
+ DM_ONRESS = "I have received a ress from %s! Type !ress to make me accept it.",
+
+ DM_RELEASE_NOTDEAD = "I am not dead or have already released.",
+ DM_RELEASED = "Released corpse!",
+
+ DM_RESURRECT_NOTACTIVE = "I have no pending resurrection request or it has expired.",
+ DM_RESURRECTED = "Successfully resurrected!",
+ DM_RESURRECTED_SOULSTONE = "Resurrected with soulstone!",
+ DM_RESURRECTED_REINCARNATE = "Resurrected with reincarnate!",
+ DM_RESURRECTED_CARD = "Resurrected with Darkmoon Card: Twisting Nether proc!",
+ DM_RESURRECTED_PLAYER = "Accepted resurrect from %s!",
+
-----------------
-- AuthManager --
-----------------