diff --git a/src/js/game/belt_path.js b/src/js/game/belt_path.js index 8ad4f7e3..81a60951 100644 --- a/src/js/game/belt_path.js +++ b/src/js/game/belt_path.js @@ -132,14 +132,14 @@ export class BeltPath extends BasicSerializableObject { tryAcceptItem(item) { if (this.spacingToFirstItem >= globalConfig.itemSpacingOnBelts) { // So, since we already need one tick to accept this item we will add this directly. - const beltProgressPerTick = + const progressGrowth = this.root.hubGoals.getBeltBaseSpeed() * this.root.dynamicTickrate.deltaSeconds * globalConfig.itemSpacingOnBelts; // First, compute how much progress we can make *at max* const maxProgress = Math.max(0, this.spacingToFirstItem - globalConfig.itemSpacingOnBelts); - const initialProgress = Math.min(maxProgress, beltProgressPerTick); + const initialProgress = Math.min(maxProgress, progressGrowth); this.items.unshift([this.spacingToFirstItem - initialProgress, item]); this.spacingToFirstItem = initialProgress; @@ -272,31 +272,10 @@ export class BeltPath extends BasicSerializableObject { } const matchingSlotIndex = matchingSlot.index; - const passOver = this.computePassOverFunctionWithoutBelts(targetEntity, matchingSlotIndex); - if (!passOver) { - return; - } - const matchingDirection = enumInvertedDirections[ejectingDirection]; - const filter = matchingSlot.slot.filter; - return function (item, remainingProgress = 0.0) { - // Check if the acceptor has a filter - if (filter && item._type !== filter) { - return false; - } - - // Try to pass over - if (passOver(item, matchingSlotIndex)) { - // Trigger animation on the acceptor comp - if (noSimplifiedBelts) { - targetAcceptorComp.onItemAccepted( - matchingSlotIndex, - matchingDirection, - item, - remainingProgress - ); - } + return function (item, startProgress = 0.0) { + if (targetAcceptorComp.tryAcceptItem(matchingSlotIndex, matchingDirection, item, startProgress)) { return true; } return false; @@ -313,7 +292,7 @@ export class BeltPath extends BasicSerializableObject { const systems = this.root.systemMgr.systems; const hubGoals = this.root.hubGoals; - // NOTICE: THIS IS COPIED FROM THE ITEM EJECTOR SYSTEM FOR PEROFMANCE REASONS + // NOTICE: THIS IS COPIED FROM THE ITEM EJECTOR SYSTEM FOR PERFORMANCE REASONS const itemProcessorComp = entity.components.ItemProcessor; if (itemProcessorComp) { @@ -323,7 +302,7 @@ export class BeltPath extends BasicSerializableObject { if (!systems.itemProcessor.checkRequirements(entity, item, matchingSlotIndex)) { return; } - return itemProcessorComp.tryTakeItem(item, matchingSlotIndex); + //return itemProcessorComp.tryTakeItem(item, matchingSlotIndex); }; } diff --git a/src/js/game/buildings/balancer.js b/src/js/game/buildings/balancer.js index 0948338c..ce685a9a 100644 --- a/src/js/game/buildings/balancer.js +++ b/src/js/game/buildings/balancer.js @@ -179,11 +179,11 @@ export class MetaBalancerBuilding extends MetaBuilding { entity.components.ItemAcceptor.setSlots([ { pos: new Vector(0, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, }, { pos: new Vector(1, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, }, ]); @@ -204,15 +204,14 @@ export class MetaBalancerBuilding extends MetaBuilding { entity.components.ItemAcceptor.setSlots([ { pos: new Vector(0, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, }, { pos: new Vector(0, 0), - directions: [ + direction: variant === enumBalancerVariants.mergerInverse ? enumDirection.left : enumDirection.right, - ], }, ]); @@ -231,7 +230,7 @@ export class MetaBalancerBuilding extends MetaBuilding { entity.components.ItemAcceptor.setSlots([ { pos: new Vector(0, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, }, ]); diff --git a/src/js/game/buildings/cutter.js b/src/js/game/buildings/cutter.js index 4950f786..21acdaa0 100644 --- a/src/js/game/buildings/cutter.js +++ b/src/js/game/buildings/cutter.js @@ -96,7 +96,7 @@ export class MetaCutterBuilding extends MetaBuilding { slots: [ { pos: new Vector(0, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, filter: "shape", }, ], diff --git a/src/js/game/buildings/filter.js b/src/js/game/buildings/filter.js index bf4c5f19..f8c29b1f 100644 --- a/src/js/game/buildings/filter.js +++ b/src/js/game/buildings/filter.js @@ -78,7 +78,7 @@ export class MetaFilterBuilding extends MetaBuilding { slots: [ { pos: new Vector(0, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, }, ], }) diff --git a/src/js/game/buildings/goal_acceptor.js b/src/js/game/buildings/goal_acceptor.js index cb51a6d2..463798ad 100644 --- a/src/js/game/buildings/goal_acceptor.js +++ b/src/js/game/buildings/goal_acceptor.js @@ -45,7 +45,7 @@ export class MetaGoalAcceptorBuilding extends MetaBuilding { slots: [ { pos: new Vector(0, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, filter: "shape", }, ], diff --git a/src/js/game/buildings/hub.js b/src/js/game/buildings/hub.js index 3a543cf0..f8ba4b82 100644 --- a/src/js/game/buildings/hub.js +++ b/src/js/game/buildings/hub.js @@ -1,6 +1,6 @@ import { enumDirection, Vector } from "../../core/vector"; import { HubComponent } from "../components/hub"; -import { ItemAcceptorComponent } from "../components/item_acceptor"; +import { enumItemAcceptorTypes, ItemAcceptorComponent } from "../components/item_acceptor"; import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor"; import { Entity } from "../entity"; import { defaultBuildingVariant, MetaBuilding } from "../meta_building"; @@ -75,75 +75,96 @@ export class MetaHubBuilding extends MetaBuilding { slots: [ { pos: new Vector(0, 0), - directions: [enumDirection.top, enumDirection.left], + direction: enumDirection.top, + filter: "shape", + }, + { + pos: new Vector(0, 0), + direction: enumDirection.left, filter: "shape", }, { pos: new Vector(1, 0), - directions: [enumDirection.top], + direction: enumDirection.top, filter: "shape", }, { pos: new Vector(2, 0), - directions: [enumDirection.top], + direction: enumDirection.top, filter: "shape", }, { pos: new Vector(3, 0), - directions: [enumDirection.top, enumDirection.right], + direction: enumDirection.top, + filter: "shape", + }, + { + pos: new Vector(3, 0), + direction: enumDirection.right, filter: "shape", }, { pos: new Vector(0, 3), - directions: [enumDirection.bottom, enumDirection.left], + direction: enumDirection.left, + filter: "shape", + }, + { + pos: new Vector(0, 3), + direction: enumDirection.bottom, filter: "shape", }, { pos: new Vector(1, 3), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, filter: "shape", }, { pos: new Vector(2, 3), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, filter: "shape", }, { pos: new Vector(3, 3), - directions: [enumDirection.bottom, enumDirection.right], + direction: enumDirection.bottom, + filter: "shape", + }, + { + pos: new Vector(3, 3), + direction: enumDirection.right, filter: "shape", }, { pos: new Vector(0, 1), - directions: [enumDirection.left], + direction: enumDirection.left, filter: "shape", }, { pos: new Vector(0, 2), - directions: [enumDirection.left], + direction: enumDirection.left, filter: "shape", }, { pos: new Vector(0, 3), - directions: [enumDirection.left], + direction: enumDirection.left, filter: "shape", }, { pos: new Vector(3, 1), - directions: [enumDirection.right], + direction: enumDirection.right, filter: "shape", }, { pos: new Vector(3, 2), - directions: [enumDirection.right], + direction: enumDirection.right, filter: "shape", }, { pos: new Vector(3, 3), - directions: [enumDirection.right], + direction: enumDirection.right, filter: "shape", }, ], + type: enumItemAcceptorTypes.hub, }) ); } diff --git a/src/js/game/buildings/mixer.js b/src/js/game/buildings/mixer.js index db8d867a..de1665c4 100644 --- a/src/js/game/buildings/mixer.js +++ b/src/js/game/buildings/mixer.js @@ -73,12 +73,12 @@ export class MetaMixerBuilding extends MetaBuilding { slots: [ { pos: new Vector(0, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, filter: "color", }, { pos: new Vector(1, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, filter: "color", }, ], diff --git a/src/js/game/buildings/painter.js b/src/js/game/buildings/painter.js index 79ae86ac..432973d0 100644 --- a/src/js/game/buildings/painter.js +++ b/src/js/game/buildings/painter.js @@ -128,12 +128,12 @@ export class MetaPainterBuilding extends MetaBuilding { slots: [ { pos: new Vector(0, 0), - directions: [enumDirection.left], + direction: enumDirection.left, filter: "shape", }, { pos: new Vector(1, 0), - directions: [enumDirection.top], + direction: enumDirection.top, filter: "color", }, ], @@ -160,14 +160,13 @@ export class MetaPainterBuilding extends MetaBuilding { entity.components.ItemAcceptor.setSlots([ { pos: new Vector(0, 0), - directions: [enumDirection.left], + direction: enumDirection.left, filter: "shape", }, { pos: new Vector(1, 0), - directions: [ + direction: variant === defaultBuildingVariant ? enumDirection.top : enumDirection.bottom, - ], filter: "color", }, ]); @@ -193,17 +192,17 @@ export class MetaPainterBuilding extends MetaBuilding { entity.components.ItemAcceptor.setSlots([ { pos: new Vector(0, 0), - directions: [enumDirection.left], + direction: enumDirection.left, filter: "shape", }, { pos: new Vector(0, 1), - directions: [enumDirection.left], + direction: enumDirection.left, filter: "shape", }, { pos: new Vector(1, 0), - directions: [enumDirection.top], + direction: enumDirection.top, filter: "color", }, ]); @@ -251,27 +250,27 @@ export class MetaPainterBuilding extends MetaBuilding { entity.components.ItemAcceptor.setSlots([ { pos: new Vector(0, 0), - directions: [enumDirection.left], + direction: enumDirection.left, filter: "shape", }, { pos: new Vector(0, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, filter: "color", }, { pos: new Vector(1, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, filter: "color", }, { pos: new Vector(2, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, filter: "color", }, { pos: new Vector(3, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, filter: "color", }, ]); diff --git a/src/js/game/buildings/reader.js b/src/js/game/buildings/reader.js index 951c7e8a..5c9307c3 100644 --- a/src/js/game/buildings/reader.js +++ b/src/js/game/buildings/reader.js @@ -84,7 +84,7 @@ export class MetaReaderBuilding extends MetaBuilding { slots: [ { pos: new Vector(0, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, }, ], }) diff --git a/src/js/game/buildings/rotater.js b/src/js/game/buildings/rotater.js index 428ab08a..e1080767 100644 --- a/src/js/game/buildings/rotater.js +++ b/src/js/game/buildings/rotater.js @@ -128,7 +128,7 @@ export class MetaRotaterBuilding extends MetaBuilding { slots: [ { pos: new Vector(0, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, filter: "shape", }, ], diff --git a/src/js/game/buildings/stacker.js b/src/js/game/buildings/stacker.js index ad1a7bc7..f36ef248 100644 --- a/src/js/game/buildings/stacker.js +++ b/src/js/game/buildings/stacker.js @@ -73,12 +73,12 @@ export class MetaStackerBuilding extends MetaBuilding { slots: [ { pos: new Vector(0, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, filter: "shape", }, { pos: new Vector(1, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, filter: "shape", }, ], diff --git a/src/js/game/buildings/storage.js b/src/js/game/buildings/storage.js index b63adc01..69e03608 100644 --- a/src/js/game/buildings/storage.js +++ b/src/js/game/buildings/storage.js @@ -1,7 +1,7 @@ import { formatBigNumber } from "../../core/utils"; import { enumDirection, Vector } from "../../core/vector"; import { T } from "../../translations"; -import { ItemAcceptorComponent } from "../components/item_acceptor"; +import { enumItemAcceptorTypes, ItemAcceptorComponent } from "../components/item_acceptor"; import { ItemEjectorComponent } from "../components/item_ejector"; import { StorageComponent } from "../components/storage"; import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins"; @@ -74,13 +74,14 @@ export class MetaStorageBuilding extends MetaBuilding { slots: [ { pos: new Vector(0, 1), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, }, { pos: new Vector(1, 1), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, }, ], + type: enumItemAcceptorTypes.storage, }) ); diff --git a/src/js/game/buildings/trash.js b/src/js/game/buildings/trash.js index 3085bc55..1524c480 100644 --- a/src/js/game/buildings/trash.js +++ b/src/js/game/buildings/trash.js @@ -74,15 +74,10 @@ export class MetaTrashBuilding extends MetaBuilding { entity.addComponent( new ItemAcceptorComponent({ slots: [ - { - pos: new Vector(0, 0), - directions: [ - enumDirection.top, - enumDirection.right, - enumDirection.bottom, - enumDirection.left, - ], - }, + { pos: new Vector(0, 0), direction: enumDirection.top }, + { pos: new Vector(0, 0), direction: enumDirection.left }, + { pos: new Vector(0, 0), direction: enumDirection.right }, + { pos: new Vector(0, 0), direction: enumDirection.bottom }, ], }) ); diff --git a/src/js/game/buildings/underground_belt.js b/src/js/game/buildings/underground_belt.js index 0f02863f..182ee9a8 100644 --- a/src/js/game/buildings/underground_belt.js +++ b/src/js/game/buildings/underground_belt.js @@ -1,6 +1,6 @@ import { Loader } from "../../core/loader"; import { enumDirection, Vector, enumAngleToDirection, enumDirectionToVector } from "../../core/vector"; -import { ItemAcceptorComponent } from "../components/item_acceptor"; +import { enumItemAcceptorTypes, ItemAcceptorComponent } from "../components/item_acceptor"; import { ItemEjectorComponent } from "../components/item_ejector"; import { enumUndergroundBeltMode, UndergroundBeltComponent } from "../components/underground_belt"; import { Entity } from "../entity"; @@ -195,6 +195,7 @@ export class MetaUndergroundBeltBuilding extends MetaBuilding { entity.addComponent( new ItemAcceptorComponent({ slots: [], + type: enumItemAcceptorTypes.undergroundBelt, }) ); } @@ -277,7 +278,7 @@ export class MetaUndergroundBeltBuilding extends MetaBuilding { entity.components.ItemAcceptor.setSlots([ { pos: new Vector(0, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, }, ]); return; diff --git a/src/js/game/components/belt.js b/src/js/game/components/belt.js index 3144ad96..81d2c65c 100644 --- a/src/js/game/components/belt.js +++ b/src/js/game/components/belt.js @@ -8,7 +8,7 @@ export const curvedBeltLength = /* Math.PI / 4 */ 0.78; /** @type {import("./item_acceptor").ItemAcceptorSlot} */ export const FAKE_BELT_ACCEPTOR_SLOT = { pos: new Vector(0, 0), - directions: [enumDirection.bottom], + direction: enumDirection.bottom, }; /** @type {Object} */ diff --git a/src/js/game/components/item_acceptor.js b/src/js/game/components/item_acceptor.js index 354f9024..5b2b7122 100644 --- a/src/js/game/components/item_acceptor.js +++ b/src/js/game/components/item_acceptor.js @@ -1,27 +1,52 @@ import { enumDirection, enumInvertedDirections, Vector } from "../../core/vector"; -import { types } from "../../savegame/serialization"; import { BaseItem } from "../base_item"; import { Component } from "../component"; - -/** @typedef {{ - * pos: Vector, - * directions: enumDirection[], - * filter?: ItemType - * }} ItemAcceptorSlot */ +import { Entity } from "../entity"; +import { GameRoot } from "../root"; /** + * @typedef {{ + * pos: Vector, + * direction: enumDirection, + * filter?: ItemType + * }} ItemAcceptorSlot + * * Contains information about a slot plus its location * @typedef {{ - * slot: ItemAcceptorSlot, - * index: number, - * acceptedDirection: enumDirection - * }} ItemAcceptorLocatedSlot */ - -/** @typedef {{ + * slot: ItemAcceptorSlot, + * index: number, + * acceptedDirection: enumDirection + * }} ItemAcceptorLocatedSlot + * + * @typedef {{ * pos: Vector, - * directions: enumDirection[], + * direction: enumDirection, * filter?: ItemType - * }} ItemAcceptorSlotConfig */ + * }} ItemAcceptorSlotConfig + * + * @typedef {Map} ItemAcceptorInput + * + * @typedef {{ + * root: GameRoot, + * entity: Entity, + * item: BaseItem, + * slotIndex: number, + * extraProgress: number + * }} InputCompletedArgs + */ + +/** @enum {string} */ +export const enumItemAcceptorTypes = { + itemProcessor: "itemProcessor", + hub: "hub", + storage: "storage", + trash: "trash", + undergroundBelt: "undergroundBelt", +}; export class ItemAcceptorComponent extends Component { static getId() { @@ -32,25 +57,15 @@ export class ItemAcceptorComponent extends Component { * * @param {object} param0 * @param {Array} param0.slots The slots from which we accept items + * @param {enumItemAcceptorTypes=} param0.type Function that gets called when the input of an item is completed */ - constructor({ slots = [] }) { + constructor({ slots = [], type = enumItemAcceptorTypes.itemProcessor }) { super(); + /** @type {ItemAcceptorInput} */ + this.currentInputs = new Map(); // @SENSETODO does this need to be saved? + this.type = type; this.setSlots(slots); - this.clear(); - } - - clear() { - /** - * Fixes belt animations - * @type {Array<{ - * item: BaseItem, - * slotIndex: number, - * animProgress: number, - * direction: enumDirection - * }>} - */ - this.itemConsumptionAnimations = []; } /** @@ -64,7 +79,7 @@ export class ItemAcceptorComponent extends Component { const slot = slots[i]; this.slots.push({ pos: slot.pos, - directions: slot.directions, + direction: slot.direction, // Which type of item to accept (shape | color | all) @see ItemType filter: slot.filter, @@ -73,31 +88,28 @@ export class ItemAcceptorComponent extends Component { } /** - * Returns if this acceptor can accept a new item at slot N - * - * NOTICE: The belt path ignores this for performance reasons and does his own check - * @param {number} slotIndex - * @param {BaseItem=} item - */ - canAcceptItem(slotIndex, item) { - const slot = this.slots[slotIndex]; - return !slot.filter || slot.filter === item.getItemType(); - } - - /** - * Called when an item has been accepted so that + * Called when trying to input a new item * @param {number} slotIndex * @param {enumDirection} direction * @param {BaseItem} item - * @param {number} remainingProgress World space remaining progress, can be set to set the start position of the item + * @param {number} startProgress World space remaining progress, can be set to set the start position of the item + * @returns {boolean} if the input was succesful */ - onItemAccepted(slotIndex, direction, item, remainingProgress = 0.0) { - this.itemConsumptionAnimations.push({ + tryAcceptItem(slotIndex, direction, item, startProgress = 0.0) { + const slot = this.slots[slotIndex]; + + //@SENSETODO see if this works for buildings like hub + + if (this.currentInputs.has(slotIndex) || (slot.filter && slot.filter != item.getItemType())) { + return false; + } + + this.currentInputs.set(slotIndex, { item, - slotIndex, direction, - animProgress: Math.min(1, remainingProgress * 2), + animProgress: Math.min(1, startProgress), }); + return true; } /** @@ -121,16 +133,12 @@ export class ItemAcceptorComponent extends Component { continue; } - // Check if the acceptor slot accepts items from our direction - for (let i = 0; i < slot.directions.length; ++i) { - // const localDirection = targetStaticComp.localDirectionToWorld(slot.directions[l]); - if (desiredDirection === slot.directions[i]) { - return { - slot, - index: slotIndex, - acceptedDirection: desiredDirection, - }; - } + if (desiredDirection === slot.direction) { + return { + slot, + index: slotIndex, + acceptedDirection: desiredDirection, + }; } } diff --git a/src/js/game/components/item_ejector.js b/src/js/game/components/item_ejector.js index bfc54cd8..b6d21e6a 100644 --- a/src/js/game/components/item_ejector.js +++ b/src/js/game/components/item_ejector.js @@ -70,7 +70,7 @@ export class ItemEjectorComponent extends Component { direction: slot.direction, item: null, lastItem: null, - progress: 0, + progress: 0, //@SENSETODO needs to be started off with extra time cachedDestSlot: null, cachedTargetEntity: null, }); @@ -127,28 +127,16 @@ export class ItemEjectorComponent extends Component { * Tries to eject a given item * @param {number} slotIndex * @param {BaseItem} item + * @param {number} startingProgress * @returns {boolean} */ - tryEject(slotIndex, item) { + tryEject(slotIndex, item, startingProgress = 0.0) { if (!this.canEjectOnSlot(slotIndex)) { return false; } this.slots[slotIndex].item = item; this.slots[slotIndex].lastItem = item; - this.slots[slotIndex].progress = 0; + this.slots[slotIndex].progress = startingProgress; return true; } - - /** - * Clears the given slot and returns the item it had - * @param {number} slotIndex - * @returns {BaseItem|null} - */ - takeSlotItem(slotIndex) { - const slot = this.slots[slotIndex]; - const item = slot.item; - slot.item = null; - slot.progress = 0.0; - return item; - } } diff --git a/src/js/game/components/item_processor.js b/src/js/game/components/item_processor.js index f7dddec1..749c1038 100644 --- a/src/js/game/components/item_processor.js +++ b/src/js/game/components/item_processor.js @@ -27,16 +27,23 @@ export const enumItemProcessorRequirements = { painterQuad: "painterQuad", }; -/** @typedef {{ +/** + * @typedef {{ * item: BaseItem, * requiredSlot?: number, * preferredSlot?: number - * }} EjectorItemToEject */ - -/** @typedef {{ + * }} EjectorItemToEject + * + * @typedef {{ * remainingTime: number, * items: Array, - * }} EjectorCharge */ + * }} EjectorCharge + * + * @typedef {{ + * item: BaseItem + * extraProgress: number + * }} ItemProcessorInput + */ export class ItemProcessorComponent extends Component { static getId() { @@ -75,9 +82,9 @@ export class ItemProcessorComponent extends Component { /** * Our current inputs - * @type {Map} + * @type {Map} */ - this.inputSlots = new Map(); + this.inputs = new Map(); this.clear(); } @@ -88,13 +95,7 @@ export class ItemProcessorComponent extends Component { // sure the outputs always match this.nextOutputSlot = 0; - this.inputSlots.clear(); - - /** - * Current input count - * @type {number} - */ - this.inputCount = 0; + this.inputs.clear(); /** * What we are currently processing, empty if we don't produce anything rn @@ -110,30 +111,4 @@ export class ItemProcessorComponent extends Component { */ this.bonusTime = 0; } - - /** - * Tries to take the item - * @param {BaseItem} item - * @param {number} sourceSlot - */ - tryTakeItem(item, sourceSlot) { - if ( - this.type === enumItemProcessorTypes.hub || - this.type === enumItemProcessorTypes.trash || - this.type === enumItemProcessorTypes.goal - ) { - // Hub has special logic .. not really nice but efficient. - this.inputSlots.set(this.inputCount, item); - this.inputCount++; - return true; - } - - // Check that we only take one item per slot - if (this.inputSlots.has(sourceSlot)) { - return false; - } - this.inputSlots.set(sourceSlot, item); - this.inputCount++; - return true; - } } diff --git a/src/js/game/hud/parts/building_placer.js b/src/js/game/hud/parts/building_placer.js index ee7bc804..a5609f1f 100644 --- a/src/js/game/hud/parts/building_placer.js +++ b/src/js/game/hud/parts/building_placer.js @@ -500,65 +500,58 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic { const acceptorSlotWsTile = staticComp.localTileToWorld(slot.pos); const acceptorSlotWsPos = acceptorSlotWsTile.toWorldSpaceCenterOfTile(); - // Go over all slots - for ( - let acceptorDirectionIndex = 0; - acceptorDirectionIndex < slot.directions.length; - ++acceptorDirectionIndex - ) { - const direction = slot.directions[acceptorDirectionIndex]; - const worldDirection = staticComp.localDirectionToWorld(direction); + const direction = slot.direction; + const worldDirection = staticComp.localDirectionToWorld(direction); - // Figure out which tile ejects to this slot - const sourceTile = acceptorSlotWsTile.add(enumDirectionToVector[worldDirection]); + // Figure out which tile ejects to this slot + const sourceTile = acceptorSlotWsTile.add(enumDirectionToVector[worldDirection]); - let isBlocked = false; - let isConnected = false; + let isBlocked = false; + let isConnected = false; - // Find all entities which are on that tile - const sourceEntities = this.root.map.getLayersContentsMultipleXY(sourceTile.x, sourceTile.y); + // Find all entities which are on that tile + const sourceEntities = this.root.map.getLayersContentsMultipleXY(sourceTile.x, sourceTile.y); - // Check for every entity: - for (let i = 0; i < sourceEntities.length; ++i) { - const sourceEntity = sourceEntities[i]; - const sourceEjector = sourceEntity.components.ItemEjector; - const sourceBeltComp = sourceEntity.components.Belt; - const sourceStaticComp = sourceEntity.components.StaticMapEntity; - const ejectorAcceptLocalTile = sourceStaticComp.worldToLocalTile(acceptorSlotWsTile); + // Check for every entity: + for (let i = 0; i < sourceEntities.length; ++i) { + const sourceEntity = sourceEntities[i]; + const sourceEjector = sourceEntity.components.ItemEjector; + const sourceBeltComp = sourceEntity.components.Belt; + const sourceStaticComp = sourceEntity.components.StaticMapEntity; + const ejectorAcceptLocalTile = sourceStaticComp.worldToLocalTile(acceptorSlotWsTile); - // If this entity is on the same layer as the slot - if so, it can either be - // connected, or it can not be connected and thus block the input - if (sourceEjector && sourceEjector.anySlotEjectsToLocalTile(ejectorAcceptLocalTile)) { - // This one is connected, all good - isConnected = true; - } else if ( - sourceBeltComp && - sourceStaticComp.localDirectionToWorld(sourceBeltComp.direction) === - enumInvertedDirections[worldDirection] - ) { - // Belt connected - isConnected = true; - } else { - // This one is blocked - isBlocked = true; - } + // If this entity is on the same layer as the slot - if so, it can either be + // connected, or it can not be connected and thus block the input + if (sourceEjector && sourceEjector.anySlotEjectsToLocalTile(ejectorAcceptLocalTile)) { + // This one is connected, all good + isConnected = true; + } else if ( + sourceBeltComp && + sourceStaticComp.localDirectionToWorld(sourceBeltComp.direction) === + enumInvertedDirections[worldDirection] + ) { + // Belt connected + isConnected = true; + } else { + // This one is blocked + isBlocked = true; } - - const alpha = isConnected || isBlocked ? 1.0 : 0.3; - const sprite = isBlocked ? badArrowSprite : goodArrowSprite; - - parameters.context.globalAlpha = alpha; - drawRotatedSprite({ - parameters, - sprite, - x: acceptorSlotWsPos.x, - y: acceptorSlotWsPos.y, - angle: Math.radians(enumDirectionToAngle[enumInvertedDirections[worldDirection]]), - size: 13, - offsetY: offsetShift + 13, - }); - parameters.context.globalAlpha = 1; } + + const alpha = isConnected || isBlocked ? 1.0 : 0.3; + const sprite = isBlocked ? badArrowSprite : goodArrowSprite; + + parameters.context.globalAlpha = alpha; + drawRotatedSprite({ + parameters, + sprite, + x: acceptorSlotWsPos.x, + y: acceptorSlotWsPos.y, + angle: Math.radians(enumDirectionToAngle[enumInvertedDirections[worldDirection]]), + size: 13, + offsetY: offsetShift + 13, + }); + parameters.context.globalAlpha = 1; } // Go over all slots diff --git a/src/js/game/logic.js b/src/js/game/logic.js index 79104958..8d251859 100644 --- a/src/js/game/logic.js +++ b/src/js/game/logic.js @@ -431,22 +431,20 @@ export class GameLogic { } } - for (let acceptorSlot = 0; acceptorSlot < acceptorSlots.length; ++acceptorSlot) { - const slot = acceptorSlots[acceptorSlot]; + for (let i = 0; i < acceptorSlots.length; ++i) { + const slot = acceptorSlots[i]; const wsTile = staticComp.localTileToWorld(slot.pos); - for (let k = 0; k < slot.directions.length; ++k) { - const direction = slot.directions[k]; - const wsDirection = staticComp.localDirectionToWorld(direction); + const direction = slot.direction; + const wsDirection = staticComp.localDirectionToWorld(direction); - const sourceTile = wsTile.add(enumDirectionToVector[wsDirection]); - if (sourceTile.equals(tile)) { - acceptors.push({ - entity, - slot, - toTile: wsTile, - fromDirection: wsDirection, - }); - } + const sourceTile = wsTile.add(enumDirectionToVector[wsDirection]); + if (sourceTile.equals(tile)) { + acceptors.push({ + entity, + slot, + toTile: wsTile, + fromDirection: wsDirection, + }); } } } diff --git a/src/js/game/systems/item_acceptor.js b/src/js/game/systems/item_acceptor.js index 780b4abd..61bf780a 100644 --- a/src/js/game/systems/item_acceptor.js +++ b/src/js/game/systems/item_acceptor.js @@ -1,58 +1,67 @@ import { globalConfig } from "../../core/config"; import { DrawParameters } from "../../core/draw_parameters"; -import { fastArrayDelete } from "../../core/utils"; import { enumDirectionToVector } from "../../core/vector"; -import { ItemAcceptorComponent } from "../components/item_acceptor"; +import { + enumItemAcceptorTypes, + ItemAcceptorComponent, + InputCompletedArgs, +} from "../components/item_acceptor"; import { GameSystemWithFilter } from "../game_system_with_filter"; +import { ShapeItem } from "../items/shape_item"; import { MapChunkView } from "../map_chunk_view"; export class ItemAcceptorSystem extends GameSystemWithFilter { constructor(root) { super(root, [ItemAcceptorComponent]); - // Well ... it's better to be verbose I guess? - this.accumulatedTicksWhileInMapOverview = 0; + /** + * @type {Object} + */ + this.handlers = { + [enumItemAcceptorTypes.itemProcessor]: this.input_ITEMPROCESSOR, + [enumItemAcceptorTypes.hub]: this.input_HUB, + [enumItemAcceptorTypes.trash]: this.input_TRASH, + }; + + // Bind all handlers + for (const key in this.handlers) { + this.handlers[key] = this.handlers[key].bind(this); + } } update() { - if (this.root.app.settings.getAllSettings().simplifiedBelts) { - // Disabled in potato mode - return; - } - - // This system doesn't render anything while in map overview, - // so simply accumulate ticks - if (this.root.camera.getIsMapOverlayActive()) { - ++this.accumulatedTicksWhileInMapOverview; - return; - } - - // Compute how much ticks we missed - const numTicks = 1 + this.accumulatedTicksWhileInMapOverview; - const progress = - this.root.dynamicTickrate.deltaSeconds * + // * 2 because its only a half tile - (same code as ejector) + const progressGrowth = 2 * + this.root.dynamicTickrate.deltaSeconds * this.root.hubGoals.getBeltBaseSpeed() * - globalConfig.itemSpacingOnBelts * // * 2 because its only a half tile - numTicks; - - // Reset accumulated ticks - this.accumulatedTicksWhileInMapOverview = 0; + globalConfig.itemSpacingOnBelts; for (let i = 0; i < this.allEntities.length; ++i) { const entity = this.allEntities[i]; - const aceptorComp = entity.components.ItemAcceptor; - const animations = aceptorComp.itemConsumptionAnimations; + const acceptorComp = entity.components.ItemAcceptor; + const inputs = acceptorComp.currentInputs; - // Process item consumption animations to avoid items popping from the belts - for (let animIndex = 0; animIndex < animations.length; ++animIndex) { - const anim = animations[animIndex]; - anim.animProgress += progress; - if (anim.animProgress > 1) { - fastArrayDelete(animations, animIndex); - animIndex -= 1; - } - } + inputs.forEach((values, index) => { + if (values.animProgress >= 1) return; // items which are inputted already + + values.animProgress += progressGrowth; + + if (values.animProgress < 1) return; + + /** @type {function(InputCompletedArgs) : string} */ + const handler = this.handlers[acceptorComp.type]; + assert(handler, "No handler for acceptor type defined: " + acceptorComp.type); + + // Call implementation + handler({ + root: this.root, + entity, + item: values.item, + slotIndex: index, + extraProgress: values.animProgress - 1, + }); + }); } } @@ -75,17 +84,16 @@ export class ItemAcceptorSystem extends GameSystemWithFilter { } const staticComp = entity.components.StaticMapEntity; - for (let animIndex = 0; animIndex < acceptorComp.itemConsumptionAnimations.length; ++animIndex) { - const { item, slotIndex, animProgress, direction } = acceptorComp.itemConsumptionAnimations[ - animIndex - ]; + acceptorComp.currentInputs.forEach((values, index) => { + const { item, animProgress, direction } = values; + if (animProgress >= 1) return; // items which are inputted already - const slotData = acceptorComp.slots[slotIndex]; + const slotData = acceptorComp.slots[index]; const realSlotPos = staticComp.localTileToWorld(slotData.pos); if (!chunk.tileSpaceRectangle.containsPoint(realSlotPos.x, realSlotPos.y)) { // Not within this chunk - continue; + return; } const fadeOutDirection = enumDirectionToVector[staticComp.localDirectionToWorld(direction)]; @@ -100,7 +108,49 @@ export class ItemAcceptorSystem extends GameSystemWithFilter { parameters, globalConfig.defaultItemDiameter ); - } + }); } } + + /** + * @param {InputCompletedArgs} args + */ + input_ITEMPROCESSOR(args) { + const entity = args.entity; + + const itemProcessorComp = entity.components.ItemProcessor; + assert(itemProcessorComp, "No item processor to input item to"); + + itemProcessorComp.inputs.set(args.slotIndex, { + item: args.item, + extraProgress: args.extraProgress, + }); // in the future the item processor will not need a list of items + } + //@SENSETODO this isn't set up like it should be yet + + /** + * @param {InputCompletedArgs} args + */ + input_HUB(args) { + const item = /** @type {ShapeItem} */ (args.item); + assert(item instanceof ShapeItem, "Input for hub is not a shape"); + + this.root.hubGoals.handleDefinitionDelivered(item.definition); + + const acceptorComp = args.entity.components.ItemAcceptor; + acceptorComp.currentInputs.delete(args.slotIndex); + } + + /** + * @param {InputCompletedArgs} args + */ + input_TRASH(args) { + // just remove the item + const acceptorComp = args.entity.components.ItemAcceptor; + acceptorComp.currentInputs.delete(args.slotIndex); + } + + //storage + + //underground belt } diff --git a/src/js/game/systems/item_ejector.js b/src/js/game/systems/item_ejector.js index db37455a..8f08b6b0 100644 --- a/src/js/game/systems/item_ejector.js +++ b/src/js/game/systems/item_ejector.js @@ -139,169 +139,76 @@ export class ItemEjectorSystem extends GameSystemWithFilter { update() { this.staleAreaDetector.update(); - // Precompute effective belt speed - let progressGrowth = 2 * this.root.dynamicTickrate.deltaSeconds; - - if (G_IS_DEV && globalConfig.debug.instantBelts) { - progressGrowth = 1; - } + // * 2 because its only a half tile - (same code as acceptor) + const progressGrowth = + 2 * + this.root.dynamicTickrate.deltaSeconds * + this.root.hubGoals.getBeltBaseSpeed() * + globalConfig.itemSpacingOnBelts; // Go over all cache entries for (let i = 0; i < this.allEntities.length; ++i) { - const sourceEntity = this.allEntities[i]; - const sourceEjectorComp = sourceEntity.components.ItemEjector; + const entity = this.allEntities[i]; + const ejectorComp = entity.components.ItemEjector; + const slots = ejectorComp.slots; - const slots = sourceEjectorComp.slots; for (let j = 0; j < slots.length; ++j) { - const sourceSlot = slots[j]; - const item = sourceSlot.item; + const slot = slots[j]; + const item = slot.item; if (!item) { - // No item available to be ejected + // No output in progress continue; } // Advance items on the slot - sourceSlot.progress = Math.min( - 1, - sourceSlot.progress + - progressGrowth * - this.root.hubGoals.getBeltBaseSpeed() * - globalConfig.itemSpacingOnBelts - ); + // @SENSETODO do we really want to cap it at one, or should the excess get passed on? + slot.progress = Math.min(1, slot.progress + progressGrowth); if (G_IS_DEV && globalConfig.debug.disableEjectorProcessing) { - sourceSlot.progress = 1.0; + slot.progress = 1; } // Check if we are still in the process of ejecting, can't proceed then - if (sourceSlot.progress < 1.0) { + if (slot.progress < 1) { continue; } // Check if we are ejecting to a belt path - const destPath = sourceSlot.cachedBeltPath; + const destPath = slot.cachedBeltPath; if (destPath) { // Try passing the item over if (destPath.tryAcceptItem(item)) { - sourceSlot.item = null; + slot.item = null; } - // Always stop here, since there can *either* be a belt path *or* - // a slot + // Always stop here, since there can *either* be a belt path *or* an acceptor continue; } // Check if the target acceptor can actually accept this item - const destEntity = sourceSlot.cachedTargetEntity; - const destSlot = sourceSlot.cachedDestSlot; - if (destSlot) { + const destEntity = slot.cachedTargetEntity; + const destSlot = slot.cachedDestSlot; + if (destEntity && destSlot) { const targetAcceptorComp = destEntity.components.ItemAcceptor; - if (!targetAcceptorComp.canAcceptItem(destSlot.index, item)) { - continue; - } - - // Try to hand over the item - if (this.tryPassOverItem(item, destEntity, destSlot.index)) { + const extraProgress = slot.progress - 1; + if ( + targetAcceptorComp.tryAcceptItem( + destSlot.index, + destSlot.acceptedDirection, + item, + extraProgress + ) + ) { // Handover successful, clear slot - if (!this.root.app.settings.getAllSettings().simplifiedBelts) { - targetAcceptorComp.onItemAccepted( - destSlot.index, - destSlot.acceptedDirection, - item - ); - } - sourceSlot.item = null; - continue; + slot.item = null; } } + + //@SENSETODO deal with other buildings - acceptor code on them needs to be different! } } } - /** - * - * @param {BaseItem} item - * @param {Entity} receiver - * @param {number} slotIndex - */ - tryPassOverItem(item, receiver, slotIndex) { - // Try figuring out how what to do with the item - // @TODO: Kinda hacky. How to solve this properly? Don't want to go through inheritance hell. - - const beltComp = receiver.components.Belt; - if (beltComp) { - const path = beltComp.assignedPath; - assert(path, "belt has no path"); - if (path.tryAcceptItem(item)) { - return true; - } - // Belt can have nothing else - return false; - } - - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - // - // NOTICE ! THIS CODE IS DUPLICATED IN THE BELT PATH FOR PERFORMANCE REASONS - // - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - - const itemProcessorComp = receiver.components.ItemProcessor; - if (itemProcessorComp) { - // Check for potential filters - if (!this.root.systemMgr.systems.itemProcessor.checkRequirements(receiver, item, slotIndex)) { - return false; - } - - // Its an item processor .. - if (itemProcessorComp.tryTakeItem(item, slotIndex)) { - return true; - } - // Item processor can have nothing else - return false; - } - - const undergroundBeltComp = receiver.components.UndergroundBelt; - if (undergroundBeltComp) { - // Its an underground belt. yay. - if ( - undergroundBeltComp.tryAcceptExternalItem( - item, - this.root.hubGoals.getUndergroundBeltBaseSpeed() - ) - ) { - return true; - } - - // Underground belt can have nothing else - return false; - } - - const storageComp = receiver.components.Storage; - if (storageComp) { - // It's a storage - if (storageComp.canAcceptItem(item)) { - storageComp.takeItem(item); - return true; - } - - // Storage can't have anything else - return false; - } - - const filterComp = receiver.components.Filter; - if (filterComp) { - // It's a filter! Unfortunately the filter has to know a lot about it's - // surrounding state and components, so it can't be within the component itself. - if (this.root.systemMgr.systems.filter.tryAcceptItem(receiver, slotIndex, item)) { - return true; - } - } - - return false; - } - /** * @param {DrawParameters} parameters * @param {MapChunkView} chunk @@ -390,11 +297,6 @@ export class ItemEjectorSystem extends GameSystemWithFilter { progress = Math.min(maxProgress, progress); } - // Skip if the item would barely be visible - if (progress < 0.05) { - continue; - } - const realPosition = staticComp.localTileToWorld(slot.pos); if (!chunk.tileSpaceRectangle.containsPoint(realPosition.x, realPosition.y)) { // Not within this chunk @@ -419,4 +321,90 @@ export class ItemEjectorSystem extends GameSystemWithFilter { } } } + + /////////////////////////////////////////////////////// OBSOLETE + + /** + * + * @param {BaseItem} item + * @param {Entity} receiver + * @param {number} slotIndex + */ + tryPassOverItem(item, receiver, slotIndex) { + // Try figuring out how what to do with the item + // @TODO: Kinda hacky. How to solve this properly? Don't want to go through inheritance hell. + + const beltComp = receiver.components.Belt; + if (beltComp) { + const path = beltComp.assignedPath; + assert(path, "belt has no path"); + if (path.tryAcceptItem(item)) { + return true; + } + // Belt can have nothing else + return false; + } + + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + // + // NOTICE ! THIS CODE IS DUPLICATED IN THE BELT PATH FOR PERFORMANCE REASONS + // + //////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + + const itemProcessorComp = receiver.components.ItemProcessor; + if (itemProcessorComp) { + // Check for potential filters + if (!this.root.systemMgr.systems.itemProcessor.checkRequirements(receiver, item, slotIndex)) { + return false; + } + + // Its an item processor .. + //if (itemProcessorComp.tryTakeItem(item, slotIndex)) { + // return true; + //} + // Item processor can have nothing else + return false; + } + + const undergroundBeltComp = receiver.components.UndergroundBelt; + if (undergroundBeltComp) { + // Its an underground belt. yay. + if ( + undergroundBeltComp.tryAcceptExternalItem( + item, + this.root.hubGoals.getUndergroundBeltBaseSpeed() + ) + ) { + return true; + } + + // Underground belt can have nothing else + return false; + } + + const storageComp = receiver.components.Storage; + if (storageComp) { + // It's a storage + if (storageComp.canAcceptItem(item)) { + storageComp.takeItem(item); + return true; + } + + // Storage can't have anything else + return false; + } + + const filterComp = receiver.components.Filter; + if (filterComp) { + // It's a filter! Unfortunately the filter has to know a lot about it's + // surrounding state and components, so it can't be within the component itself. + if (this.root.systemMgr.systems.filter.tryAcceptItem(receiver, slotIndex, item)) { + return true; + } + } + + return false; + } } diff --git a/src/js/game/systems/item_processor.js b/src/js/game/systems/item_processor.js index 36c837fb..bb5e9849 100644 --- a/src/js/game/systems/item_processor.js +++ b/src/js/game/systems/item_processor.js @@ -15,6 +15,7 @@ import { ShapeItem } from "../items/shape_item"; /** * We need to allow queuing charges, otherwise the throughput will stall */ +//@SENSETODO not sure if this is true anymore const MAX_QUEUED_CHARGES = 2; /** @@ -22,6 +23,7 @@ const MAX_QUEUED_CHARGES = 2; * * @typedef {{ * item: BaseItem, + * extraProgress?: number, * preferredSlot?: number, * requiredSlot?: number, * doNotTrack?: boolean @@ -32,8 +34,7 @@ const MAX_QUEUED_CHARGES = 2; * Type of a processor implementation * @typedef {{ * entity: Entity, - * items: Map, - * inputCount: number, + * inputs: Map, * outItems: Array * }} ProcessorImplementationPayload */ @@ -133,6 +134,8 @@ export class ItemProcessorSystem extends GameSystemWithFilter { } } + //@SENSETODO add code in here that handles queued outputs -rearrange where this is too + // If the charge was entirely emptied to the outputs, start the next charge if (itemsToEject.length === 0) { processorComp.ongoingCharges.shift(); @@ -195,7 +198,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter { // DEFAULT // By default, we can start processing once all inputs are there case null: { - return processorComp.inputCount >= processorComp.inputsPerCharge; + return processorComp.inputs.size >= processorComp.inputsPerCharge; } // QUAD PAINTER @@ -204,7 +207,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter { const pinsComp = entity.components.WiredPins; // First slot is the shape, so if it's not there we can't do anything - const shapeItem = /** @type {ShapeItem} */ (processorComp.inputSlots.get(0)); + const shapeItem = /** @type {ShapeItem} */ (processorComp.inputs.get(0).item); if (!shapeItem) { return false; } @@ -233,7 +236,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter { // Check if all colors of the enabled slots are there for (let i = 0; i < slotStatus.length; ++i) { - if (slotStatus[i] && !processorComp.inputSlots.get(1 + i)) { + if (slotStatus[i] && !processorComp.inputs.get(1 + i)) { // A slot which is enabled wasn't enabled. Make sure if there is anything on the quadrant, // it is not possible to paint, but if there is nothing we can ignore it for (let j = 0; j < 4; ++j) { @@ -260,8 +263,8 @@ export class ItemProcessorSystem extends GameSystemWithFilter { startNewCharge(entity) { const processorComp = entity.components.ItemProcessor; - // First, take items - const items = processorComp.inputSlots; + // First, take inputs + const inputs = processorComp.inputs; /** @type {Array} */ const outItems = []; @@ -273,9 +276,8 @@ export class ItemProcessorSystem extends GameSystemWithFilter { // Call implementation handler({ entity, - items, + inputs: inputs, outItems, - inputCount: processorComp.inputCount, }); // Track produced items @@ -298,8 +300,8 @@ export class ItemProcessorSystem extends GameSystemWithFilter { remainingTime: timeToProcess, }); - processorComp.inputSlots.clear(); - processorComp.inputCount = 0; + processorComp.inputs.clear(); //@SENSETODO temp, will completely replace processorcomp.inputs with acceptor inputs later + entity.components.ItemAcceptor.currentInputs.clear(); } /** @@ -314,12 +316,12 @@ export class ItemProcessorSystem extends GameSystemWithFilter { const processorComp = payload.entity.components.ItemProcessor; for (let i = 0; i < 2; ++i) { - const item = payload.items.get(i); - if (!item) { + const input = payload.inputs.get(i); + if (!input || !input.item) { continue; } payload.outItems.push({ - item, + item: input.item, preferredSlot: processorComp.nextOutputSlot++ % availableSlots, doNotTrack: true, }); @@ -331,7 +333,8 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_CUTTER(payload) { - const inputItem = /** @type {ShapeItem} */ (payload.items.get(0)); + const input = payload.inputs.get(0); + const inputItem = /** @type {ShapeItem} */ (input.item); assert(inputItem instanceof ShapeItem, "Input for cut is not a shape"); const inputDefinition = inputItem.definition; @@ -357,7 +360,8 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_CUTTER_QUAD(payload) { - const inputItem = /** @type {ShapeItem} */ (payload.items.get(0)); + const input = payload.inputs.get(0); + const inputItem = /** @type {ShapeItem} */ (input.item); assert(inputItem instanceof ShapeItem, "Input for cut is not a shape"); const inputDefinition = inputItem.definition; @@ -383,7 +387,8 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_ROTATER(payload) { - const inputItem = /** @type {ShapeItem} */ (payload.items.get(0)); + const input = payload.inputs.get(0); + const inputItem = /** @type {ShapeItem} */ (input.item); assert(inputItem instanceof ShapeItem, "Input for rotation is not a shape"); const inputDefinition = inputItem.definition; @@ -397,7 +402,8 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_ROTATER_CCW(payload) { - const inputItem = /** @type {ShapeItem} */ (payload.items.get(0)); + const input = payload.inputs.get(0); + const inputItem = /** @type {ShapeItem} */ (input.item); assert(inputItem instanceof ShapeItem, "Input for rotation is not a shape"); const inputDefinition = inputItem.definition; @@ -411,7 +417,8 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_ROTATER_180(payload) { - const inputItem = /** @type {ShapeItem} */ (payload.items.get(0)); + const input = payload.inputs.get(0); + const inputItem = /** @type {ShapeItem} */ (input.item); assert(inputItem instanceof ShapeItem, "Input for rotation is not a shape"); const inputDefinition = inputItem.definition; @@ -425,8 +432,10 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_STACKER(payload) { - const lowerItem = /** @type {ShapeItem} */ (payload.items.get(0)); - const upperItem = /** @type {ShapeItem} */ (payload.items.get(1)); + const lowerInput = payload.inputs.get(0); + const upperInput = payload.inputs.get(0); + const lowerItem = /** @type {ShapeItem} */ (lowerInput.item); + const upperItem = /** @type {ShapeItem} */ (upperInput.item); assert(lowerItem instanceof ShapeItem, "Input for lower stack is not a shape"); assert(upperItem instanceof ShapeItem, "Input for upper stack is not a shape"); @@ -451,9 +460,11 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_MIXER(payload) { + const input1 = payload.inputs.get(0); + const input2 = payload.inputs.get(1); // Find both colors and combine them - const item1 = /** @type {ColorItem} */ (payload.items.get(0)); - const item2 = /** @type {ColorItem} */ (payload.items.get(1)); + const item1 = /** @type {ColorItem} */ (input1.item); + const item2 = /** @type {ColorItem} */ (input2.item); assert(item1 instanceof ColorItem, "Input for color mixer is not a color"); assert(item2 instanceof ColorItem, "Input for color mixer is not a color"); @@ -475,8 +486,10 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_PAINTER(payload) { - const shapeItem = /** @type {ShapeItem} */ (payload.items.get(0)); - const colorItem = /** @type {ColorItem} */ (payload.items.get(1)); + const input1 = payload.inputs.get(0); + const input2 = payload.inputs.get(1); + const shapeItem = /** @type {ShapeItem} */ (input1.item); + const colorItem = /** @type {ColorItem} */ (input2.item); const colorizedDefinition = this.root.shapeDefinitionMgr.shapeActionPaintWith( shapeItem.definition, @@ -492,9 +505,9 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_PAINTER_DOUBLE(payload) { - const shapeItem1 = /** @type {ShapeItem} */ (payload.items.get(0)); - const shapeItem2 = /** @type {ShapeItem} */ (payload.items.get(1)); - const colorItem = /** @type {ColorItem} */ (payload.items.get(2)); + const shapeItem1 = /** @type {ShapeItem} */ (payload.inputs.get(0).item); + const shapeItem2 = /** @type {ShapeItem} */ (payload.inputs.get(1).item); + const colorItem = /** @type {ColorItem} */ (payload.inputs.get(2).item); assert(shapeItem1 instanceof ShapeItem, "Input for painter is not a shape"); assert(shapeItem2 instanceof ShapeItem, "Input for painter is not a shape"); @@ -522,13 +535,14 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_PAINTER_QUAD(payload) { - const shapeItem = /** @type {ShapeItem} */ (payload.items.get(0)); + const input = payload.inputs.get(0); + const shapeItem = /** @type {ShapeItem} */ (input.item); assert(shapeItem instanceof ShapeItem, "Input for painter is not a shape"); /** @type {Array} */ const colors = [null, null, null, null]; for (let i = 0; i < 4; ++i) { - const colorItem = /** @type {ColorItem} */ (payload.items.get(i + 1)); + const colorItem = /** @type {ColorItem} */ (payload.inputs.get(i + 1).item); if (colorItem) { colors[i] = colorItem.color; } @@ -549,7 +563,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter { */ process_READER(payload) { // Pass through the item - const item = payload.items.get(0); + const item = payload.inputs.get(0).item; payload.outItems.push({ item, doNotTrack: true, @@ -565,17 +579,17 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_HUB(payload) { - const hubComponent = payload.entity.components.Hub; - assert(hubComponent, "Hub item processor has no hub component"); - - // Hardcoded - for (let i = 0; i < payload.inputCount; ++i) { - const item = /** @type {ShapeItem} */ (payload.items.get(i)); - if (!item) { - continue; - } - this.root.hubGoals.handleDefinitionDelivered(item.definition); - } + //const input = payload.inputs.get(i); + //const hubComponent = payload.entity.components.Hub; + //assert(hubComponent, "Hub item processor has no hub component"); + //// Hardcoded + //for (let i = 0; i < payload.inputCount; ++i) { + // const item = /** @type {ShapeItem} */ (payload.inputs.get(i)); + // if (!item) { + // continue; + // } + // this.root.hubGoals.handleDefinitionDelivered(item.definition); + //} } /** @@ -583,7 +597,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter { */ process_GOAL(payload) { const goalComp = payload.entity.components.GoalAcceptor; - const item = payload.items.get(0); + const item = payload.inputs.get(0).item; const now = this.root.time.now(); if (goalComp.item && !item.equals(goalComp.item)) {