import React from 'react'; import PropTypes from 'prop-types'; import * as _ from 'lodash'; import TranslatedComponent from './TranslatedComponent'; import { isEmpty, stopCtxPropagation } from '../utils/UtilityFunctions'; import cn from 'classnames'; import { Modifications } from 'coriolis-data/dist'; import Modification from './Modification'; import { getBlueprint, blueprintTooltip, setWorst, setBest, setExtreme, setRandom } from '../utils/BlueprintFunctions'; /** * Modifications menu */ export default class ModificationsMenu extends TranslatedComponent { static propTypes = { ship: PropTypes.object.isRequired, m: PropTypes.object.isRequired, marker: PropTypes.string.isRequired, onChange: PropTypes.func.isRequired }; /** * Constructor * @param {Object} props React Component properties * @param {Object} context React Component context */ constructor(props, context) { super(props); this._toggleBlueprintsMenu = this._toggleBlueprintsMenu.bind(this); this._toggleSpecialsMenu = this._toggleSpecialsMenu.bind(this); this._rollWorst = this._rollWorst.bind(this); this._rollRandom = this._rollRandom.bind(this); this._rollBest = this._rollBest.bind(this); this._rollExtreme = this._rollExtreme.bind(this); this._reset = this._reset.bind(this); this.state = { blueprintMenuOpened: false, specialMenuOpened: false }; } /** * Render the blueprints * @param {Object} props React component properties * @param {Object} context React component context * @return {Object} list: Array of React Components */ _renderBlueprints(props, context) { const { m } = props; const { language, tooltip, termtip } = context; const translate = language.translate; const blueprints = []; for (const blueprintName in Modifications.modules[m.grp].blueprints) { const blueprint = getBlueprint(blueprintName, m); let blueprintGrades = []; for (let grade in Modifications.modules[m.grp].blueprints[blueprintName].grades) { // Grade is a string in the JSON so make it a number grade = Number(grade); const classes = cn('c', { active: m.blueprint && blueprint.id === m.blueprint.id && grade === m.blueprint.grade }); const close = this._blueprintSelected.bind(this, blueprintName, grade); const key = blueprintName + ':' + grade; const tooltipContent = blueprintTooltip(translate, blueprint.grades[grade], Modifications.modules[m.grp].blueprints[blueprintName].grades[grade].engineers, m.grp); blueprintGrades.unshift(
  • {grade}
  • ); } if (blueprintGrades) { blueprints.push(
    {translate(blueprint.name)}
    ); blueprints.push(); } } return blueprints; } /** * Render the specials * @param {Object} props React component properties * @param {Object} context React component context * @return {Object} list: Array of React Components */ _renderSpecials(props, context) { const { m } = props; const { language, tooltip, termtip } = context; const translate = language.translate; const specials = []; if (Modifications.modules[m.grp].specials && Modifications.modules[m.grp].specials.length > 0) { const close = this._specialSelected.bind(this, null); specials.push(
    {translate('PHRASE_NO_SPECIAL')}
    ); for (const specialName of Modifications.modules[m.grp].specials) { const close = this._specialSelected.bind(this, specialName); specials.push(
    {translate(Modifications.specials[specialName].name)}
    ); } } return specials; } /** * Render the modifications * @param {Object} props React Component properties * @return {Object} list: Array of React Components */ _renderModifications(props) { const { m, onChange, ship } = props; const modifications = []; for (const modName of Modifications.modules[m.grp].modifications) { if (!Modifications.modifications[modName].hidden) { const key = modName + (m.getModValue(modName) / 100 || 0); modifications.push(); } } return modifications; } /** * Toggle the blueprints menu */ _toggleBlueprintsMenu() { const blueprintMenuOpened = !this.state.blueprintMenuOpened; this.setState({ blueprintMenuOpened }); } /** * Activated when a blueprint is selected * @param {int} fdname The Frontier name of the blueprint * @param {int} grade The grade of the selected blueprint */ _blueprintSelected(fdname, grade) { this.context.tooltip(null); const { m, ship } = this.props; const blueprint = getBlueprint(fdname, m); blueprint.grade = grade; ship.setModuleBlueprint(m, blueprint); this.setState({ blueprintMenuOpened: false }); this.props.onChange(); } /** * Toggle the specials menu */ _toggleSpecialsMenu() { const specialMenuOpened = !this.state.specialMenuOpened; this.setState({ specialMenuOpened }); } /** * Activated when a special is selected * @param {int} special The name of the selected special */ _specialSelected(special) { this.context.tooltip(null); const { m, ship } = this.props; if (special === null) { ship.clearModuleSpecial(m); } else { ship.setModuleSpecial(m, Modifications.specials[special]); } this.setState({ specialMenuOpened: false }); this.props.onChange(); } /** * Provide a 'worst' roll within the information we have */ _rollWorst() { const { m, ship } = this.props; setWorst(ship, m); this.props.onChange(); } /** * Provide a random roll within the information we have */ _rollRandom() { const { m, ship } = this.props; setRandom(ship, m); this.props.onChange(); } /** * Provide a 'best' roll within the information we have */ _rollBest() { const { m, ship } = this.props; setBest(ship, m); this.props.onChange(); } /** * Provide an 'extreme' roll within the information we have */ _rollExtreme() { const { m, ship } = this.props; setExtreme(ship, m); this.props.onChange(); } /** * Reset modification information */ _reset() { const { m, ship } = this.props; ship.clearModifications(m); ship.clearModuleBlueprint(m); this.props.onChange(); } /** * Render the list * @return {React.Component} List */ render() { const { language, tooltip, termtip } = this.context; const translate = language.translate; const { m } = this.props; const { blueprintMenuOpened, specialMenuOpened } = this.state; const _toggleBlueprintsMenu = this._toggleBlueprintsMenu; const _toggleSpecialsMenu = this._toggleSpecialsMenu; const _rollBest = this._rollBest; const _rollExtreme = this._rollExtreme; const _rollWorst = this._rollWorst; const _rollRandom = this._rollRandom; const _reset = this._reset; let blueprintLabel; let haveBlueprint = false; let blueprintTt; 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); } let specialLabel; if (m.blueprint && m.blueprint.special) { specialLabel = m.blueprint.special.name; } else { specialLabel = translate('PHRASE_SELECT_SPECIAL'); } const specials = this._renderSpecials(this.props, this.context); const showBlueprintsMenu = blueprintMenuOpened; const showSpecial = haveBlueprint && specials.length && !blueprintMenuOpened; const showSpecialsMenu = specialMenuOpened; const showRolls = haveBlueprint && !blueprintMenuOpened && !specialMenuOpened; const showReset = !blueprintMenuOpened && !specialMenuOpened; const showMods = !blueprintMenuOpened && !specialMenuOpened; return (
    e.stopPropagation() } onContextMenu={stopCtxPropagation} > { showBlueprintsMenu ? '' : haveBlueprint ?
    {blueprintLabel}
    :
    {translate('PHRASE_SELECT_BLUEPRINT')}
    } { showBlueprintsMenu ? this._renderBlueprints(this.props, this.context) : null } { showSpecial ?
    {specialLabel}
    : null } { showSpecialsMenu ? specials : null } { showRolls || showReset ? { showRolls ? : null } { showReset ? : null }
    { translate('roll') }: { translate('worst') } { translate('best') } { translate('extreme') } { translate('random') }
    { translate('reset') }
    : null } { showMods ? { this._renderModifications(this.props) } : null }
    ); } }