Advertisement
Guest User

NoTroll v5

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