Mercurial > wow > ouroloot
diff core.lua @ 16:5ee4edd24c13
- new blizz methods for editboxes in dialog popups
- initial code for dropdowns in history (not active yet)
- hovering and shift-clicking to link out of history
- proper confirmations for history rewriting
- options checkboxes more grid-like
- saved texts get a scrollbar instead of expanding indefinitely (duh)
- rearranged savedvars a bit (and added transition code)
- stores raider join/leave times and "demographic" info, all for MLEQDKP
- minor bugfixes and tweaks
author | Farmbuyer of US-Kilrogg <farmbuyer@gmail.com> |
---|---|
date | Thu, 25 Aug 2011 00:45:31 +0000 |
parents | d8fee518ce5d |
children | d929c40cdb09 |
line wrap: on
line diff
--- a/core.lua Sun Jul 17 17:40:00 2011 +0000 +++ b/core.lua Thu Aug 25 00:45:31 2011 +0000 @@ -5,11 +5,7 @@ etc); its named indices are: - forum: saved text from forum markup window, default nil - attend: saved text from raid attendence window, default nil -- printed.FOO: last index formatted into text window FOO, default 0 -- saved: table of copies of saved texts, default nil; keys are numeric - indices of tables, subkeys of those are name/forum/attend/date -- autoshard: optional name of disenchanting player, default nil -- threshold: optional loot threshold, default nil +- printed.FOO: last loot index formatted into text window FOO, default 0 Functions arranged like this, with these lables (for jumping to). As a rule, member functions with UpperCamelCase names are called directly by @@ -33,14 +29,21 @@ After he retired, I began modifying the code. Eventually I set aside the entire package and rewrote the loot tracker module from scratch. Many of the variable/function naming conventions (sv_*, g_*, and family) stayed across the -rewrite. Some variables are needlessly initialized to nil just to look uniform. +rewrite. + +Some variables are needlessly initialized to nil just to look uniform. ]==] ------ Saved variables -OuroLootSV = nil -- possible copy of g_loot -OuroLootSV_opts = nil -- same as option_defaults until changed -OuroLootSV_hist = nil +OuroLootSV = nil -- possible copy of g_loot +OuroLootSV_saved = nil -- table of copies of saved texts, default nil; keys + -- are numeric indices of tables, subkeys of those + -- are name/forum/attend/date +OuroLootSV_opts = nil -- same as option_defaults until changed + -- autoshard: optional name of disenchanting player, default nil + -- threshold: optional loot threshold, default nil +OuroLootSV_hist = nil ------ Constants @@ -149,9 +152,9 @@ ------ Globals local g_loot = nil local g_restore_p = nil -local g_saved_tmp = nil -- restoring across a clear local g_wafer_thin = nil -- for prompting for additional rebroadcasters local g_today = nil -- "today" entry in g_loot +local g_boss_signpost = nil local opts = nil local pairs, ipairs, tinsert, tremove, tonumber = pairs, ipairs, table.insert, table.remove, tonumber @@ -329,6 +332,17 @@ opts.forum["Custom..."] = opts["forum_format"] opts["forum_format"] = nil end + if OuroLootSV then -- may not be the same as testing g_restore_p soon + if OuroLootSV.saved then + OuroLootSV_saved = OuroLootSV.saved; OuroLootSV.saved = nil + end + if OuroLootSV.threshold then + opts.threshold = OuroLootSV.threshold; OuroLootSV.threshold = nil + end + if OuroLootSV.autoshard then + opts.autoshard = OuroLootSV.autoshard; OuroLootSV.autoshard = nil + end + end -- get item filter table if needed if opts.itemfilter == nil then opts.itemfilter = addon.default_itemfilter @@ -398,23 +412,30 @@ function addon:_clear_SVs() g_loot = {} -- not saved, just fooling PLAYER_LOGOUT tests OuroLootSV = nil + OuroLootSV_saved = nil OuroLootSV_opts = nil OuroLootSV_hist = nil ReloadUI() end function addon:PLAYER_LOGOUT() - if (#g_loot > 0) or g_loot.saved - -- someday make this smarter - or (g_loot.forum and g_loot.forum ~= "") - or (g_loot.attend and g_loot.attend ~= "") - then - g_loot.autoshard = self.sharder - g_loot.threshold = self.threshold + self:UnregisterEvent("RAID_ROSTER_UPDATE") + self:UnregisterEvent("PLAYER_ENTERING_WORLD") + + local worth_saving = #g_loot > 0 or next(g_loot.raiders) + if not worth_saving then for text in self:registered_textgen_iter() do + worth_saving = worth_saving or g_loot.printed[text] > 0 + end end + if worth_saving then + opts.autoshard = self.sharder + opts.threshold = self.threshold for i,e in ipairs(g_loot) do e.cols = nil end OuroLootSV = g_loot + else + OuroLootSV = nil end + for r,t in pairs(self.history_all) do if type(t) == 'table' then if #t == 0 then self.history_all[r] = nil @@ -436,7 +457,8 @@ local R_ACTIVE, R_OFFLINE, R_LEFT = 1, 2, 3 local lastevent, now = 0, 0 - local timer_handle + local redo_count = 0 + local redo, timer_handle function addon:CheckRoster (leaving_p, now_a) if not g_loot.raiders then return end -- bad transition @@ -444,6 +466,10 @@ now = now_a or time() if leaving_p then + if timer_handle then + self:CancelTimer(timer_handle) + timer_handle = nil + end for name,r in pairs(g_loot.raiders) do r.leave = r.leave or now end @@ -457,7 +483,10 @@ end end - local redo = false + if redo then + redo_count = redo_count + 1 + end + redo = false for i = 1, GetNumRaidMembers() do local unit = 'raid'..i local name = UnitName(unit) @@ -486,21 +515,29 @@ redo = redo or r.needinfo end end - if redo then - timer_handle = self:ScheduleRepeatingTimer("RAID_ROSTER_UPDATE", 60) - elseif timer_handle then - self:CancelTimer(timer_handle) - timer_handle = nil + if redo then -- XXX test redo_count here and eventually give up? + if not timer_handle then + timer_handle = self:ScheduleRepeatingTimer("RAID_ROSTER_UPDATE", 60) + end + else + redo_count = 0 + if timer_handle then + self:CancelTimer(timer_handle) + timer_handle = nil + end end end function addon:RAID_ROSTER_UPDATE (event) if GetNumRaidMembers() == 0 then + -- Leaving a raid group. -- Because of PLAYER_ENTERING_WORLD, this code also executes on load -- screens while soloing and in regular groups. Take care. - if self.enabled then + self.dprint('flow', "GetNumRaidMembers == 0") + if self.enabled and not self.debug.notraid then + self.dprint('flow', "enabled, leaving raid") self.popped = nil - self:UnregisterEvent("CHAT_MSG_LOOT") + self:Deactivate() -- self:UnregisterEvent("CHAT_MSG_LOOT") self:CheckRoster(--[[leaving raid]]true) end return @@ -521,6 +558,7 @@ -- hot code path, be careful -- event registration from onload, joined a raid, maybe show popup + self.dprint('flow', "RRU check:", self.popped, opts.popup_on_join) if (not self.popped) and opts.popup_on_join then self.popped = StaticPopup_Show "OUROL_REMIND" self.popped.data = self @@ -737,22 +775,30 @@ ------ On/off function addon:Activate (opt_threshold, opt_bcast_only) + self.dprint('flow', ":Activate is running") self:RegisterEvent("RAID_ROSTER_UPDATE") - self:RegisterEvent("PLAYER_ENTERING_WORLD","RAID_ROSTER_UPDATE") + self:RegisterEvent("PLAYER_ENTERING_WORLD", + function() self:ScheduleTimer("RAID_ROSTER_UPDATE", 5, "PLAYER_ENTERING_WORLD") end) self.popped = true if GetNumRaidMembers() > 0 then + self.dprint('flow', ">:Activate calling RRU") self:RAID_ROSTER_UPDATE("Activate") elseif self.debug.notraid then + self.dprint('flow', ">:Activate registering loot and bossmods") self:RegisterEvent("CHAT_MSG_LOOT") _register_bossmod(self) elseif g_restore_p then g_restore_p = nil - if #g_loot == 0 then return end -- only saved texts, not worth verbage + self.popped = nil -- get the reminder if later joining a raid + if #g_loot == 0 then + -- only generated text and raider join/leave data, not worth verbage + self.dprint('flow', ">:Activate restored generated texts, un-popping") + return + end self:Print("Ouro Raid Loot restored previous data, but not in a raid", "and 5-person mode not active. |cffff0505NOT tracking loot|r;", "use 'enable' to activate loot tracking, or 'clear' to erase", "previous data, or 'help' to read about saved-texts commands.") - self.popped = nil -- get the reminder if later joining a raid return end self.rebroadcast = true -- hardcode to true; this used to be more complicated @@ -790,10 +836,9 @@ g_restore_p = nil OuroLootSV = nil self:_reset_timestamps() - g_saved_tmp = g_loot.saved if verbose_p then - if (g_saved_tmp and #g_saved_tmp>0) then - self:Print("Current loot data cleared, %d saved sets remaining.", #g_saved_tmp) + if (OuroLootSV_saved and #OuroLootSV_saved>0) then + self:Print("Current loot data cleared, %d saved sets remaining.", #OuroLootSV_saved) else self:Print("Current loot data cleared.") end @@ -900,25 +945,26 @@ end -- Called when first loading up, and then also when a 'clear' is being --- performed. If SV's are present then restore_p will be true. +-- performed. If SV's are present then g_restore_p will be true. function _init (self, possible_st) self.dprint('flow',"_init running") self.loot_clean = nil self.hist_clean = nil if g_restore_p then g_loot = OuroLootSV - self.popped = true + self.popped = #g_loot > 0 self.dprint('flow', "restoring", #g_loot, "entries") - self:ScheduleTimer("Activate", 12, g_loot.threshold) + self:ScheduleTimer("Activate", 12, opts.threshold) -- FIXME printed could be too large if entries were deleted, how much do we care? - self.sharder = g_loot.autoshard + self.sharder = opts.autoshard else g_loot = { printed = {}, raiders = {} } - g_loot.saved = g_saved_tmp; g_saved_tmp = nil -- potentially restore across a clear end - self.threshold = g_loot.threshold or self.threshold -- in the case of restoring but not tracking + self.threshold = opts.threshold or self.threshold -- in the case of restoring but not tracking self:gui_init(g_loot) + opts.autoshard = nil + opts.threshold = nil if g_restore_p then self:zero_printed_fenceposts() -- g_loot.printed.* = previous/safe values @@ -970,6 +1016,9 @@ end end bossi = addon._addLootEntry(boss) + -- + bossi = addon._adjustBossOrder (bossi, g_boss_signpost) + g_boss_signpost = nil addon.dprint('loot', "added entry", bossi) if boss.reason == 'kill' then addon:_mark_boss_kill (bossi) @@ -998,6 +1047,7 @@ self.dprint('cache', "boss <",signature,"> already in cache, skipping") else self.recent_boss:add(signature) + g_boss_signpost = #g_loot + 1 -- Possible scenarios: (1) we don't see a boss event at all (e.g., we're -- outside the instance) and so this only happens once as a non-local event, -- (2) we see a local event first and all non-local events are filtered @@ -1025,7 +1075,8 @@ function addon:_mark_boss_kill (index) local e = g_loot[index] if not e.bosskill then - return self:Print("Something horribly wrong;", index, "is not a boss entry!") + self:Print("Something horribly wrong;", index, "is not a boss entry!") + return end if e.reason ~= 'wipe' then -- enh, bail @@ -1196,14 +1247,41 @@ g_loot[index] = e return index end + + -- Problem: (1) boss kill happens, (2) fast looting happens, (3) boss + -- cache cleanup fires. Result: loot shows up before boss kill entry. + -- Solution: We need to shuffle the boss entry above any of the loot + -- from that boss. + function addon._adjustBossOrder (is, should_be) + --pprint('loot', is, should_be) + if is == should_be then --pprint('loot', "equal, yay") + return + end + if is < should_be then --pprint('loot', "...the hell? bailing") + return + end + if g_loot[should_be].kind == 'time' then + should_be = should_be + 1 + if is == should_be then + --pprint('loot', "needed to mark day entry, otherwise equal, yay") + return + end + end + + assert(g_loot[is].kind == 'boss') + local boss = tremove (g_loot, is) + --pprint('loot', "MOVING", boss.bosskill) + tinsert (g_loot, should_be, boss) + return should_be + end end ------ Saved texts function addon:check_saved_table(silent_p) - local s = g_loot.saved + local s = OuroLootSV_saved if s and (#s > 0) then return s end - g_loot.saved = nil + OuroLootSV_saved = nil if not silent_p then self:Print("There are no saved loot texts.") end end @@ -1215,8 +1293,9 @@ end function addon:save_saveas(name) - g_loot.saved = g_loot.saved or {} - local n = #(g_loot.saved) + 1 + OuroLootSV_saved = OuroLootSV_saved or {} + local SV = OuroLootSV_saved + local n = #SV + 1 local save = { name = name, date = makedate(), @@ -1226,7 +1305,7 @@ save[text] = g_loot[text] end self:Print("Saving current loot texts to #%d '%s'", n, name) - g_loot.saved[n] = save + SV[n] = save return self:save_list() end