1
0
mirror of https://github.com/tobspr/shapez.io.git synced 2026-02-12 02:49:20 +00:00

Item acceptor refactor part two - completed functionality

This commit is contained in:
Sense101 2022-01-19 00:16:59 +00:00
parent 4a1bfcda64
commit 4a14727fd3
10 changed files with 74 additions and 177 deletions

View File

@ -128,8 +128,9 @@ export class BeltPath extends BasicSerializableObject {
/** /**
* Tries to accept the item * Tries to accept the item
* @param {BaseItem} item * @param {BaseItem} item
* @param {number} startProgress
*/ */
tryAcceptItem(item) { tryAcceptItem(item, startProgress = 0) {
if (this.spacingToFirstItem >= globalConfig.itemSpacingOnBelts) { if (this.spacingToFirstItem >= globalConfig.itemSpacingOnBelts) {
// So, since we already need one tick to accept this item we will add this directly. // So, since we already need one tick to accept this item we will add this directly.
const progressGrowth = const progressGrowth =
@ -139,7 +140,7 @@ export class BeltPath extends BasicSerializableObject {
// First, compute how much progress we can make *at max* // First, compute how much progress we can make *at max*
const maxProgress = Math.max(0, this.spacingToFirstItem - globalConfig.itemSpacingOnBelts); const maxProgress = Math.max(0, this.spacingToFirstItem - globalConfig.itemSpacingOnBelts);
const initialProgress = Math.min(maxProgress, progressGrowth); const initialProgress = Math.min(maxProgress, startProgress);
this.items.unshift([this.spacingToFirstItem - initialProgress, item]); this.items.unshift([this.spacingToFirstItem - initialProgress, item]);
this.spacingToFirstItem = initialProgress; this.spacingToFirstItem = initialProgress;

View File

@ -47,25 +47,6 @@ export class MetaTrashBuilding extends MetaBuilding {
return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_cutter_and_trash); return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_cutter_and_trash);
} }
addAchievementReceiver(entity) {
if (!entity.root) {
return;
}
const itemProcessor = entity.components.ItemProcessor;
const tryTakeItem = itemProcessor.tryTakeItem.bind(itemProcessor);
itemProcessor.tryTakeItem = () => {
const taken = tryTakeItem(...arguments);
if (taken) {
entity.root.signals.achievementCheck.dispatch(ACHIEVEMENTS.trash1000, 1);
}
return taken;
};
}
/** /**
* Creates the entity at the given location * Creates the entity at the given location
* @param {Entity} entity * @param {Entity} entity
@ -88,7 +69,5 @@ export class MetaTrashBuilding extends MetaBuilding {
processorType: enumItemProcessorTypes.trash, processorType: enumItemProcessorTypes.trash,
}) })
); );
this.addAchievementReceiver(entity);
} }
} }

View File

@ -28,7 +28,12 @@ import { GameRoot } from "../root";
* item: BaseItem, * item: BaseItem,
* animProgress: number, * animProgress: number,
* direction: enumDirection * direction: enumDirection
* }>} ItemAcceptorInput * }>} ItemAcceptorInputs
*
* @typedef {Map<number, {
* item: BaseItem,
* extraProgress: number
* }>} ItemAcceptorCompletedInputs
* *
* @typedef {{ * @typedef {{
* root: GameRoot, * root: GameRoot,
@ -62,8 +67,10 @@ export class ItemAcceptorComponent extends Component {
constructor({ slots = [], type = enumItemAcceptorTypes.itemProcessor }) { constructor({ slots = [], type = enumItemAcceptorTypes.itemProcessor }) {
super(); super();
/** @type {ItemAcceptorInput} */ /** @type {ItemAcceptorInputs} */
this.currentInputs = new Map(); // @SENSETODO does this need to be saved? this.inputs = new Map();
/** @type {ItemAcceptorCompletedInputs} */
this.completedInputs = new Map(); // @SENSETODO does this need to be saved?
this.type = type; this.type = type;
this.setSlots(slots); this.setSlots(slots);
} }
@ -100,11 +107,11 @@ export class ItemAcceptorComponent extends Component {
//@SENSETODO see if this works for buildings like hub //@SENSETODO see if this works for buildings like hub
if (this.currentInputs.has(slotIndex) || (slot.filter && slot.filter != item.getItemType())) { if (this.completedInputs.has(slotIndex) || (slot.filter && slot.filter != item.getItemType())) {
return false; return false;
} }
this.currentInputs.set(slotIndex, { this.inputs.set(slotIndex, {
item, item,
direction, direction,
animProgress: Math.min(1, startProgress), animProgress: Math.min(1, startProgress),

View File

@ -134,6 +134,7 @@ export class ItemEjectorComponent extends Component {
if (!this.canEjectOnSlot(slotIndex)) { if (!this.canEjectOnSlot(slotIndex)) {
return false; return false;
} }
if (startingProgress > 0) console.log("starting with progress: " + startingProgress);
this.slots[slotIndex].item = item; this.slots[slotIndex].item = item;
this.slots[slotIndex].lastItem = item; this.slots[slotIndex].lastItem = item;
this.slots[slotIndex].progress = startingProgress; this.slots[slotIndex].progress = startingProgress;

View File

@ -30,6 +30,7 @@ export const enumItemProcessorRequirements = {
/** /**
* @typedef {{ * @typedef {{
* item: BaseItem, * item: BaseItem,
* extraProgress?: number,
* requiredSlot?: number, * requiredSlot?: number,
* preferredSlot?: number * preferredSlot?: number
* }} EjectorItemToEject * }} EjectorItemToEject
@ -84,7 +85,6 @@ export class ItemProcessorComponent extends Component {
* Our current inputs * Our current inputs
* @type {Map<number, ItemProcessorInput>} * @type {Map<number, ItemProcessorInput>}
*/ */
this.inputs = new Map();
this.clear(); this.clear();
} }
@ -95,8 +95,6 @@ export class ItemProcessorComponent extends Component {
// sure the outputs always match // sure the outputs always match
this.nextOutputSlot = 0; this.nextOutputSlot = 0;
this.inputs.clear();
/** /**
* What we are currently processing, empty if we don't produce anything rn * What we are currently processing, empty if we don't produce anything rn
* requiredSlot: Item *must* be ejected on this slot * requiredSlot: Item *must* be ejected on this slot

View File

@ -145,7 +145,7 @@ export class GameSystemManager {
// Order is important! // Order is important!
// IMPORTANT: Item acceptor must be before the belt, because it may not tick after the belt // IMPORTANT: Item acceptor must be before the belt, because it may not tick after the belt
// has put in the item into the acceptor animation, otherwise its off // has put in the item into the acceptor animqation, otherwise its off
add("itemAcceptor", ItemAcceptorSystem); add("itemAcceptor", ItemAcceptorSystem);
add("belt", BeltSystem); add("belt", BeltSystem);
@ -156,14 +156,14 @@ export class GameSystemManager {
add("storage", StorageSystem); add("storage", StorageSystem);
add("itemEjector", ItemEjectorSystem);
add("itemProcessor", ItemProcessorSystem); add("itemProcessor", ItemProcessorSystem);
add("filter", FilterSystem); add("filter", FilterSystem);
add("itemProducer", ItemProducerSystem); add("itemProducer", ItemProducerSystem);
add("itemEjector", ItemEjectorSystem);
if (this.root.gameMode.hasResources()) { if (this.root.gameMode.hasResources()) {
add("mapResources", MapResourcesSystem); add("mapResources", MapResourcesSystem);
} }

View File

@ -113,12 +113,10 @@ export class BeltUnderlaysSystem extends GameSystemWithFilter {
continue; continue;
} }
// Step 2: Check if any of the directions matches // Step 2: Check if the direction matches
for (let j = 0; j < slot.directions.length; ++j) { const slotDirection = staticComp.localDirectionToWorld(slot.direction);
const slotDirection = staticComp.localDirectionToWorld(slot.directions[j]); if (slotDirection === fromDirection) {
if (slotDirection === fromDirection) { return true;
return true;
}
} }
} }
} }

View File

@ -1,6 +1,7 @@
import { globalConfig } from "../../core/config"; import { globalConfig } from "../../core/config";
import { DrawParameters } from "../../core/draw_parameters"; import { DrawParameters } from "../../core/draw_parameters";
import { enumDirectionToVector } from "../../core/vector"; import { enumDirectionToVector } from "../../core/vector";
import { ACHIEVEMENTS } from "../../platform/achievement_provider";
import { import {
enumItemAcceptorTypes, enumItemAcceptorTypes,
ItemAcceptorComponent, ItemAcceptorComponent,
@ -40,15 +41,19 @@ export class ItemAcceptorSystem extends GameSystemWithFilter {
for (let i = 0; i < this.allEntities.length; ++i) { for (let i = 0; i < this.allEntities.length; ++i) {
const entity = this.allEntities[i]; const entity = this.allEntities[i];
const acceptorComp = entity.components.ItemAcceptor; const acceptorComp = entity.components.ItemAcceptor;
const inputs = acceptorComp.currentInputs; const inputs = acceptorComp.inputs;
inputs.forEach((values, index) => { inputs.forEach((values, index) => {
if (values.animProgress >= 1) return; // items which are inputted already
values.animProgress += progressGrowth; values.animProgress += progressGrowth;
if (values.animProgress < 1) return; if (values.animProgress < 1) return;
inputs.delete(index);
acceptorComp.completedInputs.set(index, {
item: values.item,
extraProgress: values.animProgress - 1,
}); // will be handled on the SAME frame due to processor being afterwards
/** @type {function(InputCompletedArgs) : string} */ /** @type {function(InputCompletedArgs) : string} */
const handler = this.handlers[acceptorComp.type]; const handler = this.handlers[acceptorComp.type];
assert(handler, "No handler for acceptor type defined: " + acceptorComp.type); assert(handler, "No handler for acceptor type defined: " + acceptorComp.type);
@ -84,9 +89,8 @@ export class ItemAcceptorSystem extends GameSystemWithFilter {
} }
const staticComp = entity.components.StaticMapEntity; const staticComp = entity.components.StaticMapEntity;
acceptorComp.currentInputs.forEach((values, index) => { acceptorComp.inputs.forEach((values, index) => {
const { item, animProgress, direction } = values; const { item, animProgress, direction } = values;
if (animProgress >= 1) return; // items which are inputted already
const slotData = acceptorComp.slots[index]; const slotData = acceptorComp.slots[index];
const realSlotPos = staticComp.localTileToWorld(slotData.pos); const realSlotPos = staticComp.localTileToWorld(slotData.pos);
@ -115,17 +119,7 @@ export class ItemAcceptorSystem extends GameSystemWithFilter {
/** /**
* @param {InputCompletedArgs} args * @param {InputCompletedArgs} args
*/ */
input_ITEMPROCESSOR(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 //@SENSETODO this isn't set up like it should be yet
/** /**
@ -138,7 +132,7 @@ export class ItemAcceptorSystem extends GameSystemWithFilter {
this.root.hubGoals.handleDefinitionDelivered(item.definition); this.root.hubGoals.handleDefinitionDelivered(item.definition);
const acceptorComp = args.entity.components.ItemAcceptor; const acceptorComp = args.entity.components.ItemAcceptor;
acceptorComp.currentInputs.delete(args.slotIndex); acceptorComp.inputs.delete(args.slotIndex);
} }
/** /**
@ -147,7 +141,8 @@ export class ItemAcceptorSystem extends GameSystemWithFilter {
input_TRASH(args) { input_TRASH(args) {
// just remove the item // just remove the item
const acceptorComp = args.entity.components.ItemAcceptor; const acceptorComp = args.entity.components.ItemAcceptor;
acceptorComp.currentInputs.delete(args.slotIndex); acceptorComp.inputs.delete(args.slotIndex);
args.entity.root.signals.achievementCheck.dispatch(ACHIEVEMENTS.trash1000, 1);
} }
//storage //storage

View File

@ -160,24 +160,25 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
continue; continue;
} }
// Advance items on the slot if (slot.progress < 1) {
// @SENSETODO do we really want to cap it at one, or should the excess get passed on? // Advance items on the slot
slot.progress = Math.min(1, slot.progress + progressGrowth); slot.progress += progressGrowth;
if (G_IS_DEV && globalConfig.debug.disableEjectorProcessing) { if (G_IS_DEV && globalConfig.debug.disableEjectorProcessing) {
slot.progress = 1; slot.progress = 1;
}
} }
// Check if we are still in the process of ejecting, can't proceed then // Check if we are still in the process of ejecting, can't proceed then
if (slot.progress < 1) { if (slot.progress < 1) continue;
continue;
} const extraProgress = slot.progress - 1;
// Check if we are ejecting to a belt path // Check if we are ejecting to a belt path
const destPath = slot.cachedBeltPath; const destPath = slot.cachedBeltPath;
if (destPath) { if (destPath) {
// Try passing the item over // Try passing the item over - extraProgress / 2 because the progress there is for double the distance
if (destPath.tryAcceptItem(item)) { if (destPath.tryAcceptItem(item, extraProgress / 2)) {
slot.item = null; slot.item = null;
} }
@ -190,7 +191,6 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
const destSlot = slot.cachedDestSlot; const destSlot = slot.cachedDestSlot;
if (destEntity && destSlot) { if (destEntity && destSlot) {
const targetAcceptorComp = destEntity.components.ItemAcceptor; const targetAcceptorComp = destEntity.components.ItemAcceptor;
const extraProgress = slot.progress - 1;
if ( if (
targetAcceptorComp.tryAcceptItem( targetAcceptorComp.tryAcceptItem(
destSlot.index, destSlot.index,
@ -245,7 +245,7 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
} }
// Limit the progress to the maximum available space on the next belt (also see #1000) // Limit the progress to the maximum available space on the next belt (also see #1000)
let progress = slot.progress; let progress = Math.min(1, slot.progress);
const nextBeltPath = slot.cachedBeltPath; const nextBeltPath = slot.cachedBeltPath;
if (nextBeltPath) { if (nextBeltPath) {
/* /*
@ -321,90 +321,4 @@ 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;
}
} }

View File

@ -34,7 +34,7 @@ const MAX_QUEUED_CHARGES = 2;
* Type of a processor implementation * Type of a processor implementation
* @typedef {{ * @typedef {{
* entity: Entity, * entity: Entity,
* inputs: Map<number, import("../components/item_processor").ItemProcessorInput>, * inputs: import("../components/item_acceptor").ItemAcceptorCompletedInputs,
* outItems: Array<ProducedItem> * outItems: Array<ProducedItem>
* }} ProcessorImplementationPayload * }} ProcessorImplementationPayload
*/ */
@ -83,8 +83,14 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
const processorComp = entity.components.ItemProcessor; const processorComp = entity.components.ItemProcessor;
const ejectorComp = entity.components.ItemEjector; const ejectorComp = entity.components.ItemEjector;
const currentCharge = processorComp.ongoingCharges[0]; // Check if we have an empty queue and can start a new charge - do this first so we don't waste a tick
if (processorComp.ongoingCharges.length < MAX_QUEUED_CHARGES) {
if (this.canProcess(entity)) {
this.startNewCharge(entity);
}
}
const currentCharge = processorComp.ongoingCharges[0];
if (currentCharge) { if (currentCharge) {
// Process next charge // Process next charge
if (currentCharge.remainingTime > 0.0) { if (currentCharge.remainingTime > 0.0) {
@ -101,7 +107,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
// Go over all items and try to eject them // Go over all items and try to eject them
for (let j = 0; j < itemsToEject.length; ++j) { for (let j = 0; j < itemsToEject.length; ++j) {
const { item, requiredSlot, preferredSlot } = itemsToEject[j]; const { item, requiredSlot, preferredSlot, extraProgress = 0 } = itemsToEject[j];
assert(ejectorComp, "To eject items, the building needs to have an ejector"); assert(ejectorComp, "To eject items, the building needs to have an ejector");
@ -125,7 +131,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
if (slot !== null) { if (slot !== null) {
// Alright, we can actually eject // Alright, we can actually eject
if (!ejectorComp.tryEject(slot, item)) { if (!ejectorComp.tryEject(slot, item, extraProgress)) {
assert(false, "Failed to eject"); assert(false, "Failed to eject");
} else { } else {
itemsToEject.splice(j, 1); itemsToEject.splice(j, 1);
@ -142,13 +148,6 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
} }
} }
} }
// Check if we have an empty queue and can start a new charge
if (processorComp.ongoingCharges.length < MAX_QUEUED_CHARGES) {
if (this.canProcess(entity)) {
this.startNewCharge(entity);
}
}
} }
} }
@ -192,13 +191,14 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
* @param {Entity} entity * @param {Entity} entity
*/ */
canProcess(entity) { canProcess(entity) {
const acceptorComp = entity.components.ItemAcceptor;
const processorComp = entity.components.ItemProcessor; const processorComp = entity.components.ItemProcessor;
switch (processorComp.processingRequirement) { switch (processorComp.processingRequirement) {
// DEFAULT // DEFAULT
// By default, we can start processing once all inputs are there // By default, we can start processing once all inputs are there
case null: { case null: {
return processorComp.inputs.size >= processorComp.inputsPerCharge; return acceptorComp.completedInputs.size >= processorComp.inputsPerCharge;
} }
// QUAD PAINTER // QUAD PAINTER
@ -207,7 +207,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
const pinsComp = entity.components.WiredPins; const pinsComp = entity.components.WiredPins;
// First slot is the shape, so if it's not there we can't do anything // First slot is the shape, so if it's not there we can't do anything
const shapeItem = /** @type {ShapeItem} */ (processorComp.inputs.get(0).item); const shapeItem = /** @type {ShapeItem} */ (acceptorComp.inputs.get(0).item);
if (!shapeItem) { if (!shapeItem) {
return false; return false;
} }
@ -236,7 +236,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
// Check if all colors of the enabled slots are there // Check if all colors of the enabled slots are there
for (let i = 0; i < slotStatus.length; ++i) { for (let i = 0; i < slotStatus.length; ++i) {
if (slotStatus[i] && !processorComp.inputs.get(1 + i)) { if (slotStatus[i] && !acceptorComp.inputs.get(1 + i)) {
// A slot which is enabled wasn't enabled. Make sure if there is anything on the quadrant, // 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 // it is not possible to paint, but if there is nothing we can ignore it
for (let j = 0; j < 4; ++j) { for (let j = 0; j < 4; ++j) {
@ -261,12 +261,13 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
* @param {Entity} entity * @param {Entity} entity
*/ */
startNewCharge(entity) { startNewCharge(entity) {
const acceptorComp = entity.components.ItemAcceptor;
const processorComp = entity.components.ItemProcessor; const processorComp = entity.components.ItemProcessor;
// First, take inputs // First, take inputs - but only ones that are completed
const inputs = processorComp.inputs; const inputs = acceptorComp.completedInputs;
console.log("processor added charge");
/** @type {Array<ProducedItem>} */
const outItems = []; const outItems = [];
/** @type {function(ProcessorImplementationPayload) : void} */ /** @type {function(ProcessorImplementationPayload) : void} */
@ -276,7 +277,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
// Call implementation // Call implementation
handler({ handler({
entity, entity,
inputs: inputs, inputs,
outItems, outItems,
}); });
@ -289,7 +290,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
// Queue Charge // Queue Charge
const baseSpeed = this.root.hubGoals.getProcessorBaseSpeed(processorComp.type); const baseSpeed = this.root.hubGoals.getProcessorBaseSpeed(processorComp.type);
const originalTime = 1 / baseSpeed; const originalTime = 0;
const bonusTimeToApply = Math.min(originalTime, processorComp.bonusTime); const bonusTimeToApply = Math.min(originalTime, processorComp.bonusTime);
const timeToProcess = originalTime - bonusTimeToApply; const timeToProcess = originalTime - bonusTimeToApply;
@ -300,8 +301,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
remainingTime: timeToProcess, remainingTime: timeToProcess,
}); });
processorComp.inputs.clear(); //@SENSETODO temp, will completely replace processorcomp.inputs with acceptor inputs later acceptorComp.completedInputs.clear();
entity.components.ItemAcceptor.currentInputs.clear();
} }
/** /**
@ -322,6 +322,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
} }
payload.outItems.push({ payload.outItems.push({
item: input.item, item: input.item,
extraProgress: input.extraProgress,
preferredSlot: processorComp.nextOutputSlot++ % availableSlots, preferredSlot: processorComp.nextOutputSlot++ % availableSlots,
doNotTrack: true, doNotTrack: true,
}); });
@ -351,6 +352,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
payload.outItems.push({ payload.outItems.push({
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(definition), item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(definition),
extraProgress: input.extraProgress,
requiredSlot: i, requiredSlot: i,
}); });
} }
@ -378,6 +380,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
payload.outItems.push({ payload.outItems.push({
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(definition), item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(definition),
extraProgress: input.extraProgress,
requiredSlot: i, requiredSlot: i,
}); });
} }
@ -395,6 +398,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
const rotatedDefinition = this.root.shapeDefinitionMgr.shapeActionRotateCW(inputDefinition); const rotatedDefinition = this.root.shapeDefinitionMgr.shapeActionRotateCW(inputDefinition);
payload.outItems.push({ payload.outItems.push({
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(rotatedDefinition), item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(rotatedDefinition),
extraProgress: input.extraProgress,
}); });
} }