Implement mutated attributes import
This commit is contained in:
@@ -396,6 +396,21 @@ def getAbyssalTypes():
|
|||||||
return set([r.resultingTypeID for r in gamedata_session.query(DynamicItem.resultingTypeID).distinct()])
|
return set([r.resultingTypeID for r in gamedata_session.query(DynamicItem.resultingTypeID).distinct()])
|
||||||
|
|
||||||
|
|
||||||
|
@cachedQuery(1, "itemID")
|
||||||
|
def getDynamicItem(itemID, eager=None):
|
||||||
|
try:
|
||||||
|
if isinstance(itemID, int):
|
||||||
|
if eager is None:
|
||||||
|
result = gamedata_session.query(DynamicItem).filter(DynamicItem.ID == itemID).one()
|
||||||
|
else:
|
||||||
|
result = gamedata_session.query(DynamicItem).options(*processEager(eager)).filter(DynamicItem.ID == itemID).one()
|
||||||
|
else:
|
||||||
|
raise TypeError("Need integer as argument")
|
||||||
|
except exc.NoResultFound:
|
||||||
|
result = None
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
def getRequiredFor(itemID, attrMapping):
|
def getRequiredFor(itemID, attrMapping):
|
||||||
Attribute1 = aliased(Attribute)
|
Attribute1 = aliased(Attribute)
|
||||||
Attribute2 = aliased(Attribute)
|
Attribute2 = aliased(Attribute)
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import re
|
|||||||
|
|
||||||
from logbook import Logger
|
from logbook import Logger
|
||||||
|
|
||||||
from eos.db.gamedata.queries import getAttributeInfo
|
from eos.db.gamedata.queries import getAttributeInfo, getDynamicItem
|
||||||
from eos.saveddata.cargo import Cargo
|
from eos.saveddata.cargo import Cargo
|
||||||
from eos.saveddata.citadel import Citadel
|
from eos.saveddata.citadel import Citadel
|
||||||
from eos.saveddata.booster import Booster
|
from eos.saveddata.booster import Booster
|
||||||
@@ -44,7 +44,7 @@ SLOT_ORDER = (Slot.LOW, Slot.MED, Slot.HIGH, Slot.RIG, Slot.SUBSYSTEM, Slot.SERV
|
|||||||
OFFLINE_SUFFIX = ' /OFFLINE'
|
OFFLINE_SUFFIX = ' /OFFLINE'
|
||||||
|
|
||||||
|
|
||||||
def fetchItem(typeName, eagerCat=True):
|
def fetchItem(typeName, eagerCat=False):
|
||||||
sMkt = Market.getInstance()
|
sMkt = Market.getInstance()
|
||||||
eager = 'group.category' if eagerCat else None
|
eager = 'group.category' if eagerCat else None
|
||||||
try:
|
try:
|
||||||
@@ -150,7 +150,7 @@ class RegularItemSpec(BaseItemSpec):
|
|||||||
def __fetchCharge(self, chargeName):
|
def __fetchCharge(self, chargeName):
|
||||||
if chargeName:
|
if chargeName:
|
||||||
charge = fetchItem(chargeName, eagerCat=True)
|
charge = fetchItem(chargeName, eagerCat=True)
|
||||||
if charge.category.name != 'Charge':
|
if not charge or charge.category.name != 'Charge':
|
||||||
charge = None
|
charge = None
|
||||||
else:
|
else:
|
||||||
charge = None
|
charge = None
|
||||||
@@ -203,6 +203,8 @@ class AbstractFit:
|
|||||||
self.drones = {} # Format: {item: Drone}
|
self.drones = {} # Format: {item: Drone}
|
||||||
self.fighters = []
|
self.fighters = []
|
||||||
self.cargo = {} # Format: {item: Cargo}
|
self.cargo = {} # Format: {item: Cargo}
|
||||||
|
# Other stuff
|
||||||
|
self.mutations = {} # Format: {reference: (mutaplamid item, {attr ID: attr value})}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def __slotContainerMap(self):
|
def __slotContainerMap(self):
|
||||||
@@ -259,10 +261,28 @@ class AbstractFit:
|
|||||||
self.getContainerBySlot(m.slot).append(m)
|
self.getContainerBySlot(m.slot).append(m)
|
||||||
|
|
||||||
def __makeModule(self, itemSpec):
|
def __makeModule(self, itemSpec):
|
||||||
try:
|
# Mutate item if needed
|
||||||
m = Module(itemSpec.item)
|
m = None
|
||||||
except ValueError:
|
if itemSpec.mutationIdx in self.mutations:
|
||||||
return None
|
mutaItem, mutaAttrs = self.mutations[itemSpec.mutationIdx]
|
||||||
|
mutaplasmid = getDynamicItem(mutaItem.ID)
|
||||||
|
if mutaplasmid:
|
||||||
|
try:
|
||||||
|
m = Module(mutaplasmid.resultingItem, itemSpec.item, mutaplasmid)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
for attrID, mutator in m.mutators.items():
|
||||||
|
if attrID in mutaAttrs:
|
||||||
|
mutator.value = mutaAttrs[attrID]
|
||||||
|
# If we still don't have item (item is not mutated or we
|
||||||
|
# failed to construct mutated item), try to make regular item
|
||||||
|
if m is None:
|
||||||
|
try:
|
||||||
|
m = Module(itemSpec.item)
|
||||||
|
except ValueError:
|
||||||
|
return None
|
||||||
|
|
||||||
if itemSpec.charge is not None and m.isValidCharge(itemSpec.charge):
|
if itemSpec.charge is not None and m.isValidCharge(itemSpec.charge):
|
||||||
m.charge = itemSpec.charge
|
m.charge = itemSpec.charge
|
||||||
if itemSpec.offline and m.isValidState(State.OFFLINE):
|
if itemSpec.offline and m.isValidState(State.OFFLINE):
|
||||||
@@ -425,10 +445,13 @@ class EftPort:
|
|||||||
return
|
return
|
||||||
|
|
||||||
aFit = AbstractFit()
|
aFit = AbstractFit()
|
||||||
|
aFit.mutations = cls.__getMutationData(lines)
|
||||||
|
pyfalog.error('{}'.format(aFit.mutations))
|
||||||
|
|
||||||
|
nameChars = '[^,/\[\]]' # Characters which are allowed to be used in name
|
||||||
stubPattern = '^\[.+\]$'
|
stubPattern = '^\[.+\]$'
|
||||||
modulePattern = '^(?P<typeName>[^,/]+)(, (?P<chargeName>[^,/]+))?(?P<offline>{})?( \[(?P<mutation>\d+)\])?$'.format(OFFLINE_SUFFIX)
|
modulePattern = '^(?P<typeName>{0}+)(, (?P<chargeName>{0}+))?(?P<offline>{1})?( \[(?P<mutation>\d+)\])?$'.format(nameChars, OFFLINE_SUFFIX)
|
||||||
droneCargoPattern = '^(?P<typeName>[^,/]+) x(?P<amount>\d+)$'
|
droneCargoPattern = '^(?P<typeName>{}+) x(?P<amount>\d+)$'.format(nameChars)
|
||||||
|
|
||||||
sections = []
|
sections = []
|
||||||
for section in cls.__importSectionIter(lines):
|
for section in cls.__importSectionIter(lines):
|
||||||
@@ -467,6 +490,7 @@ class EftPort:
|
|||||||
clearTail(section.itemSpecs)
|
clearTail(section.itemSpecs)
|
||||||
sections.append(section)
|
sections.append(section)
|
||||||
|
|
||||||
|
|
||||||
hasDroneBay = any(s.isDroneBay for s in sections)
|
hasDroneBay = any(s.isDroneBay for s in sections)
|
||||||
hasFighterBay = any(s.isFighterBay for s in sections)
|
hasFighterBay = any(s.isFighterBay for s in sections)
|
||||||
for section in sections:
|
for section in sections:
|
||||||
@@ -555,28 +579,61 @@ class EftPort:
|
|||||||
del lines[-1]
|
del lines[-1]
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
@classmethod
|
@staticmethod
|
||||||
def __createFit(cls, lines):
|
def __getMutationData(lines):
|
||||||
"""Create fit and set top-level entity (ship or citadel)."""
|
data = {}
|
||||||
fit = Fit()
|
consumedIndices = set()
|
||||||
header = lines.pop(0)
|
for i in range(len(lines)):
|
||||||
m = re.match('\[(?P<shipType>[\w\s]+), (?P<fitName>.+)\]', header)
|
line = lines[i]
|
||||||
if not m:
|
m = re.match('^\[(?P<ref>\d+)\]', line)
|
||||||
pyfalog.warning('EftPort.importEft: corrupted fit header')
|
if m:
|
||||||
raise EftImportError
|
ref = int(m.group('ref'))
|
||||||
shipType = m.group('shipType').strip()
|
# Attempt to apply mutation is useless w/o mutaplasmid, so skip it
|
||||||
fitName = m.group('fitName').strip()
|
# altogether if we have no info on it
|
||||||
try:
|
try:
|
||||||
ship = fetchItem(shipType, eagerCat=False)
|
mutaName = lines[i + 1]
|
||||||
try:
|
except IndexError:
|
||||||
fit.ship = Ship(ship)
|
continue
|
||||||
except ValueError:
|
else:
|
||||||
fit.ship = Citadel(ship)
|
consumedIndices.add(i)
|
||||||
fit.name = fitName
|
consumedIndices.add(i + 1)
|
||||||
except:
|
# Get custom attribute values
|
||||||
pyfalog.warning('EftPort.importEft: exception caught when parsing header')
|
mutaAttrs = {}
|
||||||
raise EftImportError
|
try:
|
||||||
return fit
|
mutaAttrsLine = lines[i + 2]
|
||||||
|
except IndexError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
consumedIndices.add(i + 2)
|
||||||
|
pairs = [p.strip() for p in mutaAttrsLine.split(',')]
|
||||||
|
for pair in pairs:
|
||||||
|
try:
|
||||||
|
attrName, value = pair.split(' ')
|
||||||
|
except ValueError:
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
value = float(value)
|
||||||
|
except (ValueError, TypeError):
|
||||||
|
continue
|
||||||
|
attrInfo = getAttributeInfo(attrName.strip())
|
||||||
|
if attrInfo is None:
|
||||||
|
continue
|
||||||
|
mutaAttrs[attrInfo.ID] = value
|
||||||
|
mutaItem = fetchItem(mutaName)
|
||||||
|
if mutaItem is None:
|
||||||
|
continue
|
||||||
|
data[ref] = (mutaItem, mutaAttrs)
|
||||||
|
# If we got here, we have seen at least correct reference line and
|
||||||
|
# mutaplasmid name line
|
||||||
|
i += 2
|
||||||
|
# Bonus points for seeing correct attrs line. Worst case we
|
||||||
|
# will have to scan it once again
|
||||||
|
if mutaAttrs:
|
||||||
|
i += 1
|
||||||
|
# Cleanup the lines from mutaplasmid info
|
||||||
|
for i in sorted(consumedIndices, reverse=True):
|
||||||
|
del lines[i]
|
||||||
|
return data
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def __importSectionIter(lines):
|
def __importSectionIter(lines):
|
||||||
@@ -590,3 +647,26 @@ class EftPort:
|
|||||||
section.lines.append(line)
|
section.lines.append(line)
|
||||||
if section.lines:
|
if section.lines:
|
||||||
yield section
|
yield section
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def __createFit(cls, lines):
|
||||||
|
"""Create fit and set top-level entity (ship or citadel)."""
|
||||||
|
fit = Fit()
|
||||||
|
header = lines.pop(0)
|
||||||
|
m = re.match('\[(?P<shipType>[\w\s]+), (?P<fitName>.+)\]', header)
|
||||||
|
if not m:
|
||||||
|
pyfalog.warning('EftPort.importEft: corrupted fit header')
|
||||||
|
raise EftImportError
|
||||||
|
shipType = m.group('shipType').strip()
|
||||||
|
fitName = m.group('fitName').strip()
|
||||||
|
try:
|
||||||
|
ship = fetchItem(shipType)
|
||||||
|
try:
|
||||||
|
fit.ship = Ship(ship)
|
||||||
|
except ValueError:
|
||||||
|
fit.ship = Citadel(ship)
|
||||||
|
fit.name = fitName
|
||||||
|
except:
|
||||||
|
pyfalog.warning('EftPort.importEft: exception caught when parsing header')
|
||||||
|
raise EftImportError
|
||||||
|
return fit
|
||||||
|
|||||||
@@ -908,7 +908,6 @@ class Port(object):
|
|||||||
|
|
||||||
return fit_list
|
return fit_list
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def exportEft(cls, fit):
|
def exportEft(cls, fit):
|
||||||
return EftPort.exportEft(fit, mutations=False, implants=False)
|
return EftPort.exportEft(fit, mutations=False, implants=False)
|
||||||
|
|||||||
Reference in New Issue
Block a user