Advertisement
Guest User

NoTroll v4

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