From eb9612b9a35e8c49a2be43a190124cbcb6657c78 Mon Sep 17 00:00:00 2001 From: DarkPhoenix Date: Wed, 14 Aug 2019 14:27:50 +0300 Subject: [PATCH] Add neut vs range graph --- eos/effects.py | 23 ++++++++++++ graphs/data/fitEwarStats/getter.py | 57 +++++++++++++++++++++++++++--- graphs/data/fitEwarStats/graph.py | 7 ++-- 3 files changed, 80 insertions(+), 7 deletions(-) diff --git a/eos/effects.py b/eos/effects.py index ff11e4774..759fa17fc 100644 --- a/eos/effects.py +++ b/eos/effects.py @@ -22599,6 +22599,29 @@ class Effect5853(BaseEffect): skill='Expedition Frigates', **kwargs) +class Effect5854(BaseEffect): + """ + shipBonusNosferatuOverride + + Used by: + Ship: Ashimmu + Ship: Bhaalgorn + Ship: Caedes + Ship: Chemosh + Ship: Cruor + Ship: Dagon + Ship: Molok + Ship: Rabisu + """ + + type = 'passive' + + @staticmethod + def handler(fit, ship, context, **kwargs): + fit.modules.filteredItemForce(lambda mod: mod.item.group.name == 'Energy Nosferatu', + 'nosOverride', ship.getModifiedItemAttr('nosOverride'), **kwargs) + + class Effect5862(BaseEffect): """ shipMissileEMDamageCB diff --git a/graphs/data/fitEwarStats/getter.py b/graphs/data/fitEwarStats/getter.py index c27b7400a..e1fa37ba2 100644 --- a/graphs/data/fitEwarStats/getter.py +++ b/graphs/data/fitEwarStats/getter.py @@ -24,6 +24,53 @@ from graphs.calc import calculateMultiplier, calculateRangeFactor from graphs.data.base import SmoothPointGetter +class Distance2NeutingStrGetter(SmoothPointGetter): + + _baseResolution = 50 + _extraDepth = 2 + + def _getCommonData(self, miscParams, src, tgt): + resonance = 1 - (miscParams['resist'] or 0) + neuts = [] + for mod in src.item.activeModulesIter(): + for effectName in ('energyNeutralizerFalloff', 'structureEnergyNeutralizerFalloff'): + if effectName in mod.item.effects: + neuts.append(( + mod.getModifiedItemAttr('energyNeutralizerAmount') / self.__getDuration(mod) * resonance, + mod.maxRange or 0, mod.falloff or 0)) + if 'energyNosferatuFalloff' in mod.item.effects and mod.getModifiedItemAttr('nosOverride'): + neuts.append(( + mod.getModifiedItemAttr('powerTransferAmount') / self.__getDuration(mod) * resonance, + mod.maxRange or 0, mod.falloff or 0)) + if 'doomsdayAOENeut' in mod.item.effects: + neuts.append(( + mod.getModifiedItemAttr('energyNeutralizerAmount') / self.__getDuration(mod) * resonance, + max(0, (mod.maxRange or 0) + mod.getModifiedItemAttr('doomsdayAOERange') - src.getRadius()), + mod.falloff or 0)) + for drone in src.item.activeDronesIter(): + if 'entityEnergyNeutralizerFalloff' in drone.item.effects: + neuts.extend(drone.amountActive * (( + drone.getModifiedItemAttr('energyNeutralizerAmount') / (drone.getModifiedItemAttr('energyNeutralizerDuration') / 1000) * resonance, + src.item.extraAttributes['droneControlRange'], 0),)) + for fighter, ability in src.item.activeFighterAbilityIter(): + if ability.effect.name == 'fighterAbilityEnergyNeutralizer': + nps = fighter.getModifiedItemAttr('fighterAbilityEnergyNeutralizerAmount') / (ability.cycleTime / 1000) + neuts.append(( + nps * fighter.amountActive * resonance, + math.inf, 0)) + return {'neuts': neuts} + + def _calculatePoint(self, x, miscParams, src, tgt, commonData): + distance = x + combinedStr = 0 + for strength, optimal, falloff in commonData['neuts']: + combinedStr += strength * calculateRangeFactor(srcOptimalRange=optimal, srcFalloffRange=falloff, distance=distance) + return combinedStr + + def __getDuration(self, mod): + return getattr(mod.getCycleParameters(), 'averageTime', math.inf) / 1000 + + class Distance2WebbingStrGetter(SmoothPointGetter): _baseResolution = 50 @@ -82,28 +129,28 @@ class Distance2EcmStrMaxGetter(SmoothPointGetter): if effectName in mod.item.effects: ecms.append(( max(mod.getModifiedItemAttr(a) for a in self.ECM_ATTRS_GENERAL) * resonance, - mod.maxRange or 0, mod.falloff or 0, 'default')) + mod.maxRange or 0, mod.falloff or 0)) if 'doomsdayAOEECM' in mod.item.effects: ecms.append(( max(mod.getModifiedItemAttr(a) for a in self.ECM_ATTRS_GENERAL) * resonance, max(0, (mod.maxRange or 0) + mod.getModifiedItemAttr('doomsdayAOERange') - src.getRadius()), - mod.falloff or 0, 'default')) + mod.falloff or 0)) for drone in src.item.activeDronesIter(): if 'entityECMFalloff' in drone.item.effects: ecms.extend(drone.amountActive * (( max(drone.getModifiedItemAttr(a) for a in self.ECM_ATTRS_GENERAL) * resonance, - src.item.extraAttributes['droneControlRange'], 0, 'default'),)) + src.item.extraAttributes['droneControlRange'], 0),)) for fighter, ability in src.item.activeFighterAbilityIter(): if ability.effect.name == 'fighterAbilityECM': ecms.append(( max(fighter.getModifiedItemAttr(a) for a in self.ECM_ATTRS_FIGHTERS) * fighter.amountActive * resonance, - math.inf, 0, 'default')) + math.inf, 0)) return {'ecms': ecms} def _calculatePoint(self, x, miscParams, src, tgt, commonData): distance = x combinedStr = 0 - for strength, optimal, falloff, stackingGroup in commonData['ecms']: + for strength, optimal, falloff in commonData['ecms']: combinedStr += strength * calculateRangeFactor(srcOptimalRange=optimal, srcFalloffRange=falloff, distance=distance) return combinedStr diff --git a/graphs/data/fitEwarStats/graph.py b/graphs/data/fitEwarStats/graph.py index 86d65a635..65deeee6f 100644 --- a/graphs/data/fitEwarStats/graph.py +++ b/graphs/data/fitEwarStats/graph.py @@ -20,8 +20,9 @@ from graphs.data.base import FitGraph, Input, XDef, YDef from .getter import ( - Distance2WebbingStrGetter, Distance2EcmStrMaxGetter, Distance2DampStrLockRangeGetter, - Distance2TdStrOptimalGetter, Distance2GdStrRangeGetter, Distance2TpStrGetter) + Distance2NeutingStrGetter, Distance2WebbingStrGetter, Distance2EcmStrMaxGetter, + Distance2DampStrLockRangeGetter, Distance2TdStrOptimalGetter, Distance2GdStrRangeGetter, + Distance2TpStrGetter) class FitEwarStatsGraph(FitGraph): @@ -31,6 +32,7 @@ class FitEwarStatsGraph(FitGraph): name = 'Electronic Warfare Stats' xDefs = [XDef(handle='distance', unit='km', label='Distance', mainInput=('distance', 'km'))] yDefs = [ + YDef(handle='neutStr', unit=None, label='Cap neutralized per second', selectorLabel='Neuts: cap per second'), YDef(handle='webStr', unit='%', label='Speed reduction', selectorLabel='Webs: speed reduction'), YDef(handle='ecmStrMax', unit=None, label='Combined ECM strength', selectorLabel='ECM: combined strength'), YDef(handle='dampStrLockRange', unit='%', label='Lock range reduction', selectorLabel='Damps: lock range reduction'), @@ -47,6 +49,7 @@ class FitEwarStatsGraph(FitGraph): ('resist', '%'): lambda v, src, tgt: None if v is None else v / 100} _limiters = {'resist': lambda src, tgt: (0, 1)} _getters = { + ('distance', 'neutStr'): Distance2NeutingStrGetter, ('distance', 'webStr'): Distance2WebbingStrGetter, ('distance', 'ecmStrMax'): Distance2EcmStrMaxGetter, ('distance', 'dampStrLockRange'): Distance2DampStrLockRangeGetter,