Add base support for breacher pods to graphs

This commit is contained in:
DarkPhoenix
2024-11-12 16:58:18 +01:00
parent c660e4058c
commit ecc3f9fa7e
6 changed files with 65 additions and 9 deletions

View File

@@ -527,11 +527,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut, M
def getDps(self, spoolOptions=None, targetProfile=None, ignoreState=False, getSpreadDPS=False): def getDps(self, spoolOptions=None, targetProfile=None, ignoreState=False, getSpreadDPS=False):
dmgDuringCycle = DmgTypes.default() dmgDuringCycle = DmgTypes.default()
# Special hack for breachers, since those are DoT and work independently of gun cycle cycleParams = self.getCycleParametersForDps()
if self.isBreacher:
cycleParams = CycleInfo(activeTime=1000, inactiveTime=0, quantity=math.inf, isInactivityReload=False)
else:
cycleParams = self.getCycleParameters()
if cycleParams is None: if cycleParams is None:
return dmgDuringCycle return dmgDuringCycle
volleyParams = self.getVolleyParameters(spoolOptions=spoolOptions, targetProfile=targetProfile, ignoreState=ignoreState) 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): and ((gang and effect.isType("gang")) or not gang):
effect.handler(fit, self, context, projectionRange, effect=effect) 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): def getCycleParameters(self, reloadOverride=None):
"""Copied from new eos as well""" """Copied from new eos as well"""
# Determine if we'll take into account reload time or not # Determine if we'll take into account reload time or not

View File

@@ -205,6 +205,30 @@ class DmgTypes:
return value 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: class RRTypes:
"""Container for tank data stats.""" """Container for tank data stats."""

View File

@@ -22,7 +22,7 @@ from copy import copy
from eos.utils.float import floatUnerr from eos.utils.float import floatUnerr
from eos.utils.spoolSupport import SpoolOptions, SpoolType 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 from graphs.data.base import FitDataCache
@@ -170,13 +170,13 @@ class TimeCache(FitDataCache):
def addDmg(ddKey, addedTime, addedDmg): def addDmg(ddKey, addedTime, addedDmg):
if addedDmg.total == 0: if addedDmg.total == 0:
return return
intCacheDmg.setdefault(ddKey, {})[addedTime] = addedDmg intCacheDmg.setdefault(ddKey, {})[addedTime] = DmgInflicted.from_dmg_types(addedDmg)
# Modules # Modules
for mod in src.item.activeModulesIter(): for mod in src.item.activeModulesIter():
if not mod.isDealingDamage(): if not mod.isDealingDamage():
continue continue
cycleParams = mod.getCycleParameters(reloadOverride=True) cycleParams = mod.getCycleParametersForDps(reloadOverride=True)
if cycleParams is None: if cycleParams is None:
continue continue
currentTime = 0 currentTime = 0
@@ -184,9 +184,12 @@ class TimeCache(FitDataCache):
for cycleTimeMs, inactiveTimeMs, isInactivityReload in cycleParams.iterCycles(): for cycleTimeMs, inactiveTimeMs, isInactivityReload in cycleParams.iterCycles():
cycleVolleys = [] cycleVolleys = []
volleyParams = mod.getVolleyParameters(spoolOptions=SpoolOptions(SpoolType.CYCLES, nonstopCycles, True)) volleyParams = mod.getVolleyParameters(spoolOptions=SpoolOptions(SpoolType.CYCLES, nonstopCycles, True))
for volleyTimeMs, volley in volleyParams.items(): for volleyTimeMs, volley in volleyParams.items():
cycleVolleys.append(volley) cycleVolleys.append(volley)
addDmg(mod, currentTime + volleyTimeMs / 1000, volley) addDmg(mod, currentTime + volleyTimeMs / 1000, volley)
if mod.isBreacher:
break
addDpsVolley(mod, currentTime, currentTime + cycleTimeMs / 1000, cycleVolleys) addDpsVolley(mod, currentTime, currentTime + cycleTimeMs / 1000, cycleVolleys)
if inactiveTimeMs > 0: if inactiveTimeMs > 0:
nonstopCycles = 0 nonstopCycles = 0

View File

@@ -98,6 +98,8 @@ def getApplicationPerKey(src, tgt, atkSpeed, atkAngle, distance, tgtSpeed, tgtAn
tgt=tgt, tgt=tgt,
distance=distance, distance=distance,
tgtSigRadius=tgtSigRadius) tgtSigRadius=tgtSigRadius)
elif mod.isBreacher:
applicationMap[mod] = 1 if inLockRange else 0
for drone in src.item.activeDronesIter(): for drone in src.item.activeDronesIter():
if not drone.isDealingDamage(): if not drone.isDealingDamage():
continue continue

View File

@@ -89,7 +89,7 @@ class FitDamageStatsGraph(FitGraph):
cols = [] cols = []
if not GraphSettings.getInstance().get('ignoreResists'): if not GraphSettings.getInstance().get('ignoreResists'):
cols.append('Target Resists') cols.append('Target Resists')
cols.extend(('Speed', 'SigRadius', 'Radius')) cols.extend(('Speed', 'SigRadius', 'Radius', 'FullHP'))
return cols return cols
# Calculation stuff # Calculation stuff

View File

@@ -197,6 +197,30 @@ class SignatureRadiusColumn(GraphColumn):
SignatureRadiusColumn.register() 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): class ShieldAmountColumn(GraphColumn):
name = 'ShieldAmount' name = 'ShieldAmount'