diff --git a/collate.py b/collate.py index f3910af5..e3df2c1e 100755 --- a/collate.py +++ b/collate.py @@ -68,29 +68,28 @@ def addmodules(data): outfile = 'outfitting.csv' modules = {} - schemakeys = ['category', 'name', 'mount', 'guidance', 'ship', 'class', 'rating'] + fields = ['id', 'category', 'name', 'mount', 'guidance', 'ship', 'class', 'rating', 'entitlement'] # slurp existing if isfile(outfile): with open(outfile) as csvfile: - reader = csv.DictReader(csvfile) + reader = csv.DictReader(csvfile, restval='') for row in reader: - key = int(row.pop('id')) # index by int for easier lookup and sorting - modules[key] = row + modules[int(row['id'])] = row # index by int for easier lookup and sorting size_pre = len(modules) for key,module in data['lastStarport'].get('modules').iteritems(): # sanity check if int(key) != module.get('id'): raise AssertionError('id: %s!=%s' % (key, module['id'])) - new = outfitting.lookup(module, ship_map) + new = outfitting.lookup(module, ship_map, True) if new: old = modules.get(int(key)) if old: # check consistency with existing data - for thing in schemakeys: - if new.get(thing,'') != old.get(thing): raise AssertionError('%s: %s "%s"!="%s"' % (key, thing, new.get(thing), old.get(thing))) + for thing in fields: + if str(new.get(thing,'')) != old.get(thing): raise AssertionError('%s: %s "%s"!="%s"' % (key, thing, new.get(thing), old.get(thing))) else: - modules[int(key)] = { k: new[k] for k in schemakeys if k in new } + modules[int(key)] = new if len(modules) > size_pre: @@ -100,12 +99,10 @@ def addmodules(data): os.rename(outfile, outfile+'.bak') with open(outfile, 'wb') as csvfile: - writer = csv.DictWriter(csvfile, ['id', 'category', 'name', 'mount', 'guidance', 'ship', 'class', 'rating']) + writer = csv.DictWriter(csvfile, fields, extrasaction='ignore') writer.writeheader() for key in sorted(modules): - row = modules[key] - row['id'] = key - writer.writerow(row) + writer.writerow(modules[key]) print 'Added %d new modules' % (len(modules) - size_pre) diff --git a/coriolis.py b/coriolis.py index 9dc6af02..a1a70200 100755 --- a/coriolis.py +++ b/coriolis.py @@ -326,5 +326,8 @@ if __name__ == "__main__": } else: modules[key] = { 'mass': m.get('mass', 0) } # Some modules don't have mass + + modules[('Planetary Approach Suite', None, '1', 'I')] = { 'mass': 0 } # not in data at time of writing + cPickle.dump(modules, open('modules.p', 'wb'), protocol = cPickle.HIGHEST_PROTOCOL) diff --git a/loadout.py b/loadout.py index 194f030a..7c07791b 100644 --- a/loadout.py +++ b/loadout.py @@ -86,10 +86,11 @@ def export(data, filename=None): else: if slot.lower().startswith('slot'): loadout[slot[-1]].append(cr + name) - elif __debug__: print 'Loadout: Unknown slot %s' % slot + elif __debug__ and not slot.lower().startswith('planetaryapproachsuite'): + print 'EDShipyard: Unknown slot %s' % slot except AssertionError as e: - if __debug__: print 'Loadout: %s' % e + if __debug__: print 'EDShipyard: %s' % e continue # Silently skip unrecognized modules except: if __debug__: raise diff --git a/modules.p b/modules.p index c6358e9c..200e1af9 100644 Binary files a/modules.p and b/modules.p differ diff --git a/outfitting.py b/outfitting.py index d1b3f90d..77ce8881 100644 --- a/outfitting.py +++ b/outfitting.py @@ -187,6 +187,7 @@ standard_map = { 'fueltank' : 'Fuel Tank', 'hyperdrive' : 'Frame Shift Drive', 'lifesupport' : 'Life Support', + # 'planetapproachsuite' : handled separately 'powerdistributor' : 'Power Distributor', 'powerplant' : 'Power Plant', 'sensors' : 'Sensors', @@ -200,7 +201,6 @@ internal_map = { 'fuelscoop' : 'Fuel Scoop', 'fueltransfer' : 'Fuel Transfer Limpet Controller', 'hullreinforcement' : 'Hull Reinforcement Package', - # 'planetapproachsuite' : 'Planetary Approach Suite', # Don't report 'prospector' : 'Prospector Limpet Controller', 'refinery' : 'Refinery', 'repairer' : 'Auto Field-Maintenance Unit', @@ -223,7 +223,7 @@ moduledata = cPickle.load(open(join(config.respath, 'modules.p'), 'rb')) # # Returns None if the module is user-specific (i.e. decal, paintjob) or PP-specific in station outfitting. # (Given the ad-hocery in this implementation a big lookup table might have been simpler and clearer). -def lookup(module, ship_map): +def lookup(module, ship_map, entitled=False): # if not module.get('category'): raise AssertionError('%s: Missing category' % module['id']) # only present post 1.3, and not present in ship loadout if not module.get('name'): raise AssertionError('%s: Missing name' % module['id']) @@ -249,15 +249,11 @@ def lookup(module, ship_map): # elif 'category' in module and module['category'].lower() == 'powerplay': # return None - # Shouldn't be listing player-specific paid stuff, other than Horizons - elif module.get('sku') and module['sku'].lower() != 'elite_horizons_v_planetary_landings': + # Shouldn't be listing player-specific paid stuff in outfitting, other than Horizons + elif not entitled and module.get('sku') and module['sku'] != 'ELITE_HORIZONS_V_PLANETARY_LANDINGS': # raise AssertionError('%s: Unexpected sku "%s"' % (module['id'], module['sku'])) return None - # Skip Horizons Planetary Approach Suite - elif name[1] in ['planetapproachsuite']: - return None - # Hardpoints - e.g. Hpt_Slugshot_Fixed_Medium elif name[0]=='hpt' and name[1] in weapon_map: if name[2] not in weaponmount_map: raise AssertionError('%s: Unknown weapon mount "%s"' % (module['id'], name[2])) @@ -298,8 +294,16 @@ def lookup(module, ship_map): elif name[0]!='int': raise AssertionError('%s: Unknown prefix "%s"' % (module['id'], name[0])) + # Horizons Planetary Approach Suite + elif name[1] == 'planetapproachsuite': + new['category'] = 'standard' + new['name'] = 'Planetary Approach Suite' + new['class'] = '1' + new['rating'] = 'I' + new['entitlement'] = 'horizons' # only listed in outfitting if the user is *playing* Horizons + # Miscellaneous Class 1 - e.g. Int_StellarBodyDiscoveryScanner_Advanced, Int_DockingComputer_Standard - elif (name[1],name[2]) in misc_internal_map: + elif len(name) > 2 and (name[1],name[2]) in misc_internal_map: # Reported category is not necessarily helpful. e.g. "Int_DockingComputer_Standard" has category "utility" new['category'] = 'internal' new['name'], new['rating'] = misc_internal_map[(name[1],name[2])] @@ -327,6 +331,14 @@ def lookup(module, ship_map): if 'on' in module and 'priority' in module: new['enabled'], new['priority'] = module['on'], module['priority'] # priority is zero-based + # Entitlements + if not entitled or not module.get('sku'): + pass + elif module['sku'].startswith('ELITE_SPECIFIC_V_POWER'): + new['entitlement'] = 'powerplay' + elif module['sku'] != 'ELITE_HORIZONS_V_PLANETARY_LANDINGS': + assert False, '%s: Unknown sku "%s"' % (module['id'], module['sku']) + # Extra module data key = (new['name'], 'ship' in new and companion.ship_map.get(name[0]) or None, new['class'], new['rating']) if __debug__: @@ -339,7 +351,8 @@ def lookup(module, ship_map): new.update(moduledata.get(key, {})) # check we've filled out mandatory fields - for thing in ['category', 'name', 'class', 'rating']: # Don't consider mass etc as mandatory + new['id'] = module['id'] + for thing in ['id', 'category', 'name', 'class', 'rating']: # Don't consider mass etc as mandatory if not new.get(thing): raise AssertionError('%s: failed to set %s' % (module['id'], thing)) if new['category'] == 'hardpoint' and not new.get('mount'): raise AssertionError('%s: failed to set %s' % (module['id'], 'mount'))