implement a suggestion or six from @blitzmann. Fix a bunch of low level bugs (unlikely to have been noticed since we don't really expose those stats). Add some properties instead of referencing the attribute directly.

This commit is contained in:
Ebag333
2017-02-24 16:10:54 -08:00
parent 5ca882d3ea
commit b3c7273681
4 changed files with 106 additions and 81 deletions

View File

@@ -129,10 +129,10 @@ class Fit(object):
self.__capRecharge = None
self.__calculatedTargets = []
self.__remoteReps = {
"Armor": 0,
"Shield": 0,
"Hull": 0,
"Capacitor": 0,
"Armor": None,
"Shield": None,
"Hull": None,
"Capacitor": None,
}
self.factorReload = False
self.boostsFits = set()
@@ -400,7 +400,7 @@ class Fit(object):
self.commandBonuses = {}
for remoterep_type in self.__remoteReps:
self.__remoteReps[remoterep_type] = 0
self.__remoteReps[remoterep_type] = None
del self.__calculatedTargets[:]
del self.__extraDrains[:]
@@ -1159,76 +1159,64 @@ class Fit(object):
@property
def remoteReps(self):
def amount_per_second(module_amount, module_duration, module_reload, module_chargerate, module_capacity, module_volume):
numcycles = math.floor(module_capacity / (module_volume * module_chargerate))
force_recalc = False
for remoterep_type in self.__remoteReps:
if self.__remoteReps[remoterep_type] is None:
force_recalc = True
break
module_amount *= numcycles
module_duration = module_chargerate * numcycles + module_reload
return module_amount / module_duration
if force_recalc is False:
return self.__remoteReps
for module in self.modules:
# Skip empty modules
if module.isEmpty:
continue
module_group = getattr(module.item.group, "name")
# Skip modules that aren't online
if getattr(module, "state", 0) < 1:
continue
if module_group in ("Remote Armor Repairer", "Ancillary Remote Armor Repairer"):
# Remote Armor Reppers
hp = module.getModifiedItemAttr("armorDamageAmount", 0)
duration = module.getModifiedItemAttr("duration", 0) / 1000
reloadTime = module.getModifiedItemAttr("reloadTime", 0) / 1000
chargeRate = module.getModifiedItemAttr("chargeRate", 1)
fueledMultiplier = module.getModifiedItemAttr("chargedArmorDamageMultiplier", 1)
capacity = module.getModifiedItemAttr("capacity", 0)
volume = module.getModifiedChargeAttr("volume", 0)
duration = module.cycleTime / 1000
if module.charge:
hp *= fueledMultiplier
hp_per_s = amount_per_second(hp, duration, reloadTime, chargeRate, capacity, volume)
else:
hp_per_s = hp / duration
# Skip modules with no duration.
if not duration:
continue
self.__remoteReps["Armor"] += hp_per_s
fueledMultiplier = module.getModifiedItemAttr("chargedArmorDamageMultiplier", 1)
elif module_group in ("Remote Hull Repairer",):
# Remote Hull Reppers
remote_module_groups = {
"Remote Armor Repairer" : "Armor",
"Ancillary Remote Armor Repairer": "Armor",
"Remote Hull Repairer" : "Hull",
"Remote Shield Booster" : "Shield",
"Ancillary Remote Shield Booster": "Shield",
"Remote Capacitor Transmitter" : "Capacitor",
}
module_group = module.item.group.name
if module_group in remote_module_groups:
remote_type = remote_module_groups[module_group]
else:
# Module isn't in our list of remote rep modules, bail
continue
if remote_type == "Hull":
hp = module.getModifiedItemAttr("structureDamageAmount", 0)
duration = module.getModifiedItemAttr("duration", 0) / 1000
hp_per_s = hp / duration
self.__remoteReps["Hull"] += hp_per_s
elif module_group in ("Remote Shield Booster", "Ancillary Remote Shield Booster"):
# Remote Shield Reppers
elif remote_type == "Armor":
hp = module.getModifiedItemAttr("armorDamageAmount", 0)
elif remote_type == "Shield":
hp = module.getModifiedItemAttr("shieldBonus", 0)
duration = module.getModifiedItemAttr("duration", 0) / 1000
reloadTime = module.getModifiedItemAttr("reloadTime", 0) / 1000
chargeRate = module.getModifiedItemAttr("chargeRate", 1)
capacity = module.getModifiedItemAttr("capacity", 0)
volume = module.getModifiedChargeAttr("volume", 0)
if module.charge:
hp_per_s = amount_per_second(hp, duration, reloadTime, chargeRate, capacity, volume)
else:
hp_per_s = hp / duration
self.__remoteReps["Shield"] += hp_per_s
elif module_group in ("Remote Capacitor Transmitter",):
# Remote Capacitor Boosters
elif remote_type == "Capacitor":
hp = module.getModifiedItemAttr("powerTransferAmount", 0)
duration = module.getModifiedItemAttr("duration", 0) / 1000
else:
hp = 0
hp_per_s = hp / duration
if self.__remoteReps[remote_type] is None:
self.__remoteReps[remote_type] = 0
self.__remoteReps["Capacitor"] += hp_per_s
self.__remoteReps[remote_type] += (hp * fueledMultiplier) / duration
return self.__remoteReps

View File

@@ -20,6 +20,7 @@
import logging
from sqlalchemy.orm import validates, reconstructor
from math import floor
import eos.db
from eos.effectHandlerHelpers import HandledItem, HandledCharge
@@ -172,7 +173,7 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
if chargeVolume is None or containerCapacity is None:
charges = 0
else:
charges = floorFloat(float(containerCapacity) / chargeVolume)
charges = floor(containerCapacity / chargeVolume)
return charges
@property
@@ -216,9 +217,10 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
def __calculateAmmoShots(self):
if self.charge is not None:
# Set number of cycles before reload is needed
# numcycles = math.floor(module_capacity / (module_volume * module_chargerate))
chargeRate = self.getModifiedItemAttr("chargeRate")
numCharges = self.numCharges
numShots = floorFloat(float(numCharges) / chargeRate)
numShots = floor(numCharges / chargeRate)
else:
numShots = None
return numShots
@@ -665,32 +667,67 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
@property
def cycleTime(self):
reactivation = (self.getModifiedItemAttr("moduleReactivationDelay") or 0)
# Reactivation time starts counting after end of module cycle
speed = self.rawCycleTime + reactivation
if self.charge:
reload = self.reloadTime
else:
reload = 0.0
# Determine if we'll take into account reload time or not
factorReload = self.owner.factorReload if self.forceReload is None else self.forceReload
# If reactivation is longer than 10 seconds then module can be reloaded
# during reactivation time, thus we may ignore reload
if factorReload and reactivation < reload:
numShots = self.numShots
# Time it takes to reload module after end of reactivation time,
# given that we started when module cycle has just over
additionalReloadTime = (reload - reactivation)
# Speed here already takes into consideration reactivation time
speed = (speed * numShots + additionalReloadTime) / numShots if numShots > 0 else speed
numShots = self.numShots
speed = self.rawCycleTime
if factorReload and self.charge:
raw_reload_time = self.reloadTime
else:
raw_reload_time = 0.0
# Module can only fire one shot at a time, think bomb launchers or defender launchers
if self.disallowRepeatingAction:
if numShots > 1:
"""
The actual mechanics behind this is complex. Behavior will be (for 3 ammo):
fire, reactivation delay, fire, reactivation delay, fire, max(reactivation delay, reload)
so your effective reload time depends on where you are at in the cycle.
We can't do that, so instead we'll average it out.
Currently would apply to bomb launchers and defender missiles
"""
effective_reload_time = ((self.reactivationDelay * numShots) + raw_reload_time) / numShots
else:
"""
Applies to MJD/MJFG
"""
effective_reload_time = max(raw_reload_time, self.reactivationDelay, 0)
else:
"""
Currently no other modules would have a reactivation delay, so for sanities sake don't try and account for it.
"""
effective_reload_time = raw_reload_time
if numShots > 0 and self.charge:
speed = (speed * numShots + effective_reload_time) / numShots
return speed
@property
def rawCycleTime(self):
speed = self.getModifiedItemAttr("speed") or self.getModifiedItemAttr("duration")
speed = max(
self.getModifiedItemAttr("speed"), # Most weapons
self.getModifiedItemAttr("duration"), # Most average modules
self.getModifiedItemAttr("durationSensorDampeningBurstProjector"),
self.getModifiedItemAttr("durationTargetIlluminationBurstProjector"),
self.getModifiedItemAttr("durationECMJammerBurstProjector"),
self.getModifiedItemAttr("durationWeaponDisruptionBurstProjector"),
0, # Return 0 if none of the above are valid
)
return speed
@property
def disallowRepeatingAction(self):
return self.getModifiedItemAttr("disallowRepeatingAction", 0)
@property
def reactivationDelay(self):
return self.getModifiedItemAttr("moduleReactivationDelay", 0)
@property
def capUse(self):
capNeed = self.getModifiedItemAttr("capacitorNeed")

View File

@@ -53,10 +53,10 @@ class OutgoingViewFull(StatsView):
counter = 0
rr_list = [
("RemoteArmor", "Armor:", "armorActive", "Armor hitpoints per second repaired remotely."),
("RemoteShield", "Shield:", "shieldActive", "Shield hitpoints per second repaired remotely."),
("RemoteHull", "Hull:", "hullActive", "Hull hitpoints per second repaired remotely."),
("RemoteCapacitor", "Capacitor:", "capacitorInfo", "Capacitor GJ/s per second transferred remotely."),
("RemoteShield", "Shield:", "shieldActive", "Shield hitpoints per second repaired remotely."),
("RemoteArmor", "Armor:", "armorActive", "Armor hitpoints per second repaired remotely."),
("RemoteHull", "Hull:", "hullActive", "Hull hitpoints per second repaired remotely."),
]
for outgoingType, label, image, tooltip in rr_list:

View File

@@ -53,10 +53,10 @@ class OutgoingViewFull(StatsView):
counter = 0
rr_list = [
("RemoteArmor", "Armor:", "armorActive", "Armor hitpoints per second repaired remotely."),
("RemoteShield", "Shield:", "shieldActive", "Shield hitpoints per second repaired remotely."),
("RemoteHull", "Hull:", "hullActive", "Hull hitpoints per second repaired remotely."),
("RemoteCapacitor", "Capacitor:", "capacitorInfo", "Capacitor GJ/s per second transferred remotely."),
("RemoteShield", "Shield:", "shieldActive", "Shield hitpoints per second repaired remotely."),
("RemoteArmor", "Armor:", "armorActive", "Armor hitpoints per second repaired remotely."),
("RemoteHull", "Hull:", "hullActive", "Hull hitpoints per second repaired remotely."),
]
for outgoingType, label, image, tooltip in rr_list: