diff core.lua @ 10:67b8537e8432

More work on ML/EQDKP generator and its spawned subprojects.
author Farmbuyer of US-Kilrogg <farmbuyer@gmail.com>
date Tue, 28 Jun 2011 07:36:26 +0000
parents 30ba1f35e164
children 952c3ac0e783
line wrap: on
line diff
--- a/core.lua	Fri Jun 17 20:30:46 2011 +0000
+++ b/core.lua	Tue Jun 28 07:36:26 2011 +0000
@@ -158,9 +158,8 @@
 local opts				= nil
 
 local pairs, ipairs, tinsert, tremove, tonumber = pairs, ipairs, table.insert, table.remove, tonumber
-
 local pprint, tabledump = addon.pprint, flib.tabledump
-
+local GetNumRaidMembers = GetNumRaidMembers
 -- En masse forward decls of symbols defined inside local blocks
 local _register_bossmod
 local makedate, create_new_cache, _init
@@ -251,10 +250,11 @@
 do
 	local caches = {}
 	local cleanup_group = AnimTimerFrame:CreateAnimationGroup()
+	local time = _G.time
 	cleanup_group:SetLooping("REPEAT")
 	cleanup_group:SetScript("OnLoop", function(cg)
 		addon.dprint('cache',"OnLoop firing")
-		local now = GetTime()
+		local now = time()
 		local alldone = true
 		-- this is ass-ugly
 		for _,c in ipairs(caches) do
@@ -275,7 +275,7 @@
 	end)
 
 	local function _add (cache, x)
-		tinsert(cache, {t=GetTime(),m=x})
+		tinsert(cache, {t=time(),m=x})
 		if not cleanup_group:IsPlaying() then
 			addon.dprint('cache', cache.name, "STARTING animation group")
 			cache.cleanup:SetDuration(2)  -- hmmm
@@ -355,8 +355,8 @@
 end
 
 function addon:OnEnable()
