Skip to content

Commit

Permalink
Implement selectable booster side effects and persist them to the dat…
Browse files Browse the repository at this point in the history
…abase, 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)
  • Loading branch information
blitzmann committed Jun 5, 2017
1 parent cf02c74 commit c2cb5d7
Show file tree
Hide file tree
Showing 10 changed files with 214 additions and 72 deletions.
26 changes: 15 additions & 11 deletions eos/db/saveddata/booster.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@

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),
Expand All @@ -34,19 +36,21 @@
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)
73 changes: 14 additions & 59 deletions eos/saveddata/booster.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import eos.db
from eos.effectHandlerHelpers import HandledItem
from eos.modifiedAttributeDict import ModifiedAttributeDict, ItemAttrShortcut
from eos.saveddata.boosterSideEffect import BoosterSideEffect

pyfalog = Logger(__name__)

Expand All @@ -37,6 +38,9 @@ def __init__(self, item):

self.itemID = item.ID if item is not None else None
self.active = True

self.__sideEffects = self.__getSideEffects()

self.build()

@reconstructor
Expand All @@ -58,34 +62,23 @@ def init(self):

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__()
def getSideEffect(self, name):
for sideEffect in self.iterSideEffects():
if sideEffect.effect.name == name:
return sideEffect
@property
def sideEffects(self):
return self.__sideEffects or []

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):
Expand Down Expand Up @@ -161,41 +154,3 @@ def __deepcopy__(self, memo):
'''

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
'''
63 changes: 63 additions & 0 deletions eos/saveddata/boosterSideEffect.py
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.
# ===============================================================================

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')

1 change: 1 addition & 0 deletions gui/boosterView.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class BoosterView(d.Display):
"State",
"attr:boosterness",
"Base Name",
"Side Effects",
"Price",
]

Expand Down
64 changes: 64 additions & 0 deletions gui/builtinContextMenus/boosterSideEffects.py
Original file line number Diff line number Diff line change
@@ -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()
2 changes: 1 addition & 1 deletion gui/builtinViewColumns/__init__.py
Original file line number Diff line number Diff line change
@@ -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"]
46 changes: 46 additions & 0 deletions gui/builtinViewColumns/sideEffects.py
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.
# =============================================================================


# 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()
1 change: 1 addition & 0 deletions gui/contextMenu.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ def getBitmap(self, context, selection):
metaSwap,
implantSets,
fighterAbilities,
boosterSideEffects,
commandFits,
tabbedFits
)
3 changes: 2 additions & 1 deletion gui/viewColumn.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,6 @@ def delayedText(self, display, colItem):
misc,
price,
propertyDisplay,
state
state,
sideEffects
)
7 changes: 7 additions & 0 deletions service/fit.py
Original file line number Diff line number Diff line change
Expand Up @@ -991,6 +991,13 @@ def toggleFighterAbility(self, fitID, ability):
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:
Expand Down

0 comments on commit c2cb5d7

Please sign in to comment.