diff --git a/Command.lua b/Command.lua
index 6ae5665..fc40f17 100644
--- a/Command.lua
+++ b/Command.lua
@@ -58,6 +58,7 @@ local DM
local SM
local IM
local CDM
+local CRM
local log
--- Initialize Command.
@@ -76,6 +77,7 @@ function C:Init()
SM = self.SummonManager
IM = self.InviteManager
CDM = self.DuelManager
+ CRM = self.RoleManager
log = self.Logger
self:LoadSavedVars()
log:Normal(L("ADDON_LOAD"))
@@ -117,6 +119,7 @@ function C:LoadSavedVars()
SM:Init()
IM:Init()
CDM:Init()
+ CRM:Init()
Cmd:Init()
log:SetDebug(self.Settings.DEBUG)
self.Global.VERSION = self.VarVersion
diff --git a/CommandManager.lua b/CommandManager.lua
index 94671ea..7d6f747 100644
--- a/CommandManager.lua
+++ b/CommandManager.lua
@@ -70,6 +70,7 @@ local DM = C.DeathManager
local SM = C.SummonManager
local IM = C.InviteManager
local CDM = C.DuelManager
+local CRM = C.RoleManager
local Chat
local CES = C.Extensions.String
local CET = C.Extensions.Table
@@ -182,7 +183,11 @@ function CM:HandleCommand(command, args, isChat, player, bnetInfo)
return false, "CM_ERR_NOACCESS", {player.Info.Name, cmd.Access, PM:GetAccess(player)}
end
end
- return cmd.Call(args, player, isChat, bnetInfo)
+ local result, arg, errArg = cmd.Call(args, player, isChat, bnetInfo)
+ if type(result) == "nil" then
+ return "CM_ERR_UNKNOWN"
+ end
+ return result, arg, errArg
else
return false, "CM_ERR_NOTREGGED", {tostring(command)}
end
@@ -1004,7 +1009,7 @@ CM:Register({"raidwarning", "rw", "raid_warning"}, PM.Access.Groups.User.Level,
return "CM_RAIDWARNING_SENT"
end, "CM_RAIDWARNING_HELP")
-CM:Register({"dungeondifficulty", "dungeondiff", "dd", "dungeonmode", "dm"}, PM.Access.Groups.User.Level, function(args, sender, isChat, bnetInfo)
+CM:Register({"dungeondifficulty", "dungeondiff", "dd"}, PM.Access.Groups.User.Level, function(args, sender, isChat, bnetInfo)
if #args < 1 then
return GT:GetDungeonDifficultyString()
end
@@ -1021,7 +1026,7 @@ CM:Register({"dungeondifficulty", "dungeondiff", "dd", "dungeonmode", "dm"}, PM.
return GT:SetDungeonDifficulty(diff)
end, "CM_DUNGEONMODE_HELP")
-CM:Register({"raiddifficulty", "raiddiff", "rd", "raidmode", "rm"}, PM.Access.Groups.User.Level, function(args, sender, isChat, bnetInfo)
+CM:Register({"raiddifficulty", "raiddiff", "rd"}, PM.Access.Groups.User.Level, function(args, sender, isChat, bnetInfo)
if #args < 1 then
return GT:GetRaidDifficultyString()
end
@@ -1094,6 +1099,40 @@ CM:Register({"startduel", "startd", "challenge"}, PM.Access.Groups.User.Level, f
return CDM:Challenge(args[1])
end, "CM_STARTDUEL_HELP")
+CM:Register({"role", "rm"}, PM.Access.Groups.User.Level, function(args, sender, isChat, bnetInfo)
+ if not CRM:IsEnabled() then
+ return false, "CM_ERR_DISABLED"
+ end
+ if #args < 1 then
+ return "CM_ROLE_CURRENT", {CRM.Roles[CRM:GetRole()]}
+ end
+ local arg = args[1]:lower()
+ if arg:match("^st") or arg:match("^i") then -- Start/Initiate/Issue
+ return CRM:Start()
+ elseif arg:match("^[sa]") then -- Set/Assign (Role)
+ if #args < 2 then
+ return false, "CM_ROLE_SET_USAGE"
+ end
+ local role = args[2]:lower()
+ if role:match("^[thd]") then
+ return CRM:SetRole(role)
+ end
+ return false, "CM_ROLE_SET_USAGE"
+ elseif arg:match("^c") then -- Confirm (Role)
+ if #args >= 2 then -- Role supplied as argument #2
+ local role = args[2]:lower()
+ if role:match("^[thd]") then
+ return CRM:SetRole(role)
+ end
+ return false, "CM_ROLE_CONFIRM_USAGE"
+ else -- No role specified
+ -- Confirm the role last chosen by the player
+ return CRM:ConfirmRole()
+ end
+ end
+ return false, "CM_ROLE_USAGE"
+end, "CM_ROLE_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 4bc3c08..afb86ec 100644
--- a/Events.lua
+++ b/Events.lua
@@ -36,6 +36,7 @@ local AC = C.AddonComm
local DM = C.DeathManager
local SM = C.SummonManager
local IM = C.InviteManager
+local RM = C.RoleManager
local CDM = C.DuelManager
--- Event handler for ADDON_LOADED
@@ -160,3 +161,7 @@ end
function C.Events.DUEL_REQUESTED(self, ...)
CDM:OnDuel((select(1, ...)))
end
+
+function C.Events.ROLE_POLL_BEGIN(self, ...)
+ RM:OnRoleCheck()
+end
diff --git a/GroupTools.lua b/GroupTools.lua
index 6b34f36..a80ef84 100644
--- a/GroupTools.lua
+++ b/GroupTools.lua
@@ -90,6 +90,14 @@ function GT:IsLFGGroup()
return false
end
+--- Check if player is in a party.
+-- (Returns false if raid)
+-- @return True if player is in a party, false otherwise.
+--
+function GT:IsParty()
+ return UnitExists("party1") and not self:IsRaid() and not self:IsLFGGroup()
+end
+
--- Check if player is in a raid.
-- @return True if the player is in a raid, false otherwise.
--
diff --git a/Number.lua b/Number.lua
new file mode 100644
index 0000000..9255041
--- /dev/null
+++ b/Number.lua
@@ -0,0 +1,45 @@
+--[[
+ * 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 C = Command
+
+if type(C.Extensions) ~= "table" then
+ C.Extensions = {}
+end
+
+C.Extensions.Number = {
+ type = "ext" -- For future use
+}
+
+local L = C.LocaleManager
+local CEN = C.Extensions.Number
+
+function CEN:FormatSeconds(seconds)
+ -- Return plain seconds if less than 60 seconds
+ if seconds < 60 then return ("%d %s"):format(seconds, L("SECONDS"):lower()) end
+ local minutes = floor(seconds / 60) -- Get number of minutes
+ local secs = tostring(seconds - minutes * 60) -- Get number of remaining seconds
+ if not secs:match("%d%d") then -- Check if seconds <= 9
+ secs = "0" .. secs -- Prefix a zero to make it look better
+ end
+ return ("%d:%s"):format(minutes, secs) -- Return in m:ss format
+end
diff --git a/RoleManager.lua b/RoleManager.lua
new file mode 100644
index 0000000..7405ebf
--- /dev/null
+++ b/RoleManager.lua
@@ -0,0 +1,215 @@
+--[[
+ * 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
+
+-- API Upvalues
+local CreateFrame = CreateFrame
+local UnitSetRole = UnitSetRole
+local UnitGetAvailableRoles = UnitGetAvailableRoles
+local UnitGroupRolesAssigned = UnitGroupRolesAssigned
+
+local C = Command
+
+C.RoleManager = {
+ Roles = {
+ TANK = "CRM_TANK",
+ HEALER = "CRM_HEALER",
+ DAMAGER = "CRM_DAMAGE",
+ NONE = "CRM_UNDEFINED",
+ Tank = "TANK",
+ Healer = "HEALER",
+ Damage = "DAMAGER",
+ Undefined = "NONE"
+ },
+ BlizzRoles = {}
+}
+
+local L = C.LocaleManager
+local RM = C.RoleManager
+local GT = C.GroupTools
+local CM
+local CEN = C.Extensions.Number
+
+local DEFAULT_DELAY = 5
+local MAX_DELAY = 60 -- Arbitrary max delay, unknown if there is an existing delay
+
+function RM:Init()
+ CM = C.ChatManager
+ self:LoadSavedVars()
+end
+
+function RM:LoadSavedVars()
+ if type(C.Global["ROLE_MANAGER"]) ~= "table" then
+ C.Global["ROLE_MANAGER"] = {}
+ end
+
+ self.Settings = C.Global["ROLE_MANAGER"]
+
+ if type(self.Settings.ENABLED) ~= "boolean" then
+ self.Settings.ENABLED = true
+ end
+
+ if type(self.Settings.DELAY) ~= "number" then
+ self.Settings.DELAY = DEFAULT_DELAY
+ end
+end
+
+function RM:OnRoleCheck()
+ if self.Settings.DELAY > 0 then
+ local frame = CreateFrame("Frame")
+ frame.Time = 0
+ frame.Delay = self.Settings.DELAY
+ frame:SetScript("OnUpdate", function(self, elapsed)
+ self.Time = self.Time + elapsed
+ if self.Time >= self.Delay then
+ self:SetScript("OnUpdate", nil)
+ RM:Announce()
+ end
+ end)
+ else
+ self:Announce()
+ end
+end
+
+function RM:Announce()
+ if not self:RolePollActive() then return end
+ local current = self:GetRole()
+ local msg
+ if current ~= self.Roles.Undefined then
+ msg = "CRM_ANNOUNCE_HASROLE"
+ else
+ msg = "CRM_ANNOUNCE_NOROLE"
+ end
+ CM:SendMessage(L(msg):format(L(self.Roles[current])), "SMART")
+end
+
+function RM:SetRole(role)
+ if type(role) ~= "string" then
+ error("RoleManager.SetRole: Argument was of type [" .. type(role) .. "], expected [string].")
+ return nil
+ end
+ role = role:lower()
+ local result = self.Roles.Damage
+ if role:match("^t") then
+ result = self.Roles.Tank
+ elseif role:match("^h") then
+ result = self.Roles.Healer
+ end
+ if not self:CanBeRole(result) then
+ return false, "CRM_SET_INVALID", {L(self.Roles[result])}
+ end
+ UnitSetRole("player", result)
+ if self:RolePollActive() then
+ RolePollPopup:Hide()
+ end
+ return "CRM_SET_SUCCESS", {L(self.Roles[result])}
+end
+
+function RM:GetRole()
+ local role = UnitGroupRolesAssigned("player")
+ if role == "TANK" then
+ return self.Roles.Tank
+ elseif role == "HEALER" then
+ return self.Roles.Healer
+ elseif role == "DAMAGER" then
+ return self.Roles.Damage
+ end
+ return self.Roles.Undefined
+end
+
+function RM:ConfirmRole()
+ local role = self:GetRole()
+ if role == self.Roles.Undefined then
+ return false, "CRM_CONFIRM_NOROLE"
+ end
+ return self:SetRole(role)
+end
+
+function RM:CanBeRole(role)
+ if type(role) ~= "string" then
+ error("RoleManager.CanBeRole: Argument was of type [" .. type(role) .. "], expected [string].")
+ return nil
+ end
+ role = role:lower()
+ local tank, healer, dps = UnitGetAvailableRoles("player")
+ if role:match("^t") then
+ return tank
+ elseif role:match("^h") then
+ return healer
+ end
+ return dps
+end
+
+function RM:RolePollActive()
+ return RolePollPopup and RolePollPopup:IsShown()
+end
+
+function RM:Start()
+ if self:RolePollActive() then
+ return false, "CRM_START_ACTIVE"
+ elseif (GT:IsParty() and GT:IsGroupLeader()) or (GT:IsRaid() and GT:IsRaidLeaderOrAssistant()) then
+
+ else
+ return false, "CRM_START_NOPRIV"
+ end
+end
+
+function RM:Enable()
+ self.Settings.ENABLED = true
+ return "CRM_ENABLED"
+end
+
+function RM:Disable()
+ self.Settings.ENABLED = false
+ return "CRM_DISABLED"
+end
+
+function RM:Toggle()
+ if self:IsEnabled() then
+ return self:Disable()
+ end
+ return self:Enable()
+end
+
+function RM:IsEnabled()
+ return self.Settings.ENABLED
+end
+
+function RM:GetDelay()
+ return CEN:FormatSeconds(self:GetRawDelay())
+end
+
+function RM:GetRawDelay()
+ return self.Settings.DELAY
+end
+
+function RM: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
+ return "CRM_SETDELAY_SUCCESS", {CEN:FormatSeconds(amount)}
+ end
+ return "CRM_SETDELAY_INSTANT"
+end
diff --git a/SummonManager.lua b/SummonManager.lua
index 612e1a2..3a8c54a 100644
--- a/SummonManager.lua
+++ b/SummonManager.lua
@@ -43,23 +43,13 @@ local L = C.LocaleManager
local SM = C.SummonManager
local CM
local GT = C.GroupTools
+local CEN = C.Extensions.Number
local DEFAULT_DELAY = 5
local MAX_DELAY = 110 -- 1 minute 50 seconds, summons expire after 2 minutes (usually)
local LastSummoner
-local function FormatSeconds(seconds)
- -- Return plain seconds if less than 60 seconds
- if seconds < 60 then return ("%d %s"):format(seconds, L("SECONDS"):lower()) end
- local minutes = floor(seconds / 60) -- Get number of minutes
- local secs = tostring(seconds - minutes * 60) -- Get number of remaining seconds
- if not secs:match("%d%d") then -- Check if seconds > 9
- secs = "0" .. secs -- Prefix a zero to make it look better
- end
- return ("%d:%s"):format(minutes, secs) -- Return in m:ss format
-end
-
function SM:Init()
CM = C.ChatManager
LastSummoner = L("UNKNOWN")
@@ -195,7 +185,7 @@ function SM:SetDelay(amount)
end
self.Settings.DELAY = amount
if amount > 0 then
- return "SM_SETDELAY_SUCCESS", {FormatSeconds(amount)}
+ return "SM_SETDELAY_SUCCESS", {CEN:FormatSeconds(amount)}
end
return "SM_SETDELAY_INSTANT"
end
diff --git a/load.xml b/load.xml
index e52cdbb..4a6775c 100644
--- a/load.xml
+++ b/load.xml
@@ -23,6 +23,7 @@
<Script file="Table.lua" />
<Script file="String.lua" />
<Include file="LocaleLoader.xml" />
+ <Script file="Number.lua" />
<Script file="Logger.lua" />
<Script file="BattleNetTools.lua" />
<Script file="GroupTools.lua" />
@@ -36,6 +37,7 @@
<Script file="SummonManager.lua" />
<Script file="InviteManager.lua" />
<Script file="DuelManager.lua" />
+ <Script file="RoleManager.lua" />
<Script file="CommandManager.lua" />
<Script file="ChatManager.lua" />
<Script file="Events.lua" />
diff --git a/locales/enUS.lua b/locales/enUS.lua
index c07b09c..b536361 100644
--- a/locales/enUS.lua
+++ b/locales/enUS.lua
@@ -90,6 +90,7 @@ local L = {
-- CommandManager --
--------------------
+ CM_ERR_UNKNOWN = "Unknown error occurred, please contact addon author.",
CM_ERR_NOTALLOWED = "%s is not allowed to be used, %s.",
CM_ERR_NOACCESS = "You do not have permission to use that command, %s. Required access level: %d. Your access level: %d.",
CM_ERR_NOTREGGED = "%q is not a registered command.",
@@ -303,6 +304,12 @@ local L = {
CM_STARTDUEL_HELP = "Challenges another player to a duel.",
CM_STARTDUEL_USAGE = "Usage: startduel <target>",
+ CM_ROLE_HELP = "Provides various commands for controlling role assignment.",
+ CM_ROLE_USAGE = "Usage: role start|set|confirm",
+ CM_ROLE_CURRENT = "My current role is %s.",
+ CM_ROLE_SET_USAGE = "Usage: role set tank|healer|dps",
+ CM_ROLE_CONFIRM_USAGE = "Usage: role confirm [tank|healer|dps]",
+
------------
-- Events --
------------
@@ -583,6 +590,33 @@ local L = {
CDM_DELAY_DISABLED = "Announce delay has been disabled, will now announce immediately.",
-----------------
+ -- RoleManager --
+ -----------------
+
+ CRM_ENABLED = "RoleManager enabled.",
+ CRM_DISABLED = "RoleManager disabled.",
+
+
+ CRM_TANK = "Tank",
+ CRM_HEALER = "Healer",
+ CRM_DAMAGE = "DPS",
+ CRM_UNDEFINED = "Undefined",
+
+ CRM_ANNOUNCE_HASROLE = "Role check started! Confirm my current role (%s) with !role confirm or set a new one with !role confirm tank|healer|dps",
+ CRM_ANNOUNCE_NOROLE = "Role check started! Set my role with !role confirm tank|healer|dps",
+
+ CRM_SET_INVALID = "I cannot fulfill the role of %s, please specify another role.",
+ CRM_SET_SUCCESS = "Successfully set my role to %s!",
+
+ CRM_CONFIRM_NOROLE = "No role set, confirmation needed with role confirm tank|healer|dps",
+
+ CRM_START_ACTIVE = "A role check is already pending, please wait until it has ended.",
+ CRM_START_NOPRIV = "Unable to start role check, not leader or assistant.",
+
+ CRM_STARTDELAY_SUCCESS = "RoleManager announce delay set to %s!",
+ CRM_STARTDELAY_INSTANT = "RoleManager now announces instantly.",
+
+ -----------------
-- AuthManager --
-----------------
diff --git a/locales/svSE.lua b/locales/svSE.lua
index 2938a48..8854ca0 100644
--- a/locales/svSE.lua
+++ b/locales/svSE.lua
@@ -90,6 +90,7 @@ local L = {
-- CommandManager --
--------------------
+ CM_ERR_UNKNOWN = "Okänt fel inträffade, kontakta addonskapare.",
CM_ERR_NOTALLOWED = "%s är inte tillåtet att användas, %s.",
CM_ERR_NOACCESS = "Du har inte tillåtelse att använda det kommandot, %s. Behörighet som krävs: %d. Din behörighet: %d.",
CM_ERR_NOTREGGED = "%q är inte ett registrerat kommando.",
@@ -303,6 +304,12 @@ local L = {
CM_STARTDUEL_HELP = "Challenges another player to a duel.",
CM_STARTDUEL_USAGE = "Usage: startduel <target>",
+ CM_ROLE_HELP = "Provides various commands for controlling role assignment.",
+ CM_ROLE_USAGE = "Användning: role start|set|confirm",
+ CM_ROLE_CURRENT = "My current role is %s.",
+ CM_ROLE_SET_USAGE = "Användning: role set tank|healer|dps",
+ CM_ROLE_CONFIRM_USAGE = "Usage: role confirm [tank|healer|dps]",
+
------------
-- Events --
------------
@@ -583,6 +590,33 @@ local L = {
CDM_DELAY_DISABLED = "Announce delay has been disabled, will now announce immediately.",
-----------------
+ -- RoleManager --
+ -----------------
+
+ CRM_ENABLED = "RoleManager enabled.",
+ CRM_DISABLED = "RoleManager disabled.",
+
+
+ CRM_TANK = "Tank",
+ CRM_HEALER = "Healer",
+ CRM_DAMAGE = "DPS",
+ CRM_UNDEFINED = "Undefined",
+
+ CRM_ANNOUNCE_HASROLE = "Role check started! Confirm my current role (%s) with !role confirm or set a new one with !role confirm tank|healer|dps",
+ CRM_ANNOUNCE_NOROLE = "Role check started! Set my role with !role confirm tank|healer|dps",
+
+ CRM_SET_INVALID = "I cannot fulfill the role of %s, please specify another role.",
+ CRM_SET_SUCCESS = "Successfully set my role to %s!",
+
+ CRM_CONFIRM_NOROLE = "No role set, confirmation needed with role confirm tank|healer|dps",
+
+ CRM_START_ACTIVE = "A role check is already pending, please wait until it has ended.",
+ CRM_START_NOPRIV = "Unable to start role check, not leader or assistant.",
+
+ CRM_STARTDELAY_SUCCESS = "RoleManager announce delay set to %s!",
+ CRM_STARTDELAY_INSTANT = "RoleManager now announces instantly.",
+
+ -----------------
-- AuthManager --
-----------------