diff --git a/graphs/data/__init__.py b/graphs/data/__init__.py
index abd740ea0..8bd2b8fbe 100644
--- a/graphs/data/__init__.py
+++ b/graphs/data/__init__.py
@@ -28,7 +28,7 @@ from . import fitShieldRegen
from . import fitCapacitor
from . import fitMobility
from . import fitWarpTime
-from . import fitLockTimeOutgoing
+from . import fitLockTime
if _config.experimentalFeatures:
- from . import fitLockTimeIncoming
+ from . import fitEcmBurstScanresDamps
diff --git a/graphs/data/fitLockTimeOutgoing/__init__.py b/graphs/data/fitEcmBurstScanresDamps/__init__.py
similarity index 90%
rename from graphs/data/fitLockTimeOutgoing/__init__.py
rename to graphs/data/fitEcmBurstScanresDamps/__init__.py
index 8713af700..baaa4b9ff 100644
--- a/graphs/data/fitLockTimeOutgoing/__init__.py
+++ b/graphs/data/fitEcmBurstScanresDamps/__init__.py
@@ -18,7 +18,7 @@
# =============================================================================
-from .graph import FitLockTimeOutgoingGraph
+from .graph import FitEcmBurstScanresDampsGraph
-FitLockTimeOutgoingGraph.register()
+FitEcmBurstScanresDampsGraph.register()
diff --git a/graphs/data/fitEcmBurstScanresDamps/getter.py b/graphs/data/fitEcmBurstScanresDamps/getter.py
new file mode 100644
index 000000000..c0934b02b
--- /dev/null
+++ b/graphs/data/fitEcmBurstScanresDamps/getter.py
@@ -0,0 +1,117 @@
+# =============================================================================
+# Copyright (C) 2010 Diego Duclos
+#
+# This file is part of pyfa.
+#
+# pyfa is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# pyfa is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with pyfa. If not, see .
+# =============================================================================
+
+
+from eos.calc import calculateLockTime
+from graphs.data.base import SmoothPointGetter
+
+
+ECM_BURST_DURATION = 30
+DRONE_LOCK_TIME = 2
+
+
+class TgtScanRes2TgtLockTimeGetter(SmoothPointGetter):
+
+ def _getCommonData(self, miscParams, src, tgt):
+ if miscParams['applyDamps']:
+ tgtScanResMult = src.item.getDampMultScanRes()
+ else:
+ tgtScanResMult = 1
+ return {
+ 'tgtScanResMult': tgtScanResMult,
+ 'sigRadius': src.item.ship.getModifiedItemAttr('signatureRadius')}
+
+ def _calculatePoint(self, x, miscParams, src, tgt, commonData):
+ scanRes = x
+ time = calculateLockTime(
+ srcScanRes=scanRes * commonData['tgtScanResMult'],
+ tgtSigRadius=commonData['sigRadius'])
+ return time
+
+
+class TgtScanRes2TgtLockUptimeGetter(TgtScanRes2TgtLockTimeGetter):
+
+ def _calculatePoint(self, *args, **kwargs):
+ # Assuming you ECM burst every 30 seconds, find out how long you
+ # will be locked before you burst another time
+ lockTime = super()._calculatePoint(*args, **kwargs)
+ lockedTime = max(0, ECM_BURST_DURATION - lockTime)
+ return lockedTime
+
+
+class SrcDmgBaseGetter(SmoothPointGetter):
+
+ def _getCommonData(self, miscParams, src, tgt):
+ if miscParams['applyDamps']:
+ tgtScanResMult = src.item.getDampMultScanRes()
+ else:
+ tgtScanResMult = 1
+ return {
+ 'tgtScanResMult': tgtScanResMult,
+ 'srcSigRadius': src.item.ship.getModifiedItemAttr('signatureRadius'),
+ 'srcEhp': sum(src.item.ehp.values()),
+ 'srcDpsWeapon': src.item.getWeaponDps().total,
+ 'srcDpsDrone': src.item.getDroneDps().total if miscParams['applyDrones'] else 0}
+
+ @staticmethod
+ def _calculateInflictedDamage(srcSigRadius, srcWeaponDps, srcDroneDps, srcEhp, tgtScanRes, tgtDps, uptimeAdjustment, uptimeAmountLimit):
+ lockTime = calculateLockTime(srcScanRes=tgtScanRes, tgtSigRadius=srcSigRadius)
+ lockUptime = max(0, ECM_BURST_DURATION - lockTime - uptimeAdjustment)
+ lockDowntime = ECM_BURST_DURATION - lockUptime
+ inflictedDmg = 0
+ remainingEhp = srcEhp
+ for i in range(int(uptimeAmountLimit)):
+ timeAliveUnderFire = min(lockUptime, remainingEhp / tgtDps)
+ timeAlive = lockDowntime + timeAliveUnderFire
+ remainingEhp -= lockUptime * tgtDps
+ inflictedDmg += timeAlive * srcWeaponDps
+ inflictedDmg += max(0, timeAlive - DRONE_LOCK_TIME - 1) * srcDroneDps
+ if remainingEhp <= 0:
+ break
+ return inflictedDmg
+
+
+class TgtScanRes2SrcDmgGetter(SrcDmgBaseGetter):
+
+ def _calculatePoint(self, x, miscParams, src, tgt, commonData):
+ damage = self._calculateInflictedDamage(
+ srcSigRadius=commonData['srcSigRadius'],
+ srcWeaponDps=commonData['srcDpsWeapon'],
+ srcDroneDps=commonData['srcDpsDrone'],
+ srcEhp=commonData['srcEhp'],
+ tgtScanRes=x * commonData['tgtScanResMult'],
+ tgtDps=miscParams['tgtDps'],
+ uptimeAdjustment=miscParams['uptimeAdj'],
+ uptimeAmountLimit=miscParams['uptimeAmtLimit'])
+ return damage
+
+
+class TgtDps2SrcDmgGetter(SrcDmgBaseGetter):
+
+ def _calculatePoint(self, x, miscParams, src, tgt, commonData):
+ damage = self._calculateInflictedDamage(
+ srcSigRadius=commonData['srcSigRadius'],
+ srcWeaponDps=commonData['srcDpsWeapon'],
+ srcDroneDps=commonData['srcDpsDrone'],
+ srcEhp=commonData['srcEhp'],
+ tgtScanRes=miscParams['tgtScanRes'] * commonData['tgtScanResMult'],
+ tgtDps=x,
+ uptimeAdjustment=miscParams['uptimeAdj'],
+ uptimeAmountLimit=miscParams['uptimeAmtLimit'])
+ return damage
diff --git a/graphs/data/fitEcmBurstScanresDamps/graph.py b/graphs/data/fitEcmBurstScanresDamps/graph.py
new file mode 100644
index 000000000..0f99a7fa4
--- /dev/null
+++ b/graphs/data/fitEcmBurstScanresDamps/graph.py
@@ -0,0 +1,64 @@
+# =============================================================================
+# Copyright (C) 2010 Diego Duclos
+#
+# This file is part of pyfa.
+#
+# pyfa is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# pyfa is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with pyfa. If not, see .
+# =============================================================================
+
+
+"""
+Disclaimer by kadesh: this graph was made to analyze my ECM burst + damp frig
+concept. I do not think it is useful for regular player, so it is disabled.
+Enable by setting config.experimentalFeatures = True.
+"""
+
+
+import math
+
+from graphs.data.base import FitGraph, XDef, YDef, Input, InputCheckbox
+from .getter import (
+ TgtScanRes2TgtLockTimeGetter, TgtScanRes2TgtLockUptimeGetter,
+ TgtScanRes2SrcDmgGetter, TgtDps2SrcDmgGetter)
+
+
+class FitEcmBurstScanresDampsGraph(FitGraph):
+
+ # UI stuff
+ internalName = 'ecmBurstScanresDamps'
+ name = 'ECM Burst + Scanres Damps'
+ xDefs = [
+ XDef(handle='tgtScanRes', unit='mm', label='Enemy scanres', mainInput=('tgtScanRes', 'mm')),
+ XDef(handle='tgtDps', unit=None, label='Enemy DPS', mainInput=('tgtDps', None))]
+ yDefs = [
+ YDef(handle='tgtLockTime', unit='s', label='Lock time'),
+ YDef(handle='tgtLockUptime', unit='s', label='Lock uptime'),
+ YDef(handle='srcDmg', unit=None, label='Damage done')]
+ inputs = [
+ Input(handle='tgtScanRes', unit='mm', label='Enemy scanres', iconID=74, defaultValue=700, defaultRange=(100, 1000)),
+ Input(handle='tgtDps', unit=None, label='Enemy DPS', iconID=1432, defaultValue=200, defaultRange=(100, 600)),
+ Input(handle='uptimeAdj', unit='s', label='Uptime adjustment', iconID=1392, defaultValue=1, defaultRange=(None, None), conditions=[(None, ('srcDmg', None))]),
+ Input(handle='uptimeAmtLimit', unit=None, label='Max amount of uptimes', iconID=1397, defaultValue=3, defaultRange=(None, None), conditions=[(None, ('srcDmg', None))])]
+ checkboxes = [
+ InputCheckbox(handle='applyDamps', label='Apply sensor dampeners', defaultValue=True),
+ InputCheckbox(handle='applyDrones', label='Use drones', defaultValue=True, conditions=[(None, ('srcDmg', None))])]
+ srcExtraCols = ('SigRadius', 'Damp ScanRes')
+
+ # Calculation stuff
+ _limiters = {'tgtScanRes': lambda src, tgt: (1, math.inf)}
+ _getters = {
+ ('tgtScanRes', 'tgtLockTime'): TgtScanRes2TgtLockTimeGetter,
+ ('tgtScanRes', 'tgtLockUptime'): TgtScanRes2TgtLockUptimeGetter,
+ ('tgtScanRes', 'srcDmg'): TgtScanRes2SrcDmgGetter,
+ ('tgtDps', 'srcDmg'): TgtDps2SrcDmgGetter}
diff --git a/graphs/data/fitLockTimeIncoming/__init__.py b/graphs/data/fitLockTime/__init__.py
similarity index 91%
rename from graphs/data/fitLockTimeIncoming/__init__.py
rename to graphs/data/fitLockTime/__init__.py
index 4d33df5ad..13f22a3ae 100644
--- a/graphs/data/fitLockTimeIncoming/__init__.py
+++ b/graphs/data/fitLockTime/__init__.py
@@ -18,7 +18,7 @@
# =============================================================================
-from .graph import FitLockTimeIncomingGraph
+from .graph import FitLockTimeGraph
-FitLockTimeIncomingGraph.register()
+FitLockTimeGraph.register()
diff --git a/graphs/data/fitLockTimeOutgoing/getter.py b/graphs/data/fitLockTime/getter.py
similarity index 100%
rename from graphs/data/fitLockTimeOutgoing/getter.py
rename to graphs/data/fitLockTime/getter.py
diff --git a/graphs/data/fitLockTimeOutgoing/graph.py b/graphs/data/fitLockTime/graph.py
similarity index 94%
rename from graphs/data/fitLockTimeOutgoing/graph.py
rename to graphs/data/fitLockTime/graph.py
index aa5732a98..135c61319 100644
--- a/graphs/data/fitLockTimeOutgoing/graph.py
+++ b/graphs/data/fitLockTime/graph.py
@@ -24,10 +24,10 @@ from graphs.data.base import FitGraph, XDef, YDef, Input
from .getter import TgtSigRadius2LockTimeGetter
-class FitLockTimeOutgoingGraph(FitGraph):
+class FitLockTimeGraph(FitGraph):
# UI stuff
- internalName = 'lockTimeOutgoingGraph'
+ internalName = 'lockTimeGraph'
name = 'Lock Time'
xDefs = [XDef(handle='tgtSigRad', unit='m', label='Target signature radius', mainInput=('tgtSigRad', 'm'))]
yDefs = [YDef(handle='time', unit='s', label='Lock time')]
diff --git a/graphs/data/fitLockTimeIncoming/getter.py b/graphs/data/fitLockTimeIncoming/getter.py
deleted file mode 100644
index dc45b04b6..000000000
--- a/graphs/data/fitLockTimeIncoming/getter.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# =============================================================================
-# Copyright (C) 2010 Diego Duclos
-#
-# This file is part of pyfa.
-#
-# pyfa is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# pyfa is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with pyfa. If not, see .
-# =============================================================================
-
-
-from eos.calc import calculateLockTime
-from graphs.data.base import SmoothPointGetter
-
-
-class ScanRes2LockTimeGetter(SmoothPointGetter):
-
- def _getCommonData(self, miscParams, src, tgt):
- if miscParams['applyDamps']:
- scanResMult = src.item.getDampMultScanRes()
- else:
- scanResMult = 1
- return {'scanResMult': scanResMult}
-
- def _calculatePoint(self, x, miscParams, src, tgt, commonData):
- scanRes = x
- time = calculateLockTime(
- srcScanRes=scanRes * commonData['scanResMult'],
- tgtSigRadius=src.item.ship.getModifiedItemAttr('signatureRadius'))
- return time
-
-
-class ScanRes2LockUptimeGetter(ScanRes2LockTimeGetter):
-
- def _calculatePoint(self, *args, **kwargs):
- # Assuming you ECM burst every 30 seconds, find out how long you
- # will be locked before you burst another time
- lockTime = super()._calculatePoint(*args, **kwargs)
- lockedTime = max(0, 30 - lockTime)
- return lockedTime
diff --git a/graphs/data/fitLockTimeIncoming/graph.py b/graphs/data/fitLockTimeIncoming/graph.py
deleted file mode 100644
index 539f673f4..000000000
--- a/graphs/data/fitLockTimeIncoming/graph.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# =============================================================================
-# Copyright (C) 2010 Diego Duclos
-#
-# This file is part of pyfa.
-#
-# pyfa is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# pyfa is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with pyfa. If not, see .
-# =============================================================================
-
-
-"""
-Disclaimer by kadesh: this graph was made to analyze my ECM burst + damp frig
-concept. I do not think it is useful for regular player, so it is disabled.
-Enable by setting config.experimentalFeatures = True.
-"""
-
-
-import math
-
-from graphs.data.base import FitGraph, XDef, YDef, Input, InputCheckbox
-from .getter import ScanRes2LockTimeGetter, ScanRes2LockUptimeGetter
-
-
-class FitLockTimeIncomingGraph(FitGraph):
-
- # UI stuff
- internalName = 'lockTimeIncomingGraph'
- name = 'Lock Time (Incoming)'
- xDefs = [XDef(handle='scanRes', unit='mm', label='Scan resolution', mainInput=('scanRes', 'mm'))]
- yDefs = [
- YDef(handle='lockTime', unit='s', label='Lock time'),
- YDef(handle='lockUptime', unit='s', label='Lock uptime')]
- inputs = [Input(handle='scanRes', unit='mm', label='Scan resolution', iconID=74, defaultValue=None, defaultRange=(100, 1000))]
- checkboxes = [InputCheckbox(handle='applyDamps', label='Apply sensor dampeners', defaultValue=True)]
- srcExtraCols = ('SigRadius', 'Damp ScanRes')
-
- # Calculation stuff
- _limiters = {'scanRes': lambda src, tgt: (1, math.inf)}
- _getters = {
- ('scanRes', 'lockTime'): ScanRes2LockTimeGetter,
- ('scanRes', 'lockUptime'): ScanRes2LockUptimeGetter}