Mercurial > wow > ouroloot
comparison core.lua @ 125:a9cf9b2fbf9b
- Fix interactions with AddonLoader.
- Plugins get a :Print with a clickable prefix, with overrideable behaviors.
- 'Deactivate' event gets a [wrapper around] current raiders table.
- Fix sorting bug in player history data.
- Smarter status line text when viewing unfiltered history.
- Do not disable history regeneration button when current history is empty.
- :BuildMainDisplay can handle the CLI args now.
author | Farmbuyer of US-Kilrogg <farmbuyer@gmail.com> |
---|---|
date | Sun, 19 Aug 2012 21:08:59 -0400 |
parents | fb4bda3ad05c |
children | dc39ce56a62d |
comparison
equal
deleted
inserted
replaced
124:1a248faf1a3b | 125:a9cf9b2fbf9b |
---|---|
19 - online 'online', 'offline', 'no_longer' [no longer in raid group] | 19 - online 'online', 'offline', 'no_longer' [no longer in raid group] |
20 [both of these next two fields use time_t values:] | 20 [both of these next two fields use time_t values:] |
21 - join time player joined the raid (or first time we've seen them) | 21 - join time player joined the raid (or first time we've seen them) |
22 - leave time player left the raid (or time we've left the raid, if | 22 - leave time player left the raid (or time we've left the raid, if |
23 'online' is not 'no_longer') | 23 'online' is not 'no_longer') |
24 - needinfo true if haven't yet gotten close enough to player to request | |
25 unit data; SHOULD be missing | |
24 | 26 |
25 Common g_loot entry indices: | 27 Common g_loot entry indices: |
26 - kind time/boss/loot | 28 - kind time/boss/loot |
27 - hour 0-23, on the *physical instance server*, not the realm server | 29 - hour 0-23, on the *physical instance server*, not the realm server |
28 - minute 0-59, ditto | 30 - minute 0-59, ditto |
442 -- COLOR can be ITEM_QUALITY_* or a formatting string ("|cff...") | 444 -- COLOR can be ITEM_QUALITY_* or a formatting string ("|cff...") |
443 -- FUNC can be "MethodName", "tab_title", or a function | 445 -- FUNC can be "MethodName", "tab_title", or a function |
444 -- | 446 -- |
445 -- Returns an opaque token and a matching number. Calling tostring() on | 447 -- Returns an opaque token and a matching number. Calling tostring() on |
446 -- the token will yield a formatted clickable string that can be displayed | 448 -- the token will yield a formatted clickable string that can be displayed |
447 -- in chat. The MethodName and raw function callbacks will both be | 449 -- in local chat. Clicking a tab_title hyperlink opens the GUI to that |
448 -- passed the addon table and the same matching number. | 450 -- tab; the MethodName and raw function callbacks will be passed the addon |
451 -- table, the same matching number, and the mouse button (ala OnClick) as | |
452 -- arguments. | |
449 -- | 453 -- |
450 -- This is largely an excuse to fool around with Lua data constructs. | 454 -- This is largely an excuse to fool around with Lua data constructs. |
451 function addon.format_hypertext (text, color, func) | 455 function addon.format_hypertext (text, color, func) |
452 local ret = newproxy(base) | 456 local ret = newproxy(base) |
453 local num = #text_map + 1 | 457 local num = #text_map + 1 |
471 DEFAULT_CHAT_FRAME:HookScript("OnHyperlinkClick", function(self, link, fullstring, mousebutton) | 475 DEFAULT_CHAT_FRAME:HookScript("OnHyperlinkClick", function(self, link, fullstring, mousebutton) |
472 local ltype, arg = strsplit(":",link) | 476 local ltype, arg = strsplit(":",link) |
473 if ltype ~= "OuroLoot" then return end | 477 if ltype ~= "OuroLoot" then return end |
474 arg = tonumber(arg) | 478 arg = tonumber(arg) |
475 local f = func_map[text_map[arg]] | 479 local f = func_map[text_map[arg]] |
476 if type(f) == 'function' then | 480 local t = type(f) |
477 f (addon, arg) | 481 if t == 'string' then |
478 elseif type(f) == 'string' then | |
479 if type(addon[f]) == 'function' then | 482 if type(addon[f]) == 'function' then |
480 addon[f](addon,arg) -- method name | 483 addon[f](addon,arg,mousebutton) -- method |
481 else | 484 else |
482 addon:BuildMainDisplay(f) -- tab title fragment | 485 addon:BuildMainDisplay(f) -- tab title fragment |
483 end | 486 end |
487 elseif t == 'function' then | |
488 f (addon, arg, mousebutton) | |
484 end | 489 end |
485 end) | 490 end) |
486 | 491 |
487 local old = ItemRefTooltip.SetHyperlink | 492 local old = ItemRefTooltip.SetHyperlink |
488 function ItemRefTooltip:SetHyperlink (link, ...) | 493 function ItemRefTooltip:SetHyperlink (link, ...) |
752 -- relogging during a raid and already have collected loot data | 757 -- relogging during a raid and already have collected loot data |
753 local OuroLootSV = OuroLootSV | 758 local OuroLootSV = OuroLootSV |
754 g_restore_p = OuroLootSV ~= nil | 759 g_restore_p = OuroLootSV ~= nil |
755 self.dprint('flow', "oninit sets restore as", g_restore_p) | 760 self.dprint('flow', "oninit sets restore as", g_restore_p) |
756 | 761 |
757 -- Primarily for plugins, but can be of use to me also... | 762 -- Primarily for plugins, but can be of use to me also... LCALLBACK |
758 self.callbacks = LibStub("CallbackHandler-1.0"):New(self) | 763 self.callbacks = LibStub("CallbackHandler-1.0"):New(self) |
759 --function self.callbacks:OnUsed (target_aka_self, eventname) end | 764 --function self.callbacks:OnUsed (target_aka_self, eventname) end |
760 --function self.callbacks:OnUnused (target_aka_self, eventname) end | 765 --function self.callbacks:OnUnused (target_aka_self, eventname) end |
761 | 766 |
762 if _G.OuroLootOptsDB == nil then | 767 if _G.OuroLootOptsDB == nil then |
868 | 873 |
869 function addon:OnEnable() | 874 function addon:OnEnable() |
870 self:RegisterEvent("PLAYER_LOGOUT") | 875 self:RegisterEvent("PLAYER_LOGOUT") |
871 self:RegisterEvent(RAID_ROSTER_UPDATE_EVENT,"RAID_ROSTER_UPDATE") | 876 self:RegisterEvent(RAID_ROSTER_UPDATE_EVENT,"RAID_ROSTER_UPDATE") |
872 | 877 |
873 -- Cribbed from Talented. I like the way jerry thinks: the first string | 878 -- This Print cribbed from Talented. I like the way jerry thinks: the |
874 -- argument can be a format spec for the remainder of the arguments. | 879 -- first string argument can be a format spec for the remainder of the |
875 -- AceConsole:Printf isn't used because we can't specify a prefix without | 880 -- arguments. AceConsole:Printf isn't used because we can't specify a |
876 -- jumping through ridonkulous hoops. The part about overriding :Print | 881 -- prefix without jumping through ridonkulous hoops. |
877 -- with a version using prefix hyperlinks is my fault. | 882 -- |
883 -- Everything dealing with a prefix hyperlink is my fault. | |
878 -- | 884 -- |
879 -- CFPrint added instead of the usual Print testing of the first arg for | 885 -- CFPrint added instead of the usual Print testing of the first arg for |
880 -- frame-ness, which would slow down all printing and only rarely be useful. | 886 -- frame-ness, which would slow down all printing and only rarely be useful. |
881 -- | 887 -- |
882 -- There is no ITEM_QUALITY_LEGENDARY constant. Sigh. | 888 -- There is no ITEM_QUALITY_LEGENDARY constant. Sigh. |
1010 Stick something in the Blizzard addons options list, where most users | 1016 Stick something in the Blizzard addons options list, where most users |
1011 will probably look these days. Try to be conservative about needless | 1017 will probably look these days. Try to be conservative about needless |
1012 frame creation. | 1018 frame creation. |
1013 ]] | 1019 ]] |
1014 local bliz = CreateFrame("Frame") | 1020 local bliz = CreateFrame("Frame") |
1015 bliz.name = "Ouro Loot" | 1021 bliz.name = "Ouro Loot" -- must match X-LoadOn-InterfaceOptions |
1022 if AddonLoader then | |
1023 AddonLoader:RemoveInterfaceOptions(bliz.name) | |
1024 end | |
1016 bliz:SetScript("OnShow", function(_b) | 1025 bliz:SetScript("OnShow", function(_b) |
1017 local button = CreateFrame("Button",nil,_b,"UIPanelButtonTemplate") | 1026 local button = CreateFrame("Button",nil,_b,"UIPanelButtonTemplate") |
1018 button:SetWidth(150) | 1027 button:SetWidth(150) |
1019 button:SetHeight(22) | 1028 button:SetHeight(22) |
1020 button:SetScript("OnClick", function() | 1029 button:SetScript("OnClick", function() |
1021 InterfaceOptionsFrameCancel:Click() | 1030 InterfaceOptionsFrameCancel:Click() |
1022 HideUIPanel(GameMenuFrame) | 1031 HideUIPanel(GameMenuFrame) |
1023 addon:OpenMainDisplayToTab"Options" | 1032 addon:BuildMainDisplay('opt') |
1024 end) | 1033 end) |
1025 button:SetText('"/ouroloot opt"') | 1034 button:SetText('"/ouroloot options"') |
1026 button:SetPoint("TOPLEFT",20,-20) | 1035 button:SetPoint("TOPLEFT",20,-20) |
1027 _b:SetScript("OnShow",nil) | 1036 _b:SetScript("OnShow",nil) |
1028 end) | 1037 end) |
1029 InterfaceOptions_AddCategory(bliz) | 1038 InterfaceOptions_AddCategory(bliz) |
1030 | 1039 |
1046 Module support (aka plugins). Field names with special meanings: | 1055 Module support (aka plugins). Field names with special meanings: |
1047 - option_defaults: (IN) Standard AceDB-style table. Use a profiles key! | 1056 - option_defaults: (IN) Standard AceDB-style table. Use a profiles key! |
1048 - db: (OUT) AceDB object, set during init. | 1057 - db: (OUT) AceDB object, set during init. |
1049 - opts: (OUT) Pointer to plugin's "db.profile" subtable. | 1058 - opts: (OUT) Pointer to plugin's "db.profile" subtable. |
1050 | 1059 |
1051 OnInitialize, [default_]OnEnable, register_text_generator, register_tab_control | 1060 Inherited unchanged: |
1052 are all inherited. | 1061 |
1062 Inherited module variants: | |
1063 - OnInitialize, OnEnable | |
1064 - register_text_generator, register_tab_control: also flag plugin as | |
1065 a text-generating module in main addon | |
1053 ]] | 1066 ]] |
1054 local prototype = {} | 1067 local prototype = {} |
1055 local registry | 1068 local textgen_registry, chat_prefixes, chat_codes |
1056 | 1069 |
1057 -- By default, no plugins. First one in sets up code for any after. | 1070 -- By default, no plugins. First one in sets up code for any after. |
1058 addon.get_plugin = flib.nullfunc | 1071 addon.get_textgen_plugin = flib.nullfunc |
1059 | 1072 |
1060 -- Fires before the plugin's own OnEnable (inherited or otherwise). | 1073 -- Called as part of NewModule, after embedding and metas are done. |
1074 -- Mostly this is one-time setup stuff that we don't need until a plugin | |
1075 -- is actually built. | |
1061 function addon:OnModuleCreated (plugin) | 1076 function addon:OnModuleCreated (plugin) |
1062 if not registry then | 1077 textgen_registry, chat_prefixes, chat_codes = {}, {}, {} |
1063 registry = {} | 1078 addon.get_textgen_plugin = function(a,t) |
1064 addon.get_plugin = function(a,t) return registry[t] end | 1079 return textgen_registry[t] |
1065 prototype.register_text_generator = function(p,t,...) | 1080 end |
1066 registry[t] = p | 1081 prototype.register_text_generator = function(p,t,...) |
1067 return addon:register_text_generator(t,...) | 1082 textgen_registry[t] = p |
1068 end | 1083 return addon:register_text_generator(t,...) |
1069 prototype.register_tab_control = function(p,t,...) | 1084 end |
1070 registry[t] = p | 1085 prototype.register_tab_control = function(p,t,...) |
1071 return addon:register_tab_control(t,...) | 1086 textgen_registry[t] = p |
1072 end | 1087 return addon:register_tab_control(t,...) |
1073 end | 1088 end |
1074 end | 1089 |
1075 | 1090 function addon:ModulePrefixClick (codenum, mousebutton) |
1076 local function module_OnInit (plugin) | 1091 local plugin = assert(chat_codes[codenum]) |
1092 if not plugin:IsEnabled() then return end | |
1093 if mousebutton == 'LeftButton' then | |
1094 if plugin.PrefixLeftClick then | |
1095 plugin:PrefixLeftClick(codenum) | |
1096 else | |
1097 self:BuildMainDisplay() | |
1098 end | |
1099 elseif mousebutton == 'RightButton' then | |
1100 local uniqueval = plugin.name | |
1101 if plugin.PrefixRightClick then | |
1102 uniqueval = plugin:PrefixRightClick(codenum) | |
1103 end | |
1104 self:BuildMainDisplay('opt',uniqueval) | |
1105 end | |
1106 end | |
1107 function addon:OnModuleCreated (plugin) | |
1108 local token, code = self.format_hypertext (plugin.moduleName, | |
1109 --[[heirloom]]7, "ModulePrefixClick") | |
1110 chat_prefixes[plugin] = token | |
1111 chat_codes[code] = plugin | |
1112 -- remove the libraries' embedded pointers so that the prototype | |
1113 -- can be inherited | |
1114 plugin.Print = nil | |
1115 end | |
1116 | |
1117 return self:OnModuleCreated(plugin) | |
1118 end | |
1119 | |
1120 function prototype.OnInitialize (plugin) | |
1077 if plugin.option_defaults then | 1121 if plugin.option_defaults then |
1078 plugin.db = addon.db:RegisterNamespace (plugin.moduleName, plugin.option_defaults) | 1122 plugin.db = addon.db:RegisterNamespace (plugin.moduleName, plugin.option_defaults) |
1079 plugin.opts = plugin.db.profile | 1123 plugin.opts = plugin.db.profile |
1080 --plugin:SetEnabledState(plugin.db.profile.enabled) if that flag is needed later | 1124 --plugin:SetEnabledState(plugin.db.profile.enabled) if that flag is needed later |
1081 end | 1125 end |
1082 end | 1126 end |
1083 | 1127 |
1084 local function module_OnEnable (plugin) | 1128 --function prototype.OnEnable (plugin) |
1085 end | 1129 --end |
1086 | 1130 |
1087 local function module_GetOption (plugin, info) | 1131 function prototype.GetOption (plugin, info) |
1088 local name = info[#info] | 1132 local name = info[#info] |
1089 return plugin.db.profile[name] | 1133 return plugin.db.profile[name] |
1090 end | 1134 end |
1091 local function module_SetOption (plugin, info, value) | 1135 function prototype.SetOption (plugin, info, value) |
1092 local name = info[#info] | 1136 local name = info[#info] |
1093 plugin.db.profile[name] = value | 1137 plugin.db.profile[name] = value |
1094 local arg = info.arg | 1138 local arg = info.arg |
1095 if type(arg) == 'function' then | 1139 if type(arg) == 'function' then |
1096 plugin[arg](plugin,info) | 1140 plugin[arg](plugin,info) |
1097 end | 1141 end |
1098 end | 1142 end |
1099 | 1143 |
1100 prototype.OnInitialize = module_OnInit | 1144 -- may eventually just rework the main print routines and inherit all 3 |
1101 prototype.OnEnable = module_OnEnable | 1145 function prototype.Print (plugin, str, ...) |
1102 prototype.default_OnEnable = module_OnEnable | 1146 local AC = LibStub("AceConsole-3.0") |
1103 prototype.GetOption = module_GetOption | 1147 local ps = tostring(chat_prefixes[plugin]) |
1104 prototype.SetOption = module_SetOption | 1148 if type(str) == 'string' and str:find("%", nil, --[[plainmatch=]]true) then |
1149 return AC:Print (ps, str:format(...)) | |
1150 else | |
1151 return AC:Print (ps, str, ...) | |
1152 end | |
1153 end | |
1105 | 1154 |
1106 addon:SetDefaultModuleLibraries("AceConsole-3.0") | 1155 addon:SetDefaultModuleLibraries("AceConsole-3.0") |
1107 addon:SetDefaultModulePrototype(prototype) | 1156 addon:SetDefaultModulePrototype(prototype) |
1108 | 1157 |
1109 local err = [[Module '%s' cannot register itself because it failed a required condition: '%s']] | 1158 local err = [[Module '%s' cannot register itself because it failed a required condition: '%s']] |
1137 | 1186 |
1138 'Activate', enabled_p, rebroadcast_p, threshold | 1187 'Activate', enabled_p, rebroadcast_p, threshold |
1139 The two boolean predicates are self-explanatory. The threshold is an | 1188 The two boolean predicates are self-explanatory. The threshold is an |
1140 ITEM_QUALITY_* constant integer. | 1189 ITEM_QUALITY_* constant integer. |
1141 | 1190 |
1142 'Deactivate' | 1191 'Deactivate', raiderdata |
1143 After all system events have been unregistered. | 1192 After all system events have been unregistered. Argument is a holder of |
1193 the current g_loot.raiders table (in 'raidersnap'). | |
1144 | 1194 |
1145 'Reset' | 1195 'Reset' |
1146 Clicking "Clear Loot", after all data manipulation is finished. | 1196 Clicking "Clear Loot", after all data manipulation is finished. |
1147 | 1197 |
1148 'NewBoss', boss | 1198 'NewBoss', boss |
1928 self.rebroadcast = false | 1978 self.rebroadcast = false |
1929 self:UnregisterEvent(RAID_ROSTER_UPDATE_EVENT) | 1979 self:UnregisterEvent(RAID_ROSTER_UPDATE_EVENT) |
1930 self:UnregisterEvent("PLAYER_ENTERING_WORLD") | 1980 self:UnregisterEvent("PLAYER_ENTERING_WORLD") |
1931 self:UnregisterEvent("CHAT_MSG_LOOT") | 1981 self:UnregisterEvent("CHAT_MSG_LOOT") |
1932 _LFR_suppressing = nil | 1982 _LFR_suppressing = nil |
1933 self:Fire ('Deactivate') | 1983 -- Passing .raiders directly doesn't work with a proxy (again, WTB Lua |
1984 -- 5.2 and its __pairs iterators). Give it the same structure as a boss | |
1985 -- entry instead. | |
1986 self:Fire ('Deactivate', { raidersnap = g_loot.raiders }) | |
1934 self:Print("Deactivated.") | 1987 self:Print("Deactivated.") |
1935 end | 1988 end |
1936 | 1989 |
1937 function addon:Clear(verbose_p) | 1990 function addon:Clear(verbose_p) |
1938 local repopup, st | 1991 local repopup, st |
3055 -- formatted timestamp. This is expensive, and destructive for P.unique. | 3108 -- formatted timestamp. This is expensive, and destructive for P.unique. |
3056 local function compare_timestamps (L, R) | 3109 local function compare_timestamps (L, R) |
3057 return L > R -- reverse of normal order, newest first | 3110 return L > R -- reverse of normal order, newest first |
3058 end | 3111 end |
3059 local function sort_player (p) | 3112 local function sort_player (p) |
3060 local new_uniques, uniques_bywhen, when_array = new(), new(), new() | 3113 local new_uniques, uniques_bywhen, when_array = {}, new(), new() |
3061 for u,tstamp in pairs(p.when) do | 3114 for u,tstamp in pairs(p.when) do |
3062 uniques_bywhen[tstamp] = u | 3115 uniques_bywhen[tstamp] = u |
3063 when_array[#when_array+1] = tstamp | 3116 when_array[#when_array+1] = tstamp |
3064 end | 3117 end |
3065 table.sort (when_array, compare_timestamps) | 3118 table.sort (when_array, compare_timestamps) |
3066 for i,tstamp in ipairs(when_array) do | 3119 for i,tstamp in ipairs(when_array) do |
3067 new_uniques[i] = uniques_bywhen[tstamp] | 3120 new_uniques[i] = uniques_bywhen[tstamp] |
3068 end | 3121 end |
3069 p.unique = new_uniques | 3122 p.unique = new_uniques |
3070 del(new_uniques) del(uniques_bywhen) del(when_array) | 3123 del(uniques_bywhen) |
3124 del(when_array) | |
3071 end | 3125 end |
3072 | 3126 |
3073 function addon:repair_history_integrity() | 3127 function addon:repair_history_integrity() |
3074 local rcount, pcount, hcount, errors = 0, 0, 0, 0 | 3128 local rcount, pcount, hcount, errors = 0, 0, 0, 0 |
3075 local empties_to_delete = {} | 3129 local empties_to_delete = {} |