Add blueprint info to modification tooltip

This commit is contained in:
Cmdr McDonald
2017-03-22 11:44:08 +00:00
parent 75a4e54453
commit a1a17bc836
5 changed files with 98 additions and 62 deletions

View File

@@ -4,6 +4,7 @@ import Persist from '../stores/Persist';
import { DamageAbsolute, DamageKinetic, DamageThermal, DamageExplosive, MountFixed, MountGimballed, MountTurret, ListModifications, Modified } from './SvgIcons'; import { DamageAbsolute, DamageKinetic, DamageThermal, DamageExplosive, MountFixed, MountGimballed, MountTurret, ListModifications, Modified } from './SvgIcons';
import { Modifications } from 'coriolis-data/dist'; import { Modifications } from 'coriolis-data/dist';
import { stopCtxPropagation } from '../utils/UtilityFunctions'; import { stopCtxPropagation } from '../utils/UtilityFunctions';
import { blueprintTooltip } from '../utils/BlueprintFunctions';
/** /**
@@ -51,6 +52,12 @@ export default class HardpointSlot extends Slot {
if (m.blueprint.special && m.blueprint.special.id >= 0) { if (m.blueprint.special && m.blueprint.special.id >= 0) {
modTT += ', ' + translate(m.blueprint.special.name); modTT += ', ' + translate(m.blueprint.special.name);
} }
modTT = (
<div>
<div>{modTT}</div>
{blueprintTooltip(translate, m.blueprint.grades[m.blueprint.grade].features, m)}
</div>
);
} }
return <div className='details' draggable='true' onDragStart={drag} onDragEnd={drop}> return <div className='details' draggable='true' onDragStart={drag} onDragEnd={drop}>

View File

@@ -4,6 +4,7 @@ import Persist from '../stores/Persist';
import { ListModifications, Modified } from './SvgIcons'; import { ListModifications, Modified } from './SvgIcons';
import { Modifications } from 'coriolis-data/dist'; import { Modifications } from 'coriolis-data/dist';
import { stopCtxPropagation } from '../utils/UtilityFunctions'; import { stopCtxPropagation } from '../utils/UtilityFunctions';
import { blueprintTooltip } from '../utils/BlueprintFunctions';
/** /**
* Internal Slot * Internal Slot
@@ -30,6 +31,12 @@ export default class InternalSlot extends Slot {
let modTT = translate('modified'); let modTT = translate('modified');
if (m && m.blueprint && m.blueprint.name) { if (m && m.blueprint && m.blueprint.name) {
modTT = translate(m.blueprint.name) + ' ' + translate('grade') + ' ' + m.blueprint.grade; modTT = translate(m.blueprint.name) + ' ' + translate('grade') + ' ' + m.blueprint.grade;
modTT = (
<div>
<div>{modTT}</div>
{blueprintTooltip(translate, m.blueprint.grades[m.blueprint.grade].features, m)}
</div>
);
} }
let mass = m.getMass() || m.cargo || m.fuel || 0; let mass = m.getMass() || m.cargo || m.fuel || 0;

View File

@@ -5,6 +5,7 @@ import { isEmpty, stopCtxPropagation } from '../utils/UtilityFunctions';
import cn from 'classnames'; import cn from 'classnames';
import { Modifications } from 'coriolis-data/dist'; import { Modifications } from 'coriolis-data/dist';
import Modification from './Modification'; import Modification from './Modification';
import { blueprintTooltip } from '../utils/BlueprintFunctions';
/** /**
* Modifications menu * Modifications menu
@@ -52,7 +53,7 @@ export default class ModificationsMenu extends TranslatedComponent {
for (const grade of Modifications.modules[m.grp].blueprints[blueprintName]) { for (const grade of Modifications.modules[m.grp].blueprints[blueprintName]) {
const close = this._blueprintSelected.bind(this, Modifications.blueprints[blueprintName].id, grade); const close = this._blueprintSelected.bind(this, Modifications.blueprints[blueprintName].id, grade);
const key = blueprintName + ':' + grade; const key = blueprintName + ':' + grade;
const tooltipContent = this._blueprintTooltip(translate, Modifications.blueprints[blueprintName].grades[grade].features); const tooltipContent = blueprintTooltip(translate, Modifications.blueprints[blueprintName].grades[grade].features);
blueprints.push(<div style={{ cursor: 'pointer' }} key={ key } onMouseOver={termtip.bind(null, tooltipContent)} onMouseOut={tooltip.bind(null, null)} onClick={ close }>{translate(Modifications.blueprints[blueprintName].name + ' grade ' + grade)}</div>); blueprints.push(<div style={{ cursor: 'pointer' }} key={ key } onMouseOver={termtip.bind(null, tooltipContent)} onMouseOut={tooltip.bind(null, null)} onClick={ close }>{translate(Modifications.blueprints[blueprintName].name + ' grade ' + grade)}</div>);
} }
} }
@@ -77,51 +78,6 @@ export default class ModificationsMenu extends TranslatedComponent {
return { blueprintMenuOpened, blueprints, modifications, specialMenuOpened, specials }; return { blueprintMenuOpened, blueprints, modifications, specialMenuOpened, specials };
} }
/**
* Generate a tooltip with details of a blueprint's effects
* @param {Object} features The features of the blueprint
* @returns {Object} The react components
*/
_blueprintTooltip(translate, features)
{
const results = [];
for (const feature in features) {
const featureIsBeneficial = this._isBeneficial(feature, features[feature]);
const featureDef = Modifications.modifications[feature];
if (!featureDef.hidden) {
let symbol = '';
if (feature === 'jitter') {
symbol = '°';
} else if (featureDef.type === 'percentage') {
symbol = '%';
}
let lowerBound = features[feature][0];
let upperBound = features[feature][1];
if (featureDef.type === 'percentage') {
lowerBound = Math.round(lowerBound * 1000) / 10;
upperBound = Math.round(upperBound * 1000) / 10;
}
const range = `${lowerBound}${symbol} - ${upperBound}${symbol}`;
results.push(<tr key={feature} className={featureIsBeneficial ? 'secondary' : 'warning'}><td style={{ textAlign: 'left' }}>{translate(feature)}</td><td style={{ textAlign: 'right' }}>{lowerBound}{symbol}</td><td style={{ textAlign: 'right' }}>{upperBound}{symbol}</td></tr>);
}
}
return (
<table>
<thead>
<tr>
<td>{translate('effect')}</td>
<td>{translate('worst')}</td>
<td>{translate('best')}</td>
</tr>
</thead>
<tbody>
{results}
</tbody>
</table>
);
}
/** /**
* Initialise the modifications * Initialise the modifications
* @param {Object} props React Component properties * @param {Object} props React Component properties
@@ -290,19 +246,6 @@ export default class ModificationsMenu extends TranslatedComponent {
this.props.onChange(); this.props.onChange();
} }
/**
* Is this feature beneficial?
*
*/
_isBeneficial(feature, values) {
const fact = (values[0] < 0 || (values[0] === 0 && values[1] < 0));
if (Modifications.modifications[feature].higherbetter) {
return !fact;
} else {
return fact;
}
}
/** /**
* Reset modification information * Reset modification information
*/ */
@@ -335,11 +278,11 @@ export default class ModificationsMenu extends TranslatedComponent {
let blueprintLabel; let blueprintLabel;
let haveBlueprint = false; let haveBlueprint = false;
let blueprintTooltip; let blueprintTt;
if (m.blueprint && !isEmpty(m.blueprint)) { if (m.blueprint && !isEmpty(m.blueprint)) {
blueprintLabel = translate(m.blueprint.name) + ' ' + translate('grade') + ' ' + m.blueprint.grade; blueprintLabel = translate(m.blueprint.name) + ' ' + translate('grade') + ' ' + m.blueprint.grade;
haveBlueprint = true; haveBlueprint = true;
blueprintTooltip = this._blueprintTooltip(translate, m.blueprint.grades[m.blueprint.grade].features); blueprintTt = blueprintTooltip(translate, m.blueprint.grades[m.blueprint.grade].features);
} }
let specialLabel; let specialLabel;
@@ -363,7 +306,7 @@ export default class ModificationsMenu extends TranslatedComponent {
onContextMenu={stopCtxPropagation} onContextMenu={stopCtxPropagation}
> >
{ haveBlueprint ? { haveBlueprint ?
<div className={ cn('section-menu', { selected: blueprintMenuOpened })} style={{ cursor: 'pointer' }} onMouseOver={termtip.bind(null, blueprintTooltip)} onMouseOut={tooltip.bind(null, null)} onClick={_toggleBlueprintsMenu}>{blueprintLabel}</div> <div className={ cn('section-menu', { selected: blueprintMenuOpened })} style={{ cursor: 'pointer' }} onMouseOver={termtip.bind(null, blueprintTt)} onMouseOut={tooltip.bind(null, null)} onClick={_toggleBlueprintsMenu}>{blueprintLabel}</div>
: :
<div className={ cn('section-menu', { selected: blueprintMenuOpened })} style={{ cursor: 'pointer' }} onClick={_toggleBlueprintsMenu}>{translate('PHRASE_SELECT_BLUEPRINT')}</div> } <div className={ cn('section-menu', { selected: blueprintMenuOpened })} style={{ cursor: 'pointer' }} onClick={_toggleBlueprintsMenu}>{translate('PHRASE_SELECT_BLUEPRINT')}</div> }
{ showBlueprintsMenu ? this.state.blueprints : null } { showBlueprintsMenu ? this.state.blueprints : null }

View File

@@ -8,6 +8,7 @@ import ModificationsMenu from './ModificationsMenu';
import { ListModifications, Modified } from './SvgIcons'; import { ListModifications, Modified } from './SvgIcons';
import { Modifications } from 'coriolis-data/dist'; import { Modifications } from 'coriolis-data/dist';
import { stopCtxPropagation } from '../utils/UtilityFunctions'; import { stopCtxPropagation } from '../utils/UtilityFunctions';
import { blueprintTooltip } from '../utils/BlueprintFunctions';
/** /**
* Standard Slot * Standard Slot
@@ -53,6 +54,12 @@ export default class StandardSlot extends TranslatedComponent {
let modTT = translate('modified'); let modTT = translate('modified');
if (m && m.blueprint && m.blueprint.name) { if (m && m.blueprint && m.blueprint.name) {
modTT = translate(m.blueprint.name) + ' ' + translate('grade') + ' ' + m.blueprint.grade; modTT = translate(m.blueprint.name) + ' ' + translate('grade') + ' ' + m.blueprint.grade;
modTT = (
<div>
<div>{modTT}</div>
{blueprintTooltip(translate, m.blueprint.grades[m.blueprint.grade].features, m)}
</div>
);
} }
if (!selected) { if (!selected) {

View File

@@ -0,0 +1,72 @@
import React from 'react';
import { Modifications } from 'coriolis-data/dist';
/**
* Generate a tooltip with details of a blueprint's effects
* @param {Object} features The features of the blueprint
* @param {Object} m The module to compare with
* @returns {Object} The react components
*/
export function blueprintTooltip(translate, features, m)
{
const results = [];
for (const feature in features) {
const featureIsBeneficial = isBeneficial(feature, features[feature]);
const featureDef = Modifications.modifications[feature];
if (!featureDef.hidden) {
let symbol = '';
if (feature === 'jitter') {
symbol = '°';
} else if (featureDef.type === 'percentage') {
symbol = '%';
}
let lowerBound = features[feature][0];
let upperBound = features[feature][1];
if (featureDef.type === 'percentage') {
lowerBound = Math.round(lowerBound * 1000) / 10;
upperBound = Math.round(upperBound * 1000) / 10;
}
const range = `${lowerBound}${symbol} - ${upperBound}${symbol}`;
if (m) {
// We have a module - add in the current value
let current = m.getModValue(feature);
if (featureDef.type === 'percentage') {
current = Math.round(current / 10) / 10;
}
results.push(<tr key={feature} className={featureIsBeneficial ? 'secondary' : 'warning'}><td style={{ textAlign: 'left' }}>{translate(feature)}</td><td style={{ textAlign: 'right' }}>{lowerBound}{symbol}</td><td style={{ textAlign: 'right' }}>{current}{symbol}</td><td style={{ textAlign: 'right' }}>{upperBound}{symbol}</td></tr>);
} else {
// We do not have a module, no value
results.push(<tr key={feature} className={featureIsBeneficial ? 'secondary' : 'warning'}><td style={{ textAlign: 'left' }}>{translate(feature)}</td><td style={{ textAlign: 'right' }}>{lowerBound}{symbol}</td><td style={{ textAlign: 'right' }}>{upperBound}{symbol}</td></tr>);
}
}
}
return (
<table>
<thead>
<tr>
<td>{translate('feature')}</td>
<td>{translate('worst')}</td>
{m ? <td>{translate('current')}</td> : null }
<td>{translate('best')}</td>
</tr>
</thead>
<tbody>
{results}
</tbody>
</table>
);
}
/**
* Is this blueprint feature beneficial?
*
*/
export function isBeneficial(feature, values) {
const fact = (values[0] < 0 || (values[0] === 0 && values[1] < 0));
if (Modifications.modifications[feature].higherbetter) {
return !fact;
} else {
return fact;
}
}