From c2cb5d763f78604bc88cb0b3499e6ac4ba719450 Mon Sep 17 00:00:00 2001 From: blitzmann Date: Sun, 4 Jun 2017 23:31:52 -0400 Subject: [PATCH 1/2] Implement selectable booster side effects and persist them to the database, very much based on the fighter ability code. Still need to name them and enable the effects. This also removes the old boosterActiveSideEffect table definition (migration script to drop table still needs to be written) --- eos/db/saveddata/booster.py | 28 ++++--- eos/saveddata/booster.py | 73 ++++--------------- eos/saveddata/boosterSideEffect.py | 63 ++++++++++++++++ gui/boosterView.py | 1 + gui/builtinContextMenus/boosterSideEffects.py | 64 ++++++++++++++++ gui/builtinViewColumns/__init__.py | 2 +- gui/builtinViewColumns/sideEffects.py | 46 ++++++++++++ gui/contextMenu.py | 1 + gui/viewColumn.py | 3 +- service/fit.py | 7 ++ 10 files changed, 215 insertions(+), 73 deletions(-) create mode 100644 eos/saveddata/boosterSideEffect.py create mode 100644 gui/builtinContextMenus/boosterSideEffects.py create mode 100644 gui/builtinViewColumns/sideEffects.py diff --git a/eos/db/saveddata/booster.py b/eos/db/saveddata/booster.py index e40762cd9..fa29c70b2 100644 --- a/eos/db/saveddata/booster.py +++ b/eos/db/saveddata/booster.py @@ -24,6 +24,8 @@ import datetime from eos.db import saveddata_meta from eos.saveddata.booster import Booster +from eos.saveddata.boosterSideEffect import BoosterSideEffect +from eos.saveddata.fit import Fit boosters_table = Table("boosters", saveddata_meta, Column("ID", Integer, primary_key=True), @@ -34,19 +36,21 @@ boosters_table = Table("boosters", saveddata_meta, Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now), ) -# Legacy booster side effect code, should disable but a mapper relies on it. -activeSideEffects_table = Table("boostersActiveSideEffects", saveddata_meta, - Column("boosterID", ForeignKey("boosters.ID"), primary_key=True), - Column("effectID", Integer, primary_key=True)) + +booster_side_effect_table = Table("boosterSideEffects", saveddata_meta, + Column("boosterID", Integer, ForeignKey("boosters.ID"), primary_key=True, index=True), + Column("effectID", Integer, nullable=False, primary_key=True), + Column("active", Boolean, default=False)) -class ActiveSideEffectsDummy(object): - def __init__(self, effectID): - self.effectID = effectID - - -mapper(ActiveSideEffectsDummy, activeSideEffects_table) mapper(Booster, boosters_table, - properties={"_Booster__activeSideEffectDummies": relation(ActiveSideEffectsDummy)}) + properties={ + "_Booster__sideEffects": relation( + BoosterSideEffect, + backref="booster", + cascade='all, delete, delete-orphan'), + } +) -Booster._Booster__activeSideEffectIDs = association_proxy("_Booster__activeSideEffectDummies", "effectID") + +mapper(BoosterSideEffect, booster_side_effect_table) diff --git a/eos/saveddata/booster.py b/eos/saveddata/booster.py index 62eb4d88f..aa5d6bfcb 100644 --- a/eos/saveddata/booster.py +++ b/eos/saveddata/booster.py @@ -24,6 +24,7 @@ from sqlalchemy.orm import reconstructor, validates import eos.db from eos.effectHandlerHelpers import HandledItem from eos.modifiedAttributeDict import ModifiedAttributeDict, ItemAttrShortcut +from eos.saveddata.boosterSideEffect import BoosterSideEffect pyfalog = Logger(__name__) @@ -37,6 +38,9 @@ class Booster(HandledItem, ItemAttrShortcut): self.itemID = item.ID if item is not None else None self.active = True + + self.__sideEffects = self.__getSideEffects() + self.build() @reconstructor @@ -58,34 +62,23 @@ class Booster(HandledItem, ItemAttrShortcut): def build(self): """ Build object. Assumes proper and valid item already set """ - self.__sideEffects = [] self.__itemModifiedAttributes = ModifiedAttributeDict() self.__itemModifiedAttributes.original = self.__item.attributes self.__itemModifiedAttributes.overrides = self.__item.overrides self.__slot = self.__calculateSlot(self.__item) - # Legacy booster side effect code, disabling as not currently implemented - ''' - for effect in self.__item.effects.itervalues(): - if effect.isType("boosterSideEffect"): - s = SideEffect(self) - s.effect = effect - s.active = effect.ID in self.__activeSideEffectIDs - self.__sideEffects.append(s) - ''' + if len(self.sideEffects) != len(self.__getSideEffects()): + self.__sideEffects = [] + for ability in self.__getSideEffects(): + self.__sideEffects.append(ability) - # Legacy booster side effect code, disabling as not currently implemented - ''' - def iterSideEffects(self): - return self.__sideEffects.__iter__() + @property + def sideEffects(self): + return self.__sideEffects or [] - def getSideEffect(self, name): - for sideEffect in self.iterSideEffects(): - if sideEffect.effect.name == name: - return sideEffect - - raise KeyError("SideEffect with %s as name not found" % name) - ''' + def __getSideEffects(self): + """Returns list of BoosterSideEffect that are loaded with data""" + return [BoosterSideEffect(effect) for effect in self.item.effects.values() if effect.type and 'boosterSideEffect' in effect.type] @property def itemModifiedAttributes(self): @@ -161,41 +154,3 @@ class Booster(HandledItem, ItemAttrShortcut): ''' return copy - - -# Legacy booster side effect code, disabling as not currently implemented -''' - class SideEffect(object): - def __init__(self, owner): - self.__owner = owner - self.__active = False - self.__effect = None - - @property - def active(self): - return self.__active - - @active.setter - def active(self, active): - if not isinstance(active, bool): - raise TypeError("Expecting a bool, not a " + type(active)) - - if active != self.__active: - if active: - self.__owner._Booster__activeSideEffectIDs.append(self.effect.ID) - else: - self.__owner._Booster__activeSideEffectIDs.remove(self.effect.ID) - - self.__active = active - - @property - def effect(self): - return self.__effect - - @effect.setter - def effect(self, effect): - if not hasattr(effect, "handler"): - raise TypeError("Need an effect with a handler") - - self.__effect = effect -''' diff --git a/eos/saveddata/boosterSideEffect.py b/eos/saveddata/boosterSideEffect.py new file mode 100644 index 000000000..71014c3a7 --- /dev/null +++ b/eos/saveddata/boosterSideEffect.py @@ -0,0 +1,63 @@ +# =============================================================================== +# 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 . +# =============================================================================== + +from logbook import Logger + +from sqlalchemy.orm import reconstructor + +pyfalog = Logger(__name__) + + +class BoosterSideEffect(object): + + def __init__(self, effect): + """Initialize from the program""" + self.__effect = effect + self.effectID = effect.ID if effect is not None else None + self.active = False + self.build() + + @reconstructor + def init(self): + """Initialize from the database""" + self.__effect = None + + if self.effectID: + self.__effect = next((x for x in self.booster.item.effects.itervalues() if x.ID == self.effectID), None) + if self.__effect is None: + pyfalog.error("Effect (id: {0}) does not exist", self.effectID) + return + + self.build() + + def build(self): + pass + + @property + def effect(self): + return self.__effect + + @property + def name(self): + return self.__effect.getattr('displayName') or self.__effect.handlerName + + @property + def attrPrefix(self): + return self.__effect.getattr('prefix') + diff --git a/gui/boosterView.py b/gui/boosterView.py index 5f43aca04..549c5fd4c 100644 --- a/gui/boosterView.py +++ b/gui/boosterView.py @@ -49,6 +49,7 @@ class BoosterView(d.Display): "State", "attr:boosterness", "Base Name", + "Side Effects", "Price", ] diff --git a/gui/builtinContextMenus/boosterSideEffects.py b/gui/builtinContextMenus/boosterSideEffects.py new file mode 100644 index 000000000..68cfed1b2 --- /dev/null +++ b/gui/builtinContextMenus/boosterSideEffects.py @@ -0,0 +1,64 @@ +# noinspection PyPackageRequirements +import wx +from gui.contextMenu import ContextMenu +import gui.mainFrame +import gui.globalEvents as GE +from service.fit import Fit +from service.settings import ContextMenuSettings + + +class BoosterSideEffect(ContextMenu): + def __init__(self): + self.mainFrame = gui.mainFrame.MainFrame.getInstance() + self.settings = ContextMenuSettings.getInstance() + + def display(self, srcContext, selection): + # if not self.settings.get('fighterAbilities'): + # return False + + if self.mainFrame.getActiveFit() is None or srcContext not in ("boosterItem"): + return False + + self.booster = selection[0] + return True + + def getText(self, itmContext, selection): + return "Side Effects" + + def addEffect(self, menu, ability): + label = ability.name + id = ContextMenu.nextID() + self.effectIds[id] = ability + menuItem = wx.MenuItem(menu, id, label, kind=wx.ITEM_CHECK) + menu.Bind(wx.EVT_MENU, self.handleMode, menuItem) + return menuItem + + def getSubMenu(self, context, selection, rootMenu, i, pitem): + msw = True if "wxMSW" in wx.PlatformInfo else False + self.context = context + self.effectIds = {} + + sub = wx.Menu() + + for effect in self.booster.sideEffects: + if not effect.effect.isImplemented: + continue + menuItem = self.addEffect(rootMenu if msw else sub, effect) + sub.AppendItem(menuItem) + menuItem.Check(effect.active) + + return sub + + def handleMode(self, event): + effect = self.effectIds[event.Id] + if effect is False or effect not in self.booster.sideEffects: + event.Skip() + return + + sFit = Fit.getInstance() + fitID = self.mainFrame.getActiveFit() + sFit.toggleBoosterSideEffect(fitID, effect) + wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID)) + + +BoosterSideEffect.register() diff --git a/gui/builtinViewColumns/__init__.py b/gui/builtinViewColumns/__init__.py index cff8bc614..2a089e176 100644 --- a/gui/builtinViewColumns/__init__.py +++ b/gui/builtinViewColumns/__init__.py @@ -1,2 +1,2 @@ __all__ = ["ammo", "ammoIcon", "attributeDisplay", "baseIcon", "baseName", - "capacitorUse", "maxRange", "price", "propertyDisplay", "state", "misc", "abilities"] + "capacitorUse", "maxRange", "price", "propertyDisplay", "state", "misc", "abilities", "sideEffects"] diff --git a/gui/builtinViewColumns/sideEffects.py b/gui/builtinViewColumns/sideEffects.py new file mode 100644 index 000000000..25adb3769 --- /dev/null +++ b/gui/builtinViewColumns/sideEffects.py @@ -0,0 +1,46 @@ +# ============================================================================= +# 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 . +# ============================================================================= + + +# noinspection PyPackageRequirements +import wx +from eos.saveddata.booster import Booster +from gui.viewColumn import ViewColumn +import gui.mainFrame + + +class SideEffects(ViewColumn): + name = "Side Effects" + + def __init__(self, fittingView, params): + ViewColumn.__init__(self, fittingView) + + self.mainFrame = gui.mainFrame.MainFrame.getInstance() + self.columnText = "Active Side Effects" + self.mask = wx.LIST_MASK_TEXT + + def getText(self, stuff): + if isinstance(stuff, Booster): + active = [x.name for x in stuff.sideEffects if x.active] + if len(active) == 0: + return "None" + return ", ".join(active) + + +SideEffects.register() diff --git a/gui/contextMenu.py b/gui/contextMenu.py index b56661217..043140db3 100644 --- a/gui/contextMenu.py +++ b/gui/contextMenu.py @@ -206,6 +206,7 @@ from gui.builtinContextMenus import ( # noqa: E402,F401 metaSwap, implantSets, fighterAbilities, + boosterSideEffects, commandFits, tabbedFits ) diff --git a/gui/viewColumn.py b/gui/viewColumn.py index 34c3c89ce..08f9ca2bb 100644 --- a/gui/viewColumn.py +++ b/gui/viewColumn.py @@ -79,5 +79,6 @@ from gui.builtinViewColumns import ( # noqa: E402, F401 misc, price, propertyDisplay, - state + state, + sideEffects ) diff --git a/service/fit.py b/service/fit.py index 896ca689d..da1b2fe0f 100644 --- a/service/fit.py +++ b/service/fit.py @@ -991,6 +991,13 @@ class Fit(object): eos.db.commit() self.recalc(fit) + def toggleBoosterSideEffect(self, fitID, sideEffect): + pyfalog.debug("Toggling booster side effect for fit ID: {0}", fitID) + fit = eos.db.getFit(fitID) + sideEffect.active = not sideEffect.active + eos.db.commit() + self.recalc(fit) + def changeChar(self, fitID, charID): pyfalog.debug("Changing character ({0}) for fit ID: {1}", charID, fitID) if fitID is None or charID is None: From 47fcbefe8bee2af94950ffb8767b6d97903bb248 Mon Sep 17 00:00:00 2001 From: blitzmann Date: Mon, 5 Jun 2017 00:16:32 -0400 Subject: [PATCH 2/2] Finish off user-selectable booster side effects - effects are applied correctly now and each has their own display name. Implements #642 --- eos/effects/boosterarmorhppenalty.py | 8 ++++++-- .../boosterarmorrepairamountpenalty.py | 8 ++++++-- .../boostercapacitorcapacitypenalty.py | 8 ++++++-- eos/effects/boostermaxvelocitypenalty.py | 8 ++++++-- ...oostermissileexplosioncloudpenaltyfixed.py | 8 ++++++-- .../boostermissileexplosionvelocitypenalty.py | 8 ++++++-- eos/effects/boostermissilevelocitypenalty.py | 8 ++++++-- eos/effects/boostershieldcapacitypenalty.py | 8 ++++++-- eos/effects/boosterturretfalloffpenalty.py | 8 ++++++-- .../boosterturretoptimalrangepenalty.py | 8 ++++++-- eos/effects/boosterturrettrackingpenalty.py | 8 ++++++-- eos/saveddata/booster.py | 19 +++++++++---------- eos/saveddata/boosterSideEffect.py | 9 ++++++--- 13 files changed, 81 insertions(+), 35 deletions(-) diff --git a/eos/effects/boosterarmorhppenalty.py b/eos/effects/boosterarmorhppenalty.py index c2db78c40..8acfcf6ad 100644 --- a/eos/effects/boosterarmorhppenalty.py +++ b/eos/effects/boosterarmorhppenalty.py @@ -3,8 +3,12 @@ # Used by: # Implants from group: Booster (12 of 48) type = "boosterSideEffect" -activeByDefault = False +# User-friendly name for the side effect +displayName = "Armor Capacity" + +# Attribute that this effect targets +attr = "boosterArmorHPPenalty" def handler(fit, booster, context): - fit.ship.boostItemAttr("armorHP", booster.getModifiedItemAttr("boosterArmorHPPenalty")) + fit.ship.boostItemAttr("armorHP", booster.getModifiedItemAttr(attr)) diff --git a/eos/effects/boosterarmorrepairamountpenalty.py b/eos/effects/boosterarmorrepairamountpenalty.py index ac06a9c22..5f556908b 100644 --- a/eos/effects/boosterarmorrepairamountpenalty.py +++ b/eos/effects/boosterarmorrepairamountpenalty.py @@ -5,9 +5,13 @@ # Implants named like: Mindflood Booster (3 of 4) # Implants named like: Sooth Sayer Booster (3 of 4) type = "boosterSideEffect" -activeByDefault = False +# User-friendly name for the side effect +displayName = "Armor Repair Amount" + +# Attribute that this effect targets +attr = "boosterArmorRepairAmountPenalty" def handler(fit, booster, context): fit.modules.filteredItemBoost(lambda mod: mod.item.group.name == "Armor Repair Unit", - "armorDamageAmount", booster.getModifiedItemAttr("boosterArmorRepairAmountPenalty")) + "armorDamageAmount", booster.getModifiedItemAttr(attr)) diff --git a/eos/effects/boostercapacitorcapacitypenalty.py b/eos/effects/boostercapacitorcapacitypenalty.py index 3a8351ac4..087b591f5 100644 --- a/eos/effects/boostercapacitorcapacitypenalty.py +++ b/eos/effects/boostercapacitorcapacitypenalty.py @@ -4,8 +4,12 @@ # Implants named like: Blue Pill Booster (3 of 5) # Implants named like: Exile Booster (3 of 4) type = "boosterSideEffect" -activeByDefault = False +# User-friendly name for the side effect +displayName = "Cap Capacity" + +# Attribute that this effect targets +attr = "boosterCapacitorCapacityPenalty" def handler(fit, booster, context): - fit.ship.boostItemAttr("capacitorCapacity", booster.getModifiedItemAttr("boosterCapacitorCapacityPenalty")) + fit.ship.boostItemAttr("capacitorCapacity", booster.getModifiedItemAttr(attr)) diff --git a/eos/effects/boostermaxvelocitypenalty.py b/eos/effects/boostermaxvelocitypenalty.py index 0bc951e9e..9059fe0f4 100644 --- a/eos/effects/boostermaxvelocitypenalty.py +++ b/eos/effects/boostermaxvelocitypenalty.py @@ -3,8 +3,12 @@ # Used by: # Implants from group: Booster (12 of 48) type = "boosterSideEffect" -activeByDefault = False +# User-friendly name for the side effect +displayName = "Velocity" + +# Attribute that this effect targets +attr = "boosterMaxVelocityPenalty" def handler(fit, booster, context): - fit.ship.boostItemAttr("maxVelocity", booster.getModifiedItemAttr("boosterMaxVelocityPenalty")) + fit.ship.boostItemAttr("maxVelocity", booster.getModifiedItemAttr(attr)) diff --git a/eos/effects/boostermissileexplosioncloudpenaltyfixed.py b/eos/effects/boostermissileexplosioncloudpenaltyfixed.py index 778e4b28c..270f53fc3 100644 --- a/eos/effects/boostermissileexplosioncloudpenaltyfixed.py +++ b/eos/effects/boostermissileexplosioncloudpenaltyfixed.py @@ -4,9 +4,13 @@ # Implants named like: Exile Booster (3 of 4) # Implants named like: Mindflood Booster (3 of 4) type = "boosterSideEffect" -activeByDefault = False +# User-friendly name for the side effect +displayName = "Missile Explosion Radius" + +# Attribute that this effect targets +attr = "boosterMissileAOECloudPenalty" def handler(fit, booster, context): fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"), - "aoeCloudSize", booster.getModifiedItemAttr("boosterMissileAOECloudPenalty")) + "aoeCloudSize", booster.getModifiedItemAttr(attr)) diff --git a/eos/effects/boostermissileexplosionvelocitypenalty.py b/eos/effects/boostermissileexplosionvelocitypenalty.py index e81a9fc96..e9857e13c 100644 --- a/eos/effects/boostermissileexplosionvelocitypenalty.py +++ b/eos/effects/boostermissileexplosionvelocitypenalty.py @@ -3,9 +3,13 @@ # Used by: # Implants named like: Blue Pill Booster (3 of 5) type = "boosterSideEffect" -activeByDefault = False +# User-friendly name for the side effect +displayName = "Missile Explosion Velocity" + +# Attribute that this effect targets +attr = "boosterAOEVelocityPenalty" def handler(fit, booster, context): fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"), - "aoeVelocity", booster.getModifiedItemAttr("boosterAOEVelocityPenalty")) + "aoeVelocity", booster.getModifiedItemAttr(attr)) diff --git a/eos/effects/boostermissilevelocitypenalty.py b/eos/effects/boostermissilevelocitypenalty.py index a4f2d1205..5ffe02dd8 100644 --- a/eos/effects/boostermissilevelocitypenalty.py +++ b/eos/effects/boostermissilevelocitypenalty.py @@ -4,9 +4,13 @@ # Implants named like: Crash Booster (3 of 4) # Implants named like: X Instinct Booster (3 of 4) type = "boosterSideEffect" -activeByDefault = False +# User-friendly name for the side effect +displayName = "Missile Velocity" + +# Attribute that this effect targets +attr = "boosterMissileVelocityPenalty" def handler(fit, booster, context): fit.modules.filteredChargeBoost(lambda mod: mod.charge.requiresSkill("Missile Launcher Operation"), - "maxVelocity", "boosterMissileVelocityPenalty") + "maxVelocity", attr) diff --git a/eos/effects/boostershieldcapacitypenalty.py b/eos/effects/boostershieldcapacitypenalty.py index b2c5ed801..8cf5d85c3 100644 --- a/eos/effects/boostershieldcapacitypenalty.py +++ b/eos/effects/boostershieldcapacitypenalty.py @@ -3,8 +3,12 @@ # Used by: # Implants from group: Booster (12 of 48) type = "boosterSideEffect" -activeByDefault = False +# User-friendly name for the side effect +displayName = "Shield Capacity" + +# Attribute that this effect targets +attr = "boosterShieldCapacityPenalty" def handler(fit, booster, context): - fit.ship.boostItemAttr("shieldCapacity", booster.getModifiedItemAttr("boosterShieldCapacityPenalty")) + fit.ship.boostItemAttr("shieldCapacity", booster.getModifiedItemAttr(attr)) diff --git a/eos/effects/boosterturretfalloffpenalty.py b/eos/effects/boosterturretfalloffpenalty.py index 84f2e2145..f79674987 100644 --- a/eos/effects/boosterturretfalloffpenalty.py +++ b/eos/effects/boosterturretfalloffpenalty.py @@ -4,9 +4,13 @@ # Implants named like: Drop Booster (3 of 4) # Implants named like: X Instinct Booster (3 of 4) type = "boosterSideEffect" -activeByDefault = False +# User-friendly name for the side effect +displayName = "Turret Falloff" + +# Attribute that this effect targets +attr = "boosterTurretFalloffPenalty" def handler(fit, booster, context): fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Gunnery"), - "falloff", booster.getModifiedItemAttr("boosterTurretFalloffPenalty")) + "falloff", booster.getModifiedItemAttr(attr)) diff --git a/eos/effects/boosterturretoptimalrangepenalty.py b/eos/effects/boosterturretoptimalrangepenalty.py index d70275c29..e4f9d7e4c 100644 --- a/eos/effects/boosterturretoptimalrangepenalty.py +++ b/eos/effects/boosterturretoptimalrangepenalty.py @@ -5,9 +5,13 @@ # Implants named like: Mindflood Booster (3 of 4) # Implants named like: Sooth Sayer Booster (3 of 4) type = "boosterSideEffect" -activeByDefault = False +# User-friendly name for the side effect +displayName = "Turret Optimal Range" + +# Attribute that this effect targets +attr = "boosterTurretOptimalRange" def handler(fit, booster, context): fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Gunnery"), - "maxRange", booster.getModifiedItemAttr("boosterTurretOptimalRange")) + "maxRange", booster.getModifiedItemAttr(attr)) diff --git a/eos/effects/boosterturrettrackingpenalty.py b/eos/effects/boosterturrettrackingpenalty.py index 6f268fdc4..0e6025b66 100644 --- a/eos/effects/boosterturrettrackingpenalty.py +++ b/eos/effects/boosterturrettrackingpenalty.py @@ -4,9 +4,13 @@ # Implants named like: Exile Booster (3 of 4) # Implants named like: Frentix Booster (3 of 4) type = "boosterSideEffect" -activeByDefault = False +# User-friendly name for the side effect +displayName = "Turret Tracking" + +# Attribute that this effect targets +attr = "boosterTurretTrackingPenalty" def handler(fit, booster, context): fit.modules.filteredItemBoost(lambda mod: mod.item.requiresSkill("Gunnery"), - "trackingSpeed", booster.getModifiedItemAttr("boosterTurretTrackingPenalty")) + "trackingSpeed", booster.getModifiedItemAttr(attr)) diff --git a/eos/saveddata/booster.py b/eos/saveddata/booster.py index aa5d6bfcb..413661e86 100644 --- a/eos/saveddata/booster.py +++ b/eos/saveddata/booster.py @@ -76,9 +76,13 @@ class Booster(HandledItem, ItemAttrShortcut): def sideEffects(self): return self.__sideEffects or [] + @property + def activeSideEffectEffects(self): + return [x.effect for x in self.sideEffects if x.active] + def __getSideEffects(self): """Returns list of BoosterSideEffect that are loaded with data""" - return [BoosterSideEffect(effect) for effect in self.item.effects.values() if effect.type and 'boosterSideEffect' in effect.type] + return [BoosterSideEffect(effect) for effect in self.item.effects.values() if effect.isType("boosterSideEffect")] @property def itemModifiedAttributes(self): @@ -111,19 +115,14 @@ class Booster(HandledItem, ItemAttrShortcut): return if not self.active: return + for effect in self.item.effects.itervalues(): if effect.runTime == runTime and \ - (effect.isType("passive") or effect.isType("boosterSideEffect")) and \ - effect.activeByDefault: + (effect.isType("passive") or effect.isType("boosterSideEffect")): + if effect.isType("boosterSideEffect") and effect not in self.activeSideEffectEffects: + continue effect.handler(fit, self, ("booster",)) - # Legacy booster code, not fully implemented - ''' - for sideEffect in self.iterSideEffects(): - if sideEffect.active and sideEffect.effect.runTime == runTime: - sideEffect.effect.handler(fit, self, ("boosterSideEffect",)) - ''' - @validates("ID", "itemID", "ammoID", "active") def validator(self, key, val): map = { diff --git a/eos/saveddata/boosterSideEffect.py b/eos/saveddata/boosterSideEffect.py index 71014c3a7..6f08c0904 100644 --- a/eos/saveddata/boosterSideEffect.py +++ b/eos/saveddata/boosterSideEffect.py @@ -55,9 +55,12 @@ class BoosterSideEffect(object): @property def name(self): - return self.__effect.getattr('displayName') or self.__effect.handlerName + return "{0}% {1}".format( + self.booster.getModifiedItemAttr(self.attr), + self.__effect.getattr('displayName') or self.__effect.handlerName, + ) @property - def attrPrefix(self): - return self.__effect.getattr('prefix') + def attr(self): + return self.__effect.getattr('attr')