When setting fighter's amount attribute to max or more than max, set it to -1 internally
It will show up as max amount when reading
This commit is contained in:
@@ -46,6 +46,7 @@ fighter_abilities_table = Table("fightersAbilities", saveddata_meta,
|
||||
mapper(Fighter, fighters_table,
|
||||
properties={
|
||||
"owner" : relation(Fit),
|
||||
"_amount" : fighters_table.c.amount,
|
||||
"_Fighter__abilities": relation(
|
||||
FighterAbility,
|
||||
backref="fighter",
|
||||
|
||||
@@ -27268,7 +27268,7 @@ class Effect6434(BaseEffect):
|
||||
@classmethod
|
||||
def handler(cls, fit, src, context, **kwargs):
|
||||
if 'projected' in context:
|
||||
amount = src.getModifiedItemAttr('{}Amount'.format(cls.prefix)) * src.amountActive
|
||||
amount = src.getModifiedItemAttr('{}Amount'.format(cls.prefix)) * src.amount
|
||||
time = src.getModifiedItemAttr('{}Duration'.format(cls.prefix))
|
||||
|
||||
if 'effect' in kwargs:
|
||||
@@ -27295,7 +27295,7 @@ class Effect6435(BaseEffect):
|
||||
def handler(cls, fit, src, context, **kwargs):
|
||||
if 'projected' not in context:
|
||||
return
|
||||
fit.ship.boostItemAttr('maxVelocity', src.getModifiedItemAttr('{}SpeedPenalty'.format(cls.prefix)) * src.amountActive,
|
||||
fit.ship.boostItemAttr('maxVelocity', src.getModifiedItemAttr('{}SpeedPenalty'.format(cls.prefix)) * src.amount,
|
||||
stackingPenalties=True, **kwargs)
|
||||
|
||||
|
||||
@@ -27316,7 +27316,7 @@ class Effect6436(BaseEffect):
|
||||
def handler(cls, fit, src, context, **kwargs):
|
||||
if 'projected' not in context:
|
||||
return
|
||||
fit.ship.increaseItemAttr('warpScrambleStatus', src.getModifiedItemAttr('{}PointStrength'.format(cls.prefix)) * src.amountActive, **kwargs)
|
||||
fit.ship.increaseItemAttr('warpScrambleStatus', src.getModifiedItemAttr('{}PointStrength'.format(cls.prefix)) * src.amount, **kwargs)
|
||||
|
||||
|
||||
class Effect6437(BaseEffect):
|
||||
@@ -27333,11 +27333,11 @@ class Effect6437(BaseEffect):
|
||||
type = 'projected', 'active'
|
||||
|
||||
@classmethod
|
||||
def handler(cls, fit, module, context, **kwargs):
|
||||
def handler(cls, fit, src, context, **kwargs):
|
||||
if 'projected' not in context:
|
||||
return
|
||||
# jam formula: 1 - (1- (jammer str/ship str))^(# of jam mods with same str))
|
||||
strModifier = 1 - (module.getModifiedItemAttr('{}Strength{}'.format(cls.prefix, fit.scanType)) * module.amountActive) / fit.scanStrength
|
||||
strModifier = 1 - (src.getModifiedItemAttr('{}Strength{}'.format(cls.prefix, fit.scanType)) * src.amount) / fit.scanStrength
|
||||
|
||||
if 'effect' in kwargs:
|
||||
from eos.modifiedAttributeDict import ModifiedAttributeDict
|
||||
|
||||
@@ -51,7 +51,7 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
|
||||
# -1 is a placeholder that represents max squadron size, which we may not know yet as ships may modify this with
|
||||
# their effects. If user changes this, it is then overridden with user value.
|
||||
self.amount = -1
|
||||
self._amount = -1
|
||||
|
||||
self.__abilities = self.__getAbilities()
|
||||
|
||||
@@ -136,12 +136,15 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
return self.__slot
|
||||
|
||||
@property
|
||||
def amountActive(self):
|
||||
return int(self.getModifiedItemAttr("fighterSquadronMaxSize")) if self.amount == -1 else self.amount
|
||||
def amount(self):
|
||||
return int(self.getModifiedItemAttr("fighterSquadronMaxSize")) if self._amount == -1 else self._amount
|
||||
|
||||
@amountActive.setter
|
||||
def amountActive(self, i):
|
||||
self.amount = int(max(min(i, self.getModifiedItemAttr("fighterSquadronMaxSize")), 0))
|
||||
@amount.setter
|
||||
def amount(self, amount):
|
||||
amount = max(0, int(amount))
|
||||
if amount >= self.getModifiedItemAttr("fighterSquadronMaxSize"):
|
||||
amount = -1
|
||||
self._amount = amount
|
||||
|
||||
@property
|
||||
def fighterSquadronMaxSize(self):
|
||||
@@ -184,7 +187,7 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
return False
|
||||
|
||||
def getVolleyParametersPerEffect(self, targetProfile=None):
|
||||
if not self.active or self.amountActive <= 0:
|
||||
if not self.active or self.amount <= 0:
|
||||
return {}
|
||||
if self.__baseVolley is None:
|
||||
self.__baseVolley = {}
|
||||
@@ -235,7 +238,7 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
return DmgTypes(em=em, thermal=thermal, kinetic=kinetic, explosive=explosive)
|
||||
|
||||
def getDpsPerEffect(self, targetProfile=None):
|
||||
if not self.active or self.amountActive <= 0:
|
||||
if not self.active or self.amount <= 0:
|
||||
return {}
|
||||
cycleParams = self.getCycleParametersPerEffectOptimizedDps(targetProfile=targetProfile)
|
||||
dpsMap = {}
|
||||
@@ -339,7 +342,7 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
if falloff is not None:
|
||||
return falloff
|
||||
|
||||
@validates("ID", "itemID", "chargeID", "amount", "amountActive")
|
||||
@validates("ID", "itemID", "chargeID", "amount")
|
||||
def validator(self, key, val):
|
||||
map = {
|
||||
"ID" : lambda _val: isinstance(_val, int),
|
||||
@@ -347,7 +350,6 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
"chargeID": lambda _val: isinstance(_val, int),
|
||||
"amount" : lambda _val: isinstance(_val, int) and _val >= -1,
|
||||
}
|
||||
|
||||
if not map[key](val):
|
||||
raise ValueError(str(val) + " is not a valid value for " + key)
|
||||
else:
|
||||
@@ -403,7 +405,7 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
effect.handler(fit, self, context)
|
||||
else:
|
||||
i = 0
|
||||
while i != self.amountActive:
|
||||
while i != self.amount:
|
||||
try:
|
||||
effect.handler(fit, self, context, effect=effect)
|
||||
except:
|
||||
@@ -412,7 +414,7 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
copy = Fighter(self.item)
|
||||
copy.amount = self.amount
|
||||
copy._amount = self._amount
|
||||
copy.active = self.active
|
||||
for ability in self.abilities:
|
||||
copyAbility = next(filter(lambda a: a.effectID == ability.effectID, copy.abilities))
|
||||
@@ -420,11 +422,11 @@ class Fighter(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut):
|
||||
return copy
|
||||
|
||||
def rebase(self, item):
|
||||
amount = self.amount
|
||||
amount = self._amount
|
||||
active = self.active
|
||||
abilityEffectStates = {a.effectID: a.active for a in self.abilities}
|
||||
Fighter.__init__(self, item)
|
||||
self.amount = amount
|
||||
self._amount = amount
|
||||
self.active = active
|
||||
for ability in self.abilities:
|
||||
if ability.effectID in abilityEffectStates:
|
||||
|
||||
@@ -127,7 +127,7 @@ class FighterAbility:
|
||||
therm = self.fighter.getModifiedItemAttr("{}DamageTherm".format(self.attrPrefix), 0)
|
||||
kin = self.fighter.getModifiedItemAttr("{}DamageKin".format(self.attrPrefix), 0)
|
||||
exp = self.fighter.getModifiedItemAttr("{}DamageExp".format(self.attrPrefix), 0)
|
||||
dmgMult = self.fighter.amountActive * self.fighter.getModifiedItemAttr("{}DamageMultiplier".format(self.attrPrefix), 1)
|
||||
dmgMult = self.fighter.amount * self.fighter.getModifiedItemAttr("{}DamageMultiplier".format(self.attrPrefix), 1)
|
||||
volley = DmgTypes(
|
||||
em=em * dmgMult * (1 - getattr(targetProfile, "emAmount", 0)),
|
||||
thermal=therm * dmgMult * (1 - getattr(targetProfile, "thermalAmount", 0)),
|
||||
|
||||
@@ -1098,7 +1098,7 @@ class Fit:
|
||||
def fighterBayUsed(self):
|
||||
amount = 0
|
||||
for f in self.fighters:
|
||||
amount += f.item.volume * f.amountActive
|
||||
amount += f.item.volume * f.amount
|
||||
|
||||
return amount
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ class ProjectedDataCache(FitDataCache):
|
||||
for fighter, ability in src.item.activeFighterAbilityIter():
|
||||
if ability.effect.name == 'fighterAbilityStasisWebifier':
|
||||
webFighters.append(MobileProjData(
|
||||
fighter.getModifiedItemAttr('fighterAbilityStasisWebifierSpeedPenalty') * fighter.amountActive,
|
||||
fighter.getModifiedItemAttr('fighterAbilityStasisWebifierSpeedPenalty') * fighter.amount,
|
||||
fighter.getModifiedItemAttr('fighterAbilityStasisWebifierOptimalRange'),
|
||||
fighter.getModifiedItemAttr('fighterAbilityStasisWebifierFalloffRange'),
|
||||
'default',
|
||||
|
||||
@@ -56,7 +56,7 @@ class Distance2NeutingStrGetter(SmoothPointGetter):
|
||||
if ability.effect.name == 'fighterAbilityEnergyNeutralizer':
|
||||
nps = fighter.getModifiedItemAttr('fighterAbilityEnergyNeutralizerAmount') / (ability.cycleTime / 1000)
|
||||
neuts.append((
|
||||
nps * fighter.amountActive * resonance,
|
||||
nps * fighter.amount * resonance,
|
||||
math.inf, 0))
|
||||
return {'neuts': neuts}
|
||||
|
||||
@@ -98,7 +98,7 @@ class Distance2WebbingStrGetter(SmoothPointGetter):
|
||||
for fighter, ability in src.item.activeFighterAbilityIter():
|
||||
if ability.effect.name == 'fighterAbilityStasisWebifier':
|
||||
webs.append((
|
||||
fighter.getModifiedItemAttr('fighterAbilityStasisWebifierSpeedPenalty') * fighter.amountActive * resonance,
|
||||
fighter.getModifiedItemAttr('fighterAbilityStasisWebifierSpeedPenalty') * fighter.amount * resonance,
|
||||
math.inf, 0, 'default'))
|
||||
return {'webs': webs}
|
||||
|
||||
@@ -143,7 +143,7 @@ class Distance2EcmStrMaxGetter(SmoothPointGetter):
|
||||
for fighter, ability in src.item.activeFighterAbilityIter():
|
||||
if ability.effect.name == 'fighterAbilityECM':
|
||||
ecms.append((
|
||||
max(fighter.getModifiedItemAttr(a) for a in self.ECM_ATTRS_FIGHTERS) * fighter.amountActive * resonance,
|
||||
max(fighter.getModifiedItemAttr(a) for a in self.ECM_ATTRS_FIGHTERS) * fighter.amount * resonance,
|
||||
math.inf, 0))
|
||||
return {'ecms': ecms}
|
||||
|
||||
|
||||
@@ -38,8 +38,6 @@ class ChangeItemAmount(ContextMenuSingle):
|
||||
value = mainItem.getProjectionInfo(fitID).amount
|
||||
except AttributeError:
|
||||
return
|
||||
elif isinstance(mainItem, es_Fighter):
|
||||
value = mainItem.amountActive
|
||||
else:
|
||||
value = mainItem.amount
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ class PriceViewFull(StatsView):
|
||||
|
||||
if fit.fighters:
|
||||
for fighter in fit.fighters:
|
||||
fighter_price += fighter.item.price.price * fighter.amountActive
|
||||
fighter_price += fighter.item.price.price * fighter.amount
|
||||
|
||||
if fit.cargo:
|
||||
for cargo in fit.cargo:
|
||||
|
||||
@@ -104,7 +104,7 @@ class PriceViewMinimal(StatsView):
|
||||
|
||||
if fit.fighters:
|
||||
for fighter in fit.fighters:
|
||||
fighter_price += fighter.item.price.price * fighter.amountActive
|
||||
fighter_price += fighter.item.price.price * fighter.amount
|
||||
|
||||
if fit.cargo:
|
||||
for cargo in fit.cargo:
|
||||
|
||||
@@ -62,7 +62,7 @@ class BaseName(ViewColumn):
|
||||
return "%dx %s" % (stuff.amount, stuff.item.name)
|
||||
elif isinstance(stuff, Fighter):
|
||||
return "%d/%d %s" % \
|
||||
(stuff.amountActive, stuff.getModifiedItemAttr("fighterSquadronMaxSize"), stuff.item.name)
|
||||
(stuff.amount, stuff.getModifiedItemAttr("fighterSquadronMaxSize"), stuff.item.name)
|
||||
elif isinstance(stuff, Cargo):
|
||||
return "%dx %s" % (stuff.amount, stuff.item.name)
|
||||
elif isinstance(stuff, Fit):
|
||||
|
||||
@@ -35,10 +35,8 @@ def formatPrice(stuff, priceObj):
|
||||
textItems = []
|
||||
if priceObj.price:
|
||||
mult = 1
|
||||
if isinstance(stuff, (Drone, Cargo)):
|
||||
if isinstance(stuff, (Drone, Fighter, Cargo)):
|
||||
mult = stuff.amount
|
||||
elif isinstance(stuff, Fighter):
|
||||
mult = stuff.amountActive
|
||||
textItems.append(formatAmount(priceObj.price * mult, 3, 3, 9, currency=True))
|
||||
if priceObj.status in (PriceStatus.fetchFail, PriceStatus.fetchTimeout):
|
||||
textItems.append("(!)")
|
||||
|
||||
@@ -22,7 +22,7 @@ class CalcChangeFighterAmountCommand(wx.Command):
|
||||
fit = Fit.getInstance().getFit(self.fitID)
|
||||
container = fit.projectedFighters if self.projected else fit.fighters
|
||||
fighter = container[self.position]
|
||||
if self.amount == fighter.amount or self.amount == fighter.amountActive:
|
||||
if self.amount == fighter.amount:
|
||||
return False
|
||||
self.savedAmount = fighter.amount
|
||||
if self.amount == -1:
|
||||
|
||||
@@ -165,7 +165,7 @@ def exportDna(fit, options, callback):
|
||||
dna += ":{0};{1}".format(drone.itemID, drone.amount)
|
||||
|
||||
for fighter in fit.fighters:
|
||||
dna += ":{0};{1}".format(fighter.itemID, fighter.amountActive)
|
||||
dna += ":{0};{1}".format(fighter.itemID, fighter.amount)
|
||||
|
||||
for cargo in fit.cargo:
|
||||
# DNA format is a simple/dumb format. As CCP uses the slot information of the item itself
|
||||
|
||||
@@ -294,9 +294,9 @@ class EfsPort:
|
||||
droneIDs.append(drone.item.typeID)
|
||||
droneNames.append("%s x%s" % (drone.item.name, drone.amount))
|
||||
for fighter in fit.fighters:
|
||||
if fighter.amountActive > 0:
|
||||
if fighter.amount > 0:
|
||||
fighterIDs.append(fighter.item.typeID)
|
||||
fighterNames.append("%s x%s" % (fighter.item.name, fighter.amountActive))
|
||||
fighterNames.append("%s x%s" % (fighter.item.name, fighter.amount))
|
||||
if len(droneNames) > 0:
|
||||
modTypeIDs.extend([0, 0])
|
||||
modTypeIDs.extend(droneIDs)
|
||||
@@ -352,7 +352,7 @@ class EfsPort:
|
||||
abBaseDamage = sum(map(lambda damType: fighterAttr(baseRefDam + damType), damTypes))
|
||||
abDamage = abBaseDamage * fighterAttr(baseRefDam + "Multiplier")
|
||||
return {
|
||||
"name": abilityName, "volley": abDamage * fighter.amountActive, "explosionRadius": fighterAttr(baseRef + "ExplosionRadius"),
|
||||
"name": abilityName, "volley": abDamage * fighter.amount, "explosionRadius": fighterAttr(baseRef + "ExplosionRadius"),
|
||||
"explosionVelocity": fighterAttr(baseRef + "ExplosionVelocity"), "optimal": fighterAttr(baseRef + rangeSuffix),
|
||||
"damageReductionFactor": damageReductionFactor, "rof": fighterAttr(baseRef + "Duration"),
|
||||
}
|
||||
@@ -435,7 +435,7 @@ class EfsPort:
|
||||
}
|
||||
weaponSystems.append(statDict)
|
||||
for fighter in fit.fighters:
|
||||
if fighter.getDps().total > 0 and fighter.amountActive > 0:
|
||||
if fighter.getDps().total > 0 and fighter.amount > 0:
|
||||
fighterAttr = fighter.getModifiedItemAttr
|
||||
abilities = []
|
||||
if "fighterAbilityAttackMissileDamageEM" in fighter.item.attributes.keys():
|
||||
@@ -449,7 +449,7 @@ class EfsPort:
|
||||
statDict = {
|
||||
"dps": fighter.getDps().total, "type": "Fighter", "name": fighter.item.name,
|
||||
"maxSpeed": fighterAttr("maxVelocity"), "abilities": abilities,
|
||||
"ehp": fighterAttr("shieldCapacity") / 0.8875 * fighter.amountActive,
|
||||
"ehp": fighterAttr("shieldCapacity") / 0.8875 * fighter.amount,
|
||||
"volley": fighter.getVolley().total, "signatureRadius": fighterAttr("signatureRadius")
|
||||
}
|
||||
weaponSystems.append(statDict)
|
||||
|
||||
@@ -111,7 +111,7 @@ def exportEft(fit, options, callback):
|
||||
minionSection.append('\n'.join(droneLines))
|
||||
fighterLines = []
|
||||
for fighter in sorted(fit.fighters, key=lambda f: f.item.name):
|
||||
fighterLines.append('{} x{}'.format(fighter.item.name, fighter.amountActive))
|
||||
fighterLines.append('{} x{}'.format(fighter.item.name, fighter.amount))
|
||||
if fighterLines:
|
||||
minionSection.append('\n'.join(fighterLines))
|
||||
if minionSection:
|
||||
|
||||
@@ -129,7 +129,7 @@ def exportESI(ofit, callback):
|
||||
for fighter in ofit.fighters:
|
||||
item = nested_dict()
|
||||
item['flag'] = INV_FLAG_FIGHTER
|
||||
item['quantity'] = fighter.amountActive
|
||||
item['quantity'] = fighter.amount
|
||||
item['type_id'] = fighter.item.ID
|
||||
fit['items'].append(item)
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ def exportMultiBuy(fit, options, callback):
|
||||
_addItem(itemAmounts, drone.item, drone.amount)
|
||||
|
||||
for fighter in fit.fighters:
|
||||
_addItem(itemAmounts, fighter.item, fighter.amountActive)
|
||||
_addItem(itemAmounts, fighter.item, fighter.amount)
|
||||
|
||||
if options[PortMultiBuyOptions.CARGO]:
|
||||
for cargo in fit.cargo:
|
||||
|
||||
@@ -312,7 +312,7 @@ def exportXml(fits, iportuser, callback):
|
||||
|
||||
for fighter in fit.fighters:
|
||||
hardware = doc.createElement("hardware")
|
||||
hardware.setAttribute("qty", "%d" % fighter.amountActive)
|
||||
hardware.setAttribute("qty", "%d" % fighter.amount)
|
||||
hardware.setAttribute("slot", "fighter bay")
|
||||
hardware.setAttribute("type", fighter.item.name)
|
||||
fitting.appendChild(hardware)
|
||||
|
||||
Reference in New Issue
Block a user