Quantcast

v7.1.4 - Time to die, localization fixes

Pawel [12-17-16 - 15:31]
v7.1.4 - Time to die, localization fixes
Filename
MaxDps.toc
helper.lua
timetodie.lua
diff --git a/MaxDps.toc b/MaxDps.toc
index 71a3416..f7d1991 100644
--- a/MaxDps.toc
+++ b/MaxDps.toc
@@ -1,6 +1,6 @@
 ## Title: MaxDps
 ## Notes: Rotation helper framework.
-## Version: 7.1.3
+## Version: 7.1.4
 ## Author: Kaminaris
 ## Interface: 70100
 ## SavedVariables: MaxDpsOptions
@@ -20,4 +20,5 @@ Libs\AceConfig-3.0\AceConfig-3.0.xml

 core.lua
 buttons.lua
-helper.lua
\ No newline at end of file
+helper.lua
+timetodie.lua
\ No newline at end of file
diff --git a/helper.lua b/helper.lua
index 5e4522b..a90ad8d 100644
--- a/helper.lua
+++ b/helper.lua
@@ -114,6 +114,12 @@ function MaxDps:EndCast(target)
 	return timeShift, spell, gcd;
 end

+function MaxDps:SameSpell(spell1, spell2)
+	local spellName1 = GetSpellInfo(spell1);
+	local spellName2 = GetSpellInfo(spell2);
+	return spellName1 == spellName2;
+end
+
 function MaxDps:TargetPercentHealth()
 	local health = UnitHealth('target');
 	if health <= 0 then
@@ -193,38 +199,6 @@ function MaxDps:Cooldown(spell, timeShift)
 	end;
 end

-function MaxDps:TimeToDie(health)
-	local unit = UnitGUID('target');
-	if unit ~= TDDps_TargetGuid then
-		return INF;
-	end
-
-	health = health or UnitHealth('target');
-
-	if health == UnitHealthMax('target') then
-		TD_Hp0, TD_T0, TD_Hpm, TD_Tm = nil, nil, nil, nil;
-		return INF;
-	end
-
-	local time = GetTime();
-
-	if not TD_Hp0 then
-		TD_Hp0, TD_T0 = health, time;
-		TD_Hpm, TD_Tm = health, time;
-		--print('phial3');
-		return INF;
-	end
-
-	TD_Hpm = (TD_Hpm + health) * .5;
-	TD_Tm = (TD_Tm + time) * .5;
-
-	if TD_Hpm >= TD_Hp0 then
-		TD_Hp0, TD_T0, TD_Hpm, TD_Tm = nil, nil, nil, nil;
-	else
-		return health * (TD_T0 - TD_Tm) / (TD_Hpm - TD_Hp0);
-	end
-end
-
 function MaxDps:Mana(minus, timeShift)
 	local _, casting = GetManaRegen();
 	local mana = UnitPower('player', 0) - minus + (casting * timeShift);
@@ -239,3 +213,23 @@ function MaxDps:Bloodlust(timeShift)

 	return false;
 end
