Allow imports of mutated drone groups via ctrl-v and additions panel context menus
This commit is contained in:
@@ -5,7 +5,7 @@ from gui import fitCommands as cmd
|
|||||||
from gui.contextMenu import ContextMenuUnconditional
|
from gui.contextMenu import ContextMenuUnconditional
|
||||||
from gui.utils.clipboard import fromClipboard
|
from gui.utils.clipboard import fromClipboard
|
||||||
from service.fit import Fit
|
from service.fit import Fit
|
||||||
from service.port.eft import parseAdditions
|
from service.port.eft import parseAdditions, importGetMutationData, lineIter
|
||||||
|
|
||||||
_t = wx.GetTranslation
|
_t = wx.GetTranslation
|
||||||
|
|
||||||
@@ -41,9 +41,12 @@ class AdditionsImport(ContextMenuUnconditional):
|
|||||||
|
|
||||||
def activate(self, callingWindow, fullContext, i):
|
def activate(self, callingWindow, fullContext, i):
|
||||||
text = fromClipboard()
|
text = fromClipboard()
|
||||||
items = parseAdditions(text)
|
lines = list(lineIter(text))
|
||||||
|
mutaData = importGetMutationData(lines)
|
||||||
|
text = '\n'.join(lines)
|
||||||
|
items = parseAdditions(text, mutaData=mutaData)
|
||||||
filterFunc = self.viewSpecMap[self.srcContext][1]
|
filterFunc = self.viewSpecMap[self.srcContext][1]
|
||||||
items = [(i.ID, a) for i, a in items if filterFunc(i)]
|
items = [(i.ID, a, m) for i, a, m in items if filterFunc(i)]
|
||||||
if not items:
|
if not items:
|
||||||
return
|
return
|
||||||
command = self.viewSpecMap[self.srcContext][2]
|
command = self.viewSpecMap[self.srcContext][2]
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class GuiImportCargosCommand(wx.Command):
|
|||||||
self.internalHistory = InternalCommandHistory()
|
self.internalHistory = InternalCommandHistory()
|
||||||
self.fitID = fitID
|
self.fitID = fitID
|
||||||
self.cargos = {}
|
self.cargos = {}
|
||||||
for itemID, amount in cargos:
|
for itemID, amount, mutation in cargos:
|
||||||
if itemID not in self.cargos:
|
if itemID not in self.cargos:
|
||||||
self.cargos[itemID] = 0
|
self.cargos[itemID] = 0
|
||||||
self.cargos[itemID] += amount
|
self.cargos[itemID] += amount
|
||||||
|
|||||||
@@ -18,11 +18,19 @@ class GuiImportLocalDronesCommand(wx.Command):
|
|||||||
|
|
||||||
def Do(self):
|
def Do(self):
|
||||||
results = []
|
results = []
|
||||||
for itemID, amount in self.drones:
|
for itemID, amount, mutation in self.drones:
|
||||||
cmd = CalcAddLocalDroneCommand(
|
if mutation:
|
||||||
fitID=self.fitID,
|
mutaplasmid, attrs = mutation
|
||||||
droneInfo=DroneInfo(itemID=itemID, amount=amount, amountActive=0),
|
info = DroneInfo(
|
||||||
forceNewStack=True)
|
itemID=mutaplasmid.resultingItem.ID,
|
||||||
|
amount=amount,
|
||||||
|
amountActive=0,
|
||||||
|
baseItemID=itemID,
|
||||||
|
mutaplasmidID=mutaplasmid.ID,
|
||||||
|
mutations=attrs)
|
||||||
|
else:
|
||||||
|
info = DroneInfo(itemID=itemID, amount=amount, amountActive=0)
|
||||||
|
cmd = CalcAddLocalDroneCommand(fitID=self.fitID, droneInfo=info, forceNewStack=True)
|
||||||
results.append(self.internalHistory.submit(cmd))
|
results.append(self.internalHistory.submit(cmd))
|
||||||
success = any(results)
|
success = any(results)
|
||||||
eos.db.flush()
|
eos.db.flush()
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class GuiImportLocalFightersCommand(wx.Command):
|
|||||||
|
|
||||||
def Do(self):
|
def Do(self):
|
||||||
results = []
|
results = []
|
||||||
for itemID, amount in self.fighters:
|
for itemID, amount, mutation in self.fighters:
|
||||||
cmd = CalcAddLocalFighterCommand(fitID=self.fitID, fighterInfo=FighterInfo(itemID=itemID, amount=amount, state=False))
|
cmd = CalcAddLocalFighterCommand(fitID=self.fitID, fighterInfo=FighterInfo(itemID=itemID, amount=amount, state=False))
|
||||||
results.append(self.internalHistory.submit(cmd))
|
results.append(self.internalHistory.submit(cmd))
|
||||||
success = any(results)
|
success = any(results)
|
||||||
|
|||||||
@@ -772,23 +772,23 @@ class MainFrame(wx.Frame):
|
|||||||
self.command.Submit(cmd.GuiAddLocalModuleCommand(activeFit, baseItem.ID))
|
self.command.Submit(cmd.GuiAddLocalModuleCommand(activeFit, baseItem.ID))
|
||||||
return
|
return
|
||||||
if importType == "AdditionsDrones":
|
if importType == "AdditionsDrones":
|
||||||
if self.command.Submit(cmd.GuiImportLocalDronesCommand(activeFit, [(i.ID, a) for i, a in importData[0]])):
|
if self.command.Submit(cmd.GuiImportLocalDronesCommand(activeFit, [(i.ID, a, m) for i, a, m in importData[0]])):
|
||||||
self.additionsPane.select("Drones")
|
self.additionsPane.select("Drones")
|
||||||
return
|
return
|
||||||
if importType == "AdditionsFighters":
|
if importType == "AdditionsFighters":
|
||||||
if self.command.Submit(cmd.GuiImportLocalFightersCommand(activeFit, [(i.ID, a) for i, a in importData[0]])):
|
if self.command.Submit(cmd.GuiImportLocalFightersCommand(activeFit, [(i.ID, a, m) for i, a, m in importData[0]])):
|
||||||
self.additionsPane.select("Fighters")
|
self.additionsPane.select("Fighters")
|
||||||
return
|
return
|
||||||
if importType == "AdditionsImplants":
|
if importType == "AdditionsImplants":
|
||||||
if self.command.Submit(cmd.GuiImportImplantsCommand(activeFit, [(i.ID, a) for i, a in importData[0]])):
|
if self.command.Submit(cmd.GuiImportImplantsCommand(activeFit, [(i.ID, a, m) for i, a, m in importData[0]])):
|
||||||
self.additionsPane.select("Implants")
|
self.additionsPane.select("Implants")
|
||||||
return
|
return
|
||||||
if importType == "AdditionsBoosters":
|
if importType == "AdditionsBoosters":
|
||||||
if self.command.Submit(cmd.GuiImportBoostersCommand(activeFit, [(i.ID, a) for i, a in importData[0]])):
|
if self.command.Submit(cmd.GuiImportBoostersCommand(activeFit, [(i.ID, a, m) for i, a, m in importData[0]])):
|
||||||
self.additionsPane.select("Boosters")
|
self.additionsPane.select("Boosters")
|
||||||
return
|
return
|
||||||
if importType == "AdditionsCargo":
|
if importType == "AdditionsCargo":
|
||||||
if self.command.Submit(cmd.GuiImportCargosCommand(activeFit, [(i.ID, a) for i, a in importData[0]])):
|
if self.command.Submit(cmd.GuiImportCargosCommand(activeFit, [(i.ID, a, m) for i, a, m in importData[0]])):
|
||||||
self.additionsPane.select("Cargo")
|
self.additionsPane.select("Cargo")
|
||||||
return
|
return
|
||||||
except (KeyboardInterrupt, SystemExit):
|
except (KeyboardInterrupt, SystemExit):
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ def importEft(lines):
|
|||||||
return
|
return
|
||||||
|
|
||||||
aFit = AbstractFit()
|
aFit = AbstractFit()
|
||||||
aFit.mutations = _importGetMutationData(lines)
|
aFit.mutations = importGetMutationData(lines)
|
||||||
|
|
||||||
stubPattern = '^\[.+?\]$'
|
stubPattern = '^\[.+?\]$'
|
||||||
modulePattern = '^(?P<typeName>{0}+?)(,\s*(?P<chargeName>{0}+?))?(?P<offline>\s*{1})?(\s*\[(?P<mutation>\d+?)\])?$'.format(NAME_CHARS, OFFLINE_SUFFIX)
|
modulePattern = '^(?P<typeName>{0}+?)(,\s*(?P<chargeName>{0}+?))?(?P<offline>\s*{1})?(\s*\[(?P<mutation>\d+?)\])?$'.format(NAME_CHARS, OFFLINE_SUFFIX)
|
||||||
@@ -572,8 +572,7 @@ def _importPrepare(lines):
|
|||||||
mutantHeaderPattern = re.compile('^\[(?P<ref>\d+)\](?P<tail>.*)')
|
mutantHeaderPattern = re.compile('^\[(?P<ref>\d+)\](?P<tail>.*)')
|
||||||
|
|
||||||
|
|
||||||
def _importGetMutationData(lines):
|
def importGetMutationData(lines):
|
||||||
data = {}
|
|
||||||
# Format: {ref: [lines]}
|
# Format: {ref: [lines]}
|
||||||
mutaLinesMap = {}
|
mutaLinesMap = {}
|
||||||
currentMutaRef = None
|
currentMutaRef = None
|
||||||
@@ -943,7 +942,7 @@ class AbstractFit:
|
|||||||
self.cargo[itemSpec.item].amount += itemSpec.amount
|
self.cargo[itemSpec.item].amount += itemSpec.amount
|
||||||
|
|
||||||
|
|
||||||
def _lineIter(text):
|
def lineIter(text):
|
||||||
"""Iterate over non-blank lines."""
|
"""Iterate over non-blank lines."""
|
||||||
for line in text.splitlines():
|
for line in text.splitlines():
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
@@ -951,11 +950,11 @@ def _lineIter(text):
|
|||||||
yield line
|
yield line
|
||||||
|
|
||||||
|
|
||||||
def parseAdditions(text):
|
def parseAdditions(text, mutaData=None):
|
||||||
items = []
|
items = []
|
||||||
sMkt = Market.getInstance()
|
sMkt = Market.getInstance()
|
||||||
pattern = '^(?P<typeName>{}+?)( x(?P<amount>\d+?))?$'.format(NAME_CHARS)
|
pattern = '^(?P<typeName>{}+?)( x(?P<amount>\d+?))?(\s*\[(?P<mutaref>\d+?)\])?$'.format(NAME_CHARS)
|
||||||
for line in _lineIter(text):
|
for line in lineIter(text):
|
||||||
m = re.match(pattern, line)
|
m = re.match(pattern, line)
|
||||||
if not m:
|
if not m:
|
||||||
continue
|
continue
|
||||||
@@ -964,19 +963,27 @@ def parseAdditions(text):
|
|||||||
continue
|
continue
|
||||||
amount = m.group('amount')
|
amount = m.group('amount')
|
||||||
amount = 1 if amount is None else int(amount)
|
amount = 1 if amount is None else int(amount)
|
||||||
items.append((item, amount))
|
mutaRef = int(m.group('mutaref')) if m.group('mutaref') else None
|
||||||
|
if mutaRef and mutaData and mutaRef in mutaData:
|
||||||
|
mutation = mutaData[mutaRef]
|
||||||
|
else:
|
||||||
|
mutation = None
|
||||||
|
items.append((item, amount, mutation))
|
||||||
return items
|
return items
|
||||||
|
|
||||||
|
|
||||||
def isValidDroneImport(text):
|
def isValidDroneImport(text):
|
||||||
pattern = 'x\d+$'
|
lines = list(lineIter(text))
|
||||||
for line in _lineIter(text):
|
mutaData = importGetMutationData(lines)
|
||||||
|
text = '\n'.join(lines)
|
||||||
|
pattern = 'x\d+(\s*\[\d+\])?$'
|
||||||
|
for line in lineIter(text):
|
||||||
if not re.search(pattern, line):
|
if not re.search(pattern, line):
|
||||||
return False, ()
|
return False, ()
|
||||||
itemData = parseAdditions(text)
|
itemData = parseAdditions(text, mutaData=mutaData)
|
||||||
if not itemData:
|
if not itemData:
|
||||||
return False, ()
|
return False, ()
|
||||||
for item, amount in itemData:
|
for item, amount, mutation in itemData:
|
||||||
if not item.isDrone:
|
if not item.isDrone:
|
||||||
return False, ()
|
return False, ()
|
||||||
return True, itemData
|
return True, itemData
|
||||||
@@ -984,13 +991,13 @@ def isValidDroneImport(text):
|
|||||||
|
|
||||||
def isValidFighterImport(text):
|
def isValidFighterImport(text):
|
||||||
pattern = 'x\d+$'
|
pattern = 'x\d+$'
|
||||||
for line in _lineIter(text):
|
for line in lineIter(text):
|
||||||
if not re.search(pattern, line):
|
if not re.search(pattern, line):
|
||||||
return False, ()
|
return False, ()
|
||||||
itemData = parseAdditions(text)
|
itemData = parseAdditions(text)
|
||||||
if not itemData:
|
if not itemData:
|
||||||
return False, ()
|
return False, ()
|
||||||
for item, amount in itemData:
|
for item, amount, mutation in itemData:
|
||||||
if not item.isFighter:
|
if not item.isFighter:
|
||||||
return False, ()
|
return False, ()
|
||||||
return True, itemData
|
return True, itemData
|
||||||
@@ -998,13 +1005,13 @@ def isValidFighterImport(text):
|
|||||||
|
|
||||||
def isValidCargoImport(text):
|
def isValidCargoImport(text):
|
||||||
pattern = 'x\d+$'
|
pattern = 'x\d+$'
|
||||||
for line in _lineIter(text):
|
for line in lineIter(text):
|
||||||
if not re.search(pattern, line):
|
if not re.search(pattern, line):
|
||||||
return False, ()
|
return False, ()
|
||||||
itemData = parseAdditions(text)
|
itemData = parseAdditions(text)
|
||||||
if not itemData:
|
if not itemData:
|
||||||
return False, ()
|
return False, ()
|
||||||
for item, amount in itemData:
|
for item, amount, mutation in itemData:
|
||||||
if item.isAbyssal:
|
if item.isAbyssal:
|
||||||
return False, ()
|
return False, ()
|
||||||
return True, itemData
|
return True, itemData
|
||||||
@@ -1012,13 +1019,13 @@ def isValidCargoImport(text):
|
|||||||
|
|
||||||
def isValidImplantImport(text):
|
def isValidImplantImport(text):
|
||||||
pattern = 'x\d+$'
|
pattern = 'x\d+$'
|
||||||
for line in _lineIter(text):
|
for line in lineIter(text):
|
||||||
if re.search(pattern, line):
|
if re.search(pattern, line):
|
||||||
return False, ()
|
return False, ()
|
||||||
itemData = parseAdditions(text)
|
itemData = parseAdditions(text)
|
||||||
if not itemData:
|
if not itemData:
|
||||||
return False, ()
|
return False, ()
|
||||||
for item, amount in itemData:
|
for item, amount, mutation in itemData:
|
||||||
if not item.isImplant:
|
if not item.isImplant:
|
||||||
return False, ()
|
return False, ()
|
||||||
return True, itemData
|
return True, itemData
|
||||||
@@ -1026,13 +1033,13 @@ def isValidImplantImport(text):
|
|||||||
|
|
||||||
def isValidBoosterImport(text):
|
def isValidBoosterImport(text):
|
||||||
pattern = 'x\d+$'
|
pattern = 'x\d+$'
|
||||||
for line in _lineIter(text):
|
for line in lineIter(text):
|
||||||
if re.search(pattern, line):
|
if re.search(pattern, line):
|
||||||
return False, ()
|
return False, ()
|
||||||
itemData = parseAdditions(text)
|
itemData = parseAdditions(text)
|
||||||
if not itemData:
|
if not itemData:
|
||||||
return False, ()
|
return False, ()
|
||||||
for item, amount in itemData:
|
for item, amount, mutation in itemData:
|
||||||
if not item.isBooster:
|
if not item.isBooster:
|
||||||
return False, ()
|
return False, ()
|
||||||
return True, itemData
|
return True, itemData
|
||||||
|
|||||||
@@ -232,14 +232,14 @@ class Port:
|
|||||||
|
|
||||||
# If we've got source file name which is used to describe ship name
|
# If we've got source file name which is used to describe ship name
|
||||||
# and first line contains something like [setup name], detect as eft config file
|
# and first line contains something like [setup name], detect as eft config file
|
||||||
if re.match("\[.*\]", firstLine) and path is not None:
|
if re.match("^\s*\[.*\]", firstLine) and path is not None:
|
||||||
filename = os.path.split(path)[1]
|
filename = os.path.split(path)[1]
|
||||||
shipName = filename.rsplit('.')[0]
|
shipName = filename.rsplit('.')[0]
|
||||||
return "EFT Config", True, cls.importEftCfg(shipName, lines, iportuser)
|
return "EFT Config", True, cls.importEftCfg(shipName, lines, iportuser)
|
||||||
|
|
||||||
# If no file is specified and there's comma between brackets,
|
# If no file is specified and there's comma between brackets,
|
||||||
# consider that we have [ship, setup name] and detect like eft export format
|
# consider that we have [ship, setup name] and detect like eft export format
|
||||||
if re.match("\[.*,.*\]", firstLine):
|
if re.match("^\s*\[.*,.*\]", firstLine):
|
||||||
return "EFT", True, (cls.importEft(lines),)
|
return "EFT", True, (cls.importEft(lines),)
|
||||||
|
|
||||||
# Check if string is in DNA format
|
# Check if string is in DNA format
|
||||||
|
|||||||
Reference in New Issue
Block a user