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

processing refactor finished

This commit is contained in:
Sense101 2022-01-19 16:35:46 +00:00
parent 4a14727fd3
commit 56a2aa5e0f
18 changed files with 126 additions and 204 deletions

View File

@ -83,17 +83,14 @@ export const globalConfig = {
puzzleMaxBoundsSize: 20, puzzleMaxBoundsSize: 20,
puzzleValidationDurationSeconds: 30, puzzleValidationDurationSeconds: 30,
buildingSpeeds: { buildingAmountsToBelt: {
cutter: 1 / 4, cutter: 4,
cutterQuad: 1 / 4, cutterQuad: 4,
rotater: 1 / 1, painter: 6,
rotaterCCW: 1 / 1, painterDouble: 8,
rotater180: 1 / 1, painterQuad: 2,
painter: 1 / 6, mixer: 5,
painterDouble: 1 / 8, stacker: 8,
painterQuad: 1 / 2,
mixer: 1 / 5,
stacker: 1 / 8,
}, },
// Zooming // Zooming

View File

@ -132,12 +132,6 @@ export class BeltPath extends BasicSerializableObject {
*/ */
tryAcceptItem(item, startProgress = 0) { 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.
const progressGrowth =
this.root.hubGoals.getBeltBaseSpeed() *
this.root.dynamicTickrate.deltaSeconds *
globalConfig.itemSpacingOnBelts;
// 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, startProgress); const initialProgress = Math.min(maxProgress, startProgress);
@ -283,64 +277,6 @@ export class BeltPath extends BasicSerializableObject {
}; };
} }
/**
* Computes a method to pass over the item to the entity
* @param {Entity} entity
* @param {number} matchingSlotIndex
* @returns {(item: BaseItem, slotIndex: number) => boolean | void}
*/
computePassOverFunctionWithoutBelts(entity, matchingSlotIndex) {
const systems = this.root.systemMgr.systems;
const hubGoals = this.root.hubGoals;
// NOTICE: THIS IS COPIED FROM THE ITEM EJECTOR SYSTEM FOR PERFORMANCE REASONS
const itemProcessorComp = entity.components.ItemProcessor;
if (itemProcessorComp) {
// Its an item processor ..
return function (item) {
// Check for potential filters
if (!systems.itemProcessor.checkRequirements(entity, item, matchingSlotIndex)) {
return;
}
//return itemProcessorComp.tryTakeItem(item, matchingSlotIndex);
};
}
const undergroundBeltComp = entity.components.UndergroundBelt;
if (undergroundBeltComp) {
// Its an underground belt. yay.
return function (item) {
return undergroundBeltComp.tryAcceptExternalItem(
item,
hubGoals.getUndergroundBeltBaseSpeed()
);
};
}
const storageComp = entity.components.Storage;
if (storageComp) {
// It's a storage
return function (item) {
if (storageComp.canAcceptItem(item)) {
storageComp.takeItem(item);
return true;
}
};
}
const filterComp = entity.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.
return function (item) {
if (systems.filter.tryAcceptItem(entity, matchingSlotIndex, item)) {
return true;
}
};
}
}
// Following code will be compiled out outside of dev versions // Following code will be compiled out outside of dev versions
/* dev:start */ /* dev:start */

View File

@ -104,8 +104,7 @@ export class MetaBalancerBuilding extends MetaBuilding {
speedMultiplier = 1; speedMultiplier = 1;
} }
const speed = const speed = root.hubGoals.getProcessingSpeed(enumItemProcessorTypes.balancer) * speedMultiplier;
(root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.balancer) / 2) * speedMultiplier;
return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]]; return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
} }

View File

