Add ability to change projection range of fits
This commit is contained in:
@@ -84,6 +84,7 @@ commandFits_table = Table("commandFits", saveddata_meta,
|
||||
|
||||
|
||||
class ProjectedFit:
|
||||
|
||||
def __init__(self, sourceID, source_fit, amount=1, active=True):
|
||||
self.sourceID = sourceID
|
||||
self.source_fit = source_fit
|
||||
|
||||
@@ -204,7 +204,7 @@ class Effect39(BaseEffect):
|
||||
|
||||
@staticmethod
|
||||
def handler(fit, module, context, projectionRange, **kwargs):
|
||||
if 'projected' in context and module.maxRange >= (projectionRange or 0):
|
||||
if 'projected' in context and module.getModifiedItemAttr('maxRange', 0) >= (projectionRange or 0):
|
||||
fit.ship.increaseItemAttr('warpScrambleStatus', module.getModifiedItemAttr('warpScrambleStrength'), **kwargs)
|
||||
|
||||
|
||||
@@ -23368,7 +23368,8 @@ class Effect5934(BaseEffect):
|
||||
def handler(fit, module, context, projectionRange, **kwargs):
|
||||
if 'projected' not in context:
|
||||
return
|
||||
|
||||
if module.getModifiedItemAttr('maxRange', 0) < (projectionRange or 0):
|
||||
return
|
||||
fit.ship.increaseItemAttr('warpScrambleStatus', module.getModifiedItemAttr('warpScrambleStrength'))
|
||||
fit.modules.filteredItemIncrease(
|
||||
lambda mod: mod.item.requiresSkill('High Speed Maneuvering') or mod.item.requiresSkill('Micro Jump Drive Operation'),
|
||||
|
||||
@@ -22,6 +22,7 @@ from gui.builtinContextMenus import shipJump
|
||||
# Generic item manipulations
|
||||
from gui.builtinContextMenus import itemRemove
|
||||
from gui.builtinContextMenus import itemAmountChange
|
||||
from gui.builtinContextMenus import itemProjectionRange
|
||||
from gui.builtinContextMenus import droneSplitStack
|
||||
from gui.builtinContextMenus import itemVariationChange
|
||||
from gui.builtinContextMenus import moduleMutations
|
||||
|
||||
128
gui/builtinContextMenus/itemProjectionRange.py
Normal file
128
gui/builtinContextMenus/itemProjectionRange.py
Normal file
@@ -0,0 +1,128 @@
|
||||
import re
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import wx
|
||||
|
||||
import gui.fitCommands as cmd
|
||||
import gui.mainFrame
|
||||
from eos.saveddata.drone import Drone
|
||||
from eos.saveddata.fighter import Fighter
|
||||
from eos.saveddata.fit import Fit as es_Fit
|
||||
from eos.saveddata.module import Module
|
||||
from gui.contextMenu import ContextMenuSingle
|
||||
from service.fit import Fit
|
||||
|
||||
|
||||
class ChangeItemProjectionRange(ContextMenuSingle):
|
||||
|
||||
def __init__(self):
|
||||
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
|
||||
|
||||
def display(self, callingWindow, srcContext, mainItem):
|
||||
if srcContext not in ('projectedFit', 'projectedModule', 'projectedDrone', 'projectedFighter'):
|
||||
return False
|
||||
if mainItem is None:
|
||||
return False
|
||||
return True
|
||||
|
||||
def getText(self, callingWindow, itmContext, mainItem):
|
||||
return 'Change {} Range'.format(itmContext)
|
||||
|
||||
def activate(self, callingWindow, fullContext, mainItem, i):
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
srcContext = fullContext[0]
|
||||
if isinstance(mainItem, es_Fit):
|
||||
try:
|
||||
value = mainItem.getProjectionInfo(fitID).projectionRange
|
||||
except AttributeError:
|
||||
return
|
||||
else:
|
||||
value = mainItem.projectionRange
|
||||
if value is not None:
|
||||
value /= 1000
|
||||
with RangeChanger(self.mainFrame, value) as dlg:
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
sFit = Fit.getInstance()
|
||||
fit = sFit.getFit(fitID)
|
||||
cleanInput = re.sub(r'[^0-9.]', '', dlg.input.GetLineText(0).strip())
|
||||
if cleanInput:
|
||||
try:
|
||||
cleanInputFloat = float(cleanInput)
|
||||
except ValueError:
|
||||
return
|
||||
newRange = cleanInputFloat * 1000
|
||||
else:
|
||||
newRange = None
|
||||
|
||||
if isinstance(mainItem, es_Fit):
|
||||
self.mainFrame.command.Submit(cmd.GuiChangeProjectedFitRangeCommand(
|
||||
fitID=fitID, projectedFitID=mainItem.ID, projectionRange=newRange))
|
||||
elif isinstance(mainItem, Module):
|
||||
if mainItem in fit.projectedModules:
|
||||
position = fit.projectedModules.index(mainItem)
|
||||
pass
|
||||
elif isinstance(mainItem, Drone):
|
||||
pass
|
||||
elif isinstance(mainItem, Fighter):
|
||||
if mainItem in fit.projectedFighters:
|
||||
position = fit.projectedFighters.index(mainItem)
|
||||
pass
|
||||
|
||||
|
||||
ChangeItemProjectionRange.register()
|
||||
|
||||
|
||||
class RangeChanger(wx.Dialog):
|
||||
|
||||
def __init__(self, parent, value):
|
||||
super().__init__(parent, title='Change Projection Range', style=wx.DEFAULT_DIALOG_STYLE)
|
||||
self.SetMinSize((346, 156))
|
||||
|
||||
bSizer1 = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
bSizer2 = wx.BoxSizer(wx.VERTICAL)
|
||||
text = wx.StaticText(self, wx.ID_ANY, 'New Range, km:')
|
||||
bSizer2.Add(text, 0)
|
||||
|
||||
bSizer1.Add(bSizer2, 0, wx.ALL, 10)
|
||||
|
||||
self.input = wx.TextCtrl(self, wx.ID_ANY, style=wx.TE_PROCESS_ENTER)
|
||||
if value is None:
|
||||
value = ''
|
||||
else:
|
||||
if value == int(value):
|
||||
value = int(value)
|
||||
value = str(value)
|
||||
self.input.SetValue(value)
|
||||
self.input.SelectAll()
|
||||
|
||||
bSizer1.Add(self.input, 0, wx.LEFT | wx.RIGHT | wx.EXPAND, 15)
|
||||
|
||||
bSizer3 = wx.BoxSizer(wx.VERTICAL)
|
||||
bSizer3.Add(wx.StaticLine(self, wx.ID_ANY), 0, wx.BOTTOM | wx.EXPAND, 15)
|
||||
|
||||
bSizer3.Add(self.CreateStdDialogButtonSizer(wx.OK | wx.CANCEL), 0, wx.EXPAND)
|
||||
bSizer1.Add(bSizer3, 0, wx.ALL | wx.EXPAND, 10)
|
||||
|
||||
self.input.SetFocus()
|
||||
self.input.Bind(wx.EVT_CHAR, self.onChar)
|
||||
self.input.Bind(wx.EVT_TEXT_ENTER, self.processEnter)
|
||||
self.SetSizer(bSizer1)
|
||||
self.CenterOnParent()
|
||||
self.Fit()
|
||||
|
||||
def processEnter(self, evt):
|
||||
self.EndModal(wx.ID_OK)
|
||||
|
||||
# checks to make sure it's valid number
|
||||
@staticmethod
|
||||
def onChar(event):
|
||||
key = event.GetKeyCode()
|
||||
|
||||
acceptable_characters = '1234567890.'
|
||||
acceptable_keycode = [3, 22, 13, 8, 127] # modifiers like delete, copy, paste
|
||||
if key in acceptable_keycode or key >= 255 or (key < 255 and chr(key) in acceptable_characters):
|
||||
event.Skip()
|
||||
return
|
||||
else:
|
||||
return False
|
||||
@@ -23,6 +23,7 @@ import wx
|
||||
from logbook import Logger
|
||||
|
||||
import gui.mainFrame
|
||||
from eos.saveddata.fit import Fit
|
||||
from gui.bitmap_loader import BitmapLoader
|
||||
from gui.utils.numberFormatter import formatAmount
|
||||
from gui.viewColumn import ViewColumn
|
||||
@@ -41,10 +42,14 @@ class ProjectionRangeColumn(ViewColumn):
|
||||
self.imageId = fittingView.imageList.GetImageIndex(1391, "icons")
|
||||
self.bitmap = BitmapLoader.getBitmap(1391, "icons")
|
||||
self.mask = wx.LIST_MASK_IMAGE
|
||||
self.projectedView = isinstance(fittingView, gui.builtinAdditionPanes.projectedView.ProjectedView)
|
||||
|
||||
def getText(self, stuff):
|
||||
projRange = getattr(stuff, 'projectionRange', None)
|
||||
if isinstance(stuff, Fit):
|
||||
fitID = self.mainFrame.getActiveFit()
|
||||
info = stuff.getProjectionInfo(fitID)
|
||||
projRange = info.projectionRange
|
||||
else:
|
||||
projRange = getattr(stuff, 'projectionRange', None)
|
||||
if projRange is None:
|
||||
return ''
|
||||
return formatAmount(projRange, 3, 0, 3, unitName='m')
|
||||
|
||||
@@ -66,6 +66,7 @@ from .gui.projectedFighter.changeAmount import GuiChangeProjectedFighterAmountCo
|
||||
from .gui.projectedFighter.changeMetas import GuiChangeProjectedFighterMetasCommand
|
||||
from .gui.projectedFit.add import GuiAddProjectedFitsCommand
|
||||
from .gui.projectedFit.changeAmount import GuiChangeProjectedFitAmountCommand
|
||||
from .gui.projectedFit.changeRange import GuiChangeProjectedFitRangeCommand
|
||||
from .gui.projectedModule.add import GuiAddProjectedModuleCommand
|
||||
from .gui.projectedModule.changeCharges import GuiChangeProjectedModuleChargesCommand
|
||||
from .gui.projectedModule.changeMetas import GuiChangeProjectedModuleMetasCommand
|
||||
|
||||
60
gui/fitCommands/calc/projectedFit/changeProjectionRange.py
Normal file
60
gui/fitCommands/calc/projectedFit/changeProjectionRange.py
Normal file
@@ -0,0 +1,60 @@
|
||||
import wx
|
||||
from logbook import Logger
|
||||
|
||||
from gui.fitCommands.helpers import restoreCheckedStates
|
||||
from service.fit import Fit
|
||||
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
class CalcChangeProjectedFitProjectionRangeCommand(wx.Command):
|
||||
|
||||
def __init__(self, fitID, projectedFitID, projectionRange):
|
||||
wx.Command.__init__(self, True, 'Change Projected Fit Projection Range')
|
||||
self.fitID = fitID
|
||||
self.projectedFitID = projectedFitID
|
||||
self.projectionRange = projectionRange
|
||||
self.savedProjectionRange = None
|
||||
self.savedStateCheckChanges = None
|
||||
|
||||
def Do(self):
|
||||
pyfalog.debug('Doing change of projected fit {} range to {} for fit {}'.format(self.projectedFitID, self.projectionRange, self.fitID))
|
||||
sFit = Fit.getInstance()
|
||||
fit = sFit.getFit(self.fitID)
|
||||
projectedFit = sFit.getFit(self.projectedFitID, projected=True)
|
||||
# Projected fit could have been deleted if we are redoing
|
||||
if projectedFit is None:
|
||||
pyfalog.debug('Projected fit is not available')
|
||||
return False
|
||||
projectionInfo = projectedFit.getProjectionInfo(self.fitID)
|
||||
if projectionInfo is None:
|
||||
pyfalog.warning('Fit projection info is not available')
|
||||
return False
|
||||
self.savedProjectionRange = projectionInfo.projectionRange
|
||||
if self.projectionRange == self.savedProjectionRange:
|
||||
return False
|
||||
projectionInfo.projectionRange = self.projectionRange
|
||||
|
||||
sFit.recalc(fit)
|
||||
self.savedStateCheckChanges = sFit.checkStates(fit, None)
|
||||
return True
|
||||
|
||||
def Undo(self):
|
||||
pyfalog.debug('Undoing change of projected fit {} range to {} for fit {}'.format(self.projectedFitID, self.projectionRange, self.fitID))
|
||||
cmd = CalcChangeProjectedFitProjectionRangeCommand(
|
||||
fitID=self.fitID,
|
||||
projectedFitID=self.projectedFitID,
|
||||
projectionRange=self.savedProjectionRange)
|
||||
result = cmd.Do()
|
||||
restoreCheckedStates(Fit.getInstance().getFit(self.fitID), self.savedStateCheckChanges)
|
||||
return result
|
||||
|
||||
@property
|
||||
def needsGuiRecalc(self):
|
||||
if self.savedStateCheckChanges is None:
|
||||
return True
|
||||
for container in self.savedStateCheckChanges:
|
||||
if len(container) > 0:
|
||||
return True
|
||||
return False
|
||||
40
gui/fitCommands/gui/projectedFit/changeRange.py
Normal file
40
gui/fitCommands/gui/projectedFit/changeRange.py
Normal file
@@ -0,0 +1,40 @@
|
||||
import wx
|
||||
|
||||
import eos.db
|
||||
import gui.mainFrame
|
||||
from gui import globalEvents as GE
|
||||
from gui.fitCommands.calc.projectedFit.changeProjectionRange import CalcChangeProjectedFitProjectionRangeCommand
|
||||
from gui.fitCommands.helpers import InternalCommandHistory
|
||||
from service.fit import Fit
|
||||
|
||||
|
||||
class GuiChangeProjectedFitRangeCommand(wx.Command):
|
||||
|
||||
def __init__(self, fitID, projectedFitID, projectionRange):
|
||||
wx.Command.__init__(self, True, 'Change Projected Fit Projection Range')
|
||||
self.internalHistory = InternalCommandHistory()
|
||||
self.fitID = fitID
|
||||
self.projectedFitID = projectedFitID
|
||||
self.projectionRange = projectionRange
|
||||
|
||||
def Do(self):
|
||||
cmd = CalcChangeProjectedFitProjectionRangeCommand(fitID=self.fitID, projectedFitID=self.projectedFitID, projectionRange=self.projectionRange)
|
||||
success = self.internalHistory.submit(cmd)
|
||||
sFit = Fit.getInstance()
|
||||
if cmd.needsGuiRecalc:
|
||||
eos.db.flush()
|
||||
sFit.recalc(self.fitID)
|
||||
sFit.fill(self.fitID)
|
||||
eos.db.commit()
|
||||
wx.PostEvent(gui.mainFrame.MainFrame.getInstance(), GE.FitChanged(fitIDs=(self.fitID,)))
|
||||
return success
|
||||
|
||||
def Undo(self):
|
||||
success = self.internalHistory.undoAll()
|
||||
eos.db.flush()
|
||||
sFit = Fit.getInstance()
|
||||
sFit.recalc(self.fitID)
|
||||
sFit.fill(self.fitID)
|
||||
eos.db.commit()
|
||||
wx.PostEvent(gui.mainFrame.MainFrame.getInstance(), GE.FitChanged(fitIDs=(self.fitID,)))
|
||||
return success
|
||||
Reference in New Issue
Block a user