diff --git a/src/js/game/belt_path.js b/src/js/game/belt_path.js index c8895d3e..fa65c11c 100644 --- a/src/js/game/belt_path.js +++ b/src/js/game/belt_path.js @@ -267,10 +267,18 @@ export class BeltPath extends BasicSerializableObject { } const matchingSlotIndex = matchingSlot.index; - const matchingDirection = enumInvertedDirections[ejectingDirection]; return function (item, startProgress = 0.0) { - if (targetAcceptorComp.tryAcceptItem(matchingSlotIndex, matchingDirection, item, startProgress)) { + const storageComp = targetEntity.components.Storage; + if ( + storageComp && + storageComp.tryAcceptItem(item) && + targetAcceptorComp.tryAcceptItem(matchingSlotIndex, item, startProgress) + ) { + // unique duplicated code for storage + return true; + } + if (targetAcceptorComp.tryAcceptItem(matchingSlotIndex, item, startProgress)) { return true; } return false; diff --git a/src/js/game/components/item_acceptor.js b/src/js/game/components/item_acceptor.js index 4abc0117..0098d9d9 100644 --- a/src/js/game/components/item_acceptor.js +++ b/src/js/game/components/item_acceptor.js @@ -24,13 +24,14 @@ import { GameRoot } from "../root"; * filter?: ItemType * }} ItemAcceptorSlotConfig * - * @typedef {Map} ItemAcceptorInputs * - * @typedef {Map} ItemAcceptorCompletedInputs @@ -58,9 +59,9 @@ export class ItemAcceptorComponent extends Component { super(); /** @type {ItemAcceptorInputs} */ - this.inputs = new Map(); + this.inputs = []; /** @type {ItemAcceptorCompletedInputs} */ - this.completedInputs = new Map(); // @SENSETODO does this need to be saved? + this.completedInputs = []; // @SENSETODO does this need to be saved? this.setSlots(slots); } @@ -86,22 +87,27 @@ export class ItemAcceptorComponent extends Component { /** * Called when trying to input a new item * @param {number} slotIndex - * @param {enumDirection} direction * @param {BaseItem} 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 */ - tryAcceptItem(slotIndex, direction, item, startProgress = 0.0) { + tryAcceptItem(slotIndex, item, startProgress = 0.0) { const slot = this.slots[slotIndex]; - if (this.completedInputs.has(slotIndex) || (slot.filter && slot.filter != item.getItemType())) { + for (let i = 0; i < this.completedInputs.length; i++) { + if (this.completedInputs[i].slotIndex == slotIndex) { + return false; + } + } + + if (slot.filter && slot.filter != item.getItemType()) { return false; } // if the start progress is bigger than 0.5, the remainder should get passed on to the ejector - this.inputs.set(slotIndex, { + this.inputs.push({ + slotIndex, item, - direction, animProgress: startProgress, }); return true; diff --git a/src/js/game/components/item_processor.js b/src/js/game/components/item_processor.js index 59a9f6d6..f5b412cd 100644 --- a/src/js/game/components/item_processor.js +++ b/src/js/game/components/item_processor.js @@ -33,10 +33,10 @@ export const enumItemProcessorRequirements = { * extraProgress?: number, * requiredSlot?: number, * preferredSlot?: number - * }} EjectorItemToEject - * - * @typedef {{ - * remainingTime: number, + * }} EjectorItemToEject */ + +/** @typedef {{ + * remainingProgress: number, * items: Array, * }} EjectorCharge * @@ -103,12 +103,6 @@ export class ItemProcessorComponent extends Component { */ this.currentCharge = null; - /** - * How much processing time we have left from the last tick - * @type {number} - */ - this.bonusTime = 0; - /** * @type {Array} */ diff --git a/src/js/game/components/storage.js b/src/js/game/components/storage.js index be243a44..ce179416 100644 --- a/src/js/game/components/storage.js +++ b/src/js/game/components/storage.js @@ -46,32 +46,19 @@ export class StorageComponent extends Component { * Returns whether this storage can accept the item * @param {BaseItem} item */ - canAcceptItem(item) { + tryAcceptItem(item) { if (this.storedCount >= this.maximumStorage) { return false; } - if (!this.storedItem || this.storedCount === 0) { - return true; - } - const itemType = item.getItemType(); - - // Check type matches - if (itemType !== this.storedItem.getItemType()) { + if (this.storedCount > 0 && this.storedItem && itemType !== this.storedItem.getItemType()) { return false; } - if (itemType === "color") { - return /** @type {ColorItem} */ (this.storedItem).color === /** @type {ColorItem} */ (item).color; - } + this.storedItem = item; + this.storedCount++; - if (itemType === "shape") { - return ( - /** @type {ShapeItem} */ (this.storedItem).definition.getHash() === - /** @type {ShapeItem} */ (item).definition.getHash() - ); - } - return false; + return true; } /** diff --git a/src/js/game/hub_goals.js b/src/js/game/hub_goals.js index c96e2d79..d1e0dda8 100644 --- a/src/js/game/hub_goals.js +++ b/src/js/game/hub_goals.js @@ -509,9 +509,9 @@ export class HubGoals extends BasicSerializableObject { /** * Processor time to process * @param {enumItemProcessorTypes} processorType - * @returns {number} process time in seconds + * @returns {number} progress in tiles */ - getProcessingTime(processorType) { + getProcessingProgress(processorType) { if (this.root.gameMode.throughputDoesNotMatter()) { return 0; } @@ -531,13 +531,20 @@ export class HubGoals extends BasicSerializableObject { case enumItemProcessorTypes.painter: case enumItemProcessorTypes.painterDouble: case enumItemProcessorTypes.painterQuad: { - return this.getProcessorTimeWithUpgrades(this.upgradeImprovements.painting, processorType); + assert( + globalConfig.buildingRatios[processorType], + "Processor type has no speed set in globalConfig.buildingRatios: " + processorType + ); + return (globalConfig.buildingRatios[processorType] - 1) / this.upgradeImprovements.painting; } - case enumItemProcessorTypes.cutter: case enumItemProcessorTypes.cutterQuad: case enumItemProcessorTypes.stacker: { - return this.getProcessorTimeWithUpgrades(this.upgradeImprovements.processors, processorType); + assert( + globalConfig.buildingRatios[processorType], + "Processor type has no speed set in globalConfig.buildingRatios: " + processorType + ); + return (globalConfig.buildingRatios[processorType] - 1) / this.upgradeImprovements.processors; } default: if (MOD_ITEM_PROCESSOR_SPEEDS[processorType]) { @@ -549,31 +556,16 @@ export class HubGoals extends BasicSerializableObject { return 0; } - /** - * @param {number} upgrade - * @param {number} upgrade - */ - getProcessorTimeWithUpgrades(upgrade, processorType) { - assert( - globalConfig.buildingRatios[processorType], - "Processor type has no speed set in globalConfig.buildingSpeeds: " + processorType - ); - - // super complicated maths here, but it works - const processorTime = - globalConfig.buildingRatios[processorType] / globalConfig.beltSpeedItemsPerSecond; - return processorTime / upgrade; - } /** * Processor speed * @param {enumItemProcessorTypes} processorType - * @returns {number} process time in seconds + * @returns {number} items/sec */ getProcessorBaseSpeed(processorType) { - const time = this.getProcessingTime(processorType); - if (!time) { + const progress = this.getProcessingProgress(processorType); + if (!progress) { return this.getBeltBaseSpeed(); } - return 1 / time; + return globalConfig.beltSpeedItemsPerSecond / (progress + 1); } } diff --git a/src/js/game/systems/item_acceptor.js b/src/js/game/systems/item_acceptor.js index 23d4605d..5b3ed3ca 100644 --- a/src/js/game/systems/item_acceptor.js +++ b/src/js/game/systems/item_acceptor.js @@ -23,19 +23,22 @@ export class ItemAcceptorSystem extends GameSystemWithFilter { const inputs = acceptorComp.inputs; const maxProgress = 0.5; - inputs.forEach((values, index) => { - values.animProgress += progressGrowth; + for (let i = 0; i < inputs.length; i++) { + const input = inputs[i]; + input.animProgress += progressGrowth; - if (values.animProgress < maxProgress) { - return; + if (input.animProgress < maxProgress) { + continue; } - inputs.delete(index); - acceptorComp.completedInputs.set(index, { - item: values.item, - extraProgress: values.animProgress - maxProgress, + inputs.splice(i, 1); + i--; + acceptorComp.completedInputs.push({ + slotIndex: input.slotIndex, + item: input.item, + extraProgress: input.animProgress - maxProgress, }); // will be handled on the SAME frame due to processor system being afterwards - }); + } } } @@ -58,10 +61,11 @@ export class ItemAcceptorSystem extends GameSystemWithFilter { } const staticComp = entity.components.StaticMapEntity; - acceptorComp.inputs.forEach((values, index) => { - const { item, animProgress, direction } = values; + for (let i = 0; i < acceptorComp.inputs.length; i++) { + const input = acceptorComp.inputs[i]; + const { item, animProgress, slotIndex } = input; - const slotData = acceptorComp.slots[index]; + const slotData = acceptorComp.slots[slotIndex]; const realSlotPos = staticComp.localTileToWorld(slotData.pos); if (!chunk.tileSpaceRectangle.containsPoint(realSlotPos.x, realSlotPos.y)) { @@ -69,7 +73,8 @@ export class ItemAcceptorSystem extends GameSystemWithFilter { return; } - const fadeOutDirection = enumDirectionToVector[staticComp.localDirectionToWorld(direction)]; + const fadeOutDirection = + enumDirectionToVector[staticComp.localDirectionToWorld(slotData.direction)]; const finalTile = realSlotPos.subScalars( fadeOutDirection.x * (animProgress - 0.5), fadeOutDirection.y * (animProgress - 0.5) @@ -81,7 +86,7 @@ export class ItemAcceptorSystem extends GameSystemWithFilter { parameters, globalConfig.defaultItemDiameter ); - }); + } } } } diff --git a/src/js/game/systems/item_ejector.js b/src/js/game/systems/item_ejector.js index bfcf2146..8968a383 100644 --- a/src/js/game/systems/item_ejector.js +++ b/src/js/game/systems/item_ejector.js @@ -152,47 +152,36 @@ export class ItemEjectorSystem extends GameSystemWithFilter { const slots = ejectorComp.slots; for (let j = 0; j < slots.length; ++j) { - const slot = slots[j]; - const item = slot.item; + const sourceSlot = slots[j]; + const item = sourceSlot.item; + if (!item) { // No output in progress continue; } - if (slot.progress < maxProgress) { + if (sourceSlot.progress < maxProgress) { // Advance items on the slot - slot.progress += progressGrowth; + sourceSlot.progress += progressGrowth; + } - // limit the progress to stop items being too close - if (slot.cachedTargetEntity && slot.cachedDestSlot) { - const acceptorComp = slot.cachedTargetEntity.components.ItemAcceptor; - const acceptorInput = acceptorComp.inputs.get(slot.cachedDestSlot.index); - - if (acceptorInput) { - const maxProgress = - 0.5 + acceptorInput.animProgress - globalConfig.itemSpacingOnBelts; - slot.progress = Math.min(maxProgress, slot.progress); - } - } - - if (G_IS_DEV && globalConfig.debug.disableEjectorProcessing) { - slot.progress = maxProgress; - } + if (G_IS_DEV && globalConfig.debug.disableEjectorProcessing) { + sourceSlot.progress = maxProgress; } // Check if we are still in the process of ejecting, can't proceed then - if (slot.progress < maxProgress) { + if (sourceSlot.progress < maxProgress) { continue; } - const extraProgress = slot.progress - maxProgress; + const extraProgress = sourceSlot.progress - maxProgress; // Check if we are ejecting to a belt path - const destPath = slot.cachedBeltPath; + const destPath = sourceSlot.cachedBeltPath; if (destPath) { // Try passing the item over if (destPath.tryAcceptItem(item, extraProgress)) { - slot.item = null; + sourceSlot.item = null; } // Always stop here, since there can *either* be a belt path *or* an acceptor @@ -200,26 +189,22 @@ export class ItemEjectorSystem extends GameSystemWithFilter { } // Check if the target acceptor can actually accept this item - const destEntity = slot.cachedTargetEntity; - const destSlot = slot.cachedDestSlot; + const destEntity = sourceSlot.cachedTargetEntity; + const destSlot = sourceSlot.cachedDestSlot; if (destEntity && destSlot) { - // storage has to have its own duplicated logic, as it's the ONLY building which the acceptor can't filter for it - const storageComp = destEntity.components.Storage; - if (storageComp && !storageComp.canAcceptItem(item)) { - continue; - } - const targetAcceptorComp = destEntity.components.ItemAcceptor; + const storageComp = destEntity.components.Storage; if ( - targetAcceptorComp.tryAcceptItem( - destSlot.index, - destSlot.acceptedDirection, - item, - extraProgress - ) + storageComp && + storageComp.tryAcceptItem(item) && + targetAcceptorComp.tryAcceptItem(destSlot.index, item, extraProgress) ) { + // unique duplicated code for storage - hacky :( + return true; + } + if (targetAcceptorComp.tryAcceptItem(destSlot.index, item, extraProgress)) { // Handover successful, clear slot - slot.item = null; + sourceSlot.item = null; } } } @@ -261,11 +246,6 @@ export class ItemEjectorSystem extends GameSystemWithFilter { continue; } - // don't render items at the start of output - if (slot.progress < 0.05) { - continue; - } - // Limit the progress to the maximum available space on the next belt (also see #1000) let progress = Math.min(0.5, slot.progress); const nextBeltPath = slot.cachedBeltPath; diff --git a/src/js/game/systems/item_processor.js b/src/js/game/systems/item_processor.js index bde78572..a40403aa 100644 --- a/src/js/game/systems/item_processor.js +++ b/src/js/game/systems/item_processor.js @@ -18,7 +18,6 @@ import { ShapeItem } from "../items/shape_item"; * * @typedef {{ * item: BaseItem, - * extraProgress?: number, * preferredSlot?: number, * requiredSlot?: number, * doNotTrack?: boolean @@ -29,7 +28,7 @@ import { ShapeItem } from "../items/shape_item"; * Type of a processor implementation * @typedef {{ * entity: Entity, - * inputs: import("../components/item_acceptor").ItemAcceptorCompletedInputs, + * items: Map, * outItems: Array * }} ProcessorImplementationPayload */ @@ -72,6 +71,11 @@ export class ItemProcessorSystem extends GameSystemWithFilter { } update() { + const progressGrowth = + this.root.dynamicTickrate.deltaSeconds * + globalConfig.beltSpeedItemsPerSecond * + globalConfig.itemSpacingOnBelts; + for (let i = 0; i < this.allEntities.length; ++i) { const entity = this.allEntities[i]; @@ -88,21 +92,21 @@ export class ItemProcessorSystem extends GameSystemWithFilter { const currentCharge = processorComp.currentCharge; if (currentCharge) { // Process next charge - if (currentCharge.remainingTime > 0.0) { - currentCharge.remainingTime -= this.root.dynamicTickrate.deltaSeconds; - if (currentCharge.remainingTime < 0.0) { - // Add bonus time, this is the time we spent too much - processorComp.bonusTime += -currentCharge.remainingTime; - } + if (currentCharge.remainingProgress > 0.0) { + currentCharge.remainingProgress -= progressGrowth; } // Check if it finished - but don't finish another charge if there are still items queued to eject, or we might keep backing up - if (currentCharge.remainingTime <= 0.0 && processorComp.queuedEjects.length < 1) { + if (currentCharge.remainingProgress <= 0.0 && processorComp.queuedEjects.length < 1) { const itemsToEject = currentCharge.items; + const extraProgress = -currentCharge.remainingProgress; + console.log(extraProgress); // Go over all items and try to eject them for (let j = 0; j < itemsToEject.length; ++j) { - processorComp.queuedEjects.push(itemsToEject[j]); + const items = itemsToEject[j]; + items.extraProgress = extraProgress; + processorComp.queuedEjects.push(items); } processorComp.currentCharge = null; @@ -111,9 +115,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter { // Go over all items and try to eject them for (let j = 0; j < processorComp.queuedEjects.length; ++j) { - const { item, requiredSlot, preferredSlot, extraProgress = 0 } = processorComp.queuedEjects[ - j - ]; + const { item, requiredSlot, preferredSlot, extraProgress } = processorComp.queuedEjects[j]; assert(ejectorComp, "To eject items, the building needs to have an ejector"); @@ -160,7 +162,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter { // DEFAULT // By default, we can start processing once all inputs are there case null: { - return acceptorComp.completedInputs.size >= processorComp.inputsPerCharge; + return acceptorComp.completedInputs.length >= processorComp.inputsPerCharge; } // QUAD PAINTER @@ -168,7 +170,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter { case enumItemProcessorRequirements.painterQuad: { const pinsComp = entity.components.WiredPins; - const input = acceptorComp.completedInputs.get(0); + const input = acceptorComp.completedInputs[0]; if (!input) { return false; } @@ -203,7 +205,10 @@ 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] && !acceptorComp.completedInputs.get(1 + i)) { + if ( + slotStatus[i] && + !acceptorComp.completedInputs.find(input => input.slotIndex == i + 1) // @TODO this is slow + ) { // 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) { @@ -234,6 +239,16 @@ export class ItemProcessorSystem extends GameSystemWithFilter { // First, take inputs - but only ones that are completed const inputs = acceptorComp.completedInputs; + // split inputs efficiently + let items = new Map(); + let extraProgress = 0; + for (let i = 0; i < inputs.length; i++) { + const input = inputs[i]; + + items.set(input.slotIndex, input.item); + extraProgress = Math.max(extraProgress, input.extraProgress); + } + const outItems = []; /** @type {function(ProcessorImplementationPayload) : void} */ @@ -243,7 +258,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter { // Call implementation handler({ entity, - inputs, + items, outItems, }); @@ -254,19 +269,14 @@ export class ItemProcessorSystem extends GameSystemWithFilter { } } - // Queue Charge - but not if we have no outItems - const originalTime = this.root.hubGoals.getProcessingTime(processorComp.type); - - const bonusTimeToApply = Math.min(originalTime, processorComp.bonusTime); - const timeToProcess = originalTime - bonusTimeToApply; - - processorComp.bonusTime -= bonusTimeToApply; + // Queue Charge + const progress = this.root.hubGoals.getProcessingProgress(processorComp.type); processorComp.currentCharge = { items: outItems, - remainingTime: timeToProcess, + remainingProgress: progress - extraProgress, }; - acceptorComp.completedInputs.clear(); + acceptorComp.completedInputs = []; } /** @@ -281,13 +291,12 @@ export class ItemProcessorSystem extends GameSystemWithFilter { const processorComp = payload.entity.components.ItemProcessor; for (let i = 0; i < 2; ++i) { - const input = payload.inputs.get(i); - if (!input || !input.item) { + const item = payload.items.get(i); + if (!item) { continue; } payload.outItems.push({ - item: input.item, - extraProgress: input.extraProgress, + item, preferredSlot: processorComp.nextOutputSlot++ % availableSlots, doNotTrack: true, }); @@ -299,8 +308,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_CUTTER(payload) { - const input = payload.inputs.get(0); - const inputItem = /** @type {ShapeItem} */ (input.item); + const inputItem = /** @type {ShapeItem} */ (payload.items.get(0)); assert(inputItem instanceof ShapeItem, "Input for cut is not a shape"); const inputDefinition = inputItem.definition; @@ -317,7 +325,6 @@ export class ItemProcessorSystem extends GameSystemWithFilter { payload.outItems.push({ item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(definition), - extraProgress: input.extraProgress, requiredSlot: i, }); } @@ -327,8 +334,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_CUTTER_QUAD(payload) { - const input = payload.inputs.get(0); - const inputItem = /** @type {ShapeItem} */ (input.item); + const inputItem = /** @type {ShapeItem} */ (payload.items.get(0)); assert(inputItem instanceof ShapeItem, "Input for cut is not a shape"); const inputDefinition = inputItem.definition; @@ -345,7 +351,6 @@ export class ItemProcessorSystem extends GameSystemWithFilter { payload.outItems.push({ item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(definition), - extraProgress: input.extraProgress, requiredSlot: i, }); } @@ -355,15 +360,13 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_ROTATER(payload) { - const input = payload.inputs.get(0); - const inputItem = /** @type {ShapeItem} */ (input.item); + const inputItem = /** @type {ShapeItem} */ (payload.items.get(0)); assert(inputItem instanceof ShapeItem, "Input for rotation is not a shape"); const inputDefinition = inputItem.definition; const rotatedDefinition = this.root.shapeDefinitionMgr.shapeActionRotateCW(inputDefinition); payload.outItems.push({ item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(rotatedDefinition), - extraProgress: input.extraProgress, }); } @@ -371,15 +374,13 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_ROTATER_CCW(payload) { - const input = payload.inputs.get(0); - const inputItem = /** @type {ShapeItem} */ (input.item); + const inputItem = /** @type {ShapeItem} */ (payload.items.get(0)); assert(inputItem instanceof ShapeItem, "Input for rotation is not a shape"); const inputDefinition = inputItem.definition; const rotatedDefinition = this.root.shapeDefinitionMgr.shapeActionRotateCCW(inputDefinition); payload.outItems.push({ item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(rotatedDefinition), - extraProgress: input.extraProgress, }); } @@ -387,15 +388,13 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_ROTATER_180(payload) { - const input = payload.inputs.get(0); - const inputItem = /** @type {ShapeItem} */ (input.item); + const inputItem = /** @type {ShapeItem} */ (payload.items.get(0)); assert(inputItem instanceof ShapeItem, "Input for rotation is not a shape"); const inputDefinition = inputItem.definition; const rotatedDefinition = this.root.shapeDefinitionMgr.shapeActionRotate180(inputDefinition); payload.outItems.push({ item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(rotatedDefinition), - extraProgress: input.extraProgress, }); } @@ -403,10 +402,8 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_STACKER(payload) { - const lowerInput = payload.inputs.get(0); - const upperInput = payload.inputs.get(1); - const lowerItem = /** @type {ShapeItem} */ (lowerInput.item); - const upperItem = /** @type {ShapeItem} */ (upperInput.item); + const lowerItem = /** @type {ShapeItem} */ (payload.items.get(0)); + const upperItem = /** @type {ShapeItem} */ (payload.items.get(1)); assert(lowerItem instanceof ShapeItem, "Input for lower stack is not a shape"); assert(upperItem instanceof ShapeItem, "Input for upper stack is not a shape"); @@ -417,7 +414,6 @@ export class ItemProcessorSystem extends GameSystemWithFilter { ); payload.outItems.push({ item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(stackedDefinition), - extraProgress: lowerInput.extraProgress, }); } @@ -432,11 +428,9 @@ 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} */ (input1.item); - const item2 = /** @type {ColorItem} */ (input2.item); + const item1 = /** @type {ColorItem} */ (payload.items.get(0)); + const item2 = /** @type {ColorItem} */ (payload.items.get(1)); assert(item1 instanceof ColorItem, "Input for color mixer is not a color"); assert(item2 instanceof ColorItem, "Input for color mixer is not a color"); @@ -451,7 +445,6 @@ export class ItemProcessorSystem extends GameSystemWithFilter { } payload.outItems.push({ item: COLOR_ITEM_SINGLETONS[resultColor], - extraProgress: input1.extraProgress, }); } @@ -459,10 +452,8 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_PAINTER(payload) { - 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 shapeItem = /** @type {ShapeItem} */ (payload.items.get(0)); + const colorItem = /** @type {ColorItem} */ (payload.items.get(1)); const colorizedDefinition = this.root.shapeDefinitionMgr.shapeActionPaintWith( shapeItem.definition, @@ -471,7 +462,6 @@ export class ItemProcessorSystem extends GameSystemWithFilter { payload.outItems.push({ item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(colorizedDefinition), - extraProgress: input1.extraProgress, }); } @@ -479,12 +469,9 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_PAINTER_DOUBLE(payload) { - const input1 = payload.inputs.get(0); - const input2 = payload.inputs.get(1); - - const shapeItem1 = /** @type {ShapeItem} */ (input1.item); - const shapeItem2 = /** @type {ShapeItem} */ (input2.item); - const colorItem = /** @type {ColorItem} */ (payload.inputs.get(2).item); + const shapeItem1 = /** @type {ShapeItem} */ (payload.items.get(0)); + const shapeItem2 = /** @type {ShapeItem} */ (payload.items.get(1)); + const colorItem = /** @type {ColorItem} */ (payload.items.get(2)); assert(shapeItem1 instanceof ShapeItem, "Input for painter is not a shape"); assert(shapeItem2 instanceof ShapeItem, "Input for painter is not a shape"); @@ -501,12 +488,10 @@ export class ItemProcessorSystem extends GameSystemWithFilter { ); payload.outItems.push({ item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(colorizedDefinition1), - extraProgress: input1.extraProgress, }); payload.outItems.push({ item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(colorizedDefinition2), - extraProgress: input2.extraProgress, }); } @@ -514,16 +499,15 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_PAINTER_QUAD(payload) { - const input = payload.inputs.get(0); - const shapeItem = /** @type {ShapeItem} */ (input.item); + const shapeItem = /** @type {ShapeItem} */ (payload.items.get(0)); 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 colorInput = payload.inputs.get(i + 1); - if (colorInput) { - colors[i] = /** @type {ColorItem} */ (colorInput.item).color; + const colorItem = /** @type {ColorItem} */ (payload.items.get(i + 1)); + if (colorItem) { + colors[i] = colorItem.color; } } @@ -534,7 +518,6 @@ export class ItemProcessorSystem extends GameSystemWithFilter { payload.outItems.push({ item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(colorizedDefinition), - extraProgress: input.extraProgress, }); } @@ -543,17 +526,16 @@ export class ItemProcessorSystem extends GameSystemWithFilter { */ process_READER(payload) { // Pass through the item - const input = payload.inputs.get(0); + const item = payload.items.get(0); payload.outItems.push({ - item: input.item, + item, doNotTrack: true, - extraProgress: input.extraProgress, }); // Track the item const readerComp = payload.entity.components.BeltReader; readerComp.lastItemTimes.push(this.root.time.now()); - readerComp.lastItem = input.item; + readerComp.lastItem = item; } /** @@ -562,13 +544,13 @@ export class ItemProcessorSystem extends GameSystemWithFilter { 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.inputs.size; ++i) { - const input = payload.inputs.get(i); - if (!input) continue; - const item = /** @type {ShapeItem} */ (input.item); - if (!item) continue; + // Hardcoded + for (let i = 0; i < payload.items.size; ++i) { + const item = /** @type {ShapeItem} */ (payload.items.get(i)); + if (!item) { + continue; + } this.root.hubGoals.handleDefinitionDelivered(item.definition); } } @@ -578,7 +560,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter { */ process_GOAL(payload) { const goalComp = payload.entity.components.GoalAcceptor; - const item = payload.inputs.get(0).item; + const item = payload.items.get(0); const now = this.root.time.now(); if (goalComp.item && !item.equals(goalComp.item)) { diff --git a/src/js/game/systems/storage.js b/src/js/game/systems/storage.js index 8db8df06..1fd23d25 100644 --- a/src/js/game/systems/storage.js +++ b/src/js/game/systems/storage.js @@ -30,21 +30,9 @@ export class StorageSystem extends GameSystemWithFilter { const entity = this.allEntities[i]; const storageComp = entity.components.Storage; const pinsComp = entity.components.WiredPins; - const acceptorComp = entity.components.ItemAcceptor; - // Take items from acceptor - const input1 = acceptorComp.completedInputs.get(0); - const input2 = acceptorComp.completedInputs.get(1); - if (input1) { - storageComp.storedItem = input1.item; - storageComp.storedCount++; - acceptorComp.completedInputs.delete(0); - } - if (input2) { - storageComp.storedItem = input2.item; - storageComp.storedCount++; - acceptorComp.completedInputs.delete(1); - } + // storage needs to delete completed inputs, since the items are already added + entity.components.ItemAcceptor.completedInputs = []; // Eject from storage if (storageComp.storedItem && storageComp.storedCount > 0) { diff --git a/src/js/game/systems/underground_belt.js b/src/js/game/systems/underground_belt.js index b28f4207..a3b92825 100644 --- a/src/js/game/systems/underground_belt.js +++ b/src/js/game/systems/underground_belt.js @@ -313,7 +313,7 @@ export class UndergroundBeltSystem extends GameSystemWithFilter { return; } - const input = acceptorComp.completedInputs.get(0); + const input = acceptorComp.completedInputs[0]; if (input) { // Check if the receiver can accept it if ( @@ -323,7 +323,7 @@ export class UndergroundBeltSystem extends GameSystemWithFilter { input.extraProgress ) ) { - acceptorComp.completedInputs.delete(0); + acceptorComp.completedInputs = []; } } }