From 9ac609528bafea241e6ac7bf6b11560d7710a3bc Mon Sep 17 00:00:00 2001 From: blitzmann Date: Wed, 19 Apr 2017 21:04:26 -0400 Subject: [PATCH 1/6] Fix issue in which drones hp/s does not consider number of drones --- gui/builtinViewColumns/misc.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/gui/builtinViewColumns/misc.py b/gui/builtinViewColumns/misc.py index c1e12f29c..1b767eb61 100644 --- a/gui/builtinViewColumns/misc.py +++ b/gui/builtinViewColumns/misc.py @@ -27,7 +27,7 @@ from gui.viewColumn import ViewColumn from gui.bitmapLoader import BitmapLoader from gui.utils.numberFormatter import formatAmount from gui.utils.listFormatter import formatList - +from eos.saveddata.drone import Drone class Miscellanea(ViewColumn): name = "Miscellanea" @@ -417,7 +417,11 @@ class Miscellanea(ViewColumn): cycleTime = stuff.getModifiedItemAttr("duration") if not repAmount or not cycleTime: return "", None - repPerSec = float(repAmount) * 1000 / cycleTime + repPerSecPerDrone = repPerSec = float(repAmount) * 1000 / cycleTime + + if isinstance(stuff, Drone): + repPerSec *= stuff.amount + text = "{0}/s".format(formatAmount(repPerSec, 3, 0, 3)) ttEntries = [] if hullAmount is not None and repAmount == hullAmount: @@ -426,7 +430,8 @@ class Miscellanea(ViewColumn): ttEntries.append("armor") if shieldAmount is not None and repAmount == shieldAmount: ttEntries.append("shield") - tooltip = "{0} repaired per second".format(formatList(ttEntries)).capitalize() + + tooltip = "{0} HP repaired per second\n{1} HP/s per drone".format(formatList(ttEntries).capitalize(), repPerSecPerDrone) return text, tooltip elif itemGroup == "Energy Neutralizer Drone": neutAmount = stuff.getModifiedItemAttr("energyNeutralizerAmount") From 3d8a80aeaadf1b49d106373694758e96045f573e Mon Sep 17 00:00:00 2001 From: blitzmann Date: Wed, 19 Apr 2017 21:33:32 -0400 Subject: [PATCH 2/6] Include drones in RR stats --- eos/saveddata/drone.py | 4 +++ eos/saveddata/fit.py | 49 +++++++++++++++++++++++----------- gui/builtinViewColumns/misc.py | 1 + 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/eos/saveddata/drone.py b/eos/saveddata/drone.py index 647e0a99c..82053290d 100644 --- a/eos/saveddata/drone.py +++ b/eos/saveddata/drone.py @@ -100,6 +100,10 @@ class Drone(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut): def charge(self): return self.__charge + @property + def cycleTime(self): + return max(self.getModifiedItemAttr("duration"), 0) + @property def dealsDamage(self): for attr in ("emDamage", "kineticDamage", "explosiveDamage", "thermalDamage"): diff --git a/eos/saveddata/fit.py b/eos/saveddata/fit.py index c2c8f02c4..04854e568 100644 --- a/eos/saveddata/fit.py +++ b/eos/saveddata/fit.py @@ -29,6 +29,7 @@ from eos import capSim from eos.effectHandlerHelpers import HandledModuleList, HandledDroneCargoList, HandledImplantBoosterList, HandledProjectedDroneList, HandledProjectedModList from eos.enum import Enum from eos.saveddata.ship import Ship +from eos.saveddata.drone import Drone from eos.saveddata.character import Character from eos.saveddata.citadel import Citadel from eos.saveddata.module import Module, State, Slot, Hardpoint @@ -1186,24 +1187,28 @@ class Fit(object): if force_recalc is False: return self.__remoteReps - # We are rerunning the recalcs. Explicitly set to 0 to make sure we don't duplicate anything and correctly set all values to 0. + # We are rerunning the recalcs. Explicitly set to 0 to make sure we don't duplicate anything and correctly + # set all values to 0. for remote_type in self.__remoteReps: self.__remoteReps[remote_type] = 0 - for module in self.modules: - # Skip empty and non-Active modules - if module.isEmpty or module.state < State.ACTIVE: + for stuff in chain(self.modules, self.drones): + remote_type = None + modifier = stuff.getModifiedItemAttr("chargedArmorDamageMultiplier", 1) + + if isinstance(stuff, Module) and (stuff.isEmpty or stuff.state < State.ACTIVE): continue + elif isinstance(stuff, Drone): + # drones don't have fueled charges, so siomply override modifier with the amount of drones active + modifier = stuff.amountActive # Covert cycleTime to seconds - duration = module.cycleTime / 1000 + duration = stuff.cycleTime / 1000 # Skip modules with no duration. if not duration: continue - fueledMultiplier = module.getModifiedItemAttr("chargedArmorDamageMultiplier", 1) - remote_module_groups = { "Remote Armor Repairer" : "Armor", "Ancillary Remote Armor Repairer": "Armor", @@ -1213,26 +1218,38 @@ class Fit(object): "Remote Capacitor Transmitter" : "Capacitor", } - module_group = module.item.group.name + module_group = stuff.item.group.name if module_group in remote_module_groups: remote_type = remote_module_groups[module_group] - else: + elif not isinstance(stuff, Drone): # Module isn't in our list of remote rep modules, bail continue if remote_type == "Hull": - hp = module.getModifiedItemAttr("structureDamageAmount", 0) + hp = stuff.getModifiedItemAttr("structureDamageAmount", 0) elif remote_type == "Armor": - hp = module.getModifiedItemAttr("armorDamageAmount", 0) + hp = stuff.getModifiedItemAttr("armorDamageAmount", 0) elif remote_type == "Shield": - hp = module.getModifiedItemAttr("shieldBonus", 0) + hp = stuff.getModifiedItemAttr("shieldBonus", 0) elif remote_type == "Capacitor": - hp = module.getModifiedItemAttr("powerTransferAmount", 0) + hp = stuff.getModifiedItemAttr("powerTransferAmount", 0) else: - hp = 0 - - self.__remoteReps[remote_type] += (hp * fueledMultiplier) / duration + droneShield = stuff.getModifiedItemAttr("shieldBonus", 0) + droneArmor = stuff.getModifiedItemAttr("armorDamageAmount", 0) + droneHull = stuff.getModifiedItemAttr("structureDamageAmount", 0) + if droneShield: + remote_type = "Shield" + hp = droneShield + elif droneArmor: + remote_type = "Armor" + hp = droneArmor + elif droneHull: + remote_type = "Hull" + hp = droneHull + else: + hp = 0 + self.__remoteReps[remote_type] += (hp * modifier) / duration return self.__remoteReps diff --git a/gui/builtinViewColumns/misc.py b/gui/builtinViewColumns/misc.py index 1b767eb61..e4130f2fe 100644 --- a/gui/builtinViewColumns/misc.py +++ b/gui/builtinViewColumns/misc.py @@ -29,6 +29,7 @@ from gui.utils.numberFormatter import formatAmount from gui.utils.listFormatter import formatList from eos.saveddata.drone import Drone + class Miscellanea(ViewColumn): name = "Miscellanea" From 25a945f9e612762210cf4579dc0314dd1add4ffe Mon Sep 17 00:00:00 2001 From: Ebag333 Date: Thu, 20 Apr 2017 11:37:11 -0700 Subject: [PATCH 3/6] Catch bug where remote reppers have the fueled multiplier applied when they have no charges. --- eos/saveddata/fit.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/eos/saveddata/fit.py b/eos/saveddata/fit.py index 04854e568..32cbe5aa8 100644 --- a/eos/saveddata/fit.py +++ b/eos/saveddata/fit.py @@ -1187,14 +1187,16 @@ class Fit(object): if force_recalc is False: return self.__remoteReps - # We are rerunning the recalcs. Explicitly set to 0 to make sure we don't duplicate anything and correctly - # set all values to 0. + # We are rerunning the recalcs. Explicitly set to 0 to make sure we don't duplicate anything and correctly set all values to 0. for remote_type in self.__remoteReps: self.__remoteReps[remote_type] = 0 for stuff in chain(self.modules, self.drones): remote_type = None - modifier = stuff.getModifiedItemAttr("chargedArmorDamageMultiplier", 1) + if stuff.charge: + fueledMultiplier = stuff.getModifiedItemAttr("chargedArmorDamageMultiplier", 1) + else: + fueledMultiplier = 1 if isinstance(stuff, Module) and (stuff.isEmpty or stuff.state < State.ACTIVE): continue @@ -1249,7 +1251,7 @@ class Fit(object): hp = droneHull else: hp = 0 - self.__remoteReps[remote_type] += (hp * modifier) / duration + self.__remoteReps[remote_type] += (hp * fueledMultiplier) / duration return self.__remoteReps From cd30d743937361fc4ecf91329703f8f1b683bd48 Mon Sep 17 00:00:00 2001 From: blitzmann Date: Thu, 20 Apr 2017 23:54:52 -0400 Subject: [PATCH 4/6] Rename fueled to modifier --- eos/saveddata/fit.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/eos/saveddata/fit.py b/eos/saveddata/fit.py index 32cbe5aa8..c9dd3677c 100644 --- a/eos/saveddata/fit.py +++ b/eos/saveddata/fit.py @@ -1187,21 +1187,24 @@ class Fit(object): if force_recalc is False: return self.__remoteReps - # We are rerunning the recalcs. Explicitly set to 0 to make sure we don't duplicate anything and correctly set all values to 0. + # We are rerunning the recalcs. Explicitly set to 0 to make sure we don't duplicate anything and correctly set + # all values to 0. for remote_type in self.__remoteReps: self.__remoteReps[remote_type] = 0 for stuff in chain(self.modules, self.drones): remote_type = None + + # Only apply the charged multiplier if we have a charge in our ancil reppers (#1135) if stuff.charge: - fueledMultiplier = stuff.getModifiedItemAttr("chargedArmorDamageMultiplier", 1) + modifier = stuff.getModifiedItemAttr("chargedArmorDamageMultiplier", 1) else: - fueledMultiplier = 1 + modifier = 1 if isinstance(stuff, Module) and (stuff.isEmpty or stuff.state < State.ACTIVE): continue elif isinstance(stuff, Drone): - # drones don't have fueled charges, so siomply override modifier with the amount of drones active + # drones don't have fueled charges, so simply override modifier with the amount of drones active modifier = stuff.amountActive # Covert cycleTime to seconds @@ -1251,7 +1254,7 @@ class Fit(object): hp = droneHull else: hp = 0 - self.__remoteReps[remote_type] += (hp * fueledMultiplier) / duration + self.__remoteReps[remote_type] += (hp * modifier) / duration return self.__remoteReps From bedd6efff2a187295696ef91c2b96c6c178052a0 Mon Sep 17 00:00:00 2001 From: Ryan Holmes Date: Wed, 26 Apr 2017 20:25:35 -0400 Subject: [PATCH 5/6] Fix for #1137 - industrial command skill was applying to incorrect attribute (#1138) --- eos/effects/miningforemanburstbonusorecapital2.py | 8 ++++---- eos/effects/shieldcommandburstbonusorecapital3.py | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eos/effects/miningforemanburstbonusorecapital2.py b/eos/effects/miningforemanburstbonusorecapital2.py index b1e7f4b57..29d55819e 100644 --- a/eos/effects/miningforemanburstbonusorecapital2.py +++ b/eos/effects/miningforemanburstbonusorecapital2.py @@ -6,13 +6,13 @@ type = "passive" def handler(fit, src, context): - fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff1Multiplier", + fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff1Value", src.getModifiedItemAttr("shipBonusORECapital2"), skill="Capital Industrial Ships") - fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff2Multiplier", + fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff2Value", src.getModifiedItemAttr("shipBonusORECapital2"), skill="Capital Industrial Ships") - fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff4Multiplier", + fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff4Value", src.getModifiedItemAttr("shipBonusORECapital2"), skill="Capital Industrial Ships") - fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff3Multiplier", + fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "warfareBuff3Value", src.getModifiedItemAttr("shipBonusORECapital2"), skill="Capital Industrial Ships") fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Mining Foreman"), "buffDuration", src.getModifiedItemAttr("shipBonusORECapital2"), skill="Capital Industrial Ships") diff --git a/eos/effects/shieldcommandburstbonusorecapital3.py b/eos/effects/shieldcommandburstbonusorecapital3.py index 5972f2044..8ad4a3462 100644 --- a/eos/effects/shieldcommandburstbonusorecapital3.py +++ b/eos/effects/shieldcommandburstbonusorecapital3.py @@ -6,13 +6,13 @@ type = "passive" def handler(fit, src, context): - fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff4Multiplier", + fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff4Value", src.getModifiedItemAttr("shipBonusORECapital3"), skill="Capital Industrial Ships") fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "buffDuration", src.getModifiedItemAttr("shipBonusORECapital3"), skill="Capital Industrial Ships") - fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff1Multiplier", + fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff1Value", src.getModifiedItemAttr("shipBonusORECapital3"), skill="Capital Industrial Ships") - fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff3Multiplier", + fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff3Value", src.getModifiedItemAttr("shipBonusORECapital3"), skill="Capital Industrial Ships") - fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff2Multiplier", + fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Shield Command"), "warfareBuff2Value", src.getModifiedItemAttr("shipBonusORECapital3"), skill="Capital Industrial Ships") From 1cf844d4155043edf05ba8a1cede634c6a387002 Mon Sep 17 00:00:00 2001 From: blitzmann Date: Sun, 30 Apr 2017 01:39:03 -0400 Subject: [PATCH 6/6] item.attributes would not contain attributes that were added during runtime. Instead, get the attribute info and search the modified attributes for the resist attribtue. --- eos/modifiedAttributeDict.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/eos/modifiedAttributeDict.py b/eos/modifiedAttributeDict.py index 757d8a3d1..56ac737db 100644 --- a/eos/modifiedAttributeDict.py +++ b/eos/modifiedAttributeDict.py @@ -342,12 +342,13 @@ class ModifiedAttributeDict(collections.MutableMapping): # effect is applied. mod = self.fit.getModifier() remoteResistID = mod.getModifiedItemAttr("remoteResistanceID") or None + attrInfo = getAttributeInfo(int(remoteResistID)) - # We really don't have a way of getting a ships attribute by ID. Fail. - resist = next((x for x in self.fit.ship.item.attributes.values() if x.ID == remoteResistID), None) + # Get the attribute of the resist + resist = self.fit.ship.itemModifiedAttributes[attrInfo.attributeName] or None if remoteResistID and resist: - boostFactor *= resist.value + boostFactor *= resist # We just transform percentage boost into multiplication factor self.multiply(attributeName, 1 + boostFactor / 100.0, *args, **kwargs)