diff --git a/eos/graph/fitDps.py b/eos/graph/fitDps.py index 71a95d26e..e831c8135 100644 --- a/eos/graph/fitDps.py +++ b/eos/graph/fitDps.py @@ -75,7 +75,7 @@ class FitDpsGraph(Graph): pyfalog.critical(e) for mod in fit.modules: - dps, _ = mod.damageStats(fit.targetResists) + dps = mod.damageStats(fit.targetResists)[1] if mod.hardpoint == Hardpoint.TURRET: if mod.state >= State.ACTIVE: total += dps * self.calculateTurretMultiplier(mod, data) @@ -88,7 +88,7 @@ class FitDpsGraph(Graph): for drone in fit.drones: multiplier = 1 if drone.getModifiedItemAttr("maxVelocity") > 1 else self.calculateTurretMultiplier( drone, data) - dps, _ = drone.damageStats(fit.targetResists) + dps = drone.damageStats(fit.targetResists)[0] total += dps * multiplier # this is janky as fuck @@ -96,7 +96,7 @@ class FitDpsGraph(Graph): for ability in fighter.abilities: if ability.dealsDamage and ability.active: multiplier = self.calculateFighterMissileMultiplier(ability, data) - dps, _ = ability.damageStats(fit.targetResists) + dps = ability.damageStats(fit.targetResists)[0] total += dps * multiplier return total diff --git a/eos/saveddata/drone.py b/eos/saveddata/drone.py index 4cddbea42..e58a9dee1 100644 --- a/eos/saveddata/drone.py +++ b/eos/saveddata/drone.py @@ -120,9 +120,11 @@ class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut): def hasAmmo(self): return self.charge is not None - @property - def dps(self): - return self.damageStats() + def getDps(self): + return self.damageStats()[0] + + def getVolley(self): + return self.damageStats()[1] def changeType(self, typeID): self.itemID = typeID diff --git a/eos/saveddata/fighter.py b/eos/saveddata/fighter.py index 8c515b945..8d45d1f51 100644 --- a/eos/saveddata/fighter.py +++ b/eos/saveddata/fighter.py @@ -172,9 +172,11 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut): def hasAmmo(self): return self.charge is not None - @property - def dps(self): - return self.damageStats() + def getDps(self): + return self.damageStats()[0] + + def getVolley(self): + return self.damageStats()[1] def damageStats(self, targetResists=None): if self.__dps is None: diff --git a/eos/saveddata/fit.py b/eos/saveddata/fit.py index e00b522fd..8a9643f33 100644 --- a/eos/saveddata/fit.py +++ b/eos/saveddata/fit.py @@ -120,10 +120,10 @@ class Fit(object): def build(self): self.__extraDrains = [] self.__ehp = None - self.__weaponDPS = None + self.__weaponDps = None self.__minerYield = None self.__weaponVolley = None - self.__droneDPS = None + self.__droneDps = None self.__droneVolley = None self.__droneYield = None self.__sustainableTank = None @@ -154,9 +154,11 @@ class Fit(object): @targetResists.setter def targetResists(self, targetResists): self.__targetResists = targetResists - self.__weaponDPS = None + self.__weaponDps = None + self.__weaponDpsSpool = None self.__weaponVolley = None - self.__droneDPS = None + self.__weaponVolleySpool = None + self.__droneDps = None self.__droneVolley = None @property @@ -277,41 +279,41 @@ class Fit(object): def projectedFighters(self): return self.__projectedFighters - @property - def weaponDPS(self): - if self.__weaponDPS is None: + def getWeaponDps(self, spool=False): + if spool: + if self.__weaponDpsSpool is None: + self.calculateWeaponStats() + return self.__weaponDpsSpool + else: + if self.__weaponDps is None: + self.calculateWeaponStats() + return self.__weaponDps + + def getWeaponVolley(self, spool=False): + if spool: + if self.__weaponVolleySpool is None: + self.calculateWeaponStats() + return self.__weaponVolleySpool + else: + if self.__weaponVolley is None: + self.calculateWeaponStats() + return self.__weaponVolley + + def getDroneDps(self): + if self.__droneDps is None: self.calculateWeaponStats() + return self.__droneDps - return self.__weaponDPS - - @property - def weaponVolley(self): - if self.__weaponVolley is None: - self.calculateWeaponStats() - - return self.__weaponVolley - - @property - def droneDPS(self): - if self.__droneDPS is None: - self.calculateWeaponStats() - - return self.__droneDPS - - @property - def droneVolley(self): + def getDroneVolley(self): if self.__droneVolley is None: self.calculateWeaponStats() - return self.__droneVolley - @property - def totalDPS(self): - return self.droneDPS + self.weaponDPS + def getTotalDps(self, spool=False): + return self.getDroneDps() + self.getWeaponDps(spool=spool) - @property - def totalVolley(self): - return self.droneVolley + self.weaponVolley + def getTotalVolley(self, spool=False): + return self.getDroneVolley() + self.getWeaponVolley(spool=spool) @property def minerYield(self): @@ -409,12 +411,14 @@ class Fit(object): def clear(self, projected=False, command=False): self.__effectiveTank = None - self.__weaponDPS = None - self.__minerYield = None + self.__weaponDps = None + self.__weaponDpsSpool = None self.__weaponVolley = None + self.__weaponVolleySpool = None + self.__minerYield = None self.__effectiveSustainableTank = None self.__sustainableTank = None - self.__droneDPS = None + self.__droneDps = None self.__droneVolley = None self.__droneYield = None self.__ehp = None @@ -1538,29 +1542,35 @@ class Fit(object): self.__droneYield = droneYield def calculateWeaponStats(self): - weaponDPS = 0 - droneDPS = 0 + weaponDps = 0 + weaponDpsSpool = 0 + droneDps = 0 weaponVolley = 0 + weaponVolleySpool = 0 droneVolley = 0 for mod in self.modules: - dps, volley = mod.damageStats(self.targetResists) - weaponDPS += dps + dps, dpsSpool, volley, volleySpool = mod.damageStats(self.targetResists) + weaponDps += dps + weaponDpsSpool += dpsSpool weaponVolley += volley + weaponVolleySpool += volleySpool for drone in self.drones: dps, volley = drone.damageStats(self.targetResists) - droneDPS += dps + droneDps += dps droneVolley += volley for fighter in self.fighters: dps, volley = fighter.damageStats(self.targetResists) - droneDPS += dps + droneDps += dps droneVolley += volley - self.__weaponDPS = weaponDPS + self.__weaponDps = weaponDps + self.__weaponDpsSpool = weaponDpsSpool self.__weaponVolley = weaponVolley - self.__droneDPS = droneDPS + self.__weaponVolleySpool = weaponVolleySpool + self.__droneDps = droneDps self.__droneVolley = droneVolley @property diff --git a/eos/saveddata/module.py b/eos/saveddata/module.py index 57aacf101..806a9a913 100644 --- a/eos/saveddata/module.py +++ b/eos/saveddata/module.py @@ -169,8 +169,10 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut): self.__charge = None self.__dps = None - self.__miningyield = None + self.__dpsSpool = None self.__volley = None + self.__volleySpool = None + self.__miningyield = None self.__reloadTime = None self.__reloadForce = None self.__chargeCycles = None @@ -404,7 +406,9 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut): def damageStats(self, targetResists): if self.__dps is None: self.__dps = 0 + self.__dpsSpool = 0 self.__volley = 0 + self.__volleySpool = 0 if not self.isEmpty and self.state >= State.ACTIVE: if self.charge: @@ -415,7 +419,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut): volley = sum([(func("%sDamage" % attr) or 0) * (1 - getattr(targetResists, "%sAmount" % attr, 0)) for attr in self.DAMAGE_TYPES]) volley *= self.getModifiedItemAttr("damageMultiplier") or 1 # Disintegrator-specific ramp-up multiplier - volley *= (self.getModifiedItemAttr("damageMultiplierBonusMax") or 0) + 1 + volleySpool = volley * ((self.getModifiedItemAttr("damageMultiplierBonusMax") or 0) + 1) if volley: cycleTime = self.cycleTime # Some weapons repeat multiple times in one cycle (think doomsdays) @@ -426,9 +430,12 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut): ) self.__volley = volley - self.__dps = (volley * weaponDoT) / (cycleTime / 1000.0) + self.__volleySpool = volleySpool + dpsFactor = weaponDoT / (cycleTime / 1000.0) + self.__dps = volley * dpsFactor + self.__dpsSpool = volleySpool * dpsFactor - return self.__dps, self.__volley + return self.__dps, self.__dpsSpool, self.__volley, self.__volleySpool @property def miningStats(self): @@ -449,13 +456,17 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut): return self.__miningyield - @property - def dps(self): - return self.damageStats(None)[0] + def getDps(self, spool=False): + if spool: + return self.damageStats(None)[1] + else: + return self.damageStats(None)[0] - @property - def volley(self): - return self.damageStats(None)[1] + def getVolley(self, spool=False): + if spool: + return self.damageStats(None)[3] + else: + return self.damageStats(None)[2] @property def reloadTime(self): diff --git a/gui/builtinStatsViews/firepowerViewFull.py b/gui/builtinStatsViews/firepowerViewFull.py index 29ce7a482..68a935326 100644 --- a/gui/builtinStatsViews/firepowerViewFull.py +++ b/gui/builtinStatsViews/firepowerViewFull.py @@ -148,10 +148,10 @@ class FirepowerViewFull(StatsView): else: self.stEff.Hide() - stats = (("labelFullDpsWeapon", lambda: fit.weaponDPS, 3, 0, 0, "%s DPS", None), - ("labelFullDpsDrone", lambda: fit.droneDPS, 3, 0, 0, "%s DPS", None), - ("labelFullVolleyTotal", lambda: fit.totalVolley, 3, 0, 0, "%s", "Volley: %.1f"), - ("labelFullDpsTotal", lambda: fit.totalDPS, 3, 0, 0, "%s", None)) + stats = (("labelFullDpsWeapon", lambda: fit.getWeaponDps(spool=True), 3, 0, 0, "%s DPS", None), + ("labelFullDpsDrone", lambda: fit.getDroneDps(), 3, 0, 0, "%s DPS", None), + ("labelFullVolleyTotal", lambda: fit.getTotalVolley(spool=True), 3, 0, 0, "%s", "Volley: %.1f"), + ("labelFullDpsTotal", lambda: fit.getTotalDps(spool=True), 3, 0, 0, "%s", None)) # See GH issue # # if fit is not None and fit.totalYield > 0: # self.miningyield.Show() diff --git a/service/port/efs.py b/service/port/efs.py index b572e5376..b74de680f 100755 --- a/service/port/efs.py +++ b/service/port/efs.py @@ -303,7 +303,7 @@ class EfsPort(): weaponSystems = [] groups = {} for mod in fit.modules: - if mod.dps > 0: + if mod.getDps() > 0: # Group weapon + ammo combinations that occur more than once keystr = str(mod.itemID) + "-" + str(mod.chargeID) if keystr in groups: @@ -320,6 +320,7 @@ class EfsPort(): explosionRadius = 0 explosionVelocity = 0 aoeFieldRange = 0 + typeing = 'None' if stats.charge: name = stats.item.name + ", " + stats.charge.name else: @@ -345,10 +346,10 @@ class EfsPort(): else: maxRange = stats.maxRange statDict = { - "dps": stats.dps * n, "capUse": stats.capUse * n, "falloff": stats.falloff, + "dps": stats.getDps(spool=True) * n, "capUse": stats.capUse * n, "falloff": stats.falloff, "type": typeing, "name": name, "optimal": maxRange, "numCharges": stats.numCharges, "numShots": stats.numShots, "reloadTime": stats.reloadTime, - "cycleTime": stats.cycleTime, "volley": stats.volley * n, "tracking": tracking, + "cycleTime": stats.cycleTime, "volley": stats.getVolley(spool=True) * n, "tracking": tracking, "maxVelocity": maxVelocity, "explosionDelay": explosionDelay, "damageReductionFactor": damageReductionFactor, "explosionRadius": explosionRadius, "explosionVelocity": explosionVelocity, "aoeFieldRange": aoeFieldRange, "damageMultiplierBonusMax": stats.getModifiedItemAttr("damageMultiplierBonusMax"), @@ -356,19 +357,19 @@ class EfsPort(): } weaponSystems.append(statDict) for drone in fit.drones: - if drone.dps[0] > 0 and drone.amountActive > 0: + if drone.getDps() > 0 and drone.amountActive > 0: droneAttr = drone.getModifiedItemAttr # Drones are using the old tracking formula for trackingSpeed. This updates it to match turrets. newTracking = droneAttr("trackingSpeed") / (droneAttr("optimalSigRadius") / 40000) statDict = { - "dps": drone.dps[0], "cycleTime": drone.cycleTime, "type": "Drone", + "dps": drone.getDps(), "cycleTime": drone.cycleTime, "type": "Drone", "optimal": drone.maxRange, "name": drone.item.name, "falloff": drone.falloff, "maxSpeed": droneAttr("maxVelocity"), "tracking": newTracking, - "volley": drone.dps[1] + "volley": drone.getVolley() } weaponSystems.append(statDict) for fighter in fit.fighters: - if fighter.dps[0] > 0 and fighter.amountActive > 0: + if fighter.getDps() > 0 and fighter.amountActive > 0: fighterAttr = fighter.getModifiedItemAttr abilities = [] if "fighterAbilityAttackMissileDamageEM" in fighter.item.attributes.keys(): @@ -380,10 +381,10 @@ class EfsPort(): ability = EfsPort.getFighterAbilityData(fighterAttr, fighter, baseRef) abilities.append(ability) statDict = { - "dps": fighter.dps[0], "type": "Fighter", "name": fighter.item.name, + "dps": fighter.getDps(), "type": "Fighter", "name": fighter.item.name, "maxSpeed": fighterAttr("maxVelocity"), "abilities": abilities, "ehp": fighterAttr("shieldCapacity") / 0.8875 * fighter.amountActive, - "volley": fighter.dps[1], "signatureRadius": fighterAttr("signatureRadius") + "volley": fighter.getVolley(), "signatureRadius": fighterAttr("signatureRadius") } weaponSystems.append(statDict) return weaponSystems @@ -622,11 +623,11 @@ class EfsPort(): shipSize = EfsPort.getShipSize(fit.ship.item.groupID) try: dataDict = { - "name": fitName, "ehp": fit.ehp, "droneDPS": fit.droneDPS, - "droneVolley": fit.droneVolley, "hp": fit.hp, "maxTargets": fit.maxTargets, - "maxSpeed": fit.maxSpeed, "weaponVolley": fit.weaponVolley, "totalVolley": fit.totalVolley, + "name": fitName, "ehp": fit.ehp, "droneDPS": fit.getDroneDps(), + "droneVolley": fit.getDroneVolley(), "hp": fit.hp, "maxTargets": fit.maxTargets, + "maxSpeed": fit.maxSpeed, "weaponVolley": fit.getWeaponVolley(spool=True), "totalVolley": fit.getTotalVolley(spool=True), "maxTargetRange": fit.maxTargetRange, "scanStrength": fit.scanStrength, - "weaponDPS": fit.weaponDPS, "alignTime": fit.alignTime, "signatureRadius": fitModAttr("signatureRadius"), + "weaponDPS": fit.getWeaponDps(spool=True), "alignTime": fit.alignTime, "signatureRadius": fitModAttr("signatureRadius"), "weapons": weaponSystems, "scanRes": fitModAttr("scanResolution"), "capUsed": fit.capUsed, "capRecharge": fit.capRecharge, "rigSlots": fitModAttr("rigSlots"), "lowSlots": fitModAttr("lowSlots"),