Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions eos/calc.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,8 @@ def calculateLockTime(srcScanRes, tgtSigRadius):
if not srcScanRes or not tgtSigRadius:
return None
return min(40000 / srcScanRes / math.asinh(tgtSigRadius) ** 2, 30 * 60)


def applyWebStrengthCap(speed_factor):
"""Single-web speed reduction cap (EVE: at most -99%)."""
return max(speed_factor, -99.0)
12 changes: 6 additions & 6 deletions eos/effects.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@


import eos.config
from eos.calc import calculateRangeFactor
from eos.calc import calculateRangeFactor, applyWebStrengthCap
from eos.const import FittingModuleState, FitSystemSecurity
from eos.utils.spoolSupport import SpoolType, SpoolOptions, calculateSpoolup, resolveSpoolOptions

Expand Down Expand Up @@ -26967,7 +26967,7 @@ def handler(fit, module, context, projectionRange, **kwargs):
return
if fit.ship.getModifiedItemAttr('disallowOffensiveModifiers'):
return
appliedBoost = module.getModifiedItemAttr('speedFactor') * calculateRangeFactor(
appliedBoost = applyWebStrengthCap(module.getModifiedItemAttr('speedFactor')) * calculateRangeFactor(
srcOptimalRange=module.getModifiedItemAttr('maxRange'),
srcFalloffRange=module.getModifiedItemAttr('falloffEffectiveness'),
distance=projectionRange)
Expand Down Expand Up @@ -27099,7 +27099,7 @@ def handler(cls, fit, src, context, projectionRange, **kwargs):
return
if fit.ship.getModifiedItemAttr('disallowOffensiveModifiers'):
return
speedBoost = src.getModifiedItemAttr('{}SpeedPenalty'.format(cls.prefix)) * src.amount
speedBoost = applyWebStrengthCap(src.getModifiedItemAttr('{}SpeedPenalty'.format(cls.prefix))) * src.amount
speedBoost *= calculateRangeFactor(
srcOptimalRange=src.getModifiedItemAttr('{}OptimalRange'.format(cls.prefix)),
srcFalloffRange=src.getModifiedItemAttr('{}FalloffRange'.format(cls.prefix)),
Expand Down Expand Up @@ -27445,7 +27445,7 @@ def handler(fit, module, context, projectionRange, **kwargs):
return
if fit.ship.getModifiedItemAttr('disallowOffensiveModifiers'):
return
fit.ship.boostItemAttr('maxVelocity', module.getModifiedItemAttr('speedFactor'),
fit.ship.boostItemAttr('maxVelocity', applyWebStrengthCap(module.getModifiedItemAttr('speedFactor')),
stackingPenalties=True, **kwargs)


Expand Down Expand Up @@ -30385,7 +30385,7 @@ def handler(fit, module, context, projectionRange, **kwargs):
return
if fit.ship.getModifiedItemAttr('disallowOffensiveModifiers'):
return
speedBoost = module.getModifiedItemAttr('speedFactor')
speedBoost = applyWebStrengthCap(module.getModifiedItemAttr('speedFactor'))
speedBoost *= calculateRangeFactor(
srcOptimalRange=module.getModifiedItemAttr('maxRange'),
srcFalloffRange=module.getModifiedItemAttr('falloffEffectiveness'),
Expand Down Expand Up @@ -30599,7 +30599,7 @@ def handler(fit, module, context, projectionRange, **kwargs):
return
if module.getModifiedItemAttr('maxRange', 0) < (projectionRange or 0):
return
fit.ship.boostItemAttr('maxVelocity', module.getModifiedItemAttr('speedFactor'),
fit.ship.boostItemAttr('maxVelocity', applyWebStrengthCap(module.getModifiedItemAttr('speedFactor')),
stackingPenalties=True, **kwargs)


Expand Down
9 changes: 5 additions & 4 deletions graphs/data/fitDamageStats/cache/projected.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

from collections import namedtuple

from eos.calc import applyWebStrengthCap
from eos.modifiedAttributeDict import getResistanceAttrID
from graphs.data.base import FitDataCache

Expand All @@ -42,14 +43,14 @@ def getProjModData(self, src):
for webEffectName in ('remoteWebifierFalloff', 'structureModuleEffectStasisWebifier'):
if webEffectName in mod.item.effects:
webMods.append(ModProjData(
mod.getModifiedItemAttr('speedFactor'),
applyWebStrengthCap(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:
webMods.append(ModProjData(
mod.getModifiedItemAttr('speedFactor'),
applyWebStrengthCap(mod.getModifiedItemAttr('speedFactor')),
max(0, (mod.maxRange or 0) + mod.getModifiedItemAttr('doomsdayAOERange')),
mod.falloff or 0,
'default',
Expand Down Expand Up @@ -82,7 +83,7 @@ def getProjDroneData(self, src):
for drone in src.item.activeDronesIter():
if 'remoteWebifierEntity' in drone.item.effects:
webDrones.extend(drone.amountActive * (MobileProjData(
drone.getModifiedItemAttr('speedFactor'),
applyWebStrengthCap(drone.getModifiedItemAttr('speedFactor')),
drone.maxRange or 0,
drone.falloff or 0,
'default',
Expand Down Expand Up @@ -111,7 +112,7 @@ def getProjFighterData(self, src):
for fighter, ability in src.item.activeFighterAbilityIter():
if ability.effect.name == 'fighterAbilityStasisWebifier':
webFighters.append(MobileProjData(
fighter.getModifiedItemAttr('fighterAbilityStasisWebifierSpeedPenalty') * fighter.amount,
applyWebStrengthCap(fighter.getModifiedItemAttr('fighterAbilityStasisWebifierSpeedPenalty')) * fighter.amount,
fighter.getModifiedItemAttr('fighterAbilityStasisWebifierOptimalRange'),
fighter.getModifiedItemAttr('fighterAbilityStasisWebifierFalloffRange'),
'default',
Expand Down
10 changes: 5 additions & 5 deletions graphs/data/fitEwarStats/getter.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

import math

from eos.calc import calculateMultiplier, calculateRangeFactor
from eos.calc import calculateMultiplier, calculateRangeFactor, applyWebStrengthCap
from graphs.calc import checkLockRange, checkDroneControlRange
from graphs.data.base import SmoothPointGetter

Expand Down Expand Up @@ -88,22 +88,22 @@ def _getCommonData(self, miscParams, src, tgt):
for effectName in ('remoteWebifierFalloff', 'structureModuleEffectStasisWebifier'):
if effectName in mod.item.effects:
webs.append((
mod.getModifiedItemAttr('speedFactor') * resonance,
applyWebStrengthCap(mod.getModifiedItemAttr('speedFactor')) * resonance,
mod.maxRange or 0, mod.falloff or 0, 'default', True, False))
if 'doomsdayAOEWeb' in mod.item.effects:
webs.append((
mod.getModifiedItemAttr('speedFactor') * resonance,
applyWebStrengthCap(mod.getModifiedItemAttr('speedFactor')) * resonance,
max(0, (mod.maxRange or 0) + mod.getModifiedItemAttr('doomsdayAOERange')),
mod.falloff or 0, 'default', False, False))
for drone in src.item.activeDronesIter():
if 'remoteWebifierEntity' in drone.item.effects:
webs.extend(drone.amountActive * ((
drone.getModifiedItemAttr('speedFactor') * resonance,
applyWebStrengthCap(drone.getModifiedItemAttr('speedFactor')) * resonance,
math.inf, 0, 'default', True, True),))
for fighter, ability in src.item.activeFighterAbilityIter():
if ability.effect.name == 'fighterAbilityStasisWebifier':
webs.append((
fighter.getModifiedItemAttr('fighterAbilityStasisWebifierSpeedPenalty') * fighter.amount * resonance,
applyWebStrengthCap(fighter.getModifiedItemAttr('fighterAbilityStasisWebifierSpeedPenalty')) * fighter.amount * resonance,
math.inf, 0, 'default', True, False))
return {'webs': webs}

Expand Down
15 changes: 15 additions & 0 deletions gui/builtinItemStatsViews/itemAttributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@
from gui.builtinItemStatsViews.attributeGrouping import *
from gui.utils.numberFormatter import formatAmount, roundDec
from service.const import GuiAttrGroup
from eos.calc import applyWebStrengthCap

_WEB_SPEED_FACTOR_EFFECTS = frozenset((
'remoteWebifierFalloff',
'structureModuleEffectStasisWebifier',
'remoteWebifierEntity',
'doomsdayAOEWeb',
))


_t = wx.GetTranslation
Expand Down Expand Up @@ -307,6 +315,13 @@ def GetData(self, attr, displayOveride=None):
val = getattr(att, "value", None)
value = val if val is not None else att

if (self.toggleView == AttributeView.NORMAL and
attr == 'speedFactor' and
self.isStuffItem and
hasattr(self.stuff, 'item') and self.stuff.item and
_WEB_SPEED_FACTOR_EFFECTS.intersection(getattr(self.stuff.item, 'effects', {}))):
value = applyWebStrengthCap(value)

if self.toggleView == AttributeView.NORMAL and (
(attr not in GroupedAttributes and not (value or valueDefault)) or info is None or not info.published or attr in RequiredSkillAttrs):
return None
Expand Down
5 changes: 3 additions & 2 deletions gui/builtinViewColumns/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from gui.utils.listFormatter import formatList
from eos.utils.float import floatUnerr
from eos.utils.spoolSupport import SpoolType, SpoolOptions
from eos.calc import applyWebStrengthCap
import eos.config


Expand Down Expand Up @@ -176,7 +177,7 @@ def __getData(self, stuff):
text_parts.append("{0}%".format(formatAmount(display, 3, 0, 3, forceSign=True)))
tooltip_parts.append("{0} dampening".format(formatList(ttEntries)).capitalize())
if 'remoteWebifierEntity' in item.effects:
speedFactor = stuff.getModifiedItemAttr("speedFactor")
speedFactor = applyWebStrengthCap(stuff.getModifiedItemAttr("speedFactor"))
if speedFactor:
text_parts.append("{0}%".format(formatAmount(speedFactor, 3, 0, 3)))
tooltip_parts.append("Speed reduction")
Expand Down Expand Up @@ -282,7 +283,7 @@ def __getData(self, stuff):
itemGroup in ("Stasis Web", "Stasis Grappler", "Stasis Webifying Drone", "Structure Stasis Webifier") or
(itemGroup in ("Structure Burst Projector", "Burst Projectors") and "doomsdayAOEWeb" in item.effects)
):
speedFactor = stuff.getModifiedItemAttr("speedFactor")
speedFactor = applyWebStrengthCap(stuff.getModifiedItemAttr("speedFactor"))
if not speedFactor:
return "", None
text = "{0}%".format(formatAmount(speedFactor, 3, 0, 3))
Expand Down
4 changes: 3 additions & 1 deletion service/port/efs.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from eos.effectHandlerHelpers import HandledList
from eos.db import gamedata_session, getCategory, getAttributeInfo, getGroup
from eos.gamedata import Attribute, Effect, Group, Item, ItemEffect
from eos.calc import applyWebStrengthCap
from eos.utils.spoolSupport import SpoolType, SpoolOptions
from gui.fitCommands.calc.module.localAdd import CalcAddLocalModuleCommand
from gui.fitCommands.calc.module.localRemove import CalcRemoveLocalModulesCommand
Expand Down Expand Up @@ -180,7 +181,8 @@ def getOutgoingProjectionData(fit):
if mod.item.group.name in ["Stasis Web", "Stasis Grappler"]:
stats["type"] = "Stasis Web"
stats["optimal"] = mod.getModifiedItemAttr("maxRange")
EfsPort.attrDirectMap(["duration", "speedFactor"], stats, mod)
EfsPort.attrDirectMap(["duration"], stats, mod)
stats["speedFactor"] = applyWebStrengthCap(mod.getModifiedItemAttr("speedFactor"))
elif mod.item.group.name == "Weapon Disruptor":
stats["type"] = "Weapon Disruptor"
stats["optimal"] = mod.getModifiedItemAttr("maxRange")
Expand Down