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...
This commit is contained in:
DarkPhoenix
2021-11-26 20:43:46 +03:00
parent 22be97f901
commit a9ef5caf2d
6 changed files with 43 additions and 27 deletions

View File

@@ -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):

View File

@@ -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

View File

@@ -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"],

View File

@@ -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

View File

@@ -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()

View File

@@ -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":