WoWInterface SVN NightWatch

[/] [trunk/] [NightWatch.lua] - Blame information for rev 21

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 Niightblade-44338
--
2 Niightblade-44338
-- NightWatch
3 Niightblade-44338
--
4 16 Niightblade-44338
-- A custom spell watcher/reporter by Nightyniight of Frostmourne-US.
5 2 Niightblade-44338
--
6 Niightblade-44338
-- Inspired by "tricks message" by Intermission.
7 Niightblade-44338
--
8 Niightblade-44338
--
9 Niightblade-44338
 
10 Niightblade-44338
local addon = LibStub("AceAddon-3.0"):NewAddon("NightWatch", "AceConsole-3.0", "AceEvent-3.0")
11 Niightblade-44338
local ACD = LibStub("AceConfigDialog-3.0")
12 Niightblade-44338
 
13 Niightblade-44338
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded.
14 Niightblade-44338
-- Listed here for Mikk's FindGlobals script.
15 Niightblade-44338
-- GLOBALS: LibStub
16 Niightblade-44338
 
17 18 Niightblade-44338
local _G = getfenv(0)
18 Niightblade-44338
local pairs = _G.pairs
19 Niightblade-44338
local print = _G.print
20 Niightblade-44338
local next = _G.next
21 Niightblade-44338
local format = _G.string.format
22 Niightblade-44338
local string_upper = _G.string.upper
23 Niightblade-44338
local string_gsub = _G.string.gsub
24 Niightblade-44338
local type = _G.type
25 2 Niightblade-44338
 
26 18 Niightblade-44338
local wipe = _G.wipe
27 Niightblade-44338
local SendChatMessage = _G.SendChatMessage
28 Niightblade-44338
local UnitInRaid = _G.UnitInRaid
29 Niightblade-44338
local UnitInParty = _G.UnitInParty
30 Niightblade-44338
local GetNumRaidMembers = _G.GetNumRaidMembers
31 Niightblade-44338
local GetNumPartyMembers = _G.GetNumPartyMembers
32 Niightblade-44338
local InCombatLockdown = _G.InCombatLockdown
33 Niightblade-44338
local GetSpellInfo = _G.GetSpellInfo
34 Niightblade-44338
local UnitName = _G.UnitName
35 Niightblade-44338
 
36 Niightblade-44338
 
37 10 Niightblade-44338
local addonVersion = GetAddOnMetadata("NightWatch", "Version")
38 Niightblade-44338
local dbVers = 8
39 Niightblade-44338
 
40 2 Niightblade-44338
local playerName = UnitName("player")
41 Niightblade-44338
local firstEnable = true
42 Niightblade-44338
 
43 Niightblade-44338
local db
44 Niightblade-44338
local clipboard = {}
45 8 Niightblade-44338
local sink = {}
46 Niightblade-44338
local i
47 Niightblade-44338
 
48 Niightblade-44338
for i = 1, 4 do
49 Niightblade-44338
        sink[i] = addon:NewModule("Sink" .. i , "LibSink-2.0")
50 Niightblade-44338
end
51 Niightblade-44338
 
52 2 Niightblade-44338
local function Print(msg)
53 Niightblade-44338
        print(format("|cffffff7fnw|r: %s",msg))
54 Niightblade-44338
end
55 8 Niightblade-44338
 
56 2 Niightblade-44338
function addon:defaultMsgFormat()
57 Niightblade-44338
        return {
58 21 Niightblade-44338
                chat =                  "<%C> %f %s%t",
59 2 Niightblade-44338
                chatTarget =    " on <<%t>>",
60 21 Niightblade-44338
                whisper =               "<%C> %f %s%t",
61 2 Niightblade-44338
                whisperTarget = " on YOU",
62 Niightblade-44338
        }
63 Niightblade-44338
end
64 Niightblade-44338
 
65 Niightblade-44338
local Default_Profile = {
66 Niightblade-44338
        profile = {
67 Niightblade-44338
                enabled = true,
68 Niightblade-44338
                spells = {},
69 8 Niightblade-44338
                sinkStorage = {
70 Niightblade-44338
                        [1] = { sink20OutputSink = "ChatFrame", },
71 Niightblade-44338
                        [2] = { sink20OutputSink = "None", },
72 Niightblade-44338
                        [3] = { sink20OutputSink = "None", },
73 Niightblade-44338
                        [4] = { sink20OutputSink = "None", },
74 Niightblade-44338
                },
75 2 Niightblade-44338
                customMsgFormat = addon:defaultMsgFormat(),
76 Niightblade-44338
                -- flagMap is used as a translation lookup and to help generate the default flag options for each watched spell.
77 Niightblade-44338
                flagMap = {
78 20 Niightblade-44338
                        SPELL_CAST_START = "starts casting",
79 Niightblade-44338
                        SPELL_CAST_SUCCESS = "cast",
80 Niightblade-44338
                        SPELL_CAST_FAILED = "failed casting",
81 2 Niightblade-44338
                        SPELL_RESURRECT = "resurrected",
82 20 Niightblade-44338
                        SPELL_CREATE = "creates",
83 Niightblade-44338
                        SPELL_MISSED = "missed with",
84 2 Niightblade-44338
                },
85 Niightblade-44338
        },
86 Niightblade-44338
}
87 Niightblade-44338
 
88 Niightblade-44338
function addon:flagDefaults()
89 Niightblade-44338
        local result = {}
90 Niightblade-44338
        for k,_ in pairs(db.flagMap) do
91 Niightblade-44338
                result[k] = false
92 Niightblade-44338
        end
93 Niightblade-44338
        return result
94 Niightblade-44338
end
95 8 Niightblade-44338
 
96 2 Niightblade-44338
function addon:wsDefaults()
97 Niightblade-44338
        return {
98 Niightblade-44338
                watched = true,
99 Niightblade-44338
                selfOnly = false,
100 Niightblade-44338
                groupOnly = false,
101 Niightblade-44338
                whisperTarget = false,
102 Niightblade-44338
                output1 = true,
103 Niightblade-44338
                output2 = false,
104 8 Niightblade-44338
                output3 = false,
105 Niightblade-44338
                output4 = false,
106 2 Niightblade-44338
                combatOnly = false,
107 Niightblade-44338
                anyFlag = true,
108 Niightblade-44338
                flags = addon:flagDefaults(),
109 Niightblade-44338
                msgFormat = addon:defaultMsgFormat(),
110 Niightblade-44338
        }
