From a9ef5caf2dc15702996272cbfba6cf175332f598 Mon Sep 17 00:00:00 2001 From: DarkPhoenix Date: Fri, 26 Nov 2021 20:43:46 +0300 Subject: [PATCH] Fix attribute fetching, which is needed to calculate mining waste of crystal'd strip miners This potentially can break many things. Some of those are fixed already, but there might be many more... --- eos/modifiedAttributeDict.py | 12 +++---- eos/saveddata/drone.py | 5 ++- eos/saveddata/fit.py | 4 +++ eos/saveddata/module.py | 11 +++--- gui/builtinStatsViews/miningyieldViewFull.py | 36 +++++++++++++------- gui/builtinViewColumns/attributeDisplay.py | 2 +- 6 files changed, 43 insertions(+), 27 deletions(-) diff --git a/eos/modifiedAttributeDict.py b/eos/modifiedAttributeDict.py index c369d4589..6ed2f3c81 100644 --- a/eos/modifiedAttributeDict.py +++ b/eos/modifiedAttributeDict.py @@ -71,30 +71,30 @@ class ItemAttrShortcut: def getModifiedItemAttr(self, key, default=0): return_value = self.itemModifiedAttributes.get(key) - return return_value or default + return return_value if return_value is not None else default def getModifiedItemAttrExtended(self, key, extraMultipliers=None, ignoreAfflictors=(), default=0): return_value = self.itemModifiedAttributes.getExtended(key, extraMultipliers=extraMultipliers, ignoreAfflictors=ignoreAfflictors) - return return_value or default + return return_value if return_value is not None else default def getItemBaseAttrValue(self, key, default=0): return_value = self.itemModifiedAttributes.getOriginal(key) - return return_value or default + return return_value if return_value is not None else default class ChargeAttrShortcut: def getModifiedChargeAttr(self, key, default=0): return_value = self.chargeModifiedAttributes.get(key) - return return_value or default + return return_value if return_value is not None else default def getModifiedChargeAttrExtended(self, key, extraMultipliers=None, ignoreAfflictors=(), default=0): return_value = self.chargeModifiedAttributes.getExtended(key, extraMultipliers=extraMultipliers, ignoreAfflictors=ignoreAfflictors) - return return_value or default + return return_value if return_value is not None else default def getChargeBaseAttrValue(self, key, default=0): return_value = self.chargeModifiedAttributes.getOriginal(key) - return return_value or default + return return_value if return_value is not None else default class ModifiedAttributeDict(MutableMapping): diff --git a/eos/saveddata/drone.py b/eos/saveddata/drone.py index 744e7e378..5e3ff3412 100644 --- a/eos/saveddata/drone.py +++ b/eos/saveddata/drone.py @@ -90,9 +90,8 @@ class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut, Mu self._mutaLoadMutators(mutatorClass=MutatorDrone) self.__itemModifiedAttributes.mutators = self.mutators - # pheonix todo: check the attribute itself, not the modified. this will always return 0 now. chargeID = self.getModifiedItemAttr("entityMissileTypeID", None) - if chargeID is not None: + if chargeID: charge = eos.db.getItem(int(chargeID)) self.__charge = charge self.__chargeModifiedAttributes.original = charge.attributes @@ -264,7 +263,7 @@ class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut, Mu cycleTime = cycleParams.averageTime yield_ = sum([getter(d) for d in self.MINING_ATTRIBUTES]) * self.amountActive yps = yield_ / (cycleTime / 1000.0) - wasteChance = self.getModifiedItemAttr("miningWasteProbability") + wasteChance = max(0, min(1, self.getModifiedItemAttr("miningWasteProbability"))) wasteMult = self.getModifiedItemAttr("miningWastedVolumeMultiplier") wps = yps * wasteChance * wasteMult return yps, wps diff --git a/eos/saveddata/fit.py b/eos/saveddata/fit.py index ed23c502a..52346c1be 100644 --- a/eos/saveddata/fit.py +++ b/eos/saveddata/fit.py @@ -396,6 +396,10 @@ class Fit: def totalYield(self): return self.droneYield + self.minerYield + @property + def totalWaste(self): + return self.droneWaste + self.minerWaste + @property def maxTargets(self): maxTargets = min(self.extraAttributes["maxTargetsLockedFromSkills"], diff --git a/eos/saveddata/module.py b/eos/saveddata/module.py index b071846cc..f3b2dc502 100644 --- a/eos/saveddata/module.py +++ b/eos/saveddata/module.py @@ -443,6 +443,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut, M if self.charge is not None: wasteChance += self.getModifiedChargeAttr("specializationCrystalMiningWasteProbabilityBonus", 0) wasteMult *= self.getModifiedChargeAttr("specializationCrystalMiningWastedVolumeMultiplierBonus", 1) + wasteChance = max(0, min(1, wasteChance)) wps = yps * wasteChance * wasteMult return yps, wps @@ -748,7 +749,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut, M # Check if the local module is over it's max limit; if it's not, we're fine maxGroupOnline = self.getModifiedItemAttr("maxGroupOnline", None) maxGroupActive = self.getModifiedItemAttr("maxGroupActive", None) - if maxGroupOnline is None and maxGroupActive is None and projectedOnto is None: + if not maxGroupOnline and not maxGroupActive and projectedOnto is None: return True # Following is applicable only to local modules, we do not want to limit projected @@ -764,11 +765,11 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut, M currOnline += 1 if mod.state >= FittingModuleState.ACTIVE: currActive += 1 - if maxGroupOnline is not None and currOnline > maxGroupOnline: + if maxGroupOnline and currOnline > maxGroupOnline: if maxState is None or maxState > FittingModuleState.OFFLINE: maxState = FittingModuleState.OFFLINE break - if maxGroupActive is not None and currActive > maxGroupActive: + if maxGroupActive and currActive > maxGroupActive: if maxState is None or maxState > FittingModuleState.ONLINE: maxState = FittingModuleState.ONLINE return True if maxState is None else maxState @@ -806,7 +807,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut, M chargeGroup = charge.groupID for i in range(5): itemChargeGroup = self.getModifiedItemAttr('chargeGroup' + str(i), None) - if itemChargeGroup is None: + if not itemChargeGroup: continue if itemChargeGroup == chargeGroup: return True @@ -817,7 +818,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut, M validCharges = set() for i in range(5): itemChargeGroup = self.getModifiedItemAttr('chargeGroup' + str(i), None) - if itemChargeGroup is not None: + if itemChargeGroup: g = eos.db.getGroup(int(itemChargeGroup), eager="items.attributes") if g is None: continue diff --git a/gui/builtinStatsViews/miningyieldViewFull.py b/gui/builtinStatsViews/miningyieldViewFull.py index 35852e7eb..fc3324e76 100644 --- a/gui/builtinStatsViews/miningyieldViewFull.py +++ b/gui/builtinStatsViews/miningyieldViewFull.py @@ -130,21 +130,33 @@ class MiningYieldViewFull(StatsView): def refreshPanel(self, fit): # If we did anything intresting, we'd update our labels to reflect the new fit's stats here - stats = (("labelFullminingyieldMiner", lambda: fit.minerYield, 3, 0, 0, "%s m\u00B3/s", None), - ("labelFullminingyieldDrone", lambda: fit.droneYield, 3, 0, 0, "%s m\u00B3/s", None), - ("labelFullminingyieldTotal", lambda: fit.totalYield, 3, 0, 0, "%s m\u00B3/s", None)) + stats = (("labelFullminingyieldMiner", lambda: fit.minerYield, lambda: fit.minerWaste, 3, 0, 0, "{}{} m\u00B3/s", None), + ("labelFullminingyieldDrone", lambda: fit.droneYield, lambda: fit.droneWaste, 3, 0, 0, "{}{} m\u00B3/s", None), + ("labelFullminingyieldTotal", lambda: fit.totalYield, lambda: fit.totalWaste, 3, 0, 0, "{}{} m\u00B3/s", None)) - counter = 0 - for labelName, value, prec, lowest, highest, valueFormat, altFormat in stats: - label = getattr(self, labelName) + def processValue(value): value = value() if fit is not None else 0 value = value if value is not None else 0 - if self._cachedValues[counter] != value: - valueStr = formatAmount(value, prec, lowest, highest) - label.SetLabel(valueFormat % valueStr) - tipStr = "Mining Yield per second ({0} per hour)".format(formatAmount(value * 3600, 3, 0, 3)) - label.SetToolTip(wx.ToolTip(tipStr)) - self._cachedValues[counter] = value + return value + + counter = 0 + for labelName, yieldValue, wasteValue, prec, lowest, highest, valueFormat, altFormat in stats: + label = getattr(self, labelName) + yieldValue = processValue(yieldValue) + wasteValue = processValue(wasteValue) + if self._cachedValues[counter] != (yieldValue, wasteValue): + yps = formatAmount(yieldValue, prec, lowest, highest) + yph = formatAmount(yieldValue * 3600, prec, lowest, highest) + wps = formatAmount(wasteValue, prec, lowest, highest) + wph = formatAmount(wasteValue * 3600, prec, lowest, highest) + wasteSuffix = '\u02b7' if wasteValue > 0 else '' + label.SetLabel(valueFormat.format(yps, wasteSuffix)) + tipLines = [] + tipLines.append("{} m\u00B3 mining yield per second ({} m\u00B3 per hour)".format(yps, yph)) + if wasteValue > 0: + tipLines.append("{} m\u00B3 mining waste per second ({} m\u00B3 per hour)".format(wps, wph)) + label.SetToolTip(wx.ToolTip('\n'.join(tipLines))) + self._cachedValues[counter] = (yieldValue, wasteValue) counter += 1 self.panel.Layout() self.headerPanel.Layout() diff --git a/gui/builtinViewColumns/attributeDisplay.py b/gui/builtinViewColumns/attributeDisplay.py index e3f074672..9817170e5 100644 --- a/gui/builtinViewColumns/attributeDisplay.py +++ b/gui/builtinViewColumns/attributeDisplay.py @@ -80,7 +80,7 @@ class AttributeDisplay(ViewColumn): else: attr = mod.getAttribute(self.info.name) - if attr is None: + if not attr: return "" if self.info.name == "volume":