Created
June 24, 2020 08:26
-
-
Save addohm/218f1df4d074ae87d45243e7ef400628 to your computer and use it in GitHub Desktop.
Angry Assignments+
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local AngryAssign = LibStub("AceAddon-3.0"):NewAddon("AngryAssignments", "AceConsole-3.0", "AceEvent-3.0", "AceComm-3.0", "AceTimer-3.0") | |
local AceGUI = LibStub("AceGUI-3.0") | |
local libS = LibStub("AceSerializer-3.0") | |
local libC = LibStub("LibCompress") | |
local lwin = LibStub("LibWindow-1.1") | |
local libCE = libC:GetAddonEncodeTable() | |
local LSM = LibStub("LibSharedMedia-3.0") | |
BINDING_HEADER_AngryAssign = "Angry Assignments" | |
BINDING_NAME_AngryAssign_WINDOW = "Toggle Window" | |
BINDING_NAME_AngryAssign_LOCK = "Toggle Lock" | |
BINDING_NAME_AngryAssign_DISPLAY = "Toggle Display" | |
BINDING_NAME_AngryAssign_SHOW_DISPLAY = "Show Display" | |
BINDING_NAME_AngryAssign_HIDE_DISPLAY = "Hide Display" | |
BINDING_NAME_AngryAssign_OUTPUT = "Output Assignment to Chat" | |
local AngryAssign_Version = 'v1.13.0c' | |
local AngryAssign_Timestamp = '20200205162926' | |
local isClassic = (WOW_PROJECT_ID == WOW_PROJECT_CLASSIC) | |
local protocolVersion = 1 | |
local comPrefix = "AnAss"..protocolVersion | |
local updateFrequency = 2 | |
local pageLastUpdate = {} | |
local pageTimerId = {} | |
local displayLastUpdate = nil | |
local displayTimerId = nil | |
local versionLastUpdate = nil | |
local versionTimerId = nil | |
local guildOfficerNames = nil | |
-- Used for version tracking | |
local warnedOOD = false | |
local versionList = {} | |
local comStarted = false | |
local warnedPermission = false | |
local currentGroup = nil | |
-- Pages Saved Variable Format | |
-- AngryAssign_Pages = { | |
-- [Id] = { Id = 1231, Updated = time(), UpdateId = self:Hash(name, contents), Name = "Name", Contents = "...", Backup = "...", CategoryId = 123 }, | |
-- ... | |
-- } | |
-- AngryAssign_Categories = { | |
-- [Id] = { Id = 1231, Name = "Name", CategoryId = 123 }, | |
-- ... | |
-- } | |
-- | |
-- Format for our addon communication | |
-- | |
-- { "PAGE", [Id], [Last Update Timestamp], [Name], [Contents], [Last Update Unique Id] } | |
-- Sent when a page is updated. Id is a random unique value. Unique Id is hash of page contents. Uses RAID. | |
-- | |
-- { "REQUEST_PAGE", [Id] } | |
-- Asks to be sent PAGE with given Id. Response is a throttled PAGE. Uses WHISPER to raid leader. | |
-- | |
-- { "DISPLAY", [Id], [Last Update Timestamp], [Last Update Unique Id] } | |
-- Raid leader / promoted sends out when new page is to be displayed. Uses RAID. | |
-- | |
-- { "REQUEST_DISPLAY" } | |
-- Asks to be sent DISPLAY. Response is a throttled DISPLAY. Uses WHISPER to raid leader. | |
-- | |
-- { "VER_QUERY" } | |
-- { "VERSION", [Version], [Project Timestamp], [Valid Raid] } | |
-- Constants for dealing with our addon communication | |
local COMMAND = 1 | |
local PAGE_Id = 2 | |
local PAGE_Updated = 3 | |
local PAGE_Name = 4 | |
local PAGE_Contents = 5 | |
local PAGE_UpdateId = 6 | |
local REQUEST_PAGE_Id = 2 | |
local DISPLAY_Id = 2 | |
local DISPLAY_Updated = 3 | |
local DISPLAY_UpdateId = 4 | |
local VERSION_Version = 2 | |
local VERSION_Timestamp = 3 | |
local VERSION_ValidRaid = 4 | |
----------------------- | |
-- Utility Functions -- | |
----------------------- | |
local function selectedLastValue(input) | |
local a = select(-1, strsplit("", input or "")) | |
return tonumber(a) | |
end | |
local function tReverse(tbl) | |
for i=1, math.floor(#tbl / 2) do | |
tbl[i], tbl[#tbl - i + 1] = tbl[#tbl - i + 1], tbl[i] | |
end | |
end | |
local _player_realm = nil | |
local function EnsureUnitFullName(unit) | |
if not _player_realm then _player_realm = select(2, UnitFullName('player')) end | |
if unit and not unit:find('-') then | |
unit = unit..'-'.._player_realm | |
end | |
return unit | |
end | |
local function EnsureUnitShortName(unit) | |
if not _player_realm then _player_realm = select(2, UnitFullName('player')) end | |
local name, realm = strsplit("-", unit, 2) | |
if not realm or realm == _player_realm then | |
return name | |
else | |
return unit | |
end | |
end | |
local function PlayerFullName() | |
if not _player_realm then _player_realm = select(2, UnitFullName('player')) end | |
return UnitName('player')..'-'.._player_realm | |
end | |
local function RGBToHex(r, g, b, a) | |
r = math.ceil(255 * r) | |
g = math.ceil(255 * g) | |
b = math.ceil(255 * b) | |
if a == nil then | |
return string.format("%02x%02x%02x", r, g, b) | |
else | |
a = math.ceil(255 * a) | |
return string.format("%02x%02x%02x%02x", r, g, b, a) | |
end | |
end | |
local function HexToRGB(hex) | |
if string.len(hex) == 8 then | |
return tonumber("0x"..hex:sub(1,2)) / 255, tonumber("0x"..hex:sub(3,4)) / 255, tonumber("0x"..hex:sub(5,6)) / 255, tonumber("0x"..hex:sub(7,8)) / 255 | |
else | |
return tonumber("0x"..hex:sub(1,2)) / 255, tonumber("0x"..hex:sub(3,4)) / 255, tonumber("0x"..hex:sub(5,6)) / 255 | |
end | |
end | |
------------------------- | |
-- Addon Communication -- | |
------------------------- | |
function AngryAssign:ReceiveMessage(prefix, data, channel, sender) | |
if prefix ~= comPrefix then return end | |
local one = libCE:Decode(data) -- Decode the compressed data | |
local two, message = libC:Decompress(one) -- Decompress the decoded data | |
if not two then error("Error decompressing: " .. message); return end | |
local success, final = libS:Deserialize(two) -- Deserialize the decompressed data | |
if not success then error("Error deserializing " .. final); return end | |
self:ProcessMessage( sender, final ) | |
end | |
function AngryAssign:SendOutMessage(data, channel, target) | |
local one = libS:Serialize( data ) | |
local two = libC:CompressHuffman(one) | |
local final = libCE:Encode(two) | |
if not channel then | |
if IsInGroup(LE_PARTY_CATEGORY_INSTANCE) or IsInRaid(LE_PARTY_CATEGORY_INSTANCE) then | |
channel = "INSTANCE_CHAT" | |
elseif IsInRaid(LE_PARTY_CATEGORY_HOME) then | |
channel = "RAID" | |
elseif IsInGroup(LE_PARTY_CATEGORY_HOME) then | |
channel = "PARTY" | |
end | |
end | |
if not channel then return end | |
-- self:Print("Sending "..data[COMMAND].." over "..channel.." to "..tostring(target)) | |
self:SendCommMessage(comPrefix, final, channel, target, "NORMAL") | |
return true | |
end | |
function AngryAssign:ProcessMessage(sender, data) | |
local cmd = data[COMMAND] | |
sender = EnsureUnitFullName(sender) | |
-- self:Print("Received "..data[COMMAND].." from "..sender) | |
if cmd == "PAGE" then | |
if sender == PlayerFullName() then return end | |
if not self:PermissionCheck(sender) then | |
self:PermissionCheckFailError(sender) | |
return | |
end | |
local contents_updated = true | |
local id = data[PAGE_Id] | |
local page = AngryAssign_Pages[id] | |
if page then | |
if data[PAGE_UpdateId] and page.UpdateId == data[PAGE_UpdateId] then return end -- The version received is same as the one we already have | |
contents_updated = page.Contents ~= data[PAGE_Contents] | |
page.Name = data[PAGE_Name] | |
page.Contents = data[PAGE_Contents] | |
page.Updated = data[PAGE_Updated] | |
page.UpdateId = data[PAGE_UpdateId] or self:Hash(page.Name, page.Contents) | |
if self:SelectedId() == id then | |
self:SelectedUpdated(sender) | |
self:UpdateSelected() | |
end | |
else | |
AngryAssign_Pages[id] = { Id = id, Updated = data[PAGE_Updated], UpdateId = data[PAGE_UpdateId], Name = data[PAGE_Name], Contents = data[PAGE_Contents] } | |
end | |
if AngryAssign_State.displayed == id then | |
self:UpdateDisplayed() | |
self:ShowDisplay() | |
if contents_updated then self:DisplayUpdateNotification() end | |
end | |
self:UpdateTree() | |
elseif cmd == "DISPLAY" then | |
if sender == PlayerFullName() then return end | |
if not self:PermissionCheck(sender) then | |
if data[DISPLAY_Id] then self:PermissionCheckFailError(sender) end | |
return | |
end | |
local id = data[DISPLAY_Id] | |
local updated = data[DISPLAY_Updated] | |
local updateId = data[DISPLAY_UpdateId] | |
local page = AngryAssign_Pages[id] | |
local sameVersion = (updateId and page and updateId == page.UpdateId) or (not updateId and page and updated == page.Updated) | |
if id and not sameVersion then | |
self:SendRequestPage(id, sender) | |
end | |
if AngryAssign_State.displayed ~= id then | |
AngryAssign_State.displayed = id | |
self:UpdateTree() | |
self:UpdateDisplayed() | |
self:ShowDisplay() | |
if id then self:DisplayUpdateNotification() end | |
end | |
elseif cmd == "REQUEST_DISPLAY" then | |
if sender == PlayerFullName() then return end | |
if not self:IsPlayerRaidLeader() then return end | |
self:SendDisplay( AngryAssign_State.displayed ) | |
elseif cmd == "REQUEST_PAGE" then | |
if sender == PlayerFullName() then return end | |
self:SendPage( data[REQUEST_PAGE_Id] ) | |
elseif cmd == "VER_QUERY" then | |
self:SendVersion() | |
elseif cmd == "VERSION" then | |
local localTimestamp, ver, timestamp | |
if AngryAssign_Timestamp:sub(1,1) == "@" then localTimestamp = "dev" else localTimestamp = tonumber(AngryAssign_Timestamp) end | |
ver = data[VERSION_Version] | |
timestamp = data[VERSION_Timestamp] | |
local localStr = tostring(localTimestamp) | |
local remoteStr = tostring(timestamp) | |
if (localStr ~= "dev" and localStr:len() ~= 14) or (remoteStr ~= "dev" and remoteStr:len() ~= 14) then | |
if localStr ~= "dev" then localTimestamp = tonumber(localStr:sub(1,8)) end | |
if remoteStr ~= "dev" then timestamp = tonumber(remoteStr:sub(1,8)) end | |
end | |
if localTimestamp ~= "dev" and timestamp ~= "dev" and timestamp > localTimestamp and not warnedOOD then | |
self:Print("Your version of Angry Assignments is out of date! Download the latest version from curse.com.") | |
warnedOOD = true | |
end | |
versionList[ sender ] = { valid = data[VERSION_ValidRaid], version = ver } | |
end | |
end | |
function AngryAssign:PermissionCheckFailError(sender) | |
if not warnedPermission then | |
self:Print( RED_FONT_COLOR_CODE .. "You have received a page update from "..Ambiguate(sender, "none").." that was rejected due to insufficient permissions. If you wish to see this page, please adjust your permission settings.|r" ) | |
warnedPermission = true | |
end | |
end | |
function AngryAssign:SendPage(id, force) | |
local lastUpdate = pageLastUpdate[id] | |
local timerId = pageTimerId[id] | |
local curTime = time() | |
if lastUpdate and (curTime - lastUpdate <= updateFrequency) then | |
if not timerId then | |
if force then | |
self:SendPageMessage(id) | |
else | |
pageTimerId[id] = self:ScheduleTimer("SendPageMessage", updateFrequency - (curTime - lastUpdate), id) | |
end | |
elseif force then | |
self:CancelTimer( timerId ) | |
self:SendPageMessage(id) | |
end | |
else | |
self:SendPageMessage(id) | |
end | |
end | |
function AngryAssign:SendPageMessage(id) | |
pageLastUpdate[id] = time() | |
pageTimerId[id] = nil | |
local page = AngryAssign_Pages[ id ] | |
if not page then error("Can't send page, does not exist"); return end | |
if not page.UpdateId then page.UpdateId = self:Hash(page.Name, page.Contents) end | |
self:SendOutMessage({ "PAGE", [PAGE_Id] = page.Id, [PAGE_Updated] = page.Updated, [PAGE_Name] = page.Name, [PAGE_Contents] = page.Contents, [PAGE_UpdateId] = page.UpdateId }) | |
end | |
function AngryAssign:SendDisplay(id, force) | |
local curTime = time() | |
if displayLastUpdate and (curTime - displayLastUpdate <= updateFrequency) then | |
if not displayTimerId then | |
if force then | |
self:SendDisplayMessage(id) | |
else | |
displayTimerId = self:ScheduleTimer("SendDisplayMessage", updateFrequency - (curTime - displayLastUpdate), id) | |
end | |
elseif force then | |
self:CancelTimer( displayTimerId ) | |
self:SendDisplayMessage(id) | |
end | |
else | |
self:SendDisplayMessage(id) | |
end | |
end | |
function AngryAssign:SendDisplayMessage(id) | |
displayLastUpdate = time() | |
displayTimerId = nil | |
local page = AngryAssign_Pages[ id ] | |
if not page then | |
self:SendOutMessage({ "DISPLAY", [DISPLAY_Id] = nil, [DISPLAY_Updated] = nil, [DISPLAY_UpdateId] = nil }) | |
else | |
if not page.UpdateId then page.UpdateId = self:Hash(page.Name, page.Contents) end | |
self:SendOutMessage({ "DISPLAY", [DISPLAY_Id] = page.Id, [DISPLAY_Updated] = page.Updated, [DISPLAY_UpdateId] = page.UpdateId }) | |
end | |
end | |
function AngryAssign:SendRequestDisplay() | |
if (IsInRaid() or IsInGroup()) then | |
local to = self:GetRaidLeader(true) | |
if to then self:SendOutMessage({ "REQUEST_DISPLAY" }, "WHISPER", to) end | |
end | |
end | |
function AngryAssign:SendVersion(force) | |
local curTime = time() | |
if versionLastUpdate and (curTime - versionLastUpdate <= updateFrequency) then | |
if not versionTimerId then | |
if force then | |
self:SendVersionMessage(id) | |
else | |
versionTimerId = self:ScheduleTimer("SendVersionMessage", updateFrequency - (curTime - versionLastUpdate), id) | |
end | |
elseif force then | |
self:CancelTimer( versionTimerId ) | |
self:SendVersionMessage() | |
end | |
else | |
self:SendVersionMessage() | |
end | |
end | |
function AngryAssign:SendVersionMessage() | |
versionLastUpdate = time() | |
versionTimerId = nil | |
local revToSend | |
local timestampToSend | |
local verToSend | |
if AngryAssign_Version:sub(1,1) == "@" then verToSend = "dev" else verToSend = AngryAssign_Version end | |
if AngryAssign_Timestamp:sub(1,1) == "@" then timestampToSend = "dev" else timestampToSend = tonumber(AngryAssign_Timestamp) end | |
self:SendOutMessage({ "VERSION", [VERSION_Version] = verToSend, [VERSION_Timestamp] = timestampToSend, [VERSION_ValidRaid] = self:IsValidRaid() }) | |
end | |
function AngryAssign:SendVerQuery() | |
self:SendOutMessage({ "VER_QUERY" }) | |
end | |
function AngryAssign:SendRequestPage(id, to) | |
if (IsInRaid() or IsInGroup()) or to then | |
if not to then to = self:GetRaidLeader(true) end | |
if to then self:SendOutMessage({ "REQUEST_PAGE", [REQUEST_PAGE_Id] = id }, "WHISPER", to) end | |
end | |
end | |
function AngryAssign:GetRaidLeader(online_only) | |
if (IsInRaid() or IsInGroup()) then | |
for i = 1, GetNumGroupMembers() do | |
local name, rank, subgroup, level, class, fileName, zone, online, isDead, role, isML = GetRaidRosterInfo(i) | |
if rank == 2 then | |
if (not online_only) or online then | |
return EnsureUnitFullName(name) | |
else | |
return nil | |
end | |
end | |
end | |
end | |
return nil | |
end | |
function AngryAssign:GetCurrentGroup() | |
local player = PlayerFullName() | |
if (IsInRaid() or IsInGroup()) then | |
for i = 1, GetNumGroupMembers() do | |
local name, _, subgroup = GetRaidRosterInfo(i) | |
if EnsureUnitFullName(name) == player then | |
return subgroup | |
end | |
end | |
end | |
return nil | |
end | |
function AngryAssign:VersionCheckOutput() | |
local missing_addon = {} | |
local invalid_raid = {} | |
local different_version = {} | |
local up_to_date = {} | |
local ver = AngryAssign_Version | |
if ver:sub(1,1) == "@" then ver = "dev" end | |
if (IsInRaid() or IsInGroup()) then | |
for i = 1, GetNumGroupMembers() do | |
local name, _, _, _, _, _, _, online = GetRaidRosterInfo(i) | |
local fullname = EnsureUnitFullName(name) | |
if online then | |
if not versionList[ fullname ] then | |
tinsert(missing_addon, name) | |
elseif versionList[ fullname ].valid == false or versionList[ fullname ].valid == nil then | |
tinsert(invalid_raid, name) | |
elseif ver ~= versionList[ fullname ].version then | |
tinsert(different_version, string.format("%s - %s", name, versionList[ fullname ].version) ) | |
else | |
tinsert(up_to_date, name) | |
end | |
end | |
end | |
end | |
self:Print("Version check results:") | |
if #up_to_date > 0 then | |
print(LIGHTYELLOW_FONT_COLOR_CODE.."Same version:|r "..table.concat(up_to_date, ", ")) | |
end | |
if #different_version > 0 then | |
print(LIGHTYELLOW_FONT_COLOR_CODE.."Different version:|r "..table.concat(different_version, ", ")) | |
end | |
if #invalid_raid > 0 then | |
print(LIGHTYELLOW_FONT_COLOR_CODE.."Not allowing changes:|r "..table.concat(invalid_raid, ", ")) | |
end | |
if #missing_addon > 0 then | |
print(LIGHTYELLOW_FONT_COLOR_CODE.."Missing addon:|r "..table.concat(missing_addon, ", ")) | |
end | |
end | |
-------------------------- | |
-- Editing Pages Window -- | |
-------------------------- | |
function AngryAssign_ToggleWindow() | |
if not AngryAssign.window then AngryAssign:CreateWindow() end | |
if AngryAssign.window:IsShown() then | |
AngryAssign.window:Hide() | |
else | |
AngryAssign.window:Show() | |
end | |
end | |
function AngryAssign_ToggleLock() | |
AngryAssign:ToggleLock() | |
end | |
local function AngryAssign_AddPage(widget, event, value) | |
local popup_name = "AngryAssign_AddPage" | |
if StaticPopupDialogs[popup_name] == nil then | |
StaticPopupDialogs[popup_name] = { | |
button1 = OKAY, | |
button2 = CANCEL, | |
OnAccept = function(self) | |
local text = self.editBox:GetText() | |
if text ~= "" then AngryAssign:CreatePage(text) end | |
end, | |
EditBoxOnEnterPressed = function(self) | |
local text = self:GetParent().editBox:GetText() | |
if text ~= "" then AngryAssign:CreatePage(text) end | |
self:GetParent():Hide() | |
end, | |
text = "New page name:", | |
hasEditBox = true, | |
whileDead = true, | |
EditBoxOnEscapePressed = function(self) self:GetParent():Hide() end, | |
hideOnEscape = true, | |
preferredIndex = 3 | |
} | |
end | |
StaticPopup_Show(popup_name) | |
end | |
local function AngryAssign_RenamePage(pageId) | |
local page = AngryAssign:Get(pageId) | |
if not page then return end | |
local popup_name = "AngryAssign_RenamePage_"..page.Id | |
if StaticPopupDialogs[popup_name] == nil then | |
StaticPopupDialogs[popup_name] = { | |
button1 = OKAY, | |
button2 = CANCEL, | |
OnAccept = function(self) | |
local text = self.editBox:GetText() | |
AngryAssign:RenamePage(page.Id, text) | |
end, | |
EditBoxOnEnterPressed = function(self) | |
local text = self:GetParent().editBox:GetText() | |
AngryAssign:RenamePage(page.Id, text) | |
self:GetParent():Hide() | |
end, | |
OnShow = function(self) | |
self.editBox:SetText(page.Name) | |
end, | |
whileDead = true, | |
hasEditBox = true, | |
EditBoxOnEscapePressed = function(self) self:GetParent():Hide() end, | |
hideOnEscape = true, | |
preferredIndex = 3 | |
} | |
end | |
StaticPopupDialogs[popup_name].text = 'Rename page "'.. page.Name ..'" to:' | |
StaticPopup_Show(popup_name) | |
end | |
local function AngryAssign_DeletePage(pageId) | |
local page = AngryAssign:Get(pageId) | |
if not page then return end | |
local popup_name = "AngryAssign_DeletePage_"..page.Id | |
if StaticPopupDialogs[popup_name] == nil then | |
StaticPopupDialogs[popup_name] = { | |
button1 = OKAY, | |
button2 = CANCEL, | |
OnAccept = function(self) | |
AngryAssign:DeletePage(page.Id) | |
end, | |
whileDead = true, | |
hideOnEscape = true, | |
preferredIndex = 3 | |
} | |
end | |
StaticPopupDialogs[popup_name].text = 'Are you sure you want to delete page "'.. page.Name ..'"?' | |
StaticPopup_Show(popup_name) | |
end | |
local function AngryAssign_AddCategory(widget, event, value) | |
local popup_name = "AngryAssign_AddCategory" | |
if StaticPopupDialogs[popup_name] == nil then | |
StaticPopupDialogs[popup_name] = { | |
button1 = OKAY, | |
button2 = CANCEL, | |
OnAccept = function(self) | |
local text = self.editBox:GetText() | |
if text ~= "" then AngryAssign:CreateCategory(text) end | |
end, | |
EditBoxOnEnterPressed = function(self) | |
local text = self:GetParent().editBox:GetText() | |
if text ~= "" then AngryAssign:CreateCategory(text) end | |
self:GetParent():Hide() | |
end, | |
text = "New category name:", | |
hasEditBox = true, | |
whileDead = true, | |
EditBoxOnEscapePressed = function(self) self:GetParent():Hide() end, | |
hideOnEscape = true, | |
preferredIndex = 3 | |
} | |
end | |
StaticPopup_Show(popup_name) | |
end | |
local function AngryAssign_RenameCategory(catId) | |
local cat = AngryAssign:GetCat(catId) | |
if not cat then return end | |
local popup_name = "AngryAssign_RenameCategory_"..cat.Id | |
if StaticPopupDialogs[popup_name] == nil then | |
StaticPopupDialogs[popup_name] = { | |
button1 = OKAY, | |
button2 = CANCEL, | |
OnAccept = function(self) | |
local text = self.editBox:GetText() | |
AngryAssign:RenameCategory(cat.Id, text) | |
end, | |
EditBoxOnEnterPressed = function(self) | |
local text = self:GetParent().editBox:GetText() | |
AngryAssign:RenameCategory(cat.Id, text) | |
self:GetParent():Hide() | |
end, | |
OnShow = function(self) | |
self.editBox:SetText(cat.Name) | |
end, | |
whileDead = true, | |
hasEditBox = true, | |
EditBoxOnEscapePressed = function(self) self:GetParent():Hide() end, | |
hideOnEscape = true, | |
preferredIndex = 3 | |
} | |
end | |
StaticPopupDialogs[popup_name].text = 'Rename category "'.. cat.Name ..'" to:' | |
StaticPopup_Show(popup_name) | |
end | |
local function AngryAssign_DeleteCategory(catId) | |
local cat = AngryAssign:GetCat(catId) | |
if not cat then return end | |
local popup_name = "AngryAssign_DeleteCategory_"..cat.Id | |
if StaticPopupDialogs[popup_name] == nil then | |
StaticPopupDialogs[popup_name] = { | |
button1 = OKAY, | |
button2 = CANCEL, | |
OnAccept = function(self) | |
AngryAssign:DeleteCategory(cat.Id) | |
end, | |
whileDead = true, | |
hideOnEscape = true, | |
preferredIndex = 3 | |
} | |
end | |
StaticPopupDialogs[popup_name].text = 'Are you sure you want to delete category "'.. cat.Name ..'"?' | |
StaticPopup_Show(popup_name) | |
end | |
local function AngryAssign_AssignCategory(frame, entryId, catId) | |
HideDropDownMenu(1) | |
AngryAssign:AssignCategory(entryId, catId) | |
end | |
local function AngryAssign_RevertPage(widget, event, value) | |
if not AngryAssign.window then return end | |
AngryAssign:UpdateSelected(true) | |
end | |
function AngryAssign:DisplayPageByName( name ) | |
for id, page in pairs(AngryAssign_Pages) do | |
if page.Name == name then | |
return self:DisplayPage( id ) | |
end | |
end | |
return false | |
end | |
function AngryAssign:DisplayPage( id ) | |
if not self:PermissionCheck() then return end | |
self:TouchPage( id ) | |
self:SendPage( id, true ) | |
self:SendDisplay( id, true ) | |
if AngryAssign_State.displayed ~= id then | |
AngryAssign_State.displayed = id | |
AngryAssign:UpdateDisplayed() | |
AngryAssign:ShowDisplay() | |
AngryAssign:UpdateTree() | |
AngryAssign:DisplayUpdateNotification() | |
end | |
return true | |
end | |
local function AngryAssign_DisplayPage(widget, event, value) | |
if not AngryAssign:PermissionCheck() then return end | |
local id = AngryAssign:SelectedId() | |
AngryAssign:DisplayPage( id ) | |
end | |
local function AngryAssign_ClearPage(widget, event, value) | |
if not AngryAssign:PermissionCheck() then return end | |
AngryAssign:ClearDisplayed() | |
AngryAssign:SendDisplay( nil, true ) | |
end | |
local function AngryAssign_TextChanged(widget, event, value) | |
AngryAssign.window.button_revert:SetDisabled(false) | |
AngryAssign.window.button_restore:SetDisabled(false) | |
AngryAssign.window.button_display:SetDisabled(true) | |
AngryAssign.window.button_output:SetDisabled(true) | |
end | |
local function AngryAssign_TextEntered(widget, event, value) | |
AngryAssign:UpdateContents(AngryAssign:SelectedId(), value) | |
end | |
local function AngryAssign_RestorePage(widget, event, value) | |
if not AngryAssign.window then return end | |
local page = AngryAssign_Pages[AngryAssign:SelectedId()] | |
if not page or not page.Backup then return end | |
AngryAssign.window.text:SetText( page.Backup ) | |
AngryAssign.window.text.button:Enable() | |
AngryAssign_TextChanged(widget, event, value) | |
end | |
local function AngryAssign_CategoryMenuList(entryId, parentId) | |
local categories = {} | |
local checkedId | |
if entryId > 0 then | |
local page = AngryAssign_Pages[entryId] | |
checkedId = page.CategoryId | |
else | |
local cat = AngryAssign_Categories[-entryId] | |
checkedId = cat.CategoryId | |
end | |
for _, cat in pairs(AngryAssign_Categories) do | |
if cat.Id ~= -entryId and (parentId or not cat.CategoryId) and (not parentId or cat.CategoryId == parentId) then | |
local subMenu = AngryAssign_CategoryMenuList(entryId, cat.Id) | |
table.insert(categories, { text = cat.Name, value = cat.Id, menuList = subMenu, hasArrow = (subMenu ~= nil), checked = (checkedId == cat.Id), func = AngryAssign_AssignCategory, arg1 = entryId, arg2 = cat.Id }) | |
end | |
end | |
table.sort(categories, function(a,b) return a.text < b.text end) | |
if #categories > 0 then | |
return categories | |
end | |
end | |
local PagesDropDownList | |
function AngryAssign_PageMenu(pageId) | |
local page = AngryAssign_Pages[pageId] | |
if not page then return end | |
if not PagesDropDownList then | |
PagesDropDownList = { | |
{ notCheckable = true, isTitle = true }, | |
{ text = "Rename", notCheckable = true, func = function(frame, pageId) AngryAssign_RenamePage(pageId) end }, | |
{ text = "Delete", notCheckable = true, func = function(frame, pageId) AngryAssign_DeletePage(pageId) end }, | |
{ text = "Category", notCheckable = true, hasArrow = true }, | |
} | |
end | |
local permission = AngryAssign:PermissionCheck() | |
PagesDropDownList[1].text = page.Name | |
PagesDropDownList[2].arg1 = pageId | |
PagesDropDownList[2].disabled = not permission | |
PagesDropDownList[3].arg1 = pageId | |
PagesDropDownList[3].disabled = not permission | |
local categories = AngryAssign_CategoryMenuList(pageId) | |
if categories ~= nil then | |
PagesDropDownList[4].menuList = categories | |
PagesDropDownList[4].disabled = false | |
else | |
PagesDropDownList[4].menuList = {} | |
PagesDropDownList[4].disabled = true | |
end | |
return PagesDropDownList | |
end | |
local CategoriesDropDownList | |
local function AngryAssign_CategoryMenu(catId) | |
local cat = AngryAssign_Categories[catId] | |
if not cat then return end | |
if not CategoriesDropDownList then | |
CategoriesDropDownList = { | |
{ notCheckable = true, isTitle = true }, | |
{ text = "Rename", notCheckable = true, func = function(frame, pageId) AngryAssign_RenameCategory(pageId) end }, | |
{ text = "Delete", notCheckable = true, func = function(frame, pageId) AngryAssign_DeleteCategory(pageId) end }, | |
{ text = "Category", notCheckable = true, hasArrow = true }, | |
} | |
end | |
CategoriesDropDownList[1].text = cat.Name | |
CategoriesDropDownList[2].arg1 = catId | |
CategoriesDropDownList[3].arg1 = catId | |
local categories = AngryAssign_CategoryMenuList(-catId) | |
if categories ~= nil then | |
CategoriesDropDownList[4].menuList = categories | |
CategoriesDropDownList[4].disabled = false | |
else | |
CategoriesDropDownList[4].menuList = {} | |
CategoriesDropDownList[4].disabled = true | |
end | |
return CategoriesDropDownList | |
end | |
local AngryAssign_DropDown | |
local function AngryAssign_TreeClick(widget, event, value, selected, button) | |
HideDropDownMenu(1) | |
local selectedId = selectedLastValue(value) | |
if selectedId < 0 then | |
if button == "RightButton" then | |
if not AngryAssign_DropDown then | |
AngryAssign_DropDown = CreateFrame("Frame", "AngryAssignMenuFrame", UIParent, "UIDropDownMenuTemplate") | |
end | |
EasyMenu(AngryAssign_CategoryMenu(-selectedId), AngryAssign_DropDown, "cursor", 0 , 0, "MENU") | |
else | |
local status = (widget.status or widget.localstatus).groups | |
status[value] = not status[value] | |
widget:RefreshTree() | |
end | |
return false | |
else | |
if button == "RightButton" then | |
if not AngryAssign_DropDown then | |
AngryAssign_DropDown = CreateFrame("Frame", "AngryAssignMenuFrame", UIParent, "UIDropDownMenuTemplate") | |
end | |
EasyMenu(AngryAssign_PageMenu(selectedId), AngryAssign_DropDown, "cursor", 0 , 0, "MENU") | |
return false | |
end | |
end | |
end | |
function AngryAssign:CreateWindow() | |
local window = AceGUI:Create("Frame") | |
window:SetTitle("Angry Assignments") | |
window:SetStatusText("") | |
window:SetLayout("Flow") | |
if AngryAssign:GetConfig('scale') then window.frame:SetScale( AngryAssign:GetConfig('scale') ) end | |
window:SetStatusTable(AngryAssign_State.window) | |
window:Hide() | |
AngryAssign.window = window | |
AngryAssign_Window = window.frame | |
window.frame:SetMinResize(700, 400) | |
window.frame:SetFrameStrata("HIGH") | |
window.frame:SetFrameLevel(1) | |
window.frame:SetClampedToScreen(true) | |
tinsert(UISpecialFrames, "AngryAssign_Window") | |
local tree = AceGUI:Create("AngryTreeGroup") | |
tree:SetTree( self:GetTree() ) | |
tree:SelectByValue(1) | |
tree:SetStatusTable(AngryAssign_State.tree) | |
tree:SetFullWidth(true) | |
tree:SetFullHeight(true) | |
tree:SetLayout("Flow") | |
tree:SetCallback("OnGroupSelected", function(widget, event, value) AngryAssign:UpdateSelected(true) end) | |
tree:SetCallback("OnClick", AngryAssign_TreeClick) | |
window:AddChild(tree) | |
window.tree = tree | |
local text = AceGUI:Create("MultiLineEditBox") | |
text:SetLabel(nil) | |
text:SetFullWidth(true) | |
text:SetFullHeight(true) | |
text:SetCallback("OnTextChanged", AngryAssign_TextChanged) | |
text:SetCallback("OnEnterPressed", AngryAssign_TextEntered) | |
tree:AddChild(text) | |
window.text = text | |
text.button:SetWidth(75) | |
local buttontext = text.button:GetFontString() | |
buttontext:ClearAllPoints() | |
buttontext:SetPoint("TOPLEFT", text.button, "TOPLEFT", 15, -1) | |
buttontext:SetPoint("BOTTOMRIGHT", text.button, "BOTTOMRIGHT", -15, 1) | |
tree:PauseLayout() | |
local button_display = AceGUI:Create("Button") | |
button_display:SetText("Send and Display") | |
button_display:SetWidth(140) | |
button_display:SetHeight(22) | |
button_display:ClearAllPoints() | |
button_display:SetPoint("BOTTOMRIGHT", text.frame, "BOTTOMRIGHT", 0, 4) | |
button_display:SetCallback("OnClick", AngryAssign_DisplayPage) | |
tree:AddChild(button_display) | |
window.button_display = button_display | |
local button_revert = AceGUI:Create("Button") | |
button_revert:SetText("Revert") | |
button_revert:SetWidth(80) | |
button_revert:SetHeight(22) | |
button_revert:ClearAllPoints() | |
button_revert:SetDisabled(true) | |
button_revert:SetPoint("BOTTOMLEFT", text.button, "BOTTOMRIGHT", 6, 0) | |
button_revert:SetCallback("OnClick", AngryAssign_RevertPage) | |
tree:AddChild(button_revert) | |
window.button_revert = button_revert | |
local button_restore = AceGUI:Create("Button") | |
button_restore:SetText("Restore") | |
button_restore:SetWidth(80) | |
button_restore:SetHeight(22) | |
button_restore:ClearAllPoints() | |
button_restore:SetPoint("LEFT", button_revert.frame, "RIGHT", 6, 0) | |
button_restore:SetCallback("OnClick", AngryAssign_RestorePage) | |
tree:AddChild(button_restore) | |
window.button_restore = button_restore | |
local button_output = AceGUI:Create("Button") | |
button_output:SetText("Output") | |
button_output:SetWidth(80) | |
button_output:SetHeight(22) | |
button_output:ClearAllPoints() | |
button_output:SetPoint("BOTTOMLEFT", button_restore.frame, "BOTTOMRIGHT", 6, 0) | |
button_output:SetCallback("OnClick", AngryAssign_OutputDisplayed) | |
tree:AddChild(button_output) | |
window.button_output = button_output | |
window:PauseLayout() | |
local button_add = AceGUI:Create("Button") | |
button_add:SetText("Add") | |
button_add:SetWidth(80) | |
button_add:SetHeight(19) | |
button_add:ClearAllPoints() | |
button_add:SetPoint("BOTTOMLEFT", window.frame, "BOTTOMLEFT", 17, 18) | |
button_add:SetCallback("OnClick", AngryAssign_AddPage) | |
window:AddChild(button_add) | |
window.button_add = button_add | |
local button_rename = AceGUI:Create("Button") | |
button_rename:SetText("Rename") | |
button_rename:SetWidth(80) | |
button_rename:SetHeight(19) | |
button_rename:ClearAllPoints() | |
button_rename:SetPoint("BOTTOMLEFT", button_add.frame, "BOTTOMRIGHT", 5, 0) | |
button_rename:SetCallback("OnClick", function() AngryAssign_RenamePage() end) | |
window:AddChild(button_rename) | |
window.button_rename = button_rename | |
local button_delete = AceGUI:Create("Button") | |
button_delete:SetText("Delete") | |
button_delete:SetWidth(80) | |
button_delete:SetHeight(19) | |
button_delete:ClearAllPoints() | |
button_delete:SetPoint("BOTTOMLEFT", button_rename.frame, "BOTTOMRIGHT", 5, 0) | |
button_delete:SetCallback("OnClick", function() AngryAssign_DeletePage() end) | |
window:AddChild(button_delete) | |
window.button_delete = button_delete | |
local button_add_cat = AceGUI:Create("Button") | |
button_add_cat:SetText("Add Category") | |
button_add_cat:SetWidth(120) | |
button_add_cat:SetHeight(19) | |
button_add_cat:ClearAllPoints() | |
button_add_cat:SetPoint("BOTTOMLEFT", button_delete.frame, "BOTTOMRIGHT", 5, 0) | |
button_add_cat:SetCallback("OnClick", function() AngryAssign_AddCategory() end) | |
window:AddChild(button_add_cat) | |
window.button_add_cat = button_add_cat | |
local button_clear = AceGUI:Create("Button") | |
button_clear:SetText("Clear") | |
button_clear:SetWidth(80) | |
button_clear:SetHeight(19) | |
button_clear:ClearAllPoints() | |
button_clear:SetPoint("BOTTOMRIGHT", window.frame, "BOTTOMRIGHT", -135, 18) | |
button_clear:SetCallback("OnClick", AngryAssign_ClearPage) | |
window:AddChild(button_clear) | |
window.button_clear = button_clear | |
self:UpdateSelected(true) | |
self:UpdateMedia() | |
--self:CreateIconPicker() | |
end | |
local function AngryAssign_IconPicker_Clicked(widget, event) | |
local texture | |
if widget:GetUserData('name') then | |
icon = widget:GetUserData('name') | |
else | |
icon = '{icon '..strmatch(widget.image:GetTexture():lower(), "^interface\\icons\\([-_%w]+)$")..'}' | |
end | |
local position = AngryAssign.window.text.editBox:GetCursorPosition() | |
if position > 0 then | |
local text = AngryAssign.window.text:GetText() | |
AngryAssign.window.text:SetText( strsub(text, 1, position)..icon..strsub(text, position+1, AngryAssign.window.text.editBox:GetNumLetters()) ) | |
AngryAssign.window.text.editBox:SetCursorPosition( position, string.len(text) ) | |
else | |
AngryAssign.window.text:SetText( AngryAssign.window.text:GetText()..icon) | |
end | |
AngryAssign.window.text.button:Enable() | |
AngryAssign_TextChanged() | |
end | |
local iconCache = nil | |
local function AngryAssign_IconPicker_TextChanged(widget, event, value) | |
AngryAssign.iconpicker_scroll:ReleaseChildren() | |
local names = {} | |
local spellID = strmatch(value, '|Hspell:(%d+)|') | |
local itemID = strmatch(value, '|Hitem:(%d+):') | |
if spellID then | |
local path = select(3, GetSpellInfo(tonumber(spellID))) | |
tinsert(names, path) | |
elseif itemID then | |
local path = select(10, GetItemInfo(tonumber(itemID))) | |
tinsert(names, path) | |
elseif value ~= "" then | |
if not iconCache then iconCache = GetMacroIcons() end | |
local iconsFound = 0 | |
local subname = value:lower() | |
for _, path in ipairs(iconCache) do | |
if path:lower():find(subname) then | |
tinsert(names, "Interface\\Icons\\"..path) | |
iconsFound = iconsFound + 1 | |
end | |
if iconsFound >= 60 then | |
break | |
end | |
end | |
end | |
for _, path in ipairs(names) do | |
if path then | |
local icon = AceGUI:Create("Icon") | |
icon:SetImage(path) | |
icon:SetImageSize(32, 32) | |
icon:SetWidth(36) | |
icon:SetHeight(36) | |
icon:SetCallback('OnClick', AngryAssign_IconPicker_Clicked) | |
AngryAssign.iconpicker_scroll:AddChild(icon) | |
end | |
end | |
end | |
function AngryAssign:CreateIconButton(name, texture) | |
local icon = AceGUI:Create("Icon") | |
icon:SetImage(texture) | |
icon:SetImageSize(20, 20) | |
icon:SetWidth(21) | |
icon:SetHeight(24) | |
icon:SetUserData('name', name) | |
icon:SetCallback('OnClick', AngryAssign_IconPicker_Clicked) | |
return icon | |
end | |
function AngryAssign:CreateIconPicker() | |
local window = AceGUI:Create("Window") | |
window:SetTitle("Insert an Icon") | |
window:SetLayout("List") | |
window:SetWidth(240) | |
window:SetHeight(320) | |
window.frame:SetParent(self.window.frame) | |
window.frame:ClearAllPoints() | |
window.frame:SetPoint("TOPLEFT", self.window.frame, "TOPRIGHT", 4, -4) | |
window.frame:SetMovable(false) | |
window.title:SetScript("OnMouseDown", nil) | |
window.title:SetScript("OnMouseUp", nil) | |
window:EnableResize(false) | |
self.iconpicker = window | |
local group = AceGUI:Create("SimpleGroup") | |
group:SetLayout("Flow") | |
group:SetFullWidth(true) | |
for i = 8, 1, -1 do | |
group:AddChild( self:CreateIconButton("{rt"..i.."}", "Interface\\TargetingFrame\\UI-RaidTargetingIcon_"..i) ) | |
end | |
group:AddChild( self:CreateIconButton("{bl}", "Interface\\Icons\\SPELL_Nature_Bloodlust") ) | |
group:AddChild( self:CreateIconButton("{hs}", "Interface\\Icons\\INV_Stone_04") ) | |
window:AddChild(group) | |
local heading = AceGUI:Create("Heading") | |
heading:SetFullWidth(true) | |
window:AddChild(heading) | |
local text = AceGUI:Create("EditBox") | |
text:SetFullWidth(true) | |
text:DisableButton(true) | |
text:SetCallback("OnTextChanged", AngryAssign_IconPicker_TextChanged) | |
window:AddChild(text) | |
local scroll = AceGUI:Create("ScrollFrame") | |
scroll:SetLayout("Flow") | |
scroll:SetFullWidth(true) | |
scroll:SetFullHeight(true) | |
window:AddChild(scroll) | |
self.iconpicker_scroll = scroll | |
end | |
function AngryAssign:SelectedUpdated(sender) | |
if self.window and self.window.text.button:IsEnabled() then | |
local popup_name = "AngryAssign_PageUpdated" | |
if StaticPopupDialogs[popup_name] == nil then | |
StaticPopupDialogs[popup_name] = { | |
button1 = OKAY, | |
whileDead = true, | |
text = "", | |
hideOnEscape = true, | |
preferredIndex = 3 | |
} | |
end | |
StaticPopupDialogs[popup_name].text = "The page you are editing has been updated by "..sender..".\n\nYou can view this update by reverting your changes." | |
StaticPopup_Show(popup_name) | |
return true | |
else | |
return false | |
end | |
end | |
local function GetTree_InsertPage(tree, page) | |
if page.Id == AngryAssign_State.displayed then | |
table.insert(tree, { value = page.Id, text = page.Name, icon = "Interface\\BUTTONS\\UI-GuildButton-MOTD-Up" }) | |
else | |
table.insert(tree, { value = page.Id, text = page.Name }) | |
end | |
end | |
local function GetTree_InsertChildren(categoryId, displayedPages) | |
local tree = {} | |
for _, cat in pairs(AngryAssign_Categories) do | |
if cat.CategoryId == categoryId then | |
table.insert(tree, { value = -cat.Id, text = cat.Name, children = GetTree_InsertChildren(cat.Id, displayedPages) }) | |
end | |
end | |
for _, page in pairs(AngryAssign_Pages) do | |
if page.CategoryId == categoryId then | |
displayedPages[page.Id] = true | |
GetTree_InsertPage(tree, page) | |
end | |
end | |
table.sort(tree, function(a,b) return a.text < b.text end) | |
return tree | |
end | |
function AngryAssign:GetTree() | |
local tree = {} | |
local displayedPages = {} | |
for _, cat in pairs(AngryAssign_Categories) do | |
if not cat.CategoryId then | |
table.insert(tree, { value = -cat.Id, text = cat.Name, children = GetTree_InsertChildren(cat.Id, displayedPages) }) | |
end | |
end | |
for _, page in pairs(AngryAssign_Pages) do | |
if not page.CategoryId or not displayedPages[page.Id] then | |
GetTree_InsertPage(tree, page) | |
end | |
end | |
table.sort(tree, function(a,b) return a.text < b.text end) | |
return tree | |
end | |
function AngryAssign:UpdateTree(id) | |
if not self.window then return end | |
self.window.tree:SetTree( self:GetTree() ) | |
if id then | |
self:SetSelectedId( id ) | |
end | |
end | |
function AngryAssign:UpdateSelected(destructive) | |
if not self.window then return end | |
local page = AngryAssign_Pages[ self:SelectedId() ] | |
local permission = self:PermissionCheck() | |
if destructive or not self.window.text.button:IsEnabled() then | |
if page then | |
self.window.text:SetText( page.Contents ) | |
else | |
self.window.text:SetText("") | |
end | |
self.window.text.button:Disable() | |
end | |
if page and permission then | |
self.window.button_rename:SetDisabled(false) | |
self.window.button_revert:SetDisabled(not self.window.text.button:IsEnabled()) | |
self.window.button_display:SetDisabled(self.window.text.button:IsEnabled()) | |
self.window.button_output:SetDisabled(self.window.text.button:IsEnabled()) | |
self.window.button_restore:SetDisabled(not self.window.text.button:IsEnabled() and page.Backup == page.Contents) | |
self.window.text:SetDisabled(false) | |
else | |
self.window.button_rename:SetDisabled(true) | |
self.window.button_revert:SetDisabled(true) | |
self.window.button_display:SetDisabled(true) | |
self.window.button_output:SetDisabled(true) | |
self.window.button_restore:SetDisabled(true) | |
self.window.text:SetDisabled(true) | |
end | |
if page then | |
self.window.button_delete:SetDisabled(false) | |
else | |
self.window.button_delete:SetDisabled(true) | |
end | |
if permission then | |
self.window.button_add:SetDisabled(false) | |
self.window.button_clear:SetDisabled(false) | |
else | |
self.window.button_add:SetDisabled(true) | |
self.window.button_clear:SetDisabled(true) | |
end | |
end | |
---------------------------------- | |
-- Performing changes functions -- | |
---------------------------------- | |
function AngryAssign:SelectedId() | |
return selectedLastValue( AngryAssign_State.tree.selected ) | |
end | |
function AngryAssign:SetSelectedId(selectedId) | |
local page = AngryAssign_Pages[selectedId] | |
if page then | |
if page.CategoryId then | |
local cat = AngryAssign_Categories[page.CategoryId] | |
local path = { } | |
while cat do | |
table.insert(path, -cat.Id) | |
if cat.CategoryId then | |
cat = AngryAssign_Categories[cat.CategoryId] | |
else | |
cat = nil | |
end | |
end | |
tReverse(path) | |
table.insert(path, page.Id) | |
self.window.tree:SelectByPath(unpack(path)) | |
else | |
self.window.tree:SelectByValue(page.Id) | |
end | |
else | |
self.window.tree:SetSelected() | |
end | |
end | |
function AngryAssign:Get(id) | |
if id == nil then id = self:SelectedId() end | |
return AngryAssign_Pages[id] | |
end | |
function AngryAssign:GetCat(id) | |
return AngryAssign_Categories[id] | |
end | |
function AngryAssign:Hash(name, contents) | |
local code = libC:fcs32init() | |
code = libC:fcs32update(code, name) | |
code = libC:fcs32update(code, "\n") | |
code = libC:fcs32update(code, contents) | |
return libC:fcs32final(code) | |
end | |
function AngryAssign:CreatePage(name) | |
if not self:PermissionCheck() then return end | |
local id = self:Hash("page", math.random(2000000000)) | |
AngryAssign_Pages[id] = { Id = id, Updated = time(), UpdateId = self:Hash(name, ""), Name = name, Contents = "" } | |
self:UpdateTree(id) | |
self:SendPage(id, true) | |
end | |
function AngryAssign:RenamePage(id, name) | |
local page = self:Get(id) | |
if not page or not self:PermissionCheck() then return end | |
page.Name = name | |
page.Updated = time() | |
page.UpdateId = self:Hash(page.Name, page.Contents) | |
self:SendPage(id, true) | |
self:UpdateTree() | |
if AngryAssign_State.displayed == id then | |
self:UpdateDisplayed() | |
self:ShowDisplay() | |
end | |
end | |
function AngryAssign:DeletePage(id) | |
AngryAssign_Pages[id] = nil | |
if self.window and self:SelectedId() == id then | |
self:SetSelectedId(nil) | |
self:UpdateSelected(true) | |
end | |
if AngryAssign_State.displayed == id then | |
self:ClearDisplayed() | |
end | |
self:UpdateTree() | |
end | |
function AngryAssign:TouchPage(id) | |
if not self:PermissionCheck() then return end | |
local page = self:Get(id) | |
if not page then return end | |
page.Updated = time() | |
end | |
function AngryAssign:CreateCategory(name) | |
local id = self:Hash("cat", math.random(2000000000)) | |
AngryAssign_Categories[id] = { Id = id, Name = name } | |
if AngryAssign_State.tree.groups then | |
AngryAssign_State.tree.groups[ -id ] = true | |
end | |
self:UpdateTree() | |
end | |
function AngryAssign:RenameCategory(id, name) | |
local cat = self:GetCat(id) | |
if not cat then return end | |
cat.Name = name | |
self:UpdateTree() | |
end | |
function AngryAssign:DeleteCategory(id) | |
local cat = self:GetCat(id) | |
if not cat then return end | |
local selectedId = self:SelectedId() | |
for _, c in pairs(AngryAssign_Categories) do | |
if cat.Id == c.CategoryId then | |
c.CategoryId = cat.CategoryId | |
end | |
end | |
for _, p in pairs(AngryAssign_Pages) do | |
if cat.Id == p.CategoryId then | |
p.CategoryId = cat.CategoryId | |
end | |
end | |
AngryAssign_Categories[id] = nil | |
self:UpdateTree() | |
self:SetSelectedId(selectedId) | |
end | |
function AngryAssign:AssignCategory(entryId, parentId) | |
local page, cat | |
if entryId > 0 then | |
page = self:Get(entryId) | |
else | |
cat = self:GetCat(-entryId) | |
end | |
local parent = self:GetCat(parentId) | |
if not (page or cat) or not parent then return end | |
if page then | |
if page.CategoryId == parentId then | |
page.CategoryId = nil | |
else | |
page.CategoryId = parentId | |
end | |
end | |
if cat then | |
if cat.CategoryId == parentId then | |
cat.CategoryId = nil | |
else | |
cat.CategoryId = parentId | |
end | |
end | |
local selectedId = self:SelectedId() | |
self:UpdateTree() | |
if selectedId == entryId then | |
self:SetSelectedId( selectedId ) | |
end | |
end | |
function AngryAssign:UpdateContents(id, value) | |
if not self:PermissionCheck() then return end | |
local page = self:Get(id) | |
if not page then return end | |
local new_content = value:gsub('^%s+', ''):gsub('%s+$', '') | |
local contents_updated = new_content ~= page.Contents | |
page.Contents = new_content | |
page.Backup = new_content | |
page.Updated = time() | |
page.UpdateId = self:Hash(page.Name, page.Contents) | |
self:SendPage(id, true) | |
self:UpdateSelected(true) | |
if AngryAssign_State.displayed == id then | |
self:UpdateDisplayed() | |
self:ShowDisplay() | |
if contents_updated then self:DisplayUpdateNotification() end | |
end | |
end | |
function AngryAssign:CreateBackup() | |
for _, page in pairs(AngryAssign_Pages) do | |
page.Backup = page.Contents | |
end | |
self:UpdateSelected() | |
end | |
function AngryAssign:ClearDisplayed() | |
AngryAssign_State.displayed = nil | |
self:UpdateDisplayed() | |
self:UpdateTree() | |
end | |
function AngryAssign:IsGuildOfficer(player) | |
if not player then return false end | |
local fullplayer = EnsureUnitFullName(player) | |
if guildOfficerNames == nil then | |
self:UpdateOfficerRank() | |
end | |
return guildOfficerNames[fullplayer] | |
end | |
function AngryAssign:ResetOfficerRank() | |
guildOfficerNames = nil | |
end | |
function AngryAssign:UpdateOfficerRank() | |
guildOfficerNames = {} | |
if C_Club and C_Club.GetGuildClubId then | |
local clubId, streamId = C_Club.GetGuildClubId(), nil | |
local memberIds = CommunitiesUtil.GetMemberIdsSortedByName(clubId, streamId) | |
local allMemberList = CommunitiesUtil.GetMemberInfo(clubId, memberIds) | |
for _, memberInfo in ipairs(allMemberList) do | |
if memberInfo.name and (memberInfo.role == Enum.ClubRoleIdentifier.Owner or memberInfo.role == Enum.ClubRoleIdentifier.Leader or memberInfo.role == Enum.ClubRoleIdentifier.Moderator) then | |
guildOfficerNames[EnsureUnitFullName(memberInfo.name)] = true | |
end | |
end | |
end | |
return guildOfficerNames | |
end | |
function AngryAssign:IsPlayerRaidLeader() | |
local leader = self:GetRaidLeader() | |
return leader and PlayerFullName() == EnsureUnitFullName(leader) | |
end | |
function AngryAssign:IsGuildRaid() | |
local leader = self:GetRaidLeader() | |
if self:IsGuildOfficer(leader) then | |
return true | |
end | |
return false | |
end | |
function AngryAssign:IsValidRaid() | |
if self:GetConfig('allowall') then | |
return true | |
end | |
local leader = self:GetRaidLeader() | |
if self:IsGuildOfficer(leader) then | |
return true | |
end | |
for token in string.gmatch( AngryAssign:GetConfig('allowplayers') , "[^%s!#$%%&()*+,./:;<=>?@\\^_{|}~%[%]]+") do | |
if leader and EnsureUnitFullName(token):lower() == EnsureUnitFullName(leader):lower() then | |
return true | |
end | |
end | |
if self:IsPlayerRaidLeader() then | |
return true | |
end | |
return false | |
end | |
function AngryAssign:PermissionCheck(sender) | |
if not sender then sender = PlayerFullName() end | |
if (IsInRaid() or IsInGroup()) then | |
return (UnitIsGroupLeader(EnsureUnitShortName(sender)) == true or UnitIsGroupAssistant(EnsureUnitShortName(sender)) == true) and self:IsValidRaid() | |
else | |
return sender == PlayerFullName() | |
end | |
end | |
function AngryAssign:PermissionsUpdated() | |
self:UpdateSelected() | |
if comStarted then | |
self:SendRequestDisplay() | |
end | |
if (IsInRaid() or IsInGroup()) and not self:IsValidRaid() then | |
self:ClearDisplayed() | |
end | |
end | |
--------------------- | |
-- Displaying Page -- | |
--------------------- | |
local function DragHandle_MouseDown(frame) frame:GetParent():GetParent():StartSizing("RIGHT") end | |
local function DragHandle_MouseUp(frame) | |
local display = frame:GetParent():GetParent() | |
display:StopMovingOrSizing() | |
AngryAssign_State.display.width = display:GetWidth() | |
lwin.SavePosition(display) | |
AngryAssign:UpdateBackdrop() | |
end | |
local function Mover_MouseDown(frame) frame:GetParent():StartMoving() end | |
local function Mover_MouseUp(frame) | |
local display = frame:GetParent() | |
display:StopMovingOrSizing() | |
lwin.SavePosition(display) | |
end | |
function AngryAssign:ResetPosition() | |
AngryAssign_State.display = {} | |
AngryAssign_State.directionUp = false | |
AngryAssign_State.locked = false | |
self.display_text:Show() | |
self.mover:Show() | |
self.frame:SetWidth(300) | |
lwin.RegisterConfig(self.frame, AngryAssign_State.display) | |
lwin.RestorePosition(self.frame) | |
self:UpdateDirection() | |
end | |
function AngryAssign_ToggleDisplay() | |
AngryAssign:ToggleDisplay() | |
end | |
function AngryAssign_ShowDisplay() | |
AngryAssign:ShowDisplay() | |
end | |
function AngryAssign_HideDisplay() | |
AngryAssign:HideDisplay() | |
end | |
function AngryAssign:ShowDisplay() | |
self.display_text:Show() | |
self:UpdateBackdrop() | |
AngryAssign_State.display.hidden = false | |
end | |
function AngryAssign:HideDisplay() | |
self.display_text:Hide() | |
AngryAssign_State.display.hidden = true | |
end | |
function AngryAssign:ToggleDisplay() | |
if self.display_text:IsShown() then | |
self:HideDisplay() | |
else | |
self:ShowDisplay() | |
end | |
end | |
function AngryAssign:CreateDisplay() | |
local frame = CreateFrame("Frame", nil, UIParent) | |
frame:SetPoint("CENTER",0,0) | |
frame:SetWidth(AngryAssign_State.display.width or 300) | |
frame:SetHeight(1) | |
frame:SetMovable(true) | |
frame:SetResizable(true) | |
frame:SetClampedToScreen(true) | |
frame:SetMinResize(180,1) | |
frame:SetMaxResize(830,1) | |
frame:SetFrameStrata("MEDIUM") | |
self.frame = frame | |
lwin.RegisterConfig(frame, AngryAssign_State.display) | |
lwin.RestorePosition(frame) | |
local text = CreateFrame("ScrollingMessageFrame", nil, frame) | |
text:SetIndentedWordWrap(true) | |
text:SetJustifyH("LEFT") | |
text:SetFading(false) | |
text:SetMaxLines(70) | |
text:SetHeight(700) | |
text:SetHyperlinksEnabled(false) | |
self.display_text = text | |
local backdrop = text:CreateTexture() | |
backdrop:SetDrawLayer("BACKGROUND") | |
self.backdrop = backdrop | |
local mover = CreateFrame("Frame", nil, frame) | |
mover:SetPoint("LEFT",0,0) | |
mover:SetPoint("RIGHT",0,0) | |
mover:SetHeight(16) | |
mover:EnableMouse(true) | |
mover:SetBackdrop({ bgFile = "Interface\\Tooltips\\UI-Tooltip-Background" }) | |
mover:SetBackdropColor( 0.616, 0.149, 0.114, 0.9) | |
mover:SetScript("OnMouseDown", Mover_MouseDown) | |
mover:SetScript("OnMouseUp", Mover_MouseUp) | |
self.mover = mover | |
if AngryAssign_State.locked then mover:Hide() end | |
local label = mover:CreateFontString() | |
label:SetFontObject("GameFontNormal") | |
label:SetJustifyH("CENTER") | |
label:SetPoint("LEFT", 38, 0) | |
label:SetPoint("RIGHT", -38, 0) | |
label:SetText("Angry Assignments") | |
local direction = CreateFrame("Button", nil, mover) | |
direction:SetPoint("LEFT", 2, 0) | |
direction:SetWidth(16) | |
direction:SetHeight(16) | |
direction:SetNormalTexture("Interface\\Buttons\\UI-Panel-QuestHideButton") | |
direction:SetPushedTexture("Interface\\Buttons\\UI-Panel-QuestHideButton") | |
direction:SetHighlightTexture("Interface\\Buttons\\UI-Panel-MinimizeButton-Highlight", "ADD") | |
direction:SetScript("OnClick", function() AngryAssign:ToggleDirection() end) | |
self.direction_button = direction | |
local lock = CreateFrame("Button", nil, mover) | |
lock:SetNormalTexture("Interface\\LFGFRAME\\UI-LFG-ICON-LOCK") | |
lock:GetNormalTexture():SetTexCoord(0, 0.71875, 0, 0.875) | |
lock:SetPoint("LEFT", direction, "RIGHT", 4, 0) | |
lock:SetWidth(12) | |
lock:SetHeight(14) | |
lock:SetScript("OnClick", function() AngryAssign:ToggleLock() end) | |
local drag = CreateFrame("Frame", nil, mover) | |
drag:SetFrameLevel(mover:GetFrameLevel() + 10) | |
drag:SetWidth(16) | |
drag:SetHeight(16) | |
drag:SetPoint("BOTTOMRIGHT", 0, 0) | |
drag:EnableMouse(true) | |
drag:SetScript("OnMouseDown", DragHandle_MouseDown) | |
drag:SetScript("OnMouseUp", DragHandle_MouseUp) | |
drag:SetAlpha(0.5) | |
local dragtex = drag:CreateTexture(nil, "OVERLAY") | |
dragtex:SetTexture("Interface\\AddOns\\AngryAssignments\\Textures\\draghandle") | |
dragtex:SetWidth(16) | |
dragtex:SetHeight(16) | |
dragtex:SetBlendMode("ADD") | |
dragtex:SetPoint("CENTER", drag) | |
local glow = text:CreateTexture() | |
glow:SetDrawLayer("BORDER") | |
glow:SetTexture("Interface\\AddOns\\AngryAssignments\\Textures\\LevelUpTex") | |
glow:SetSize(223, 115) | |
glow:SetTexCoord(0.56054688, 0.99609375, 0.24218750, 0.46679688) | |
glow:SetVertexColor( HexToRGB(self:GetConfig('glowColor')) ) | |
glow:SetAlpha(0) | |
self.display_glow = glow | |
local glow2 = text:CreateTexture() | |
glow2:SetDrawLayer("BORDER") | |
glow2:SetTexture("Interface\\AddOns\\AngryAssignments\\Textures\\LevelUpTex") | |
glow2:SetSize(418, 7) | |
glow2:SetTexCoord(0.00195313, 0.81835938, 0.01953125, 0.03320313) | |
glow2:SetVertexColor( HexToRGB(self:GetConfig('glowColor')) ) | |
glow2:SetAlpha(0) | |
self.display_glow2 = glow2 | |
if AngryAssign_State.display.hidden then text:Hide() end | |
self:UpdateMedia() | |
self:UpdateDirection() | |
end | |
function AngryAssign:ToggleLock() | |
AngryAssign_State.locked = not AngryAssign_State.locked | |
if AngryAssign_State.locked then | |
self.mover:Hide() | |
else | |
self.mover:Show() | |
end | |
end | |
function AngryAssign:ToggleDirection() | |
AngryAssign_State.directionUp = not AngryAssign_State.directionUp | |
self:UpdateDirection() | |
end | |
function AngryAssign:UpdateDirection() | |
if AngryAssign_State.directionUp then | |
self.display_text:ClearAllPoints() | |
self.display_text:SetPoint("BOTTOMLEFT", 0, 8) | |
self.display_text:SetPoint("RIGHT", 0, 0) | |
self.display_text:SetInsertMode(SCROLLING_MESSAGE_FRAME_INSERT_MODE_BOTTOM) | |
self.direction_button:GetNormalTexture():SetTexCoord(0, 0.5, 0.5, 1) | |
self.direction_button:GetPushedTexture():SetTexCoord(0.5, 1, 0.5, 1) | |
self.display_glow:ClearAllPoints() | |
self.display_glow:SetPoint("BOTTOM", 0, -4) | |
self.display_glow:SetTexCoord(0.56054688, 0.99609375, 0.24218750, 0.46679688) | |
self.display_glow2:ClearAllPoints() | |
self.display_glow2:SetPoint("TOP", self.display_glow, "BOTTOM", 0, 6) | |
else | |
self.display_text:ClearAllPoints() | |
self.display_text:SetPoint("TOPLEFT", 0, -8) | |
self.display_text:SetPoint("RIGHT", 0, 0) | |
self.display_text:SetInsertMode(SCROLLING_MESSAGE_FRAME_INSERT_MODE_TOP) | |
self.direction_button:GetNormalTexture():SetTexCoord(0, 0.5, 0, 0.5) | |
self.direction_button:GetPushedTexture():SetTexCoord(0.5, 1, 0, 0.5) | |
self.display_glow:ClearAllPoints() | |
self.display_glow:SetPoint("TOP", 0, 4) | |
self.display_glow:SetTexCoord(0.56054688, 0.99609375, 0.46679688, 0.24218750) | |
self.display_glow2:ClearAllPoints() | |
self.display_glow2:SetPoint("BOTTOM", self.display_glow, "TOP", 0, 0) | |
end | |
if self.display_text:IsShown() then | |
self.display_text:Hide() | |
self.display_text:Show() | |
end | |
self:UpdateDisplayed() | |
end | |
function AngryAssign:UpdateBackdrop() | |
local first, last | |
for lineIndex, visibleLine in ipairs(self.display_text.visibleLines) do | |
local messageInfo = self.display_text.historyBuffer:GetEntryAtIndex(lineIndex) | |
if messageInfo then | |
if not first then first = visibleLine end | |
last = visibleLine | |
end | |
end | |
if first and last and self:GetConfig('backdropShow') then | |
self.backdrop:ClearAllPoints() | |
if AngryAssign_State.directionUp then | |
self.backdrop:SetPoint("TOPLEFT", last, "TOPLEFT", -4, 4) | |
self.backdrop:SetPoint("BOTTOMRIGHT", first, "BOTTOMRIGHT", 4, -4) | |
else | |
self.backdrop:SetPoint("TOPLEFT", first, "TOPLEFT", -4, 4) | |
self.backdrop:SetPoint("BOTTOMRIGHT", last, "BOTTOMRIGHT", 4, -4) | |
end | |
self.backdrop:SetColorTexture( HexToRGB(self:GetConfig('backdropColor')) ) | |
self.backdrop:Show() | |
else | |
self.backdrop:Hide() | |
end | |
end | |
local editFontName, editFontHeight, editFontFlags | |
function AngryAssign:UpdateMedia() | |
local fontName = LSM:Fetch("font", AngryAssign:GetConfig('fontName')) | |
local fontHeight = AngryAssign:GetConfig('fontHeight') | |
local fontFlags = AngryAssign:GetConfig('fontFlags') | |
self.display_text:SetTextColor( HexToRGB(self:GetConfig('color')) ) | |
self.display_text:SetFont(fontName, fontHeight, fontFlags) | |
self.display_text:SetSpacing( AngryAssign:GetConfig('lineSpacing') ) | |
if self.window then | |
if self:GetConfig('editBoxFont') then | |
if not editFontName then | |
editFontName, editFontHeight, editFontFlags = self.window.text.editBox:GetFont() | |
end | |
self.window.text.editBox:SetFont(fontName, fontHeight, fontFlags) | |
elseif editFontName then | |
self.window.text.editBox:SetFont(editFontName, editFontHeight, editFontFlags) | |
end | |
end | |
self:UpdateBackdrop() | |
end | |
local updateFlasher, updateFlasher2 = nil, nil | |
function AngryAssign:DisplayUpdateNotification() | |
if updateFlasher == nil then | |
updateFlasher = self.display_glow:CreateAnimationGroup() | |
-- Flashing in | |
local fade1 = updateFlasher:CreateAnimation("Alpha") | |
fade1:SetDuration(0.5) | |
fade1:SetFromAlpha(0) | |
fade1:SetToAlpha(1) | |
fade1:SetOrder(1) | |
-- Holding it visible for 1 second | |
fade1:SetEndDelay(5) | |
-- Flashing out | |
local fade2 = updateFlasher:CreateAnimation("Alpha") | |
fade2:SetDuration(0.5) | |
fade2:SetFromAlpha(1) | |
fade2:SetToAlpha(0) | |
fade2:SetOrder(3) | |
end | |
if updateFlasher2 == nil then | |
updateFlasher2 = self.display_glow2:CreateAnimationGroup() | |
-- Flashing in | |
local fade1 = updateFlasher2:CreateAnimation("Alpha") | |
fade1:SetDuration(0.5) | |
fade1:SetFromAlpha(0) | |
fade1:SetToAlpha(1) | |
fade1:SetOrder(1) | |
-- Holding it visible for 1 second | |
fade1:SetEndDelay(5) | |
-- Flashing out | |
local fade2 = updateFlasher2:CreateAnimation("Alpha") | |
fade2:SetDuration(0.5) | |
fade2:SetFromAlpha(1) | |
fade2:SetToAlpha(0) | |
fade2:SetOrder(3) | |
end | |
updateFlasher:Play() | |
updateFlasher2:Play() | |
end | |
local function ci_pattern(pattern) | |
local p = pattern:gsub("(%%?)(.)", function(percent, letter) | |
if percent ~= "" or not letter:match("%a") then | |
return percent .. letter | |
else | |
return string.format("[%s%s]", letter:lower(), letter:upper()) | |
end | |
end) | |
return p | |
end | |
function AngryAssign:UpdateDisplayedIfNewGroup() | |
local newGroup = self:GetCurrentGroup() | |
if newGroup ~= currentGroup then | |
currentGroup = newGroup | |
self:UpdateDisplayed() | |
end | |
end | |
function AngryAssign:UpdateDisplayed() | |
local page = AngryAssign_Pages[ AngryAssign_State.displayed ] | |
if page then | |
local text = page.Contents | |
local highlights = { } | |
for token in string.gmatch( AngryAssign:GetConfig('highlight') , "[^%s%p]+") do | |
token = token:lower() | |
if token == 'group'then | |
tinsert(highlights, 'g'..(currentGroup or 0)) | |
else | |
tinsert(highlights, token) | |
end | |
end | |
local highlightHex = self:GetConfig('highlightColor') | |
text = text:gsub("||", "|") | |
:gsub(ci_pattern('|cblue'), "|cff00cbf4") | |
:gsub(ci_pattern('|cgreen'), "|cff0adc00") | |
:gsub(ci_pattern('|cred'), "|cffeb310c") | |
:gsub(ci_pattern('|cyellow'), "|cfffaf318") | |
:gsub(ci_pattern('|corange'), "|cffff9d00") | |
:gsub(ci_pattern('|cpink'), "|cfff64c97") | |
:gsub(ci_pattern('|cpurple'), "|cffdc44eb") | |
:gsub(ci_pattern('|cdeathknight'), "|cffc41f3b") | |
:gsub(ci_pattern('|cdruid'), "|cffff7d0a") | |
:gsub(ci_pattern('|chunter'), "|cffabd473") | |
:gsub(ci_pattern('|cmage'), "|cff40C7eb") | |
:gsub(ci_pattern('|cmonk'), "|cff00ff96") | |
:gsub(ci_pattern('|cpaladin'), "|cfff58cba") | |
:gsub(ci_pattern('|cpriest'), "|cffffffff") | |
:gsub(ci_pattern('|crogue'), "|cfffff569") | |
:gsub(ci_pattern('|cshaman'), "|cff0070de") | |
:gsub(ci_pattern('|cwarlock'), "|cff8787ed") | |
:gsub(ci_pattern('|cwarrior'), "|cffc79c6e") | |
:gsub(ci_pattern('|cdemonhunter'), "|cffa330c9") | |
:gsub("([^%s%p]+)", function(word) | |
local word_lower = word:lower() | |
for _, token in ipairs(highlights) do | |
if token == word_lower then | |
return string.format("|cff%s%s|r", highlightHex, word) | |
end | |
end | |
return word | |
end) | |
:gsub(ci_pattern('{spell%s+(%d+)}'), function(id) | |
return GetSpellLink(id) | |
end) | |
:gsub(ci_pattern('{boss%s+(%d+)}'), function(id) | |
return select(5, EJ_GetEncounterInfo(id)) | |
end) | |
:gsub(ci_pattern('{journal%s+(%d+)}'), function(id) | |
return C_EncounterJournal.GetSectionInfo(id) and C_EncounterJournal.GetSectionInfo(id).link | |
end) | |
:gsub(ci_pattern('{star}'), "{rt1}") | |
:gsub(ci_pattern('{circle}'), "{rt2}") | |
:gsub(ci_pattern('{diamond}'), "{rt3}") | |
:gsub(ci_pattern('{triangle}'), "{rt4}") | |
:gsub(ci_pattern('{moon}'), "{rt5}") | |
:gsub(ci_pattern('{square}'), "{rt6}") | |
:gsub(ci_pattern('{cross}'), "{rt7}") | |
:gsub(ci_pattern('{x}'), "{rt7}") | |
:gsub(ci_pattern('{skull}'), "{rt8}") | |
:gsub(ci_pattern('{rt([1-8])}'), "|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_%1:0|t" ) | |
:gsub(ci_pattern('{healthstone}'), "{hs}") | |
:gsub(ci_pattern('{hs}'), "|TInterface\\Icons\\INV_Stone_04:0|t") | |
:gsub(ci_pattern('{bloodlust}'), "{bl}") | |
:gsub(ci_pattern('{bl}'), "|TInterface\\Icons\\SPELL_Nature_Bloodlust:0|t") | |
:gsub(ci_pattern('{icon%s+(%d+)}'), function(id) | |
return format("|T%s:0|t", select(3, GetSpellInfo(tonumber(id))) ) | |
end) | |
:gsub(ci_pattern('{icon%s+([%w_]+)}'), "|TInterface\\Icons\\%1:0|t") | |
:gsub(ci_pattern('{damage}'), "{dps}") | |
:gsub(ci_pattern('{tank}'), "|TInterface\\LFGFrame\\UI-LFG-ICON-PORTRAITROLES:0:0:0:0:64:64:0:19:22:41|t") | |
:gsub(ci_pattern('{healer}'), "|TInterface\\LFGFrame\\UI-LFG-ICON-PORTRAITROLES:0:0:0:0:64:64:20:39:1:20|t") | |
:gsub(ci_pattern('{dps}'), "|TInterface\\LFGFrame\\UI-LFG-ICON-PORTRAITROLES:0:0:0:0:64:64:20:39:22:41|t") | |
:gsub(ci_pattern('{hero}'), "{heroism}") | |
:gsub(ci_pattern('{heroism}'), "|TInterface\\Icons\\ABILITY_Shaman_Heroism:0|t") | |
:gsub(ci_pattern('{hunter}'), "|TInterface\\GLUES\\CHARACTERCREATE\\UI-CHARACTERCREATE-CLASSES:0:0:0:0:64:64:0:16:16:32|t") | |
:gsub(ci_pattern('{warrior}'), "|TInterface\\GLUES\\CHARACTERCREATE\\UI-CHARACTERCREATE-CLASSES:0:0:0:0:64:64:0:16:0:16|t") | |
:gsub(ci_pattern('{rogue}'), "|TInterface\\GLUES\\CHARACTERCREATE\\UI-CHARACTERCREATE-CLASSES:0:0:0:0:64:64:32:48:0:16|t") | |
:gsub(ci_pattern('{mage}'), "|TInterface\\GLUES\\CHARACTERCREATE\\UI-CHARACTERCREATE-CLASSES:0:0:0:0:64:64:16:32:0:16|t") | |
:gsub(ci_pattern('{priest}'), "|TInterface\\GLUES\\CHARACTERCREATE\\UI-CHARACTERCREATE-CLASSES:0:0:0:0:64:64:32:48:16:32|t") | |
:gsub(ci_pattern('{warlock}'), "|TInterface\\GLUES\\CHARACTERCREATE\\UI-CHARACTERCREATE-CLASSES:0:0:0:0:64:64:48:64:16:32|t") | |
:gsub(ci_pattern('{paladin}'), "|TInterface\\GLUES\\CHARACTERCREATE\\UI-CHARACTERCREATE-CLASSES:0:0:0:0:64:64:0:16:32:48|t") | |
:gsub(ci_pattern('{deathknight}'), "|TInterface\\GLUES\\CHARACTERCREATE\\UI-CHARACTERCREATE-CLASSES:0:0:0:0:64:64:16:32:32:48|t") | |
:gsub(ci_pattern('{druid}'), "|TInterface\\GLUES\\CHARACTERCREATE\\UI-CHARACTERCREATE-CLASSES:0:0:0:0:64:64:48:64:0:16|t") | |
:gsub(ci_pattern('{monk}'), "|TInterface\\GLUES\\CHARACTERCREATE\\UI-CHARACTERCREATE-CLASSES:0:0:0:0:64:64:32:48:32:48|t") | |
:gsub(ci_pattern('{shaman}'), "|TInterface\\GLUES\\CHARACTERCREATE\\UI-CHARACTERCREATE-CLASSES:0:0:0:0:64:64:16:32:16:32|t") | |
:gsub(ci_pattern('{demonhunter}'), "|TInterface\\GLUES\\CHARACTERCREATE\\UI-CHARACTERCREATE-CLASSES:0:0:0:0:64:64:64:48:32:48|t") | |
self.display_text:Clear() | |
local lines = { strsplit("\n", text) } | |
local lines_count = #lines | |
for i = 1, lines_count do | |
local line | |
if AngryAssign_State.directionUp then | |
line = lines[i] | |
else | |
line = lines[lines_count - i + 1] | |
end | |
if line == "" then line = " " end | |
self.display_text:AddMessage(line) | |
end | |
else | |
self.display_text:Clear() | |
end | |
self:UpdateBackdrop() | |
end | |
function AngryAssign_OutputDisplayed() | |
return AngryAssign:OutputDisplayed( AngryAssign:SelectedId() ) | |
end | |
function AngryAssign:OutputDisplayed(id) | |
if not self:PermissionCheck() then | |
self:Print( RED_FONT_COLOR_CODE .. "You don't have permission to output a page.|r" ) | |
end | |
if not id then id = AngryAssign_State.displayed end | |
local page = AngryAssign_Pages[ id ] | |
local channel | |
if not isClassic and (IsInGroup(LE_PARTY_CATEGORY_INSTANCE) or IsInRaid(LE_PARTY_CATEGORY_INSTANCE)) then | |
channel = "INSTANCE_CHAT" | |
elseif IsInRaid() then | |
if UnitIsGroupAssistant('player') or UnitIsGroupLeader('player') then | |
channel = "RAID_WARNING" | |
else | |
channel = "RAID" | |
end | |
elseif IsInGroup() then | |
channel = "PARTY" | |
end | |
if channel and page then | |
local output = page.Contents | |
if LOCALIZED_CLASS_NAMES_MALE["DEATHKNIGHT"] == nil then LOCALIZED_CLASS_NAMES_MALE["DEATHKNIGHT"] = "" end | |
if LOCALIZED_CLASS_NAMES_MALE["MONK"] == nil then LOCALIZED_CLASS_NAMES_MALE["MONK"] = "" end | |
if LOCALIZED_CLASS_NAMES_MALE["DEMONHUNTER"] == nil then LOCALIZED_CLASS_NAMES_MALE["DEMONHUNTER"] = "" end | |
output = output:gsub("||", "|") | |
:gsub(ci_pattern('|r'), "") | |
:gsub(ci_pattern('|cblue'), "") | |
:gsub(ci_pattern('|cgreen'), "") | |
:gsub(ci_pattern('|cred'), "") | |
:gsub(ci_pattern('|cyellow'), "") | |
:gsub(ci_pattern('|corange'), "") | |
:gsub(ci_pattern('|cpink'), "") | |
:gsub(ci_pattern('|cpurple'), "") | |
:gsub(ci_pattern('|cdeathknight'), "") | |
:gsub(ci_pattern('|cdruid'), "") | |
:gsub(ci_pattern('|chunter'), "") | |
:gsub(ci_pattern('|cmage'), "") | |
:gsub(ci_pattern('|cmonk'), "") | |
:gsub(ci_pattern('|cpaladin'), "") | |
:gsub(ci_pattern('|cpriest'), "") | |
:gsub(ci_pattern('|crogue'), "") | |
:gsub(ci_pattern('|cshaman'), "") | |
:gsub(ci_pattern('|cwarlock'), "") | |
:gsub(ci_pattern('|cwarrior'), "") | |
:gsub(ci_pattern('|cdemonhunter'), "") | |
:gsub(ci_pattern('|c%w?%w?%w?%w?%w?%w?%w?%w?'), "") | |
:gsub(ci_pattern('{spell%s+(%d+)}'), function(id) | |
return GetSpellLink(id) | |
end) | |
:gsub(ci_pattern('{boss%s+(%d+)}'), function(id) | |
return select(5, EJ_GetEncounterInfo(id)) | |
end) | |
:gsub(ci_pattern('{journal%s+(%d+)}'), function(id) | |
return C_EncounterJournal.GetSectionInfo(id) and C_EncounterJournal.GetSectionInfo(id).link | |
end) | |
:gsub(ci_pattern('{star}'), "{rt1}") | |
:gsub(ci_pattern('{circle}'), "{rt2}") | |
:gsub(ci_pattern('{diamond}'), "{rt3}") | |
:gsub(ci_pattern('{triangle}'), "{rt4}") | |
:gsub(ci_pattern('{moon}'), "{rt5}") | |
:gsub(ci_pattern('{square}'), "{rt6}") | |
:gsub(ci_pattern('{cross}'), "{rt7}") | |
:gsub(ci_pattern('{x}'), "{rt7}") | |
:gsub(ci_pattern('{skull}'), "{rt8}") | |
:gsub(ci_pattern('{healthstone}'), "{hs}") | |
:gsub(ci_pattern('{hs}'), 'Healthstone') | |
:gsub(ci_pattern('{bloodlust}'), "{bl}") | |
:gsub(ci_pattern('{bl}'), 'Bloodlust') | |
:gsub(ci_pattern('{icon%s+([%w_]+)}'), '') | |
:gsub(ci_pattern('{damage}'), 'Damage') | |
:gsub(ci_pattern('{tank}'), 'Tanks') | |
:gsub(ci_pattern('{healer}'), 'Healers') | |
:gsub(ci_pattern('{dps}'), 'Damage') | |
:gsub(ci_pattern('{hero}'), "{heroism}") | |
:gsub(ci_pattern('{heroism}'), 'Heroism') | |
:gsub(ci_pattern('{hunter}'), LOCALIZED_CLASS_NAMES_MALE["HUNTER"]) | |
:gsub(ci_pattern('{warrior}'), LOCALIZED_CLASS_NAMES_MALE["WARRIOR"]) | |
:gsub(ci_pattern('{rogue}'), LOCALIZED_CLASS_NAMES_MALE["ROGUE"]) | |
:gsub(ci_pattern('{mage}'), LOCALIZED_CLASS_NAMES_MALE["MAGE"]) | |
:gsub(ci_pattern('{priest}'), LOCALIZED_CLASS_NAMES_MALE["PRIEST"]) | |
:gsub(ci_pattern('{warlock}'), LOCALIZED_CLASS_NAMES_MALE["WARLOCK"]) | |
:gsub(ci_pattern('{paladin}'), LOCALIZED_CLASS_NAMES_MALE["PALADIN"]) | |
:gsub(ci_pattern('{deathknight}'), LOCALIZED_CLASS_NAMES_MALE["DEATHKNIGHT"]) | |
:gsub(ci_pattern('{druid}'), LOCALIZED_CLASS_NAMES_MALE["DRUID"]) | |
:gsub(ci_pattern('{monk}'), LOCALIZED_CLASS_NAMES_MALE["MONK"]) | |
:gsub(ci_pattern('{shaman}'), LOCALIZED_CLASS_NAMES_MALE["SHAMAN"]) | |
:gsub(ci_pattern('{demonhunter}'), LOCALIZED_CLASS_NAMES_MALE["DEMONHUNTER"]) | |
local lines = { strsplit("\n", output) } | |
for _, line in ipairs(lines) do | |
if line ~= "" then | |
SendChatMessage(line, channel) | |
end | |
end | |
end | |
end | |
----------------- | |
-- Addon Setup -- | |
----------------- | |
local configDefaults = { | |
scale = 1, | |
hideoncombat = false, | |
fontName = "Friz Quadrata TT", | |
fontHeight = 12, | |
fontFlags = "NONE", | |
highlight = "", | |
highlightColor = "ffd200", | |
color = "ffffff", | |
allowall = false, | |
lineSpacing = 0, | |
allowplayers = "", | |
backdropShow = false, | |
backdropColor = "00000080", | |
glowColor = "FF0000", | |
editBoxFont = false, | |
} | |
function AngryAssign:GetConfig(key) | |
if AngryAssign_Config[key] == nil then | |
return configDefaults[key] | |
else | |
return AngryAssign_Config[key] | |
end | |
end | |
function AngryAssign:SetConfig(key, value) | |
if configDefaults[key] == value then | |
AngryAssign_Config[key] = nil | |
else | |
AngryAssign_Config[key] = value | |
end | |
end | |
function AngryAssign:RestoreDefaults() | |
AngryAssign_Config = {} | |
self:UpdateMedia() | |
self:UpdateDisplayed() | |
LibStub("AceConfigRegistry-3.0"):NotifyChange("AngryAssign") | |
end | |
local blizOptionsPanel | |
function AngryAssign:OnInitialize() | |
if AngryAssign_State == nil then | |
AngryAssign_State = { tree = {}, window = {}, display = {}, displayed = nil, locked = false, directionUp = false } | |
end | |
if AngryAssign_Pages == nil then AngryAssign_Pages = { } end | |
if AngryAssign_Config == nil then AngryAssign_Config = { } end | |
if AngryAssign_Categories == nil then | |
AngryAssign_Categories = { } | |
else | |
for _, cat in pairs(AngryAssign_Categories) do | |
if cat.Children then | |
for _, pageId in ipairs(cat.Children) do | |
local page = AngryAssign_Pages[pageId] | |
if page then | |
page.CategoryId = cat.Id | |
end | |
end | |
cat.Children = nil | |
end | |
end | |
end | |
local ver = AngryAssign_Version | |
if ver:sub(1,1) == "@" then ver = "dev" end | |
local options = { | |
name = "Angry Assignments "..ver, | |
handler = AngryAssign, | |
type = "group", | |
args = { | |
window = { | |
type = "execute", | |
order = 3, | |
name = "Toggle Window", | |
desc = "Shows/hides the edit window (also available in game keybindings)", | |
func = function() AngryAssign_ToggleWindow() end | |
}, | |
help = { | |
type = "execute", | |
order = 99, | |
name = "Help", | |
hidden = true, | |
func = function() | |
LibStub("AceConfigCmd-3.0").HandleCommand(self, "aa", "AngryAssign", "") | |
end | |
}, | |
toggle = { | |
type = "execute", | |
order = 1, | |
name = "Toggle Display", | |
desc = "Shows/hides the display frame (also available in game keybindings)", | |
func = function() AngryAssign_ToggleDisplay() end | |
}, | |
deleteall = { | |
type = "execute", | |
name = "Delete All Pages", | |
desc = "Deletes all pages", | |
order = 4, | |
hidden = true, | |
cmdHidden = false, | |
confirm = true, | |
func = function() | |
AngryAssign_State.displayed = nil | |
AngryAssign_Pages = {} | |
AngryAssign_Categories = {} | |
self:UpdateTree() | |
self:UpdateSelected() | |
self:UpdateDisplayed() | |
if self.window then self.window.tree:SetSelected(nil) end | |
self:Print("All pages have been deleted.") | |
end | |
}, | |
defaults = { | |
type = "execute", | |
name = "Restore Defaults", | |
desc = "Restore configuration values to their default settings", | |
order = 10, | |
hidden = true, | |
cmdHidden = false, | |
confirm = true, | |
func = function() | |
self:RestoreDefaults() | |
end | |
}, | |
output = { | |
type = "execute", | |
name = "Output", | |
desc = "Outputs currently displayed assignents to chat", | |
order = 11, | |
hidden = true, | |
cmdHidden = false, | |
confirm = true, | |
func = function() | |
self:OutputDisplayed() | |
end | |
}, | |
send = { | |
type = "input", | |
name = "Send and Display", | |
desc = "Sends page with specified name", | |
order = 12, | |
hidden = true, | |
cmdHidden = false, | |
confirm = true, | |
get = function(info) return "" end, | |
set = function(info, val) | |
local result = self:DisplayPageByName( val:trim() ) | |
if result == false then | |
self:Print( RED_FONT_COLOR_CODE .. "A page with the name \""..val:trim().."\" could not be found.|r" ) | |
elseif not result then | |
self:Print( RED_FONT_COLOR_CODE .. "You don't have permission to send a page.|r" ) | |
end | |
end | |
}, | |
clear = { | |
type = "execute", | |
name = "Clear", | |
desc = "Clears currently displayed page", | |
order = 13, | |
hidden = true, | |
cmdHidden = false, | |
confirm = true, | |
func = function() | |
AngryAssign_ClearPage() | |
end | |
}, | |
backup = { | |
type = "execute", | |
order = 20, | |
name = "Backup Pages", | |
desc = "Creates a backup of all pages with their current contents", | |
func = function() | |
self:CreateBackup() | |
self:Print("Created a backup of all pages.") | |
end | |
}, | |
resetposition = { | |
type = "execute", | |
order = 22, | |
name = "Reset Position", | |
desc = "Resets position for the assignment display", | |
func = function() | |
self:ResetPosition() | |
end | |
}, | |
version = { | |
type = "execute", | |
order = 21, | |
name = "Version Check", | |
desc = "Displays a list of all users (in the raid) running the addon and the version they're running", | |
func = function() | |
if (IsInRaid() or IsInGroup()) then | |
versionList = {} -- start with a fresh version list, when displaying it | |
self:SendOutMessage({ "VER_QUERY" }) | |
self:ScheduleTimer("VersionCheckOutput", 3) | |
self:Print("Version check running...") | |
else | |
self:Print("You must be in a raid group to run the version check.") | |
end | |
end | |
}, | |
lock = { | |
type = "execute", | |
order = 2, | |
name = "Toggle Lock", | |
desc = "Shows/hides the display mover (also available in game keybindings)", | |
func = function() self:ToggleLock() end | |
}, | |
config = { | |
type = "group", | |
order = 5, | |
name = "General", | |
inline = true, | |
args = { | |
highlight = { | |
type = "input", | |
order = 1, | |
name = "Highlight", | |
desc = "A list of words to highlight on displayed pages (separated by spaces or punctuation)\n\nUse 'Group' to highlight the current group you are in, ex. G2", | |
get = function(info) return self:GetConfig('highlight') end, | |
set = function(info, val) | |
self:SetConfig('highlight', val) | |
self:UpdateDisplayed() | |
end | |
}, | |
hideoncombat = { | |
type = "toggle", | |
order = 3, | |
name = "Hide on Combat", | |
desc = "Enable to hide display frame upon entering combat", | |
get = function(info) return self:GetConfig('hideoncombat') end, | |
set = function(info, val) | |
self:SetConfig('hideoncombat', val) | |
end | |
}, | |
scale = { | |
type = "range", | |
order = 4, | |
name = "Scale", | |
desc = "Sets the scale of the edit window", | |
min = 0.3, | |
max = 3, | |
get = function(info) return self:GetConfig('scale') end, | |
set = function(info, val) | |
self:SetConfig('scale', val) | |
if AngryAssign.window then AngryAssign.window.frame:SetScale(val) end | |
end | |
}, | |
backdrop = { | |
type = "toggle", | |
order = 5, | |
name = "Display Backdrop", | |
desc = "Enable to display a backdrop behind the assignment display", | |
get = function(info) return self:GetConfig('backdropShow') end, | |
set = function(info, val) | |
self:SetConfig('backdropShow', val) | |
self:UpdateBackdrop() | |
end | |
}, | |
backdropcolor = { | |
type = "color", | |
order = 6, | |
name = "Backdrop Color", | |
desc = "The color used by the backdrop", | |
hasAlpha = true, | |
get = function(info) | |
local hex = self:GetConfig('backdropColor') | |
return HexToRGB(hex) | |
end, | |
set = function(info, r, g, b, a) | |
self:SetConfig('backdropColor', RGBToHex(r, g, b, a)) | |
self:UpdateMedia() | |
self:UpdateDisplayed() | |
end | |
}, | |
updatecolor = { | |
type = "color", | |
order = 7, | |
name = "Update Notification Color", | |
desc = "The color used by the update notification glow", | |
get = function(info) | |
local hex = self:GetConfig('glowColor') | |
return HexToRGB(hex) | |
end, | |
set = function(info, r, g, b) | |
self:SetConfig('glowColor', RGBToHex(r, g, b)) | |
self.display_glow:SetVertexColor(r, g, b) | |
self.display_glow2:SetVertexColor(r, g, b) | |
end | |
} | |
} | |
}, | |
font = { | |
type = "group", | |
order = 6, | |
name = "Font", | |
inline = true, | |
args = { | |
fontname = { | |
type = 'select', | |
order = 1, | |
dialogControl = 'LSM30_Font', | |
name = 'Face', | |
desc = 'Sets the font face used to display a page', | |
values = LSM:HashTable("font"), | |
get = function(info) return self:GetConfig('fontName') end, | |
set = function(info, val) | |
self:SetConfig('fontName', val) | |
self:UpdateMedia() | |
end | |
}, | |
fontheight = { | |
type = "range", | |
order = 2, | |
name = "Size", | |
desc = function() | |
return "Sets the font height used to display a page" | |
end, | |
min = 6, | |
max = 24, | |
step = 1, | |
get = function(info) return self:GetConfig('fontHeight') end, | |
set = function(info, val) | |
self:SetConfig('fontHeight', val) | |
self:UpdateMedia() | |
end | |
}, | |
fontflags = { | |
type = "select", | |
order = 3, | |
name = "Outline", | |
desc = "Sets the font outline used to display a page", | |
values = { ["NONE"] = "None", ["OUTLINE"] = "Outline", ["THICKOUTLINE"] = "Thick Outline", ["MONOCHROMEOUTLINE"] = "Monochrome" }, | |
get = function(info) return self:GetConfig('fontFlags') end, | |
set = function(info, val) | |
self:SetConfig('fontFlags', val) | |
self:UpdateMedia() | |
end | |
}, | |
color = { | |
type = "color", | |
order = 4, | |
name = "Normal Color", | |
desc = "The normal color used to display assignments", | |
get = function(info) | |
local hex = self:GetConfig('color') | |
return HexToRGB(hex) | |
end, | |
set = function(info, r, g, b) | |
self:SetConfig('color', RGBToHex(r, g, b)) | |
self:UpdateMedia() | |
self:UpdateDisplayed() | |
end | |
}, | |
highlightcolor = { | |
type = "color", | |
order = 5, | |
name = "Highlight Color", | |
desc = "The color used to emphasize highlighted words", | |
get = function(info) | |
local hex = self:GetConfig('highlightColor') | |
return HexToRGB(hex) | |
end, | |
set = function(info, r, g, b) | |
self:SetConfig('highlightColor', RGBToHex(r, g, b)) | |
self:UpdateDisplayed() | |
end | |
}, | |
linespacing = { | |
type = "range", | |
order = 6, | |
name = "Line Spacing", | |
desc = function() | |
return "Sets the line spacing used to display a page" | |
end, | |
min = 0, | |
max = 10, | |
step = 1, | |
get = function(info) return self:GetConfig('lineSpacing') end, | |
set = function(info, val) | |
self:SetConfig('lineSpacing', val) | |
self:UpdateMedia() | |
self:UpdateDisplayed() | |
end | |
}, | |
editBoxFont = { | |
type = "toggle", | |
order = 7, | |
name = "Change Edit Box Font", | |
desc = "Enable to set edit box font to display font", | |
get = function(info) return self:GetConfig('editBoxFont') end, | |
set = function(info, val) | |
self:SetConfig('editBoxFont', val) | |
self:UpdateMedia() | |
end | |
}, | |
} | |
}, | |
permissions = { | |
type = "group", | |
order = 7, | |
name = "Permissions", | |
inline = true, | |
args = { | |
allowall = { | |
type = "toggle", | |
order = 1, | |
name = "Allow All", | |
desc = "Enable to allow changes from any raid assistant, even if you aren't in a guild raid", | |
get = function(info) return self:GetConfig('allowall') end, | |
set = function(info, val) | |
self:SetConfig('allowall', val) | |
self:PermissionsUpdated() | |
end | |
}, | |
allowplayers = { | |
type = "input", | |
order = 2, | |
name = "Allow Players", | |
desc = "A list of players that when they are the raid leader to allow changes from all raid assistants", | |
get = function(info) return self:GetConfig('allowplayers') end, | |
set = function(info, val) | |
self:SetConfig('allowplayers', val) | |
self:PermissionsUpdated() | |
end | |
}, | |
} | |
} | |
} | |
} | |
self:RegisterChatCommand("aa", "ChatCommand") | |
LibStub("AceConfig-3.0"):RegisterOptionsTable("AngryAssign", options) | |
blizOptionsPanel = LibStub("AceConfigDialog-3.0"):AddToBlizOptions("AngryAssign", "Angry Assignments") | |
blizOptionsPanel.default = function() self:RestoreDefaults() end | |
end | |
function AngryAssign:ChatCommand(input) | |
if not input or input:trim() == "" then | |
InterfaceOptionsFrame_OpenToCategory(blizOptionsPanel) | |
InterfaceOptionsFrame_OpenToCategory(blizOptionsPanel) | |
else | |
LibStub("AceConfigCmd-3.0").HandleCommand(self, "aa", "AngryAssign", input) | |
end | |
end | |
function AngryAssign:OnEnable() | |
self:ResetOfficerRank() | |
self:CreateDisplay() | |
self:ScheduleTimer("AfterEnable", 4) | |
self:RegisterEvent("PLAYER_REGEN_DISABLED") | |
self:RegisterEvent("PLAYER_GUILD_UPDATE") | |
self:RegisterEvent("GUILD_ROSTER_UPDATE") | |
GuildRoster() | |
LSM.RegisterCallback(self, "LibSharedMedia_Registered", "UpdateMedia") | |
LSM.RegisterCallback(self, "LibSharedMedia_SetGlobal", "UpdateMedia") | |
end | |
function AngryAssign:PARTY_LEADER_CHANGED() | |
self:PermissionsUpdated() | |
if AngryAssign_State.displayed and not (self:IsGuildRaid() or self:IsValidRaid()) then self:ClearDisplayed() end | |
end | |
function AngryAssign:PARTY_CONVERTED_TO_RAID() | |
self:SendRequestDisplay() | |
self:SendVerQuery() | |
self:UpdateDisplayedIfNewGroup() | |
end | |
function AngryAssign:GROUP_JOINED() | |
self:SendVerQuery() | |
self:UpdateDisplayedIfNewGroup() | |
self:ScheduleTimer("SendRequestDisplay", 0.5) | |
end | |
function AngryAssign:PLAYER_REGEN_DISABLED() | |
if AngryAssign:GetConfig('hideoncombat') then | |
self:HideDisplay() | |
end | |
end | |
function AngryAssign:GROUP_ROSTER_UPDATE() | |
self:UpdateSelected() | |
if not (IsInRaid() or IsInGroup()) then | |
if AngryAssign_State.displayed then self:ClearDisplayed() end | |
currentGroup = nil | |
warnedPermission = false | |
else | |
self:UpdateDisplayedIfNewGroup() | |
end | |
end | |
function AngryAssign:PLAYER_GUILD_UPDATE() | |
self:ResetOfficerRank() | |
self:PermissionsUpdated() | |
end | |
function AngryAssign:GUILD_ROSTER_UPDATE(...) | |
local canRequestRosterUpdate = ... | |
self:ResetOfficerRank() | |
if canRequestRosterUpdate then | |
GuildRoster() | |
end | |
end | |
function AngryAssign:AfterEnable() | |
self:RegisterComm(comPrefix, "ReceiveMessage") | |
comStarted = true | |
if not (IsInRaid() or IsInGroup()) then | |
self:ClearDisplayed() | |
end | |
--self:RegisterEvent("PARTY_CONVERTED_TO_RAID") | |
self:RegisterEvent("PARTY_LEADER_CHANGED") | |
self:RegisterEvent("GROUP_JOINED") | |
self:RegisterEvent("GROUP_ROSTER_UPDATE") | |
self:SendRequestDisplay() | |
self:UpdateDisplayedIfNewGroup() | |
self:SendVerQuery() | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment