diff --git a/eos/saveddata/module.py b/eos/saveddata/module.py index 302c670cb..bd63caea6 100644 --- a/eos/saveddata/module.py +++ b/eos/saveddata/module.py @@ -955,6 +955,13 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut, M and ((gang and effect.isType("gang")) or not gang): effect.handler(fit, self, context, projectionRange, effect=effect) + def getCycleParametersForDps(self, reloadOverride=None): + # Special hack for breachers, since those are DoT and work independently of gun cycle + if self.isBreacher: + return CycleInfo(activeTime=1000, inactiveTime=0, quantity=math.inf, isInactivityReload=False) + else: + return self.getCycleParameters(reloadOverride=reloadOverride) + def getCycleParameters(self, reloadOverride=None): """Copied from new eos as well""" # Determine if we'll take into account reload time or not diff --git a/eos/utils/stats.py b/eos/utils/stats.py index a64cd31cb..aa0a9ae3d 100644 --- a/eos/utils/stats.py +++ b/eos/utils/stats.py @@ -45,6 +45,9 @@ class BreacherInfo: self.relative *= mul return self + def __truediv__(self, div): + return type(self)(absolute=self.absolute / div, relative=self.relative / div) + class DmgTypes: """ @@ -176,6 +179,17 @@ class DmgTypes: b *= mul return self + def __truediv__(self, div): + new = type(self)( + em=self._em / div, + thermal=self._thermal / div, + kinetic=self._kinetic / div, + explosive=self._explosive / div) + new.profile = self.profile + for k, v in self._breachers.items(): + new._breachers[k] = [b / div for b in v] + return new + def __bool__(self): return any(( self._em, self._thermal, self._kinetic, self._explosive, @@ -199,30 +213,6 @@ class DmgTypes: return value -class DmgInflicted(DmgTypes): - - @classmethod - def from_dmg_types(cls, dmg_types): - return cls(em=dmg_types.em, thermal=dmg_types.thermal, kinetic=dmg_types.kinetic, explosive=dmg_types.explosive, breacher=dmg_types.breacher) - - def __add__(self, other): - return type(self)( - em=self.em + other.em, - thermal=self.thermal + other.thermal, - kinetic=self.kinetic + other.kinetic, - explosive=self.explosive + other.explosive, - breacher=self.breacher + other.breacher) - - def __iadd__(self, other): - self.em += other.em - self.thermal += other.thermal - self.kinetic += other.kinetic - self.explosive += other.explosive - self.breacher += other.breacher - self._calcTotal() - return self - - class RRTypes: """Container for tank data stats.""" diff --git a/graphs/data/fitDamageStats/cache/time.py b/graphs/data/fitDamageStats/cache/time.py index 16ee6a595..72306b8c7 100644 --- a/graphs/data/fitDamageStats/cache/time.py +++ b/graphs/data/fitDamageStats/cache/time.py @@ -22,7 +22,7 @@ from copy import copy from eos.utils.float import floatUnerr from eos.utils.spoolSupport import SpoolOptions, SpoolType -from eos.utils.stats import DmgTypes, DmgInflicted +from eos.utils.stats import DmgTypes from graphs.data.base import FitDataCache @@ -170,27 +170,37 @@ class TimeCache(FitDataCache): def addDmg(ddKey, addedTime, addedDmg): if addedDmg.total == 0: return - intCacheDmg.setdefault(ddKey, {})[addedTime] = DmgInflicted.from_dmg_types(addedDmg) + addedDmg._breachers = {addedTime + k: v for k, v in addedDmg._breachers.items()} + intCacheDmg.setdefault(ddKey, {})[addedTime] = addedDmg # Modules for mod in src.item.activeModulesIter(): if not mod.isDealingDamage(): continue - cycleParams = mod.getCycleParameters(reloadOverride=True) + cycleParams = mod.getCycleParametersForDps(reloadOverride=True) if cycleParams is None: continue currentTime = 0 nonstopCycles = 0 + isBreacher = mod.isBreacher for cycleTimeMs, inactiveTimeMs, isInactivityReload in cycleParams.iterCycles(): cycleVolleys = [] volleyParams = mod.getVolleyParameters(spoolOptions=SpoolOptions(SpoolType.CYCLES, nonstopCycles, True)) for volleyTimeMs, volley in volleyParams.items(): cycleVolleys.append(volley) - addDmg(mod, currentTime + volleyTimeMs / 1000, volley) - if mod.isBreacher: + time = currentTime + volleyTimeMs / 1000 + if isBreacher: + time += 1 + addDmg(mod, time, volley) + if isBreacher: break - addDpsVolley(mod, currentTime, currentTime + cycleTimeMs / 1000, cycleVolleys) + timeStart = currentTime + timeFinish = currentTime + cycleTimeMs / 1000 + if isBreacher: + timeStart += 1 + timeFinish += 1 + addDpsVolley(mod, timeStart, timeFinish, cycleVolleys) if inactiveTimeMs > 0: nonstopCycles = 0 else: