|
|
|
@ -175,6 +175,11 @@ export class BeltPath extends BasicSerializableObject {
|
|
|
|
|
*/
|
|
|
|
|
onPathChanged() {
|
|
|
|
|
this.acceptorTarget = this.computeAcceptingEntityAndSlot();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* How many items past the first item are compressed
|
|
|
|
|
*/
|
|
|
|
|
this.numCompressedItemsAfterFirstItem = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -426,6 +431,26 @@ export class BeltPath extends BasicSerializableObject {
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check first nonzero offset
|
|
|
|
|
let firstNonzero = 0;
|
|
|
|
|
for (let i = this.items.length - 2; i >= 0; --i) {
|
|
|
|
|
if (this.items[i][_nextDistance] < globalConfig.itemSpacingOnBelts + 1e-5) {
|
|
|
|
|
++firstNonzero;
|
|
|
|
|
} else {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Should warn, but this check isn't actually accurate
|
|
|
|
|
// if (firstNonzero !== this.numCompressedItemsAfterFirstItem) {
|
|
|
|
|
// console.warn(
|
|
|
|
|
// "First nonzero index is " +
|
|
|
|
|
// firstNonzero +
|
|
|
|
|
// " but stored is " +
|
|
|
|
|
// this.numCompressedItemsAfterFirstItem
|
|
|
|
|
// );
|
|
|
|
|
// }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* dev:end */
|
|
|
|
@ -1038,11 +1063,15 @@ export class BeltPath extends BasicSerializableObject {
|
|
|
|
|
// Store how much velocity (strictly its distance, not velocity) we have to distribute over all items
|
|
|
|
|
let remainingVelocity = beltSpeed;
|
|
|
|
|
|
|
|
|
|
for (let i = this.items.length - 1; i >= 0; --i) {
|
|
|
|
|
const nextDistanceAndItem = this.items[i];
|
|
|
|
|
// Store the last item we processed, so we can skip clashed ones
|
|
|
|
|
let lastItemProcessed;
|
|
|
|
|
|
|
|
|
|
for (lastItemProcessed = this.items.length - 1; lastItemProcessed >= 0; --lastItemProcessed) {
|
|
|
|
|
const nextDistanceAndItem = this.items[lastItemProcessed];
|
|
|
|
|
|
|
|
|
|
// Compute how much spacing we need at least
|
|
|
|
|
const minimumSpacing = i === this.items.length - 1 ? 0 : globalConfig.itemSpacingOnBelts;
|
|
|
|
|
const minimumSpacing =
|
|
|
|
|
lastItemProcessed === this.items.length - 1 ? 0 : globalConfig.itemSpacingOnBelts;
|
|
|
|
|
|
|
|
|
|
// Compute how much we can advance
|
|
|
|
|
const clampedProgress = Math.max(
|
|
|
|
@ -1067,9 +1096,19 @@ export class BeltPath extends BasicSerializableObject {
|
|
|
|
|
// Try to directly get rid of the item
|
|
|
|
|
if (this.tryHandOverItem(nextDistanceAndItem[_item], excessVelocity)) {
|
|
|
|
|
this.items.pop();
|
|
|
|
|
|
|
|
|
|
this.numCompressedItemsAfterFirstItem = Math.max(
|
|
|
|
|
0,
|
|
|
|
|
this.numCompressedItemsAfterFirstItem - 1
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (isFirstItemProcessed) {
|
|
|
|
|
// Skip N null items after first items
|
|
|
|
|
lastItemProcessed -= this.numCompressedItemsAfterFirstItem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
isFirstItemProcessed = false;
|
|
|
|
|
this.spacingToFirstItem += clampedProgress;
|
|
|
|
|
if (remainingVelocity < 0.01) {
|
|
|
|
@ -1077,11 +1116,22 @@ export class BeltPath extends BasicSerializableObject {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Compute compressed item count
|
|
|
|
|
this.numCompressedItemsAfterFirstItem = Math.max(
|
|
|
|
|
0,
|
|
|
|
|
this.numCompressedItemsAfterFirstItem,
|
|
|
|
|
this.items.length - 2 - lastItemProcessed
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Check if we have an item which is ready to be emitted
|
|
|
|
|
const lastItem = this.items[this.items.length - 1];
|
|
|
|
|
if (lastItem && lastItem[_nextDistance] === 0 && this.acceptorTarget) {
|
|
|
|
|
if (this.tryHandOverItem(lastItem[_item])) {
|
|
|
|
|
this.items.pop();
|
|
|
|
|
this.numCompressedItemsAfterFirstItem = Math.max(
|
|
|
|
|
0,
|
|
|
|
|
this.numCompressedItemsAfterFirstItem - 1
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1205,6 +1255,11 @@ export class BeltPath extends BasicSerializableObject {
|
|
|
|
|
worldPos.y + 2
|
|
|
|
|
);
|
|
|
|
|
progress += nextDistanceAndItem[_nextDistance];
|
|
|
|
|
|
|
|
|
|
if (this.items.length - 1 - this.numCompressedItemsAfterFirstItem === i) {
|
|
|
|
|
parameters.context.fillStyle = "red";
|
|
|
|
|
parameters.context.fillRect(worldPos.x + 5, worldPos.y, 20, 3);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < this.entityPath.length; ++i) {
|
|
|
|
|