Mercurial > wow > ouroloot
diff core.lua @ 56:fcc0d0ff5832
- instance_tag() also returns max instance size as a plain number, adjust
call sites
- clean up .raiders table, add some new fields, use copies of this instead
of a single string
- make sure datarev field is properly updated when it's already present
- avoid multiple GetRaidRosterInfo loops scattered throughout the addon,
instead just traverse the .raiders list, regularly updated
- make the 'loot' and 'boss' broadcasts versioned. Handle receiving older.
- new format for plaintext attendance output
author | Farmbuyer of US-Kilrogg <farmbuyer@gmail.com> |
---|---|
date | Fri, 13 Apr 2012 04:28:46 +0000 |
parents | ac57a4342812 |
children | 81d5449621f8 |
line wrap: on
line diff
--- a/core.lua Sat Apr 07 05:40:20 2012 +0000 +++ b/core.lua Fri Apr 13 04:28:46 2012 +0000 @@ -6,6 +6,18 @@ - forum saved text from forum markup window, default nil - attend saved text from raid attendence window, default nil - printed.FOO last loot index formatted into text window FOO, default 0 +- raiders accumulating raid roster data as we see raid members; indexed + by player name with subtable fields: +- class capitalized English codename ("WARRIOR", "DEATHKNIGHT", etc) +- subgroup 1-8 +- race English codename ("BloodElf", etc) +- sex 1 = unknown/error, 2 = male, 3 = female +- level can be 0 if player was offline at the time +- guild guild name, or missing if unguilded +- online 1 = online, 2 = offline, 3 = no longer in raid + [both of these next two fields use time_t values:] +- join time player joined the raid (or first time we've seen them) +- leave time player left the raid (or time we've left the raid) Common g_loot entry indices: - kind time/boss/loot @@ -19,26 +31,29 @@ Boss specific g_loot indices: - bossname name of boss/encounter; -- may be changed if "snarky boss names" option is enabled + may be changed if "snarky boss names" option is enabled - reason wipe/kill ("pull" does not generate an entry) - instance name of instance, including size and difficulty -- duration in seconds; may be missing -- raiderlist "Able, Baker, Charlie"; may be missing +- maxsize 5/10/25, presumably also 15 and 40 could show 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 Loot specific g_loot indices: - person recipient - person_class class of recipient if available; may be missing; -- will be classID-style (e.g., DEATHKNIGHT) + will be classID-style (e.g., DEATHKNIGHT) - itemname not including square brackets - id itemID as number - itemlink full clickable link - itexture icon path (e.g., Interface\Icons\INV_Misc_Rune_01) - quality ITEM_QUALITY_* number - disposition offspec/gvault/shard; missing otherwise; can be set from -- the extratext field + the extratext field - count e.g., "x3"; missing otherwise; can be set/removed from -- extratext; triggers only for a stack of items, not "the boss -- dropped double axes today" + extratext; triggers only for a stack of items, not "the boss + dropped double axes today" - is_heroic true if item is heroic; missing otherwise - cache_miss if GetItemInfo failed; SHOULD be missing (changes other fields) - bcast_from if rebroadcast from another player; missing otherwise @@ -88,7 +103,7 @@ ------ Constants local option_defaults = { - ['datarev'] = 15, -- cheating, this isn't actually an option + ['datarev'] = 16, -- cheating, this isn't actually an option ['popup_on_join'] = true, ['register_slashloot'] = true, ['scroll_to_bottom'] = true, @@ -138,7 +153,7 @@ -- Play cute games with namespaces here just to save typing. WTB Lua 5.2 PST. do local _G = _G setfenv (1, addon) - commrev = 15 -- number + commrev = '16' revision = _G.GetAddOnMetadata(nametag,"Version") or "?" -- "x.yy.z", etc ident = "OuroLoot2" identTg = "OuroLoot2Tg" @@ -233,10 +248,10 @@ local g_boss_signpost = nil local opts = nil -local pairs, ipairs, tinsert, tremove, tonumber, wipe = - pairs, ipairs, table.insert, table.remove, tonumber, table.wipe +local pairs, ipairs, tinsert, tremove, tostring, tonumber, wipe = + pairs, ipairs, table.insert, table.remove, tostring, tonumber, table.wipe local pprint, tabledump = addon.pprint, flib.tabledump -local GetNumRaidMembers = GetNumRaidMembers +local CopyTable, GetNumRaidMembers = CopyTable, GetNumRaidMembers -- En masse forward decls of symbols defined inside local blocks local _register_bossmod, makedate, create_new_cache, _init, _log @@ -323,29 +338,30 @@ end end --- Returns an instance name or abbreviation +-- Returns an instance name or abbreviation, followed by the raid size local function instance_tag() local name, typeof, diffcode, diffstr, _, perbossheroic, isdynamic = GetInstanceInfo() - local t + local t, r name = addon.instance_abbrev[name] or name - if typeof == "none" then return name end + if typeof == "none" then return name, MAX_RAID_MEMBERS end -- diffstr is "5 Player", "10 Player (Heroic)", etc. ugh. if (GetLFGMode()) and (GetLFGModeType() == 'raid') then - t = 'LFR' + t,r = 'LFR', 25 elseif diffcode == 1 then - t = ((GetNumRaidMembers()>0) and "10" or "5") + t,r = (GetNumRaidMembers()>0) and "10",10 or "5",5 elseif diffcode == 2 then - t = ((GetNumRaidMembers()>0) and "25" or "5h") + t,r = (GetNumRaidMembers()>0) and "25",25 or "5h",5 elseif diffcode == 3 then - t = "10h" + t,r = "10h", 10 elseif diffcode == 4 then - t = "25h" + t,r = "25h", 25 end -- dynamic difficulties always return normal "codes" if isdynamic and perbossheroic == 1 then t = t .. "h" end - return name .. "(" .. t .. ")" + pprint("instance_tag final", t, r) + return name .. "(" .. t .. ")", r end addon.instance_tag = instance_tag -- grumble addon.latest_instance = nil -- spelling reminder, assigned elsewhere @@ -448,6 +464,7 @@ opts[opt] = default end end + opts.datarev = option_defaults.datarev -- transition&remove old options opts['forum_use_itemid'] = nil @@ -510,18 +527,33 @@ self.history_all.HISTFORMAT = nil -- don't keep this in live data --OuroLootSV_hist = nil - -- Handle changes to the stored data format, in stages from oldest to - -- newest. This won't look coherent until multiple stages are happening. - if stored_datarev == nil then - self:Print("Transitioning saved data format to 15...") - for i,e in ipairs(OuroLootSV) do - if e.bosskill then - e.bossname, e.bosskill = e.bosskill, nil + -- Handle changes to the stored data format in stages from oldest to newest. + if OuroLootSV then + local dirty = false + if stored_datarev == nil then + self:Print("Transitioning saved data format to 15..."); dirty = true + for i,e in ipairs(OuroLootSV) do + if e.bosskill then + e.bossname, e.bosskill = e.bosskill, nil + end end + stored_datarev = 15 end - stored_datarev = 15 + if stored_datarev == 15 then + self:Print("Transitioning saved data format to 16..."); dirty = true + for i,e in ipairs(OuroLootSV) do + if e.kind == 'boss' then + e.maxsize, e.raiderlist, e.raidersnap = 0, nil, {} + end + end + OuroLootSV.raiders = OuroLootSV.raiders or {} + for name,r in pairs(OuroLootSV.raiders) do + r.subgroup = 0 + end + stored_datarev = 16 + end + if dirty then self:Print("Saved data has been massaged into shape.") end end - --if stored_datarev == 15 then.... _init(self) self.dprint('flow', "version strings:", revision_large, self.status_text) @@ -681,9 +713,9 @@ do local IsInInstance, UnitName, UnitIsConnected, UnitClass, UnitRace, UnitSex, - UnitLevel, UnitInRaid, UnitIsVisible, GetGuildInfo = + UnitLevel, UnitInRaid, UnitIsVisible, GetGuildInfo, GetRaidRosterInfo = IsInInstance, UnitName, UnitIsConnected, UnitClass, UnitRace, UnitSex, - UnitLevel, UnitInRaid, UnitIsVisible, GetGuildInfo + UnitLevel, UnitInRaid, UnitIsVisible, GetGuildInfo, GetRaidRosterInfo local time, difftime = time, difftime local R_ACTIVE, R_OFFLINE, R_LEFT = 1, 2, 3 @@ -727,15 +759,21 @@ g_loot.raiders[name] = { needinfo=true } end local r = g_loot.raiders[name] + -- We grab a bunch of return values here, but only pay attention to + -- them under specific circumstances. + local grri_name, connected, subgroup, level, class, _ + grri_name, _, subgroup, level, _, class, connected = GetRaidRosterInfo(i) + assert(name==grri_name, "UnitName =/= grri_name of same raidindex") + r.subgroup = subgroup if r.needinfo and UnitIsVisible(unit) then r.needinfo = nil - r.class = select(2,UnitClass(unit)) + r.class = class --select(2,UnitClass(unit)) r.race = select(2,UnitRace(unit)) r.sex = UnitSex(unit) - r.level = UnitLevel(unit) + r.level = level --UnitLevel(unit) r.guild = GetGuildInfo(unit) end - local connected = UnitIsConnected(unit) + --local connected = UnitIsConnected(unit) if connected and r.online ~= R_ACTIVE then r.join = r.join or now r.online = R_ACTIVE @@ -870,7 +908,7 @@ -- This is only a 'while' to make jumping out of it easy and still do cleanup below. while local_override or ((iquality >= self.threshold) and not opts.itemfilter[itemid]) do if (self.rebroadcast and (not from)) and not local_override then - self:broadcast('loot', recipient, itemid, count) + self:vbroadcast('loot', recipient, itemid, count) end if (not self.enabled) and (not local_override) then break end local signature = recipient .. iname .. (count or "") @@ -1211,32 +1249,6 @@ addon.sender_list.namesI = byindex end --- Message sending. --- See OCR_funcs.tag at the end of this file for incoming message treatment. -do - local function assemble(...) - local msg = ... - for i = 2, select('#',...) do - msg = msg .. '\a' .. (select(i,...) or "") - end - return msg - end - - -- broadcast('tag', <stuff>) - function addon:broadcast(...) - local msg = assemble(...) - self.dprint('comm', "<broadcast>:", msg) - -- the "GUILD" here is just so that we can also pick up on it - self:SendCommMessage(self.ident, msg, self.debug.comm and "GUILD" or "RAID") - end - -- whispercast(<to>, 'tag', <stuff>) - function addon:whispercast(to,...) - local msg = assemble(...) - self.dprint('comm', "<whispercast>@", to, ":", msg) - self:SendCommMessage(self.identTg, msg, "WHISPER", to) - end -end - function addon:DoPing() self:Print("Give me a ping, Vasili. One ping only, please.") self.sender_list.active = {} @@ -1361,7 +1373,7 @@ possible_st:SetData(g_loot) end - self.status_text = ("%s communicating as ident %s commrev %d"):format(self.revision,self.ident,self.commrev) + self.status_text = ("%s communicating as ident %s commrev %s"):format(self.revision,self.ident,self.commrev) self:RegisterComm(self.ident) self:RegisterComm(self.identTg, "OnCommReceivedNocache") @@ -1418,11 +1430,11 @@ addon.recent_boss = create_new_cache ('boss', 10, fixup_durations) -- Similar to _do_loot, but duration+ parms only present when locally generated. - local function _do_boss (self, reason, bossname, intag, duration, raiders) - self.dprint('loot',">>_do_boss, R:", reason, "B:", bossname, "T:", intag, - "D:", duration, "RL:", (raiders and #raiders or 'nil')) + local function _do_boss (self, reason, bossname, intag, maxsize, duration) + self.dprint('loot',">>_do_boss, R:", reason, "B:", bossname, + "T:", intag, "MS:", maxsize, "D:", duration) if self.rebroadcast and duration then - self:broadcast('boss', reason, bossname, intag) + self:vbroadcast('boss', reason, bossname, intag, maxsize) end -- This is only a loop to make jumping out of it easy, and still do cleanup below. while self.enabled do @@ -1447,8 +1459,9 @@ bossname = bossname, reason = reason, instance = intag, - duration = duration, -- these two deliberately may be nil - raiderlist = raiders and table.concat(raiders, ", ") + duration = duration, -- deliberately may be nil + raidersnap = CopyTable(g_loot.raiders), + maxsize = maxsize, } tinsert(candidates,c) end @@ -1456,7 +1469,7 @@ end self.dprint('loot',"<<_do_boss out") end - -- No wrapping layer for now + -- This exposes the function to OCR, and can be a wrapper layer later. addon.on_boss_broadcast = _do_boss function addon:_mark_boss_kill (index) @@ -2028,6 +2041,45 @@ ------ Player communication do + local select, tconcat, strsplit = select, table.concat, strsplit + --[[ old way: repeated string concatenations, BAD + new way: new table on every call, BAD + local msg = ... + for i = 2, select('#',...) do + msg = msg .. '\a' .. (select(i,...) or "") + end + return msg + ]] + local function assemble(t,...) + if select('#',...) > 0 then + local msg = {t,...} + -- tconcat requires strings, but T is known to be one already + for i = 2, #msg do + msg[i] = tostring(msg[i]) or "" + end + return tconcat (msg, '\a') + end + return t + end + + -- broadcast('tag', <stuff>) + -- vbroadcast('tag', <stuff>) + function addon:vbroadcast(tag,...) + return self:broadcast(self.commrev..tag,...) + end + function addon:broadcast(tag,...) + local msg = assemble(tag,...) + self.dprint('comm', "<broadcast>:", msg) + -- the "GUILD" here is just so that we can also pick up on it + self:SendCommMessage(self.ident, msg, self.debug.comm and "GUILD" or "RAID") + end + -- whispercast(<to>, 'tag', <stuff>) + function addon:whispercast(to,...) + local msg = assemble(...) + self.dprint('comm', "<whispercast>@", to, ":", msg) + self:SendCommMessage(self.identTg, msg, "WHISPER", to) + end + local function adduser (name, status, active) if status then addon.sender_list.names[name] = status end if active then addon.sender_list.active[name] = active end @@ -2059,12 +2111,21 @@ adduser (sender, nil, true) addon:CHAT_MSG_LOOT ("broadcast", recip, item, count, sender, extratext) end + OCR_funcs['16loot'] = OCR_funcs.loot OCR_funcs.boss = function (sender, _, reason, bossname, instancetag) - addon.dprint('comm', "DOTboss, sender", sender, "reason", reason, "name", bossname, "it", instancetag) + addon.dprint('comm', "DOTboss, sender", sender, "reason", reason, + "name", bossname, "it", instancetag) if not addon.enabled then return end adduser (sender, nil, true) - addon:on_boss_broadcast (reason, bossname, instancetag) + addon:on_boss_broadcast (reason, bossname, instancetag, --[[maxsize=]]0) + end + OCR_funcs['16boss'] = function (sender, _, reason, bossname, instancetag, maxsize) + addon.dprint('comm', "DOTboss16, sender", sender, "reason", reason, + "name", bossname, "it", instancetag, "size", maxsize) + if not addon.enabled then return end + adduser (sender, nil, true) + addon:on_boss_broadcast (reason, bossname, instancetag, maxsize) end OCR_funcs.bcast_req = function (sender)