diff --git a/coriolis-data b/coriolis-data index 00f8c742..48477d80 160000 --- a/coriolis-data +++ b/coriolis-data @@ -1 +1 @@ -Subproject commit 00f8c7423fac9660884c0eecdea74846dc6c7d53 +Subproject commit 48477d8037af3dc219de0a100878453334d54ddc diff --git a/coriolis.py b/coriolis.py old mode 100644 new mode 100755 index 4a559c15..9dc6af02 --- a/coriolis.py +++ b/coriolis.py @@ -1,4 +1,7 @@ +#!/usr/bin/python +# # Export ship loadout in Coriolis format +# from collections import OrderedDict import cPickle @@ -66,9 +69,10 @@ weaponmount_map = { # Modules that have a name as well as a group bulkheads = outfitting.armour_map.values() -scanners = [x[0] for x in outfitting.misc_internal_map.values()] -countermeasures = [x[0] for x in outfitting.countermeasure_map.values()] -fixup_map = { +fixup_map = {} +fixup_map.update({ x[0] : ('Scanner', x[0]) for x in outfitting.misc_internal_map.values() }) +fixup_map.update({ x[0] : ('Countermeasure', x[0]) for x in outfitting.countermeasure_map.values() }) +fixup_map.update({ 'Advanced Plasma Accelerator' : ('Plasma Accelerator', 'Advanced Plasma Accelerator'), 'Cytoscrambler Burst Laser' : ('Burst Laser', 'Cytoscrambler'), 'Enforcer Cannon' : ('Multi-cannon', 'Enforcer'), @@ -77,10 +81,11 @@ fixup_map = { 'Multi-Cannon' : ('Multi-cannon', None), 'Pacifier Frag-Cannon' : ('Fragment Cannon', 'Pacifier'), 'Pack-Hound Missile Rack' : ('Missile Rack', 'Pack-Hound'), - 'Pulse Disruptor Laser' : ('Pulse Laser', 'Distruptor'), # Note sp - 'Shock Mine Launcher' : ('Mine Launcher', 'Shock Mine Launcher'), # XXX + 'Pulse Disruptor Laser' : ('Pulse Laser', 'Disruptor'), + 'Retributor Beam Laser' : ('Beam Laser', 'Retributor'), + 'Shock Mine Launcher' : ('Mine Launcher', 'Shock Mine Launcher'), 'Standard Docking Computer' : ('Docking Computer', 'Standard Docking Computer'), -} +}) # Ship masses @@ -153,12 +158,6 @@ def export(data, filename=None): if module['name'] in fixup_map: thing['group'], name = fixup_map[module['name']] if name: thing['name'] = name - elif module['name'] in scanners: - thing['group'] = 'Scanner' - thing['name'] = module['name'] - elif module['name'] in countermeasures: - thing['group'] = 'Countermeasure' - thing['name'] = module['name'] else: thing['group'] = module['name'] @@ -226,3 +225,106 @@ def export(data, filename=None): filename = join(config.get('outdir'), '%s.%s.json' % (ship, time.strftime('%Y-%m-%dT%H.%M.%S', time.localtime(querytime)))) with open(filename, 'wt') as h: h.write(string) + + +# +# build ship and module databases from https://github.com/cmmcleod/coriolis-data +# +if __name__ == "__main__": + import json + data = json.load(open('coriolis-data/dist/index.json')) + + # Map Coriolis's names to names displayed in the in-game shipyard + coriolis_ship_map = { + 'Cobra Mk III' : 'Cobra MkIII', + 'Cobra Mk IV' : 'Cobra MkIV', + 'Viper' : 'Viper MkIII', + 'Viper Mk IV' : 'Viper MkIV', + } + + # From https://github.com/cmmcleod/coriolis/blob/master/src/app/shipyard/Constants.js + ModuleGroupToName = { + # Standard + 'pp' : 'Power Plant', + 't' : 'Thrusters', + 'fsd' : 'Frame Shift Drive', + 'ls' : 'Life Support', + 'pd' : 'Power Distributor', + 's' : 'Sensors', + 'ft' : 'Fuel Tank', + 'pas' : 'Planetary Approach Suite', + + # Internal + 'fs' : 'Fuel Scoop', + 'sc' : 'Scanner', + 'am' : 'Auto Field-Maintenance Unit', + 'bsg' : 'Bi-Weave Shield Generator', + 'cr' : 'Cargo Rack', + 'fi' : 'Frame Shift Drive Interdictor', + 'hb' : 'Hatch Breaker Limpet Controller', + 'hr' : 'Hull Reinforcement Package', + 'rf' : 'Refinery', + 'scb' : 'Shield Cell Bank', + 'sg' : 'Shield Generator', + 'pv' : 'Planetary Vehicle Hangar', + 'psg' : 'Prismatic Shield Generator', + 'dc' : 'Docking Computer', + 'fx' : 'Fuel Transfer Limpet Controller', + 'pc' : 'Prospector Limpet Controller', + 'cc' : 'Collector Limpet Controller', + + # Hard Points + 'bl' : 'Beam Laser', + 'ul' : 'Burst Laser', + 'c' : 'Cannon', + 'cs' : 'Cargo Scanner', + 'cm' : 'Countermeasure', + 'fc' : 'Fragment Cannon', + 'ws' : 'Frame Shift Wake Scanner', + 'kw' : 'Kill Warrant Scanner', + 'nl' : 'Mine Launcher', + 'ml' : 'Mining Laser', + 'mr' : 'Missile Rack', + 'pa' : 'Plasma Accelerator', + 'mc' : 'Multi-cannon', + 'pl' : 'Pulse Laser', + 'rg' : 'Rail Gun', + 'sb' : 'Shield Booster', + 'tp' : 'Torpedo Pylon' + }; + + specials = { v:k for k,v in fixup_map.items() } + + ships = {} + modules = {} + + # Ship and armour masses + for m in data['Ships'].values(): + name = coriolis_ship_map.get(m['properties']['name'], str(m['properties']['name'])) + ships[name] = { 'hullMass' : m['properties']['hullMass'] } + for i in range(len(bulkheads)): + modules[(bulkheads[i], name, '1', 'I')] = { 'mass': m['bulkheads'][i]['mass'] } + cPickle.dump(ships, open('ships.p', 'wb'), protocol = cPickle.HIGHEST_PROTOCOL) + + # Module masses + for cat in data['Modules'].values(): + for grp, mlist in cat.iteritems(): + for m in mlist: + key = ('name' in m and specials[(ModuleGroupToName[grp], m['name'])] or specials.get((ModuleGroupToName[grp], None), ModuleGroupToName[grp]), + None, + str(m['class']), + str(m['rating'])) + if key in modules: + # Test our assumption that mount and guidance don't affect mass + assert modules[key]['mass'] == m.get('mass', 0), '%s !=\n%s' % (key, m) + elif grp == 'fsd': + modules[key] = { 'mass' : m['mass'], + 'optmass' : m['optmass'], + 'maxfuel' : m['maxfuel'], + 'fuelmul' : m['fuelmul'], + 'fuelpower' : m['fuelpower'], + } + else: + modules[key] = { 'mass': m.get('mass', 0) } # Some modules don't have mass + cPickle.dump(modules, open('modules.p', 'wb'), protocol = cPickle.HIGHEST_PROTOCOL) + diff --git a/eddb.py b/eddb.py index cc233ed8..003aa67e 100755 --- a/eddb.py +++ b/eddb.py @@ -31,8 +31,9 @@ class EDDB: return (station_id, bool(flags & EDDB.HAS_MARKET), bool(flags & EDDB.HAS_OUTFITTING), bool(flags & EDDB.HAS_SHIPYARD)) -# build databases from files systems.json, stations.json and modules.json from http://eddb.io/api -# and from https://github.com/cmmcleod/coriolis-data +# +# build databases from files systems.json and stations.json from http://eddb.io/api +# if __name__ == "__main__": import json @@ -64,72 +65,3 @@ if __name__ == "__main__": (EDDB.HAS_SHIPYARD if x['has_shipyard'] else 0))) for x in stations]) cPickle.dump(station_ids, open('stations.p', 'wb'), protocol = cPickle.HIGHEST_PROTOCOL) - - - # Map eddb's names to names displayed in the in-game shipyard - eddb_ship_map = { - 'Sidewinder Mk. I' : 'Sidewinder', - 'Eagle Mk. II' : 'Eagle', - 'Cobra Mk. III' : 'Cobra MkIII', - 'Cobra MK IV' : 'Cobra MkIV', - 'Viper Mk III' : 'Viper MkIII', - 'Viper MK IV' : 'Viper MkIV', - } - - # PP modules (see weapon-map in outfitting.py) - specials = { - 'Retributor' : 'Retributor Beam Laser', - 'Pack-Hound' : 'Pack-Hound Missile Rack', - 'Mining Lance' : 'Mining Lance Beam Laser', - 'Enforcer' : 'Enforcer Cannon', - 'Advanced' : 'Advanced Plasma Accelerator', - 'Distruptor' : 'Pulse Disruptor Laser', - 'Cytoscrambler' : 'Cytoscrambler Burst Laser', - 'Imperial Hammer' : 'Imperial Hammer Rail Gun', - 'Pacifier' : 'Pacifier Frag-Cannon', - 'Prismatic' : 'Prismatic Shield Generator', - } - - # Module masses - modules = {} - for m in json.load(open('modules.json')): - # ignore mount and guidance, and convert strings to ascii to save space - key = (specials.get(m['name'], str(m['name'] or m['group']['name'])), - m['ship'] and eddb_ship_map.get(m['ship'], str(m['ship'])), - str(m['class']), - str(m['rating'])) - if key in modules: - # Test our assumption that mount and guidance don't affect mass - assert modules[key]['mass'] == m.get('mass', 0), '%s !=\n%s' % (key, m) - else: - modules[key] = { 'mass': m.get('mass', 0) } # Some modules don't have mass - - # Add FSD data from Coriolis - for m in json.load(open('coriolis-data/components/standard/frame_shift_drive.json')).values(): - key = ('Frame Shift Drive', None, str(m['class']), str(m['rating'])) - assert key in modules, key - modules[key].update({ - 'optmass' : m['optmass'], - 'maxfuel' : m['maxfuel'], - 'fuelmul' : m['fuelmul'], - 'fuelpower' : m['fuelpower'], - }) - cPickle.dump(modules, open('modules.p', 'wb'), protocol = cPickle.HIGHEST_PROTOCOL) - - - # Map Coriolis's names to names displayed in the in-game shipyard - coriolis_ship_map = { - 'Cobra Mk III' : 'Cobra MkIII', - 'Cobra Mk IV' : 'Cobra MkIV', - 'Viper' : 'Viper MkIII', - 'Viper Mk IV' : 'Viper MkIV', - } - - # Ship masses - ships = {} - for f in os.listdir('coriolis-data/ships'): - if not f.endswith('.json'): continue - for m in json.load(open(join('coriolis-data/ships', f))).values(): - ships[coriolis_ship_map.get(m['properties']['name'], str(m['properties']['name']))] = { 'hullMass' : m['properties']['hullMass'] } - cPickle.dump(ships, open('ships.p', 'wb'), protocol = cPickle.HIGHEST_PROTOCOL) - diff --git a/modules.p b/modules.p index 49761e7b..c6358e9c 100644 Binary files a/modules.p and b/modules.p differ diff --git a/outfitting.py b/outfitting.py index b7bbb814..d1b3f90d 100644 --- a/outfitting.py +++ b/outfitting.py @@ -1,3 +1,4 @@ +from collections import OrderedDict import cPickle from os.path import join import time @@ -8,13 +9,13 @@ from config import config # Map API module names to in-game names -armour_map = { - 'grade1' : 'Lightweight Alloy', - 'grade2' : 'Reinforced Alloy', - 'grade3' : 'Military Grade Composite', - 'mirrored' : 'Mirrored Surface Composite', - 'reactive' : 'Reactive Surface Composite', -} +armour_map = OrderedDict([ + ('grade1', 'Lightweight Alloy'), + ('grade2', 'Reinforced Alloy'), + ('grade3', 'Military Grade Composite'), + ('mirrored', 'Mirrored Surface Composite'), + ('reactive', 'Reactive Surface Composite'), +]) weapon_map = { 'advancedtorppylon' : 'Torpedo Pylon', @@ -288,7 +289,7 @@ def lookup(module, ship_map): new['category'] = 'utility' new['name'] = utility_map[len(name)>4 and (name[1],name[4]) or name[1]] if not name[2].startswith('size') or not name[3].startswith('class'): raise AssertionError('%s: Unknown class/rating "%s/%s"' % (module['id'], name[2], name[3])) - new['class'] = name[2][4:] + new['class'] = str(name[2][4:]) new['rating'] = rating_map[name[3][5:]] elif name[0]=='hpt': @@ -319,7 +320,7 @@ def lookup(module, ship_map): raise AssertionError('%s: Unknown module "%s"' % (module['id'], name[1])) if not name[2].startswith('size') or not name[3].startswith('class'): raise AssertionError('%s: Unknown class/rating "%s/%s"' % (module['id'], name[2], name[3])) - new['class'] = name[2][4:] + new['class'] = str(name[2][4:]) new['rating'] = (name[1]=='buggybay' and planet_rating_map or rating_map)[name[3][5:]] # Disposition of fitted modules diff --git a/ships.p b/ships.p index e1a1674b..02a270c1 100644 --- a/ships.p +++ b/ships.p @@ -1,5 +1,5 @@ -�}q(UFederal Assault Ship}qUhullMassqM�sU -Viper MkIVq}qhK�sUFederal Gunship}qhMDsUViper MkIIIq}qhK<sUImperial Eagle}q hK2sUImperial Cutter}q -hMLsUEagle}qhK2sUPython}qhM^sUType-6 Transporter}q hK�sUFer-de-Lance}qhK�sUVulture}qhK�sUAdder}qhK#sUType-7 Transporter}qhM�sUFederal Corvette}qhM�sUDiamondback Scout}qhK�sUHauler}qhKsUDiamondback Explorer}qhM*sUFederal Dropship}qhMDsUCobra MkIIIq}qhK�sUOrca}qhMDsU -Sidewinder}qhKsUAsp Explorer}qhMsUType-9 Heavy}qhM�sU -Cobra MkIVq}qhK�sUImperial Courier}qhK#sUAnaconda}q hM�sUImperial Clipper}q!hM�sUKeelback}q"hK�sU Asp Scout}q#hK�su. \ No newline at end of file +�}q(UFederal Assault Shipq}qUhullMassqM�sU +Viper MkIVq}qhK�sUFederal Gunshipq}qhMDsUViper MkIIIq }q +hK<sUImperial Eagleq}qhK2sUImperial Cutterq }qhMLsUEagleq}qhK2sUPythonq}qhM^sUType-6 Transporterq}qhK�sUFer-de-Lanceq}qhK�sUVultureq}qhK�sUAdderq}qhK#sUType-7 Transporterq}qhM�sUFederal Corvetteq}qhM�sUDiamondback Scoutq}q hK�sUAsp Explorerq!}q"hMsUDiamondback Explorerq#}q$hM*sUFederal Dropshipq%}q&hMDsUCobra MkIIIq'}q(hK�sUOrcaq)}q*hMDsU +Sidewinderq+}q,hKsUHaulerq-}q.hKsUType-9 Heavyq/}q0hM�sU +Cobra MkIVq1}q2hK�sUImperial Courierq3}q4hK#sUAnacondaq5}q6hM�sUImperial Clipperq7}q8hM�sUKeelbackq9}q:hK�sU Asp Scoutq;}q<hK�su. \ No newline at end of file