Add separate spoolup calculator
This commit is contained in:
@@ -28,6 +28,8 @@ from eos.enum import Enum
|
||||
from eos.modifiedAttributeDict import ChargeAttrShortcut, ItemAttrShortcut, ModifiedAttributeDict
|
||||
from eos.saveddata.citadel import Citadel
|
||||
from eos.saveddata.mutator import Mutator
|
||||
from eos.utils.spoolSupport import SpoolType, calculateSpoolup
|
||||
from eos.utils.float import floatUnerr
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
@@ -169,9 +171,11 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
self.__charge = None
|
||||
|
||||
self.__dps = None
|
||||
self.__dpsSpool = None
|
||||
self.__dpsSpoolZero = None
|
||||
self.__dpsSpoolFull = None
|
||||
self.__volley = None
|
||||
self.__volleySpool = None
|
||||
self.__volleySpoolZero = None
|
||||
self.__volleySpoolFull = None
|
||||
self.__miningyield = None
|
||||
self.__reloadTime = None
|
||||
self.__reloadForce = None
|
||||
@@ -249,8 +253,8 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
if chargeVolume is None or containerCapacity is None:
|
||||
charges = 0
|
||||
else:
|
||||
charges = floor(containerCapacity / chargeVolume)
|
||||
return int(charges)
|
||||
charges = int(floatUnerr(containerCapacity / chargeVolume))
|
||||
return charges
|
||||
|
||||
@property
|
||||
def numShots(self):
|
||||
@@ -416,9 +420,11 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
def damageStats(self, targetResists):
|
||||
if self.__dps is None:
|
||||
self.__dps = 0
|
||||
self.__dpsSpool = 0
|
||||
self.__dpsSpoolZero = 0
|
||||
self.__dpsSpoolFull = 0
|
||||
self.__volley = 0
|
||||
self.__volleySpool = 0
|
||||
self.__volleySpoolZero = 0
|
||||
self.__volleySpoolFull = 0
|
||||
|
||||
if not self.isEmpty and self.state >= State.ACTIVE:
|
||||
if self.charge:
|
||||
@@ -426,12 +432,24 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
else:
|
||||
func = self.getModifiedItemAttr
|
||||
|
||||
volley = sum([(func("%sDamage" % attr) or 0) * (1 - getattr(targetResists, "%sAmount" % attr, 0)) for attr in self.DAMAGE_TYPES])
|
||||
volley *= self.getModifiedItemAttr("damageMultiplier") or 1
|
||||
# Disintegrator-specific ramp-up multiplier
|
||||
volleySpool = volley * ((self.getModifiedItemAttr("damageMultiplierBonusMax") or 0) + 1)
|
||||
if volley:
|
||||
cycleTime = self.cycleTime
|
||||
cycleTime = self.cycleTime
|
||||
|
||||
# Base volley
|
||||
volleyBase = sum([(func("%sDamage" % attr) or 0) * (1 - getattr(targetResists, "%sAmount" % attr, 0)) for attr in self.DAMAGE_TYPES])
|
||||
volleyBase *= self.getModifiedItemAttr("damageMultiplier") or 1
|
||||
spoolMultMax = self.getModifiedItemAttr("damageMultiplierBonusMax") or 0
|
||||
spoolMultPerCycle = self.getModifiedItemAttr("damageMultiplierBonusPerCycle") or 0
|
||||
# Volley affected by module-specific spoolup
|
||||
if spoolMultMax:
|
||||
volley = volleyBase * (1 + calculateSpoolup(spoolMultMax, spoolMultPerCycle, cycleTime, self.spoolType, self.spoolAmount))
|
||||
else:
|
||||
volley = volleyBase
|
||||
# Full spoolup
|
||||
if spoolMultMax:
|
||||
volleySpoolFull = volleyBase * (1 + calculateSpoolup(spoolMultMax, spoolMultPerCycle, cycleTime, SpoolType.SCALE, 1))
|
||||
else:
|
||||
volleySpoolFull = volleyBase
|
||||
if volleyBase:
|
||||
# Some weapons repeat multiple times in one cycle (think doomsdays)
|
||||
# Get the number of times it fires off
|
||||
weaponDoT = max(
|
||||
@@ -440,12 +458,12 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
)
|
||||
|
||||
self.__volley = volley
|
||||
self.__volleySpool = volleySpool
|
||||
self.__volleySpoolFull = volleySpoolFull
|
||||
dpsFactor = weaponDoT / (cycleTime / 1000.0)
|
||||
self.__dps = volley * dpsFactor
|
||||
self.__dpsSpool = volleySpool * dpsFactor
|
||||
self.__dpsSpoolFull = volleySpoolFull * dpsFactor
|
||||
|
||||
return self.__dps, self.__dpsSpool, self.__volley, self.__volleySpool
|
||||
return self.__dps, self.__dpsSpoolFull, self.__volley, self.__volleySpoolFull
|
||||
|
||||
@property
|
||||
def miningStats(self):
|
||||
@@ -730,6 +748,11 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
|
||||
def clear(self):
|
||||
self.__dps = None
|
||||
self.__dpsSpoolZero = None
|
||||
self.__dpsSpoolFull = None
|
||||
self.__volley = None
|
||||
self.__volleySpoolZero = None
|
||||
self.__volleySpoolFull = None
|
||||
self.__miningyield = None
|
||||
self.__volley = None
|
||||
self.__reloadTime = None
|
||||
|
||||
0
eos/utils/__init__.py
Normal file
0
eos/utils/__init__.py
Normal file
26
eos/utils/float.py
Normal file
26
eos/utils/float.py
Normal file
@@ -0,0 +1,26 @@
|
||||
"""
|
||||
Sometimes use of floats may lead to undesirable results, e.g.
|
||||
int(2.3 / 0.1) = 22.
|
||||
We cannot afford to use different number representations (e.g. representations
|
||||
provided by decimal or fraction modules), thus consequences are worked around by
|
||||
this module.
|
||||
"""
|
||||
|
||||
import math
|
||||
import sys
|
||||
|
||||
|
||||
# As we will be rounding numbers after operations (which introduce higher error
|
||||
# than base float representation error), we need to keep less significant
|
||||
# numbers than for single float number w/o operations
|
||||
keepDigits = int(sys.float_info.dig / 2)
|
||||
|
||||
|
||||
def floatUnerr(value):
|
||||
"""Round possible float number error, killing some precision in process."""
|
||||
if value == 0:
|
||||
return value
|
||||
# Find round factor, taking into consideration that we want to keep at least
|
||||
# predefined amount of significant digits
|
||||
roundFactor = int(keepDigits - math.ceil(math.log10(abs(value))))
|
||||
return round(value, roundFactor)
|
||||
43
eos/utils/spoolSupport.py
Normal file
43
eos/utils/spoolSupport.py
Normal file
@@ -0,0 +1,43 @@
|
||||
# ===============================================================================
|
||||
# Copyright (C) 2010 Diego Duclos
|
||||
#
|
||||
# This file is part of eos.
|
||||
#
|
||||
# eos is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# eos 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with eos. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ===============================================================================
|
||||
|
||||
|
||||
from enum import IntEnum, unique
|
||||
|
||||
from eos.utils.float import floatUnerr
|
||||
|
||||
|
||||
@unique
|
||||
class SpoolType(IntEnum):
|
||||
SCALE = 0 # [0..1]
|
||||
TIME = 1 # Expressed via time in seconds since spoolup started
|
||||
CYCLES = 2 # Expressed in amount of cycles since spoolup started
|
||||
|
||||
|
||||
def calculateSpoolup(modMaxValue, modStepValue, modCycleTime, spoolType, spoolAmount):
|
||||
if spoolType == SpoolType.SCALE:
|
||||
return (floatUnerr(spoolAmount * modMaxValue) // modStepValue) * modStepValue
|
||||
elif spoolType == SpoolType.TIME:
|
||||
# Stub
|
||||
return 0
|
||||
elif spoolType == SpoolType.CYCLES:
|
||||
cycles = round(spoolAmount)
|
||||
return min(modMaxValue, cycles * modStepValue)
|
||||
else:
|
||||
return 0
|
||||
Reference in New Issue
Block a user