1
0
mirror of https://github.com/tobspr/shapez.io.git synced 2025-12-13 10:11:50 +00:00

Major cleanup and fixes

This commit is contained in:
Sense101 2022-01-23 20:11:13 +00:00
commit b0fc52a55f
10 changed files with 164 additions and 222 deletions

View File

@ -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;

View File

@ -24,13 +24,14 @@ import { GameRoot } from "../root";
* filter?: ItemType
* }} ItemAcceptorSlotConfig
*
* @typedef {Map<number, {
* @typedef {Array<{
* slotIndex: number,
* item: BaseItem,
* animProgress: number,
* direction: enumDirection
* }>} ItemAcceptorInputs
*
* @typedef {Map<number, {
* @typedef {Array<{
* slotIndex: number,
* item: BaseItem,
* extraProgress: number
* }>} 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;

View File

@ -33,10 +33,10 @@ export const enumItemProcessorRequirements = {
* extraProgress?: number,
* requiredSlot?: number,
* preferredSlot?: number
* }} EjectorItemToEject
*
* @typedef {{
* remainingTime: number,
* }} EjectorItemToEject */
/** @typedef {{
* remainingProgress: number,
* items: Array<EjectorItemToEject>,
* }} 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<EjectorItemToEject>}
*/

View File

@ -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;
}
/**

View File

@ -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);
}
}

View File

@ -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
);
});
}
}
}
}

View File

@ -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;

View File

@ -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<number, BaseItem>,
* outItems: Array<ProducedItem>
* }} 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<enumColors>} */
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)) {

View File

@ -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) {

View File

@ -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 = [];
}
}
}