Merge branch 'release/2.3.3'

This commit is contained in:
Cmdr McDonald
2017-04-15 20:46:45 +01:00
6 changed files with 91 additions and 29 deletions

View File

@@ -1,3 +1,9 @@
#2.3.3
* Remove unused blueprint when hitting reset
* Add 'purchase module' external link to EDDB for refit items
* Use coriolis-data 2.3.3:
* Add Felicity Farseer to list of engineers that supply sensor and detailed surface scanner modifications
#2.3.2 #2.3.2
* Use scan range for DSS rather than scan time * Use scan range for DSS rather than scan time
* Fix companion API import of Dolphin * Fix companion API import of Dolphin

View File

@@ -1,6 +1,6 @@
{ {
"name": "coriolis_shipyard", "name": "coriolis_shipyard",
"version": "2.3.2", "version": "2.3.3",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/EDCD/coriolis" "url": "https://github.com/EDCD/coriolis"

View File

@@ -6,6 +6,7 @@ import Ship from '../shipyard/Ship';
import { Insurance } from '../shipyard/Constants'; import { Insurance } from '../shipyard/Constants';
import { slotName, slotComparator } from '../utils/SlotFunctions'; import { slotName, slotComparator } from '../utils/SlotFunctions';
import TranslatedComponent from './TranslatedComponent'; import TranslatedComponent from './TranslatedComponent';
import { ShoppingIcon } from '../components/SvgIcons';
/** /**
* Cost Section * Cost Section
@@ -31,6 +32,7 @@ export default class CostSection extends TranslatedComponent {
this._buildRetrofitShip = this._buildRetrofitShip.bind(this); this._buildRetrofitShip = this._buildRetrofitShip.bind(this);
this._onBaseRetrofitChange = this._onBaseRetrofitChange.bind(this); this._onBaseRetrofitChange = this._onBaseRetrofitChange.bind(this);
this._defaultRetrofitName = this._defaultRetrofitName.bind(this); this._defaultRetrofitName = this._defaultRetrofitName.bind(this);
this._eddbShoppingList = this._eddbShoppingList.bind(this);
let data = Ships[props.ship.id]; // Retrieve the basic ship properties, slots and defaults let data = Ships[props.ship.id]; // Retrieve the basic ship properties, slots and defaults
let retrofitName = this._defaultRetrofitName(props.ship.id, props.buildName); let retrofitName = this._defaultRetrofitName(props.ship.id, props.buildName);
@@ -325,12 +327,27 @@ export default class CostSection extends TranslatedComponent {
</div>; </div>;
} }
/**
* Open up a window for EDDB with a shopping list of our retrofit components
*/
_eddbShoppingList() {
const { retrofitCosts } = this.state;
const { ship } = this.props;
// Provide unique list of non-PP module EDDB IDs to buy
const modIds = retrofitCosts.filter(item => item.retroItem.incCost && item.buyId && !item.buyPp).map(item => item.buyId).filter((v, i, a) => a.indexOf(v) === i);
// Open up the relevant URL
window.open('https://eddb.io/station?m=' + modIds.join(','));
}
/** /**
* Render the retofit tab * Render the retofit tab
* @return {React.Component} Tab contents * @return {React.Component} Tab contents
*/ */
_retrofitTab() { _retrofitTab() {
let { retrofitTotal, retrofitCosts, moduleDiscount, retrofitName } = this.state; let { retrofitTotal, retrofitCosts, moduleDiscount, retrofitName } = this.state;
const { termtip, tooltip } = this.context;
let { translate, formats, units } = this.context.language; let { translate, formats, units } = this.context.language;
let int = formats.int; let int = formats.int;
let rows = [], options = [<option key='stock' value=''>{translate('Stock')}</option>]; let rows = [], options = [<option key='stock' value=''>{translate('Stock')}</option>];
@@ -370,7 +387,8 @@ export default class CostSection extends TranslatedComponent {
<tbody> <tbody>
{rows} {rows}
<tr className='ri'> <tr className='ri'>
<td colSpan='4' className='lbl' >{translate('cost')}</td> <td className='lbl' ><button onClick={this._eddbShoppingList} onMouseOver={termtip.bind(null, 'PHRASE_REFIT_SHOPPING_LIST')} onMouseOut={tooltip.bind(null, null)}><ShoppingIcon className='lg' style={{ fill: 'black' }}/></button></td>
<td colSpan='3' className='lbl' >{translate('cost')}</td>
<td colSpan='2' className={cn('val', retrofitTotal > 0 ? 'warning' : 'secondary-disabled')} style={{ borderBottom:'none' }}> <td colSpan='2' className={cn('val', retrofitTotal > 0 ? 'warning' : 'secondary-disabled')} style={{ borderBottom:'none' }}>
{int(retrofitTotal)}{units.CR} {int(retrofitTotal)}{units.CR}
</td> </td>
@@ -403,6 +421,8 @@ export default class CostSection extends TranslatedComponent {
if (ship.bulkheads.m.index != retrofitShip.bulkheads.m.index) { if (ship.bulkheads.m.index != retrofitShip.bulkheads.m.index) {
item = { item = {
buyClassRating: ship.bulkheads.m.class + ship.bulkheads.m.rating, buyClassRating: ship.bulkheads.m.class + ship.bulkheads.m.rating,
buyId: ship.bulkheads.m.eddbID,
buyPp: ship.bulkheads.m.pp,
buyName: ship.bulkheads.m.name, buyName: ship.bulkheads.m.name,
sellClassRating: retrofitShip.bulkheads.m.class + retrofitShip.bulkheads.m.rating, sellClassRating: retrofitShip.bulkheads.m.class + retrofitShip.bulkheads.m.rating,
sellName: retrofitShip.bulkheads.m.name, sellName: retrofitShip.bulkheads.m.name,
@@ -424,6 +444,8 @@ export default class CostSection extends TranslatedComponent {
if (modId != retroModId) { if (modId != retroModId) {
item = { netCost: 0, retroItem: retroSlotGroup[i] }; item = { netCost: 0, retroItem: retroSlotGroup[i] };
if (slotGroup[i].m) { if (slotGroup[i].m) {
item.buyId = slotGroup[i].m.eddbID,
item.buyPp = slotGroup[i].m.pp,
item.buyName = slotGroup[i].m.name || slotGroup[i].m.grp; item.buyName = slotGroup[i].m.name || slotGroup[i].m.grp;
item.buyClassRating = slotGroup[i].m.class + slotGroup[i].m.rating; item.buyClassRating = slotGroup[i].m.class + slotGroup[i].m.rating;
item.netCost = slotGroup[i].discountedCost; item.netCost = slotGroup[i].discountedCost;

View File

@@ -130,10 +130,10 @@ export default class ModificationsMenu extends TranslatedComponent {
*/ */
_blueprintSelected(fdname, grade) { _blueprintSelected(fdname, grade) {
this.context.tooltip(null); this.context.tooltip(null);
const { m } = this.props; const { m, ship } = this.props;
const blueprint = getBlueprint(fdname, m); const blueprint = getBlueprint(fdname, m);
blueprint.grade = grade; blueprint.grade = grade;
m.blueprint = blueprint; ship.setModuleBlueprint(m, blueprint);
this.setState({ blueprintMenuOpened: false }); this.setState({ blueprintMenuOpened: false });
this.props.onChange(); this.props.onChange();
@@ -155,15 +155,10 @@ export default class ModificationsMenu extends TranslatedComponent {
this.context.tooltip(null); this.context.tooltip(null);
const { m, ship } = this.props; const { m, ship } = this.props;
if (m.blueprint) {
if (special === null) { if (special === null) {
m.blueprint.special = null; ship.clearModuelSpecial(m);
} else { } else {
m.blueprint.special = Modifications.specials[special]; ship.setModuleSpecial(m, Modifications.specials[special]);
}
ship.recalculateDps();
ship.recalculateHps();
ship.recalculateEps();
} }
this.setState({ specialMenuOpened: false }); this.setState({ specialMenuOpened: false });
@@ -268,7 +263,7 @@ export default class ModificationsMenu extends TranslatedComponent {
_reset() { _reset() {
const { m, ship } = this.props; const { m, ship } = this.props;
ship.clearModifications(m); ship.clearModifications(m);
ship.clearBlueprint(m); ship.clearModuleBlueprint(m);
this.props.onChange(); this.props.onChange();
} }
@@ -294,7 +289,7 @@ export default class ModificationsMenu extends TranslatedComponent {
let blueprintLabel; let blueprintLabel;
let haveBlueprint = false; let haveBlueprint = false;
let blueprintTt; let blueprintTt;
if (m.blueprint && !isEmpty(m.blueprint)) { if (m.blueprint && m.blueprint.name) {
blueprintLabel = translate(m.blueprint.name) + ' ' + translate('grade') + ' ' + m.blueprint.grade; blueprintLabel = translate(m.blueprint.name) + ' ' + translate('grade') + ' ' + m.blueprint.grade;
haveBlueprint = true; haveBlueprint = true;
blueprintTt = blueprintTooltip(translate, m.blueprint.grades[m.blueprint.grade], Modifications.modules[m.grp].blueprints[m.blueprint.fdname].grades[m.blueprint.grade].engineers, m.grp); blueprintTt = blueprintTooltip(translate, m.blueprint.grades[m.blueprint.grade], Modifications.modules[m.grp].blueprints[m.blueprint.fdname].grades[m.blueprint.grade].engineers, m.grp);

View File

@@ -38,6 +38,7 @@ export const terms = {
PHRASE_SELECT_SPECIAL: 'Click to select an experimental effect', PHRASE_SELECT_SPECIAL: 'Click to select an experimental effect',
PHRASE_NO_SPECIAL: 'No experimental effect', PHRASE_NO_SPECIAL: 'No experimental effect',
PHRASE_SHOPPING_LIST: 'Stations that sell this build', PHRASE_SHOPPING_LIST: 'Stations that sell this build',
PHRASE_REFIT_SHOPPING_LIST: 'Stations that sell required modules',
PHRASE_TOTAL_EFFECTIVE_SHIELD: 'Total amount of damage that can be taken from each damage type, if using all shield cells', PHRASE_TOTAL_EFFECTIVE_SHIELD: 'Total amount of damage that can be taken from each damage type, if using all shield cells',
PHRASE_TIME_TO_LOSE_SHIELDS: 'Shields will hold for', PHRASE_TIME_TO_LOSE_SHIELDS: 'Shields will hold for',
PHRASE_TIME_TO_RECOVER_SHIELDS: 'Shields will recover in', PHRASE_TIME_TO_RECOVER_SHIELDS: 'Shields will recover in',

View File

@@ -429,11 +429,45 @@ export default class Ship {
} }
/** /**
* Clear blueprint for a module * Set blueprint for a module
* @param {Number} m The module for which to clear the modifications * @param {Object} m The module for which to set the blueprint
* @param {Object} bp The blueprint
*/ */
clearBlueprint(m) { setModuleBlueprint(m, bp) {
m.blueprint = bp;
this.updateModificationsString();
}
/**
* Clear blueprint for a module
* @param {Object} m The module for which to clear the blueprint
*/
clearModuleBlueprint(m) {
m.blueprint = {}; m.blueprint = {};
this.updateModificationsString();
}
/**
* Set special for a module
* @param {Object} m The module for which to set the blueprint
* @param {Object} special The special
*/
setModuleSpecial(m, special) {
if (m.blueprint) {
m.blueprint.special = special;
}
this.recalculateDps().recalculateHps().recalculateEps();
}
/**
* Clear special for a module
* @param {Object} m The module for which to clear the blueprint
*/
clearModuleSpecial(m) {
if (m.blueprint) {
m.blueprint.special = null;
}
this.recalculateDps().recalculateHps().recalculateEps();
} }
/** /**
@@ -1445,18 +1479,22 @@ export default class Ship {
// Now work out the size of the binary buffer from our modifications array // Now work out the size of the binary buffer from our modifications array
let bufsize = 0; let bufsize = 0;
for (let slot of slots) { for (let i = 0; i < slots.length; i++) {
if (slot.length > 0) { if (slots[i].length > 0 || (blueprints[i] && blueprints[i].id)) {
// Length is 1 for the slot ID, 10 for the blueprint name and grade, 5 for each modification, and 1 for the end marker // Length is 1 for the slot ID, 5 for each modification, and 1 for the end marker
bufsize = bufsize + 1 + 10 + (5 * slot.length) + 1; bufsize = bufsize + 1 + (5 * slots[i].length) + 1;
if (blueprints[i] && blueprints[i].id) {
// Additional 10 for the blueprint and grade
bufsize += 10;
} }
}
for (let special of specials) { if (specials[i]) {
if (special) { // Additional 5 for each special
// Length is 5 for each special
bufsize += 5; bufsize += 5;
} }
} }
}
if (bufsize > 0) { if (bufsize > 0) {
bufsize = bufsize + 1; // For end marker bufsize = bufsize + 1; // For end marker
@@ -1465,7 +1503,7 @@ export default class Ship {
let curpos = 0; let curpos = 0;
let i = 0; let i = 0;
for (let slot of slots) { for (let slot of slots) {
if (slot.length > 0) { if (slot.length > 0 || (blueprints[i] && blueprints[i].id)) {
buffer.writeInt8(i, curpos++); buffer.writeInt8(i, curpos++);
if (blueprints[i] && blueprints[i].id) { if (blueprints[i] && blueprints[i].id) {
buffer.writeInt8(MODIFICATION_ID_BLUEPRINT, curpos++); buffer.writeInt8(MODIFICATION_ID_BLUEPRINT, curpos++);