diff --git a/eos/config.py b/eos/config.py index 0ea812008..ce612880b 100644 --- a/eos/config.py +++ b/eos/config.py @@ -26,6 +26,7 @@ pyfalog.debug("Saveddata connection string: {0}", saveddata_connectionstring) settings = { "useStaticAdaptiveArmorHardener": False, "strictSkillLevels": True, + "globalDefaultSpoolupPercentage": 1.0 } # Autodetect path, only change if the autodetection bugs out. diff --git a/eos/effects/shipmoduleremotearmormutadaptiverepairer.py b/eos/effects/shipmoduleremotearmormutadaptiverepairer.py index ec98c1e23..29d52fb47 100644 --- a/eos/effects/shipmoduleremotearmormutadaptiverepairer.py +++ b/eos/effects/shipmoduleremotearmormutadaptiverepairer.py @@ -5,7 +5,7 @@ from eos.utils.spoolSupport import SpoolType, SpoolOptions, calculateSpoolup, resolveSpoolOptions - +import eos.config type = "projected", "active" runTime = "late" @@ -17,8 +17,7 @@ def handler(fit, container, context, **kwargs): cycleTime = container.getModifiedItemAttr("duration") / 1000.0 repSpoolMax = container.getModifiedItemAttr("repairMultiplierBonusMax") repSpoolPerCycle = container.getModifiedItemAttr("repairMultiplierBonusPerCycle") - # TODO: fetch spoolup option - defaultSpoolValue = 1 + defaultSpoolValue = eos.config.settings['globalDefaultSpoolupPercentage'] spoolType, spoolAmount = resolveSpoolOptions(SpoolOptions(SpoolType.SCALE, defaultSpoolValue, False), container) rps = repAmountBase * (1 + calculateSpoolup(repSpoolMax, repSpoolPerCycle, cycleTime, spoolType, spoolAmount)[0]) / cycleTime rpsPreSpool = repAmountBase * (1 + calculateSpoolup(repSpoolMax, repSpoolPerCycle, cycleTime, SpoolType.SCALE, 0)[0]) / cycleTime diff --git a/gui/builtinAdditionPanes/implantView.py b/gui/builtinAdditionPanes/implantView.py index 9b7f881f8..84c437ea3 100644 --- a/gui/builtinAdditionPanes/implantView.py +++ b/gui/builtinAdditionPanes/implantView.py @@ -204,7 +204,10 @@ class ImplantDisplay(d.Display): def removeImplant(self, implant): fitID = self.mainFrame.getActiveFit() - self.mainFrame.command.Submit(cmd.GuiRemoveImplantCommand(fitID, self.original.index(implant))) + sFit = Fit.getInstance() + fit = sFit.getFit(fitID) + if fit.implantLocation == ImplantLocation.FIT: + self.mainFrame.command.Submit(cmd.GuiRemoveImplantCommand(fitID, self.original.index(implant))) def click(self, event): event.Skip() diff --git a/gui/builtinContextMenus/spoolUp.py b/gui/builtinContextMenus/spoolUp.py new file mode 100644 index 000000000..a75568802 --- /dev/null +++ b/gui/builtinContextMenus/spoolUp.py @@ -0,0 +1,82 @@ +# noinspection PyPackageRequirements +import wx + +import eos.config +import gui.mainFrame +from eos.utils.spoolSupport import SpoolType, SpoolOptions +from gui import globalEvents as GE +from gui.contextMenu import ContextMenu +from service.settings import ContextMenuSettings +from service.fit import Fit + + +class SpoolUp(ContextMenu): + def __init__(self): + self.mainFrame = gui.mainFrame.MainFrame.getInstance() + self.settings = ContextMenuSettings.getInstance() + self.cycleMap = {} + self.resetId = None + + def display(self, srcContext, selection): + if not self.settings.get('spoolup'): + return False + + if srcContext not in ("fittingModule") or self.mainFrame.getActiveFit() is None: + return False + + self.mod = selection[0] + + return self.mod.item.group.name in ("Precursor Weapon", "Mutadaptive Remote Armor Repairer") + + def getText(self, itmContext, selection): + return "Spoolup Cycles" + + def getSubMenu(self, context, selection, rootMenu, i, pitem): + m = wx.Menu() + if "wxMSW" in wx.PlatformInfo: + bindmenu = rootMenu + else: + bindmenu = m + + isNotDefault = self.mod.spoolType is not None and self.mod.spoolAmount is not None + cycleDefault = self.mod.getSpoolData(spoolOptions=SpoolOptions(SpoolType.SCALE, eos.config.settings['globalDefaultSpoolupPercentage'], True))[0] + cycleCurrent = self.mod.getSpoolData(spoolOptions=SpoolOptions(SpoolType.SCALE, eos.config.settings['globalDefaultSpoolupPercentage'], False))[0] + cycleMin = self.mod.getSpoolData(spoolOptions=SpoolOptions(SpoolType.SCALE, 0, True))[0] + cycleMax = self.mod.getSpoolData(spoolOptions=SpoolOptions(SpoolType.SCALE, 1, True))[0] + + for cycle in range(cycleMin, cycleMax + 1): + menuId = ContextMenu.nextID() + + # Show default only for current value and when not overriden + if not isNotDefault and cycle == cycleDefault: + text = "{} (default)".format(cycle) + else: + text = "{}".format(cycle) + + item = wx.MenuItem(m, menuId, text, kind=wx.ITEM_CHECK) + bindmenu.Bind(wx.EVT_MENU, self.handleSpoolChange, item) + m.Append(item) + item.Check(isNotDefault and cycle == cycleCurrent) + self.cycleMap[menuId] = cycle + + self.resetId = ContextMenu.nextID() + item = wx.MenuItem(m, self.resetId, "Reset") + bindmenu.Bind(wx.EVT_MENU, self.handleSpoolChange, item) + m.Append(item) + + return m + + def handleSpoolChange(self, event): + if event.Id == self.resetId: + self.mod.spoolType = None + self.mod.spoolAmount = None + elif event.Id in self.cycleMap: + cycles = self.cycleMap[event.Id] + self.mod.spoolType = SpoolType.CYCLES + self.mod.spoolAmount = cycles + fitID = self.mainFrame.getActiveFit() + Fit.getInstance().recalc(fitID) + wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID)) + + +SpoolUp.register() diff --git a/gui/builtinPreferenceViews/pyfaContextMenuPreferences.py b/gui/builtinPreferenceViews/pyfaContextMenuPreferences.py index 7c767c5fb..6ff7c8210 100644 --- a/gui/builtinPreferenceViews/pyfaContextMenuPreferences.py +++ b/gui/builtinPreferenceViews/pyfaContextMenuPreferences.py @@ -36,7 +36,7 @@ class PFContextMenuPref(PreferenceView): self.rbBox1 = wx.RadioBox(panel, -1, "Set as Damage Pattern", wx.DefaultPosition, wx.DefaultSize, ['Disabled', 'Enabled'], 1, wx.RA_SPECIFY_COLS) self.rbBox1.SetSelection(self.settings.get('ammoPattern')) - rbSizerRow1.Add(self.rbBox1, 1, wx.TOP | wx.RIGHT, 5) + rbSizerRow1.Add(self.rbBox1, 1, wx.ALL, 5) self.rbBox1.Bind(wx.EVT_RADIOBOX, self.OnSetting1Change) self.rbBox2 = wx.RadioBox(panel, -1, "Change Skills", wx.DefaultPosition, wx.DefaultSize, ['Disabled', 'Enabled'], 1, wx.RA_SPECIFY_COLS) @@ -56,36 +56,39 @@ class PFContextMenuPref(PreferenceView): self.rbBox4 = wx.RadioBox(panel, -1, "Variations", wx.DefaultPosition, wx.DefaultSize, ['Disabled', 'Enabled'], 1, wx.RA_SPECIFY_COLS) self.rbBox4.SetSelection(self.settings.get('metaSwap')) - rbSizerRow2.Add(self.rbBox4, 1, wx.TOP | wx.RIGHT, 5) + rbSizerRow2.Add(self.rbBox4, 1, wx.ALL, 5) self.rbBox4.Bind(wx.EVT_RADIOBOX, self.OnSetting4Change) - ''' - self.rbBox5 = wx.RadioBox(panel, -1, "Charge", wx.DefaultPosition, wx.DefaultSize, ['Disabled', 'Enabled'], 1, wx.RA_SPECIFY_COLS) - self.rbBox5.SetSelection(self.settings.get('moduleAmmoPicker')) - rbSizerRow2.Add(self.rbBox5, 1, wx.ALL, 5) - self.rbBox5.Bind(wx.EVT_RADIOBOX, self.OnSetting5Change) - ''' + # self.rbBox5 = wx.RadioBox(panel, -1, "Charge", wx.DefaultPosition, wx.DefaultSize, ['Disabled', 'Enabled'], 1, wx.RA_SPECIFY_COLS) + # self.rbBox5.SetSelection(self.settings.get('moduleAmmoPicker')) + # rbSizerRow2.Add(self.rbBox5, 0, wx.ALL, 5) + # self.rbBox5.Bind(wx.EVT_RADIOBOX, self.OnSetting5Change) self.rbBox6 = wx.RadioBox(panel, -1, "Charge (All)", wx.DefaultPosition, wx.DefaultSize, ['Disabled', 'Enabled'], 1, wx.RA_SPECIFY_COLS) self.rbBox6.SetSelection(self.settings.get('moduleGlobalAmmoPicker')) rbSizerRow2.Add(self.rbBox6, 1, wx.ALL, 5) self.rbBox6.Bind(wx.EVT_RADIOBOX, self.OnSetting6Change) + self.rbBox7 = wx.RadioBox(panel, -1, "Project onto Fit", wx.DefaultPosition, wx.DefaultSize, ['Disabled', 'Enabled'], 1, wx.RA_SPECIFY_COLS) + self.rbBox7.SetSelection(self.settings.get('project')) + rbSizerRow2.Add(self.rbBox7, 1, wx.ALL, 5) + self.rbBox7.Bind(wx.EVT_RADIOBOX, self.OnSetting7Change) + mainSizer.Add(rbSizerRow2, 1, wx.ALL | wx.EXPAND, 0) # Row 3 rbSizerRow3 = wx.BoxSizer(wx.HORIZONTAL) - self.rbBox7 = wx.RadioBox(panel, -1, "Project onto Fit", wx.DefaultPosition, wx.DefaultSize, ['Disabled', 'Enabled'], 1, wx.RA_SPECIFY_COLS) - self.rbBox7.SetSelection(self.settings.get('project')) - rbSizerRow3.Add(self.rbBox7, 1, wx.TOP | wx.RIGHT, 5) - self.rbBox7.Bind(wx.EVT_RADIOBOX, self.OnSetting7Change) - self.rbBox8 = wx.RadioBox(panel, -1, "Fill with module", wx.DefaultPosition, wx.DefaultSize, ['Disabled', 'Enabled'], 1, wx.RA_SPECIFY_COLS) self.rbBox8.SetSelection(self.settings.get('moduleFill')) - rbSizerRow3.Add(self.rbBox8, 1, wx.TOP | wx.RIGHT, 5) + rbSizerRow3.Add(self.rbBox8, 1, wx.ALL, 5) self.rbBox8.Bind(wx.EVT_RADIOBOX, self.OnSetting8Change) + self.rbBox9 = wx.RadioBox(panel, -1, "Spoolup", wx.DefaultPosition, wx.DefaultSize, ['Disabled', 'Enabled'], 1, wx.RA_SPECIFY_COLS) + self.rbBox9.SetSelection(self.settings.get('spoolup')) + rbSizerRow3.Add(self.rbBox9, 1, wx.ALL, 5) + self.rbBox9.Bind(wx.EVT_RADIOBOX, self.OnSetting9Change) + mainSizer.Add(rbSizerRow3, 1, wx.ALL | wx.EXPAND, 0) panel.SetSizer(mainSizer) @@ -115,6 +118,9 @@ class PFContextMenuPref(PreferenceView): def OnSetting8Change(self, event): self.settings.set('moduleFill', event.GetInt()) + def OnSetting9Change(self, event): + self.settings.set('spoolup', event.GetInt()) + def getImage(self): return BitmapLoader.getBitmap("settings_menu", "gui") diff --git a/gui/builtinPreferenceViews/pyfaEnginePreferences.py b/gui/builtinPreferenceViews/pyfaEnginePreferences.py index c41921393..fe5bcc5cb 100644 --- a/gui/builtinPreferenceViews/pyfaEnginePreferences.py +++ b/gui/builtinPreferenceViews/pyfaEnginePreferences.py @@ -8,6 +8,7 @@ import gui.globalEvents as GE from gui.preferenceView import PreferenceView from service.settings import EOSSettings import gui.mainFrame +from wx.lib.intctrl import IntCtrl logger = logging.getLogger(__name__) @@ -61,6 +62,22 @@ class PFFittingEnginePref(PreferenceView): wx.DefaultPosition, wx.DefaultSize, 0) mainSizer.Add(self.cbUniversalAdaptiveArmorHardener, 0, wx.ALL | wx.EXPAND, 5) + + spoolup_sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.spool_up_label = wx.StaticText(panel, wx.ID_ANY, "Global Default Spoolup Percentage:", wx.DefaultPosition, wx.DefaultSize, 0) + self.spool_up_label.Wrap(-1) + self.spool_up_label.SetCursor(helpCursor) + self.spool_up_label.SetToolTip( + wx.ToolTip('The amount of spoolup to use by default on module which support it. Can be changed on a per-module basis')) + + spoolup_sizer.Add(self.spool_up_label, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) + + self.spoolup_value = IntCtrl(panel, min=0, max=100, limited=True) + spoolup_sizer.Add(self.spoolup_value , 0, wx.ALL, 5) + + mainSizer.Add(spoolup_sizer, 0, wx.ALL | wx.EXPAND, 0) + # Future code once new cap sim is implemented ''' self.cbGlobalForceReactivationTimer = wx.CheckBox( panel, wx.ID_ANY, u"Factor in reactivation timer", wx.DefaultPosition, wx.DefaultSize, 0 ) @@ -96,9 +113,15 @@ class PFFittingEnginePref(PreferenceView): self.cbUniversalAdaptiveArmorHardener.SetValue(self.engine_settings.get("useStaticAdaptiveArmorHardener")) self.cbUniversalAdaptiveArmorHardener.Bind(wx.EVT_CHECKBOX, self.OnCBUniversalAdaptiveArmorHardenerChange) + self.spoolup_value.SetValue(int(self.engine_settings.get("globalDefaultSpoolupPercentage") * 100)) + self.spoolup_value.Bind(wx.lib.intctrl.EVT_INT, self.OnSpoolupChange) + panel.SetSizer(mainSizer) panel.Layout() + def OnSpoolupChange(self, event): + self.engine_settings.set("globalDefaultSpoolupPercentage", self.spoolup_value.GetValue() / 100) + def OnCBGlobalForceReloadStateChange(self, event): self.sFit.serviceFittingOptions["useGlobalForceReload"] = self.cbGlobalForceReload.GetValue() fitID = self.mainFrame.getActiveFit() diff --git a/gui/builtinStatsViews/firepowerViewFull.py b/gui/builtinStatsViews/firepowerViewFull.py index 4c773c9f1..c678e0b61 100644 --- a/gui/builtinStatsViews/firepowerViewFull.py +++ b/gui/builtinStatsViews/firepowerViewFull.py @@ -25,7 +25,7 @@ from gui.bitmap_loader import BitmapLoader from gui.utils.numberFormatter import formatAmount, roundToPrec from eos.utils.spoolSupport import SpoolType, SpoolOptions from service.fit import Fit - +import eos.config class FirepowerViewFull(StatsView): name = "firepowerViewFull" @@ -157,8 +157,7 @@ class FirepowerViewFull(StatsView): formatAmount(preSpool, prec, lowest, highest), formatAmount(fullSpool, prec, lowest, highest)) - # TODO: fetch spoolup option - defaultSpoolValue = 1 + defaultSpoolValue = eos.config.settings['globalDefaultSpoolupPercentage'] stats = ( ( "labelFullDpsWeapon", diff --git a/gui/builtinStatsViews/outgoingViewFull.py b/gui/builtinStatsViews/outgoingViewFull.py index 3b6a6ce58..740042b8c 100644 --- a/gui/builtinStatsViews/outgoingViewFull.py +++ b/gui/builtinStatsViews/outgoingViewFull.py @@ -23,6 +23,7 @@ from gui.statsView import StatsView from gui.bitmap_loader import BitmapLoader from gui.utils.numberFormatter import formatAmount, roundToPrec from eos.utils.spoolSupport import SpoolType, SpoolOptions +import eos.config stats = [ @@ -101,8 +102,7 @@ class OutgoingViewFull(StatsView): formatAmount(preSpool, prec, lowest, highest), formatAmount(fullSpool, prec, lowest, highest)) - # TODO: fetch spoolup option - defaultSpoolValue = 1 + defaultSpoolValue = eos.config.settings['globalDefaultSpoolupPercentage'] counter = 0 for labelName, labelDesc, valueFormat, image, tooltip, val, preSpoolVal, fullSpoolVal, prec, lowest, highest in stats: label = getattr(self, labelName) diff --git a/gui/builtinStatsViews/outgoingViewMinimal.py b/gui/builtinStatsViews/outgoingViewMinimal.py index 055a65e9e..4ed86831f 100644 --- a/gui/builtinStatsViews/outgoingViewMinimal.py +++ b/gui/builtinStatsViews/outgoingViewMinimal.py @@ -22,6 +22,7 @@ import wx from gui.statsView import StatsView from gui.utils.numberFormatter import formatAmount, roundToPrec from eos.utils.spoolSupport import SpoolType, SpoolOptions +import eos.config stats = [ @@ -100,8 +101,7 @@ class OutgoingViewMinimal(StatsView): formatAmount(preSpool, prec, lowest, highest), formatAmount(fullSpool, prec, lowest, highest)) - # TODO: fetch spoolup option - defaultSpoolValue = 1 + defaultSpoolValue = eos.config.settings['globalDefaultSpoolupPercentage'] counter = 0 for labelName, labelDesc, valueFormat, image, tooltip, val, preSpoolVal, fullSpoolVal, prec, lowest, highest in stats: label = getattr(self, labelName) diff --git a/gui/builtinViewColumns/misc.py b/gui/builtinViewColumns/misc.py index e9bff3d56..24c5d7a55 100644 --- a/gui/builtinViewColumns/misc.py +++ b/gui/builtinViewColumns/misc.py @@ -28,6 +28,7 @@ from gui.bitmap_loader import BitmapLoader from gui.utils.numberFormatter import formatAmount from gui.utils.listFormatter import formatList from eos.utils.spoolSupport import SpoolType, SpoolOptions +import eos.config class Miscellanea(ViewColumn): @@ -117,8 +118,8 @@ class Miscellanea(ViewColumn): text = "{0}".format(formatAmount(trackingSpeed, 3, 0, 3)) tooltip = "tracking speed" info.append((text, tooltip)) - # TODO: fetch spoolup option - defaultSpoolValue = 1 + + defaultSpoolValue = eos.config.settings['globalDefaultSpoolupPercentage'] spoolTime = stuff.getSpoolData(spoolOptions=SpoolOptions(SpoolType.SCALE, defaultSpoolValue, False))[1] if spoolTime: text = "{0}s".format(formatAmount(spoolTime, 3, 0, 3)) @@ -339,8 +340,7 @@ class Miscellanea(ViewColumn): tooltip = "Armor repaired per second" return text, tooltip elif itemGroup == "Mutadaptive Remote Armor Repairer": - # TODO: fetch spoolup option - defaultSpoolValue = 1 + defaultSpoolValue = eos.config.settings['globalDefaultSpoolupPercentage'] spoolOptDefault = SpoolOptions(SpoolType.SCALE, defaultSpoolValue, False) spoolOptPre = SpoolOptions(SpoolType.SCALE, 0, True) spoolOptFull = SpoolOptions(SpoolType.SCALE, 1, True) diff --git a/gui/contextMenu.py b/gui/contextMenu.py index 7c1caf085..b479ab913 100644 --- a/gui/contextMenu.py +++ b/gui/contextMenu.py @@ -183,6 +183,7 @@ from gui.builtinContextMenus import ( # noqa: E402,F401 openFit, moduleGlobalAmmoPicker, moduleAmmoPicker, + spoolUp, itemStats, damagePattern, marketJump, diff --git a/gui/fitCommands/__init__.py b/gui/fitCommands/__init__.py index 42b718c5d..793431ab7 100644 --- a/gui/fitCommands/__init__.py +++ b/gui/fitCommands/__init__.py @@ -35,3 +35,4 @@ from .guiToggleDrone import GuiToggleDroneCommand from .guiFitRename import GuiFitRenameCommand from .guiChangeImplantLocation import GuiChangeImplantLocation from .guiImportMutatedModule import GuiImportMutatedModuleCommand +from .guiSetSpoolup import GuiSetSpoolup diff --git a/gui/fitCommands/calc/fitSetSpoolup.py b/gui/fitCommands/calc/fitSetSpoolup.py new file mode 100644 index 000000000..9274d94bc --- /dev/null +++ b/gui/fitCommands/calc/fitSetSpoolup.py @@ -0,0 +1,37 @@ +import wx +import eos.db +from logbook import Logger +from eos.saveddata.booster import Booster +pyfalog = Logger(__name__) + + +class FitSetSpoolupCommand(wx.Command): + def __init__(self, fitID, position, spoolType, spoolAmount): + wx.Command.__init__(self, True) + self.fitID = fitID + self.position = position + self.spoolType = spoolType + self.spoolAmount = spoolAmount + self.projected = False # todo: get this to work with projected modules? Is that a thing? + self.cache = None + + def Do(self): + return self.__set(self.spoolType, self.spoolAmount) + + def Undo(self): + if self.cache: + self.__set(*self.cache) + return True + + def __set(self, type, amount): + fit = eos.db.getFit(self.fitID) + source = fit.modules if not self.projected else fit.projectedModules + + mod = source[self.position] + self.cache = mod.spoolType, mod.spoolAmount + + mod.spoolType = type + mod.spoolAmount = amount + + eos.db.commit() + return True diff --git a/gui/fitCommands/guiSetSpoolup.py b/gui/fitCommands/guiSetSpoolup.py new file mode 100644 index 000000000..60f0c6f1e --- /dev/null +++ b/gui/fitCommands/guiSetSpoolup.py @@ -0,0 +1,32 @@ +import wx +from service.fit import Fit + +import gui.mainFrame +from gui import globalEvents as GE +from .calc.fitSetSpoolup import FitSetSpoolupCommand + + +class GuiSetSpoolup(wx.Command): + def __init__(self, fitID, module, spoolupType, spoolupAmount): + wx.Command.__init__(self, True, "Booster Add") + self.mainFrame = gui.mainFrame.MainFrame.getInstance() + self.sFit = Fit.getInstance() + self.internal_history = wx.CommandProcessor() + self.fitID = fitID + self.position = module.modPosition + self.spoolType = spoolupType + self.spoolupAmount = spoolupAmount + + def Do(self): + if self.internal_history.Submit(FitSetSpoolupCommand(self.fitID, self.position, self.spoolType, self.spoolupAmount)): + self.sFit.recalc(self.fitID) + wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.fitID)) + return True + return False + + def Undo(self): + for _ in self.internal_history.Commands: + self.internal_history.Undo() + self.sFit.recalc(self.fitID) + wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.fitID)) + return True diff --git a/service/settings.py b/service/settings.py index df5038d1f..b901b1d72 100644 --- a/service/settings.py +++ b/service/settings.py @@ -526,6 +526,7 @@ class ContextMenuSettings(object): "targetResists" : 1, "whProjector" : 1, "moduleFill" : 1, + "spoolup" : 1, } self.ContextMenuDefaultSettings = SettingsProvider.getInstance().getSettings("pyfaContextMenuSettings", ContextMenuDefaultSettings)