From 1fb99368939fc93a0aec431734db1f75d33d4a19 Mon Sep 17 00:00:00 2001 From: DarkPhoenix Date: Fri, 12 Apr 2019 17:55:56 +0300 Subject: [PATCH] Fix booster commands --- eos/effectHandlerHelpers.py | 38 ++++++--- gui/fitCommands/calc/fitAddBooster.py | 99 ++++++++++++++---------- gui/fitCommands/calc/fitRemoveBooster.py | 35 ++++----- gui/fitCommands/calc/fitRemoveModule.py | 10 +-- gui/fitCommands/guiAddBooster.py | 8 +- gui/fitCommands/guiMetaSwap.py | 11 +-- gui/fitCommands/helpers.py | 37 +++++++++ 7 files changed, 154 insertions(+), 84 deletions(-) diff --git a/eos/effectHandlerHelpers.py b/eos/effectHandlerHelpers.py index 3c1dfb611..0db2a8172 100644 --- a/eos/effectHandlerHelpers.py +++ b/eos/effectHandlerHelpers.py @@ -22,6 +22,7 @@ from logbook import Logger from eos.exception import HandledListActionError from utils.deprecated import deprecated + pyfalog = Logger(__name__) @@ -274,22 +275,41 @@ class HandledBoosterList(HandledList): self.remove(booster) raise HandledListActionError(booster) - self.makeRoom(booster) + if self.__slotCheck(booster): + HandledList.append(self, booster) + self.remove(booster) + raise HandledListActionError(booster) + + HandledList.append(self, booster) + + def insert(self, idx, booster): + if booster.isInvalid: + HandledList.insert(self, idx, booster) + self.remove(booster) + raise HandledListActionError(booster) + + if self.__slotCheck(booster): + HandledList.insert(self, idx, booster) + self.remove(booster) + raise HandledListActionError(booster) + HandledList.append(self, booster) def makeRoom(self, booster): # if needed, remove booster that was occupying slot oldObj = next((m for m in self if m.slot == booster.slot), None) - if oldObj: - pyfalog.info("Slot {0} occupied with {1}, replacing with {2}", booster.slot, oldObj.item.name, - booster.item.name) - itemID = oldObj.itemID - state = oldObj.active - sideEffects = {se.effectID: se.active for se in oldObj.sideEffects} + if oldObj is not None: + pyfalog.info("Slot {0} occupied with {1}, replacing with {2}", booster.slot, oldObj.item.name, booster.item.name) + position = self.index(oldObj) + from gui.fitCommands.helpers import BoosterInfo + boosterInfo = BoosterInfo.fromBooster(oldObj) oldObj.itemID = 0 # hack to remove from DB. See GH issue #324 self.remove(oldObj) - return itemID, state, sideEffects - return None, None, None + return position, boosterInfo + return None, None + + def __slotCheck(self, booster): + return any(b.slot == booster.slot for b in self) class HandledSsoCharacterList(list): diff --git a/gui/fitCommands/calc/fitAddBooster.py b/gui/fitCommands/calc/fitAddBooster.py index 11a53c1ef..800da9e96 100644 --- a/gui/fitCommands/calc/fitAddBooster.py +++ b/gui/fitCommands/calc/fitAddBooster.py @@ -1,60 +1,73 @@ import wx -import eos.db from logbook import Logger -from eos.saveddata.booster import Booster + +import eos.db +from eos.exception import HandledListActionError +from service.fit import Fit + + pyfalog = Logger(__name__) class FitAddBoosterCommand(wx.Command): - """" - from sFit.addBooster - """ - def __init__(self, fitID, itemID, state, sideEffects): - wx.Command.__init__(self, True) + + def __init__(self, fitID, newBoosterInfo, newPosition=None): + wx.Command.__init__(self, True, 'Add Booster') self.fitID = fitID - self.newItemID = itemID - self.newState = state - self.newSideEffects = sideEffects - self.newIndex = None - self.oldItemID = None - self.oldState = None - self.oldSideEffects = None + self.newBoosterInfo = newBoosterInfo + self.newPosition = newPosition + self.oldBoosterInfo = None + self.oldPosition = None def Do(self): - pyfalog.debug("Adding booster ({0}) to fit ID: {1}", self.newItemID, self.fitID) + pyfalog.debug('Doing addition of booster {} to fit {}'.format(self.newBoosterInfo, self.fitID)) + fit = Fit.getInstance().getFit(self.fitID) - fit = eos.db.getFit(self.fitID) - item = eos.db.getItem(self.newItemID, eager="attributes") - - if next((x for x in fit.boosters if x.itemID == self.newItemID), None): - return False # already have item in list of boosters - - try: - booster = Booster(item) - except ValueError: - pyfalog.warning("Invalid item: {0}", self.newItemID) + if any(self.newBoosterInfo.itemID == b.itemID for b in fit.boosters): + pyfalog.debug('Skipping as such booster is already on the fit') return False - if self.newState is not None: - booster.active = self.newState - if self.newSideEffects is not None: - for sideEffect in booster.sideEffects: - sideEffect.active = self.newSideEffects.get(sideEffect.effectID, False) + newBooster = self.newBoosterInfo.toBooster() + if newBooster is None: + return False + self.oldPosition, self.oldBoosterInfo = fit.boosters.makeRoom(newBooster) - self.oldItemID, self.oldState, self.oldSideEffects = fit.boosters.makeRoom(booster) - fit.boosters.append(booster) - self.newIndex = fit.boosters.index(booster) + if self.newPosition is not None: + try: + fit.boosters.insert(self.newPosition, newBooster) + except HandledListActionError: + pyfalog.warning('Failed to insert to list') + cmd = FitAddBoosterCommand( + fitID=self.fitID, + newBoosterInfo=self.oldBoosterInfo, + newPosition=self.oldPosition) + cmd.Do() + return False + else: + try: + fit.boosters.append(newBooster) + except HandledListActionError: + pyfalog.warning('Failed to append to list') + cmd = FitAddBoosterCommand( + fitID=self.fitID, + newBoosterInfo=self.oldBoosterInfo, + newPosition=self.oldPosition) + cmd.Do() + return False + self.newPosition = fit.boosters.index(newBooster) + + eos.db.commit() return True def Undo(self): - if self.oldItemID: - # If we had an item in the slot previously, add it back. - cmd = FitAddBoosterCommand(self.fitID, self.oldItemID, self.oldState, self.oldSideEffects) - cmd.Do() - return True - - from .fitRemoveBooster import FitRemoveBoosterCommand # Avoid circular import - cmd = FitRemoveBoosterCommand(self.fitID, self.newIndex) - cmd.Do() - return True + pyfalog.debug('Undo addition of booster {} to fit {}'.format(self.newBoosterInfo, self.fitID)) + if self.oldBoosterInfo and self.oldPosition: + cmd = FitAddBoosterCommand( + fitID=self.fitID, + newBoosterInfo=self.oldBoosterInfo, + newPosition=self.oldPosition) + return cmd.Do() + from .fitRemoveBooster import FitRemoveBoosterCommand + cmd = FitRemoveBoosterCommand(self.fitID, self.newPosition) + return cmd.Do() diff --git a/gui/fitCommands/calc/fitRemoveBooster.py b/gui/fitCommands/calc/fitRemoveBooster.py index 36a30638b..b2f4fc189 100644 --- a/gui/fitCommands/calc/fitRemoveBooster.py +++ b/gui/fitCommands/calc/fitRemoveBooster.py @@ -1,38 +1,37 @@ import wx -import eos.db from logbook import Logger + +import eos.db +from gui.fitCommands.helpers import BoosterInfo +from service.fit import Fit + + pyfalog = Logger(__name__) class FitRemoveBoosterCommand(wx.Command): - """" - from sFit.removeBooster - """ + def __init__(self, fitID, position): - wx.Command.__init__(self, True, "Implant remove") + wx.Command.__init__(self, True, 'Remove Booster') self.fitID = fitID self.position = position - self.savedItemID = None - self.savedState = None - self.savedSideEffects = None + self.savedBoosterInfo = None def Do(self): - pyfalog.debug("Removing booster from position ({0}) for fit ID: {1}", self.position, self.fitID) + pyfalog.debug('Doing removal of booster from position {} on fit {}'.format(self.position, self.fitID)) - fit = eos.db.getFit(self.fitID) + fit = Fit.getInstance().getFit(self.fitID) booster = fit.boosters[self.position] - self.savedItemID = booster.itemID - self.savedState = booster.active - self.savedSideEffects = {se.effectID: se.active for se in booster.sideEffects} + self.savedBoosterInfo = BoosterInfo.fromBooster(booster) fit.boosters.remove(booster) + eos.db.commit() return True def Undo(self): + pyfalog.debug('Undoing removal of booster {} on fit {}'.format(self.savedBoosterInfo, self.fitID)) from .fitAddBooster import FitAddBoosterCommand # Avoid circular import cmd = FitAddBoosterCommand( fitID=self.fitID, - itemID=self.savedItemID, - state=self.savedState, - sideEffects=self.savedSideEffects) - cmd.Do() - return True + newBoosterInfo=self.savedBoosterInfo, + newPosition=self.position) + return cmd.Do() diff --git a/gui/fitCommands/calc/fitRemoveModule.py b/gui/fitCommands/calc/fitRemoveModule.py index c386a3b76..960a7014e 100644 --- a/gui/fitCommands/calc/fitRemoveModule.py +++ b/gui/fitCommands/calc/fitRemoveModule.py @@ -15,7 +15,7 @@ class FitRemoveModuleCommand(wx.Command): wx.Command.__init__(self, True, 'Remove Module') self.fitID = fitID self.positions = positions - self.oldModInfos = {} + self.savedModInfos = {} def Do(self): pyfalog.debug('Doing removal of modules from positions {} on fit {}'.format(self.positions, self.fitID)) @@ -24,21 +24,21 @@ class FitRemoveModuleCommand(wx.Command): for position in self.positions: mod = fit.modules[position] if not mod.isEmpty: - self.oldModInfos[position] = ModuleInfo.fromModule(mod) + self.savedModInfos[position] = ModuleInfo.fromModule(mod) fit.modules.free(position) # If no modules were removed, report that command was not completed - if not len(self.oldModInfos) > 0: + if not len(self.savedModInfos) > 0: eos.db.commit() return False eos.db.commit() return True def Undo(self): - pyfalog.debug('Undoing removal of modules {} on fit {}'.format(self.oldModInfos, self.fitID)) + pyfalog.debug('Undoing removal of modules {} on fit {}'.format(self.savedModInfos, self.fitID)) results = [] from gui.fitCommands.calc.fitReplaceModule import FitReplaceModuleCommand - for position, modInfo in self.oldModInfos.items(): + for position, modInfo in self.savedModInfos.items(): cmd = FitReplaceModuleCommand(fitID=self.fitID, position=position, newModInfo=modInfo) results.append(cmd.Do()) return any(results) diff --git a/gui/fitCommands/guiAddBooster.py b/gui/fitCommands/guiAddBooster.py index f2acbbcbf..aa20c1c81 100644 --- a/gui/fitCommands/guiAddBooster.py +++ b/gui/fitCommands/guiAddBooster.py @@ -3,12 +3,14 @@ from service.fit import Fit import gui.mainFrame from gui import globalEvents as GE +from gui.fitCommands.helpers import BoosterInfo from .calc.fitAddBooster import FitAddBoosterCommand class GuiAddBoosterCommand(wx.Command): + def __init__(self, fitID, itemID): - wx.Command.__init__(self, True, "Booster Add") + wx.Command.__init__(self, True, 'Add Booster') self.mainFrame = gui.mainFrame.MainFrame.getInstance() self.sFit = Fit.getInstance() self.internal_history = wx.CommandProcessor() @@ -16,7 +18,9 @@ class GuiAddBoosterCommand(wx.Command): self.itemID = itemID def Do(self): - if self.internal_history.Submit(FitAddBoosterCommand(self.fitID, self.itemID, True, {})): + if self.internal_history.Submit(FitAddBoosterCommand( + fitID=self.fitID, + newBoosterInfo=BoosterInfo(itemID=self.itemID))): self.sFit.recalc(self.fitID) wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.fitID)) return True diff --git a/gui/fitCommands/guiMetaSwap.py b/gui/fitCommands/guiMetaSwap.py index fc587e669..a9a0c7fb7 100644 --- a/gui/fitCommands/guiMetaSwap.py +++ b/gui/fitCommands/guiMetaSwap.py @@ -3,10 +3,9 @@ from service.fit import Fit import gui.mainFrame from gui import globalEvents as GE -from gui.fitCommands.helpers import ModuleInfo +from gui.fitCommands.helpers import ModuleInfo, BoosterInfo from .calc.fitRemoveImplant import FitRemoveImplantCommand from .calc.fitAddImplant import FitAddImplantCommand -from .calc.fitRemoveBooster import FitRemoveBoosterCommand from .calc.fitAddBooster import FitAddBoosterCommand from .calc.fitRemoveCargo import FitRemoveCargoCommand from .calc.fitAddCargo import FitAddCargoCommand @@ -32,7 +31,7 @@ class GuiMetaSwapCommand(wx.Command): for x in selection: position = fit.modules.index(x) self.data.append(((FitReplaceModuleCommand, fitID, position, ModuleInfo( - itemID=itemID, chargeID=x.chargeID, state=x.state, spoolType=x.spoolType, spoolAmount=x.spoolAmount)),),) + itemID=itemID, chargeID=x.chargeID, state=x.state, spoolType=x.spoolType, spoolAmount=x.spoolAmount)),)) elif context == 'implantItem': for x in selection: idx = fit.implants.index(x) @@ -40,10 +39,8 @@ class GuiMetaSwapCommand(wx.Command): self.data.append(((FitRemoveImplantCommand, fitID, idx), (FitAddImplantCommand, fitID, itemID, state))) elif context == 'boosterItem': for x in selection: - idx = fit.boosters.index(x) - state = x.active - sideEffects = {se.effectID: se.active for se in x.sideEffects} - self.data.append(((FitRemoveBoosterCommand, fitID, idx), (FitAddBoosterCommand, fitID, itemID, state, sideEffects))) + self.data.append(((FitAddBoosterCommand, fitID, BoosterInfo( + itemID=itemID, state=x.active, sideEffects={se.effectID: se.active for se in x.sideEffects})),)) elif context == 'cargoItem': for x in selection: self.data.append(((FitRemoveCargoCommand, fitID, x.itemID, 1, True), (FitAddCargoCommand, fitID, itemID, x.amount))) diff --git a/gui/fitCommands/helpers.py b/gui/fitCommands/helpers.py index 9b0e690a2..99932180b 100644 --- a/gui/fitCommands/helpers.py +++ b/gui/fitCommands/helpers.py @@ -2,6 +2,7 @@ from logbook import Logger import eos.db from eos.const import FittingModuleState +from eos.saveddata.booster import Booster from eos.saveddata.module import Module from service.market import Market from utils.repr import makeReprStr @@ -85,6 +86,42 @@ class ModuleInfo: 'chargeID', 'state', 'spoolType', 'spoolAmount']) +class BoosterInfo: + + def __init__(self, itemID, state=None, sideEffects=None): + self.itemID = itemID + self.state = state + self.sideEffects = sideEffects + + @classmethod + def fromBooster(cls, booster): + if booster is None: + return None + info = cls( + itemID=booster.itemID, + state=booster.active, + sideEffects={se.effectID: se.active for se in booster.sideEffects}) + return info + + def toBooster(self): + item = Market.getInstance().getItem(self.itemID) + try: + booster = Booster(item) + except ValueError: + pyfalog.warning('Invalid item: {}'.format(self.itemID)) + return None + if self.state is not None: + booster.active = self.state + if self.sideEffects is not None: + for sideEffect in booster.sideEffects: + if sideEffect.effectID in self.sideEffects: + sideEffect.active = self.sideEffects[sideEffect.effectID] + return booster + + def __repr__(self): + return makeReprStr(self, ['itemID', 'state', 'sideEffects']) + + def stateLimit(itemIdentity): item = Market.getInstance().getItem(itemIdentity) if {'moduleBonusAssaultDamageControl', 'moduleBonusIndustrialInvulnerability'}.intersection(item.effects):