Add lock range limit support to ewar graph

This commit is contained in:
DarkPhoenix
2019-09-27 20:43:28 +03:00
parent 0ed16b9a6f
commit fd017df561

View File

@@ -20,9 +20,8 @@
import math import math
from graphs.calc import calculateMultiplier, calculateRangeFactor from graphs.calc import calculateMultiplier, calculateRangeFactor, checkLockRange, checkDroneControlRange
from graphs.data.base import SmoothPointGetter from graphs.data.base import SmoothPointGetter
from service.settings import GraphSettings
class Distance2NeutingStrGetter(SmoothPointGetter): class Distance2NeutingStrGetter(SmoothPointGetter):
@@ -38,34 +37,37 @@ class Distance2NeutingStrGetter(SmoothPointGetter):
if effectName in mod.item.effects: if effectName in mod.item.effects:
neuts.append(( neuts.append((
mod.getModifiedItemAttr('energyNeutralizerAmount') / self.__getDuration(mod) * resonance, mod.getModifiedItemAttr('energyNeutralizerAmount') / self.__getDuration(mod) * resonance,
mod.maxRange or 0, mod.falloff or 0)) mod.maxRange or 0, mod.falloff or 0, True, False))
if 'energyNosferatuFalloff' in mod.item.effects and mod.getModifiedItemAttr('nosOverride'): if 'energyNosferatuFalloff' in mod.item.effects and mod.getModifiedItemAttr('nosOverride'):
neuts.append(( neuts.append((
mod.getModifiedItemAttr('powerTransferAmount') / self.__getDuration(mod) * resonance, mod.getModifiedItemAttr('powerTransferAmount') / self.__getDuration(mod) * resonance,
mod.maxRange or 0, mod.falloff or 0)) mod.maxRange or 0, mod.falloff or 0, True, False))
if 'doomsdayAOENeut' in mod.item.effects: if 'doomsdayAOENeut' in mod.item.effects:
neuts.append(( neuts.append((
mod.getModifiedItemAttr('energyNeutralizerAmount') / self.__getDuration(mod) * resonance, mod.getModifiedItemAttr('energyNeutralizerAmount') / self.__getDuration(mod) * resonance,
max(0, (mod.maxRange or 0) + mod.getModifiedItemAttr('doomsdayAOERange') - src.getRadius()), max(0, (mod.maxRange or 0) + mod.getModifiedItemAttr('doomsdayAOERange') - src.getRadius()),
mod.falloff or 0)) mod.falloff or 0, False, False))
for drone in src.item.activeDronesIter(): for drone in src.item.activeDronesIter():
if 'entityEnergyNeutralizerFalloff' in drone.item.effects: if 'entityEnergyNeutralizerFalloff' in drone.item.effects:
neuts.extend(drone.amountActive * (( neuts.extend(drone.amountActive * ((
drone.getModifiedItemAttr('energyNeutralizerAmount') / (drone.getModifiedItemAttr('energyNeutralizerDuration') / 1000) * resonance, drone.getModifiedItemAttr('energyNeutralizerAmount') / (drone.getModifiedItemAttr('energyNeutralizerDuration') / 1000) * resonance,
math.inf if GraphSettings.getInstance().get('ignoreDCR') else src.item.extraAttributes['droneControlRange'], math.inf, 0, True, True),))
0),))
for fighter, ability in src.item.activeFighterAbilityIter(): for fighter, ability in src.item.activeFighterAbilityIter():
if ability.effect.name == 'fighterAbilityEnergyNeutralizer': if ability.effect.name == 'fighterAbilityEnergyNeutralizer':
nps = fighter.getModifiedItemAttr('fighterAbilityEnergyNeutralizerAmount') / (ability.cycleTime / 1000) nps = fighter.getModifiedItemAttr('fighterAbilityEnergyNeutralizerAmount') / (ability.cycleTime / 1000)
neuts.append(( neuts.append((
nps * fighter.amount * resonance, nps * fighter.amount * resonance,
math.inf, 0)) math.inf, 0, True, False))
return {'neuts': neuts} return {'neuts': neuts}
def _calculatePoint(self, x, miscParams, src, tgt, commonData): def _calculatePoint(self, x, miscParams, src, tgt, commonData):
distance = x distance = x
inLockRange = checkLockRange(src=src, distance=distance)
inDroneRange = checkDroneControlRange(src=src, distance=distance)
combinedStr = 0 combinedStr = 0
for strength, optimal, falloff in commonData['neuts']: for strength, optimal, falloff, needsLock, needsDcr in commonData['neuts']:
if (needsLock and not inLockRange) or (needsDcr and not inDroneRange):
continue
combinedStr += strength * calculateRangeFactor(srcOptimalRange=optimal, srcFalloffRange=falloff, distance=distance) combinedStr += strength * calculateRangeFactor(srcOptimalRange=optimal, srcFalloffRange=falloff, distance=distance)
return combinedStr return combinedStr
@@ -86,29 +88,32 @@ class Distance2WebbingStrGetter(SmoothPointGetter):
if effectName in mod.item.effects: if effectName in mod.item.effects:
webs.append(( webs.append((
mod.getModifiedItemAttr('speedFactor') * resonance, mod.getModifiedItemAttr('speedFactor') * resonance,
mod.maxRange or 0, mod.falloff or 0, 'default')) mod.maxRange or 0, mod.falloff or 0, 'default', True, False))
if 'doomsdayAOEWeb' in mod.item.effects: if 'doomsdayAOEWeb' in mod.item.effects:
webs.append(( webs.append((
mod.getModifiedItemAttr('speedFactor') * resonance, mod.getModifiedItemAttr('speedFactor') * resonance,
max(0, (mod.maxRange or 0) + mod.getModifiedItemAttr('doomsdayAOERange') - src.getRadius()), max(0, (mod.maxRange or 0) + mod.getModifiedItemAttr('doomsdayAOERange') - src.getRadius()),
mod.falloff or 0, 'default')) mod.falloff or 0, 'default', False, False))
for drone in src.item.activeDronesIter(): for drone in src.item.activeDronesIter():
if 'remoteWebifierEntity' in drone.item.effects: if 'remoteWebifierEntity' in drone.item.effects:
webs.extend(drone.amountActive * (( webs.extend(drone.amountActive * ((
drone.getModifiedItemAttr('speedFactor') * resonance, drone.getModifiedItemAttr('speedFactor') * resonance,
math.inf if GraphSettings.getInstance().get('ignoreDCR') else src.item.extraAttributes['droneControlRange'], math.inf, 0, 'default', True, True),))
0, 'default'),))
for fighter, ability in src.item.activeFighterAbilityIter(): for fighter, ability in src.item.activeFighterAbilityIter():
if ability.effect.name == 'fighterAbilityStasisWebifier': if ability.effect.name == 'fighterAbilityStasisWebifier':
webs.append(( webs.append((
fighter.getModifiedItemAttr('fighterAbilityStasisWebifierSpeedPenalty') * fighter.amount * resonance, fighter.getModifiedItemAttr('fighterAbilityStasisWebifierSpeedPenalty') * fighter.amount * resonance,
math.inf, 0, 'default')) math.inf, 0, 'default', True, False))
return {'webs': webs} return {'webs': webs}
def _calculatePoint(self, x, miscParams, src, tgt, commonData): def _calculatePoint(self, x, miscParams, src, tgt, commonData):
distance = x distance = x
inLockRange = checkLockRange(src=src, distance=distance)
inDroneRange = checkDroneControlRange(src=src, distance=distance)
strMults = {} strMults = {}
for strength, optimal, falloff, stackingGroup in commonData['webs']: for strength, optimal, falloff, stackingGroup, needsLock, needsDcr in commonData['webs']:
if (needsLock and not inLockRange) or (needsDcr and not inDroneRange):
continue
strength *= calculateRangeFactor(srcOptimalRange=optimal, srcFalloffRange=falloff, distance=distance) strength *= calculateRangeFactor(srcOptimalRange=optimal, srcFalloffRange=falloff, distance=distance)
strMults.setdefault(stackingGroup, []).append((1 + strength / 100, None)) strMults.setdefault(stackingGroup, []).append((1 + strength / 100, None))
strMult = calculateMultiplier(strMults) strMult = calculateMultiplier(strMults)
@@ -132,29 +137,32 @@ class Distance2EcmStrMaxGetter(SmoothPointGetter):
if effectName in mod.item.effects: if effectName in mod.item.effects:
ecms.append(( ecms.append((
max(mod.getModifiedItemAttr(a) for a in self.ECM_ATTRS_GENERAL) * resonance, max(mod.getModifiedItemAttr(a) for a in self.ECM_ATTRS_GENERAL) * resonance,
mod.maxRange or 0, mod.falloff or 0)) mod.maxRange or 0, mod.falloff or 0, True, False))
if 'doomsdayAOEECM' in mod.item.effects: if 'doomsdayAOEECM' in mod.item.effects:
ecms.append(( ecms.append((
max(mod.getModifiedItemAttr(a) for a in self.ECM_ATTRS_GENERAL) * resonance, max(mod.getModifiedItemAttr(a) for a in self.ECM_ATTRS_GENERAL) * resonance,
max(0, (mod.maxRange or 0) + mod.getModifiedItemAttr('doomsdayAOERange') - src.getRadius()), max(0, (mod.maxRange or 0) + mod.getModifiedItemAttr('doomsdayAOERange') - src.getRadius()),
mod.falloff or 0)) mod.falloff or 0, False, False))
for drone in src.item.activeDronesIter(): for drone in src.item.activeDronesIter():
if 'entityECMFalloff' in drone.item.effects: if 'entityECMFalloff' in drone.item.effects:
ecms.extend(drone.amountActive * (( ecms.extend(drone.amountActive * ((
max(drone.getModifiedItemAttr(a) for a in self.ECM_ATTRS_GENERAL) * resonance, max(drone.getModifiedItemAttr(a) for a in self.ECM_ATTRS_GENERAL) * resonance,
math.inf if GraphSettings.getInstance().get('ignoreDCR') else src.item.extraAttributes['droneControlRange'], math.inf, 0, True, True),))
0),))
for fighter, ability in src.item.activeFighterAbilityIter(): for fighter, ability in src.item.activeFighterAbilityIter():
if ability.effect.name == 'fighterAbilityECM': if ability.effect.name == 'fighterAbilityECM':
ecms.append(( ecms.append((
max(fighter.getModifiedItemAttr(a) for a in self.ECM_ATTRS_FIGHTERS) * fighter.amount * resonance, max(fighter.getModifiedItemAttr(a) for a in self.ECM_ATTRS_FIGHTERS) * fighter.amount * resonance,
math.inf, 0)) math.inf, 0, True, False))
return {'ecms': ecms} return {'ecms': ecms}
def _calculatePoint(self, x, miscParams, src, tgt, commonData): def _calculatePoint(self, x, miscParams, src, tgt, commonData):
distance = x distance = x
inLockRange = checkLockRange(src=src, distance=distance)
inDroneRange = checkDroneControlRange(src=src, distance=distance)
combinedStr = 0 combinedStr = 0
for strength, optimal, falloff in commonData['ecms']: for strength, optimal, falloff, needsLock, needsDcr in commonData['ecms']:
if (needsLock and not inLockRange) or (needsDcr and not inDroneRange):
continue
combinedStr += strength * calculateRangeFactor(srcOptimalRange=optimal, srcFalloffRange=falloff, distance=distance) combinedStr += strength * calculateRangeFactor(srcOptimalRange=optimal, srcFalloffRange=falloff, distance=distance)
return combinedStr return combinedStr
@@ -172,24 +180,27 @@ class Distance2DampStrLockRangeGetter(SmoothPointGetter):
if effectName in mod.item.effects: if effectName in mod.item.effects:
damps.append(( damps.append((
mod.getModifiedItemAttr('maxTargetRangeBonus') * resonance, mod.getModifiedItemAttr('maxTargetRangeBonus') * resonance,
mod.maxRange or 0, mod.falloff or 0, 'default')) mod.maxRange or 0, mod.falloff or 0, 'default', True, False))
if 'doomsdayAOEDamp' in mod.item.effects: if 'doomsdayAOEDamp' in mod.item.effects:
damps.append(( damps.append((
mod.getModifiedItemAttr('maxTargetRangeBonus') * resonance, mod.getModifiedItemAttr('maxTargetRangeBonus') * resonance,
max(0, (mod.maxRange or 0) + mod.getModifiedItemAttr('doomsdayAOERange') - src.getRadius()), max(0, (mod.maxRange or 0) + mod.getModifiedItemAttr('doomsdayAOERange') - src.getRadius()),
mod.falloff or 0, 'default')) mod.falloff or 0, 'default', False, False))
for drone in src.item.activeDronesIter(): for drone in src.item.activeDronesIter():
if 'remoteSensorDampEntity' in drone.item.effects: if 'remoteSensorDampEntity' in drone.item.effects:
damps.extend(drone.amountActive * (( damps.extend(drone.amountActive * ((
drone.getModifiedItemAttr('maxTargetRangeBonus') * resonance, drone.getModifiedItemAttr('maxTargetRangeBonus') * resonance,
math.inf if GraphSettings.getInstance().get('ignoreDCR') else src.item.extraAttributes['droneControlRange'], math.inf, 0, 'default', True, True),))
0, 'default'),))
return {'damps': damps} return {'damps': damps}
def _calculatePoint(self, x, miscParams, src, tgt, commonData): def _calculatePoint(self, x, miscParams, src, tgt, commonData):
distance = x distance = x
inLockRange = checkLockRange(src=src, distance=distance)
inDroneRange = checkDroneControlRange(src=src, distance=distance)
strMults = {} strMults = {}
for strength, optimal, falloff, stackingGroup in commonData['damps']: for strength, optimal, falloff, stackingGroup, needsLock, needsDcr in commonData['damps']:
if (needsLock and not inLockRange) or (needsDcr and not inDroneRange):
continue
strength *= calculateRangeFactor(srcOptimalRange=optimal, srcFalloffRange=falloff, distance=distance) strength *= calculateRangeFactor(srcOptimalRange=optimal, srcFalloffRange=falloff, distance=distance)
strMults.setdefault(stackingGroup, []).append((1 + strength / 100, None)) strMults.setdefault(stackingGroup, []).append((1 + strength / 100, None))
strMult = calculateMultiplier(strMults) strMult = calculateMultiplier(strMults)
@@ -210,24 +221,27 @@ class Distance2TdStrOptimalGetter(SmoothPointGetter):
if effectName in mod.item.effects: if effectName in mod.item.effects:
tds.append(( tds.append((
mod.getModifiedItemAttr('maxRangeBonus') * resonance, mod.getModifiedItemAttr('maxRangeBonus') * resonance,
mod.maxRange or 0, mod.falloff or 0, 'default')) mod.maxRange or 0, mod.falloff or 0, 'default', True, False))
if 'doomsdayAOETrack' in mod.item.effects: if 'doomsdayAOETrack' in mod.item.effects:
tds.append(( tds.append((
mod.getModifiedItemAttr('maxRangeBonus') * resonance, mod.getModifiedItemAttr('maxRangeBonus') * resonance,
max(0, (mod.maxRange or 0) + mod.getModifiedItemAttr('doomsdayAOERange') - src.getRadius()), max(0, (mod.maxRange or 0) + mod.getModifiedItemAttr('doomsdayAOERange') - src.getRadius()),
mod.falloff or 0, 'default')) mod.falloff or 0, 'default', False, False))
for drone in src.item.activeDronesIter(): for drone in src.item.activeDronesIter():
if 'npcEntityWeaponDisruptor' in drone.item.effects: if 'npcEntityWeaponDisruptor' in drone.item.effects:
tds.extend(drone.amountActive * (( tds.extend(drone.amountActive * ((
drone.getModifiedItemAttr('maxRangeBonus') * resonance, drone.getModifiedItemAttr('maxRangeBonus') * resonance,
math.inf if GraphSettings.getInstance().get('ignoreDCR') else src.item.extraAttributes['droneControlRange'], math.inf, 0, 'default', True, True),))
0, 'default'),))
return {'tds': tds} return {'tds': tds}
def _calculatePoint(self, x, miscParams, src, tgt, commonData): def _calculatePoint(self, x, miscParams, src, tgt, commonData):
distance = x distance = x
inLockRange = checkLockRange(src=src, distance=distance)
inDroneRange = checkDroneControlRange(src=src, distance=distance)
strMults = {} strMults = {}
for strength, optimal, falloff, stackingGroup in commonData['tds']: for strength, optimal, falloff, stackingGroup, needsLock, needsDcr in commonData['tds']:
if (needsLock and not inLockRange) or (needsDcr and not inDroneRange):
continue
strength *= calculateRangeFactor(srcOptimalRange=optimal, srcFalloffRange=falloff, distance=distance) strength *= calculateRangeFactor(srcOptimalRange=optimal, srcFalloffRange=falloff, distance=distance)
strMults.setdefault(stackingGroup, []).append((1 + strength / 100, None)) strMults.setdefault(stackingGroup, []).append((1 + strength / 100, None))
strMult = calculateMultiplier(strMults) strMult = calculateMultiplier(strMults)
@@ -249,20 +263,24 @@ class Distance2GdStrRangeGetter(SmoothPointGetter):
gds.append(( gds.append((
mod.getModifiedItemAttr('missileVelocityBonus') * resonance, mod.getModifiedItemAttr('missileVelocityBonus') * resonance,
mod.getModifiedItemAttr('explosionDelayBonus') * resonance, mod.getModifiedItemAttr('explosionDelayBonus') * resonance,
mod.maxRange or 0, mod.falloff or 0, 'default')) mod.maxRange or 0, mod.falloff or 0, 'default', True, False))
if 'doomsdayAOETrack' in mod.item.effects: if 'doomsdayAOETrack' in mod.item.effects:
gds.append(( gds.append((
mod.getModifiedItemAttr('missileVelocityBonus') * resonance, mod.getModifiedItemAttr('missileVelocityBonus') * resonance,
mod.getModifiedItemAttr('explosionDelayBonus') * resonance, mod.getModifiedItemAttr('explosionDelayBonus') * resonance,
max(0, (mod.maxRange or 0) + mod.getModifiedItemAttr('doomsdayAOERange') - src.getRadius()), max(0, (mod.maxRange or 0) + mod.getModifiedItemAttr('doomsdayAOERange') - src.getRadius()),
mod.falloff or 0, 'default')) mod.falloff or 0, 'default', False, False))
return {'gds': gds} return {'gds': gds}
def _calculatePoint(self, x, miscParams, src, tgt, commonData): def _calculatePoint(self, x, miscParams, src, tgt, commonData):
distance = x distance = x
inLockRange = checkLockRange(src=src, distance=distance)
inDroneRange = checkDroneControlRange(src=src, distance=distance)
velocityStrMults = {} velocityStrMults = {}
timeStrMults = {} timeStrMults = {}
for velocityStr, timeStr, optimal, falloff, stackingGroup in commonData['gds']: for velocityStr, timeStr, optimal, falloff, stackingGroup, needsLock, needsDcr in commonData['gds']:
if (needsLock and not inLockRange) or (needsDcr and not inDroneRange):
continue
rangeFactor = calculateRangeFactor(srcOptimalRange=optimal, srcFalloffRange=falloff, distance=distance) rangeFactor = calculateRangeFactor(srcOptimalRange=optimal, srcFalloffRange=falloff, distance=distance)
velocityStr *= rangeFactor velocityStr *= rangeFactor
timeStr *= rangeFactor timeStr *= rangeFactor
@@ -287,24 +305,27 @@ class Distance2TpStrGetter(SmoothPointGetter):
if effectName in mod.item.effects: if effectName in mod.item.effects:
tps.append(( tps.append((
mod.getModifiedItemAttr('signatureRadiusBonus') * resonance, mod.getModifiedItemAttr('signatureRadiusBonus') * resonance,
mod.maxRange or 0, mod.falloff or 0, 'default')) mod.maxRange or 0, mod.falloff or 0, 'default', True, False))
if 'doomsdayAOEPaint' in mod.item.effects: if 'doomsdayAOEPaint' in mod.item.effects:
tps.append(( tps.append((
mod.getModifiedItemAttr('signatureRadiusBonus') * resonance, mod.getModifiedItemAttr('signatureRadiusBonus') * resonance,
max(0, (mod.maxRange or 0) + mod.getModifiedItemAttr('doomsdayAOERange') - src.getRadius()), max(0, (mod.maxRange or 0) + mod.getModifiedItemAttr('doomsdayAOERange') - src.getRadius()),
mod.falloff or 0, 'default')) mod.falloff or 0, 'default', False, False))
for drone in src.item.activeDronesIter(): for drone in src.item.activeDronesIter():
if 'remoteTargetPaintEntity' in drone.item.effects: if 'remoteTargetPaintEntity' in drone.item.effects:
tps.extend(drone.amountActive * (( tps.extend(drone.amountActive * ((
drone.getModifiedItemAttr('signatureRadiusBonus') * resonance, drone.getModifiedItemAttr('signatureRadiusBonus') * resonance,
math.inf if GraphSettings.getInstance().get('ignoreDCR') else src.item.extraAttributes['droneControlRange'], math.inf, 0, 'default', True, True),))
0, 'default'),))
return {'tps': tps} return {'tps': tps}
def _calculatePoint(self, x, miscParams, src, tgt, commonData): def _calculatePoint(self, x, miscParams, src, tgt, commonData):
distance = x distance = x
inLockRange = checkLockRange(src=src, distance=distance)
inDroneRange = checkDroneControlRange(src=src, distance=distance)
strMults = {} strMults = {}
for strength, optimal, falloff, stackingGroup in commonData['tps']: for strength, optimal, falloff, stackingGroup, needsLock, needsDcr in commonData['tps']:
if (needsLock and not inLockRange) or (needsDcr and not inDroneRange):
continue
strength *= calculateRangeFactor(srcOptimalRange=optimal, srcFalloffRange=falloff, distance=distance) strength *= calculateRangeFactor(srcOptimalRange=optimal, srcFalloffRange=falloff, distance=distance)
strMults.setdefault(stackingGroup, []).append((1 + strength / 100, None)) strMults.setdefault(stackingGroup, []).append((1 + strength / 100, None))
strMult = calculateMultiplier(strMults) strMult = calculateMultiplier(strMults)