1
0
mirror of https://github.com/tobspr/shapez.io.git synced 2025-12-15 19:21:49 +00:00

refactor tunnel to be exactly the same speed as belt

This commit is contained in:
Sense101 2022-01-19 20:28:04 +00:00
parent 4dbbff9477
commit 638cdc2733
3 changed files with 37 additions and 31 deletions

View File

@ -56,9 +56,8 @@ export class UndergroundBeltComponent extends Component {
this.consumptionAnimations = []; this.consumptionAnimations = [];
/** /**
* Used only on reciever * Used only on reciever to store which items are currently "travelling"
* Reciever: Used to store which items are currently "travelling" * @type {Array<[BaseItem, number]>} Format is [Item, Tile progress]
* @type {Array<[BaseItem, number]>} Format is [Item, ingame time to eject the item]
*/ */
this.pendingItems = []; this.pendingItems = [];
} }
@ -66,30 +65,22 @@ export class UndergroundBeltComponent extends Component {
/** /**
* Tries to accept a tunneled item * Tries to accept a tunneled item
* @param {BaseItem} item * @param {BaseItem} item
* @param {number} travelDistance How many tiles this item has to travel * @param {number} travelDistance
* @param {number} beltSpeed How fast this item travels * @param {number} startProgress The starting tile progress
* @param {number} now Current ingame time
*/ */
tryAcceptTunneledItem(item, travelDistance, beltSpeed, now) { tryAcceptTunneledItem(item, travelDistance, startProgress = 0) {
if (this.mode !== enumUndergroundBeltMode.receiver) { if (this.mode !== enumUndergroundBeltMode.receiver) {
// Only receivers can accept tunneled items // Only receivers can accept tunneled items
return false; return false;
} }
// Notice: We assume that for all items the travel distance is the same // Notice: We assume that for all items the travel distance is the same
const maxItemsInTunnel = (2 + travelDistance) / globalConfig.itemSpacingOnBelts; const maxItemsInTunnel = travelDistance / globalConfig.itemSpacingOnBelts;
if (this.pendingItems.length >= maxItemsInTunnel) { if (this.pendingItems.length >= maxItemsInTunnel) {
// Simulate a real belt which gets full at some point // Simulate a real belt which gets full at some point
return false; return false;
} }
// NOTICE: this.pendingItems.push([item, startProgress]);
// This corresponds to the item ejector - it needs 0.5 additional tiles to eject the item.
// So instead of adding 1 we add 0.5 only.
// Additionally it takes 1 tile for the acceptor which we just add on top.
const travelDuration = (travelDistance + 1.5) / beltSpeed / globalConfig.itemSpacingOnBelts;
this.pendingItems.push([item, now + travelDuration]);
return true; return true;
} }
} }

View File

