mirror of
https://github.com/EDCD/coriolis.git
synced 2025-12-09 14:45:35 +00:00
Fix retrofit cost
This commit is contained in:
@@ -2,7 +2,7 @@ import React from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import cn from 'classnames';
|
import cn from 'classnames';
|
||||||
import Persist from '../stores/Persist';
|
import Persist from '../stores/Persist';
|
||||||
import Ship from '../shipyard/Ship';
|
import { Factory, Ship } from 'ed-forge';
|
||||||
import { Insurance } from '../shipyard/Constants';
|
import { Insurance } from '../shipyard/Constants';
|
||||||
import TranslatedComponent from './TranslatedComponent';
|
import TranslatedComponent from './TranslatedComponent';
|
||||||
import { ShoppingIcon } from './SvgIcons';
|
import { ShoppingIcon } from './SvgIcons';
|
||||||
@@ -28,13 +28,15 @@ export default class CostSection extends TranslatedComponent {
|
|||||||
super(props);
|
super(props);
|
||||||
autoBind(this);
|
autoBind(this);
|
||||||
|
|
||||||
|
const { ship, buildName } = props;
|
||||||
|
this.shipType = ship.getShipType();
|
||||||
this.state = {
|
this.state = {
|
||||||
retrofitName: this._defaultRetrofitName(props.ship, props.buildName),
|
retrofitName: Persist.hasBuild(ship.getShipType(), buildName) ? buildName : null,
|
||||||
shipDiscount: Persist.getShipDiscount(),
|
shipDiscount: Persist.getShipDiscount(),
|
||||||
moduleDiscount: Persist.getModuleDiscount(),
|
moduleDiscount: Persist.getModuleDiscount(),
|
||||||
insurance: Insurance[Persist.getInsurance()],
|
insurance: Insurance[Persist.getInsurance()],
|
||||||
tab: Persist.getCostTab(),
|
tab: Persist.getCostTab(),
|
||||||
buildOptions: Persist.getBuildsNamesFor(props.ship.getShipType()),
|
buildOptions: Persist.getBuildsNamesFor(ship.getShipType()),
|
||||||
predicate: 'cr',
|
predicate: 'cr',
|
||||||
desc: true,
|
desc: true,
|
||||||
excluded: {},
|
excluded: {},
|
||||||
@@ -43,36 +45,15 @@ export default class CostSection extends TranslatedComponent {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a ship instance to base/reference retrofit changes from
|
* Create a ship instance to base/reference retrofit changes from
|
||||||
* @param {string} ship Ship
|
|
||||||
* @param {string} name Build name
|
|
||||||
* @param {Ship} retrofitShip Existing retrofit ship
|
|
||||||
* @return {Ship} Retrofit ship
|
* @return {Ship} Retrofit ship
|
||||||
*/
|
*/
|
||||||
_buildRetrofitShip(ship, name, retrofitShip) {
|
_buildRetrofitShip() {
|
||||||
// TODO: once ships have been persisted, this can be fixed
|
const { retrofitName } = this.state;
|
||||||
return ship;
|
if (Persist.hasBuild(this.shipType, retrofitName)) {
|
||||||
// let data = Ships[shipId]; // Retrieve the basic ship properties, slots and defaults
|
return new Ship(Persist.getBuild(this.shipType, retrofitName));
|
||||||
|
} else {
|
||||||
// if (!retrofitShip) { // Don't create a new instance unless needed
|
return Factory.newShip(this.shipType);
|
||||||
// retrofitShip = new Ship(shipId, data.properties, data.slots); // Create a new Ship for retrofit comparison
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
// if (Persist.hasBuild(shipId, name)) {
|
|
||||||
// retrofitShip.buildFrom(Persist.getBuild(shipId, name)); // Populate modules from existing build
|
|
||||||
// } else {
|
|
||||||
// retrofitShip.buildWith(data.defaults); // Populate with default components
|
|
||||||
// }
|
|
||||||
// return retrofitShip;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the default retrofit build name if it exists
|
|
||||||
* @param {string} ship Ship
|
|
||||||
* @param {string} name Build name
|
|
||||||
* @return {string} Build name or null
|
|
||||||
*/
|
|
||||||
_defaultRetrofitName(ship, name) {
|
|
||||||
return Persist.hasBuild(ship.getShipType(), name) ? name : null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -220,8 +201,8 @@ export default class CostSection extends TranslatedComponent {
|
|||||||
*/
|
*/
|
||||||
_retrofitInfo() {
|
_retrofitInfo() {
|
||||||
const { ship } = this.props;
|
const { ship } = this.props;
|
||||||
const { desc, moduleDiscount, predicate, retrofitName } = this.state;
|
const { desc, moduleDiscount, predicate, retrofitName, excluded } = this.state;
|
||||||
const retrofitShip = this._buildRetrofitShip(ship, retrofitName);
|
const retrofitShip = this._buildRetrofitShip();
|
||||||
|
|
||||||
const currentModules = ship.getModules();
|
const currentModules = ship.getModules();
|
||||||
const oldModules = retrofitShip.getModules();
|
const oldModules = retrofitShip.getModules();
|
||||||
@@ -229,37 +210,38 @@ export default class CostSection extends TranslatedComponent {
|
|||||||
const sellModules = differenceBy(oldModules, currentModules, (m) => m.getItem());
|
const sellModules = differenceBy(oldModules, currentModules, (m) => m.getItem());
|
||||||
|
|
||||||
let modules = [];
|
let modules = [];
|
||||||
for (let m of buyModules) {
|
let totalCost = 0;
|
||||||
const key = `buy_${m.getSlot()}`;
|
const addModule = (m, costFactor) => {
|
||||||
|
const key = `${m.getItem()}@${m.getSlot()}`;
|
||||||
|
const cost = costFactor * m.readMeta('cost') * (1 - moduleDiscount);
|
||||||
modules.push({
|
modules.push({
|
||||||
key,
|
key, cost,
|
||||||
cost: m.readMeta('cost') * (1 - moduleDiscount),
|
rating: m.getClassRating(),
|
||||||
buyRating: m.getClassRating(),
|
item: m.readMeta('type'),
|
||||||
buyItem: m.readMeta('type'),
|
|
||||||
});
|
});
|
||||||
|
if (!excluded[key]) {
|
||||||
|
totalCost += cost;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
for (let m of buyModules) {
|
||||||
|
addModule(m, 1);
|
||||||
}
|
}
|
||||||
for (let m of sellModules) {
|
for (let m of sellModules) {
|
||||||
const key = `sell_${m.getSlot()}`;
|
addModule(m, -1);
|
||||||
modules.push({
|
|
||||||
key,
|
|
||||||
cost: -1 * m.readMeta('cost') * moduleDiscount,
|
|
||||||
sellRating: m.getClassRating(),
|
|
||||||
sellItem: m.readMeta('type'),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let _sortF = undefined;
|
let _sortF = undefined;
|
||||||
switch (predicate) {
|
switch (predicate) {
|
||||||
case 'cr': _sortF = (o) => o.cost;
|
case 'cr': _sortF = (o) => o.cost; break;
|
||||||
case 'm':
|
case 'm':
|
||||||
default: _sortF = (o) => o.buyItem || o.sellItem;
|
default: _sortF = (o) => o.item; break;
|
||||||
};
|
};
|
||||||
|
|
||||||
modules = sortBy(modules, _sortF);
|
modules = sortBy(modules, _sortF);
|
||||||
if (desc) {
|
if (desc) {
|
||||||
reverse(modules);
|
reverse(modules);
|
||||||
}
|
}
|
||||||
return modules;
|
return [totalCost, modules];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -267,46 +249,18 @@ export default class CostSection extends TranslatedComponent {
|
|||||||
* @return {React.Component} Tab contents
|
* @return {React.Component} Tab contents
|
||||||
*/
|
*/
|
||||||
_retrofitTab() {
|
_retrofitTab() {
|
||||||
let { excluded, moduleDiscount, retrofitName } = this.state;
|
let { buildOptions, excluded, moduleDiscount, retrofitName } = this.state;
|
||||||
const { termtip, tooltip } = this.context;
|
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 options = [<option key='stock' value=''>{translate('Stock')}</option>];
|
|
||||||
|
|
||||||
for (let opt of this.state.buildOptions) {
|
|
||||||
options.push(<option key={opt} value={opt}>{opt}</option>);
|
|
||||||
}
|
|
||||||
|
|
||||||
const retrofitInfo = this._retrofitInfo();
|
|
||||||
const retrofitTotal = 0;
|
|
||||||
let rows = [];
|
|
||||||
for (let i of retrofitInfo) {
|
|
||||||
const disabled = excluded[i.key];
|
|
||||||
rows.push(
|
|
||||||
<tr key={i.key} className={cn('highlight', { disabled })}
|
|
||||||
onClick={() => this._toggleExcluded(i.key)}>
|
|
||||||
<td className='ptr' style={{ width: '1em' }}>{i.buyRating}</td>
|
|
||||||
<td className='le ptr shorten cap'>{translate(i.buyItem)}</td>
|
|
||||||
<td className='ptr' style={{ width: '1em' }}>{i.sellRating}</td>
|
|
||||||
<td className='le ptr shorten cap'>{translate(i.sellItem)}</td>
|
|
||||||
<td colSpan='2' className={cn('ri ptr', disabled ? 'disabled' : (i.cost < 0 ? 'secondary-disabled' : 'warning'))}>
|
|
||||||
{int(i.cost)}{units.CR}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
);
|
|
||||||
retrofitTotal += disabled ? 0 : i.cost;
|
|
||||||
}
|
|
||||||
if (!rows.length) {
|
|
||||||
rows = <tr><td colSpan='7' style={{ padding: '3em 0' }}>{translate('PHRASE_NO_RETROCH')}</td></tr>;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
const [retrofitTotal, retrofitInfo] = this._retrofitInfo();
|
||||||
return <div>
|
return <div>
|
||||||
<div className='scroll-x'>
|
<div className='scroll-x'>
|
||||||
<table style={{ width: '100%' }}>
|
<table style={{ width: '100%' }}>
|
||||||
<thead>
|
<thead>
|
||||||
<tr className='main'>
|
<tr className='main'>
|
||||||
<th colSpan='2' className='sortable le' onClick={() => this._sortBy('m')}>{translate('sell')}</th>
|
<th colSpan='2' className='sortable le' onClick={() => this._sortBy('m')}>{translate('module')}</th>
|
||||||
<th colSpan='2' className='sortable le' onClick={() => this._sortBy('m')}>{translate('buy')}</th>
|
|
||||||
<th colSpan='2' className='sortable le' onClick={() => this._sortBy('cr')}>
|
<th colSpan='2' className='sortable le' onClick={() => this._sortBy('cr')}>
|
||||||
{translate('net cost')}
|
{translate('net cost')}
|
||||||
{moduleDiscount ? <u className='cap optional-hide' style={{ marginLeft: '0.5em' }}>{`[${translate('modules')} -${formats.pct(moduleDiscount)}]`}</u> : null}
|
{moduleDiscount ? <u className='cap optional-hide' style={{ marginLeft: '0.5em' }}>{`[${translate('modules')} -${formats.pct(moduleDiscount)}]`}</u> : null}
|
||||||
@@ -314,20 +268,33 @@ export default class CostSection extends TranslatedComponent {
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{rows}
|
{retrofitInfo.length ?
|
||||||
|
retrofitInfo.map((info) => (
|
||||||
|
<tr key={info.key} className={cn('highlight', { disabled: excluded[info.key] })}
|
||||||
|
onClick={() => this._toggleExcluded(info.key)}>
|
||||||
|
<td className='ptr' style={{ width: '1em' }}>{info.rating}</td>
|
||||||
|
<td className='le ptr shorten cap'>{translate(info.item)}</td>
|
||||||
|
<td colSpan="2" className={cn('ri ptr', excluded[info.key] ? 'disabled' : (info.cost < 0 ? 'secondary-disabled' : 'warning'))}>
|
||||||
|
{int(info.cost)}{units.CR}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)) : (
|
||||||
|
<tr><td colSpan='7' style={{ padding: '3em 0' }}>{translate('PHRASE_NO_RETROCH')}</td></tr>
|
||||||
|
)}
|
||||||
<tr className='ri'>
|
<tr className='ri'>
|
||||||
<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 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 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>
|
||||||
</tr>
|
</tr>
|
||||||
<tr className='ri'>
|
<tr className='ri'>
|
||||||
<td colSpan='4' className='lbl cap' >{translate('retrofit from')}</td>
|
<td colSpan='2' className='lbl cap' >{translate('retrofit from')}</td>
|
||||||
<td className='val cen' style={{ borderRight: 'none', width: '1em' }}><u className='primary-disabled'>▾</u></td>
|
<td className='val cen' style={{ borderRight: 'none', width: '1em' }}><u className='primary-disabled'>▾</u></td>
|
||||||
<td className='val' style={{ borderLeft:'none', padding: 0 }}>
|
<td className='val' style={{ borderLeft:'none', padding: 0 }}>
|
||||||
<select style={{ width: '100%', padding: 0 }} value={retrofitName || translate('Stock')} onChange={this._onBaseRetrofitChange}>
|
<select style={{ width: '100%', padding: 0 }} value={retrofitName || translate('Stock')} onChange={this._onBaseRetrofitChange}>
|
||||||
{options}
|
<option key='stock' value=''>{translate('Stock')}</option>
|
||||||
|
{buildOptions.map((opt) => <option key={opt} value={opt}>{opt}</option>)}
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
Reference in New Issue
Block a user