diff --git a/eos/modifiedAttributeDict.py b/eos/modifiedAttributeDict.py index 27045075e..13283089f 100644 --- a/eos/modifiedAttributeDict.py +++ b/eos/modifiedAttributeDict.py @@ -285,8 +285,23 @@ class ModifiedAttributeDict(collections.MutableMapping): # Add extra multipliers to the group, not modifying initial data source if extraMultipliers is not None: penalizedMultiplierGroups = copy(penalizedMultiplierGroups) - for k, v in extraMultipliers.items(): - penalizedMultiplierGroups[k] = penalizedMultiplierGroups.get(k, []) + v + for stackGroup, operationsData in extraMultipliers.items(): + multipliers = [] + for mult, resAttrID in operationsData: + if not resAttrID: + multipliers.append(mult) + continue + resAttrInfo = getAttributeInfo(resAttrID) + if not resAttrInfo: + multipliers.append(mult) + continue + resMult = self.fit.ship.itemModifiedAttributes[resAttrInfo.attributeName] + if resMult is None or resMult == 1: + multipliers.append(mult) + continue + mult = (mult - 1) * resMult + 1 + multipliers.append(mult) + penalizedMultiplierGroups[stackGroup] = penalizedMultiplierGroups.get(stackGroup, []) + multipliers postIncrease = self.__postIncreases.get(key, 0) # Grab initial value, priorities are: diff --git a/gui/builtinGraphs/fitDamageStats/calc.py b/gui/builtinGraphs/fitDamageStats/calc.py index 541a2db5a..812e55f9d 100644 --- a/gui/builtinGraphs/fitDamageStats/calc.py +++ b/gui/builtinGraphs/fitDamageStats/calc.py @@ -172,6 +172,8 @@ def getFighterAbilityMult(fighter, ability, fit, distance, tgtSpeed, tgtSigRadiu def applyWebs(tgt, currentUnwebbedSpeed, webMods, distance): + if tgt.ship.getModifiedItemAttr('disallowOffensiveModifiers'): + return currentUnwebbedSpeed unwebbedSpeed = tgt.ship.getModifiedItemAttr('maxVelocity') try: speedRatio = currentUnwebbedSpeed / unwebbedSpeed @@ -179,22 +181,24 @@ def applyWebs(tgt, currentUnwebbedSpeed, webMods, distance): currentWebbedSpeed = 0 else: appliedMultipliers = {} - for boost, optimal, falloff, stackingChain in webMods: + for boost, optimal, falloff, stackingChain, resistanceAttrID in webMods: appliedBoost = boost * _calcRangeFactor(atkOptimalRange=optimal, atkFalloffRange=falloff, distance=distance) if appliedBoost: - appliedMultipliers.setdefault(stackingChain, []).append(1 + appliedBoost / 100) + appliedMultipliers.setdefault(stackingChain, []).append((1 + appliedBoost / 100, resistanceAttrID)) webbedSpeed = tgt.ship.getModifiedItemAttrWithExtraMods('maxVelocity', extraMultipliers=appliedMultipliers) currentWebbedSpeed = webbedSpeed * speedRatio return currentWebbedSpeed def applyTps(tgt, tpMods, distance): + if tgt.ship.getModifiedItemAttr('disallowOffensiveModifiers'): + return 1 untpedSig = tgt.ship.getModifiedItemAttr('signatureRadius') appliedMultipliers = {} - for boost, optimal, falloff, stackingChain in tpMods: + for boost, optimal, falloff, stackingChain, resistanceAttrID in tpMods: appliedBoost = boost * _calcRangeFactor(atkOptimalRange=optimal, atkFalloffRange=falloff, distance=distance) if appliedBoost: - appliedMultipliers.setdefault(stackingChain, []).append(1 + appliedBoost / 100) + appliedMultipliers.setdefault(stackingChain, []).append((1 + appliedBoost / 100, resistanceAttrID)) tpedSig = tgt.ship.getModifiedItemAttrWithExtraMods('signatureRadius', extraMultipliers=appliedMultipliers) mult = tpedSig / untpedSig return mult diff --git a/gui/builtinGraphs/fitDamageStats/graph.py b/gui/builtinGraphs/fitDamageStats/graph.py index 725a906dc..3545cd987 100644 --- a/gui/builtinGraphs/fitDamageStats/graph.py +++ b/gui/builtinGraphs/fitDamageStats/graph.py @@ -179,6 +179,7 @@ class FitDamageStatsGraph(FitGraph): for distance in self._iterLinear(mainInput[1]): if applyProjected: webMods, tpMods = self._projectedCache.getProjModData(fit) + webDrones, tpDrones = self._projectedCache.getProjDroneData(fit) tgtSpeed = applyWebs( tgt=tgt, currentUnwebbedSpeed=miscInputMap['tgtSpeed'], diff --git a/gui/builtinGraphs/fitDamageStats/projectedCache.py b/gui/builtinGraphs/fitDamageStats/projectedCache.py index 195945643..18dad96a8 100644 --- a/gui/builtinGraphs/fitDamageStats/projectedCache.py +++ b/gui/builtinGraphs/fitDamageStats/projectedCache.py @@ -20,6 +20,7 @@ from gui.builtinGraphs.base import FitDataCache from eos.const import FittingModuleState +from eos.modifiedAttributeDict import getResistanceAttrID class ProjectedDataCache(FitDataCache): @@ -28,23 +29,43 @@ class ProjectedDataCache(FitDataCache): try: projectedData = self._data[fit.ID]['modules'] except KeyError: - # Format of items for both: (boost strength, optimal, falloff, stacking group) + # Format of items for both: (boost strength, optimal, falloff, stacking group, resistance attr ID) webMods = [] tpMods = [] projectedData = self._data.setdefault(fit.ID, {})['modules'] = (webMods, tpMods) for mod in fit.modules: if mod.state <= FittingModuleState.ONLINE: continue - if 'remoteWebifierFalloff' in mod.item.effects or 'structureModuleEffectStasisWebifier' in mod.item.effects: - webMods.append((mod.getModifiedItemAttr('speedFactor'), mod.maxRange or 0, mod.falloff or 0, 'default')) + for webEffectName in ('remoteWebifierFalloff', 'structureModuleEffectStasisWebifier'): + if webEffectName in mod.item.effects: + webMods.append(( + mod.getModifiedItemAttr('speedFactor'), + mod.maxRange or 0, + mod.falloff or 0, + 'default', + getResistanceAttrID(modifyingItem=mod, effect=mod.item.effects[webEffectName]))) if 'doomsdayAOEWeb' in mod.item.effects: - maxRange = max(0, (mod.maxRange or 0) + mod.getModifiedItemAttr('doomsdayAOERange') - fit.ship.getModifiedItemAttr('radius')) - webMods.append((mod.getModifiedItemAttr('speedFactor'), maxRange, mod.falloff or 0, 'default')) - if 'remoteTargetPaintFalloff' in mod.item.effects or 'structureModuleEffectTargetPainter' in mod.item.effects: - tpMods.append((mod.getModifiedItemAttr('signatureRadiusBonus'), mod.maxRange or 0, mod.falloff or 0, 'default')) + webMods.append(( + mod.getModifiedItemAttr('speedFactor'), + max(0, (mod.maxRange or 0) + mod.getModifiedItemAttr('doomsdayAOERange') - fit.ship.getModifiedItemAttr('radius')), + mod.falloff or 0, + 'default', + getResistanceAttrID(modifyingItem=mod, effect=mod.item.effects['doomsdayAOEWeb']))) + for tpEffectName in ('remoteTargetPaintFalloff', 'structureModuleEffectTargetPainter'): + if tpEffectName in mod.item.effects: + tpMods.append(( + mod.getModifiedItemAttr('signatureRadiusBonus'), + mod.maxRange or 0, + mod.falloff or 0, + 'default', + getResistanceAttrID(modifyingItem=mod, effect=mod.item.effects[tpEffectName]))) if 'doomsdayAOEPaint' in mod.item.effects: - maxRange = max(0, (mod.maxRange or 0) + mod.getModifiedItemAttr('doomsdayAOERange') - fit.ship.getModifiedItemAttr('radius')) - tpMods.append((mod.getModifiedItemAttr('signatureRadiusBonus'), maxRange, mod.falloff or 0, 'default')) + tpMods.append(( + mod.getModifiedItemAttr('signatureRadiusBonus'), + max(0, (mod.maxRange or 0) + mod.getModifiedItemAttr('doomsdayAOERange') - fit.ship.getModifiedItemAttr('radius')), + mod.falloff or 0, + 'default', + getResistanceAttrID(modifyingItem=mod, effect=mod.item.effects['doomsdayAOEPaint']))) return projectedData def getProjDroneData(self, fit): @@ -67,7 +88,36 @@ class ProjectedDataCache(FitDataCache): drone.getModifiedItemAttr('maxVelocity'), drone.getModifiedItemAttr('radius')),)) if 'remoteTargetPaintEntity' in drone.item.effects: - webMods.extend(drone.amountActive * (( + tpMods.extend(drone.amountActive * (( + drone.getModifiedItemAttr('signatureRadiusBonus'), + drone.maxRange or 0, + drone.falloff or 0, + 'default', + drone.getModifiedItemAttr('maxVelocity'), + drone.getModifiedItemAttr('radius')),)) + return projectedData + + def getProjFighterData(self, fit): + try: + projectedData = self._data[fit.ID]['fighters'] + except KeyError: + # Format of items for both: (boost strength, optimal, falloff, stacking group, speed, radius) + webMods = [] + tpMods = [] + projectedData = self._data.setdefault(fit.ID, {})['fighters'] = (webMods, tpMods) + for drone in fit.drones: + if drone.amountActive <= 0: + continue + if 'remoteWebifierEntity' in drone.item.effects: + webMods.extend(drone.amountActive * (( + drone.getModifiedItemAttr('speedFactor'), + drone.maxRange or 0, + drone.falloff or 0, + 'default', + drone.getModifiedItemAttr('maxVelocity'), + drone.getModifiedItemAttr('radius')),)) + if 'remoteTargetPaintEntity' in drone.item.effects: + tpMods.extend(drone.amountActive * (( drone.getModifiedItemAttr('signatureRadiusBonus'), drone.maxRange or 0, drone.falloff or 0,