diff --git a/eos/db/saveddata/fighter.py b/eos/db/saveddata/fighter.py index bb1ed133f..0e24620b8 100644 --- a/eos/db/saveddata/fighter.py +++ b/eos/db/saveddata/fighter.py @@ -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", diff --git a/eos/effects.py b/eos/effects.py index 06e4988d7..8addc6f6c 100644 --- a/eos/effects.py +++ b/eos/effects.py @@ -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 diff --git a/eos/saveddata/fighter.py b/eos/saveddata/fighter.py index 876c631aa..c4562225f 100644 --- a/eos/saveddata/fighter.py +++ b/eos/saveddata/fighter.py @@ -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: diff --git a/eos/saveddata/fighterAbility.py b/eos/saveddata/fighterAbility.py index ea1a1e31a..a69daf6d3 100644 --- a/eos/saveddata/fighterAbility.py +++ b/eos/saveddata/fighterAbility.py @@ -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)), diff --git a/eos/saveddata/fit.py b/eos/saveddata/fit.py index beaf980de..c200dd52a 100644 --- a/eos/saveddata/fit.py +++ b/eos/saveddata/fit.py @@ -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 diff --git a/graphs/data/fitDamageStats/cache/projected.py b/graphs/data/fitDamageStats/cache/projected.py index dd073f7a2..f68f700c2 100644 --- a/graphs/data/fitDamageStats/cache/projected.py +++ b/graphs/data/fitDamageStats/cache/projected.py @@ -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', diff --git a/graphs/data/fitEwarStats/getter.py b/graphs/data/fitEwarStats/getter.py index e1fa37ba2..cbc820b86 100644 --- a/graphs/data/fitEwarStats/getter.py +++ b/graphs/data/fitEwarStats/getter.py @@ -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} diff --git a/gui/builtinContextMenus/itemAmountChange.py b/gui/builtinContextMenus/itemAmountChange.py index 1bff2d106..96bd58fbd 100644 --- a/gui/builtinContextMenus/itemAmountChange.py +++ b/gui/builtinContextMenus/itemAmountChange.py @@ -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 diff --git a/gui/builtinStatsViews/priceViewFull.py b/gui/builtinStatsViews/priceViewFull.py index da90945c9..2415f1ef4 100644 --- a/gui/builtinStatsViews/priceViewFull.py +++ b/gui/builtinStatsViews/priceViewFull.py @@ -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: diff --git a/gui/builtinStatsViews/priceViewMinimal.py b/gui/builtinStatsViews/priceViewMinimal.py index 3bab797c1..adaf6ad44 100644 --- a/gui/builtinStatsViews/priceViewMinimal.py +++ b/gui/builtinStatsViews/priceViewMinimal.py @@ -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: diff --git a/gui/builtinViewColumns/baseName.py b/gui/builtinViewColumns/baseName.py index 052660338..77b251aa7 100644 --- a/gui/builtinViewColumns/baseName.py +++ b/gui/builtinViewColumns/baseName.py @@ -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): diff --git a/gui/builtinViewColumns/price.py b/gui/builtinViewColumns/price.py index a17ee6c7e..6a79f0bd4 100644 --- a/gui/builtinViewColumns/price.py +++ b/gui/builtinViewColumns/price.py @@ -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("(!)") diff --git a/gui/fitCommands/calc/fighter/changeAmount.py b/gui/fitCommands/calc/fighter/changeAmount.py index 0d481f7d8..417d7fc97 100644 --- a/gui/fitCommands/calc/fighter/changeAmount.py +++ b/gui/fitCommands/calc/fighter/changeAmount.py @@ -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: diff --git a/service/port/dna.py b/service/port/dna.py index c67394210..8f568fe88 100644 --- a/service/port/dna.py +++ b/service/port/dna.py @@ -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 diff --git a/service/port/efs.py b/service/port/efs.py index 1ccbf21f7..9b1cfcf5f 100755 --- a/service/port/efs.py +++ b/service/port/efs.py @@ -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) diff --git a/service/port/eft.py b/service/port/eft.py index cc8beeebd..48fe75176 100644 --- a/service/port/eft.py +++ b/service/port/eft.py @@ -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: diff --git a/service/port/esi.py b/service/port/esi.py index ed81fc210..7b1e35954 100644 --- a/service/port/esi.py +++ b/service/port/esi.py @@ -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) diff --git a/service/port/multibuy.py b/service/port/multibuy.py index 2dfe7eff8..f539cb748 100644 --- a/service/port/multibuy.py +++ b/service/port/multibuy.py @@ -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: diff --git a/service/port/xml.py b/service/port/xml.py index 40a4ef26b..5f105a718 100644 --- a/service/port/xml.py +++ b/service/port/xml.py @@ -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)