From 313264a49fafecd4a2a0b55d579006cd1e201ed8 Mon Sep 17 00:00:00 2001 From: DarkPhoenix Date: Fri, 16 Aug 2019 20:55:25 +0300 Subject: [PATCH] Implement RR parameter getter --- eos/saveddata/module.py | 48 +++++++++++++++++++++++- eos/utils/stats.py | 81 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+), 1 deletion(-) diff --git a/eos/saveddata/module.py b/eos/saveddata/module.py index 5831bbe1a..7b49e0dcf 100644 --- a/eos/saveddata/module.py +++ b/eos/saveddata/module.py @@ -30,7 +30,7 @@ from eos.saveddata.mutator import Mutator from eos.utils.cycles import CycleInfo, CycleSequence from eos.utils.float import floatUnerr from eos.utils.spoolSupport import calculateSpoolup, resolveSpoolOptions -from eos.utils.stats import DmgTypes +from eos.utils.stats import DmgTypes, RRTypes pyfalog = Logger(__name__) @@ -134,6 +134,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut): self.__charge = None self.__baseVolley = None + self.__baseRRAmount = None self.__baseRemoteReps = None self.__miningyield = None self.__reloadTime = None @@ -482,6 +483,50 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut): explosive=dmgDuringCycle.explosive * dpsFactor) return dps + def getRepAmountParameters(self, spoolOptions=None, ignoreState=False): + if self.isEmpty or (self.state < FittingModuleState.ACTIVE and not ignoreState): + return {} + remoteModuleGroups = { + "Remote Armor Repairer": "Armor", + "Ancillary Remote Armor Repairer": "Armor", + "Mutadaptive Remote Armor Repairer": "Armor", + "Remote Hull Repairer": "Hull", + "Remote Shield Booster": "Shield", + "Ancillary Remote Shield Booster": "Shield", + "Remote Capacitor Transmitter": "Capacitor"} + rrType = remoteModuleGroups.get(self.item.group.name) + if rrType is None: + return {} + if self.__baseRRAmount is None: + self.__baseRRAmount = {} + shieldAmount = 0 + armorAmount = 0 + hullAmount = 0 + capacitorAmount = 0 + if rrType == "Hull": + hullAmount += self.getModifiedItemAttr("structureDamageAmount", 0) + elif rrType == "Armor": + armorAmount += self.getModifiedItemAttr("armorDamageAmount", 0) + elif rrType == "Shield": + shieldAmount += self.getModifiedItemAttr("shieldBonus", 0) + elif rrType == "Capacitor": + capacitorAmount += self.getModifiedItemAttr("powerTransferAmount", 0) + rrDelay = 0 if rrType == "Shield" else self.rawCycleTime + self.__baseRRAmount[rrDelay] = RRTypes(shield=shieldAmount, armor=armorAmount, hull=hullAmount, capacitor=capacitorAmount) + spoolType, spoolAmount = resolveSpoolOptions(spoolOptions, self) + spoolBoost = calculateSpoolup( + self.getModifiedItemAttr("repairMultiplierBonusMax", 0), + self.getModifiedItemAttr("repairMultiplierBonusPerCycle", 0), + self.rawCycleTime / 1000, spoolType, spoolAmount)[0] + spoolMultiplier = 1 + spoolBoost + adjustedRRAmount = {} + for rrTime, rrAmount in self.__baseRRAmount.items(): + if spoolMultiplier == 1: + adjustedRRAmount[rrTime] = rrAmount + else: + adjustedRRAmount[rrTime] = rrAmount * spoolMultiplier + return adjustedRRAmount + def getRemoteReps(self, spoolOptions=None, ignoreState=False): if self.isEmpty or (self.state < FittingModuleState.ACTIVE and not ignoreState): return None, 0 @@ -789,6 +834,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut): def clear(self): self.__baseVolley = None + self.__baseRRAmount = None self.__baseRemoteReps = None self.__miningyield = None self.__reloadTime = None diff --git a/eos/utils/stats.py b/eos/utils/stats.py index 46e6adfc0..95f13aa95 100644 --- a/eos/utils/stats.py +++ b/eos/utils/stats.py @@ -112,3 +112,84 @@ class DmgTypes: def __repr__(self): spec = ['em', 'thermal', 'kinetic', 'explosive', 'total'] return makeReprStr(self, spec) + + +class RRTypes: + """Container for tank data stats.""" + + def __init__(self, shield, armor, hull, capacitor): + self.shield = shield + self.armor = armor + self.hull = hull + self.capacitor = capacitor + + # Iterator is needed to support tuple-style unpacking + def __iter__(self): + yield self.shield + yield self.armor + yield self.hull + yield self.capacitor + + def __eq__(self, other): + if not isinstance(other, RRTypes): + return NotImplemented + # Round for comparison's sake because often tanking numbers are + # generated from data which includes float errors + return ( + floatUnerr(self.shield) == floatUnerr(other.shield) and + floatUnerr(self.armor) == floatUnerr(other.armor) and + floatUnerr(self.hull) == floatUnerr(other.hull) and + floatUnerr(self.capacitor) == floatUnerr(other.capacitor)) + + def __bool__(self): + return any((self.shield, self.armor, self.hull, self.capacitor)) + + def __add__(self, other): + return type(self)( + shield=self.shield + other.shield, + armor=self.armor + other.armor, + hull=self.hull + other.hull, + capacitor=self.capacitor + other.capacitor) + + def __iadd__(self, other): + self.shield += other.shield + self.armor += other.armor + self.hull += other.hull + self.capacitor += other.capacitor + return self + + def __mul__(self, mul): + return type(self)( + shield=self.shield * mul, + armor=self.armor * mul, + hull=self.hull * mul, + capacitor=self.capacitor * mul) + + def __imul__(self, mul): + if mul == 1: + return + self.shield *= mul + self.armor *= mul + self.hull *= mul + self.capacitor *= mul + return self + + def __truediv__(self, div): + return type(self)( + shield=self.shield / div, + armor=self.armor / div, + hull=self.hull / div, + capacitor=self.capacitor / div) + + def __itruediv__(self, div): + if div == 1: + return self + self.shield /= div + self.armor /= div + self.hull /= div + self.capacitor /= div + return self + + def __repr__(self): + spec = ['shield', 'armor', 'hull', 'capacitor'] + return makeReprStr(self, spec)