diff --git a/ChangeLog.md b/ChangeLog.md index 0f7dda9b..ab1cf2b1 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -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 * Use scan range for DSS rather than scan time * Fix companion API import of Dolphin diff --git a/package.json b/package.json index f9851ca5..f2047f42 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "coriolis_shipyard", - "version": "2.3.2", + "version": "2.3.3", "repository": { "type": "git", "url": "https://github.com/EDCD/coriolis" diff --git a/src/app/components/CostSection.jsx b/src/app/components/CostSection.jsx index 302dd5c8..0da51961 100644 --- a/src/app/components/CostSection.jsx +++ b/src/app/components/CostSection.jsx @@ -6,6 +6,7 @@ import Ship from '../shipyard/Ship'; import { Insurance } from '../shipyard/Constants'; import { slotName, slotComparator } from '../utils/SlotFunctions'; import TranslatedComponent from './TranslatedComponent'; +import { ShoppingIcon } from '../components/SvgIcons'; /** * Cost Section @@ -31,6 +32,7 @@ export default class CostSection extends TranslatedComponent { this._buildRetrofitShip = this._buildRetrofitShip.bind(this); this._onBaseRetrofitChange = this._onBaseRetrofitChange.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 retrofitName = this._defaultRetrofitName(props.ship.id, props.buildName); @@ -325,12 +327,27 @@ export default class CostSection extends TranslatedComponent { ; } + /** + * 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 * @return {React.Component} Tab contents */ _retrofitTab() { let { retrofitTotal, retrofitCosts, moduleDiscount, retrofitName } = this.state; + const { termtip, tooltip } = this.context; let { translate, formats, units } = this.context.language; let int = formats.int; let rows = [], options = []; @@ -370,7 +387,8 @@ export default class CostSection extends TranslatedComponent { {rows} - {translate('cost')} + + {translate('cost')} 0 ? 'warning' : 'secondary-disabled')} style={{ borderBottom:'none' }}> {int(retrofitTotal)}{units.CR} @@ -403,6 +421,8 @@ export default class CostSection extends TranslatedComponent { if (ship.bulkheads.m.index != retrofitShip.bulkheads.m.index) { item = { buyClassRating: ship.bulkheads.m.class + ship.bulkheads.m.rating, + buyId: ship.bulkheads.m.eddbID, + buyPp: ship.bulkheads.m.pp, buyName: ship.bulkheads.m.name, sellClassRating: retrofitShip.bulkheads.m.class + retrofitShip.bulkheads.m.rating, sellName: retrofitShip.bulkheads.m.name, @@ -424,6 +444,8 @@ export default class CostSection extends TranslatedComponent { if (modId != retroModId) { item = { netCost: 0, retroItem: retroSlotGroup[i] }; 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.buyClassRating = slotGroup[i].m.class + slotGroup[i].m.rating; item.netCost = slotGroup[i].discountedCost; diff --git a/src/app/components/ModificationsMenu.jsx b/src/app/components/ModificationsMenu.jsx index 1e657e79..5e040613 100644 --- a/src/app/components/ModificationsMenu.jsx +++ b/src/app/components/ModificationsMenu.jsx @@ -130,10 +130,10 @@ export default class ModificationsMenu extends TranslatedComponent { */ _blueprintSelected(fdname, grade) { this.context.tooltip(null); - const { m } = this.props; + const { m, ship } = this.props; const blueprint = getBlueprint(fdname, m); blueprint.grade = grade; - m.blueprint = blueprint; + ship.setModuleBlueprint(m, blueprint); this.setState({ blueprintMenuOpened: false }); this.props.onChange(); @@ -155,15 +155,10 @@ export default class ModificationsMenu extends TranslatedComponent { this.context.tooltip(null); const { m, ship } = this.props; - if (m.blueprint) { - if (special === null) { - m.blueprint.special = null; - } else { - m.blueprint.special = Modifications.specials[special]; - } - ship.recalculateDps(); - ship.recalculateHps(); - ship.recalculateEps(); + if (special === null) { + ship.clearModuelSpecial(m); + } else { + ship.setModuleSpecial(m, Modifications.specials[special]); } this.setState({ specialMenuOpened: false }); @@ -268,7 +263,7 @@ export default class ModificationsMenu extends TranslatedComponent { _reset() { const { m, ship } = this.props; ship.clearModifications(m); - ship.clearBlueprint(m); + ship.clearModuleBlueprint(m); this.props.onChange(); } @@ -294,7 +289,7 @@ export default class ModificationsMenu extends TranslatedComponent { let blueprintLabel; let haveBlueprint = false; let blueprintTt; - if (m.blueprint && !isEmpty(m.blueprint)) { + if (m.blueprint && m.blueprint.name) { blueprintLabel = translate(m.blueprint.name) + ' ' + translate('grade') + ' ' + m.blueprint.grade; 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); diff --git a/src/app/i18n/en.js b/src/app/i18n/en.js index b154cae4..5ef042f3 100644 --- a/src/app/i18n/en.js +++ b/src/app/i18n/en.js @@ -38,6 +38,7 @@ export const terms = { PHRASE_SELECT_SPECIAL: 'Click to select an experimental effect', PHRASE_NO_SPECIAL: 'No experimental effect', 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_TIME_TO_LOSE_SHIELDS: 'Shields will hold for', PHRASE_TIME_TO_RECOVER_SHIELDS: 'Shields will recover in', diff --git a/src/app/shipyard/Ship.js b/src/app/shipyard/Ship.js index 0de8b2ef..99dcd23d 100755 --- a/src/app/shipyard/Ship.js +++ b/src/app/shipyard/Ship.js @@ -429,11 +429,45 @@ export default class Ship { } /** - * Clear blueprint for a module - * @param {Number} m The module for which to clear the modifications + * Set blueprint for a module + * @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 = {}; + 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,16 +1479,20 @@ export default class Ship { // Now work out the size of the binary buffer from our modifications array let bufsize = 0; - for (let slot of slots) { - if (slot.length > 0) { - // Length is 1 for the slot ID, 10 for the blueprint name and grade, 5 for each modification, and 1 for the end marker - bufsize = bufsize + 1 + 10 + (5 * slot.length) + 1; - } - } - for (let special of specials) { - if (special) { - // Length is 5 for each special - bufsize += 5; + for (let i = 0; i < slots.length; i++) { + if (slots[i].length > 0 || (blueprints[i] && blueprints[i].id)) { + // Length is 1 for the slot ID, 5 for each modification, and 1 for the end marker + bufsize = bufsize + 1 + (5 * slots[i].length) + 1; + + if (blueprints[i] && blueprints[i].id) { + // Additional 10 for the blueprint and grade + bufsize += 10; + } + + if (specials[i]) { + // Additional 5 for each special + bufsize += 5; + } } } @@ -1465,7 +1503,7 @@ export default class Ship { let curpos = 0; let i = 0; for (let slot of slots) { - if (slot.length > 0) { + if (slot.length > 0 || (blueprints[i] && blueprints[i].id)) { buffer.writeInt8(i, curpos++); if (blueprints[i] && blueprints[i].id) { buffer.writeInt8(MODIFICATION_ID_BLUEPRINT, curpos++);