Mercurial > wow > ouroloot
changeset 69:8442272a8418
- Make sure popup dialogs are on top of Ace3's widgets.
- Minor code reorganization. Safety hook for future boss-entry code.
- Avoid same bug from a couple revs ago when adding manual boss kills.
- Ask players about snapshot data when manually entering boss kills.
- Blizzard rearranged the button order in 3-entry popups some time ago
and I failed to adapt the code until now.
author | Farmbuyer of US-Kilrogg <farmbuyer@gmail.com> |
---|---|
date | Fri, 11 May 2012 03:08:12 +0000 |
parents | 3bed6d51e077 |
children | cdee65c1bd8c |
files | LibFarmbuyer.lua core.lua gui.lua text_tabs.lua verbage.lua |
diffstat | 5 files changed, 210 insertions(+), 126 deletions(-) [+] |
line wrap: on
line diff
--- a/LibFarmbuyer.lua Wed May 09 09:38:14 2012 +0000 +++ b/LibFarmbuyer.lua Fri May 11 03:08:12 2012 +0000 @@ -54,7 +54,7 @@ Ditto for table recycling. ]] -local MAJOR, MINOR = "LibFarmbuyer", 16 +local MAJOR, MINOR = "LibFarmbuyer", 17 assert(LibStub,MAJOR.." requires LibStub") local lib = LibStub:NewLibrary(MAJOR, MINOR) if not lib then return end @@ -167,10 +167,16 @@ StaticPopupDialogs[dialog.which].OnAccept (dialog, dialog.data, dialog.data2) dialog:Hide() end -local function OnShow_witheditbox (dialog, data) +local function OnShow_ontop (dialog, data) local info = StaticPopupDialogs[dialog.which] - --dialog[info.hasWideEditBox and "wideEditBox" or "editBox"]:SetFocus() - dialog.editBox:SetFocus() + -- ace3's elements are hardcoded to this strata, make sure popups + -- can also be seen (their toplevel=true attribute handles the + -- framelevels within the same strata) + info.saved_strata = dialog:GetFrameStrata() + dialog:SetFrameStrata("FULLSCREEN_DIALOG") + if info.hasEditBox then + dialog.editBox:SetFocus() + end if info.farm_OnShow then return info.farm_OnShow (dialog, data) end @@ -183,9 +189,14 @@ return info.farm_OnAccept (dialog, data, data2) end end -local function OnHide_cleanup (dialog) +local function OnHide_cleanup (dialog, data) + local info = StaticPopupDialogs[dialog.which] + if info.farm_OnHide then + return info.farm_OnHide (dialog, data) + end dialog.data = nil dialog.data2 = nil + dialog:SetFrameStrata(info.saved_strata or "DIALOG") end --[[ @@ -195,10 +206,6 @@ if t.hasEditBox then t.EditBoxOnTextChanged = EditBoxOnTextChanged_notempty t.EditBoxOnEnterPressed = EditBoxOnEnterPressed_accept - if t.OnShow then - t.farm_OnShow = t.OnShow - end - t.OnShow = OnShow_witheditbox if t.OnAccept then t.farm_OnAccept = t.OnAccept end @@ -207,9 +214,10 @@ t.EditBoxOnEscapePressed = StaticPopup_EscapePressed end - if not t.OnHide then - t.OnHide = OnHide_cleanup - end + t.farm_OnShow = t.OnShow + t.OnShow = OnShow_ontop + t.farm_OnHide = t.OnHide + t.OnHide = OnHide_cleanup t.timeout = 0 t.whileDead = true
--- a/core.lua Wed May 09 09:38:14 2012 +0000 +++ b/core.lua Fri May 11 03:08:12 2012 +0000 @@ -40,7 +40,9 @@ up; can be 0 if we're outside an instance and the player inside has an older version - duration in seconds; may be missing (only present if local) -- raidersnap copy of g_loot.raiders at the time of the boss event +- raidersnap copy of g_loot.raiders at the time of the boss event; may be + empty for manual snapshots the player didn't want included + (not necessarily an "error" if this is missing entirely) Loot specific g_loot indices: - person recipient @@ -107,7 +109,7 @@ ------ Constants local option_defaults = { - ['datarev'] = 18, -- cheating, this isn't actually an option + ['datarev'] = 19, -- cheating, this isn't actually an option ['popup_on_join'] = true, ['register_slashloot'] = true, ['scroll_to_bottom'] = true, @@ -616,6 +618,11 @@ end end + bumpers[18] = bumpers[16] + -- In the not-very-many days between 16 and 19, I managed to break + -- the exact same data in the exact same way. At least they're + -- not actually running the same loop twice... probably... sigh. + --[===[ local real = bumpers bumpers = newproxy(true) @@ -997,9 +1004,10 @@ -- this is set on various boss interactions, so we've got a kill/wipe -- entry already if addon.latest_instance then return end - addon.latest_instance = instance_tag() - local ss, max = addon:snapshot_raid() - addon:_mark_boss_kill (addon._addLootEntry{ + --addon.latest_instance = instance_tag() + local ss, max, inst = addon:snapshot_raid() + addon.latest_instance = inst + addon:_mark_boss_kill (addon._addBossEntry{ kind='boss', reason='kill', bossname=[[trash]], instance=addon.latest_instance, duration=0, raidersnap=ss, maxsize=max @@ -1204,8 +1212,8 @@ end elseif cmd == "fake" then -- maybe comment this out for real users - self:_mark_boss_kill (self._addLootEntry{ - kind='boss',reason='kill',bossname="Baron Steamroller",instance=instance_tag(),duration=0 + self:_mark_boss_kill (self._addBossEntry{ + kind='boss',reason='kill',bossname="Baron Steamroller",duration=0 }) self:CHAT_MSG_LOOT ('manual', my_name, 54797) if self.display then @@ -1581,7 +1589,7 @@ end end end - bossi = addon._addLootEntry(boss) + bossi = addon._addBossEntry(boss) -- addon. bossi = addon._adjustBossOrder (bossi, g_boss_signpost) or bossi g_boss_signpost = nil @@ -1657,6 +1665,7 @@ local attempts = 1 local first + -- Maybe redo this to only collapse *contiguous* wipes...? local i,d = 1,g_loot[1] while d ~= e do if d.bossname and @@ -1820,6 +1829,23 @@ return index end + -- Safety wrapper only. + -- XXX Maybe pprint something here. + function addon._addBossEntry (e) + local ret = addon._addLootEntry(e) + assert(e.kind=='boss') + local needSize = e.maxsize == nil + local needSnap = e.raidersnap == nil + local needInst = e.instance == nil + if needSize or needSnap then + local ss, max, inst = addon:snapshot_raid() + if needSize then e.maxsize = max end + if needSnap then e.raidersnap = ss end + if needInst then e.instance = inst end + end + return ret + 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
--- a/gui.lua Wed May 09 09:38:14 2012 +0000 +++ b/gui.lua Fri May 11 03:08:12 2012 +0000 @@ -711,7 +711,7 @@ notCheckable = true, }}, { - "Change from 'wipe' to 'kill'|Also collapses other wipe entries.", + "Change from 'wipe' to 'kill'|Also collapses previous wipe entries.", "Rebroadcast this boss%boss|Broadcasts the kill event and all subsequent loot until next boss.", "Delete this boss event|Permanent, no going back!", "Delete remaining entries for this boss%boss|Erases everything from here down until a new boss/day.\n\nHold down the Shift key to also delete the player's corresponding History entry.", @@ -2195,104 +2195,6 @@ ------ Popup dialogs --- Callback for each Next/Accept stage of inserting a new loot row via dropdown -local function eoi_st_insert_OnAccept_boss (dialog, data) - if data.all_done then - -- It'll probably be the final entry in the table, but there might have - -- been real loot happening at the same time. - local boss_index = addon._addLootEntry{ - kind = 'boss', - bossname = (OuroLootSV_opts.snarky_boss and addon.boss_abbrev[data.name] or data.name) or data.name, - reason = 'kill', - instance = data.instance, - duration = 0, - } - local entry = tremove(g_loot,boss_index) - tinsert(g_loot,data.rowindex,entry) - addon:_mark_boss_kill(data.rowindex) - data.display:GetUserData("eoiST"):OuroLoot_Refresh(data.rowindex) - dialog.data = nil -- free up memory - addon:Print("Inserted %s %s (entry %d).", data.kind, data.name, data.rowindex) - return - end - - local text = dialog.editBox:GetText() - - -- second click - if data.name and text then - data.instance = text - data.all_done = true - -- in future do one more thing, for now just jump to the check - return eoi_st_insert_OnAccept_boss (dialog, data) - end - - -- first click - if text then - data.name = text - local getinstance = StaticPopup_Show("OUROL_EOI_INSERT","instance") - getinstance.data = data - getinstance.editBox:SetText((addon.instance_tag())) - -- This suppresses auto-hide (which would case the getinstance dialog - -- to go away), but only when mouse clicking. OnEnter is on its own. - return true - end -end - -local function eoi_st_insert_OnAccept_loot (dialog, data) - if data.all_done then - --local real_rebroadcast, real_enabled = addon.rebroadcast, addon.enabled - --g_rebroadcast, g_enabled = false, true - data.display:Hide() - local loot_index = addon:CHAT_MSG_LOOT ("manual", data.recipient, data.name, data.notes) - --g_rebroadcast, g_enabled = real_g_rebroadcast, real_g_enabled - local entry = tremove(g_loot,loot_index) - tinsert(g_loot,data.rowindex,entry) - --data.display:GetUserData("eoiST"):OuroLoot_Refresh(data.rowindex) - addon:_fill_out_eoi_data(data.rowindex) - addon:BuildMainDisplay() - dialog.data = nil - addon:Print("Inserted %s %s (entry %d).", data.kind, data.name, data.rowindex) - return - end - - local text = dialog.editBox:GetText():trim() - - -- third click - if data.name and data.recipient and text then - data.notes = (text ~= "<none>") and text or nil - data.all_done = true - return eoi_st_insert_OnAccept_loot (dialog, data) - end - - -- second click - if data.name and text then - data.recipient = text - local getnotes = StaticPopup_Show("OUROL_EOI_INSERT","notes") - getnotes.data = data - getnotes.editBox:SetText("<none>") - getnotes.editBox:HighlightText() - return true - end - - -- first click - if text then - data.name = text - dialog:Hide() -- technically a "different" one about to be shown - local getrecipient = StaticPopup_Show("OUROL_EOI_INSERT","recipient") - getrecipient.data = data - getrecipient.editBox:SetText("") - return true - end -end - -local function eoi_st_insert_OnAccept (dialog, data) - if data.kind == 'boss' then - return eoi_st_insert_OnAccept_boss (dialog, data) - elseif data.kind == 'loot' then - return eoi_st_insert_OnAccept_loot (dialog, data) - end -end - StaticPopupDialogs["OUROL_CLEAR"] = flib.StaticPopup{ text = "Clear current loot information and text?", button1 = YES, @@ -2356,17 +2258,18 @@ } StaticPopupDialogs["OUROL_REMIND"] = flib.StaticPopup{ - text = "Do you wish to activate Ouro Loot?\n\n(Hit the Escape key to close this window without clicking)", + text = "Do you wish to activate Ouro Loot?\n\n(Hit the Escape key to close this window without clicking; Enter is the same as Activate)", button1 = "Activate recording", -- "accept", left - button3 = "Broadcast only", -- "alt", middle - button2 = "Help", -- "cancel", right + button2 = "Broadcast Only", -- "cancel", middle + button3 = HELP_LABEL, -- "alt", right OnAccept = function (dialog, addon) addon:Activate() end, - OnAlt = function (dialog, addon) + noCancelOnEscape = true, + OnCancel = function (dialog, addon) addon:Activate(nil,true) end, - OnCancel = function (dialog, addon) + OnAlt = function (dialog, addon) -- hitting escape also calls this, but the 3rd arg would be "clicked" -- in both cases, not useful here. local helpbutton = dialog.button2 @@ -2381,6 +2284,128 @@ end, } +-- Callback for each Next/Accept stage of inserting a new loot or boss row via +-- dropdown. Thanks to noCancelOnReuse, each Show done here will technically +-- Hide and redisplay the same dialog, passing along the same 'data' structure +-- each time. The topmost call to our OnAccept will then finish by hiding the +-- (very last) dialog. +-- +-- This is really, really hideous to read. +local function eoi_st_insert_OnAccept_boss (dialog, data, data2) + if data.all_done then + -- It'll probably be the final entry in the table, but there might have + -- been real loot happening at the same time. + local boss_index = addon._addBossEntry{ + kind = 'boss', + bossname = (OuroLootSV_opts.snarky_boss and addon.boss_abbrev[data.name] or data.name) or data.name, + reason = 'kill', + instance = data.instance, + duration = 0, + maxsize = data.max_raid_size, + raidersnap = data.yes_snap or {}, + } + local entry = tremove(g_loot,boss_index) + tinsert(g_loot,data.rowindex,entry) + addon:_mark_boss_kill(data.rowindex) + data.display:GetUserData("eoiST"):OuroLoot_Refresh(data.rowindex) + dialog.data = nil -- free up memory + addon:Print("Inserted %s %s (entry %d).", data.kind, data.name, data.rowindex) + return + end + + -- third click + if data.name and data.instance then + data.all_done = true + -- this is how we distinguish OnAccept from OnCancel ("clicked"); the + -- 3rd param is handled all in StaticPopup_OnClick + if data2 ~= 'clicked' then + data.yes_snap = data.maybe_snap + end + return eoi_st_insert_OnAccept_boss (dialog, data) + end + + local text = dialog.editBox:GetText():trim() + + -- second click + if data.name and text then + data.instance = text + -- not "resuing" this dialog in the same sense as with loot + dialog.data = nil + dialog:Hide() + local getsnap = StaticPopup_Show("OUROL_EOI_INSERT_INCLUDE_RAIDERSNAP") + getsnap.data = data + return true + end + + -- first click + if text then + data.name = text + local maybe_instance + data.maybe_snap, data.max_raid_size, maybe_instance = addon:snapshot_raid() + local getinstance = StaticPopup_Show("OUROL_EOI_INSERT","instance") + getinstance.data = data + getinstance.editBox:SetText(maybe_instance) + -- This suppresses auto-hide (which would cause the getinstance dialog + -- to go away), but only when mouse clicking. OnEnter is on its own. + return true + end +end + +local function eoi_st_insert_OnAccept_loot (dialog, data) + if data.all_done then + --local real_rebroadcast, real_enabled = addon.rebroadcast, addon.enabled + --g_rebroadcast, g_enabled = false, true + data.display:Hide() + local loot_index = addon:CHAT_MSG_LOOT ("manual", data.recipient, data.name, data.notes) + --g_rebroadcast, g_enabled = real_g_rebroadcast, real_g_enabled + local entry = tremove(g_loot,loot_index) + tinsert(g_loot,data.rowindex,entry) + --data.display:GetUserData("eoiST"):OuroLoot_Refresh(data.rowindex) + addon:_fill_out_eoi_data(data.rowindex) + addon:BuildMainDisplay() + dialog.data = nil + addon:Print("Inserted %s %s (entry %d).", data.kind, data.name, data.rowindex) + return + end + + local text = dialog.editBox:GetText():trim() + + -- third click + if data.name and data.recipient and text then + data.notes = (text ~= "<none>") and text or nil + data.all_done = true + return eoi_st_insert_OnAccept_loot (dialog, data) + end + + -- second click + if data.name and text then + data.recipient = text + local getnotes = StaticPopup_Show("OUROL_EOI_INSERT","notes") + getnotes.data = data + getnotes.editBox:SetText("<none>") + getnotes.editBox:HighlightText() + return true + end + + -- first click + if text then + data.name = text + dialog:Hide() -- technically a "different" one about to be shown + local getrecipient = StaticPopup_Show("OUROL_EOI_INSERT","recipient") + getrecipient.data = data + getrecipient.editBox:SetText("") + return true + end +end + +local function eoi_st_insert_OnAccept (dialog, data) + if data.kind == 'boss' then + return eoi_st_insert_OnAccept_boss (dialog, data) + elseif data.kind == 'loot' then + return eoi_st_insert_OnAccept_loot (dialog, data) + end +end + -- The data member here is a table built with: -- {rowindex=<GUI row receiving click>, display=_d, kind=<loot/boss>} do @@ -2408,10 +2433,8 @@ t.enterClicksFirstButton = nil -- no effect with editbox focused t.OnAccept = eoi_st_insert_OnAccept StaticPopupDialogs["OUROL_EOI_INSERT"] = t -end --- This seems to be gratuitous use of metatables, really. -do + -- This seems to be gratuitous use of metatables, really. local OEIL = { text = "Paste the new item into here, then click Next or press Enter:", __index = StaticPopupDialogs["OUROL_EOI_INSERT"] @@ -2425,6 +2448,24 @@ return true end end) + + t = flib.StaticPopup{ + -- Concatenate this once at load time. There is no ITEM_QUALITY_LEGENDARY constant. + text = "Include a snapshot of the " .. ITEM_QUALITY_COLORS[5].hex + .. "CURRENT|r raid?\n\nClicking '" .. YES .. "' will allow this entry to " + .. "appear in attendance lists, but with the roster as it is NOW, not as it " + .. "was THEN. Clicking '" .. NO .."' means this kill cannot be included in " + .. "attendance.\n\n(Enter = '" .. YES .."', Escape = '" .. CANCEL .. "')", + button1 = YES, -- "accept", left + button2 = NO, -- "cancel", middle + button3 = CANCEL, -- "alt", right + } + -- Hitting Escape still hides the frame, but doesn't run OnCancel (which + -- is for the "No" button, not the "Cancel"/OnAlt button). Dizzy yet? + t.noCancelOnEscape = true + t.OnAccept = eoi_st_insert_OnAccept_boss + t.OnCancel = eoi_st_insert_OnAccept_boss + StaticPopupDialogs["OUROL_EOI_INSERT_INCLUDE_RAIDERSNAP"] = t end StaticPopupDialogs["OUROL_REASSIGN_ENTER"] = flib.StaticPopup{
--- a/text_tabs.lua Wed May 09 09:38:14 2012 +0000 +++ b/text_tabs.lua Fri May 11 03:08:12 2012 +0000 @@ -176,7 +176,7 @@ local e = loot[i] if e.kind == 'boss' and e.reason == 'kill' then - -- This could, concievably, be different on a per-boss basis + -- Raid size can potentially be different on a per-boss basis -- (e.g., "we're dropping to 10-man for the PvP boss") local i,o = do_attendance (e.raidersnap, e.maxsize / MEMBERS_PER_RAID_GROUP)
--- a/verbage.lua Wed May 09 09:38:14 2012 +0000 +++ b/verbage.lua Fri May 11 03:08:12 2012 +0000 @@ -512,6 +512,13 @@ the loot grid. The surefire way to avoid this is to not release spirit until DBM announces the wipe, but the problem isn't serious enough to really worry about. (Right-click the spurious entries and delete them.) + +When a boss is killed, ALL previous wipes for that boss are removed and +collapsed... even if they're on other days with other raids. If you only +raid with one guild, this can result in some amusing statistics ("kill +on 27th attempt" would actually mean something), but if there are multiple +raid configurations without clearing loot in between, then this number +is simply garbage. ]] T.todo_todolist = todo