Advertisement
Guest User

NoTroll v3

a guest
Jul 21st, 2014
245
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 last = {}
  72.  
  73. function f:Announce(channel, spellID, caster, target, isPet)
  74.     if channel == "NONE" then return end
  75.  
  76.     if isPet then
  77.         caster = gsub(caster, "pet", "player")
  78.     end
  79.  
  80.     local guid, now = UnitGUID(caster), GetTime()
  81.     if last[guid] and last[guid] < 1 then return end
  82.     last[guid] = now
  83.  
  84.     local spellLink = GetSpellLink(spellID)
  85.     local playerName = GetUnitName(unit, true)
  86.  
  87.     if channel == "SELF" then
  88.         -- Clickable player links in self messages
  89.         local playerLink = "|Hplayer:"..playerName.."|h["..playerName.."]|h"
  90.         if isPet then
  91.             playerLink = format(L.SOMEONES_PET, playerLink)
  92.         end
  93.         print("|cffffff9a[NoTroll]|r", format(L.ANNOUNCE_MESSAGE, playerLink, spellLink))
  94.     else
  95.         -- Can't send player links to channels
  96.         if isPet then
  97.             playerName = format(L.SOMEONES_PET, playerName)
  98.         end
  99.         SendChatMessage(format(L.ANNOUNCE_MESSAGE, playerName, spellLink), channel)
  100.     end
  101. end
  102.  
  103. -------------------------------------------------------------------------
  104. -- Make player names in channel messages from the addon
  105. -- clickable in your local chat frame.
  106.  
  107. local ANNOUNCE_PATTERN = L.ANNOUNCE_MESSAGE:gsub("%%1$s", "(.+)"):gsub("%%2$s", ".+")
  108.  
  109. function f.AddLocalMessageLinks(frame, event, message, ...)
  110.     local playerName = strmatch(message, ANNOUNCE_PATTERN)
  111.     if playerName then
  112.         local playerLink = "|Hplayer:"..playerName.."|h["..playerName.."]|h"
  113.         message = gsub(message, playerName, playerLink)
  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 RefreshOptions
  128.  
  129.     local title = self:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge")
  130.     title:SetPoint("TOPLEFT", 16, -16)
  131.     title:SetPoint("TOPRIGHT", -32, -16)
  132.     title:SetJustifyH("LEFT")
  133.     title:SetText(self.name)
  134.     self.Title = Title
  135.  
  136.     local notes = self:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
  137.     notes:SetPoint("TOPLEFT", title, "BOTTOMLEFT", 0, -8)
  138.     notes:SetPoint("TOPRIGHT", title, "BOTTOMRIGHT", 0, -8)
  139.     notes:SetHeight(32)
  140.     notes:SetJustifyH("LEFT")
  141.     notes:SetJustifyV("TOP")
  142.     notes:SetText(GetAddOnMetadata(ADDON, "Notes"))
  143.     self.Notes = Notes
  144.  
  145.     local scrollFrame = CreateFrame("ScrollFrame", "$parentScrollFrame", self, "UIPanelScrollFrameTemplate")
  146.     scrollFrame:SetPoint("TOPLEFT", notes, "BOTTOMLEFT", 0, -16)
  147.     scrollFrame:SetPoint("BOTTOMRIGHT", -38, 16)
  148.     self.ScrollFrame = scrollFrame
  149.  
  150.     scrollFrame.ScrollBar:EnableMouseWheel(true)
  151.     scrollFrame.ScrollBar:SetScript("OnMouseWheel", function(self, delta)
  152.         ScrollFrameTemplate_OnMouseWheel(scrollFrame, delta)
  153.     end)
  154.  
  155.     local barBG = scrollFrame:CreateTexture(nil, "BACKGROUND", nil, -6)
  156.     barBG:SetPoint("TOP")
  157.     barBG:SetPoint("RIGHT", 25, 0)
  158.     barBG:SetPoint("BOTTOM")
  159.     barBG:SetWidth(26)
  160.     barBG:SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-ScrollBar")
  161.     barBG:SetTexCoord(0, 0.45, 0.1640625, 1)
  162.     barBG:SetAlpha(0.5)
  163.     scrollFrame.ScrollBar.bg = barBG
  164.  
  165.     local scrollChild = CreateFrame("Frame", nil, scrollFrame)
  166.     scrollChild:SetSize(scrollFrame:GetWidth(), 100)
  167.     scrollFrame.ScrollChild = scrollChild
  168.  
  169.     scrollFrame:SetScrollChild(scrollChild)
  170.     scrollFrame:SetScript("OnSizeChanged", function(self)
  171.         scrollChild:SetWidth(self:GetWidth())
  172.     end)
  173.  
  174.     --------------------------------------------------------------------
  175.  
  176.     local dialog = CreateFrame("Frame", nil, self)
  177.     dialog:SetPoint("TOPLEFT", notes, "BOTTOMLEFT", 0, -16)
  178.     dialog:SetPoint("BOTTOMRIGHT", -16, 16)
  179.     dialog:SetBackdrop({ edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", edgeSize = 16 })
  180.     dialog:SetBackdropBorderColor(1, 0.82, 0, 0.8)
  181.     self.Dialog = dialog
  182.  
  183.     dialog.bg = dialog:CreateTexture(nil, "BACKGROUND")
  184.     dialog.bg:SetPoint("BOTTOMLEFT", 3, 3)
  185.     dialog.bg:SetPoint("TOPRIGHT", -3, -3)
  186.     dialog.bg:SetTexture("Interface\\FrameGeneral\\UI-Background-Rock", true, true)
  187.     dialog.bg:SetHorizTile(true)
  188.     dialog.bg:SetVertTile(true)
  189.     dialog.bg:SetVertexColor(0.4, 0.4, 0.4, 0.8)
  190.  
  191.     dialog:Hide()
  192.     dialog:SetScript("OnShow", function(self)
  193.         self:GetParent().ScrollFrame:Hide()
  194.         self.EditBox:SetText("")
  195.         self.Text:SetText("")
  196.         self.EditBox:SetFocus()
  197.     end)
  198.     dialog:SetScript("OnHide", function(self)
  199.         self:GetParent().ScrollFrame:Show()
  200.         self.EditBox:SetText("")
  201.         self.Text:SetText("")
  202.         RefreshOptions()
  203.     end)
  204.  
  205.     local dialogTitle = dialog:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge")
  206.     dialogTitle:SetPoint("TOPLEFT", 16, -16)
  207.     dialogTitle:SetText(L.ADD_SPELL)
  208.     dialog.Title = dialogTitle
  209.  
  210.     local dialogNotes = dialog:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
  211.     dialogNotes:SetPoint("TOPLEFT", dialogTitle, "BOTTOMLEFT", 0, -8)
  212.     dialogNotes:SetPoint("RIGHT", -32, 0)
  213.     dialogNotes:SetHeight(16)
  214.     dialogNotes:SetJustifyH("LEFT")
  215.     dialogNotes:SetJustifyV("TOP")
  216.     dialogNotes:SetText(L.ADD_SPELL_DESC)
  217.  
  218.     local dialogBox = CreateFrame("EditBox", "$parentEditBox", dialog, "InputBoxTemplate")
  219.     dialogBox:SetPoint("TOPLEFT", dialogNotes, "BOTTOMLEFT", 6, -12)
  220.     dialogBox:SetSize(160, 24)
  221.     dialogBox:SetAltArrowKeyMode(false)
  222.     dialogBox:SetAutoFocus(false)
  223.     dialogBox:SetMaxLetters(6)
  224.     dialogBox:SetNumeric(true)
  225.     dialog.EditBox = dialogBox
  226.  
  227.     dialogBox:SetScript("OnTextChanged", function(self, userInput)
  228.         if not userInput then return end
  229.  
  230.         local spell = self:GetNumber()
  231.         if spell == 0 then
  232.             dialog.Text:SetText("")
  233.             dialog.Button:SetEnabled(false)
  234.             return
  235.         end
  236.  
  237.         local name, _, icon = GetSpellInfo(spell)
  238.         if name and icon then
  239.             dialog.Text:SetFormattedText("|T%s:0|t %s", icon, name)
  240.             dialog.Button:SetEnabled(true)
  241.         else
  242.             dialog.Text:SetText(RED_FONT_COLOR_CODE .. L.ADD_SPELL_INVALID .. "|r")
  243.             dialog.Button:Disable()
  244.         end
  245.     end)
  246.  
  247.     dialogBox:SetScript("OnEnterPressed", function(self)
  248.         if not dialog.Button:IsEnabled() then return end
  249.         local id = self:GetNumber()
  250.         if id and id > 0 and GetSpellInfo(id) then
  251.             db[id] = "RAID"
  252.             dialog:Hide()
  253.         end
  254.     end)
  255.  
  256.     local dialogButton = CreateFrame("Button", "$parentAddButton", dialog, "UIPanelButtonTemplate")
  257.     dialogButton:SetPoint("LEFT", dialogBox, "RIGHT", 12, 0)
  258.     dialogButton:SetWidth(80)
  259.     dialogButton:SetText(OKAY)
  260.     dialogButton:SetScript("OnClick", function()
  261.         dialogBox:GetScript("OnEnterPressed")(dialogBox)
  262.     end)
  263.     dialog.Button = dialogButton
  264.  
  265.     local dialogText = dialog:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
  266.     dialogText:SetPoint("LEFT", dialogButton, "RIGHT", 12, 0)
  267.     dialogText:SetPoint("RIGHT", dialog, -16, 0)
  268.     dialogText:SetJustifyH("LEFT")
  269.     dialogText:SetJustifyV("TOP")
  270.     dialogText:SetText("")
  271.     dialog.Text = dialogText
  272.  
  273.     local dialogHelp = dialog:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
  274.     dialogHelp:SetPoint("TOPLEFT", dialogBox, "BOTTOMLEFT", -6, -16)
  275.     dialogHelp:SetPoint("RIGHT", dialog, -16, 0)
  276.     dialogHelp:SetHeight(32)
  277.     dialogHelp:SetJustifyH("LEFT")
  278.     dialogHelp:SetJustifyV("TOP")
  279.     dialogHelp:SetNonSpaceWrap(true)
  280.     dialogHelp:SetText(L.ADD_SPELL_HELP)
  281.     dialog.HelpText = dialogHelp
  282.  
  283.     --------------------------------------------------------------------
  284.  
  285.     local add = CreateFrame("Button", "$parentPanelButton", self, "UIPanelButtonTemplate")
  286.     add:SetPoint("TOPRIGHT", title, "BOTTOMRIGHT", 0, -8)
  287.     add:SetSize(160, 32)
  288.     add:SetText("|TInterface\\LFGFRAME\\LFGROLE_BW:0:0:0:0:64:16:48:64:0:16:255:255:153|t " .. L.ADD_SPELL)
  289.     self.AddButton = add
  290.  
  291.     notes:SetPoint("TOPRIGHT", add, "TOPLEFT", -24, 0)
  292.  
  293.     add:SetScript("OnClick", function(self)
  294.         if dialog:IsShown() then
  295.             dialog:Hide()
  296.             self:SetText("|TInterface\\LFGFRAME\\LFGROLE_BW:0:0:0:0:64:16:48:64:0:16:255:255:153|t " .. L.ADD_SPELL)
  297.         else
  298.             dialog:Show()
  299.             self:SetText(CANCEL)
  300.         end
  301.     end)
  302.  
  303.     --------------------------------------------------------------------
  304.  
  305.     local function Row_OnEnter(self)
  306.         self.name:SetTextColor(1, 1, 1)
  307.         self.highlight:Show()
  308.         GameTooltip:SetOwner(self, "ANCHOR_NONE")
  309.         GameTooltip:SetPoint("TOPRIGHT", self, "TOPLEFT")
  310.         GameTooltip:SetSpellByID(self.id)
  311.         GameTooltip:Show()
  312.     end
  313.     local function Row_OnLeave(self)
  314.         self.name:SetTextColor(1, 0.82, 0)
  315.         self.highlight:Hide()
  316.         GameTooltip:Hide()
  317.     end
  318.     local function Row_OnHide(self)
  319.         self.id = 0
  320.         self.icon:SetTexture(nil)
  321.         self.name:SetText("")
  322.         self.channel.valueText:SetText("")
  323.     end
  324.  
  325.     -- Delete button functions:
  326.     local function Delete_OnClick(self)
  327.         if GameTooltip:IsOwned(self) then
  328.             GameTooltip:Hide()
  329.         end
  330.         local id = self:GetParent().id
  331.         db[id] = nil
  332.         RefreshOptions()
  333.     end
  334.     local function Delete_OnEnter(self)
  335.         GameTooltip:SetOwner(self, "ANCHOR_LEFT")
  336.         GameTooltip:SetText(L.DELETE_SPELL)
  337.         GameTooltip:AddLine(L.DELETE_SPELL_DESC, 1, 1, 1, true)
  338.         GameTooltip:Show()
  339.     end
  340.  
  341.     -- Filter dropdown functions:
  342.     local CURRENT_SPELL, CURRENT_DROPDOWN
  343.     local function Dropdown_ClickFunc(info)
  344.         db[CURRENT_SPELL] = info.value
  345.         CURRENT_DROPDOWN:SetValue(info.value, ChannelNames[info.value])
  346.     end
  347.     local function Dropdown_Initialize(self, level) -- self is the dropdown menu
  348.         if not level then return end
  349.         CURRENT_DROPDOWN = self:GetParent()
  350.         CURRENT_SPELL = CURRENT_DROPDOWN:GetParent().id
  351.         local selected = db[CURRENT_SPELL]
  352.         local info = UIDropDownMenu_CreateInfo()
  353.         for i = 1, #orderedChannels do
  354.             local k = orderedChannels[i]
  355.             info.text = ChannelNames[k]
  356.             info.value = k
  357.             info.checked = k == selected
  358.             info.func = Dropdown_ClickFunc
  359.             UIDropDownMenu_AddButton(info, level)
  360.         end
  361.     end
  362.     local function Dropdown_OnEnter(self)
  363.         Row_OnEnter(self:GetParent())
  364.     end
  365.     local function Dropdown_OnLeave(self)
  366.         Row_OnLeave(self:GetParent())
  367.     end
  368.  
  369.     -- Rows:
  370.     local rows = setmetatable({}, { __index = function(t, i)
  371.         local row = CreateFrame("Frame", nil, scrollChild)
  372.         row:SetHeight(40)
  373.         row:SetPoint("LEFT")
  374.         row:SetPoint("RIGHT")
  375.         if i > 1 then
  376.             row:SetPoint("TOP", t[i-1], "BOTTOM", 0, -4)
  377.         else
  378.             row:SetPoint("TOP")
  379.         end
  380.  
  381.         row:EnableMouse(true)
  382.         row:SetScript("OnEnter", Row_OnEnter)
  383.         row:SetScript("OnLeave", Row_OnLeave)
  384.  
  385.         row:EnableMouseWheel(true)
  386.         row:SetScript("OnMouseWheel", function(self, delta)
  387.             ScrollFrameTemplate_OnMouseWheel(scrollFrame, delta)
  388.         end)
  389.  
  390.         local highlight = row:CreateTexture(nil, "BACKGROUND")
  391.         highlight:SetAllPoints(true)
  392.         highlight:SetBlendMode("ADD")
  393.         highlight:SetTexture([[Interface\QuestFrame\UI-QuestLogTitleHighlight]])
  394.         highlight:SetVertexColor(0.2, 0.4, 0.8)
  395.         highlight:Hide()
  396.         row.highlight = highlight
  397.  
  398.         local delete = CreateFrame("Button", "$parentDelete"..i, row, "UIPanelCloseButton")
  399.         delete:SetPoint("LEFT", -2, -1)
  400.         delete:SetSize(32, 32)
  401.         delete:SetScript("OnClick", Delete_OnClick)
  402.         delete:SetScript("OnEnter", Delete_OnEnter)
  403.         delete:SetScript("OnLeave", GameTooltip_Hide)
  404.         row.delete = delete
  405.  
  406.         local icon = row:CreateTexture(nil, "ARTWORK")
  407.         icon:SetPoint("LEFT", delete, "RIGHT", 2, 0)
  408.         icon:SetSize(32, 32)
  409.         icon:SetTexCoord(0.1, 0.9, 0.1, 0.9)
  410.         row.icon = icon
  411.  
  412.         local name = row:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge")
  413.         name:SetPoint("LEFT", icon, "RIGHT", 8, 0)
  414.         row.name = name
  415.  
  416.         local channel = LibStub("PhanxConfig-Dropdown"):New(row, nil, nil, Dropdown_Initialize)
  417.         channel:SetPoint("RIGHT", 0, 5)
  418.         channel:SetWidth(200)
  419.         channel.OnEnter = Dropdown_OnEnter
  420.         channel.OnLeave = Dropdown_OnLeave
  421.         row.channel = channel
  422.  
  423.         t[i] = row
  424.         return row
  425.     end })
  426.     self.rows = rows
  427.  
  428.     --------------------------------------------------------------------
  429.  
  430.     -- OnShow for self:
  431.     local pool = {}
  432.     local sortedSpells = {}
  433.     local sortFunc = function(a, b)
  434.         return a.name < b.name or (a.name == b.name and a.id < b.id)
  435.     end
  436.  
  437.     function RefreshOptions()
  438.         for i = #sortedSpells, 1, -1 do
  439.             pool[tremove(sortedSpells, i)] = true
  440.         end
  441.  
  442.         for id, channel in pairs(db) do
  443.             local name, _, icon = GetSpellInfo(id)
  444.             if name and icon then
  445.                 local spell = next(pool) or {}
  446.                 pool[spell] = nil
  447.                 spell.name = name
  448.                 spell.icon = icon
  449.                 spell.id = id
  450.                 spell.channel = channel
  451.                 tinsert(sortedSpells, spell)
  452.             end
  453.         end
  454.         sort(sortedSpells, sortFunc)
  455.  
  456.         if #sortedSpells > 0 then
  457.             local height = 0
  458.             for i = 1, #sortedSpells do
  459.                 local spell = sortedSpells[i]
  460.                 local row = rows[i]
  461.                 row.id = spell.id
  462.                 row.name:SetText(spell.name)
  463.                 row.icon:SetTexture(spell.icon)
  464.                 row.channel:SetValue(spell.channel, ChannelNames[spell.channel])
  465.                 row:Show()
  466.                 height = height + 4 + row:GetHeight()
  467.             end
  468.             for i = #sortedSpells + 1, #rows do
  469.                 rows[i]:Hide()
  470.             end
  471.             scrollChild:SetHeight(height)
  472.             add:Show()
  473.         else
  474.             for i = 1, #rows do
  475.                 rows[i]:Hide()
  476.             end
  477.             scrollChild:SetHeight(100)
  478.             dialog:Show()
  479.             add:Hide()
  480.         end
  481.     end
  482.  
  483.     self:SetScript("OnShow", nil)
  484.     self.refresh = RefreshOptions
  485.     RefreshOptions()
  486. end)
  487.  
  488. f.name = GetAddOnMetadata(ADDON, "Title")
  489. InterfaceOptions_AddCategory(f)
  490.  
  491. _G["SLASH_"..ADDON.."1"] = "/notroll"
  492. SlashCmdList[ADDON] = function()
  493.     InterfaceOptionsFrame_OpenToCategory(f)
  494.     InterfaceOptionsFrame_OpenToCategory(f)
  495. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement