Advertisement
Guest User

NoTroll v3

a guest
Jul 20th, 2014
243
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. local ADDON, private = ...
  2. local f = CreateFrame("Frame", ADDON, InterfaceOptionsFramePanelContainer)
  3.  
  4. local db = { -- default values
  5.     [2825]   = "RAID", -- Bloodlust
  6.     [32182]  = "RAID", -- Heroism
  7.     [80353]  = "RAID", -- Time Warp
  8.     [13159]  = "RAID", -- Aspect of Fail
  9.     [41450]  = "RAID", -- Blessing of Piss me off
  10.     [73325]  = "RAID", -- Leap of Fail
  11.     [34477]  = "RAID", -- MD
  12.     [20736]  = "RAID", -- Distracting Shot
  13.     [62124]  = "RAID", -- Reckoning * paladin
  14.     [56222]  = "RAID", -- Dark Command
  15.     [49576]  = "RAID", -- Death Grip
  16.     [2649]   = "RAID", -- Generic hunter growl
  17.     [39270]  = "RAID", -- main target growl
  18.     [103128] = "RAID", -- suffering
  19. }
  20.  
  21. local L = {
  22.     ANNOUNCE_MESSAGE = "%1$s used %2$s!",
  23.     SOMEONES_PET = "%s's pet",
  24.  
  25.     ADD_SPELL = "Add Spell",
  26.     ADD_SPELL_DESC = "Use this dialog to add a new spell to be announced.",
  27.     ADD_SPELL_HELP = "Enter the numeric ID of the spell you want to add. If you don't know the ID, look up the spell on Wowhead.com and copy the number out of the spell page URL.",
  28.     ADD_SPELL_INVALID = "That is not a valid spell ID!",
  29.     DELETE_SPELL = "Delete Spell",
  30.     DELETE_SPELL_DESC = "Permanently remove this spell from this list. If you only want to disable it temporarily, change the channel to NONE instead.",
  31. }
  32.  
  33. local ChannelNames = {
  34.     NONE = NONE,
  35.     SELF = PLAYER,
  36.     SAY = CHAT_MSG_SAY,
  37.     PARTY = CHAT_MSG_PARTY,
  38.     RAID = CHAT_MSG_RAID,
  39. }
  40.  
  41. local orderedChannels = { "NONE", "SELF", "SAY", "PARTY", "RAID" }
  42.  
  43. -------------------------------------------------------------------------
  44. --  Event handling
  45.  
  46. f:RegisterEvent("PLAYER_LOGIN")
  47. f:SetScript("OnEvent", function(self, event)
  48.     NoTrollDB = NoTrollDB or db
  49.     db = NoTrollDB
  50.  
  51.     for id in pairs(db) do
  52.         if not GetSpellInfo(id) then
  53.             print("Invalid spell in db:", id)
  54.         end
  55.     end
  56.  
  57.     self:UnregisterEvent("PLAYER_LOGIN")
  58.     self:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED")
  59.  
  60.     self:SetScript("OnEvent", function(self, event, unit, _, _, _, spellID)
  61.         local channel = db[spellID]
  62.         if channel and strmatch(unit, "%d") then -- ignore player, target, focus, etc.
  63.             self:Announce(channel, spellID, unit)
  64.         end
  65.     end)
  66. end)
  67.  
  68. -------------------------------------------------------------------------
  69. --  Announce logic
  70.  
  71. local lastText, lastTime = "", 0
  72. function f:Announce(channel, spellID, caster, target, isPet)
  73.     if channel == "NONE" then return end
  74.  
  75.     if isPet then
  76.         unit = gsub(unit, "pet", "player")
  77.     end
  78.  
  79.     local spellLink = GetSpellLink(spellID)
  80.     local playerName = GetUnitName(unit, true)
  81.  
  82.     if channel == "SELF" then
  83.         -- Clickable player links in self messages
  84.         local playerLink = "|Hplayer:"..playerName.."|h["..playerName.."]|h"
  85.         if isPet then
  86.             playerLink = format(L.SOMEONES_PET, playerLink)
  87.         end
  88.         print("|cffffff9a[NoTroll]|r", format(L.ANNOUNCE_MESSAGE, playerLink, spellLink))
  89.     else
  90.         -- Can't send player links to channels
  91.         if isPet then
  92.             playerName = format(L.SOMEONES_PET, playerName)
  93.         end
  94.         local now, message = GetTime(), format(L.ANNOUNCE_MESSAGE, playerName, spellLink)
  95.         if message ~= lastText or now - lastTime > 5 then
  96.             lastText, lastTime = message, now
  97.             SendChatMessage(message, channel)
  98.         end
  99.     end
  100. end
  101.  
  102. -------------------------------------------------------------------------
  103. -- Make player names in channel messages from the addon clickable LOCALLY ONLY
  104.  
  105. local ANNOUNCE_PATTERN = L.ANNOUNCE_MESSAGE:gsub("%%1$s", "(.+)"):gsub("%%2$s", ".+")
  106.  
  107. function f:AddLocalMessageLinks(_, message, ...)
  108.     local name = strmatch(message, ANNOUNCE_PATTERN)
  109.     if name then
  110.         local char = strmatch(playerName, "^[^%s%-]+")
  111.         local class = UnitClass(char)
  112.         local link = "|Hplayer:"..char.."|h["..name.."]|h"
  113.         message = gsub(message, name, link)
  114.         return false, message, ...
  115.     end
  116. end
  117.  
  118. ChatFrame_AddMessageEventFilter("CHAT_MSG_PARTY", f.AddLocalMessageLinks)
  119. ChatFrame_AddMessageEventFilter("CHAT_MSG_RAID", f.AddLocalMessageLinks)
  120. ChatFrame_AddMessageEventFilter("CHAT_MSG_SAY", f.AddLocalMessageLinks)
  121.  
  122. -------------------------------------------------------------------------
  123. -- Options panel
  124.  
  125. f:Hide()
  126. f:SetScript("OnShow", function(self)
  127.     local title = self:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge")
  128.     title:SetPoint("TOPLEFT", 16, -16)
  129.     title:SetPoint("TOPRIGHT", -32, -16)
  130.     title:SetJustifyH("LEFT")
  131.     title:SetText(self.name)
  132.     self.Title = Title
  133.  
  134.     local notes = self:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
  135.     notes:SetPoint("TOPLEFT", title, "BOTTOMLEFT", 0, -8)
  136.     notes:SetPoint("TOPRIGHT", title, "BOTTOMRIGHT", 0, -8)
  137.     notes:SetHeight(32)
  138.     notes:SetJustifyH("LEFT")
  139.     notes:SetJustifyV("TOP")
  140.     notes:SetText(GetAddOnMetadata(ADDON, "Notes"))
  141.     self.Notes = Notes
  142.  
  143.     local scrollFrame = CreateFrame("ScrollFrame", "$parentScrollFrame", self, "UIPanelScrollFrameTemplate")
  144.     scrollFrame:SetPoint("TOPLEFT", notes, "BOTTOMLEFT", 0, -16)
  145.     scrollFrame:SetPoint("BOTTOMRIGHT", -38, 16)
  146.     self.ScrollFrame = scrollFrame
  147.  
  148.     scrollFrame.ScrollBar:EnableMouseWheel(true)
  149.     scrollFrame.ScrollBar:SetScript("OnMouseWheel", function(self, delta)
  150.         ScrollFrameTemplate_OnMouseWheel(scrollFrame, delta)
  151.     end)
  152.  
  153.     local barBG = scrollFrame:CreateTexture(nil, "BACKGROUND", nil, -6)
  154.     barBG:SetPoint("TOP")
  155.     barBG:SetPoint("RIGHT", 25, 0)
  156.     barBG:SetPoint("BOTTOM")
  157.     barBG:SetWidth(26)
  158.     barBG:SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-ScrollBar")
  159.     barBG:SetTexCoord(0, 0.45, 0.1640625, 1)
  160.     barBG:SetAlpha(0.5)
  161.     scrollFrame.ScrollBar.bg = barBG
  162.  
  163.     local scrollChild = CreateFrame("Frame", nil, scrollFrame)
  164.     scrollChild:SetSize(scrollFrame:GetWidth(), 100)
  165.     scrollFrame.ScrollChild = scrollChild
  166.  
  167.     scrollFrame:SetScrollChild(scrollChild)
  168.     scrollFrame:SetScript("OnSizeChanged", function(self)
  169.         scrollChild:SetWidth(self:GetWidth())
  170.     end)
  171.  
  172.     --------------------------------------------------------------------
  173.  
  174.     local dialog = CreateFrame("Frame", nil, self)
  175.     dialog:SetPoint("TOPLEFT", notes, "BOTTOMLEFT", 0, -16)
  176.     dialog:SetPoint("BOTTOMRIGHT", -16, 16)
  177.     dialog:SetBackdrop({ edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", edgeSize = 16 })
  178.     dialog:SetBackdropBorderColor(1, 0.82, 0, 0.8)
  179.     self.Dialog = dialog
  180.  
  181.     dialog.bg = dialog:CreateTexture(nil, "BACKGROUND")
  182.     dialog.bg:SetPoint("BOTTOMLEFT", 3, 3)
  183.     dialog.bg:SetPoint("TOPRIGHT", -3, -3)
  184.     dialog.bg:SetTexture("Interface\\FrameGeneral\\UI-Background-Rock", true, true)
  185.     dialog.bg:SetHorizTile(true)
  186.     dialog.bg:SetVertTile(true)
  187.     dialog.bg:SetVertexColor(0.4, 0.4, 0.4, 0.8)
  188.  
  189.     dialog:Hide()
  190.     dialog:SetScript("OnShow", function(self)
  191.         self:GetParent().ScrollFrame:Hide()
  192.         self.EditBox:SetText("")
  193.         self.Text:SetText("")
  194.         self.EditBox:SetFocus()
  195.     end)
  196.     dialog:SetScript("OnHide", function(self)
  197.         self:GetParent().ScrollFrame:Show()
  198.         self.EditBox:SetText("")
  199.         self.Text:SetText("")
  200.         self:GetParent().refresh()
  201.     end)
  202.  
  203.     local dialogTitle = dialog:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge")
  204.     dialogTitle:SetPoint("TOPLEFT", 16, -16)
  205.     dialogTitle:SetText(L.ADD_SPELL)
  206.     dialog.Title = dialogTitle
  207.  
  208.     local dialogNotes = dialog:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
  209.     dialogNotes:SetPoint("TOPLEFT", dialogTitle, "BOTTOMLEFT", 0, -8)
  210.     dialogNotes:SetPoint("RIGHT", -32, 0)
  211.     dialogNotes:SetHeight(16)
  212.     dialogNotes:SetJustifyH("LEFT")
  213.     dialogNotes:SetJustifyV("TOP")
  214.     dialogNotes:SetText(L.ADD_SPELL_DESC)
  215.  
  216.     local dialogBox = CreateFrame("EditBox", "$parentEditBox", dialog, "InputBoxTemplate")
  217.     dialogBox:SetPoint("TOPLEFT", dialogNotes, "BOTTOMLEFT", 6, -12)
  218.     dialogBox:SetSize(160, 24)
  219.     dialogBox:SetAltArrowKeyMode(false)
  220.     dialogBox:SetAutoFocus(false)
  221.     dialogBox:SetMaxLetters(6)
  222.     dialogBox:SetNumeric(true)
  223.     dialog.EditBox = dialogBox
  224.  
  225.     dialogBox:SetScript("OnTextChanged", function(self, userInput)
  226.         if not userInput then return end
  227.  
  228.         local spell = self:GetNumber()
  229.         if spell == 0 then
  230.             dialog.Text:SetText("")
  231.             dialog.Button:SetEnabled(false)
  232.             return
  233.         end
  234.  
  235.         local name, _, icon = GetSpellInfo(spell)
  236.         if name and icon then
  237.             dialog.Text:SetFormattedText("|T%s:0|t %s", icon, name)
  238.             dialog.Button:SetEnabled(true)
  239.         else
  240.             dialog.Text:SetText(RED_FONT_COLOR_CODE .. L.ADD_SPELL_INVALID .. "|r")
  241.             dialog.Button:Disable()
  242.         end
  243.     end)
  244.  
  245.     dialogBox:SetScript("OnEnterPressed", function(self)
  246.         if not dialog.Button:IsEnabled() then return end
  247.         local id = self:GetNumber()
  248.         if id and id > 0 and GetSpellInfo(id) then
  249.             db[id] = "RAID"
  250.             dialog:Hide()
  251.         end
  252.     end)
  253.  
  254.     local dialogButton = CreateFrame("Button", "$parentAddButton", dialog, "UIPanelButtonTemplate")
  255.     dialogButton:SetPoint("LEFT", dialogBox, "RIGHT", 12, 0)
  256.     dialogButton:SetWidth(80)
  257.     dialogButton:SetText(OKAY)
  258.     dialogButton:SetScript("OnClick", function()
  259.         dialogBox:GetScript("OnEnterPressed")(dialogBox)
  260.     end)
  261.     dialog.Button = dialogButton
  262.  
  263.     local dialogText = dialog:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
  264.     dialogText:SetPoint("LEFT", dialogButton, "RIGHT", 12, 0)
  265.     dialogText:SetPoint("RIGHT", dialog, -16, 0)
  266.     dialogText:SetJustifyH("LEFT")
  267.     dialogText:SetJustifyV("TOP")
  268.     dialogText:SetText("")
  269.     dialog.Text = dialogText
  270.  
  271.     local dialogHelp = dialog:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
  272.     dialogHelp:SetPoint("TOPLEFT", dialogBox, "BOTTOMLEFT", -6, -16)
  273.     dialogHelp:SetPoint("RIGHT", dialog, -16, 0)
  274.     dialogHelp:SetHeight(32)
  275.     dialogHelp:SetJustifyH("LEFT")
  276.     dialogHelp:SetJustifyV("TOP")
  277.     dialogHelp:SetNonSpaceWrap(true)
  278.     dialogHelp:SetText(L.ADD_SPELL_HELP)
  279.     dialog.HelpText = dialogHelp
  280.  
  281.     --------------------------------------------------------------------
  282.  
  283.     local add = CreateFrame("Button", "$parentPanelButton", self, "UIPanelButtonTemplate")
  284.     add:SetPoint("TOPRIGHT", title, "BOTTOMRIGHT", 0, -8)
  285.     add:SetSize(160, 32)
  286.     add:SetText("|TInterface\\LFGFRAME\\LFGROLE_BW:0:0:0:0:64:16:48:64:0:16:255:255:153|t " .. L.ADD_SPELL)
  287.     self.AddButton = add
  288.  
  289.     notes:SetPoint("TOPRIGHT", add, "TOPLEFT", -24, 0)
  290.  
  291.     add:SetScript("OnClick", function(self)
  292.         if dialog:IsShown() then
  293.             dialog:Hide()
  294.             self:SetText("|TInterface\\LFGFRAME\\LFGROLE_BW:0:0:0:0:64:16:48:64:0:16:255:255:153|t " .. L.ADD_SPELL)
  295.         else
  296.             dialog:Show()
  297.             self:SetText(CANCEL)
  298.         end
  299.     end)
  300.  
  301.     --------------------------------------------------------------------
  302.  
  303.     local function Row_OnEnter(self)
  304.         self.name:SetTextColor(1, 1, 1)
  305.         self.highlight:Show()
  306.         GameTooltip:SetOwner(self, "ANCHOR_NONE")
  307.         GameTooltip:SetPoint("TOPRIGHT", self, "TOPLEFT")
  308.         GameTooltip:SetSpellByID(self.id)
  309.         GameTooltip:Show()
  310.     end
  311.     local function Row_OnLeave(self)
  312.         self.name:SetTextColor(1, 0.82, 0)
  313.         self.highlight:Hide()
  314.         GameTooltip:Hide()
  315.     end
  316.     local function Row_OnHide(self)
  317.         self.id = 0
  318.         self.icon:SetTexture(nil)
  319.         self.name:SetText("")
  320.         self.channel.valueText:SetText("")
  321.     end
  322.  
  323.     -- Delete button functions:
  324.     local function Delete_OnClick(self)
  325.         if GameTooltip:IsOwned(self) then
  326.             GameTooltip:Hide()
  327.         end
  328.         local id = self:GetParent().id
  329.         db[id] = nil
  330.         self.refresh()
  331.     end
  332.     local function Delete_OnEnter(self)
  333.         GameTooltip:SetOwner(self, "ANCHOR_LEFT")
  334.         GameTooltip:SetText(L.DELETE_SPELL)
  335.         GameTooltip:AddLine(L.DELETE_SPELL_DESC, 1, 1, 1, true)
  336.         GameTooltip:Show()
  337.     end
  338.  
  339.     -- Filter dropdown functions:
  340.     local CURRENT_SPELL, CURRENT_DROPDOWN
  341.     local function Dropdown_ClickFunc(info)
  342.         db[CURRENT_SPELL] = info.value
  343.         CURRENT_DROPDOWN:SetValue(info.value, ChannelNames[info.value])
  344.     end
  345.     local function Dropdown_Initialize(self, level) -- self is the dropdown menu
  346.         if not level then return end
  347.         CURRENT_DROPDOWN = self:GetParent()
  348.         CURRENT_SPELL = CURRENT_DROPDOWN:GetParent().id
  349.         local selected = db[CURRENT_SPELL]
  350.         local info = UIDropDownMenu_CreateInfo()
  351.         for i = 1, #orderedChannels do
  352.             local k = orderedChannels[i]
  353.             info.text = ChannelNames[k]
  354.             info.value = k
  355.             info.checked = k == selected
  356.             info.func = Dropdown_ClickFunc
  357.             UIDropDownMenu_AddButton(info, level)
  358.         end
  359.     end
  360.     local function Dropdown_OnEnter(self)
  361.         Row_OnEnter(self:GetParent())
  362.     end
  363.     local function Dropdown_OnLeave(self)
  364.         Row_OnLeave(self:GetParent())
  365.     end
  366.  
  367.     -- Rows:
  368.     local rows = setmetatable({}, { __index = function(t, i)
  369.         local row = CreateFrame("Frame", nil, scrollChild)
  370.         row:SetHeight(40)
  371.         row:SetPoint("LEFT")
  372.         row:SetPoint("RIGHT")
  373.         if i > 1 then
  374.             row:SetPoint("TOP", t[i-1], "BOTTOM", 0, -4)
  375.         else
  376.             row:SetPoint("TOP")
  377.         end
  378.  
  379.         row:EnableMouse(true)
  380.         row:SetScript("OnEnter", Row_OnEnter)
  381.         row:SetScript("OnLeave", Row_OnLeave)
  382.  
  383.         row:EnableMouseWheel(true)
  384.         row:SetScript("OnMouseWheel", function(self, delta)
  385.             ScrollFrameTemplate_OnMouseWheel(scrollFrame, delta)
  386.         end)
  387.  
  388.         local highlight = row:CreateTexture(nil, "BACKGROUND")
  389.         highlight:SetAllPoints(true)
  390.         highlight:SetBlendMode("ADD")
  391.         highlight:SetTexture([[Interface\QuestFrame\UI-QuestLogTitleHighlight]])
  392.         highlight:SetVertexColor(0.2, 0.4, 0.8)
  393.         highlight:Hide()
  394.         row.highlight = highlight
  395.  
  396.         local delete = CreateFrame("Button", "$parentDelete"..i, row, "UIPanelCloseButton")
  397.         delete:SetPoint("LEFT", -2, -1)
  398.         delete:SetSize(32, 32)
  399.         delete:SetScript("OnClick", Delete_OnClick)
  400.         delete:SetScript("OnEnter", Delete_OnEnter)
  401.         delete:SetScript("OnLeave", GameTooltip_Hide)
  402.         row.delete = delete
  403.  
  404.         local icon = row:CreateTexture(nil, "ARTWORK")
  405.         icon:SetPoint("LEFT", delete, "RIGHT", 2, 0)
  406.         icon:SetSize(32, 32)
  407.         icon:SetTexCoord(0.1, 0.9, 0.1, 0.9)
  408.         row.icon = icon
  409.  
  410.         local name = row:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge")
  411.         name:SetPoint("LEFT", icon, "RIGHT", 8, 0)
  412.         row.name = name
  413.  
  414.         local channel = LibStub("PhanxConfig-Dropdown"):New(row, nil, nil, Dropdown_Initialize)
  415.         channel:SetPoint("RIGHT", 0, 5)
  416.         channel:SetWidth(200)
  417.         channel.OnEnter = Dropdown_OnEnter
  418.         channel.OnLeave = Dropdown_OnLeave
  419.         row.channel = channel
  420.  
  421.         t[i] = row
  422.         return row
  423.     end })
  424.     self.rows = rows
  425.  
  426.     --------------------------------------------------------------------
  427.  
  428.     -- OnShow for self:
  429.     local pool = {}
  430.     local sortedSpells = {}
  431.     local sortFunc = function(a, b)
  432.         return a.name < b.name or (a.name == b.name and a.id < b.id)
  433.     end
  434.     self.refresh = function()
  435.         for i = #sortedSpells, 1, -1 do
  436.             pool[tremove(sortedSpells, i)] = true
  437.         end
  438.  
  439.         for id, channel in pairs(db) do
  440.             local name, _, icon = GetSpellInfo(id)
  441.             if name and icon then
  442.                 local spell = next(pool) or {}
  443.                 pool[spell] = nil
  444.                 spell.name = name
  445.                 spell.icon = icon
  446.                 spell.id = id
  447.                 spell.channel = channel
  448.                 tinsert(sortedSpells, spell)
  449.             end
  450.         end
  451.         sort(sortedSpells, sortFunc)
  452.  
  453.         if #sortedSpells > 0 then
  454.             local height = 0
  455.             for i = 1, #sortedSpells do
  456.                 local spell = sortedSpells[i]
  457.                 local row = rows[i]
  458.                 row.id = spell.id
  459.                 row.name:SetText(spell.name)
  460.                 row.icon:SetTexture(spell.icon)
  461.                 row.channel:SetValue(spell.channel, ChannelNames[spell.channel])
  462.                 row:Show()
  463.                 height = height + 4 + row:GetHeight()
  464.             end
  465.             for i = #sortedSpells + 1, #rows do
  466.                 rows[i]:Hide()
  467.             end
  468.             scrollChild:SetHeight(height)
  469.             add:Show()
  470.         else
  471.             for i = 1, #rows do
  472.                 rows[i]:Hide()
  473.             end
  474.             scrollChild:SetHeight(100)
  475.             dialog:Show()
  476.             add:Hide()
  477.         end
  478.     end
  479.  
  480.     self:SetScript("OnShow", nil)
  481.     self.refresh()
  482. end)
  483.  
  484. f.name = GetAddOnMetadata(ADDON, "Title")
  485. InterfaceOptions_AddCategory(f)
  486.  
  487. _G["SLASH_"..ADDON.."1"] = "/notroll"
  488. SlashCmdList[ADDON] = function()
  489.     InterfaceOptionsFrame_OpenToCategory(f)
  490.     InterfaceOptionsFrame_OpenToCategory(f)
  491. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement