From e82ab0aec0adc2285657eeffc39c30189a454b8a Mon Sep 17 00:00:00 2001 From: Felix Linker Date: Tue, 28 Dec 2021 00:38:25 +0100 Subject: [PATCH] Update multiple-slot actions to ed-forge --- src/app/components/HardpointSlotSection.jsx | 108 +++++++++--------- src/app/components/InternalSlotSection.jsx | 115 +++++++------------- src/app/components/StandardSlotSection.jsx | 86 +++++---------- src/app/components/UtilitySlotSection.jsx | 41 +++---- 4 files changed, 140 insertions(+), 210 deletions(-) diff --git a/src/app/components/HardpointSlotSection.jsx b/src/app/components/HardpointSlotSection.jsx index 676840af..5eb5fe24 100644 --- a/src/app/components/HardpointSlotSection.jsx +++ b/src/app/components/HardpointSlotSection.jsx @@ -5,6 +5,8 @@ import { MountFixed, MountGimballed, MountTurret } from '../components/SvgIcons' import { stopCtxPropagation } from '../utils/UtilityFunctions'; import autoBind from 'auto-bind'; +const SIZE_ORDER = ['huge', 'large', 'medium', 'small']; + /** * Hardpoint slot section */ @@ -22,30 +24,37 @@ export default class HardpointSlotSection extends SlotSection { * Empty all slots */ _empty() { - // TODO: - // this.props.ship.emptyWeapons(); + this.props.ship.getHardpoints(undefined, true).forEach((slot) => slot.reset()); this._close(); } /** * Fill slots with specified module - * @param {string} group Group name - * @param {string} mount Mount Type - F, G, T - * @param {SyntheticEvent} event Event + * @param {string} type Type of item + * @param {string} rating Mount Type - (fixed, gimbal, turret) + * @param {SyntheticEvent} event Event */ - _fill(group, mount, event) { - // TODO: - // this.props.ship.useWeapon(group, mount, null, event.getModifierState('Alt')); + _fill(type, rating, event) { + const fillAll = event.getModifierState('Alt'); + this.props.ship.getHardpoints(undefined, true).forEach((slot) => { + if (slot.isEmpty() || fillAll) { + const slotSize = slot.getSize(); + const fittingSizes = SIZE_ORDER.slice(SIZE_ORDER.findIndex((e) => e === slotSize)); + for (const size of fittingSizes) { + try { + slot.setItem(type, size, rating); + } catch (err) { + // Try next item if this doesn't fit/exist + continue; + } + // If still here, we were able to apply the module + break; + } + } + }); this._close(); } - /** - * Empty all on section header right click - */ - _contextMenu() { - this._empty(); - } - /** * Generate the slot React Components * @return {Array} Array of Slots @@ -58,7 +67,6 @@ export default class HardpointSlotSection extends SlotSection { for (let h of ship.getHardpoints(undefined, true)) { slots.push( e.stopPropagation()} onContextMenu={stopCtxPropagation}> -
{translate('pl')}
+
{translate('pulselaser')}
-
{translate('ul')}
+
{translate('burstlaser')}
-
{translate('bl')}
+
{translate('beamlaser')}
-
{translate('mc')}
+
{translate('multicannon')}
-
{translate('c')}
+
{translate('cannon')}
-
{translate('fc')}
+
{translate('fragcannon')}
-
{translate('pa')}
+
{translate('plasmaacc')}
-
{translate('rg')}
+
{translate('railgun')}
-
{translate('nl')}
+
{translate('minelauncher')}
-
{translate('rfl')}
+
{translate('flaklauncher')}
; } diff --git a/src/app/components/InternalSlotSection.jsx b/src/app/components/InternalSlotSection.jsx index 1a305540..291057a0 100644 --- a/src/app/components/InternalSlotSection.jsx +++ b/src/app/components/InternalSlotSection.jsx @@ -3,6 +3,25 @@ import SlotSection from './SlotSection'; import Slot from './Slot'; import { stopCtxPropagation } from '../utils/UtilityFunctions'; import autoBind from 'auto-bind'; +import { TYPES } from 'ed-forge/lib/src/data/slots'; + +/** + * Sets all empty slots of a ship to a item of the given size. + * @param {Ship} ship Ship to set items for + * @param {boolean} fillAll True to also fill occupied + * @param {string} type Item type + * @param {string} rating Item rating + */ +function setAllEmpty(ship, fillAll, type, rating = '') { + ship.getModules(TYPES.ANY_INTERNAL, undefined, true).forEach((slot) => { + if (slot.isEmpty() || fillAll) { + try { + // Maybe the item does not exist. Simply catch this error. + slot.setItem(type, slot.getSize(), rating); + } catch (e) {} + } + }); +} /** * Internal slot section @@ -21,8 +40,7 @@ export default class InternalSlotSection extends SlotSection { * Empty all slots */ _empty() { - // TODO: - // this.props.ship.emptyInternal(); + this.props.ship.getModules(TYPES.ANY_INTERNAL).forEach((slot) => slot.reset()); this._close(); } @@ -31,13 +49,8 @@ export default class InternalSlotSection extends SlotSection { * @param {SyntheticEvent} event Event */ _fillWithCargo(event) { - let clobber = event.getModifierState('Alt'); - let ship = this.props.ship; - ship.internal.forEach((slot) => { - if ((clobber || !slot.m) && canMount(ship, slot, 'cr')) { - ship.use(slot, ModuleUtils.findInternal('cr', slot.maxClass, 'E')); - } - }); + const fillAll = event.getModifierState('Alt'); + setAllEmpty(this.props.ship, fillAll, 'cargorack'); this._close(); } @@ -46,13 +59,8 @@ export default class InternalSlotSection extends SlotSection { * @param {SyntheticEvent} event Event */ _fillWithFuelTanks(event) { - let clobber = event.getModifierState('Alt'); - let ship = this.props.ship; - ship.internal.forEach((slot) => { - if ((clobber || !slot.m) && canMount(ship, slot, 'ft')) { - ship.use(slot, ModuleUtils.findInternal('ft', slot.maxClass, 'C')); - } - }); + const fillAll = event.getModifierState('Alt'); + setAllEmpty(this.props.ship, fillAll, 'fueltank', '3'); this._close(); } @@ -61,13 +69,8 @@ export default class InternalSlotSection extends SlotSection { * @param {SyntheticEvent} event Event */ _fillWithLuxuryCabins(event) { - let clobber = event.getModifierState('Alt'); - let ship = this.props.ship; - ship.internal.forEach((slot) => { - if ((clobber || !slot.m) && canMount(ship, slot, 'pcq')) { - ship.use(slot, ModuleUtils.findInternal('pcq', Math.min(slot.maxClass, 6), 'B')); // Passenger cabins top out at 6 - } - }); + const fillAll = event.getModifierState('Alt'); + setAllEmpty(this.props.ship, fillAll, 'passengercabins', '4'); this._close(); } @@ -76,13 +79,8 @@ export default class InternalSlotSection extends SlotSection { * @param {SyntheticEvent} event Event */ _fillWithFirstClassCabins(event) { - let clobber = event.getModifierState('Alt'); - let ship = this.props.ship; - ship.internal.forEach((slot) => { - if ((clobber || !slot.m) && canMount(ship, slot, 'pcm')) { - ship.use(slot, ModuleUtils.findInternal('pcm', Math.min(slot.maxClass, 6), 'C')); // Passenger cabins top out at 6 - } - }); + const fillAll = event.getModifierState('Alt'); + setAllEmpty(this.props.ship, fillAll, 'passengercabins', '3'); this._close(); } @@ -91,13 +89,8 @@ export default class InternalSlotSection extends SlotSection { * @param {SyntheticEvent} event Event */ _fillWithBusinessClassCabins(event) { - let clobber = event.getModifierState('Alt'); - let ship = this.props.ship; - ship.internal.forEach((slot) => { - if ((clobber || !slot.m) && canMount(ship, slot, 'pci')) { - ship.use(slot, ModuleUtils.findInternal('pci', Math.min(slot.maxClass, 6), 'D')); // Passenger cabins top out at 6 - } - }); + const fillAll = event.getModifierState('Alt'); + setAllEmpty(this.props.ship, fillAll, 'passengercabins', '2'); this._close(); } @@ -106,13 +99,8 @@ export default class InternalSlotSection extends SlotSection { * @param {SyntheticEvent} event Event */ _fillWithEconomyClassCabins(event) { - let clobber = event.getModifierState('Alt'); - let ship = this.props.ship; - ship.internal.forEach((slot) => { - if ((clobber || !slot.m) && canMount(ship, slot, 'pce')) { - ship.use(slot, ModuleUtils.findInternal('pce', Math.min(slot.maxClass, 6), 'E')); // Passenger cabins top out at 6 - } - }); + const fillAll = event.getModifierState('Alt'); + setAllEmpty(this.props.ship, fillAll, 'passengercabins', '1'); this._close(); } @@ -121,16 +109,8 @@ export default class InternalSlotSection extends SlotSection { * @param {SyntheticEvent} event Event */ _fillWithCells(event) { - let clobber = event.getModifierState('Alt'); - let ship = this.props.ship; - let chargeCap = 0; // Capacity of single activation - ship.internal.forEach(function(slot) { - if ((clobber && !(slot.m && ModuleUtils.isShieldGenerator(slot.m.grp)) || !slot.m) && canMount(ship, slot, 'scb')) { - ship.use(slot, ModuleUtils.findInternal('scb', slot.maxClass, 'A')); - ship.setSlotEnabled(slot, chargeCap <= ship.shieldStrength); // Don't waste cell capacity on overcharge - chargeCap += slot.m.recharge; - } - }); + const fillAll = event.getModifierState('Alt'); + setAllEmpty(this.props.ship, fillAll, 'scb', '5'); this._close(); } @@ -139,13 +119,8 @@ export default class InternalSlotSection extends SlotSection { * @param {SyntheticEvent} event Event */ _fillWithArmor(event) { - let clobber = event.getModifierState('Alt'); - let ship = this.props.ship; - ship.internal.forEach((slot) => { - if ((clobber || !slot.m) && canMount(ship, slot, 'hr')) { - ship.use(slot, ModuleUtils.findInternal('hr', Math.min(slot.maxClass, 5), 'D')); // Hull reinforcements top out at 5D - } - }); + const fillAll = event.getModifierState('Alt'); + setAllEmpty(this.props.ship, fillAll, 'hrp', '2'); this._close(); } @@ -154,23 +129,11 @@ export default class InternalSlotSection extends SlotSection { * @param {SyntheticEvent} event Event */ _fillWithModuleReinforcementPackages(event) { - let clobber = event.getModifierState('Alt'); - let ship = this.props.ship; - ship.internal.forEach((slot) => { - if ((clobber || !slot.m) && canMount(ship, slot, 'mrp')) { - ship.use(slot, ModuleUtils.findInternal('mrp', Math.min(slot.maxClass, 5), 'D')); // Module reinforcements top out at 5D - } - }); + const fillAll = event.getModifierState('Alt'); + setAllEmpty(this.props.ship, fillAll, 'mrp', '2'); this._close(); } - /** - * Empty all on section header right click - */ - _contextMenu() { - this._empty(); - } - /** * Generate the slot React Components * @return {Array} Array of Slots @@ -217,7 +180,7 @@ export default class InternalSlotSection extends SlotSection {
  • {translate('pce')}
  • {translate('pci')}
  • {translate('pcm')}
  • - { ship.luxuryCabins ?
  • {translate('pcq')}
  • : ''} + { ship.readMeta('luxuryCabins') ?
  • {translate('pcq')}
  • : ''}
  • {translate('PHRASE_ALT_ALL')}
  • ; diff --git a/src/app/components/StandardSlotSection.jsx b/src/app/components/StandardSlotSection.jsx index 2547d5f6..41a8eee6 100644 --- a/src/app/components/StandardSlotSection.jsx +++ b/src/app/components/StandardSlotSection.jsx @@ -1,10 +1,10 @@ import React from 'react'; -import cn from 'classnames'; import SlotSection from './SlotSection'; import Slot from './Slot'; import autoBind from 'auto-bind'; import { stopCtxPropagation, moduleGet } from '../utils/UtilityFunctions'; import { ShipProps, Module } from 'ed-forge'; +import { getModuleInfo } from 'ed-forge/lib/src/data/items'; const { CONSUMED_RETR, LADEN_MASS } = ShipProps; /** @@ -22,65 +22,35 @@ export default class StandardSlotSection extends SlotSection { } /** - * Use the lightest/optimal available standard modules + * Resets all modules of the ship */ - _optimizeStandard() { - this.props.ship.useLightestStandard(); + _emptyAll() { + this.props.ship.getModules().forEach((slot) => slot.reset()); this._close(); } /** - * Fill all standard slots with the specificed rating (using max class) - * @param {Boolean} shielded True if shield generator should be included - * @param {integer} bulkheadIndex Bulkhead to use see Constants.BulkheadNames + * Sets all modules to a specific rating + * @param {string} rating Module rating to set + * @param {string} fsdPPException Custom rating for FSD */ - _multiPurpose(shielded, bulkheadIndex) { - ShipRoles.multiPurpose(this.props.ship, shielded, bulkheadIndex); + _nRated(rating, fsdPPException) { + const { ship } = this.props; + const pp = ship.getPowerPlant(); + pp.setItem('powerplant', pp.getSize(), fsdPPException || rating); + const eng = ship.getThrusters(); + eng.setItem('thrusters', eng.getSize(), rating); + const fsd = ship.getFSD(); + fsd.setItem('fsd', fsd.getSize(), fsdPPException || rating); + const ls = ship.getLifeSupport(); + ls.setItem('lifesupport', ls.getSize(), rating); + const pd = ship.getPowerDistributor(); + pd.setItem('powerdistributor', pd.getSize(), rating); + const sen = ship.getSensors(); + sen.setItem('sensors', sen.getSize(), rating); this._close(); } - /** - * Trader Build - * @param {Boolean} shielded True if shield generator should be included - */ - _optimizeCargo(shielded) { - ShipRoles.trader(this.props.ship, shielded); - this._close(); - } - - /** - * Miner Build - * @param {Boolean} shielded True if shield generator should be included - */ - _optimizeMiner(shielded) { - ShipRoles.miner(this.props.ship, shielded); - this._close(); - } - - /** - * Explorer role - * @param {Boolean} planetary True if Planetary Vehicle Hangar (PVH) should be included - */ - _optimizeExplorer(planetary) { - ShipRoles.explorer(this.props.ship, planetary); - this._close(); - } - - /** - * Racer role - */ - _optimizeRacer() { - ShipRoles.racer(this.props.ship); - this._close(); - } - - /** - * On right click optimize the standard modules - */ - _contextMenu() { - this._optimizeStandard(); - } - /** * Creates a new slot for a given module. * @param {Module} m Module to create the slot for @@ -134,17 +104,13 @@ export default class StandardSlotSection extends SlotSection { const { translate } = this.context.language; return
    e.stopPropagation()} onContextMenu={stopCtxPropagation}>
      -
    • {translate('Maximize Jump Range')}
    • +
    • {translate('empty all slots')}
    -
    {translate('roles')}
    +
    {translate('core')}
      -
    • {translate('Multi-purpose')}
    • -
    • {translate('Combat')}
    • -
    • {translate('Trader')}
    • -
    • {translate('Explorer')}
    • -
    • {translate('Planetary Explorer')}
    • -
    • {translate('Miner')}
    • -
    • {translate('Racer')}
    • +
    • {translate('A-rated')}
    • +
    • {translate('D-rated')}
    • +
    • {translate('D-rated + A-rated FSD/PP')}
    ; } diff --git a/src/app/components/UtilitySlotSection.jsx b/src/app/components/UtilitySlotSection.jsx index bfb7e6c7..256d9edc 100644 --- a/src/app/components/UtilitySlotSection.jsx +++ b/src/app/components/UtilitySlotSection.jsx @@ -21,31 +21,26 @@ export default class UtilitySlotSection extends SlotSection { * Empty all utility slots and close the menu */ _empty() { - this.props.ship.emptyUtility(); - this.props.onChange(); + this.props.ship.getUtilities().forEach((slot) => slot.reset()); this._close(); } /** * Mount module in utility slot, replace all if Alt is held - * @param {string} group Module Group name + * @param {string} type Module type * @param {string} rating Module Rating - * @param {string} name Module name * @param {Synthetic} event Event */ - _use(group, rating, name, event) { - this.props.ship.useUtility(group, rating, name, event.getModifierState('Alt')); - this.props.onChange(); + _use(type, rating, event) { + const fillAll = event.getModifierState('Alt'); + for (const slot of this.props.ship.getUtilities(undefined, true)) { + if (slot.isEmpty() || fillAll) { + slot.setItem(type, '', rating); + } + } this._close(); } - /** - * Empty all utility slots on right-click - */ - _contextMenu() { - this._empty(); - } - /** * Create all HardpointSlots (React component) for the slots * @return {Array} Array of HardpointSlots @@ -58,8 +53,6 @@ export default class UtilitySlotSection extends SlotSection { for (let h of ship.getUtilities(undefined, true)) { slots.push(
    {translate('sb')}
      -
    • A
    • -
    • B
    • -
    • C
    • -
    • D
    • -
    • E
    • +
    • A
    • +
    • B
    • +
    • C
    • +
    • D
    • +
    • E
    {translate('hs')}
      -
    • {translate('Heat Sink Launcher')}
    • +
    • {translate('Heat Sink Launcher')}
    {translate('ch')}
      -
    • {translate('Chaff Launcher')}
    • +
    • {translate('Chaff Launcher')}
    {translate('po')}
      -
    • {translate('Point Defence')}
    • +
    • {translate('Point Defence')}
    ; }