From ecc3f9fa7eeebac4710f46b1e7236b0afc2091de Mon Sep 17 00:00:00 2001 From: DarkPhoenix Date: Tue, 12 Nov 2024 16:58:18 +0100 Subject: [PATCH] Add base support for breacher pods to graphs --- eos/saveddata/module.py | 13 ++++++---- eos/utils/stats.py | 24 +++++++++++++++++++ graphs/data/fitDamageStats/cache/time.py | 9 ++++--- .../data/fitDamageStats/calc/application.py | 2 ++ graphs/data/fitDamageStats/graph.py | 2 +- .../attributeDisplayGraph.py | 24 +++++++++++++++++++ 6 files changed, 65 insertions(+), 9 deletions(-) diff --git a/eos/saveddata/module.py b/eos/saveddata/module.py index 49b01bf8e..89bb9ef55 100644 --- a/eos/saveddata/module.py +++ b/eos/saveddata/module.py @@ -527,11 +527,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut, M def getDps(self, spoolOptions=None, targetProfile=None, ignoreState=False, getSpreadDPS=False): dmgDuringCycle = DmgTypes.default() - # Special hack for breachers, since those are DoT and work independently of gun cycle - if self.isBreacher: - cycleParams = CycleInfo(activeTime=1000, inactiveTime=0, quantity=math.inf, isInactivityReload=False) - else: - cycleParams = self.getCycleParameters() + cycleParams = self.getCycleParametersForDps() if cycleParams is None: return dmgDuringCycle volleyParams = self.getVolleyParameters(spoolOptions=spoolOptions, targetProfile=targetProfile, ignoreState=ignoreState) @@ -965,6 +961,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 456c079ce..26d75cbd2 100644 --- a/eos/utils/stats.py +++ b/eos/utils/stats.py @@ -205,6 +205,30 @@ 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 8064810cc..667a299ed 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 +from eos.utils.stats import DmgTypes, DmgInflicted from graphs.data.base import FitDataCache @@ -170,13 +170,13 @@ class TimeCache(FitDataCache): def addDmg(ddKey, addedTime, addedDmg): if addedDmg.total == 0: return - intCacheDmg.setdefault(ddKey, {})[addedTime] = addedDmg + intCacheDmg.setdefault(ddKey, {})[addedTime] = DmgInflicted.from_dmg_types(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 @@ -184,9 +184,12 @@ class TimeCache(FitDataCache): 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: + break addDpsVolley(mod, currentTime, currentTime + cycleTimeMs / 1000, cycleVolleys) if inactiveTimeMs > 0: nonstopCycles = 0 diff --git a/graphs/data/fitDamageStats/calc/application.py b/graphs/data/fitDamageStats/calc/application.py index 6950687a5..eb75750fc 100644 --- a/graphs/data/fitDamageStats/calc/application.py +++ b/graphs/data/fitDamageStats/calc/application.py @@ -98,6 +98,8 @@ def getApplicationPerKey(src, tgt, atkSpeed, atkAngle, distance, tgtSpeed, tgtAn tgt=tgt, distance=distance, tgtSigRadius=tgtSigRadius) + elif mod.isBreacher: + applicationMap[mod] = 1 if inLockRange else 0 for drone in src.item.activeDronesIter(): if not drone.isDealingDamage(): continue diff --git a/graphs/data/fitDamageStats/graph.py b/graphs/data/fitDamageStats/graph.py index bde7d71b6..bae69f435 100644 --- a/graphs/data/fitDamageStats/graph.py +++ b/graphs/data/fitDamageStats/graph.py @@ -89,7 +89,7 @@ class FitDamageStatsGraph(FitGraph): cols = [] if not GraphSettings.getInstance().get('ignoreResists'): cols.append('Target Resists') - cols.extend(('Speed', 'SigRadius', 'Radius')) + cols.extend(('Speed', 'SigRadius', 'Radius', 'FullHP')) return cols # Calculation stuff diff --git a/gui/builtinViewColumns/attributeDisplayGraph.py b/gui/builtinViewColumns/attributeDisplayGraph.py index e993e9d23..19d507ff1 100644 --- a/gui/builtinViewColumns/attributeDisplayGraph.py +++ b/gui/builtinViewColumns/attributeDisplayGraph.py @@ -197,6 +197,30 @@ class SignatureRadiusColumn(GraphColumn): SignatureRadiusColumn.register() +class FullHpColumn(GraphColumn): + + name = 'FullHP' + stickPrefixToValue = True + + def __init__(self, fittingView, params): + super().__init__(fittingView, 68) + + def _getValue(self, stuff): + if isinstance(stuff, Fit): + full_hp = stuff.hp.get('shield', 0) + stuff.hp.get('armor', 0) + stuff.hp.get('hull', 0) + elif isinstance(stuff, TargetProfile): + full_hp = stuff.hp + else: + full_hp = 0 + return full_hp, 'hp' + + def _getFitTooltip(self): + return 'Total raw HP' + + +FullHpColumn.register() + + class ShieldAmountColumn(GraphColumn): name = 'ShieldAmount'