111 Niightblade-44338
end
112 Niightblade-44338
 
113 8 Niightblade-44338
local wantIconLinks = {
114 Niightblade-44338
        ["ChatFrame"] = true,
115 Niightblade-44338
        ["Default"] = true,
116 Niightblade-44338
        ["Blizzard Error Frame"] = true,
117 Niightblade-44338
        ["Raid Warning"] = true,
118 Niightblade-44338
}
119 Niightblade-44338
 
120 2 Niightblade-44338
local icons = {
121 Niightblade-44338
        star = "|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_1:0|t",
122 Niightblade-44338
        circle = "|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_2:0|t",
123 Niightblade-44338
        diamond = "|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_3:0|t",
124 Niightblade-44338
        triangle = "|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_4:0|t",
125 Niightblade-44338
        moon = "|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_5:0|t",
126 Niightblade-44338
        square = "|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_6:0|t",
127 Niightblade-44338
        cross = "|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_7:0|t",
128 Niightblade-44338
        skull = "|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_8:0|t",
129 Niightblade-44338
}
130 Niightblade-44338
 
131 17 Niightblade-44338
-- Borrowed from SmartRes2
132 Niightblade-44338
local resSpells = {
133 Niightblade-44338
        [(GetSpellInfo(2006))]  = true, -- Resurrection
134 Niightblade-44338
        [(GetSpellInfo(2008))]  = true, -- Ancestral Spirit
135 Niightblade-44338
        [(GetSpellInfo(7328))]  = true, -- Redemption
136 Niightblade-44338
        [(GetSpellInfo(50769))] = true, -- Revive
137 Niightblade-44338
        [(GetSpellInfo(20484))] = true, -- Rebirth
138 Niightblade-44338
        [(GetSpellInfo(8342))]  = true, -- Defibrillate (Goblin Jumper Cables)
139 Niightblade-44338
        [(GetSpellInfo(22999))] = true, -- Defibrillate (Goblin Jumper Cables XL)
140 Niightblade-44338
        [(GetSpellInfo(54732))] = true, -- Defibrillate (Gnomish Army Knife)
141 Niightblade-44338
}
142 Niightblade-44338
 
143 2 Niightblade-44338
function addon:makeOptions()
144 Niightblade-44338
        local opts = {
145 10 Niightblade-44338
                name = "NightWatch " .. addonVersion,
146 2 Niightblade-44338
                type = "group",
147 Niightblade-44338
                handler = addon,
148 Niightblade-44338
                -- inline = false,
149 Niightblade-44338
                childGroups = "tab",
150 Niightblade-44338
                args = {
151 Niightblade-44338
                        test = {
152 Niightblade-44338
                                name = "test",
153 Niightblade-44338
                                order = 0, guiHidden = true, cmdHidden = true,
154 Niightblade-44338
                                type = "execute",
155 Niightblade-44338
                                func = "test",
156 Niightblade-44338
                        },
157 Niightblade-44338
                        enable = {
158 Niightblade-44338
                                name = "Enable addon",
159 Niightblade-44338
                                order = 10, guiHidden = true,
160 Niightblade-44338
                                type = "execute",
161 Niightblade-44338
                                func = function(info) addon:Enable() end,
162 Niightblade-44338
                        },
163 Niightblade-44338
                        enabled = {
164 Niightblade-44338
                                name = "Enabled",
165 Niightblade-44338
                                order = 20, cmdHidden = true,
166 Niightblade-44338
                                type = "toggle",
167 Niightblade-44338
                                get = function(info) return db[info[#info]] end,
168 8 Niightblade-44338
                                set = function(info, value)
169 Niightblade-44338
                                        if value then
170 Niightblade-44338
                                                addon:Enable()
171 Niightblade-44338
                                        else
172 Niightblade-44338
                                                addon:Disable()
173 2 Niightblade-44338
                                        end
174 Niightblade-44338
                                end,
175 Niightblade-44338
                        },
176 Niightblade-44338
                        reset = {
177 Niightblade-44338
                                name = "Reset Profile",
178 Niightblade-44338
                                desc = "Reset *all* profile settings to default values.",
179 Niightblade-44338
                                order = 30, -- width = "half",
180 Niightblade-44338
                                type = "execute",
181 Niightblade-44338
                                func = "resetSettings",
182 Niightblade-44338
                                confirm = true,
183 Niightblade-44338
                                confirmText = "This action is permanent.  Are you sure?",
184 Niightblade-44338
                        },
185 Niightblade-44338
                        disable = {
186 Niightblade-44338
                                name = "Disable addon",
187 Niightblade-44338
                                order = 40, guiHidden = true,
188 Niightblade-44338
                                type = "execute",
189 Niightblade-44338
                                func = function(info) addon:Disable() end,
190 Niightblade-44338
                        },
191 Niightblade-44338
                        config = {
192 Niightblade-44338
                                name = "Toggle config",
193 Niightblade-44338
                                order = 50, guiHidden = true,
194 Niightblade-44338
                                type = "execute",
195 Niightblade-44338
                                func = "openConfig"
196 Niightblade-44338
                        },
197 Niightblade-44338
                },
198 Niightblade-44338
        }
199 8 Niightblade-44338
 
200 2 Niightblade-44338
        opts.args.spell = {
201 Niightblade-44338
                name = "Spell Options",
202 Niightblade-44338
                order = 10,
203 Niightblade-44338
                type = "group",
204 Niightblade-44338
                handler = addon,
205 Niightblade-44338
                cmdHidden = true,
206 Niightblade-44338
                childGroups = "tab",
207 Niightblade-44338
                args = {
208 Niightblade-44338
                        selectedSpell = {
209 Niightblade-44338
                                name = "Selected Spell",
210 Niightblade-44338
                                order = 10,
211 Niightblade-44338
                                type = "select",
212 Niightblade-44338
                                values = function() return addon:convertLookup(db.spells) end,
213 Niightblade-44338
                                get = function() return db.selSpell end,
214 Niightblade-44338
                                set = function(_, value) db.selSpell = value end,
215 Niightblade-44338
                        },
216 Niightblade-44338
                        deleteSpell = {
217 Niightblade-44338
                                name = "Delete",
218 Niightblade-44338
                                desc = "Delete selected spell.",
219 Niightblade-44338
                                order = 20, width = "half",  cmdHidden = true,
220 Niightblade-44338
                                type = "execute",
221 Niightblade-44338
                                func =  "deleteSpell",
222 Niightblade-44338
                                confirm = true,
223 Niightblade-44338
                                confirmText = "This action is permanent.  Are you sure?",
224 Niightblade-44338
                        },
225 Niightblade-44338
                        addSpell = {
226 Niightblade-44338
                                name = "Add New Spell",
227 Niightblade-44338
                                desc = "Add a new spell.",
228 Niightblade-44338
                                order = 30, cmdHidden = true, -- width = "half",
229 Niightblade-44338
                                type = "input",
230 Niightblade-44338
                                get = function() return nil end,
231 Niightblade-44338
                                set = "addSpell",
232 Niightblade-44338
                                validate = function(info, value)
233 Niightblade-44338
                                        if value:len() < 3 then
234 Niightblade-44338
                                                return "Must be at least 3 characters long."
235 Niightblade-44338
                                        end
236 Niightblade-44338
                                        return true
237 Niightblade-44338
                                end,
238 Niightblade-44338
                        },
239 Niightblade-44338
                },
240 Niightblade-44338
        }
241 8 Niightblade-44338
 
242 2 Niightblade-44338
        opts.args.spell.args.general = {
243 Niightblade-44338
                name = "General",
244 Niightblade-44338
                order = 10,
245 Niightblade-44338
                type = "group",
246 Niightblade-44338
                cmdHidden = true, width = "half",
247 Niightblade-44338
                handler = addon,
248 Niightblade-44338
                get = "getterFunc",
249 Niightblade-44338
                set = "setterFunc",
250 Niightblade-44338
                disabled = function() return not db.selSpell end,
251 Niightblade-44338
                args = {
252 Niightblade-44338
                        watched = {
253 Niightblade-44338
                                name = "Watch",
254 Niightblade-44338
                                desc = "Watch this spell.",
255 Niightblade-44338
                                order = 10,
256 Niightblade-44338
                                type = "toggle",
257 Niightblade-44338
                        },
258 Niightblade-44338
                        head1 = {
259 Niightblade-44338
                                name = "",
260 Niightblade-44338
                                order = 20,
261 Niightblade-44338
                                type = "header",
262 Niightblade-44338
                        },
263 Niightblade-44338
                        selfOnly = {
264 Niightblade-44338
                                name = "Self Only",
265 Niightblade-44338
                                desc = "Only announce when YOU cast this spell.",
266 Niightblade-44338
                                order = 30,
267 Niightblade-44338
                                type = "toggle",
268 Niightblade-44338
                        },
269 Niightblade-44338
                        groupOnly = {
270 Niightblade-44338
                                name = "Group Only",
271 Niightblade-44338
                                desc = "Only announce spells cast by persons in your raid/party.",
272 Niightblade-44338
                                order = 40,
273 Niightblade-44338
                                type = "toggle",
274 Niightblade-44338
                        },
275 Niightblade-44338
                        combatOnly = {
276 Niightblade-44338
                                name = "Combat Only",
277 Niightblade-44338
                                desc = "Only announce when you are in combat.",
278 Niightblade-44338
                                order = 50,
279 Niightblade-44338
                                type = "toggle",
280 Niightblade-44338
                        },
281 Niightblade-44338
                        whisperTarget = {
282 Niightblade-44338
                                name = "Whisper Target",
283 Niightblade-44338
                                desc = "Whisper the target of spell, if applicable.",
284 Niightblade-44338
                                order = 60,
285 Niightblade-44338
                                type = "toggle",
286 Niightblade-44338
                        },
287 Niightblade-44338
                        flags = {
288 Niightblade-44338
                                name = "Combatlog Flags",
289 Niightblade-44338
                                order = 90,
290 Niightblade-44338
                                type = "multiselect",
291 Niightblade-44338
                                values = function() return addon:convertLookup(db.flagMap) end,
292 Niightblade-44338
                                get = "getFlag",
293 Niightblade-44338
                                set = "setFlag",
294 Niightblade-44338
                                disabled = function() return (not db.selSpell) or addon:isAnyFlag() end,
295 Niightblade-44338
                        },
296 Niightblade-44338
                        all = {
297 Niightblade-44338
                                name = "All",
298 Niightblade-44338
                                desc = "Set all flags.",
299 Niightblade-44338
                                order = 100, width = "half",
300 Niightblade-44338
                                type = "execute",
301 Niightblade-44338
                                func =  function(info,key) addon:setAllFlagsTo(info, true) end,
302 Niightblade-44338
                                disabled = "isAnyFlag",
303 Niightblade-44338
                        },
304 Niightblade-44338
                        none = {
305 Niightblade-44338
                                name = "None",
306 Niightblade-44338
                                desc = "Clear all flags.",
307 Niightblade-44338
                                order = 110, width = "half",
308 Niightblade-44338
                                type = "execute",
309 Niightblade-44338
                                func =  function(info,key) addon:setAllFlagsTo(info, false) end,
310 Niightblade-44338
                                disabled = "isAnyFlag",
311 Niightblade-44338
                        },
312 Niightblade-44338
                        anyFlag = {
313 Niightblade-44338
                                name = "Any flag",
314 Niightblade-44338
                                desc = "Announce on ANY flag (not just the ones listed).",
315 Niightblade-44338
                                order = 120,
316 Niightblade-44338
                                type = "toggle",
317 Niightblade-44338
                        },
318 Niightblade-44338
                },
319 Niightblade-44338
        }
320 Niightblade-44338
 
321 8 Niightblade-44338
        for i = 1,4 do
322 Niightblade-44338
                opts.args.spell.args.general.args["output" .. i] = {
323 Niightblade-44338
                                name = "Output " .. i,
324 Niightblade-44338
                                desc = "Send output here.",
325 Niightblade-44338
                                order = 70 + 1,
326 Niightblade-44338
                                type = "toggle",
327 Niightblade-44338
                        }
328 Niightblade-44338
        end
329 Niightblade-44338
 
330 2 Niightblade-44338
        opts.args.spell.args.msgFormat = {
331 Niightblade-44338
                name = "Message Format",
332 Niightblade-44338
                type = "group",
333 Niightblade-44338
                order = 20,
334 Niightblade-44338
                cmdHidden = true,
335 Niightblade-44338
                handler = addon,
336 Niightblade-44338
                get = "mfGetterFunc",
337 Niightblade-44338
                set = "mfSetterFunc",
338 Niightblade-44338
                disabled = function() return not db.selSpell end,
339 Niightblade-44338
                args = {
340 Niightblade-44338
                        chat = {
341 Niightblade-44338
                                name = "Chat Format",
342 Niightblade-44338
                                desc = "Define chat format.",
343 Niightblade-44338
                                order = 10, width = "double",
344 Niightblade-44338
                                type = "input",
345 Niightblade-44338
                        },
346 Niightblade-44338
                        chatTarget = {
347 Niightblade-44338
                                name = "Chat Target Format",
348 Niightblade-44338
                                desc = "If set, this will replace %t if there is a target.",
349 Niightblade-44338
                                order = 20,
350 Niightblade-44338
                                type = "input",
351 Niightblade-44338
                        },
352 Niightblade-44338
                        chatTest = {
353 6 Niightblade-44338
                                name = function() return addon:chatTest() end,
354 2 Niightblade-44338
                                order = 25,
355 Niightblade-44338
                                type = "description",
356 Niightblade-44338
                        },
357 Niightblade-44338
                        whisper = {
358 Niightblade-44338
                                name = "Whisper Format",
359 Niightblade-44338
                                desc = "Define whisper format.",
360 Niightblade-44338
                                order = 30, width = "double",
361 Niightblade-44338
                                type = "input",
362 Niightblade-44338
                        },
363 Niightblade-44338
                        whisperTarget = {
364 Niightblade-44338
                                name = "Whisper Target Format",
365 Niightblade-44338
                                desc = "If set, this will replace %t if there is a target.",
366 Niightblade-44338
                                order = 40,
367 Niightblade-44338
                                type = "input",
368 8 Niightblade-44338
                        },
369 2 Niightblade-44338
                        whisperTest = {
370 6 Niightblade-44338
                                name = function() return addon:whisperTest() end,
371 2 Niightblade-44338
                                order = 60,
372 Niightblade-44338
                                type = "description",
373 Niightblade-44338
                        },
374 Niightblade-44338
                        -- head1 = {
375 Niightblade-44338
                                -- name = '',
376 Niightblade-44338
                                -- order = 70,
377 Niightblade-44338
                                -- type = "header",
378 Niightblade-44338
                        -- },
379 Niightblade-44338
                        setDefaultFmt = {
380 6 Niightblade-44338
                                name = "Set As Default",
381 2 Niightblade-44338
                                desc = "Make these formats the default for new spells.",
382 Niightblade-44338
                                order = 100, -- width = "half",
383 Niightblade-44338
                                type = "execute",
384 6 Niightblade-44338
                                func = function()
385 Niightblade-44338
                                        if not db.selSpell then return end
386 2 Niightblade-44338
                                        db.customMsgFormat.chat = db.spells[db.selSpell].msgFormat.chat
387 Niightblade-44338
                                        db.customMsgFormat.chatTarget = db.spells[db.selSpell].msgFormat.chatTarget
388 Niightblade-44338
                                end,
389 Niightblade-44338
                        },
390 Niightblade-44338
                        copyFmt = {
391 6 Niightblade-44338
                                name = "Copy",
392 2 Niightblade-44338
                                desc = "Copy these formats.",
393 Niightblade-44338
                                order = 110, width = "half",
394 Niightblade-44338
                                type = "execute",
395 6 Niightblade-44338
                                func = function() addon:copyFmt(db.selSpell) end,
396 2 Niightblade-44338
                        },
397 Niightblade-44338
                        pasteFmt = {
398 6 Niightblade-44338
                                name = "Paste",
399 2 Niightblade-44338
                                desc = "Paste formats.",
400 Niightblade-44338
                                order = 120, width = "half",
401 Niightblade-44338
                                type = "execute",
402 6 Niightblade-44338
                                func = function() addon:pasteFmt(db.selSpell) end,
403 2 Niightblade-44338
                        },
404 6 Niightblade-44338
                        setFmtToAll = {
405 Niightblade-44338
                                name = "Set All",
406 Niightblade-44338
                                desc = "Sets these formats for all spells",
407 Niightblade-44338
                                order = 130, width = "half",
408 2 Niightblade-44338
                                type = "execute",
409 6 Niightblade-44338
                                func = function() addon:setFmtToAll(db.selSpell) end,
410 2 Niightblade-44338
                        },
411 6 Niightblade-44338
                        resetFmtToDefault = {
412 Niightblade-44338
                                name = "Reset",
413 Niightblade-44338
                                desc = "Resets these formats to program defaults.",
414 Niightblade-44338
                                order = 140, width = "half",
415 Niightblade-44338
                                type = "execute",
416 Niightblade-44338
                                func = function() addon:resetFmtToDefault(db.selSpell) end,
417 8 Niightblade-44338
                        },
418 2 Niightblade-44338
                        formatHelp = {
419 Niightblade-44338
                                name =  "\n** Format Syntax **\n" ..
420 Niightblade-44338
                                                "%c = Caster\n" ..
421 Niightblade-44338
                                                "%s = Spell\n" ..
422 Niightblade-44338
                                                "%t = Target\n" ..
423 Niightblade-44338
                                                "%f = Flags\n" ..
424 Niightblade-44338
                                                "For UPPERCASE text, use an uppercase placeholder.",
425 Niightblade-44338
                                order = 150,
426 Niightblade-44338
                                type = "description",
427 Niightblade-44338
                        },
428 Niightblade-44338
                },
429 Niightblade-44338
        }
430 Niightblade-44338
 
431 Niightblade-44338
        opts.args.output = {
432 8 Niightblade-44338
                name = "Outputs",
433 2 Niightblade-44338
                desc = "Configure output options.",
434 Niightblade-44338
                type = "group",
435 Niightblade-44338
                order = 30,
436 Niightblade-44338
                cmdHidden = true,
437 Niightblade-44338
                args = {}
438 Niightblade-44338
        }
439 Niightblade-44338
 
440 8 Niightblade-44338
        local sinkOpts = {}
441 Niightblade-44338
        for i = 1, #sink do
442 Niightblade-44338
                sinkOpts[i] = sink[i]:GetSinkAce3OptionsDataTable()
443 Niightblade-44338
                sinkOpts[i].name = "Output " .. i
444 Niightblade-44338
                sinkOpts[i].desc = "Where to send this output."
445 Niightblade-44338
                sinkOpts[i].order = 10 + i
446 Niightblade-44338
                -- sinkOpts[i].inline = true
447 Niightblade-44338
                opts.args.output.args["output" .. i] = sinkOpts[i]
448 Niightblade-44338
        end
449 2 Niightblade-44338
 
450 Niightblade-44338
        opts.args.flagOptions = {
451 Niightblade-44338
                name = "Flag Options",
452 Niightblade-44338
                desc = "Configure flag options.",
453 Niightblade-44338
                type = "group",
454 Niightblade-44338
                order = 700,
455 Niightblade-44338
                cmdHidden = true,
456 Niightblade-44338
                args = {
457 Niightblade-44338
                        selectedFlag = {
458 Niightblade-44338
                                name = "Selected Flag",
459 Niightblade-44338
                                order = 10,
460 Niightblade-44338
                                type = "select",
461 Niightblade-44338
                                values = function() return addon:convertLookup(db.flagMap) end,
462 Niightblade-44338
                                get = function() return db.selFlag end,
463 Niightblade-44338
                                set = function(_, value) db.selFlag = value end,
464 Niightblade-44338
                        },
465 Niightblade-44338
                        translation = {
466 Niightblade-44338
                                name = "Translation",
467 Niightblade-44338
                                desc = "Friendly text for this flag.",
468 Niightblade-44338
                                order = 20,
469 Niightblade-44338
                                type = "input",
470 Niightblade-44338
                                get = function() return db.flagMap[db.selFlag] or '' end,
471 Niightblade-44338
                                set = function(_, value) db.flagMap[db.selFlag] = value end,
472 Niightblade-44338
                        },
473 Niightblade-44338
                        head1 = {
474 Niightblade-44338
                                name = "",
475 Niightblade-44338
                                order = 40,
476 Niightblade-44338
                                type = "header",
477 Niightblade-44338
                        },
478 Niightblade-44338
                        deleteFlag = {
479 Niightblade-44338
                                name = "Delete Flag",
480 Niightblade-44338
                                desc = "Delete selected flag.",
481 Niightblade-44338
                                order = 75, -- width = "half",
482 Niightblade-44338
                                type = "execute",
483 Niightblade-44338
                                func =  function()
484 Niightblade-44338
                                        db.flagMap[db.selFlag] = nil
485 Niightblade-44338
                                        LibStub("AceConfigRegistry-3.0"):NotifyChange("NightWatch")
486 Niightblade-44338
                                        end,
487 Niightblade-44338
                                confirm = true,
488 Niightblade-44338
                                confirmText = "This action is permanent.  Are you sure?",
489 Niightblade-44338
                        },
490 Niightblade-44338
                        addFlag = {
491 Niightblade-44338
                                name = "Add New Flag",
492 Niightblade-44338
                                desc = "Add a new flag.",
493 Niightblade-44338
                                order = 80,
494 Niightblade-44338
                                type = "input",
495 Niightblade-44338
                                get = function() return nil end,
496 8 Niightblade-44338
                                set = function(_, value)
497 2 Niightblade-44338
                                        db.flagMap[value] = value
498 Niightblade-44338
                                        LibStub("AceConfigRegistry-3.0"):NotifyChange("NightWatch")
499 Niightblade-44338
                                end,
500 Niightblade-44338
                                validate = function(info, value)
501 Niightblade-44338
                                        if value:len() < 3 then
502 Niightblade-44338
                                                return "Must be at least 3 characters long."
503 Niightblade-44338
                                        end
504 Niightblade-44338
                                        return true
505 Niightblade-44338
                                end,
506 Niightblade-44338
                        },
507 Niightblade-44338
                },
508 Niightblade-44338
        }
509 Niightblade-44338
 
510 8 Niightblade-44338
 
511 2 Niightblade-44338
        opts.args.profile = LibStub("AceDBOptions-3.0"):GetOptionsTable(addon.db)
512 Niightblade-44338
        opts.args.profile.order = -10
513 Niightblade-44338
 
514 Niightblade-44338
        return opts
515 Niightblade-44338
end
516 Niightblade-44338
 
517 Niightblade-44338
function addon:OnInitialize()
518 Niightblade-44338
    addon.db = LibStub("AceDB-3.0"):New("NightWatchDB", Default_Profile, "Default")
519 Niightblade-44338
        db = addon.db.profile
520 Niightblade-44338
 
521 16 Niightblade-44338
--      addon.db.RegisterCallback( self, "OnNewProfile", "profileChanged" )             -- OnProfileChanged seems to cover new profiles too.
522 Niightblade-44338
        addon.db.RegisterCallback( self, "OnProfileReset", "profileChanged" )
523 Niightblade-44338
        addon.db.RegisterCallback( self, "OnProfileChanged", "profileChanged" )
524 Niightblade-44338
        addon.db.RegisterCallback( self, "OnProfileCopied", "profileChanged" )
525 2 Niightblade-44338
 
526 Niightblade-44338
        LibStub("AceConfig-3.0"):RegisterOptionsTable("NightWatch", addon:makeOptions())
527 Niightblade-44338
        LibStub("AceConfigDialog-3.0"):AddToBlizOptions("NightWatch", "NightWatch")
528 Niightblade-44338
    addon:RegisterChatCommand("nw", "chatCommand")
529 Niightblade-44338
    addon:RegisterChatCommand("nightwatch", "chatCommand")
530 Niightblade-44338
 
531 16 Niightblade-44338
        addon:profileChanged()
532 2 Niightblade-44338
end
533 Niightblade-44338
 
534 Niightblade-44338
 
535 Niightblade-44338
function addon:OnEnable()
536 Niightblade-44338
        addon:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED", "combatLogEvent")
537 Niightblade-44338
        db.enabled = true
538 Niightblade-44338
        if not firstEnable then
539 Niightblade-44338
                Print("enabled")
540 Niightblade-44338
        else
541 Niightblade-44338
                firstEnable = false
542 Niightblade-44338
        end
543 Niightblade-44338
end
544 Niightblade-44338
 
545 Niightblade-44338
function addon:OnDisable()
546 Niightblade-44338
        addon:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
547 Niightblade-44338
        db.enabled = false
548 Niightblade-44338
        Print("disabled")
549 Niightblade-44338
end
550 Niightblade-44338
 
551 Niightblade-44338
function addon:chatCommand(input)
552 Niightblade-44338
    if not input or input:trim() == "" then
553 Niightblade-44338
        addon:openConfig()
554 Niightblade-44338
                return
555 Niightblade-44338
        end
556 Niightblade-44338
    if input == "help" then
557 Niightblade-44338
                input = ""
558 Niightblade-44338
        end
559 Niightblade-44338
        LibStub("AceConfigCmd-3.0").HandleCommand(addon, "nw", "NightWatch", input)
560 Niightblade-44338
end
561 Niightblade-44338
 
562 Niightblade-44338
-------------------------------------------------------------------------------
563 Niightblade-44338
-- 0 1          2      3        4        5         6        7        8         9        10         11           12
564 Niightblade-44338
-- _,timestamp, event, srcGUID, srcName, srcFlags, dstGUID, dstName, dstFlags, spellID, spellName, spellSchool, missType, ...)
565 Niightblade-44338
--
566 17 Niightblade-44338
local flag, source, target, spell
567 Niightblade-44338
local msg, whisperTarget
568 2 Niightblade-44338
function addon:combatLogEvent(_, _, flag, _, source, _, _, target, _, _, spell, ...)
569 17 Niightblade-44338
--                              0  1  2     3  4       5  6   7       8  9  10
570 2 Niightblade-44338
 
571 10 Niightblade-44338
        if not db.spells[spell] then return end                                                                 -- Spell not in database, quit
572 8 Niightblade-44338
 
573 2 Niightblade-44338
        local ws = db.spells[spell]
574 Niightblade-44338
 
575 Niightblade-44338
        if not ws.watched then return end                                                                                       -- Not being watched, quit
576 8 Niightblade-44338
 
577 2 Niightblade-44338
        if not (ws.anyFlag or ws.flags[flag]) then return end                                   -- Doesn't match flags, quit
578 Niightblade-44338
 
579 Niightblade-44338
        if ws.selfOnly and not (source == playerName) then return end                   -- Check for self-cast only
580 Niightblade-44338
 
581 Niightblade-44338
        if ws.combatOnly and not InCombatLockdown() then return end                             -- Check for self in combat
582 8 Niightblade-44338
 
583 2 Niightblade-44338
        if ws.groupOnly and not (UnitInRaid(source) or UnitInParty(source)) then return end     -- Check for source in raid/party
584 8 Niightblade-44338
 
585 2 Niightblade-44338
        if db.flagMap[flag] then                                                                                                        -- Convert flag to more friendly version, if available.
586 Niightblade-44338
                flag = db.flagMap[flag]
587 Niightblade-44338
        end
588 8 Niightblade-44338
 
589 19 Niightblade-44338
        if resSpells[spell] and not target then                         -- Partial fix for res spell target not showing in combatlog.  gg bliz.
590 Niightblade-44338
                target = UnitName(source .. "-target") or nil
591 17 Niightblade-44338
        end
592 Niightblade-44338
 
593 2 Niightblade-44338
        if target then
594 Niightblade-44338
                if ws.whisperTarget then                                                                                                -- Whisper target
595 Niightblade-44338
                        if ws.msgFormat.whisperTarget then
596 Niightblade-44338
                                whisperTarget = addon:formatMsg(nil, nil, target, nil, ws.msgFormat.whisperTarget)
597 Niightblade-44338
                        end
598 Niightblade-44338
                        SendChatMessage(addon:formatMsg(source, spell, whisperTarget, flag, ws.msgFormat.whisper), "WHISPER", nil, target)
599 Niightblade-44338
                end
600 Niightblade-44338
                target = addon:formatMsg(nil, nil, target, nil, ws.msgFormat.chatTarget)
601 Niightblade-44338
        end
602 Niightblade-44338
 
603 17 Niightblade-44338
        msg = addon:formatMsg(source, spell, target, flag, ws.msgFormat.chat)           -- Format message
604 8 Niightblade-44338
 
605 Niightblade-44338
        for i = 1, #sink do
606 17 Niightblade-44338
                if ws["output" .. i] then                                                                                               -- Send message to output(s)
607 8 Niightblade-44338
                        if wantIconLinks[db.sinkStorage[i].sink20OutputSink] then
608 Niightblade-44338
                                msg = addon:mkIconLinks(msg)
609 Niightblade-44338
                        end
610 Niightblade-44338
                        addon:pour(sink[i], msg)
611 2 Niightblade-44338
                end
612 Niightblade-44338
        end
613 Niightblade-44338
 
614 Niightblade-44338
end
615 Niightblade-44338
 
616 Niightblade-44338
-------------------------------------------------------------------------------
617 Niightblade-44338
 
618 16 Niightblade-44338
function addon:profileChanged()
619 2 Niightblade-44338
        db = addon.db.profile
620 16 Niightblade-44338
        for i = 1, #sink do
621 Niightblade-44338
                sink[i]:SetSinkStorage(db.sinkStorage[i])
622 Niightblade-44338
        end     addon:dbUpgrade()
623 2 Niightblade-44338
        addon:resetSelected()
624 Niightblade-44338
end
625 Niightblade-44338
 
626 15 Niightblade-44338
function addon:dbUpgrade()
627 16 Niightblade-44338
        if db.dbVers and db.dbVers > 7 then return end                                                  -- DB Already upgraded
628 10 Niightblade-44338
 
629 Niightblade-44338
        -- Upgrade data format from previous addon versions (=<0.6)
630 Niightblade-44338
        -- (Renamed db.spell to db.spells just to torture myself.
631 Niightblade-44338
        -- Also moved away from AceDB's magic ['*'] feature since it was
632 Niightblade-44338
        -- auto-creating spells everty time I checked the spell was in the db.
633 Niightblade-44338
        -- Sigh.)
634 Niightblade-44338
        if db.spell then
635 Niightblade-44338
                Print("Upgrading database")
636 Niightblade-44338
                db.spells = addon:deepcopy(db.spell)                                                                    -- Quick and dirty ...
637 Niightblade-44338
                db.spell = nil
638 Niightblade-44338
                db.selected = nil
639 Niightblade-44338
                Print("Upgrade complete")
640 9 Niightblade-44338
        end
641 10 Niightblade-44338
 
642 Niightblade-44338
        -- Remove obsolete sink data from previous addon versions (=<0.7)
643 Niightblade-44338
        for i = 1, 4 do
644 Niightblade-44338
                if db["sinkStorage" .. i] then
645 Niightblade-44338
                        db.sinkStorage[i] = db["sinkStorage" .. i]
646 Niightblade-44338
                        db["sinkStorage" .. i] = nil
647 2 Niightblade-44338
                end
648 Niightblade-44338
        end
649 10 Niightblade-44338
 
650 Niightblade-44338
        db.dbVers = dbVers
651 2 Niightblade-44338
end
652 Niightblade-44338
 
653 Niightblade-44338
function addon:resetSelected()
654 Niightblade-44338
        if not db.selSpell or not db.spells[db.selSpell] or db.spells[db.selSpell] == "" then
655 Niightblade-44338
                db.selSpell = (next(db.spells) or nil)
656 Niightblade-44338
        end
657 Niightblade-44338
end
658 Niightblade-44338
 
659 Niightblade-44338
function addon:openConfig()
660 Niightblade-44338
        ACD[ACD.OpenFrames.NightWatch and "Close" or "Open"](ACD,"NightWatch")
661 Niightblade-44338
end
662 Niightblade-44338
 
663 8 Niightblade-44338
function addon:resetSettings()
664 2 Niightblade-44338
        addon.db:ResetProfile()
665 Niightblade-44338
        Print("All settings in this profile have been reset to default values.")
666 Niightblade-44338
end
667 Niightblade-44338
 
668 Niightblade-44338
function addon:getterFunc(info)
669 Niightblade-44338
        if not db.selSpell then return nil end
670 Niightblade-44338
        return db.spells[db.selSpell][info[#info]]
671 Niightblade-44338
end
672 Niightblade-44338
 
673 Niightblade-44338
function addon:setterFunc(info, value)
674 Niightblade-44338
        if not db.selSpell then return end
675 Niightblade-44338
        db.spells[db.selSpell][info[#info]] = value
676 Niightblade-44338
end
677 Niightblade-44338
 
678 Niightblade-44338
function addon:test()
679 Niightblade-44338
        Print("Adding test spells.")
680 Niightblade-44338
        addon:addSpell(nil, "Hearthstone")
681 Niightblade-44338
        addon:addSpell(nil, "Using Direbrew's Remote")
682 Niightblade-44338
        addon:addSpell(nil, "Toy Train Set")
683 Niightblade-44338
        addon:addSpell(nil, "Rebirth")
684 Niightblade-44338
        addon:addSpell(nil, "Tricks of the Trade")
685 Niightblade-44338
        addon:addSpell(nil, "Misdirection")
686 Niightblade-44338
        LibStub("AceConfigRegistry-3.0"):NotifyChange("NightWatch")
687 Niightblade-44338
end
688 Niightblade-44338
 
689 8 Niightblade-44338
function addon:addSpell(info, value)
690 2 Niightblade-44338
        db.spells[value] = addon:wsDefaults()
691 Niightblade-44338
        -- db.spells[value].watched = true
692 Niightblade-44338
        db.spells[value].msgFormat = addon:deepcopy(db.customMsgFormat)
693 Niightblade-44338
        db.selSpell = value
694 Niightblade-44338
end
695 Niightblade-44338
 
696 Niightblade-44338
function addon:deleteSpell()
697 Niightblade-44338
        if not db.selSpell then return end
698 Niightblade-44338
        wipe(db.spells[db.selSpell])
699 Niightblade-44338
        db.spells[db.selSpell] = nil
700 Niightblade-44338
        addon:resetSelected()
701 Niightblade-44338
end
702 Niightblade-44338
 
703 Niightblade-44338
function addon:getFlag(info, key)
704 Niightblade-44338
        if not db.selSpell then return nil end
705 Niightblade-44338
        return db.spells[db.selSpell].flags[key]
706 Niightblade-44338
end
707 Niightblade-44338
 
708 Niightblade-44338
function addon:setFlag(info, key, value)
709 Niightblade-44338
        if not db.selSpell then return nil end
710 Niightblade-44338
        db.spells[db.selSpell].flags[key] = value
711 Niightblade-44338
end
712 Niightblade-44338
 
713 Niightblade-44338
function addon:isAnyFlag()
714 Niightblade-44338
        if not db.selSpell then return nil end
715 Niightblade-44338
        return db.spells[db.selSpell].anyFlag
716 Niightblade-44338
end
717 Niightblade-44338
 
718 Niightblade-44338
function addon:setAllFlagsTo(info, value)
719 Niightblade-44338
        if not db.selSpell then return end
720 Niightblade-44338
        for k in pairs(db.spells[db.selSpell].flags) do
721 Niightblade-44338
                db.spells[db.selSpell].flags[k] = value
722 Niightblade-44338
        end
723 Niightblade-44338
end
724 Niightblade-44338
 
725 Niightblade-44338
function addon:mfGetterFunc(info)
726 Niightblade-44338
        if not db.selSpell then return nil end
727 Niightblade-44338
        return db.spells[db.selSpell][info[#info-1]][info[#info]]
728 Niightblade-44338
end
729 Niightblade-44338
 
730 Niightblade-44338
function addon:mfSetterFunc(info, value)
731 Niightblade-44338
        if not db.selSpell then return nil end
732 Niightblade-44338
        db.spells[db.selSpell][info[#info-1]][info[#info]] = value
733 Niightblade-44338
end
734 Niightblade-44338
 
735 Niightblade-44338
function addon:chatTest()
736 Niightblade-44338
        if not db.selSpell then return nil end
737 Niightblade-44338
        return addon:testMsg(
738 8 Niightblade-44338
                        db.spells[db.selSpell].msgFormat.chat,
739 2 Niightblade-44338
                        db.spells[db.selSpell].msgFormat.chatTarget
740 8 Niightblade-44338
                )
741 2 Niightblade-44338
end
742 Niightblade-44338
 
743 Niightblade-44338
function addon:whisperTest()
744 Niightblade-44338
        if not db.selSpell then return nil end
745 Niightblade-44338
        return addon:testMsg(
746 8 Niightblade-44338
                        db.spells[db.selSpell].msgFormat.whisper,
747 2 Niightblade-44338
                        db.spells[db.selSpell].msgFormat.whisperTarget
748 8 Niightblade-44338
                )
749 2 Niightblade-44338
end
750 8 Niightblade-44338
 
751 2 Niightblade-44338
 function addon:testMsg(formatString, targetFormatString)
752 Niightblade-44338
        local source, spell, target, flag = "Caster", db.selSpell or "Spell", "Target", "Flag"
753 Niightblade-44338
        if not (targetFormatString == "" or targetFormatString == nil) then
754 Niightblade-44338
                target = addon:formatMsg(nil, nil, target, nil, targetFormatString)
755 Niightblade-44338
        end
756 Niightblade-44338
        return addon:mkIconLinks(addon:formatMsg(source, spell, target, flag, formatString))
757 Niightblade-44338
end
758 Niightblade-44338
 
759 Niightblade-44338
function addon:formatMsg(caster, spell, target, flag, formatString)
760 Niightblade-44338
        if not formatString then return "" end
761 Niightblade-44338
        local msg = formatString
762 Niightblade-44338
        if not caster then caster = '' end
763 Niightblade-44338
        if not spell then spell = '' end
764 Niightblade-44338
        if not target then target = '' end
765 Niightblade-44338
        if not flag then flag = '' end
766 Niightblade-44338
        msg = string_gsub(msg, "%%c", caster)
767 Niightblade-44338
        msg = string_gsub(msg, "%%C", string_upper(caster))
768 Niightblade-44338
        msg = string_gsub(msg, "%%t", target)
769 Niightblade-44338
        msg = string_gsub(msg, "%%T", string_upper(target))
770 Niightblade-44338
        msg = string_gsub(msg, "%%s", spell)
771 Niightblade-44338
        msg = string_gsub(msg, "%%S", string_upper(spell))
772 Niightblade-44338
        msg = string_gsub(msg, "%%f", flag)
773 Niightblade-44338
        msg = string_gsub(msg, "%%F", string_upper(flag))
774 Niightblade-44338
        return msg
775 Niightblade-44338
end
776 Niightblade-44338
 
777 Niightblade-44338
function addon:mkIconLinks(msg)
778 Niightblade-44338
        if not msg then return "" end
779 Niightblade-44338
        for k,v in pairs(icons) do
780 Niightblade-44338
                msg = string_gsub(msg, "{" .. k .."}", v)
781 Niightblade-44338
        end
782 Niightblade-44338
        return msg
783 Niightblade-44338
end
784 Niightblade-44338
 
785 6 Niightblade-44338
function addon:copyFmt(value)
786 Niightblade-44338
        if not value then return end
787 Niightblade-44338
        clipboard.fmt = addon:deepcopy(db.spells[value].msgFormat)
788 2 Niightblade-44338
end
789 Niightblade-44338
 
790 6 Niightblade-44338
function addon:pasteFmt(value)
791 Niightblade-44338
        if not value then return end
792 Niightblade-44338
        db.spells[value].msgFormat = addon:deepcopy(clipboard.fmt)
793 2 Niightblade-44338
end
794 Niightblade-44338
 
795 6 Niightblade-44338
function addon:setFmtToAll(value)
796 Niightblade-44338
        if not value then return end
797 Niightblade-44338
        addon:copyFmt(value)
798 Niightblade-44338
        for k,_ in pairs(db.spells) do
799 Niightblade-44338
                addon:pasteFmt(k)
800 Niightblade-44338
        end
801 8 Niightblade-44338
end
802 2 Niightblade-44338
 
803 6 Niightblade-44338
function addon:resetFmtToDefault(value)
804 Niightblade-44338
        if not value then return end
805 Niightblade-44338
        db.spells[value].msgFormat = addon:defaultMsgFormat()
806 Niightblade-44338
end
807 Niightblade-44338
 
808 2 Niightblade-44338
-- From Recount
809 Niightblade-44338
function addon:deepcopy(object)
810 Niightblade-44338
        local lookup_table = {}
811 Niightblade-44338
        local function _copy(object)
812 Niightblade-44338
                if type(object) ~= "table" then
813 Niightblade-44338
                        return object
814 Niightblade-44338
                elseif lookup_table[object] then
815 Niightblade-44338
                        return lookup_table[object]
816 Niightblade-44338
                end
817 Niightblade-44338
                local new_table = {}
818 Niightblade-44338
                lookup_table[object] = new_table
819 Niightblade-44338
                for index, value in pairs(object) do
820 Niightblade-44338
                        new_table[_copy(index)] = _copy(value)
821 Niightblade-44338
                end
822 Niightblade-44338
                return setmetatable(new_table, getmetatable(object))
823 Niightblade-44338
        end
824 Niightblade-44338
        return _copy(object)
825 Niightblade-44338
end
826 Niightblade-44338
 
827 Niightblade-44338
function addon:pour(dest, text, color, icon)
828 Niightblade-44338
        text = format("|cffffff7fnw|r: %s", text)
829 Niightblade-44338
        color = color or {r=1,g=1,b=1}
830 Niightblade-44338
        icon = icon or nil
831 Niightblade-44338
        dest:Pour(text,color.r,color.g,color.b,nil,nil,nil,nil,nil,icon)
832 Niightblade-44338
end
833 Niightblade-44338
 
834 Niightblade-44338
function addon:convertLookup(data)
835 Niightblade-44338
        local result = {}
836 Niightblade-44338
        for k,_ in pairs(data) do
837 Niightblade-44338
                result[k] = k
838 Niightblade-44338
        end
839 Niightblade-44338
        return result
840 Niightblade-44338
end