@ -54,7 +54,7 @@ export class MetaCutterBuilding extends MetaBuilding {
if (root.gameMode.throughputDoesNotMatter()) { if (root.gameMode.throughputDoesNotMatter()) {
return []; return [];
} }
const speed = root.hubGoals.getProcessorBaseSpeed( const speed = root.hubGoals.getProcessingSpeed(
variant === enumCutterVariants.quad variant === enumCutterVariants.quad
? enumItemProcessorTypes.cutterQuad ? enumItemProcessorTypes.cutterQuad
: enumItemProcessorTypes.cutter : enumItemProcessorTypes.cutter

View File

@ -164,7 +164,6 @@ export class MetaHubBuilding extends MetaBuilding {
filter: "shape", filter: "shape",
}, },
], ],
type: enumItemAcceptorTypes.hub,
}) })
); );
} }

View File

@ -47,7 +47,7 @@ export class MetaMixerBuilding extends MetaBuilding {
if (root.gameMode.throughputDoesNotMatter()) { if (root.gameMode.throughputDoesNotMatter()) {
return []; return [];
} }
const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.mixer); const speed = root.hubGoals.getProcessingSpeed(enumItemProcessorTypes.mixer);
return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]]; return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
} }

View File

@ -73,15 +73,15 @@ export class MetaPainterBuilding extends MetaBuilding {
switch (variant) { switch (variant) {
case defaultBuildingVariant: case defaultBuildingVariant:
case enumPainterVariants.mirrored: { case enumPainterVariants.mirrored: {
const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.painter); const speed = root.hubGoals.getProcessingSpeed(enumItemProcessorTypes.painter);
return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]]; return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
} }
case enumPainterVariants.double: { case enumPainterVariants.double: {
const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.painterDouble); const speed = root.hubGoals.getProcessingSpeed(enumItemProcessorTypes.painterDouble);
return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed, true)]]; return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed, true)]];
} }
case enumPainterVariants.quad: { case enumPainterVariants.quad: {
const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.painterQuad); const speed = root.hubGoals.getProcessingSpeed(enumItemProcessorTypes.painterQuad);
return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]]; return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
} }
} }

View File

@ -70,15 +70,15 @@ export class MetaRotaterBuilding extends MetaBuilding {
} }
switch (variant) { switch (variant) {
case defaultBuildingVariant: { case defaultBuildingVariant: {
const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.rotater); const speed = root.hubGoals.getProcessingSpeed(enumItemProcessorTypes.rotater);
return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]]; return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
} }
case enumRotaterVariants.ccw: { case enumRotaterVariants.ccw: {
const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.rotaterCCW); const speed = root.hubGoals.getProcessingSpeed(enumItemProcessorTypes.rotaterCCW);
return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]]; return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
} }
case enumRotaterVariants.rotate180: { case enumRotaterVariants.rotate180: {
const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.rotater180); const speed = root.hubGoals.getProcessingSpeed(enumItemProcessorTypes.rotater180);
return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]]; return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
} }
} }

View File

@ -40,7 +40,7 @@ export class MetaStackerBuilding extends MetaBuilding {
if (root.gameMode.throughputDoesNotMatter()) { if (root.gameMode.throughputDoesNotMatter()) {
return []; return [];
} }
const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.stacker); const speed = root.hubGoals.getProcessingSpeed(enumItemProcessorTypes.stacker);
return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]]; return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
} }

View File

@ -1,7 +1,7 @@
import { formatBigNumber } from "../../core/utils"; import { formatBigNumber } from "../../core/utils";
import { enumDirection, Vector } from "../../core/vector"; import { enumDirection, Vector } from "../../core/vector";
import { T } from "../../translations"; import { T } from "../../translations";
import { enumItemAcceptorTypes, ItemAcceptorComponent } from "../components/item_acceptor"; import { ItemAcceptorComponent } from "../components/item_acceptor";
import { ItemEjectorComponent } from "../components/item_ejector"; import { ItemEjectorComponent } from "../components/item_ejector";
import { StorageComponent } from "../components/storage"; import { StorageComponent } from "../components/storage";
import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins"; import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
@ -81,7 +81,6 @@ export class MetaStorageBuilding extends MetaBuilding {
direction: enumDirection.bottom, direction: enumDirection.bottom,
}, },
], ],
type: enumItemAcceptorTypes.storage,
}) })
); );

