Tweaks supporting standard modules schema changes

This commit is contained in:
Colin McLeod
2016-02-17 17:52:58 -08:00
parent 9175fb60af
commit 05e160f702
12 changed files with 111 additions and 98 deletions

View File

@@ -11,6 +11,7 @@
"engine": "node >= 4.0.0",
"license": "MIT",
"scripts": {
"extract-translations": "grep -hroE \"translate\\('[^']+'\\)\" src/* | grep -oE \"'[^']+'\" | grep -oE \"[^']+\" | sort -u -f",
"clean": "rimraf build",
"start": "node devServer.js",
"lint": "eslint --ext .js,.jsx src",

View File

@@ -127,7 +127,7 @@ export default class AvailableModulesMenu extends TranslatedComponent {
}
if (i > 0 && modules.length > 3 && m.class != prevClass && (m.rating != prevRating || m.mount) && m.grp != 'pa') {
elems.push(<br key={m.grp + i} />);
elems.push(<br key={'b' + m.grp + i} />);
}
elems.push(

View File

@@ -63,7 +63,7 @@ export default class ShipSummaryTable extends TranslatedComponent {
</tr>
<tr>
<th className='lft'>{translate('strength')}</th>
<th onMouseEnter={termtip.bind(null, 'PHRASE_SG_RECOVER', { cap: 0 })} onMouseLeave={hide}>{translate('recover')}</th>
<th onMouseEnter={termtip.bind(null, 'PHRASE_SG_RECOVER', { cap: 0 })} onMouseLeave={hide}>{translate('recovery')}</th>
<th onMouseEnter={termtip.bind(null, 'PHRASE_SG_RECHARGE', { cap: 0 })} onMouseLeave={hide}>{translate('recharge')}</th>
<th className='lft'>{translate('hull')}</th>
<th onMouseEnter={termtip.bind(null, 'PHRASE_UNLADEN', { cap: 0 })} onMouseLeave={hide}>{translate('unladen')}</th>

View File

@@ -303,7 +303,7 @@ export default class StandardSlotSection extends SlotSection {
<li className='c' onClick={_fill.bind(this, 'B')}>B</li>
<li className='c' onClick={_fill.bind(this, 'A')}>A</li>
</ul>
<div className='select-group cap'>{translate('builds / roles')}</div>
<div className='select-group cap'>{translate('roles')}</div>
<ul>
<li className='lc' onClick={this._optimizeCargo}>{translate('Trader')}</li>
<li className='lc' onClick={this._optimizeExplorer}>{translate('Explorer')}</li>

View File

@@ -16,7 +16,7 @@ class SvgIcon extends React.Component {
/**
* Standard SVG view box, can/should be overriden by sub-classes as necessary
* @return {string} view box string
* @return {String} view box string
*/
viewBox() { return '0 0 32 32'; }
@@ -118,7 +118,7 @@ export class Embed extends SvgIcon {
export class Equalizer extends SvgIcon {
/**
* Overriden view box
* @return {string} view box
* @return {String} view box
*/
viewBox() { return '0 0 1024 1024'; }
/**
@@ -164,7 +164,7 @@ export class Fuel extends SvgIcon {
export class GitHub extends SvgIcon {
/**
* Overriden view box
* @return {string} view box
* @return {String} view box
*/
viewBox() { return '0 0 1024 1024'; }
/**
@@ -228,7 +228,7 @@ export class LinkIcon extends SvgIcon {
export class NoPower extends SvgIcon {
/**
* Overriden view box
* @return {string} view box
* @return {String} view box
*/
viewBox() { return '0 0 512 512'; }
/**
@@ -259,7 +259,7 @@ export class Notification extends SvgIcon {
export class Power extends SvgIcon {
/**
* Overriden view box
* @return {string} view box
* @return {String} view box
*/
viewBox() { return '0 0 512 512'; }
/**
@@ -320,7 +320,7 @@ export class Warning extends SvgIcon {
export class MountFixed extends SvgIcon {
/**
* Overriden view box
* @return {string} view box
* @return {String} view box
*/
viewBox() { return '0 0 200 200'; }
/**
@@ -344,7 +344,7 @@ export class MountFixed extends SvgIcon {
export class MountGimballed extends SvgIcon {
/**
* Overriden view box
* @return {string} view box
* @return {String} view box
*/
viewBox() { return '0 0 200 200'; }
/**
@@ -365,7 +365,7 @@ export class MountGimballed extends SvgIcon {
export class MountTurret extends SvgIcon {
/**
* Overriden view box
* @return {string} view box
* @return {String} view box
*/
viewBox() { return '0 0 200 200'; }
/**
@@ -452,7 +452,7 @@ export class Switch extends SvgIcon {
export class StationCoriolis extends SvgIcon {
/**
* Overriden view box
* @return {string} view box
* @return {String} view box
*/
viewBox() { return '0 0 200 200'; }
/**
@@ -473,7 +473,7 @@ export class StationCoriolis extends SvgIcon {
export class StationOcellus extends SvgIcon {
/**
* Overriden view box
* @return {string} view box
* @return {String} view box
*/
viewBox() { return '0 0 200 200'; }
/**
@@ -495,7 +495,7 @@ export class StationOcellus extends SvgIcon {
export class StationOrbis extends SvgIcon {
/**
* Overriden view box
* @return {string} view box
* @return {String} view box
*/
viewBox() { return '0 0 200 200'; }
/**
@@ -516,7 +516,7 @@ export class StationOrbis extends SvgIcon {
export class StationOutpost extends SvgIcon {
/**
* Overriden view box
* @return {string} view box
* @return {String} view box
*/
viewBox() { return '0 0 200 200'; }
/**
@@ -551,7 +551,7 @@ export class Upload extends SvgIcon {
export class Loader extends SvgIcon {
/**
* Overriden view box
* @return {string} view box
* @return {String} view box
*/
viewBox() { return '0 0 40 40'; }
/**

View File

@@ -27,49 +27,50 @@ export const terms = {
PHRASE_FASTEST_RANGE: 'Consecutive max range jumps',
PHRASE_SG_RECOVER: 'Recovery (to 50%) after collapse',
PHRASE_SG_RECHARGE: 'Time from 50% to 100% Charge',
T_LOAD: 't-load',
// Only Translate to other languages if the name is different in-game
am: 'Auto Field-Maintenance Unit',
'Basic Discovery Scanner': 'Basic Discovery Scanner',
bh: 'Bulkheads',
bl: 'Beam Laser',
bh: 'bulkheads',
bsg: 'Bi-Weave Shield Generator',
ul: 'Burst Laser',
c: 'Cannon',
cr: 'Cargo Rack',
cs: 'Cargo Scanner',
cc: 'Collector Limpet Controller',
cm: 'Countermeasure',
cr: 'Cargo Rack',
cs: 'Cargo Scanner',
dc: 'Docking Computer',
fc: 'Fragment Cannon',
fd: 'Frame Shift Drive',
ws: 'Frame Shift Wake Scanner',
fsd: 'Frame Shift Drive',
fi: 'FSD Interdictor',
fs: 'Fuel Scoop',
fsd: 'Frame Shift Drive',
ft: 'Fuel Tank',
fx: 'Fuel Transfer Limpet Controller',
hb: 'Hatch Breaker Limpet Controller',
hr: 'Hull Reinforcement Package',
kw: 'Kill Warrant Scanner',
ls: 'life support',
nl: 'Mine Launcher',
mc: 'Multi-cannon',
ml: 'Mining Laser',
mr: 'Missile Rack',
mc: 'Multi-cannon',
nl: 'Mine Launcher',
pa: 'Plasma Accelerator',
pas: 'Planetary Approach Suite',
pc: 'Prospector Limpet Controller',
pd: 'power distributor',
pl: 'Pulse Laser',
pp: 'power plant',
psg: 'Prismatic Shield Generator',
pc: 'Prospector Limpet Controller',
pl: 'Pulse Laser',
pv: 'Planetary Vehicle Hanger',
rg: 'Rail Gun',
rf: 'Refinery',
sc: 'scanner',
rg: 'Rail Gun',
s: 'sensors',
sb: 'Shield Booster',
sc: 'scanner',
scb: 'Shield Cell Bank',
sg: 'Shield Generator',
T_LOAD: 't-load',
t: 'thrusters',
tp: 'Torpedo Pylon'
tp: 'Torpedo Pylon',
ul: 'Burst Laser',
ws: 'Frame Shift Wake Scanner'
};

View File

@@ -82,7 +82,7 @@ export const terms = {
'fixed': 'fijo',
'forum': 'Foro',
'fc': 'Ca\u00f1\u00f3n de fragmentaci\u00f3n',
'fd': 'Motor de salto',
'fsd': 'Motor de salto',
'ws': 'Esc\u00e1ner de Salto',
'fi': 'Interdictor FSD',
'fuel': 'Combustible',

View File

@@ -71,6 +71,7 @@ export default class OutfittingPage extends Page {
title: 'Outfitting - ' + data.properties.name,
costTab: Persist.getCostTab() || 'costs',
buildName,
newBuildName: buildName,
shipId,
ship,
code,
@@ -89,11 +90,11 @@ export default class OutfittingPage extends Page {
*/
_buildNameChange(event) {
let stateChanges = {
buildName: event.target.value
newBuildName: event.target.value
};
if (Persist.hasBuild(this.state.shipId, stateChanges.buildName)) {
stateChanges.savedCode = Persist.getBuild(this.state.shipId, stateChanges.buildName);
if (Persist.hasBuild(this.state.shipId, stateChanges.newBuildName)) {
stateChanges.savedCode = Persist.getBuild(this.state.shipId, stateChanges.newBuildName);
} else {
stateChanges.savedCode = null;
}
@@ -106,9 +107,31 @@ export default class OutfittingPage extends Page {
*/
_saveBuild() {
let code = this.state.ship.toString();
Persist.saveBuild(this.state.shipId, this.state.buildName, code);
this._updateRoute(this.state.shipId, code, this.state.buildName);
this.setState({ code, savedCode: code });
let { buildName, newBuildName, shipId } = this.state;
if (buildName === newBuildName) {
Persist.saveBuild(shipId, buildName, code);
this._updateRoute(shipId, buildName, code);
} else {
Persist.saveBuild(shipId, newBuildName, code);
this._updateRoute(shipId, newBuildName, code);
}
this.setState({ buildName: newBuildName, code, savedCode: code });
}
/**
* Rename the current build
*/
_renameBuild() {
let { buildName, newBuildName, shipId, ship } = this.state;
if (buildName != newBuildName && newBuildName.length) {
let code = ship.toString();
Persist.deleteBuild(shipId, buildName);
Persist.saveBuild(shipId, newBuildName, code);
this._updateRoute(shipId, newBuildName, code);
this.setState({ buildName: newBuildName, code, savedCode: code });
}
}
/**
@@ -159,17 +182,17 @@ export default class OutfittingPage extends Page {
this._fuelChange(this.state.fuelLevel);
}
this._updateRoute(shipId, code, buildName);
this._updateRoute(shipId, buildName, code);
this.setState({ code });
}
/**
* Update the current route based on build
* @param {string} shipId Ship Id
* @param {string} code Serialized ship 'code'
* @param {string} buildName Current build name
* @param {string} code Serialized ship 'code'
*/
_updateRoute(shipId, code, buildName) {
_updateRoute(shipId, buildName, code) {
Router.replace(outfitURL(shipId, code, buildName));
}
@@ -243,11 +266,12 @@ export default class OutfittingPage extends Page {
let state = this.state,
{ language, termtip, tooltip, sizeRatio, onWindowResize } = this.context,
{ translate, units, formats } = language,
{ ship, code, savedCode, buildName, chartWidth, fuelCapacity, fuelLevel } = state,
{ ship, code, savedCode, buildName, newBuildName, chartWidth, fuelCapacity, fuelLevel } = state,
hide = tooltip.bind(null, null),
menu = this.props.currentMenu,
shipUpdated = this._shipUpdated,
canSave = buildName && code !== savedCode,
canSave = (newBuildName || buildName) && code !== savedCode,
canRename = buildName && newBuildName && buildName != newBuildName,
canReload = savedCode && canSave,
hStr = ship.getHardpointsString(),
sStr = ship.getStandardString(),
@@ -258,10 +282,13 @@ export default class OutfittingPage extends Page {
<div id='overview'>
<h1>{ship.name}</h1>
<div id='build'>
<input value={buildName} onChange={this._buildNameChange} placeholder={translate('Enter Name')} maxsize={50} />
<input value={newBuildName} onChange={this._buildNameChange} placeholder={translate('Enter Name')} maxsize={50} />
<button onClick={canSave && this._saveBuild} disabled={!canSave} onMouseOver={termtip.bind(null, 'save')} onMouseOut={hide}>
<FloppyDisk className='lg' />
</button>
<button onClick={canRename && this._renameBuild} disabled={!canRename} onMouseOver={termtip.bind(null, 'rename')} onMouseOut={hide}>
<span style={{ textTransform: 'none', fontSize: '1.8em' }}>a|</span>
</button>
<button onClick={canReload && this._reloadBuild} disabled={!canReload} onMouseOver={termtip.bind(null, 'reload')} onMouseOut={hide}>
<Reload className='lg'/>
</button>

View File

@@ -9,6 +9,16 @@ export const ArmourMultiplier = [
export const SizeMap = ['', 'small', 'medium', 'large', 'capital'];
export const StandardArray = [
'pp', // Power Plant
't', // Thrusters
'fsd', // Frame Shift Drive
'ls', // Life Support
'pd', // Power Distributor
's', // Sensors
'ft', // Fuel Tank
];
// Map to lookup group labels/names for component grp, used for JSON Serialization
export const ModuleGroupToName = {
// Standard
@@ -19,6 +29,7 @@ export const ModuleGroupToName = {
pd: 'Power Distributor',
s: 'Sensors',
ft: 'Fuel Tank',
pas: 'Planetary Approach Suite',
// Internal
fs: 'Fuel Scoop',

View File

@@ -11,27 +11,6 @@ function filter(arr, maxClass, minClass, mass) {
return arr.filter(m => m.class <= maxClass && m.class >= minClass && (m.maxmass === undefined || mass <= m.maxmass));
}
/**
* Filter eligble modules based on parameters
* @param {Object} data Available modules object
* @param {number} maxClass Max class
* @param {number} minClass Minimum class
* @param {number} mass Mass
* @return {Array} Fitlered module subset
*/
function filterToArray(data, maxClass, minClass, mass) {
let arr = [];
for (let id in data) {
let m = data[id];
if (m.class <= maxClass && m.class >= minClass && (m.maxmass === undefined || mass <= m.maxmass)) {
arr.push(m);
}
}
return arr;
}
/**
* The available module set for a specific ship
*/
@@ -46,6 +25,7 @@ export default class ModuleSet {
* @param {Array} maxHardPoint Array of hardpoint slots classes/sizes
*/
constructor(modules, mass, maxStandardArr, maxInternal, maxHardPoint) {
let stnd = modules.standard;
this.mass = mass;
this.standard = {};
this.internal = {};
@@ -53,22 +33,16 @@ export default class ModuleSet {
this.hpClass = {};
this.intClass = {};
this.standard[0] = filterToArray(modules.standard[0], maxStandardArr[0], 0, mass); // Power Plant
this.standard[2] = filterToArray(modules.standard[2], maxStandardArr[2], 0, mass); // FSD
this.standard[4] = filterToArray(modules.standard[4], maxStandardArr[4], 0, mass); // Power Distributor
this.standard[6] = filterToArray(modules.standard[6], maxStandardArr[6], 0, mass); // Fuel Tank
this.standard[0] = filter(stnd.pp, maxStandardArr[0], 0, mass); // Power Plant
this.standard[2] = filter(stnd.fsd, maxStandardArr[2], 0, mass); // FSD
this.standard[4] = filter(stnd.pd, maxStandardArr[4], 0, mass); // Power Distributor
this.standard[6] = filter(stnd.ft, maxStandardArr[6], 0, mass); // Fuel Tank
// Thrusters, filter modules by class only (to show full list of ratings for that class)
let ths = modules.standard[1];
let minThrusterClass = Object.keys(modules.standard[1]).reduce(
(clazz, thId) => (ths[thId].maxmass >= mass && ths[thId].class < clazz) ? ths[thId].class : clazz,
maxStandardArr[1]
);
this.standard[1] = filterToArray(modules.standard[1], maxStandardArr[1], minThrusterClass, 0); // Thrusters
let minThrusterClass = stnd.t.reduce((clazz, th) => (th.maxmass >= mass && th.class < clazz) ? th.class : clazz, maxStandardArr[1]);
this.standard[1] = filter(stnd.t, maxStandardArr[1], minThrusterClass, 0); // Thrusters
// Slots where module class must be equal to slot class
this.standard[3] = filterToArray(modules.standard[3], maxStandardArr[3], maxStandardArr[3], 0); // Life Supprt
this.standard[5] = filterToArray(modules.standard[5], maxStandardArr[5], maxStandardArr[5], mass); // Sensors
this.standard[3] = filter(stnd.ls, maxStandardArr[3], maxStandardArr[3], 0); // Life Supprt
this.standard[5] = filter(stnd.s, maxStandardArr[5], maxStandardArr[5], mass); // Sensors
for (let h in modules.hardpoints) {
this.hardpoints[h] = filter(modules.hardpoints[h], maxHardPoint, 0, mass);

View File

@@ -1,7 +1,9 @@
import { ModuleNameToGroup, BulkheadNames } from './Constants';
import { ModuleNameToGroup, BulkheadNames, StandardArray } from './Constants';
import ModuleSet from './ModuleSet';
import { Ships, Modules } from 'coriolis-data/dist';
/**
* Created a cargo hatch model
* @return {Object} Cargo hatch model
@@ -12,22 +14,17 @@ export function cargoHatch() {
/**
* Finds the standard module type with the specified ID
* @param {number} typeIndex Standard Module Type (0 - Power Plant, 1 - Thrusters, etc)
* @param {string} id The module ID or '[Class][Rating]'
* @return {Object} The standard module or null
* @param {String|Number} type Standard Module Type (0/pp - Power Plant, 1/t - Thrusters, etc)
* @param {String} id The module ID or '[Class][Rating]'
* @return {Object} The standard module or null
*/
export function standard(typeIndex, id) {
let standard = Modules.standard[typeIndex];
if (standard[id]) {
return standard[id];
} else {
for (let k in standard) {
if (standard[k].id == id) {
return standard[k];
}
}
export function standard(type, id) {
if (!isNaN(type)) {
type = StandardArray[type];
}
return null;
let s = Modules.standard[type].find(e => e.id == id || (e.class == id.charAt(0) && e.rating == id.charAt(1)));
return s || null;
};
/**
@@ -212,11 +209,13 @@ export function isShieldGenerator(g) {
* Creates a new ModuleSet that contains all available modules
* that the specified ship is eligible to use.
*
* 6.5 T is the lightest possible mass of standard components that any ship can use
*
* @param {string} shipId Unique ship Id/Key
* @return {ModuleSet} The set of modules the ship can install
*/
export function forShip(shipId) {
let ship = Ships[shipId];
let maxInternal = isNaN(ship.slots.internal[0]) ? ship.slots.internal[0].class : ship.slots.internal[0];
return new ModuleSet(Modules, ship.minMassFilter || ship.properties.hullMass + 5, ship.slots.standard, maxInternal, ship.slots.hardpoints[0]);
return new ModuleSet(Modules, ship.properties.hullMass + 6.5, ship.slots.standard, maxInternal, ship.slots.hardpoints[0]);
}

View File

@@ -241,8 +241,8 @@ export function diffDetails(language, m, mm) {
</div>);
}
if (m.grp == 'fd' || massDiff || capDiff) {
let fsd = m.grp == 'fd' ? m : null;
if (m.grp == 'fsd' || massDiff || capDiff) {
let fsd = m.grp == 'fsd' ? m : null;
let maxRange = this.calcUnladenRange(massDiff, m.fuel, fsd);
let ladenRange = this.calcLadenRange(massDiff + capDiff, m.fuel, fsd);