mirror of
https://github.com/EDCD/coriolis.git
synced 2025-12-09 14:45:35 +00:00
@@ -72,6 +72,11 @@ export default class Modification extends TranslatedComponent {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let inputClassNames = {
|
||||||
|
'cb': true,
|
||||||
|
'greyed-out': !this.props.highlight
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div onBlur={this._updateFinished.bind(this)} key={name}
|
<div onBlur={this._updateFinished.bind(this)} key={name}
|
||||||
className={cn('cb', 'modification-container')}
|
className={cn('cb', 'modification-container')}
|
||||||
@@ -84,12 +89,12 @@ export default class Modification extends TranslatedComponent {
|
|||||||
<td className={'input-container'}>
|
<td className={'input-container'}>
|
||||||
<span>
|
<span>
|
||||||
{this.props.editable ?
|
{this.props.editable ?
|
||||||
<NumberEditor className={'cb'} value={this.state.value}
|
<NumberEditor className={cn(inputClassNames)} value={this.state.value}
|
||||||
decimals={2} style={{ textAlign: 'right' }} step={0.01}
|
decimals={2} style={{ textAlign: 'right' }} step={0.01}
|
||||||
stepModifier={1} onKeyDown={ this.props.onKeyDown }
|
stepModifier={1} onKeyDown={ this.props.onKeyDown }
|
||||||
onValueChange={this._updateValue.bind(this)} /> :
|
onValueChange={this._updateValue.bind(this)} /> :
|
||||||
<input type="text" value={formats.f2(this.state.value)}
|
<input type="text" value={formats.f2(this.state.value)}
|
||||||
disabled className={'number-editor'}
|
disabled className={cn('number-editor', 'greyed-out')}
|
||||||
style={{ textAlign: 'right', cursor: 'inherit' }}/>
|
style={{ textAlign: 'right', cursor: 'inherit' }}/>
|
||||||
}
|
}
|
||||||
<span className={'unit-container'}>
|
<span className={'unit-container'}>
|
||||||
|
|||||||
@@ -214,11 +214,11 @@ export default class ModificationsMenu extends TranslatedComponent {
|
|||||||
for (const modName of Modifications.modules[m.grp].modifications) {
|
for (const modName of Modifications.modules[m.grp].modifications) {
|
||||||
if (!Modifications.modifications[modName].hidden) {
|
if (!Modifications.modifications[modName].hidden) {
|
||||||
const key = modName + (m.getModValue(modName) / 100 || 0);
|
const key = modName + (m.getModValue(modName) / 100 || 0);
|
||||||
const editable = modName !== 'fallofffromrange' &&
|
const editable = modName !== 'fallofffromrange';
|
||||||
m.blueprint.grades[m.blueprint.grade].features[modName];
|
const highlight = m.blueprint.grades[m.blueprint.grade].features[modName];
|
||||||
this.lastNeId = modName;
|
this.lastNeId = modName;
|
||||||
(editable ? modifiableModifications : modifications).push(
|
(editable && highlight ? modifiableModifications : modifications).push(
|
||||||
<Modification key={ key } ship={ ship } m={ m }
|
<Modification key={ key } ship={ ship } m={ m } highlight={highlight}
|
||||||
value={m.getPretty(modName) || 0} modItems={this.modItems}
|
value={m.getPretty(modName) || 0} modItems={this.modItems}
|
||||||
onChange={onChange} onKeyDown={this._keyDown} name={modName}
|
onChange={onChange} onKeyDown={this._keyDown} name={modName}
|
||||||
editable={editable} handleModChange = {this._handleModChange} />
|
editable={editable} handleModChange = {this._handleModChange} />
|
||||||
|
|||||||
@@ -198,12 +198,12 @@ export default class OutfittingPage extends Page {
|
|||||||
if (parts.length >= 5) {
|
if (parts.length >= 5) {
|
||||||
// We have control information in the code
|
// We have control information in the code
|
||||||
const control = LZString.decompressFromBase64(Utils.fromUrlSafe(parts[4])).split('/');
|
const control = LZString.decompressFromBase64(Utils.fromUrlSafe(parts[4])).split('/');
|
||||||
sys = parseFloat(control[0]);
|
sys = parseFloat(control[0]) || sys;
|
||||||
eng = parseFloat(control[1]);
|
eng = parseFloat(control[1]) || eng;
|
||||||
wep = parseFloat(control[2]);
|
wep = parseFloat(control[2]) || wep;
|
||||||
boost = control[3] == 1 ? true : false;
|
boost = control[3] == 1 ? true : false;
|
||||||
fuel = parseFloat(control[4]);
|
fuel = parseFloat(control[4]) || fuel;
|
||||||
cargo = parseInt(control[5]);
|
cargo = parseInt(control[5]) || cargo;
|
||||||
if (control[6]) {
|
if (control[6]) {
|
||||||
const shipId = control[6];
|
const shipId = control[6];
|
||||||
opponent = new Ship(shipId, Ships[shipId].properties, Ships[shipId].slots);
|
opponent = new Ship(shipId, Ships[shipId].properties, Ships[shipId].slots);
|
||||||
@@ -217,9 +217,9 @@ export default class OutfittingPage extends Page {
|
|||||||
const opponentParts = opponentCode.split('.');
|
const opponentParts = opponentCode.split('.');
|
||||||
if (opponentParts.length >= 5) {
|
if (opponentParts.length >= 5) {
|
||||||
const opponentControl = LZString.decompressFromBase64(Utils.fromUrlSafe(opponentParts[4])).split('/');
|
const opponentControl = LZString.decompressFromBase64(Utils.fromUrlSafe(opponentParts[4])).split('/');
|
||||||
opponentSys = parseFloat(opponentControl[0]);
|
opponentSys = parseFloat(opponentControl[0]) || opponentSys;
|
||||||
opponentEng = parseFloat(opponentControl[1]);
|
opponentEng = parseFloat(opponentControl[1]) || opponentEng;
|
||||||
opponentWep = parseFloat(opponentControl[2]);
|
opponentWep = parseFloat(opponentControl[2]) || opponentWep;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -227,7 +227,7 @@ export default class OutfittingPage extends Page {
|
|||||||
opponent.buildWith(Ships[shipId].defaults);
|
opponent.buildWith(Ships[shipId].defaults);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
engagementRange = parseInt(control[8]);
|
engagementRange = parseInt(control[8]) || engagementRange;
|
||||||
|
|
||||||
// Multi-crew pips were introduced later on so assign default values
|
// Multi-crew pips were introduced later on so assign default values
|
||||||
// because those values might not be present.
|
// because those values might not be present.
|
||||||
|
|||||||
@@ -81,8 +81,8 @@ export default class Module {
|
|||||||
// the amount of base resistance the hrp has.
|
// the amount of base resistance the hrp has.
|
||||||
if (!isNaN(result) && this.grp === 'hr' &&
|
if (!isNaN(result) && this.grp === 'hr' &&
|
||||||
(name === 'kinres' || name === 'thermres' || name === 'explres')) {
|
(name === 'kinres' || name === 'thermres' || name === 'explres')) {
|
||||||
let baseRes = this[name];
|
let baseRes = this[name];
|
||||||
result = result * (1 - baseRes);
|
result = result * (1 - baseRes);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sanitise the resultant value to 4dp equivalent
|
// Sanitise the resultant value to 4dp equivalent
|
||||||
@@ -180,7 +180,7 @@ export default class Module {
|
|||||||
modValue = value - baseValue;
|
modValue = value - baseValue;
|
||||||
if (this.grp === 'hr' &&
|
if (this.grp === 'hr' &&
|
||||||
(name === 'kinres' || name === 'thermres' || name === 'explres')) {
|
(name === 'kinres' || name === 'thermres' || name === 'explres')) {
|
||||||
modValue = modValue / (1 - baseValue);
|
modValue = modValue / (1 - baseValue);
|
||||||
}
|
}
|
||||||
} else if (name === 'shieldboost' || name === 'hullboost') {
|
} else if (name === 'shieldboost' || name === 'hullboost') {
|
||||||
modValue = (1 + value) / (1 + baseValue) - 1;
|
modValue = (1 + value) / (1 + baseValue) - 1;
|
||||||
@@ -192,7 +192,7 @@ export default class Module {
|
|||||||
modValue = modValue * 10000;
|
modValue = modValue * 10000;
|
||||||
} else if (modification.type === 'numeric' && name !== 'burst' &&
|
} else if (modification.type === 'numeric' && name !== 'burst' &&
|
||||||
name !== 'burstrof') {
|
name !== 'burstrof') {
|
||||||
modValue = modValue * 100;
|
modValue = modValue * 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setModValue(name, modValue, valueIsWithSpecial);
|
this.setModValue(name, modValue, valueIsWithSpecial);
|
||||||
@@ -242,38 +242,38 @@ export default class Module {
|
|||||||
const modification = Modifications.modifications[name];
|
const modification = Modifications.modifications[name];
|
||||||
let result = this[name];
|
let result = this[name];
|
||||||
|
|
||||||
if (modification) {
|
if (modification) {
|
||||||
// We store percentages as decimals, so to get them back we need to divide by 10000. Otherwise
|
// We store percentages as decimals, so to get them back we need to divide by 10000. Otherwise
|
||||||
// we divide by 100. Both ways we end up with a value with two decimal places
|
// we divide by 100. Both ways we end up with a value with two decimal places
|
||||||
let modValue;
|
let modValue;
|
||||||
if (modification.type === 'percentage') {
|
if (modification.type === 'percentage') {
|
||||||
modValue = this.getModValue(name) / 10000;
|
modValue = this.getModValue(name) / 10000;
|
||||||
} else if (modification.type === 'numeric') {
|
} else if (modification.type === 'numeric') {
|
||||||
modValue = this.getModValue(name) / 100;
|
modValue = this.getModValue(name) / 100;
|
||||||
} else {
|
} else {
|
||||||
modValue = this.getModValue(name);
|
modValue = this.getModValue(name);
|
||||||
|
}
|
||||||
|
if (modValue) {
|
||||||
|
if (!result && modification.method === 'additive') {
|
||||||
|
// If the modification is additive and no value is given by default we
|
||||||
|
// start at zero
|
||||||
|
result = 0;
|
||||||
}
|
}
|
||||||
if (modValue) {
|
|
||||||
if (!result && modification.method === 'additive') {
|
|
||||||
// If the modification is additive and no value is given by default we
|
|
||||||
// start at zero
|
|
||||||
result = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result !== undefined) {
|
if (result !== undefined) {
|
||||||
if (modification.method === 'additive') {
|
if (modification.method === 'additive') {
|
||||||
result = result + modValue;
|
result = result + modValue;
|
||||||
} else if (modification.method === 'overwrite') {
|
} else if (modification.method === 'overwrite') {
|
||||||
result = modValue;
|
result = modValue;
|
||||||
} else if (name === 'shieldboost' || name === 'hullboost') {
|
} else if (name === 'shieldboost' || name === 'hullboost') {
|
||||||
result = (1 + result) * (1 + modValue) - 1;
|
result = (1 + result) * (1 + modValue) - 1;
|
||||||
} else {
|
} else {
|
||||||
result = result * (1 + modValue);
|
result = result * (1 + modValue);
|
||||||
}
|
}
|
||||||
} else if (name === 'burst' || name === 'burstrof') {
|
} else if (name === 'burstrof') {
|
||||||
// Burst and burst rate of fire are special, as it can not exist but
|
// Burst and burst rate of fire are special, as it can not exist but
|
||||||
// have a modification
|
// have a modification
|
||||||
result = modValue / 100;
|
result = modValue / 100;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1187,28 +1187,28 @@ export default class Ship {
|
|||||||
// handle unladen mass
|
// handle unladen mass
|
||||||
unladenMass += chain(slots)
|
unladenMass += chain(slots)
|
||||||
.map(slot => slot.m ? slot.m.get('mass') : null)
|
.map(slot => slot.m ? slot.m.get('mass') : null)
|
||||||
.filter()
|
.map(mass => mass || 0)
|
||||||
.reduce((sum, mass) => sum + mass)
|
.reduce((sum, mass) => sum + mass)
|
||||||
.value();
|
.value();
|
||||||
|
|
||||||
// handle fuel capacity
|
// handle fuel capacity
|
||||||
fuelCapacity += chain(slots)
|
fuelCapacity += chain(slots)
|
||||||
.map(slot => slot.m ? slot.m.get('fuel') : null)
|
.map(slot => slot.m ? slot.m.get('fuel') : null)
|
||||||
.filter()
|
.map(fuel => fuel || 0)
|
||||||
.reduce((sum, fuel) => sum + fuel)
|
.reduce((sum, fuel) => sum + fuel)
|
||||||
.value();
|
.value();
|
||||||
|
|
||||||
// handle cargo capacity
|
// handle cargo capacity
|
||||||
cargoCapacity += chain(slots)
|
cargoCapacity += chain(slots)
|
||||||
.map(slot => slot.m ? slot.m.get('cargo') : null)
|
.map(slot => slot.m ? slot.m.get('cargo') : null)
|
||||||
.filter()
|
.map(cargo => cargo || 0)
|
||||||
.reduce((sum, cargo) => sum + cargo)
|
.reduce((sum, cargo) => sum + cargo)
|
||||||
.value();
|
.value();
|
||||||
|
|
||||||
// handle passenger capacity
|
// handle passenger capacity
|
||||||
passengerCapacity += chain(slots)
|
passengerCapacity += chain(slots)
|
||||||
.map(slot => slot.m ? slot.m.get('passengers') : null)
|
.map(slot => slot.m ? slot.m.get('passengers') : null)
|
||||||
.filter()
|
.map(passengers => passengers || 0)
|
||||||
.reduce((sum, passengers) => sum + passengers)
|
.reduce((sum, passengers) => sum + passengers)
|
||||||
.value();
|
.value();
|
||||||
|
|
||||||
|
|||||||
@@ -147,80 +147,77 @@ export function shipFromLoadoutJSON(json) {
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
for (const module of json.Modules) {
|
if (module.Slot.toLowerCase().search(/hardpoint/) !== -1) {
|
||||||
if (module.Slot.toLowerCase().search(/hardpoint/) !== -1) {
|
// Add hardpoints
|
||||||
// Add hardpoints
|
let hardpoint;
|
||||||
let hardpoint;
|
let hardpointClassNum = -1;
|
||||||
let hardpointClassNum = -1;
|
let hardpointSlotNum = -1;
|
||||||
let hardpointSlotNum = -1;
|
let hardpointArrayNum = 0;
|
||||||
let hardpointArrayNum = 0;
|
for (let i in shipTemplate.slots.hardpoints) {
|
||||||
for (let i in shipTemplate.slots.hardpoints) {
|
if (shipTemplate.slots.hardpoints[i] === hardpointClassNum) {
|
||||||
if (shipTemplate.slots.hardpoints[i] === hardpointClassNum) {
|
// Another slot of the same class
|
||||||
// Another slot of the same class
|
hardpointSlotNum++;
|
||||||
hardpointSlotNum++;
|
} else {
|
||||||
} else {
|
// The first slot of a new class
|
||||||
// The first slot of a new class
|
hardpointClassNum = shipTemplate.slots.hardpoints[i];
|
||||||
hardpointClassNum = shipTemplate.slots.hardpoints[i];
|
hardpointSlotNum = 1;
|
||||||
hardpointSlotNum = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now that we know what we're looking for, find it
|
|
||||||
const hardpointName = HARDPOINT_NUM_TO_CLASS[hardpointClassNum] + 'Hardpoint' + hardpointSlotNum;
|
|
||||||
const hardpointSlot = json.Modules.find(elem => elem.Slot.toLowerCase() === hardpointName.toLowerCase());
|
|
||||||
if (!hardpointSlot) {
|
|
||||||
// This can happen with old imports that don't contain new hardpoints
|
|
||||||
} else if (!hardpointSlot) {
|
|
||||||
// No module
|
|
||||||
} else {
|
|
||||||
hardpoint = _moduleFromFdName(hardpointSlot.Item);
|
|
||||||
ship.use(ship.hardpoints[hardpointArrayNum], hardpoint, true);
|
|
||||||
ship.hardpoints[hardpointArrayNum].enabled = hardpointSlot.On;
|
|
||||||
ship.hardpoints[hardpointArrayNum].priority = hardpointSlot.Priority;
|
|
||||||
modsToAdd.push({ coriolisMod: hardpoint, json: hardpointSlot });
|
|
||||||
}
|
|
||||||
hardpointArrayNum++;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (module.Slot.toLowerCase().search(/slot\d/) !== -1) {
|
|
||||||
let internalSlotNum = 1;
|
|
||||||
let militarySlotNum = 1;
|
|
||||||
for (let i in shipTemplate.slots.internal) {
|
|
||||||
if (!shipTemplate.slots.internal.hasOwnProperty(i)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const isMilitary = isNaN(shipTemplate.slots.internal[i]) ? shipTemplate.slots.internal[i].name = 'military' : false;
|
|
||||||
|
|
||||||
// The internal slot might be a standard or a military slot. Military slots have a different naming system
|
// Now that we know what we're looking for, find it
|
||||||
let internalSlot = null;
|
const hardpointName = HARDPOINT_NUM_TO_CLASS[hardpointClassNum] + 'Hardpoint' + hardpointSlotNum;
|
||||||
if (isMilitary) {
|
const hardpointSlot = json.Modules.find(elem => elem.Slot.toLowerCase() === hardpointName.toLowerCase());
|
||||||
const internalName = 'Military0' + militarySlotNum;
|
if (!hardpointSlot) {
|
||||||
internalSlot = json.Modules.find(elem => elem.Slot.toLowerCase() === internalName.toLowerCase());
|
// This can happen with old imports that don't contain new hardpoints
|
||||||
militarySlotNum++;
|
} else if (!hardpointSlot) {
|
||||||
} else {
|
// No module
|
||||||
// Slot numbers are not contiguous so handle skips.
|
} else {
|
||||||
while (internalSlot === null && internalSlotNum < 99) {
|
hardpoint = _moduleFromFdName(hardpointSlot.Item);
|
||||||
// Slot sizes have no relationship to the actual size, either, so check all possibilities
|
ship.use(ship.hardpoints[hardpointArrayNum], hardpoint, true);
|
||||||
for (let slotsize = 0; slotsize < 9; slotsize++) {
|
ship.hardpoints[hardpointArrayNum].enabled = hardpointSlot.On;
|
||||||
const internalName = 'Slot' + (internalSlotNum <= 9 ? '0' : '0') + internalSlotNum + '_Size' + slotsize;
|
ship.hardpoints[hardpointArrayNum].priority = hardpointSlot.Priority;
|
||||||
if (json.Modules.find(elem => elem.Slot.toLowerCase() === internalName.toLowerCase())) {
|
modsToAdd.push({ coriolisMod: hardpoint, json: hardpointSlot });
|
||||||
internalSlot = json.Modules.find(elem => elem.Slot.toLowerCase() === internalName.toLowerCase());
|
}
|
||||||
break;
|
hardpointArrayNum++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (module.Slot.toLowerCase().search(/slot\d/) !== -1) {
|
||||||
|
let internalSlotNum = 0;
|
||||||
|
let militarySlotNum = 1;
|
||||||
|
for (let i in shipTemplate.slots.internal) {
|
||||||
|
if (!shipTemplate.slots.internal.hasOwnProperty(i)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const isMilitary = isNaN(shipTemplate.slots.internal[i]) ? shipTemplate.slots.internal[i].name == 'military' : false;
|
||||||
|
|
||||||
|
// The internal slot might be a standard or a military slot. Military slots have a different naming system
|
||||||
|
let internalSlot = null;
|
||||||
|
if (isMilitary) {
|
||||||
|
const internalName = 'Military0' + militarySlotNum;
|
||||||
|
internalSlot = json.Modules.find(elem => elem.Slot.toLowerCase() === internalName.toLowerCase());
|
||||||
|
militarySlotNum++;
|
||||||
|
} else {
|
||||||
|
// Slot numbers are not contiguous so handle skips.
|
||||||
|
for (; internalSlot === null && internalSlotNum < 99; internalSlotNum++) {
|
||||||
|
// Slot sizes have no relationship to the actual size, either, so check all possibilities
|
||||||
|
for (let slotsize = 0; slotsize < 9; slotsize++) {
|
||||||
|
const internalName = 'Slot' + (internalSlotNum <= 9 ? '0' : '') + internalSlotNum + '_Size' + slotsize;
|
||||||
|
if (json.Modules.find(elem => elem.Slot.toLowerCase() === internalName.toLowerCase())) {
|
||||||
|
internalSlot = json.Modules.find(elem => elem.Slot.toLowerCase() === internalName.toLowerCase());
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
internalSlotNum++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!internalSlot) {
|
if (!internalSlot) {
|
||||||
// This can happen with old imports that don't contain new slots
|
// This can happen with old imports that don't contain new slots
|
||||||
} else {
|
} else {
|
||||||
const internalJson = internalSlot;
|
const internalJson = internalSlot;
|
||||||
const internal = _moduleFromFdName(internalJson.Item);
|
const internal = _moduleFromFdName(internalJson.Item);
|
||||||
ship.use(ship.internal[i], internal, true);
|
ship.use(ship.internal[i], internal, true);
|
||||||
ship.internal[i].enabled = internalJson.On === true;
|
ship.internal[i].enabled = internalJson.On === true;
|
||||||
ship.internal[i].priority = internalJson.Priority;
|
ship.internal[i].priority = internalJson.Priority;
|
||||||
modsToAdd.push({ coriolisMod: internal, json: internalSlot });
|
modsToAdd.push({ coriolisMod: internal, json: internalSlot });
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,7 +74,7 @@
|
|||||||
border-color:#fff;
|
border-color:#fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
input:disabled {
|
input.greyed-out {
|
||||||
border-color: #888;
|
border-color: #888;
|
||||||
color: #888;
|
color: #888;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user