-	self:RegisterEvent "PLAYER_LOGOUT"
-	self:RegisterEvent "RAID_ROSTER_UPDATE"
+	self:RegisterEvent("PLAYER_LOGOUT")
+	self:RegisterEvent("RAID_ROSTER_UPDATE")
 
 	-- Cribbed from Talented.  I like the way jerry thinks: the first argument
 	-- can be a format spec for the remainder of the arguments.  (The new
@@ -401,6 +401,7 @@
 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
@@ -423,26 +424,113 @@
 	OuroLootSV_hist = self.history_all
 end
 
-function addon:RAID_ROSTER_UPDATE (event)
-	if GetNumRaidMembers() > 0 then
+do
+	local IsInInstance, UnitName, UnitIsConnected, UnitClass, UnitRace, UnitSex,
+				UnitLevel, UnitInRaid, UnitIsVisible, GetGuildInfo =
+	      IsInInstance, UnitName, UnitIsConnected, UnitClass, UnitRace, UnitSex,
+		  		UnitLevel, UnitInRaid, UnitIsVisible, GetGuildInfo
+	local time, difftime = time, difftime
+	local R_ACTIVE, R_OFFLINE, R_LEFT = 1, 2, 3
+
+	local lastevent, now = 0, 0
+	local timer_handle
+
+	function addon:CheckRoster (leaving_p, now_a)
+		if not g_loot.raiders then return end -- bad transition
+
+		now = now_a or time()
+
+		if leaving_p then
+			for name,r in pairs(g_loot.raiders) do
+				r.leave = r.leave or now
+			end
+			return
+		end
+
+		for name,r in pairs(g_loot.raiders) do
+			if r.online ~= R_LEFT and not UnitInRaid(name) then
+				r.online = R_LEFT
+				r.leave = now
+			end
+		end
+
+		local redo = false
+		for i = 1, GetNumRaidMembers() do
+			local unit = 'raid'..i
+			local name = UnitName(unit)
+			-- No, that's not my typo, it really is "uknownbeing" in Blizzard's code.
+			if name and name ~= UNKNOWN and name ~= UNKNOWNOBJECT and name ~= UKNOWNBEING then
+				if not g_loot.raiders[name] then
+					g_loot.raiders[name] = { needinfo=true }
+				end
+				local r = g_loot.raiders[name]
+				if r.needinfo and UnitIsVisible(unit) then
+					r.needinfo = nil
+					r.class    = select(2,UnitClass(unit))
+					r.race     = select(2,UnitRace(unit))
+					r.sex      = UnitSex(unit)
+					r.level    = UnitLevel(unit)
+					r.guild    = GetGuildInfo(unit)
+				end
+				local connected = UnitIsConnected(unit)
+				if connected and r.online ~= R_ACTIVE then
+					r.join = r.join or now
+					r.online = R_ACTIVE
+				elseif (not connected) and r.online ~= R_OFFLINE then
+					r.leave = now
+					r.online = R_OFFLINE
+				end
+				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
+		end
+	end
+
+	function addon:RAID_ROSTER_UPDATE (event)
+		if GetNumRaidMembers() == 0 then
+			-- 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.popped = nil
+				self:UnregisterEvent("CHAT_MSG_LOOT")
+				self:CheckRoster(--[[leaving raid]]true)
+			end
+			return
+		end
+
 		local inside,whatkind = IsInInstance()
 		if inside and (whatkind == "pvp" or whatkind == "arena") then
 			return self.dprint('flow', "got RRU event but in pvp zone, bailing")
 		end
+
+		local docheck = self.enabled
 		if event == "Activate" then
 			-- dispatched manually from Activate
-			self:RegisterEvent "CHAT_MSG_LOOT"
+			self:RegisterEvent("CHAT_MSG_LOOT")
 			_register_bossmod(self)
+			docheck = true
 		elseif event == "RAID_ROSTER_UPDATE" then
+			-- hot code path, be careful
+
 			-- event registration from onload, joined a raid, maybe show popup
-			if opts.popup_on_join and not self.popped then
+			if (not self.popped) and opts.popup_on_join then
 				self.popped = StaticPopup_Show "OUROL_REMIND"
 				self.popped.data = self
+				return
 			end
 		end
-	else
-		self:UnregisterEvent "CHAT_MSG_LOOT"
-		self.popped = nil
+		if docheck and not InCombatLockdown() then
+			now = time()
+			if difftime(now,lastevent) > 45 then
+				lastevent = now
+				self:CheckRoster(false,now)
+			end
+		end
 	end
 end
 
@@ -645,12 +733,13 @@
 
 ------ On/off
 function addon:Activate (opt_threshold, opt_bcast_only)
-	self:RegisterEvent "RAID_ROSTER_UPDATE"
+	self:RegisterEvent("RAID_ROSTER_UPDATE")
+	self:RegisterEvent("PLAYER_ENTERING_WORLD","RAID_ROSTER_UPDATE")
 	self.popped = true
 	if GetNumRaidMembers() > 0 then
 		self:RAID_ROSTER_UPDATE("Activate")
 	elseif self.debug.notraid then
-		self:RegisterEvent "CHAT_MSG_LOOT"
+		self:RegisterEvent("CHAT_MSG_LOOT")
 		_register_bossmod(self)
 	elseif g_restore_p then
 		g_restore_p = nil
@@ -677,8 +766,9 @@
 function addon:Deactivate()
 	self.enabled = false
 	self.rebroadcast = false
-	self:UnregisterEvent "RAID_ROSTER_UPDATE"
-	self:UnregisterEvent "CHAT_MSG_LOOT"
+	self:UnregisterEvent("RAID_ROSTER_UPDATE")
+	self:UnregisterEvent("PLAYER_ENTERING_WORLD")
+	self:UnregisterEvent("CHAT_MSG_LOOT")
 	self:Print("Ouro Raid Loot deactivated.")
 end
 
@@ -819,7 +909,7 @@
 		-- FIXME printed could be too large if entries were deleted, how much do we care?
 		self.sharder = g_loot.autoshard
 	else
-		g_loot = { printed = {} }
+		g_loot = { printed = {}, raiders = {} }
 		g_loot.saved = g_saved_tmp; g_saved_tmp = nil	-- potentially restore across a clear
 	end
 
@@ -1093,10 +1183,11 @@
 		if not done_todays_date then do_todays_date() end
 
 		local h, m = GetGameTime()
-		local localuptime = math.floor(GetTime())
+		--local localuptime = math.floor(GetTime())
+		local time_t = time()
 		e.hour = h
 		e.minute = m
-		e.stamp = localuptime
+		e.stamp = time_t --localuptime
 		local index = #g_loot + 1
 		g_loot[index] = e
 		return index
@@ -1126,9 +1217,10 @@
 		name = name,
 		date = makedate(),
 		count = #g_loot,
-		forum = g_loot.forum,
-		attend = g_loot.attend,
 	}
+	for text in self:registered_textgen_iter() do
+		save[text] = g_loot[text]
+	end
 	self:Print("Saving current loot texts to #%d '%s'", n, name)
 	g_loot.saved[n] = save
 	return self:save_list()
@@ -1144,8 +1236,9 @@
 	self:Clear(--[[verbose_p=]]false)
 	-- Clear will already have displayed the window, and re-selected the first
 	-- tab.  Set these up for when the text tabs are clicked.
-	g_loot.forum = save.forum
-	g_loot.attend = save.attend
+	for text in self:registered_textgen_iter() do
+		g_loot[text] = save[text]
+	end
 end
 
 function addon:save_delete(num)