Add ability to change projection range of fits

This commit is contained in:
DarkPhoenix
2019-09-29 23:41:45 +03:00
parent 33103dbee9
commit 20868d6b44
8 changed files with 241 additions and 4 deletions

View File

@@ -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

View File

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

View File

@@ -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

View 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

View File

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

View File

@@ -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

View 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

View 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