mirror of
https://github.com/EDCD/coriolis.git
synced 2025-12-09 14:45:35 +00:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0a37b36ec2 | ||
|
|
85e6796e88 | ||
|
|
fa1ef47b71 | ||
|
|
f31e3c09f4 | ||
|
|
e6ab536601 | ||
|
|
5bced9fe56 | ||
|
|
67742060d3 | ||
|
|
ca2136544c | ||
|
|
ee19e9af50 | ||
|
|
f457fd0bff | ||
|
|
c1ce07e039 | ||
|
|
c8d1536f77 | ||
|
|
231ad4af59 |
@@ -1,3 +1,12 @@
|
||||
#2.2.5
|
||||
* Calculate rate of fire for multi-burst weapons
|
||||
* Add note to disable ghostery in error situation
|
||||
* Use coriolis-data 2.2.5:
|
||||
* Fix incorrect ID for emissive munitions special
|
||||
* Fix rate of fire for burst lasers
|
||||
* Add fragment cannon modifications
|
||||
* Fix internal name of dazzle shell
|
||||
|
||||
#2.2.4
|
||||
* Add shortlink for outfitting page
|
||||
* Use coriolis-data 2.2.4:
|
||||
|
||||
@@ -271,7 +271,7 @@
|
||||
"totalExplDpe": 0,
|
||||
"totalExplDps": 0,
|
||||
"totalExplSDps": 0,
|
||||
"totalHps": 33.28,
|
||||
"totalHps": 33.62,
|
||||
"totalKinDpe": 103.97,
|
||||
"totalKinDps": 28.92,
|
||||
"totalKinSDps": 21.23,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "coriolis_shipyard",
|
||||
"version": "2.2.4",
|
||||
"version": "2.2.5",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/EDCD/coriolis"
|
||||
|
||||
@@ -8,7 +8,7 @@ import Header from './components/Header';
|
||||
import Tooltip from './components/Tooltip';
|
||||
import ModalImport from './components/ModalImport';
|
||||
import * as CompanionApiUtils from './utils/CompanionApiUtils';
|
||||
import { outfitURL } from './utils/UrlGenerators'
|
||||
import { outfitURL } from './utils/UrlGenerators';
|
||||
|
||||
import AboutPage from './pages/AboutPage';
|
||||
import NotFoundPage from './pages/NotFoundPage';
|
||||
|
||||
@@ -72,7 +72,7 @@ export default class ComparisonTable extends TranslatedComponent {
|
||||
* @return {React.Component} Table row
|
||||
*/
|
||||
_buildRow(build, facets, formats, units) {
|
||||
let url = outfitURL(build.id, build.toString(), build.buildName)
|
||||
let url = outfitURL(build.id, build.toString(), build.buildName);
|
||||
let cells = [
|
||||
<td key='s' className='tl'><Link href={url}>{build.name}</Link></td>,
|
||||
<td key='bn' className='tl'><Link href={url}>{build.buildName}</Link></td>
|
||||
|
||||
@@ -48,22 +48,22 @@ export default class HardpointSlot extends Slot {
|
||||
let modTT = translate('modified');
|
||||
if (m && m.blueprint) {
|
||||
modTT = translate(m.blueprint.name) + ' ' + translate('grade') + ' ' + m.blueprint.grade;
|
||||
if (m.blueprint.special && m.blueprint.special.id) {
|
||||
if (m.blueprint.special && m.blueprint.special.id) {
|
||||
modTT += ', ' + translate(m.blueprint.special.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return <div className='details' draggable='true' onDragStart={drag} onDragEnd={drop}>
|
||||
<div className={'cb'}>
|
||||
<div className={'l'}>
|
||||
{m.mount && m.mount == 'F' ? <span onMouseOver={termtip.bind(null, 'fixed')} onMouseOut={tooltip.bind(null, null)}><MountFixed /></span> : ''}
|
||||
{m.mount && m.mount == 'G' ? <span onMouseOver={termtip.bind(null, 'gimballed')} onMouseOut={tooltip.bind(null, null)}><MountGimballed /></span> : ''}
|
||||
{m.mount && m.mount == 'T' ? <span onMouseOver={termtip.bind(null, 'turreted')} onMouseOut={tooltip.bind(null, null)}><MountTurret /></span> : ''}
|
||||
{m.getDamageType() && m.getDamageType().match('K') ? <span onMouseOver={termtip.bind(null, 'kinetic')} onMouseOut={tooltip.bind(null, null)}><DamageKinetic /></span> : ''}
|
||||
{m.getDamageType() && m.getDamageType().match('T') ? <span onMouseOver={termtip.bind(null, 'thermal')} onMouseOut={tooltip.bind(null, null)}><DamageThermal /></span> : ''}
|
||||
{m.getDamageType() && m.getDamageType().match('E') ? <span onMouseOver={termtip.bind(null, 'explosive')} onMouseOut={tooltip.bind(null, null)}><DamageExplosive /></span> : ''}
|
||||
{m.mount && m.mount == 'F' ? <span onMouseOver={termtip.bind(null, 'fixed')} onMouseOut={tooltip.bind(null, null)}><MountFixed /></span> : ''}
|
||||
{m.mount && m.mount == 'G' ? <span onMouseOver={termtip.bind(null, 'gimballed')} onMouseOut={tooltip.bind(null, null)}><MountGimballed /></span> : ''}
|
||||
{m.mount && m.mount == 'T' ? <span onMouseOver={termtip.bind(null, 'turreted')} onMouseOut={tooltip.bind(null, null)}><MountTurret /></span> : ''}
|
||||
{m.getDamageType() && m.getDamageType().match('K') ? <span onMouseOver={termtip.bind(null, 'kinetic')} onMouseOut={tooltip.bind(null, null)}><DamageKinetic /></span> : ''}
|
||||
{m.getDamageType() && m.getDamageType().match('T') ? <span onMouseOver={termtip.bind(null, 'thermal')} onMouseOut={tooltip.bind(null, null)}><DamageThermal /></span> : ''}
|
||||
{m.getDamageType() && m.getDamageType().match('E') ? <span onMouseOver={termtip.bind(null, 'explosive')} onMouseOut={tooltip.bind(null, null)}><DamageExplosive /></span> : ''}
|
||||
{classRating} {translate(m.name || m.grp)}{ m.mods && Object.keys(m.mods).length > 0 ? <span className='r' onMouseOver={termtip.bind(null, modTT)} onMouseOut={tooltip.bind(null, null)}><Modified /></span> : null }
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={'r'}>{formats.round(m.getMass())}{u.T}</div>
|
||||
</div>
|
||||
|
||||
@@ -346,6 +346,7 @@ export default class ModalImport extends TranslatedComponent {
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// console.log(e.stack);
|
||||
this.setState({ errorMsg: (typeof e == 'string') ? e : 'Cannot Parse the data!' });
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -63,9 +63,24 @@ export default class Modification extends TranslatedComponent {
|
||||
let translate = this.context.language.translate;
|
||||
let name = this.props.name;
|
||||
|
||||
if (name === 'type') {
|
||||
// We don't show type
|
||||
return null;
|
||||
}
|
||||
|
||||
let symbol;
|
||||
if (name === 'jitter') {
|
||||
symbol = '°';
|
||||
} else if (name !== 'burst') {
|
||||
symbol = '%';
|
||||
}
|
||||
if (symbol) {
|
||||
symbol = ' (' + symbol + ')';
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={'cb'} key={name}>
|
||||
<div className={'cb'}>{translate(name)}{name === 'jitter' ? ' (°)' : ' (%)'}</div>
|
||||
<div className={'cb'}>{translate(name)}{symbol}</div>
|
||||
<NumberEditor className={'cb'} style={{ width: '90%', textAlign: 'center' }} step={0.01} stepModifier={1} decimals={2} value={this.state.value} onValueChange={this._updateValue.bind(this)} />
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -42,6 +42,7 @@ export default class ErrorDetails extends React.Component {
|
||||
return <div className='error'>
|
||||
<h1>Jameson, we have a problem..</h1>
|
||||
<h1><small>{error.message}</small></h1>
|
||||
<div>Please note that this site uses Google Analytics to track performance and usage. If you are blocking cookies, for example using Ghostery, please disable blocking for this site and try again.</div>
|
||||
{content}
|
||||
</div>;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import * as ModuleUtils from './ModuleUtils';
|
||||
import * as _ from 'lodash';
|
||||
import { Modifications } from 'coriolis-data/dist';
|
||||
|
||||
/**
|
||||
* Module - active module in a ship's buildout
|
||||
@@ -65,8 +66,20 @@ export default class Module {
|
||||
_getModifiedValue(name, additive) {
|
||||
let result = this[name] || (additive ? 0 : null); // Additive NULL === 0
|
||||
if (result != null) {
|
||||
// Jitter is special, being the only non-percentage value (it is in fact degrees)
|
||||
const modValue = name === 'jitter' ? this.getModValue(name) / 100 : this.getModValue(name) / 10000;
|
||||
const modification = Modifications.modifications[name];
|
||||
if (!modification) {
|
||||
return result;
|
||||
}
|
||||
// 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
|
||||
let modValue;
|
||||
if (modification.type === 'percentage') {
|
||||
modValue = this.getModValue(name) / 10000;
|
||||
} else if (modification.type === 'numeric') {
|
||||
modValue = this.getModValue(name) / 100;
|
||||
} else {
|
||||
modValue = this.getModValue(name);
|
||||
}
|
||||
if (modValue) {
|
||||
if (additive) {
|
||||
result = result + modValue;
|
||||
@@ -74,7 +87,18 @@ export default class Module {
|
||||
result = result * (1 + modValue);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (name === 'burst') {
|
||||
// Burst is special, as if it can not exist but have a modification
|
||||
const modValue = this.getModValue(name) / 100;
|
||||
return modValue;
|
||||
} else if (name === 'burstrof') {
|
||||
// Burst rate of fire is special, as if it can not exist but have a modification
|
||||
const modValue = this.getModValue(name) / 100;
|
||||
return modValue;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -425,7 +449,7 @@ export default class Module {
|
||||
getDps() {
|
||||
// DPS is a synthetic value
|
||||
let damage = this.getDamage();
|
||||
let rpshot = this.getRoundsPerShot() || 1;
|
||||
let rpshot = this.roundspershot || 1;
|
||||
let rof = this.getRoF() || 1;
|
||||
|
||||
return damage * rpshot * rof;
|
||||
@@ -438,7 +462,7 @@ export default class Module {
|
||||
getEps() {
|
||||
// EPS is a synthetic value
|
||||
let distdraw = this.getDistDraw();
|
||||
let rpshot = this.getRoundsPerShot() || 1;
|
||||
let rpshot = this.roundspershot || 1;
|
||||
let rof = this.getRoF() || 1;
|
||||
|
||||
return distdraw * rpshot * rof;
|
||||
@@ -451,7 +475,7 @@ export default class Module {
|
||||
getHps() {
|
||||
// HPS is a synthetic value
|
||||
let heat = this.getThermalLoad();
|
||||
let rpshot = this.getRoundsPerShot() || 1;
|
||||
let rpshot = this.roundspershot || 1;
|
||||
let rof = this.getRoF() || 1;
|
||||
|
||||
return heat * rpshot * rof;
|
||||
@@ -482,11 +506,35 @@ export default class Module {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rate of fire for this module, taking in to account modifications
|
||||
* Get the burst size for this module, taking in to account modifications
|
||||
* @return {Number} the burst size of this module
|
||||
*/
|
||||
getBurst() {
|
||||
return this._getModifiedValue('burst');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the burst rate of fire for this module, taking in to account modifications
|
||||
* @return {Number} the burst rate of fire of this module
|
||||
*/
|
||||
getBurstRoF() {
|
||||
return this._getModifiedValue('burstrof');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rate of fire for this module, taking in to account modifications.
|
||||
* The rate of fire is a combination value, and needs to take in to account
|
||||
* bursts of fire.
|
||||
* Firing goes [burst 1] [burst interval] [burst 2] [burst interval] ... [burst n] [interval]
|
||||
* where 'n' is 'burst', 'burst interval' is '1/burstrof' and 'interval' is '1/rof'
|
||||
* @return {Number} the rate of fire for this module
|
||||
*/
|
||||
getRoF() {
|
||||
return this._getModifiedValue('rof');
|
||||
const burst = this.getBurst() || 1;
|
||||
const burstRoF = this.getBurstRoF() || 1;
|
||||
const intRoF = this._getModifiedValue('rof');
|
||||
|
||||
return burst / (((burst - 1) / burstRoF) + 1 / intRoF);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -8,7 +8,7 @@ import { outfitURL } from '../utils/UrlGenerators';
|
||||
|
||||
const STANDARD = ['powerPlant', 'thrusters', 'frameShiftDrive', 'lifeSupport', 'powerDistributor', 'sensors', 'fuelTank'];
|
||||
|
||||
const STANDARD_GROUPS = {'powerPlant': 'pp', 'thrusters': 't', 'frameShiftDrive': 'fsd', 'lifeSupport': 'ls', 'powerDistributor': 'pd', 'sensors': 's', 'fuelTank': 'ft'};
|
||||
const STANDARD_GROUPS = { 'powerPlant': 'pp', 'thrusters': 't', 'frameShiftDrive': 'fsd', 'lifeSupport': 'ls', 'powerDistributor': 'pd', 'sensors': 's', 'fuelTank': 'ft' };
|
||||
|
||||
/**
|
||||
* Generates ship-loadout JSON Schema standard object
|
||||
|
||||
@@ -458,7 +458,7 @@ export default class Ship {
|
||||
} else if (name === 'shieldreinforcement') {
|
||||
m.setModValue(name, value);
|
||||
this.recalculateShieldCells();
|
||||
} else if (name === 'burst' || name === 'clip' || name === 'damage' || name === 'distdraw' || name === 'jitter' || name === 'piercing' || name === 'range' || name === 'reload' || name === 'rof' || name === 'thermload') {
|
||||
} else if (name === 'burst' || name == 'burstrof' || name === 'clip' || name === 'damage' || name === 'distdraw' || name === 'jitter' || name === 'piercing' || name === 'range' || name === 'reload' || name === 'rof' || name === 'thermload') {
|
||||
m.setModValue(name, value);
|
||||
this.recalculateDps();
|
||||
this.recalculateHps();
|
||||
@@ -1260,7 +1260,7 @@ export default class Ship {
|
||||
let modElements = mods[j].split(':');
|
||||
if (modElements[0].match('[0-9]+')) {
|
||||
const modification = _.find(Modifications.modifications, function(o) { return o.id === modElements[0]; });
|
||||
if (modification != null) arr[i][modification.name] = Number(modElements[1]);
|
||||
if (modification != null) arr[i][modification.name] = Number(modElements[1]);
|
||||
} else {
|
||||
arr[i][modElements[0]] = Number(modElements[1]);
|
||||
}
|
||||
@@ -1297,7 +1297,7 @@ export default class Ship {
|
||||
bulkheadBlueprint = this.bulkheads.m.blueprint;
|
||||
}
|
||||
slots.push(bulkheadMods);
|
||||
blueprints.push(bulkheadBlueprint)
|
||||
blueprints.push(bulkheadBlueprint);
|
||||
specials.push(bulkheadBlueprint ? bulkheadBlueprint.special : null);
|
||||
|
||||
for (let slot of this.standard) {
|
||||
@@ -1356,7 +1356,7 @@ export default class Ship {
|
||||
for (let special of specials) {
|
||||
if (special) {
|
||||
// Length is 5 for each special
|
||||
bufsize += 5;
|
||||
bufsize += 5;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1376,20 +1376,20 @@ export default class Ship {
|
||||
buffer.writeInt8(MODIFICATION_ID_GRADE, curpos++);
|
||||
buffer.writeInt32LE(blueprints[i].grade, curpos);
|
||||
curpos += 4;
|
||||
}
|
||||
}
|
||||
if (specials[i]) {
|
||||
buffer.writeInt8(MODIFICATION_ID_SPECIAL, curpos++);
|
||||
buffer.writeInt32LE(specials[i].id, curpos);
|
||||
curpos += 4;
|
||||
}
|
||||
}
|
||||
for (let slotMod of slot) {
|
||||
buffer.writeInt8(slotMod.id, curpos++);
|
||||
if (isNaN(slotMod.value)) {
|
||||
// Need to write the string with exactly four characters, so pad with whitespace
|
||||
buffer.write((" " + slotMod.value).slice(-4), curpos, 4);
|
||||
} else {
|
||||
buffer.writeInt32LE(slotMod.value, curpos);
|
||||
}
|
||||
if (isNaN(slotMod.value)) {
|
||||
// Need to write the string with exactly four characters, so pad with whitespace
|
||||
buffer.write((' ' + slotMod.value).slice(-4), curpos, 4);
|
||||
} else {
|
||||
buffer.writeInt32LE(slotMod.value, curpos);
|
||||
}
|
||||
// const modification = _.find(Modifications.modifications, function(o) { return o.id === slotMod.id; });
|
||||
// console.log('ENCODE Slot ' + i + ': ' + modification.name + ' = ' + slotMod.value);
|
||||
curpos += 4;
|
||||
@@ -1414,7 +1414,7 @@ export default class Ship {
|
||||
* See updateModificationsString() for details of the structure.
|
||||
* @param {String} buffer Buffer holding modification info
|
||||
* @param {Array} modArr Modification array
|
||||
* @param {Array} bluprintArr Blueprint array
|
||||
* @param {Array} blueprintArr Blueprint array
|
||||
*/
|
||||
decodeModificationsStruct(buffer, modArr, blueprintArr) {
|
||||
let curpos = 0;
|
||||
@@ -1428,22 +1428,22 @@ export default class Ship {
|
||||
if (modificationId === 40) {
|
||||
// Type is special, in that it's a character string
|
||||
modificationValue = buffer.toString('utf8', curpos, curpos + 4).trim();
|
||||
} else {
|
||||
} else {
|
||||
modificationValue = buffer.readInt32LE(curpos);
|
||||
}
|
||||
}
|
||||
curpos += 4;
|
||||
// There are a number of 'special' modification IDs, check for them here
|
||||
if (modificationId === MODIFICATION_ID_BLUEPRINT) {
|
||||
// There are a number of 'special' modification IDs, check for them here
|
||||
if (modificationId === MODIFICATION_ID_BLUEPRINT) {
|
||||
blueprint = Object.assign(blueprint, _.find(Modifications.blueprints, function(o) { return o.id === modificationValue; }));
|
||||
} else if (modificationId === MODIFICATION_ID_GRADE) {
|
||||
} else if (modificationId === MODIFICATION_ID_GRADE) {
|
||||
blueprint.grade = modificationValue;
|
||||
} else if (modificationId === MODIFICATION_ID_SPECIAL) {
|
||||
} else if (modificationId === MODIFICATION_ID_SPECIAL) {
|
||||
blueprint.special = _.find(Modifications.specials, function(o) { return o.id === modificationValue; });
|
||||
} else {
|
||||
} else {
|
||||
const modification = _.find(Modifications.modifications, function(o) { return o.id === modificationId; });
|
||||
// console.log('DECODE Slot ' + slot + ': ' + modification.name + ' = ' + modificationValue);
|
||||
modifications[modification.name] = modificationValue;
|
||||
}
|
||||
}
|
||||
modificationId = buffer.readInt8(curpos++);
|
||||
}
|
||||
modArr[slot] = modifications;
|
||||
|
||||
@@ -277,29 +277,43 @@ export function shipFromJson(json) {
|
||||
function _addModifications(module, modifiers, blueprint, grade) {
|
||||
if (!modifiers || !modifiers.modifiers) return;
|
||||
|
||||
var special;
|
||||
let special;
|
||||
for (const i in modifiers.modifiers) {
|
||||
// Look up the modifiers to find what we need to do
|
||||
const modifierActions = Modifications.modifierActions[modifiers.modifiers[i].name];
|
||||
const value = modifiers.modifiers[i].value;
|
||||
// Some special modifications
|
||||
if (modifiers.modifiers[i].name === 'mod_weapon_clip_size_override') {
|
||||
// This is a numeric addition to the clip size, but we need to work it out in terms of being a percentage so
|
||||
// that it works the same as other modifications
|
||||
const origClip = module.clip || 1;
|
||||
module.setModValue('clip', ((modifiers.modifiers[i].value - origClip) / origClip) * 10000);
|
||||
} else if (modifiers.modifiers[i].name === 'mod_weapon_burst_size') {
|
||||
// This is an absolute number that acts as an override
|
||||
module.setModValue('burst', modifiers.modifiers[i].value * 100);
|
||||
} else if (modifiers.modifiers[i].name === 'mod_weapon_burst_rof') {
|
||||
// For some reason this is a non-normalised percentage (i.e. 12.23% is 12.23 value rather than 0.1223 as everywhere else), so fix that here
|
||||
module.setModValue('burstrof', modifiers.modifiers[i].value * 100);
|
||||
} else {
|
||||
// Look up the modifiers to find what we need to do
|
||||
const modifierActions = Modifications.modifierActions[modifiers.modifiers[i].name];
|
||||
const value = modifiers.modifiers[i].value;
|
||||
|
||||
// Carry out the required changes
|
||||
for (const action in modifierActions) {
|
||||
if (isNaN(modifierActions[action])) {
|
||||
module.setModValue(action, modifierActions[action]);
|
||||
} else {
|
||||
const actionValue = modifierActions[action] * value;
|
||||
let mod = module.getModValue(action) / 10000;
|
||||
if (!mod) {
|
||||
mod = 0;
|
||||
// Carry out the required changes
|
||||
for (const action in modifierActions) {
|
||||
if (isNaN(modifierActions[action])) {
|
||||
module.setModValue(action, modifierActions[action]);
|
||||
} else {
|
||||
const actionValue = modifierActions[action] * value;
|
||||
let mod = module.getModValue(action) / 10000;
|
||||
if (!mod) {
|
||||
mod = 0;
|
||||
}
|
||||
module.setModValue(action, ((1 + mod) * (1 + actionValue) - 1) * 10000);
|
||||
}
|
||||
module.setModValue(action, ((1 + mod) * (1 + actionValue) - 1) * 10000);
|
||||
}
|
||||
}
|
||||
|
||||
// Note the special if present
|
||||
if (modifiers.modifiers[i].name && modifiers.modifiers[i].name.startsWith('special_')) {
|
||||
special = Modifications.specials[modifiers.modifiers[i].name];
|
||||
special = Modifications.specials[modifiers.modifiers[i].name];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user