View difference between Paste ID: 1HbNqCtX and QmkusGk9
SHOW: | | - or go back to the newest paste.
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-
		if channel then
60+
61-
			self:Announce(spellID, unit, channel)
61+
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-
function f:Announce(spellID, unit, channel)
69+
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-
		SendChatMessage(format(L.ANNOUNCE_MESSAGE, playerName, spellLink), channel)
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-
-- Make player names in channel messages from the addon clickable
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-
		GameTooltip:SetText(L.DELETE_SPELL_DESC, nil, nil, nil, true)
317+
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