+
+function MaxDps:FormatTime(left)
+	local seconds = left >= 0        and math.floor((left % 60)    / 1   ) or 0;
+	local minutes = left >= 60       and math.floor((left % 3600)  / 60  ) or 0;
+	local hours   = left >= 3600     and math.floor((left % 86400) / 3600) or 0;
+	local days    = left >= 86400    and math.floor((left % 31536000) / 86400) or 0;
+	local years   = left >= 31536000 and math.floor( left / 31536000) or 0;
+
+	if years > 0 then
+		return string.format("%d [Y] %d [D] %d:%d:%d [H]", years, days, hours, minutes, seconds);
+	elseif days > 0 then
+		return string.format("%d [D] %d:%d:%d [H]", days, hours, minutes, seconds);
+	elseif hours > 0 then
+		return string.format("%d:%d:%d [H]", hours, minutes, seconds);
+	elseif minutes > 0 then
+		return string.format("%d:%d [M]", minutes, seconds);
+	else
+		return string.format("%d [S]", seconds);
+	end
+end
diff --git a/timetodie.lua b/timetodie.lua
new file mode 100644
index 0000000..dd4880c
--- /dev/null
+++ b/timetodie.lua
@@ -0,0 +1,124 @@
+local INF = 2147483647;
+
+function MaxDps:InitTTD(maxSamples, interval)
+	self.ttd = {};
+	self.ttd.Windows = maxSamples or 8; -- Max number of samples
+
+	-- Code variables
+	self.ttd.GUID = nil; -- Remember GUID of mob you are tracking
+	self.ttd.MaxValue = 0; -- Remember max HP for relative shift
+	self.ttd.Last = GetTime(); -- Remember last update
+	self.ttd.Start = nil; -- First data collection time for relative shift
+	self.ttd.Index = 0; -- Current ring buffer index
+	self.ttd.Times = {}; -- Ring buffer data - data_x
+	self.ttd.Values = {}; -- Ring buffer data - data_y
+	self.ttd.Samples = 0; -- Number of collected (active) samples
+	self.ttd.Estimate = nil; -- Estimated end time (not relative)
+	self.ttd.TimeToDie = INF; -- Estimated end time relative
+
+	self.ttd.Timer = self:ScheduleRepeatingTimer('TimeToDie', interval or 1.5);
+end
+
+function MaxDps:DisableTTD()
+	if self.ttd.Timer then
+		self:CancelTimer(self.ttd.Timer);
+	end
+end
+
+function MaxDps:TimeToDie(target)
+	target = target or 'target';
+
+	-- Query current time (throttle updating over time)
+	local now = GetTime();
+
+	-- Current data
+	local data = UnitHealth(target);
+
+	-- Reset data?
+	if data == UnitHealthMax(target) or not self.ttd.GUID or self.ttd.GUID ~= UnitGUID(target) then
+		self.ttd.GUID = nil
+		self.ttd.Start = nil
+		self.ttd.Estimate = nil
+	end
+
+	-- No start time?
+	if not self.ttd.Start or not self.ttd.GUID then
+		self.ttd.Start = now;
+		self.ttd.Index = 0;
+		self.ttd.Samples = 0;
+		self.ttd.MaxValue = UnitHealthMax(target) / 2;
+		self.ttd.GUID = UnitGUID(target);
+	end
+
+	-- Remember current time
+	self.ttd.Last = now;
+
+	-- Save new data (Use relative values to prevent 'overflow')
+	self.ttd.Values[self.ttd.Index] = data - self.ttd.MaxValue;
+	self.ttd.Times[self.ttd.Index] = now - self.ttd.Start;
+
+	-- Next index
+	self.ttd.Index = self.ttd.Index + 1;
+
+	-- Update number of active samples
+	if self.ttd.Index > self.ttd.Samples then
+		self.ttd.Samples = self.ttd.Index;
+	end
+
+	-- Using table as ring buffer
+	if self.ttd.Index >= self.ttd.Windows then
+		self.ttd.Index = 0;
+	end
+
+	-- Min number of samples
+	if self.ttd.Samples >= 2 then
+		-- Estimation variables
+		local SS_xy, SS_xx, x_M, y_M = 0, 0, 0, 0;
+
+		-- Calc pre-solution values
+		for index = 0, self.ttd.Samples - 1 do
+			-- Calc mean value
+			x_M = x_M + self.ttd.Times[index] / self.ttd.Samples;
+			y_M = y_M + self.ttd.Values[index] / self.ttd.Samples;
+
+			-- Calc sum of squares
+			SS_xx = SS_xx + self.ttd.Times[index] * self.ttd.Times[index];
+			SS_xy = SS_xy + self.ttd.Times[index] * self.ttd.Values[index];
+		end
+
+		-- Few last additions to mean value / sum of squares
+		SS_xx = SS_xx - self.ttd.Samples * x_M * x_M;
+		SS_xy = SS_xy - self.ttd.Samples * x_M * y_M;
+
+		-- Calc a_0, a_1 of linear interpolation (data_y = a_1 * data_x + a_0)
+		local a_1 = SS_xy / SS_xx;
+		local a_0 = (y_M - a_1 * x_M) + self.ttd.MaxValue;
+
+		-- Find zero-point (Switch back to absolute values)
+		local x = -(a_0 / a_1);
+
+		-- Valid/Usable solution
+		if a_1 and a_1 < 1 and a_0 and a_0 > 0 and x and x > 0 then
+			self.ttd.Estimate = x + self.ttd.Start;
+			-- Fallback
+		else
+			self.ttd.Estimate = nil;
+		end
+
+		-- Not enough data
+	else
+		self.ttd.Estimate = nil;
+	end
+
+	-- No/False information
+	if not self.ttd.Estimate then
+		self.ttd.TimeToDie = INF;
+		-- Already over
+	elseif now > self.ttd.Estimate then
+		self.ttd.TimeToDie = 0;
+	else
+		self.ttd.TimeToDie = self.ttd.Estimate - now;
+	end
+
+	return self.ttd.TimeToDie;
+end
\ No newline at end of file