diff --git a/src/js/game/components/item_processor.js b/src/js/game/components/item_processor.js index 4c0e1835..a3991d1f 100644 --- a/src/js/game/components/item_processor.js +++ b/src/js/game/components/item_processor.js @@ -84,10 +84,16 @@ export class ItemProcessorComponent extends Component { /** * Our current inputs - * @type {Array<{ item: BaseItem, sourceSlot: number }>} + * @type {Array} */ this.inputSlots = []; + /** + * Current input count + * @type {number} + */ + this.inputCount = 0; + /** * What we are currently processing, empty if we don't produce anything rn * requiredSlot: Item *must* be ejected on this slot @@ -115,19 +121,16 @@ export class ItemProcessorComponent extends Component { this.type === enumItemProcessorTypes.goal ) { // Hub has special logic .. not really nice but efficient. - this.inputSlots.push({ item, sourceSlot }); + this.inputSlots.push(item); + this.inputCount++; return true; } // Check that we only take one item per slot - for (let i = 0; i < this.inputSlots.length; ++i) { - const slot = this.inputSlots[i]; - if (slot.sourceSlot === sourceSlot) { - return false; - } - } + if (this.inputSlots[sourceSlot]) return false; - this.inputSlots.push({ item, sourceSlot }); + this.inputSlots[sourceSlot] = item; + this.inputCount++; return true; } } diff --git a/src/js/game/systems/item_processor.js b/src/js/game/systems/item_processor.js index 3794473f..cc654968 100644 --- a/src/js/game/systems/item_processor.js +++ b/src/js/game/systems/item_processor.js @@ -32,8 +32,7 @@ const MAX_QUEUED_CHARGES = 2; * Type of a processor implementation * @typedef {{ * entity: Entity, - * items: Array<{ item: BaseItem, sourceSlot: number }>, - * itemsBySlot: Object, + * items: Array, * outItems: Array * }} ProcessorImplementationPayload */ @@ -189,7 +188,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter { // DEFAULT // By default, we can start processing once all inputs are there case null: { - return processorComp.inputSlots.length >= processorComp.inputsPerCharge; + return processorComp.inputCount >= processorComp.inputsPerCharge; } // QUAD PAINTER @@ -197,18 +196,12 @@ export class ItemProcessorSystem extends GameSystemWithFilter { case enumItemProcessorRequirements.painterQuad: { const pinsComp = entity.components.WiredPins; - /** @type {Object.} */ - const itemsBySlot = {}; - for (let i = 0; i < processorComp.inputSlots.length; ++i) { - itemsBySlot[processorComp.inputSlots[i].sourceSlot] = processorComp.inputSlots[i]; - } - // First slot is the shape, so if it's not there we can't do anything - if (!itemsBySlot[0]) { + if (!processorComp.inputSlots[0]) { return false; } - const shapeItem = /** @type {ShapeItem} */ (itemsBySlot[0].item); + const shapeItem = /** @type {ShapeItem} */ (processorComp.inputSlots[0]); const slotStatus = []; // Check which slots are enabled @@ -233,7 +226,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] && !itemsBySlot[1 + i]) { + if (slotStatus[i] && !processorComp.inputSlots[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) { @@ -262,13 +255,6 @@ export class ItemProcessorSystem extends GameSystemWithFilter { // First, take items const items = processorComp.inputSlots; - processorComp.inputSlots = []; - - /** @type {Object} */ - const itemsBySlot = {}; - for (let i = 0; i < items.length; ++i) { - itemsBySlot[items[i].sourceSlot] = items[i].item; - } /** @type {Array} */ const outItems = []; @@ -281,7 +267,6 @@ export class ItemProcessorSystem extends GameSystemWithFilter { handler({ entity, items, - itemsBySlot, outItems, }); @@ -304,6 +289,9 @@ export class ItemProcessorSystem extends GameSystemWithFilter { items: outItems, remainingTime: timeToProcess, }); + + processorComp.inputSlots.length = 0; + processorComp.inputCount = 0; } /** @@ -320,8 +308,9 @@ export class ItemProcessorSystem extends GameSystemWithFilter { const nextSlot = processorComp.nextOutputSlot++ % availableSlots; for (let i = 0; i < payload.items.length; ++i) { + if (!payload.items[i]) continue; payload.outItems.push({ - item: payload.items[i].item, + item: payload.items[i], preferredSlot: (nextSlot + i) % availableSlots, doNotTrack: true, }); @@ -333,7 +322,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_CUTTER(payload) { - const inputItem = /** @type {ShapeItem} */ (payload.items[0].item); + const inputItem = /** @type {ShapeItem} */ (payload.items[0]); assert(inputItem instanceof ShapeItem, "Input for cut is not a shape"); const inputDefinition = inputItem.definition; @@ -354,7 +343,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_CUTTER_QUAD(payload) { - const inputItem = /** @type {ShapeItem} */ (payload.items[0].item); + const inputItem = /** @type {ShapeItem} */ (payload.items[0]); assert(inputItem instanceof ShapeItem, "Input for cut is not a shape"); const inputDefinition = inputItem.definition; @@ -375,7 +364,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_ROTATER(payload) { - const inputItem = /** @type {ShapeItem} */ (payload.items[0].item); + const inputItem = /** @type {ShapeItem} */ (payload.items[0]); assert(inputItem instanceof ShapeItem, "Input for rotation is not a shape"); const inputDefinition = inputItem.definition; @@ -389,7 +378,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_ROTATER_CCW(payload) { - const inputItem = /** @type {ShapeItem} */ (payload.items[0].item); + const inputItem = /** @type {ShapeItem} */ (payload.items[0]); assert(inputItem instanceof ShapeItem, "Input for rotation is not a shape"); const inputDefinition = inputItem.definition; @@ -403,7 +392,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_ROTATER_180(payload) { - const inputItem = /** @type {ShapeItem} */ (payload.items[0].item); + const inputItem = /** @type {ShapeItem} */ (payload.items[0]); assert(inputItem instanceof ShapeItem, "Input for rotation is not a shape"); const inputDefinition = inputItem.definition; @@ -417,8 +406,8 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_STACKER(payload) { - const lowerItem = /** @type {ShapeItem} */ (payload.itemsBySlot[0]); - const upperItem = /** @type {ShapeItem} */ (payload.itemsBySlot[1]); + const lowerItem = /** @type {ShapeItem} */ (payload.items[0]); + const upperItem = /** @type {ShapeItem} */ (payload.items[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"); @@ -444,8 +433,8 @@ export class ItemProcessorSystem extends GameSystemWithFilter { */ process_MIXER(payload) { // Find both colors and combine them - const item1 = /** @type {ColorItem} */ (payload.items[0].item); - const item2 = /** @type {ColorItem} */ (payload.items[1].item); + const item1 = /** @type {ColorItem} */ (payload.items[0]); + const item2 = /** @type {ColorItem} */ (payload.items[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"); @@ -467,8 +456,8 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_PAINTER(payload) { - const shapeItem = /** @type {ShapeItem} */ (payload.itemsBySlot[0]); - const colorItem = /** @type {ColorItem} */ (payload.itemsBySlot[1]); + const shapeItem = /** @type {ShapeItem} */ (payload.items[0]); + const colorItem = /** @type {ColorItem} */ (payload.items[1]); const colorizedDefinition = this.root.shapeDefinitionMgr.shapeActionPaintWith( shapeItem.definition, @@ -484,9 +473,9 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_PAINTER_DOUBLE(payload) { - const shapeItem1 = /** @type {ShapeItem} */ (payload.itemsBySlot[0]); - const shapeItem2 = /** @type {ShapeItem} */ (payload.itemsBySlot[1]); - const colorItem = /** @type {ColorItem} */ (payload.itemsBySlot[2]); + const shapeItem1 = /** @type {ShapeItem} */ (payload.items[0]); + const shapeItem2 = /** @type {ShapeItem} */ (payload.items[1]); + const colorItem = /** @type {ColorItem} */ (payload.items[2]); assert(shapeItem1 instanceof ShapeItem, "Input for painter is not a shape"); assert(shapeItem2 instanceof ShapeItem, "Input for painter is not a shape"); @@ -514,14 +503,14 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_PAINTER_QUAD(payload) { - const shapeItem = /** @type {ShapeItem} */ (payload.itemsBySlot[0]); + const shapeItem = /** @type {ShapeItem} */ (payload.items[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) { - if (payload.itemsBySlot[i + 1]) { - colors[i] = /** @type {ColorItem} */ (payload.itemsBySlot[i + 1]).color; + if (payload.items[i + 1]) { + colors[i] = /** @type {ColorItem} */ (payload.items[i + 1]).color; } } @@ -540,7 +529,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter { */ process_READER(payload) { // Pass through the item - const item = payload.itemsBySlot[0]; + const item = payload.items[0]; payload.outItems.push({ item, doNotTrack: true, @@ -560,7 +549,8 @@ export class ItemProcessorSystem extends GameSystemWithFilter { assert(hubComponent, "Hub item processor has no hub component"); for (let i = 0; i < payload.items.length; ++i) { - const item = /** @type {ShapeItem} */ (payload.items[i].item); + if (!payload.items[i]) continue; + const item = /** @type {ShapeItem} */ (payload.items[i]); this.root.hubGoals.handleDefinitionDelivered(item.definition); } } @@ -570,7 +560,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter { */ process_GOAL(payload) { const goalComp = payload.entity.components.GoalAcceptor; - const item = payload.items[0].item; + const item = payload.items[0]; const now = this.root.time.now(); if (goalComp.item && !item.equals(goalComp.item)) { @@ -584,7 +574,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter { if (this.root.gameMode.getIsEditor()) { // while playing in editor, assign the item - goalComp.item = payload.items[0].item; + goalComp.item = payload.items[0]; } goalComp.lastDelivery = {