@ -150,14 +150,14 @@ export class GameSystemManager {
add("belt", BeltSystem); add("belt", BeltSystem);
add("undergroundBelt", UndergroundBeltSystem);
add("miner", MinerSystem); add("miner", MinerSystem);
add("storage", StorageSystem); add("storage", StorageSystem);
add("itemEjector", ItemEjectorSystem); add("itemEjector", ItemEjectorSystem);
add("undergroundBelt", UndergroundBeltSystem);
add("itemProcessor", ItemProcessorSystem); add("itemProcessor", ItemProcessorSystem);
add("filter", FilterSystem); add("filter", FilterSystem);

View File

@ -225,7 +225,11 @@ export class UndergroundBeltSystem extends GameSystemWithFilter {
this.staleAreaWatcher.update(); this.staleAreaWatcher.update();
const sender = enumUndergroundBeltMode.sender; const sender = enumUndergroundBeltMode.sender;
const now = this.root.time.now();
const progressGrowth =
this.root.dynamicTickrate.deltaSeconds *
this.root.hubGoals.getBeltBaseSpeed() *
globalConfig.itemSpacingOnBelts;
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];
@ -233,7 +237,7 @@ export class UndergroundBeltSystem extends GameSystemWithFilter {
if (undergroundComp.mode === sender) { if (undergroundComp.mode === sender) {
this.handleSender(entity); this.handleSender(entity);
} else { } else {
this.handleReceiver(entity, now); this.handleReceiver(entity, progressGrowth);
} }
} }
} }
@ -253,8 +257,8 @@ export class UndergroundBeltSystem extends GameSystemWithFilter {
// Search in the direction of the tunnel // Search in the direction of the tunnel
for ( for (
let searchOffset = 0; let searchOffset = 1;
searchOffset < globalConfig.undergroundBeltMaxTilesByTier[undergroundComp.tier]; searchOffset < globalConfig.undergroundBeltMaxTilesByTier[undergroundComp.tier] + 1;
++searchOffset ++searchOffset
) { ) {
currentTile = currentTile.add(searchVector); currentTile = currentTile.add(searchVector);
@ -281,6 +285,9 @@ export class UndergroundBeltSystem extends GameSystemWithFilter {
break; break;
} }
console.log("distance: " + searchOffset);
// make sure to link the other way as well
receiverUndergroundComp.cachedLinkedEntity = { entity: null, distance: searchOffset };
return { entity: potentialReceiver, distance: searchOffset }; return { entity: potentialReceiver, distance: searchOffset };
} }
@ -310,13 +317,13 @@ export class UndergroundBeltSystem extends GameSystemWithFilter {
const input = acceptorComp.completedInputs.get(0); const input = acceptorComp.completedInputs.get(0);
if (input) { if (input) {
console.log("found input");
// Check if the receiver can accept it // Check if the receiver can accept it
if ( if (
cacheEntry.entity.components.UndergroundBelt.tryAcceptTunneledItem( cacheEntry.entity.components.UndergroundBelt.tryAcceptTunneledItem(
input.item, input.item,
cacheEntry.distance, cacheEntry.distance,
this.root.hubGoals.getUndergroundBeltBaseSpeed(), input.extraProgress
this.root.time.now()
) )
) { ) {
acceptorComp.completedInputs.delete(0); acceptorComp.completedInputs.delete(0);
@ -327,20 +334,28 @@ export class UndergroundBeltSystem extends GameSystemWithFilter {
/** /**
* *
* @param {Entity} entity * @param {Entity} entity
* @param {number} now * @param {number} progressGrowth
*/ */
handleReceiver(entity, now) { handleReceiver(entity, progressGrowth) {
const undergroundComp = entity.components.UndergroundBelt; const undergroundComp = entity.components.UndergroundBelt;
// Try to eject items, we only check the first one because it is sorted by remaining time if (!undergroundComp.cachedLinkedEntity) return;
const nextItemAndDuration = undergroundComp.pendingItems[0]; const distance = undergroundComp.cachedLinkedEntity.distance;
if (nextItemAndDuration) {
if (now > nextItemAndDuration[1]) { // Move items along
for (let i = 0; i < undergroundComp.pendingItems.length; i++) {
const itemAndProgress = undergroundComp.pendingItems[i];
if (itemAndProgress[1] < distance) {
itemAndProgress[1] += progressGrowth;
}
if (itemAndProgress[1] >= distance) {
const ejectorComp = entity.components.ItemEjector; const ejectorComp = entity.components.ItemEjector;
const nextSlotIndex = ejectorComp.getFirstFreeSlot(); const nextSlotIndex = ejectorComp.getFirstFreeSlot();
if (nextSlotIndex !== null) { if (nextSlotIndex !== null) {
if (ejectorComp.tryEject(nextSlotIndex, nextItemAndDuration[0])) { const extraProgress = itemAndProgress[1] - distance;
if (ejectorComp.tryEject(nextSlotIndex, itemAndProgress[0], extraProgress)) {
undergroundComp.pendingItems.shift(); undergroundComp.pendingItems.shift();
} }
} }