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:
commit
b0fc52a55f
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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>}
|
||||
*/
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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)) {
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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 = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user