Introduction

This information was created to contribute to the improvement of the Recount WoW addon.  My intention was to post this information directly on the wowace forum which supports Recount.

For sometime I have noticed an issue with the DPS and activity timer values in Recount.  After investigating Recount versions 77004 and 77485, it was uncovered that an assumption in the lua code throws the players activity time value off.  Therefore DPS value is also off because it is based on activity time.

Below are my findings and code fixes.  Patch files are also available for those interested.

Patch Files

My patch for Recount r79988 (mod-r79988.patch.zip)

My patch for Recount r78174 (mod-r78174.patch.zip)
My patch for Recount r77485 (mod-r77485.patch.zip)
My patch for Recount r77004 (mod-r77004.patch.zip)

Details

The core change to improving or fixing the units activity time value is to use the 3.5 second activity cap correctly in Recount:AddTimeEvent function in Tracker.lua file.  My testing showed that the 3.5 second limit was being trigger for situation when should not.

The most noticable of the time counter issue was that Recount itself reported two different activity times for a solo player on a single battle.  What was stranger, was that the detailed battle time was larger then the rough battle start and stop times included with the popup menu title for the individual battle.

The issue of the solo player on a single battle time was found to deviate more for toons that use high speed weapons like rogues, while the slower caster type toons was not so far off.  It was uncover that the a player upon entering battle was always having 3.5 seconds of battle time being added to their battle time.  The reason being is a player activity is only recorded while in battle, so the last activity from this player will be the last battle.  That is usually more then 3.5 seconds, so 3.5 seconds was added to active battle time eventhough battle just started.  My recommended fix would be to set all players last LastAbility time to the start time of a new battle.  My fix changes, shown below in red, are in Recount:PutInCombat function in Recount.lua file.

	...
	function Recount:PutInCombat()
		Recount.InCombat=true
		Recount.InCombatT=Recount.CurTime
		Recount.InCombatF=date("%H:%M:%S")
		Recount.FightingWho=""
		Recount.FightingLevel=0
		
		Recount:FixLastTime()
	
		if Recount.db.profile.MainWindow.AutoHide then
		...
	

To complete this fix, the end of battle time mark is also need by calling the new Recount:FixEndTime function in Recount.lua file.

	...
	function Recount:LeaveCombat(Time)
	
		if Recount.db.profile.MainWindow.AutoHide then
			Recount.RefreshMainWindow()
			Recount.MainWindow:Show()
		end
	
		--Did we actually fight someone?
		Recount.InCombat=false
		if (Recount.FightingWho=="") then
			return
		end
		
		Recount:FixEndTime()
	
		-- Elsia: Only sync for actual fights
		...
	
	...
	function Recount:FixLastTime()
		local Time=GetTime()
		for name,v in pairs(Recount.db2.combatants) do
			v.LastAbility=Time
		end
	end
	
	function Recount:FixEndTime()
		local Time=GetTime()
		local Adding
		local DamFlag, HealFlag, ActFlag = {false,false,false}
		
		for name,v in pairs(Recount.db2.combatants) do
			if (v.LastAbility) then 
				Adding=Time-v.LastAbility
				Adding=math.floor(100*Adding+0.5)/100
				
				if (v.Fights and v.Fights["CurrentFightData"]) then
					DamFlag = ((v.Fights["CurrentFightData"].Damage ~= nil) and (v.Fights["CurrentFightData"].Damage > 0))
					HealFlag = ((v.Fights["CurrentFightData"].Healing ~= nil) and (v.Fights["CurrentFightData"].Healing > 0))
					ActFlag = ((v.Fights["CurrentFightData"].ActiveTime ~= nil) and (v.Fights["CurrentFightData"].ActiveTime > 0))
				end
				
				if (DamFlag or HealFlag or ActFlag) then
					Recount:AddOwnerPetLazySyncAmount(v,"ActiveTime", Adding)
					Recount:AddAmount(v,"ActiveTime",Adding)
				end
				if (DamFlag) then Recount:AddAmount(v,"TimeDamage",Adding) end
				if (HealFlag) then Recount:AddAmount(v,"TimeHeal",Adding) end
			end
		end
	end
	
	function Recount:DelayedResizeWindows()
	...
	

Another place the 3.5 second limit and time bloat is invoked, is everytime a new target unit seen.  And although most of these units and information is currectly ignore, it should be corrected.  This can easily be corrected by setting LastActive time to the current time at creation.  My recommended fix would be to set the LastActive time when init or creating a unit.  My fix changes, shown below in red, are in Recount:InitCombatant function in Recount.lua file.

	...
	function Recount:InitCombatant(name)
		local combatant = Recount.db2.combatants[name]
		
		combatant.Fights = {}
		combatant.LastActive = time()
	end
	...
	

The new target unit creatation without the LastActive being set issue, uncovered another problem that the unneeded units clean up code is too aggressive.  What was found was that a unit being attacked or attacking you is being created and destroy in memory each time damage is taken or given from it.  I recommend letting the idler loop code take care of the memory cleanup (say outside of active battle).  I made the following changes in red in Recount.lua and GUI_Main.lua files to address this issue

	...
	function Recount:TimeTick()
	...
					--Recount:Print("gc: "..name)
					Recount:DetermineType(name)
	
					if v.type=="Pet" then
						v.enClass="PET"
					elseif not v.isPlayer then
						v.enClass="MOB"
					end
				end
			end
			
			if (Recount:CheckRetention(name)) then
				-- prior check if CheckRetention does not think it should be removed
				local idler = v.checkLater or v.type == "Unknown" or v.enClass == "UNKNOWN" or (not Recount.db.profile.Filters.Data[v.type] and not Recount.db.profile.Filters.Show[v.type])
				
				v.LastActive = v.LastActive or Time
				if idler and Time-v.LastActive > 30 then
					Recount:DeleteCombatant(name,true)
					gotdeleted = true
		--		elseif idler then
		--			Recount:Print(name.."t: "..(Time-v.LastActive))
				end
			else
				-- DeleteCombatant in CheckRetention does not currently delete, so delete it now
				v.LastActive = v.LastActive or Time
				if Time-v.LastActive > 30 then
					Recount:DeleteCombatant(name,true)
					gotdeleted = true
				end
			end
			
		
			if name == Recount.Player and not v.inGroup then
			...
			
	...		
	function Recount:DeleteCombatant(name, deleteNow)
		deleteNow = deleteNow or false
		
		if not Recount.db2.combatants[name] then return end
		--if (not deleteNow and Recount.InCombat==true) then return end		-- let idler loop clean up
		if not deleteNow then return end
	
		if Recount.db2.combatants[name].Owner then
		...
	

Other Findings

Sadly it was uncovered that recount does on occasion not include some of your damage.  What I found was about 1 in 10 times a rogue intial attack ambush was not recorded by Recount.  I also found about 1 and 20 times a casters initial attack damage was not recorded by Recount.  This is quite understandable problem because I have seem this same issue with other addons since the 2.4 WoW changes.  I could not easily come up with straight forward clean code fix, so I hope the active developers can fix it.

Conclusion

I hope you and the developer/author like and include my changes in Recount in the near future.

Contact

Enter the information below and clicking the send button to contact me

Your Name:
Your E-mail Address:
E-mail Subject:
Message:
Fill in the two words in to the right
This page is for humans use only -->

[ Home ]

© 2008 Brian Beardmore.  All rights reserved.
Last Updated on 08.10.2008