View File

@ -1,6 +1,6 @@
import { Loader } from "../../core/loader"; import { Loader } from "../../core/loader";
import { enumDirection, Vector, enumAngleToDirection, enumDirectionToVector } from "../../core/vector"; import { enumDirection, Vector, enumAngleToDirection, enumDirectionToVector } from "../../core/vector";
import { enumItemAcceptorTypes, ItemAcceptorComponent } from "../components/item_acceptor"; import { ItemAcceptorComponent } from "../components/item_acceptor";
import { ItemEjectorComponent } from "../components/item_ejector"; import { ItemEjectorComponent } from "../components/item_ejector";
import { enumUndergroundBeltMode, UndergroundBeltComponent } from "../components/underground_belt"; import { enumUndergroundBeltMode, UndergroundBeltComponent } from "../components/underground_belt";
import { Entity } from "../entity"; import { Entity } from "../entity";
@ -184,7 +184,6 @@ export class MetaUndergroundBeltBuilding extends MetaBuilding {
* @param {Entity} entity * @param {Entity} entity
*/ */
setupEntityComponents(entity) { setupEntityComponents(entity) {
// Required, since the item processor needs this.
entity.addComponent( entity.addComponent(
new ItemEjectorComponent({ new ItemEjectorComponent({
slots: [], slots: [],
@ -195,7 +194,6 @@ export class MetaUndergroundBeltBuilding extends MetaBuilding {
entity.addComponent( entity.addComponent(
new ItemAcceptorComponent({ new ItemAcceptorComponent({
slots: [], slots: [],
type: enumItemAcceptorTypes.undergroundBelt,
}) })
); );
} }

View File

@ -45,8 +45,7 @@ import { GameRoot } from "../root";
*/ */
/** @enum {string} */ /** @enum {string} */
export const enumItemAcceptorTypes = { const enumItemAcceptorTypes = {
itemProcessor: "itemProcessor",
hub: "hub", hub: "hub",
storage: "storage", storage: "storage",
trash: "trash", trash: "trash",
@ -64,14 +63,13 @@ export class ItemAcceptorComponent extends Component {
* @param {Array<ItemAcceptorSlotConfig>} param0.slots The slots from which we accept items * @param {Array<ItemAcceptorSlotConfig>} param0.slots The slots from which we accept items
* @param {enumItemAcceptorTypes=} param0.type Function that gets called when the input of an item is completed * @param {enumItemAcceptorTypes=} param0.type Function that gets called when the input of an item is completed
*/ */
constructor({ slots = [], type = enumItemAcceptorTypes.itemProcessor }) { constructor({ slots = [] }) {
super(); super();
/** @type {ItemAcceptorInputs} */ /** @type {ItemAcceptorInputs} */
this.inputs = new Map(); this.inputs = new Map();
/** @type {ItemAcceptorCompletedInputs} */ /** @type {ItemAcceptorCompletedInputs} */
this.completedInputs = new Map(); // @SENSETODO does this need to be saved? this.completedInputs = new Map(); // @SENSETODO does this need to be saved?
this.type = type;
this.setSlots(slots); this.setSlots(slots);
} }

View File

@ -70,7 +70,7 @@ export class ItemEjectorComponent extends Component {
direction: slot.direction, direction: slot.direction,
item: null, item: null,
lastItem: null, lastItem: null,
progress: 0, //@SENSETODO needs to be started off with extra time progress: 0,
cachedDestSlot: null, cachedDestSlot: null,
cachedTargetEntity: null, cachedTargetEntity: null,
}); });
@ -134,7 +134,6 @@ 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

@ -507,55 +507,39 @@ export class HubGoals extends BasicSerializableObject {
} }
/** /**
* Processor speed * Processor time to process
* @param {enumItemProcessorTypes} processorType * @param {enumItemProcessorTypes} processorType
* @returns {number} items / sec * @returns {number} process time in seconds
*/ */
getProcessorBaseSpeed(processorType) { getProcessingTime(processorType) {
if (this.root.gameMode.throughputDoesNotMatter()) { if (this.root.gameMode.throughputDoesNotMatter()) {
return globalConfig.beltSpeedItemsPerSecond * globalConfig.puzzleModeSpeed * 10; return 0;
} }
switch (processorType) { switch (processorType) {
case enumItemProcessorTypes.trash: case enumItemProcessorTypes.trash:
case enumItemProcessorTypes.hub: case enumItemProcessorTypes.hub:
case enumItemProcessorTypes.goal: case enumItemProcessorTypes.goal:
return 1e30;
case enumItemProcessorTypes.balancer: case enumItemProcessorTypes.balancer:
return globalConfig.beltSpeedItemsPerSecond * this.upgradeImprovements.belt * 2;
case enumItemProcessorTypes.reader: case enumItemProcessorTypes.reader:
return globalConfig.beltSpeedItemsPerSecond * this.upgradeImprovements.belt; case enumItemProcessorTypes.rotater:
case enumItemProcessorTypes.rotaterCCW:
case enumItemProcessorTypes.rotater180:
return 0;
case enumItemProcessorTypes.mixer: case enumItemProcessorTypes.mixer:
case enumItemProcessorTypes.painter: case enumItemProcessorTypes.painter:
case enumItemProcessorTypes.painterDouble: case enumItemProcessorTypes.painterDouble:
case enumItemProcessorTypes.painterQuad: { case enumItemProcessorTypes.painterQuad: {
assert( return this.getProcessorTimeWithUpgrades(this.upgradeImprovements.painting, processorType);
globalConfig.buildingSpeeds[processorType], // b2 + 4 = 4
"Processor type has no speed set in globalConfig.buildingSpeeds: " + processorType // b2 + 8 = 8
);
return (
globalConfig.beltSpeedItemsPerSecond *
this.upgradeImprovements.painting *
globalConfig.buildingSpeeds[processorType]
);
} }
case enumItemProcessorTypes.cutter: case enumItemProcessorTypes.cutter:
case enumItemProcessorTypes.cutterQuad: case enumItemProcessorTypes.cutterQuad:
case enumItemProcessorTypes.rotater:
case enumItemProcessorTypes.rotaterCCW:
case enumItemProcessorTypes.rotater180:
case enumItemProcessorTypes.stacker: { case enumItemProcessorTypes.stacker: {
assert( return this.getProcessorTimeWithUpgrades(this.upgradeImprovements.processors, processorType);
globalConfig.buildingSpeeds[processorType],
"Processor type has no speed set in globalConfig.buildingSpeeds: " + processorType
);
return (
globalConfig.beltSpeedItemsPerSecond *
this.upgradeImprovements.processors *
globalConfig.buildingSpeeds[processorType]
);
} }
default: default:
if (MOD_ITEM_PROCESSOR_SPEEDS[processorType]) { if (MOD_ITEM_PROCESSOR_SPEEDS[processorType]) {
@ -564,6 +548,33 @@ export class HubGoals extends BasicSerializableObject {
assertAlways(false, "invalid processor type: " + processorType); assertAlways(false, "invalid processor type: " + processorType);
} }
return 1 / globalConfig.beltSpeedItemsPerSecond; return 0;
}
/**
* @param {number} upgrade
* @param {number} upgrade
*/
getProcessorTimeWithUpgrades(upgrade, processorType) {
assert(
globalConfig.buildingAmountsToBelt[processorType],
"Processor type has no speed set in globalConfig.buildingSpeeds: " + processorType
);
const processorTime =
globalConfig.buildingAmountsToBelt[processorType] / globalConfig.beltSpeedItemsPerSecond;
return processorTime / upgrade;
}
/**
* Processor speed
* @param {enumItemProcessorTypes} processorType
* @returns {number} process time in seconds
*/
getProcessingSpeed(processorType) {
const time = this.getProcessingTime(processorType);
if (time == 0) {
return time;
}
return 1 / time;
} }
} }

View File

@ -2,11 +2,7 @@ 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 { ACHIEVEMENTS } from "../../platform/achievement_provider";
import { import { ItemAcceptorComponent, InputCompletedArgs } from "../components/item_acceptor";
enumItemAcceptorTypes,
ItemAcceptorComponent,
InputCompletedArgs,
} from "../components/item_acceptor";
import { GameSystemWithFilter } from "../game_system_with_filter"; import { GameSystemWithFilter } from "../game_system_with_filter";
import { ShapeItem } from "../items/shape_item"; import { ShapeItem } from "../items/shape_item";
import { MapChunkView } from "../map_chunk_view"; import { MapChunkView } from "../map_chunk_view";
@ -14,29 +10,16 @@ import { MapChunkView } from "../map_chunk_view";
export class ItemAcceptorSystem extends GameSystemWithFilter { export class ItemAcceptorSystem extends GameSystemWithFilter {
constructor(root) { constructor(root) {
super(root, [ItemAcceptorComponent]); super(root, [ItemAcceptorComponent]);
/**
* @type {Object<enumItemAcceptorTypes, function(InputCompletedArgs) : string>}
*/
this.handlers = {
[enumItemAcceptorTypes.itemProcessor]: this.input_ITEMPROCESSOR,
[enumItemAcceptorTypes.hub]: this.input_HUB,
[enumItemAcceptorTypes.trash]: this.input_TRASH,
};
// Bind all handlers
for (const key in this.handlers) {
this.handlers[key] = this.handlers[key].bind(this);
}
} }
update() { update() {
// * 2 because its only a half tile - (same code as ejector) // same code for belts, acceptors and ejectors - add helper method???
const progressGrowth = const progressGrowth =
2 *
this.root.dynamicTickrate.deltaSeconds * this.root.dynamicTickrate.deltaSeconds *
this.root.hubGoals.getBeltBaseSpeed() * this.root.hubGoals.getBeltBaseSpeed() *
globalConfig.itemSpacingOnBelts; globalConfig.itemSpacingOnBelts;
// it's only half a belt
const maxProgress = 0.5;
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];
@ -46,26 +29,13 @@ export class ItemAcceptorSystem extends GameSystemWithFilter {
inputs.forEach((values, index) => { inputs.forEach((values, index) => {
values.animProgress += progressGrowth; values.animProgress += progressGrowth;
if (values.animProgress < 1) return; if (values.animProgress < maxProgress) return;
inputs.delete(index); inputs.delete(index);
acceptorComp.completedInputs.set(index, { acceptorComp.completedInputs.set(index, {
item: values.item, item: values.item,
extraProgress: values.animProgress - 1, extraProgress: values.animProgress - maxProgress,
}); // will be handled on the SAME frame due to processor being afterwards }); // will be handled on the SAME frame due to processor system being afterwards
/** @type {function(InputCompletedArgs) : string} */
const handler = this.handlers[acceptorComp.type];
assert(handler, "No handler for acceptor type defined: " + acceptorComp.type);
// Call implementation
handler({
root: this.root,
entity,
item: values.item,
slotIndex: index,
extraProgress: values.animProgress - 1,
});
}); });
} }
} }
@ -102,8 +72,8 @@ export class ItemAcceptorSystem extends GameSystemWithFilter {
const fadeOutDirection = enumDirectionToVector[staticComp.localDirectionToWorld(direction)]; const fadeOutDirection = enumDirectionToVector[staticComp.localDirectionToWorld(direction)];
const finalTile = realSlotPos.subScalars( const finalTile = realSlotPos.subScalars(
fadeOutDirection.x * (animProgress / 2 - 0.5), fadeOutDirection.x * (animProgress - 0.5),
fadeOutDirection.y * (animProgress / 2 - 0.5) fadeOutDirection.y * (animProgress - 0.5)
); );
item.drawItemCenteredClipped( item.drawItemCenteredClipped(

View File

@ -139,12 +139,13 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
update() { update() {
this.staleAreaDetector.update(); this.staleAreaDetector.update();
// * 2 because its only a half tile - (same code as acceptor) // same code for belts, acceptors and ejectors - add helper method???
const progressGrowth = const progressGrowth =
2 *
this.root.dynamicTickrate.deltaSeconds * this.root.dynamicTickrate.deltaSeconds *
this.root.hubGoals.getBeltBaseSpeed() * this.root.hubGoals.getBeltBaseSpeed() *
globalConfig.itemSpacingOnBelts; globalConfig.itemSpacingOnBelts;
// it's only half a belt
const maxProgress = 0.5;
// Go over all cache entries // Go over all cache entries
for (let i = 0; i < this.allEntities.length; ++i) { for (let i = 0; i < this.allEntities.length; ++i) {
@ -160,25 +161,25 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
continue; continue;
} }
if (slot.progress < 1) { if (slot.progress < maxProgress) {
// Advance items on the slot // Advance items on the slot
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 = maxProgress;
} }
} }
// 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) continue; if (slot.progress < maxProgress) continue;
const extraProgress = slot.progress - 1; const extraProgress = slot.progress - maxProgress;
// 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 - extraProgress / 2 because the progress there is for double the distance // Try passing the item over
if (destPath.tryAcceptItem(item, extraProgress / 2)) { if (destPath.tryAcceptItem(item, extraProgress)) {
slot.item = null; slot.item = null;
} }
@ -203,8 +204,6 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
slot.item = null; slot.item = null;
} }
} }
//@SENSETODO deal with other buildings - acceptor code on them needs to be different!
} }
} }
} }
@ -244,8 +243,13 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
continue; 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) // Limit the progress to the maximum available space on the next belt (also see #1000)
let progress = Math.min(1, slot.progress); let progress = Math.min(0.5, slot.progress);
const nextBeltPath = slot.cachedBeltPath; const nextBeltPath = slot.cachedBeltPath;
if (nextBeltPath) { if (nextBeltPath) {
/* /*
@ -281,7 +285,7 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
^ max progress = 0.3 ^ max progress = 0.3
Because now our range actually only goes to the end of the building, and not towards the center of the building, we need to multiply Because now our range actually only goes to the end of the building, and not towards the center of the building, we need to multiply
all values by 2: all values by 2: <--------- except max progress is now 0.5 rather than 1, so this isn't needed anymore
Building Belt Building Belt
| X | X | | X | X |
@ -293,7 +297,7 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
*/ */
const maxProgress = const maxProgress =
(0.5 + nextBeltPath.spacingToFirstItem - globalConfig.itemSpacingOnBelts) * 2; 0.5 + nextBeltPath.spacingToFirstItem - globalConfig.itemSpacingOnBelts;
progress = Math.min(maxProgress, progress); progress = Math.min(maxProgress, progress);
} }
@ -306,8 +310,8 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
const realDirection = staticComp.localDirectionToWorld(slot.direction); const realDirection = staticComp.localDirectionToWorld(slot.direction);
const realDirectionVector = enumDirectionToVector[realDirection]; const realDirectionVector = enumDirectionToVector[realDirection];
const tileX = realPosition.x + 0.5 + realDirectionVector.x * 0.5 * progress; const tileX = realPosition.x + 0.5 + realDirectionVector.x * progress;
const tileY = realPosition.y + 0.5 + realDirectionVector.y * 0.5 * progress; const tileY = realPosition.y + 0.5 + realDirectionVector.y * progress;
const worldX = tileX * globalConfig.tileSize; const worldX = tileX * globalConfig.tileSize;
const worldY = tileY * globalConfig.tileSize; const worldY = tileY * globalConfig.tileSize;

View File

@ -1,4 +1,5 @@
import { globalConfig } from "../../core/config"; import { globalConfig } from "../../core/config";
import { ACHIEVEMENTS } from "../../platform/achievement_provider";
import { BaseItem } from "../base_item"; import { BaseItem } from "../base_item";
import { enumColorMixingResults, enumColors } from "../colors"; import { enumColorMixingResults, enumColors } from "../colors";
import { import {
@ -13,10 +14,10 @@ import { ColorItem, COLOR_ITEM_SINGLETONS } from "../items/color_item";
import { ShapeItem } from "../items/shape_item"; import { ShapeItem } from "../items/shape_item";
/** /**
* We need to allow queuing charges, otherwise the throughput will stall * We need to allow queuing charges, otherwise the throughput will stalls
*/ */
//@SENSETODO not sure if this is true anymore //@SENSETODO not sure if this is true anymore
const MAX_QUEUED_CHARGES = 2; const MAX_QUEUED_CHARGES = 1;
/** /**
* Whole data for a produced item * Whole data for a produced item
@ -266,7 +267,6 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
// First, take inputs - but only ones that are completed // First, take inputs - but only ones that are completed
const inputs = acceptorComp.completedInputs; const inputs = acceptorComp.completedInputs;
console.log("processor added charge");
const outItems = []; const outItems = [];
@ -289,8 +289,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
} }
// Queue Charge // Queue Charge
const baseSpeed = this.root.hubGoals.getProcessorBaseSpeed(processorComp.type); const originalTime = this.root.hubGoals.getProcessingTime(processorComp.type);
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;
@ -414,6 +413,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
const rotatedDefinition = this.root.shapeDefinitionMgr.shapeActionRotateCCW(inputDefinition); const rotatedDefinition = this.root.shapeDefinitionMgr.shapeActionRotateCCW(inputDefinition);
payload.outItems.push({ payload.outItems.push({
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(rotatedDefinition), item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(rotatedDefinition),
extraProgress: input.extraProgress,
}); });
} }
@ -429,6 +429,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
const rotatedDefinition = this.root.shapeDefinitionMgr.shapeActionRotate180(inputDefinition); const rotatedDefinition = this.root.shapeDefinitionMgr.shapeActionRotate180(inputDefinition);
payload.outItems.push({ payload.outItems.push({
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(rotatedDefinition), item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(rotatedDefinition),
extraProgress: input.extraProgress,
}); });
} }
@ -437,7 +438,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
*/ */
process_STACKER(payload) { process_STACKER(payload) {
const lowerInput = payload.inputs.get(0); const lowerInput = payload.inputs.get(0);
const upperInput = payload.inputs.get(0); const upperInput = payload.inputs.get(1);
const lowerItem = /** @type {ShapeItem} */ (lowerInput.item); const lowerItem = /** @type {ShapeItem} */ (lowerInput.item);
const upperItem = /** @type {ShapeItem} */ (upperInput.item); const upperItem = /** @type {ShapeItem} */ (upperInput.item);
@ -450,6 +451,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
); );
payload.outItems.push({ payload.outItems.push({
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(stackedDefinition), item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(stackedDefinition),
extraProgress: lowerInput.extraProgress,
}); });
} }
@ -457,7 +459,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
* @param {ProcessorImplementationPayload} payload * @param {ProcessorImplementationPayload} payload
*/ */
process_TRASH(payload) { process_TRASH(payload) {
// Do nothing .. payload.entity.root.signals.achievementCheck.dispatch(ACHIEVEMENTS.trash1000, 1);
} }
/** /**
@ -483,6 +485,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
} }
payload.outItems.push({ payload.outItems.push({
item: COLOR_ITEM_SINGLETONS[resultColor], item: COLOR_ITEM_SINGLETONS[resultColor],
extraProgress: input1.extraProgress,
}); });
} }
@ -502,6 +505,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
payload.outItems.push({ payload.outItems.push({
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(colorizedDefinition), item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(colorizedDefinition),
extraProgress: input1.extraProgress,
}); });
} }
@ -509,8 +513,11 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
* @param {ProcessorImplementationPayload} payload * @param {ProcessorImplementationPayload} payload
*/ */
process_PAINTER_DOUBLE(payload) { process_PAINTER_DOUBLE(payload) {
const shapeItem1 = /** @type {ShapeItem} */ (payload.inputs.get(0).item); const input1 = payload.inputs.get(0);
const shapeItem2 = /** @type {ShapeItem} */ (payload.inputs.get(1).item); 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 colorItem = /** @type {ColorItem} */ (payload.inputs.get(2).item);
assert(shapeItem1 instanceof ShapeItem, "Input for painter is not a shape"); assert(shapeItem1 instanceof ShapeItem, "Input for painter is not a shape");
@ -528,10 +535,12 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
); );
payload.outItems.push({ payload.outItems.push({
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(colorizedDefinition1), item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(colorizedDefinition1),
extraProgress: input1.extraProgress,
}); });
payload.outItems.push({ payload.outItems.push({
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(colorizedDefinition2), item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(colorizedDefinition2),
extraProgress: input2.extraProgress,
}); });
} }
@ -559,6 +568,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
payload.outItems.push({ payload.outItems.push({
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(colorizedDefinition), item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(colorizedDefinition),
extraProgress: input.extraProgress,
}); });
} }
@ -567,33 +577,34 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
*/ */
process_READER(payload) { process_READER(payload) {
// Pass through the item // Pass through the item
const item = payload.inputs.get(0).item; const input = payload.inputs.get(0);
payload.outItems.push({ payload.outItems.push({
item, item: input.item,
doNotTrack: true, doNotTrack: true,
extraProgress: input.extraProgress,
}); });
// Track the item // Track the item
const readerComp = payload.entity.components.BeltReader; const readerComp = payload.entity.components.BeltReader;
readerComp.lastItemTimes.push(this.root.time.now()); readerComp.lastItemTimes.push(this.root.time.now());
readerComp.lastItem = item; readerComp.lastItem = input.item;
} }
/** /**
* @param {ProcessorImplementationPayload} payload * @param {ProcessorImplementationPayload} payload
*/ */
process_HUB(payload) { process_HUB(payload) {
//const input = payload.inputs.get(i); const hubComponent = payload.entity.components.Hub;
//const hubComponent = payload.entity.components.Hub; assert(hubComponent, "Hub item processor has no hub component");
//assert(hubComponent, "Hub item processor has no hub component"); // Hardcoded
//// Hardcoded for (let i = 0; i < payload.inputs.size; ++i) {
//for (let i = 0; i < payload.inputCount; ++i) { const input = payload.inputs.get(i);
// const item = /** @type {ShapeItem} */ (payload.inputs.get(i)); if (!input) continue;
// if (!item) { const item = /** @type {ShapeItem} */ (input.item);
// continue; if (!item) continue;
// }
// this.root.hubGoals.handleDefinitionDelivered(item.definition); this.root.hubGoals.handleDefinitionDelivered(item.definition);
//} }
} }
/** /**

View File

@ -294,6 +294,7 @@ export class UndergroundBeltSystem extends GameSystemWithFilter {
*/ */
handleSender(entity) { handleSender(entity) {
const undergroundComp = entity.components.UndergroundBelt; const undergroundComp = entity.components.UndergroundBelt;
const acceptorComp = entity.components.ItemAcceptor;
// Find the current receiver // Find the current receiver
let cacheEntry = undergroundComp.cachedLinkedEntity; let cacheEntry = undergroundComp.cachedLinkedEntity;