From 4c2da4c4995fc7d9d3342a355d0b928d208ed884 Mon Sep 17 00:00:00 2001 From: Pawel Date: Sat, 17 Dec 2016 16:31:09 +0100 Subject: [PATCH] v7.1.4 - Time to die, localization fixes --- MaxDps.toc | 5 ++- helper.lua | 58 ++++++++++++--------------- timetodie.lua | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 153 insertions(+), 34 deletions(-) create mode 100644 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 -- 1.7.9.5