Quantcast

Added SummonManager, announces to group when player receives a summon.

F16Gaming [08-08-12 - 05:18]
Added SummonManager, announces to group when player receives a summon.

Added commands acceptsummon, declinesummon, set sm
[enable|disable|toggle|delay].
Localization updates.
Various minor optimizations and fixes.
Filename
AddonComm.lua
Command.lua
CommandManager.lua
Events.lua
LocaleManager.lua
SummonManager.lua
load.xml
locales/enUS.lua
locales/svSE.lua
diff --git a/AddonComm.lua b/AddonComm.lua
index db449d9..06b72c4 100644
--- a/AddonComm.lua
+++ b/AddonComm.lua
@@ -196,6 +196,8 @@ function AC:Receive(msgType, msg, channel, sender)
 end

 function AC:Send(msgType, msg, channel, target)
+	-- Don't send version update notices if this is a dev version
+	if msgType == self.Type.VersionUpdate and C.Version:lower() == "dev" and not C.OverrideACUpdateNotice then return end
 	channel = channel or "RAID"
 	if channel == "RAID" and not GT:IsRaid() then
 		if not GT:IsGroup() then return end
diff --git a/Command.lua b/Command.lua
index d6206b0..f3a92a7 100644
--- a/Command.lua
+++ b/Command.lua
@@ -37,7 +37,7 @@ local assert = assert
 Command = {
 	Name = "Command",
 	Version = GetAddOnMetadata("Command", "Version"),
-	VersionNum = 7, -- Increment on every release
+	VersionNum = 8, -- Increment on every release
 	VersionChecked = false, -- Prevent spam of "New Version" notice
 	Loaded = false,
 	VarVersion = 2,
@@ -55,6 +55,7 @@ local PM
 local RM
 local AC
 local DM
+local SM
 local log

 --- Initialize Command.
@@ -70,6 +71,7 @@ function C:Init()
 	RM = self.RollManager
 	AC = self.AddonComm
 	DM = self.DeathManager
+	SM = self.SummonManager
 	log = self.Logger
 	self:LoadSavedVars()
 	log:Normal(L("ADDON_LOAD"))
@@ -112,6 +114,7 @@ function C:LoadSavedVars()
 	RM:Init()
 	AC:Init()
 	DM:Init()
+	SM:Init()
 	Cmd:Init()
 	log:SetDebug(self.Settings.DEBUG)
 	self.Global.VERSION = self.VarVersion
diff --git a/CommandManager.lua b/CommandManager.lua
index 3e8d938..92fb740 100644
--- a/CommandManager.lua
+++ b/CommandManager.lua
@@ -67,6 +67,7 @@ local LM = C.LootManager
 local GT = C.GroupTools
 local AM = C.AuthManager
 local DM = C.DeathManager
+local SM = C.SummonManager
 local Chat
 local CES = C.Extensions.String
 local CET = C.Extensions.Table
@@ -238,58 +239,83 @@ CM:Register({"set", "s"}, PM.Access.Groups.Admin.Level, function(args, sender, i
 	if #args <= 0 then
 		return false, "CM_SET_USAGE"
 	end
-	args[1] = args[1]:lower()
-	if args[1]:match("^c") then -- Command Char setting
+	local mod = args[1]:lower()
+	if mod:match("^c") then -- Command Char setting
 		if #args < 2 then
 			return false, "CM_ERR_NOCMDCHAR"
 		end
 		return Chat:SetCmdChar(args[2])
-	elseif args[1]:match("^g") then -- Group invite (announce)
+	elseif mod:match("^g") then -- Group invite (announce)
 		if #args < 2 then
 			return false, "CM_SET_GROUPINVITE_USAGE"
 		end
 		args[2] = args[2]:lower()
-		local time = tonumber(args[2])
-		if time then
-			return C:SetGroupInviteDelay(time)
+		local delay = tonumber(args[2])
+		if delay then
+			return C:SetGroupInviteDelay(delay)
 		elseif args[2]:match("^[eay]") then -- Enable
 			return C:EnableGroupInvite()
 		elseif args[2]:match("^[dn]") then -- Disable
 			return C:DisableGroupInvite()
 		end
 		return false, "CM_SET_GROUPINVITE_USAGE"
-	elseif args[1]:match("^d") then -- DeathManager
+	elseif mod: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
+			return "CM_SET_DM_ISDISABLED"
 		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].*rel") then -- Enable release
+		local setting = args[2]:lower()
+		if setting:match("^[eay].*rel") then -- Enable release
 			return C.DeathManager:EnableRelease()
-		elseif args[2]:match("^[dn].*rel") then -- Disable release
+		elseif setting:match("^[dn].*rel") then -- Disable release
 			return C.DeathManager:DisableRelease()
-		elseif args[2]:match("^[eay].*r") then -- Enable ress
+		elseif setting:match("^[eay].*r") then -- Enable ress
 			return C.DeathManager:EnableResurrect()
-		elseif args[2]:match("^[dn].*r") then -- Disable ress
+		elseif setting:match("^[dn].*r") then -- Disable ress
 			return C.DeathManager:DisableResurrect()
-		elseif args[2]:match("^[eay]") then -- Enable
+		elseif setting:match("^[eay]") then -- Enable
 			return C.DeathManager:Enable()
-		elseif args[2]:match("^[dn]") then -- Disable
+		elseif setting:match("^[dn]") then -- Disable
 			return C.DeathManager:Disable()
-		elseif args[2]:match("^t.*rel") then -- Toggle release
+		elseif setting:match("^t.*rel") then -- Toggle release
 			return C.DeathManager:ToggleRelease()
-		elseif args[2]:match("^t.*r") then -- Toggle resurrect
+		elseif setting:match("^t.*r") then -- Toggle resurrect
 			return C.DeathManager:ToggleResurrect()
-		elseif args[2]:match("^t") then -- Toggle
+		elseif setting:match("^t") then -- Toggle
 			return C.DeathManager:Toggle()
 		end
 		return false, "CM_SET_DM_USAGE"
+	elseif mod:match("^s") then -- SummonManager
+		if #args < 2 then
+			if SM:IsEnabled() then
+				return "CM_SET_SM_ISENABLED"
+			end
+			return "CM_SET_SM_ISDISABLED"
+		end
+		if isChat then -- Players are only allowed to check status of SummonManager
+			return false, "CM_ERR_NOCHAT"
+		end
+		local setting = args[2]:lower()
+		if setting:match("^[eay]") then -- Enable
+			return SM:Enable()
+		elseif setting:match("^di") or setting:match("^n") then -- Disable
+			return SM:Disable()
+		elseif setting:match("^to") then -- Toggle
+			return SM:Toggle()
+		elseif setting:match("^[std]") then -- (Set) Delay
+			if #args < 3 then
+				return "CM_SET_SM_DELAY_CURRENT", {SM:GetDelay()}
+			end
+			local newDelay = tonumber(args[3])
+			if not newDelay then return false, "CM_SET_SM_DELAY_USAGE" end
+			return SM:SetDelay(newDelay)
+		end
+		return false, "CM_SET_SM_USAGE"
 	end
 	return false, "CM_SET_USAGE"
 end, "CM_SET_HELP")
@@ -922,6 +948,20 @@ CM:Register({"resurrect", "ressurrect", "ress", "res"}, PM.Access.Groups.User.Le
 	return DM:Resurrect()
 end, "CM_RESURRECT_HELP")

+CM:Register({"acceptsummon", "as", "acceptsumm", "asumm"}, PM.Access.Groups.User.Level, function(args, sender, isChat)
+	if not SM:IsEnabled() then
+		return false, "CM_ERR_DISABLED"
+	end
+	return SM:AcceptSummon()
+end, "CM_ACCEPTSUMMON_HELP")
+
+CM:Register({"declinesummon", "ds", "declinesumm", "dsumm", "cancelsummon", "csumm"}, PM.Access.Groups.User.Level, function(args, sender, isChat)
+	if not SM:IsEnabled() then
+		return false, "CM_ERR_DISABLED"
+	end
+	return SM:DeclineSummon()
+end, "CM_DECLINESUMMON_HELP")
+
 for i,v in ipairs(CM.Slash) do
 	_G["SLASH_" .. C.Name:upper() .. i] = "/" .. v
 end
diff --git a/Events.lua b/Events.lua
index f65fbf0..4969bb4 100644
--- a/Events.lua
+++ b/Events.lua
@@ -34,6 +34,7 @@ local CM = C.ChatManager
 local QM = C.QueueManager
 local AC = C.AddonComm
 local DM = C.DeathManager
+local SM = C.SummonManager

 --- Event handler for ADDON_LOADED
 -- @name Command.Events.ADDON_LOADED
@@ -150,3 +151,7 @@ function C.Events.PLAYER_UNGHOST(self, ...)
 	DM.Dead = false
 	DM.Resurrection = false
 end
+
+function C.Events.CONFIRM_SUMMON(self, ...)
+	SM:OnSummon()
+end
diff --git a/LocaleManager.lua b/LocaleManager.lua
index 9489553..e12205d 100644
--- a/LocaleManager.lua
+++ b/LocaleManager.lua
@@ -49,7 +49,7 @@ local function l_index(self, k)
 	k = tostring(k):upper()
 	master = LM:GetMaster()
 	if self == master then -- Prevent recursion
-		return ("%%%s%%"):format(k)
+		return ("%s"):format(k)
 	end
 	local val = master[k]
 	if val then return val end
diff --git a/SummonManager.lua b/SummonManager.lua
new file mode 100644
index 0000000..ea7c972
--- /dev/null
+++ b/SummonManager.lua
@@ -0,0 +1,195 @@
+--[[
+	* 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/>.
+--]]
+
+-- Upvalues
+local type = type
+local floor = floor
+local tostring = tostring
+
+-- API Upvalues
+local CreateFrame = CreateFrame
+local CancelSummon = CancelSummon
+local ConfirmSummon = ConfirmSummon
+local PlayerCanTeleport = PlayerCanTeleport
+local GetSummonConfirmSummoner = GetSummonConfirmSummoner
+local GetSummonConfirmAreaName = GetSummonConfirmAreaName
+local GetSummonConfirmTimeLeft = GetSummonConfirmTimeLeft
+
+local C = Command
+
+C.SummonManager = {}
+
+local L = C.LocaleManager
+local SM = C.SummonManager
+local CM
+
+local MAX_TIME = 110 -- 1 minute 50 seconds, summons expire after 2 minutes (usually)
+
+local LastSummoner
+
+function SM:Init()
+	CM = C.ChatManager
+	LastSummoner = L("UNKNOWN")
+	self:LoadSavedVars()
+end
+
+function SM:LoadSavedVars()
+	if type(C.Global["SUMMON_MANAGER"]) ~= "table" then
+		C.Global["SUMMON_MANAGER"] = {}
+	end
+
+	self.Settings = C.Global["SUMMON_MANAGER"]
+
+	if type(self.Settings.ENABLED) ~= "boolean" then
+		self.Settings.ENABLED = true
+	end
+
+	if type(self.Settings.TIME) ~= "number" then
+		self.Settings.TIME = 0
+	end
+end
+
+function SM:OnSummon()
+	if self.DelayActive then return end
+	if self.Settings.TIME > 0 then
+		self.DelayActive = true
+		local frame = CreateFrame("Frame")
+		frame.Time = 0 -- Current time
+		frame.Delay = self.Settings.TIME -- Delay to wait
+		frame:SetScript("OnUpdate", function(self, elapsed)
+			self.Time = self.Time + elapsed
+			if self.Time >= self.Delay then
+				self:SetScript("OnUpdate", nil)
+				SM.DelayActive = false
+				if SM:HasSummon() then SM:Announce() end
+			end
+		end)
+	else
+		self:Announce()
+	end
+end
+
+function SM:Announce()
+	if not self:HasSummon() then return end
+
+	local name = GetSummonConfirmSummoner()
+	local area = GetSummonConfirmAreaName()
+	local left = GetSummonConfirmTimeLeft()
+
+	if left >= 60 then -- Convert to m:s format
+		local minutes = floor(left / 60)
+		local seconds = tostring(left - minutes * 60)
+		if not seconds:match("%d%d") then
+			seconds = "0" .. seconds
+		end
+		left = ("%d:%s"):format(minutes, seconds)
+	else
+		left = ("%d %s"):format(left, L("SECONDS"):lower())
+	end
+
+	if not name or not area or not left then return end
+
+	LastSummoner = name
+
+	CM:SendMessage(L("SM_ONSUMMON"):format(area, name, left), "SMART")
+end
+
+function SM:AcceptSummon()
+	if not self:HasSummon() then
+		return false, "SM_ERR_NOSUMMON"
+	end
+
+	ConfirmSummon()
+
+	return "SM_ACCEPTED", {LastSummoner}
+end
+
+function SM:DeclineSummon()
+	if not self:HasSummon() then
+		return false, "SM_ERR_NOSUMMON"
+	end
+
+	CancelSummon()
+
+	return "SM_DECLINED", {LastSummoner}
+end
+
+function SM:HasSummon()
+	return PlayerCanTeleport()
+end
+
+function SM:IsEnabled()
+	return self.Settings.ENABLED
+end
+
+function SM:Enable()
+	self.Settings.ENABLED = true
+	return "SM_ENABLED"
+end
+
+function SM:Disable()
+	self.Settings.ENABLED = false
+	return "SM_DISABLED"
+end
+
+function SM:Toggle()
+	if self:IsEnabled() then
+		return self:Disable()
+	end
+	return self:Enable()
+end
+
+function SM:GetDelay()
+	local total = self:GetRawDelay()
+	if total >= 60 then
+		local minutes = floor(total / 60)
+		local seconds = tostring(total - minutes * 60)
+		if not seconds:match("%d%d") then
+			seconds = "0" .. seconds
+		end
+		return ("%d:%s"):format(minutes, seconds)
+	end
+	return ("%d %s"):format(total, L("SECONDS"))
+end
+
+function SM:GetRawDelay()
+	return self.Settings.DELAY
+end
+
+function SM:SetDelay(amount)
+	if amount < 0 then
+		amount = 0
+	elseif amount > MAX_DELAY then
+		amount = MAX_DELAY
+	end
+	self.Settings.DELAY = amount
+	if amount > 0 then
+		if amount >= 60 then
+			local minutes = floor(amount / 60)
+			local seconds = tostring(amount - minutes * 60)
+			if not seconds:match("%d%d") then
+				seconds = "0" .. seconds
+			end
+			return "SM_SETDELAY_SUCCESS", {("%d:%s"):format(minutes, seconds)}
+		else
+			return "SM_SETDELAY_SUCCESS", {("%d %s"):format(amount, L("SECONDS"))}
+		end
+	end
+	return "SM_SETDELAY_INSTANT"
+end
diff --git a/load.xml b/load.xml
index 0bb4fa8..da850fb 100644
--- a/load.xml
+++ b/load.xml
@@ -33,6 +33,7 @@
 	<Script file="LootManager.lua" />
 	<Script file="AddonComm.lua" />
 	<Script file="DeathManager.lua" />
+	<Script file="SummonManager.lua" />
 	<Script file="CommandManager.lua" />
 	<Script file="ChatManager.lua" />
 	<Script file="Events.lua" />
diff --git a/locales/enUS.lua b/locales/enUS.lua
index e198fce..2537e7a 100644
--- a/locales/enUS.lua
+++ b/locales/enUS.lua
@@ -33,6 +33,8 @@ local L = {

 	YES = "Yes",
 	NO = "No",
+	UNKNOWN = "Unknown",
+	SECONDS = "Second(s)",

 	------------------
 	-- WoW Specific --
@@ -115,10 +117,15 @@ 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_GROUPINVITE_USAGE = "Usage: set groupinvite enable|disable|<delay>",
 	CM_SET_DM_ISENABLED = "DeathManager is enabled.",
 	CM_SET_DM_ISDISABLED = "DeathManager is disabled.",
-	CM_SET_DM_USAGE = "Usage: set dm [enable|disable]",
+	CM_SET_DM_USAGE = "Usage: set dm [enable|disable|toggle|enableress|disableress|toggleress|enablerel|disablerel|togglerel]",
+	CM_SET_SM_ISENABLED = "SummonManager is enabled.",
+	CM_SET_SM_ISDISABLED = "SummonManager is disabled.",
+	CM_SET_SM_DELAY_CURRENT = "The current delay for summon announcements is %s.",
+	CM_SET_SM_DELAY_USAGE = "Usage: set sm delay <delay>"
+	CM_SET_SM_USAGE = "Usage: set sm [enable|disable|toggle|delay]",

 	CM_LOCALE_HELP = "Change locale settings.",
 	CM_LOCALE_USAGE ="Usage: locale [set|reset|usemaster|playerindependent]",
@@ -274,6 +281,10 @@ local L = {

 	CM_RESURRECT_HELP = "Player will accept pending resurrect request.",

+	CM_ACCEPTSUMMON_HELP = "Player will accept a pending summon request.",
+
+	CM_DECLINESUMMON_HELP = "Player will decline a pending summon request.",
+
 	------------
 	-- Events --
 	------------
@@ -336,7 +347,7 @@ local L = {
 	LOOT_SM_SUCCESS = "Successfully set the loot method to %s!",
 	LOOT_SM_SUCCESSMASTER = "Successfully set the loot method to %s (%s)!",

-	LOOT_SLM_NOLOEAD = "Unable to change master looter, not group leader.",
+	LOOT_SLM_NOLEAD = "Unable to change master looter, not group leader.",
 	LOOT_SLM_METHOD = "Cannot set master looter when loot method is set to %s.",
 	LOOT_SLM_SPECIFY = "Master looter not specified.",
 	LOOT_SLM_SUCCESS = "Successfully set %s as the master looter!",
@@ -469,6 +480,25 @@ local L = {
 	DM_RESURRECTED_CARD = "Resurrected with Darkmoon Card: Twisting Nether proc!",
 	DM_RESURRECTED_PLAYER = "Accepted resurrect from %s!",

+	-------------------
+	-- SummonManager --
+	-------------------
+
+	SM_ERR_NOSUMMON = "I do not have an active summon request.",
+
+	SM_ENABLED = "Summon Manager has been enabled!",
+
+	SM_DISABLED = "Summon Manager has been disabled!",
+
+	SM_ONSUMMON = "I have received a summon to %s from %s, expires in %s! Type !acceptsummon or !declinesummon to make me accept or decline the request.",
+
+	SM_ACCEPTED = "Accepted summon request from %s!",
+
+	SM_DECLINED = "Declined summon request from %s!",
+
+	SM_SETDELAY_SUCCESS = "Summon announce delay successfully set to %s!",
+	SM_SETDELAY_INSTANT = "Summons will now announce instantly when received.",
+
 	-----------------
 	-- AuthManager --
 	-----------------
diff --git a/locales/svSE.lua b/locales/svSE.lua
index af5ee9c..240b73a 100644
--- a/locales/svSE.lua
+++ b/locales/svSE.lua
@@ -33,6 +33,8 @@ local L = {

 	YES = "Ja",
 	NO = "Nej",
+	UNKNOWN = "Okänd",
+	SECONDS = "Sekund(er)",

 	------------------
 	-- WoW Specific --
@@ -115,10 +117,15 @@ 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_GROUPINVITE_USAGE = "Användning: set groupinvite enable|disable|<fördröjning>",
 	CM_SET_DM_ISENABLED = "DeathManager is enabled.",
 	CM_SET_DM_ISDISABLED = "DeathManager is disabled.",
-	CM_SET_DM_USAGE = "Usage: set dm [enable|disable]",
+	CM_SET_DM_USAGE = "Användning: set dm [enable|disable|toggle|enableress|disableress|toggleress|enablerel|disablerel|togglerel]",
+	CM_SET_SM_ISENABLED = "SummonManager is enabled.",
+	CM_SET_SM_ISDISABLED = "SummonManager is disabled.",
+	CM_SET_SM_DELAY_CURRENT = "The current delay for summon announcements is %s.",
+	CM_SET_SM_DELAY_USAGE = "Usage: set sm delay <delay>"
+	CM_SET_SM_USAGE = "Användning: set sm [enable|disable|toggle|delay]",

 	CM_LOCALE_HELP = "Change locale settings.",
 	CM_LOCALE_USAGE ="Användning: locale [set|reset|usemaster|playerindependent]",
@@ -274,6 +281,10 @@ local L = {

 	CM_RESURRECT_HELP = "Player will accept pending resurrect request.",

+	CM_ACCEPTSUMMON_HELP = "Player will accept a pending summon request.",
+
+	CM_DECLINESUMMON_HELP = "Player will decline a pending summon request.",
+
 	------------
 	-- Events --
 	------------
@@ -336,7 +347,7 @@ local L = {
 	LOOT_SM_SUCCESS = "Successfully set the loot method to %s!",
 	LOOT_SM_SUCCESSMASTER = "Successfully set the loot method to %s (%s)!",

-	LOOT_SLM_NOLOEAD = "Unable to change master looter, not group leader.",
+	LOOT_SLM_NOLEAD = "Unable to change master looter, not group leader.",
 	LOOT_SLM_METHOD = "Cannot set master looter when loot method is set to %s.",
 	LOOT_SLM_SPECIFY = "Master looter not specified.",
 	LOOT_SLM_SUCCESS = "Successfully set %s as the master looter!",
@@ -469,6 +480,25 @@ local L = {
 	DM_RESURRECTED_CARD = "Resurrected with Darkmoon Card: Twisting Nether proc!",
 	DM_RESURRECTED_PLAYER = "Accepted resurrect from %s!",

+	-------------------
+	-- SummonManager --
+	-------------------
+
+	SM_ERR_NOSUMMON = "I do not have an active summon request.",
+
+	SM_ENABLED = "Summon Manager has been enabled!",
+
+	SM_DISABLED = "Summon Manager has been disabled!",
+
+	SM_ONSUMMON = "I have received a summon to %s from %s, expires in %s! Type !acceptsummon or !declinesummon to make me accept or decline the request.",
+
+	SM_ACCEPTED = "Accepted summon request from %s!",
+
+	SM_DECLINED = "Declined summon request from %s!",
+
+	SM_SETDELAY_SUCCESS = "Summon announce delay successfully set to %s!",
+	SM_SETDELAY_INSTANT = "Summons will now announce instantly when received.",
+
 	-----------------
 	-- AuthManager --
 	-----------------