mirror of
https://github.com/tobspr/shapez.io.git
synced 2026-03-02 03:39:21 +00:00
Vastly improve belt performance
This commit is contained in:
@@ -137,6 +137,9 @@ export class BeltSystem extends GameSystemWithFilter {
|
||||
const originalRect = staticComp.getTileSpaceBounds();
|
||||
const affectedArea = originalRect.expandedInAllDirections(1);
|
||||
|
||||
/** @type {Set<BeltPath>} */
|
||||
const changedPaths = new Set();
|
||||
|
||||
for (let x = affectedArea.x; x < affectedArea.right(); ++x) {
|
||||
for (let y = affectedArea.y; y < affectedArea.bottom(); ++y) {
|
||||
if (originalRect.containsPoint(x, y)) {
|
||||
@@ -189,10 +192,17 @@ export class BeltSystem extends GameSystemWithFilter {
|
||||
// Make sure the chunks know about the update
|
||||
this.root.signals.entityChanged.dispatch(targetEntity);
|
||||
}
|
||||
|
||||
if (targetBeltComp.assignedPath) {
|
||||
changedPaths.add(targetBeltComp.assignedPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// notify all paths *afterwards* to avoid multi-updates
|
||||
changedPaths.forEach(path => path.onSurroundingsChanged());
|
||||
|
||||
if (G_IS_DEV && globalConfig.debug.checkBeltPaths) {
|
||||
this.debug_verifyBeltPaths();
|
||||
}
|
||||
@@ -361,24 +371,10 @@ export class BeltSystem extends GameSystemWithFilter {
|
||||
const followUpBeltComp = followUpEntity.components.Belt;
|
||||
if (followUpBeltComp) {
|
||||
const followUpStatic = followUpEntity.components.StaticMapEntity;
|
||||
const followUpAcceptor = followUpEntity.components.ItemAcceptor;
|
||||
|
||||
// Check if the belt accepts items from our direction
|
||||
const acceptorSlots = followUpAcceptor.slots;
|
||||
for (let i = 0; i < acceptorSlots.length; ++i) {
|
||||
const slot = acceptorSlots[i];
|
||||
|
||||
// Make sure the acceptor slot is on the same layer
|
||||
if (slot.layer !== entity.layer) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (let k = 0; k < slot.directions.length; ++k) {
|
||||
const localDirection = followUpStatic.localDirectionToWorld(slot.directions[k]);
|
||||
if (enumInvertedDirections[localDirection] === followUpDirection) {
|
||||
return followUpEntity;
|
||||
}
|
||||
}
|
||||
const acceptedDirection = followUpStatic.localDirectionToWorld(enumDirection.top);
|
||||
if (acceptedDirection === followUpDirection) {
|
||||
return followUpEntity;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -405,21 +401,12 @@ export class BeltSystem extends GameSystemWithFilter {
|
||||
const supplyBeltComp = supplyEntity.components.Belt;
|
||||
if (supplyBeltComp) {
|
||||
const supplyStatic = supplyEntity.components.StaticMapEntity;
|
||||
const supplyEjector = supplyEntity.components.ItemEjector;
|
||||
const otherDirection = supplyStatic.localDirectionToWorld(
|
||||
enumInvertedDirections[supplyBeltComp.direction]
|
||||
);
|
||||
|
||||
// Check if the belt accepts items from our direction
|
||||
const ejectorSlots = supplyEjector.slots;
|
||||
for (let i = 0; i < ejectorSlots.length; ++i) {
|
||||
const slot = ejectorSlots[i];
|
||||
|
||||
// Make sure the ejector slot is on the same layer
|
||||
if (slot.layer !== entity.layer) {
|
||||
continue;
|
||||
}
|
||||
const localDirection = supplyStatic.localDirectionToWorld(slot.direction);
|
||||
if (enumInvertedDirections[localDirection] === supplyDirection) {
|
||||
return supplyEntity;
|
||||
}
|
||||
if (otherDirection === supplyDirection) {
|
||||
return supplyEntity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@ import { globalConfig } from "../../core/config";
|
||||
import { DrawParameters } from "../../core/draw_parameters";
|
||||
import { createLogger } from "../../core/logging";
|
||||
import { Rectangle } from "../../core/rectangle";
|
||||
import { enumDirectionToVector, Vector } from "../../core/vector";
|
||||
import { BaseItem, enumItemType, enumItemTypeToLayer } from "../base_item";
|
||||
import { enumDirection, enumDirectionToVector, Vector } from "../../core/vector";
|
||||
import { BaseItem, enumItemTypeToLayer } from "../base_item";
|
||||
import { ItemEjectorComponent } from "../components/item_ejector";
|
||||
import { Entity } from "../entity";
|
||||
import { GameSystemWithFilter } from "../game_system_with_filter";
|
||||
@@ -120,15 +120,13 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
|
||||
const ejectorComp = entity.components.ItemEjector;
|
||||
const staticComp = entity.components.StaticMapEntity;
|
||||
|
||||
// Clear the old cache.
|
||||
ejectorComp.cachedConnectedSlots = null;
|
||||
|
||||
for (let ejectorSlotIndex = 0; ejectorSlotIndex < ejectorComp.slots.length; ++ejectorSlotIndex) {
|
||||
const ejectorSlot = ejectorComp.slots[ejectorSlotIndex];
|
||||
for (let slotIndex = 0; slotIndex < ejectorComp.slots.length; ++slotIndex) {
|
||||
const ejectorSlot = ejectorComp.slots[slotIndex];
|
||||
|
||||
// Clear the old cache.
|
||||
ejectorSlot.cachedDestSlot = null;
|
||||
ejectorSlot.cachedTargetEntity = null;
|
||||
ejectorSlot.cachedBeltPath = null;
|
||||
|
||||
// Figure out where and into which direction we eject items
|
||||
const ejectSlotWsTile = staticComp.localTileToWorld(ejectorSlot.pos);
|
||||
@@ -146,8 +144,21 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
|
||||
for (let i = 0; i < targetEntities.length; ++i) {
|
||||
const targetEntity = targetEntities[i];
|
||||
|
||||
const targetAcceptorComp = targetEntity.components.ItemAcceptor;
|
||||
const targetStaticComp = targetEntity.components.StaticMapEntity;
|
||||
const targetBeltComp = targetEntity.components.Belt;
|
||||
|
||||
// Check for belts (special case)
|
||||
if (targetBeltComp) {
|
||||
const beltAcceptingDirection = targetStaticComp.localDirectionToWorld(enumDirection.top);
|
||||
if (ejectSlotWsDirection === beltAcceptingDirection) {
|
||||
ejectorSlot.cachedTargetEntity = targetEntity;
|
||||
ejectorSlot.cachedBeltPath = targetBeltComp.assignedPath;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for item acceptors
|
||||
const targetAcceptorComp = targetEntity.components.ItemAcceptor;
|
||||
if (!targetAcceptorComp) {
|
||||
// Entity doesn't accept items
|
||||
continue;
|
||||
@@ -164,13 +175,6 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ok we found a connection
|
||||
if (ejectorComp.cachedConnectedSlots) {
|
||||
ejectorComp.cachedConnectedSlots.push(ejectorSlot);
|
||||
} else {
|
||||
ejectorComp.cachedConnectedSlots = [ejectorSlot];
|
||||
}
|
||||
|
||||
// A slot can always be connected to one other slot only
|
||||
ejectorSlot.cachedTargetEntity = targetEntity;
|
||||
ejectorSlot.cachedDestSlot = matchingSlot;
|
||||
@@ -199,11 +203,7 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!sourceEjectorComp.cachedConnectedSlots) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const slots = sourceEjectorComp.cachedConnectedSlots;
|
||||
const slots = sourceEjectorComp.slots;
|
||||
for (let j = 0; j < slots.length; ++j) {
|
||||
const sourceSlot = slots[j];
|
||||
const item = sourceSlot.item;
|
||||
@@ -212,7 +212,6 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
|
||||
continue;
|
||||
}
|
||||
|
||||
const destSlot = sourceSlot.cachedDestSlot;
|
||||
const targetEntity = sourceSlot.cachedTargetEntity;
|
||||
|
||||
// Advance items on the slot
|
||||
@@ -229,18 +228,34 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if the target acceptor can actually accept this item
|
||||
const targetAcceptorComp = targetEntity.components.ItemAcceptor;
|
||||
if (!targetAcceptorComp.canAcceptItem(destSlot.index, item)) {
|
||||
// Check if we are ejecting to a belt path
|
||||
const destPath = sourceSlot.cachedBeltPath;
|
||||
if (destPath) {
|
||||
// Try passing the item over
|
||||
if (destPath.tryAcceptItem(item)) {
|
||||
sourceSlot.item = null;
|
||||
}
|
||||
|
||||
// Always stop here, since there can *either* be a belt path *or*
|
||||
// a slot
|
||||
continue;
|
||||
}
|
||||
|
||||
// Try to hand over the item
|
||||
if (this.tryPassOverItem(item, targetEntity, destSlot.index)) {
|
||||
// Handover successful, clear slot
|
||||
targetAcceptorComp.onItemAccepted(destSlot.index, destSlot.acceptedDirection, item);
|
||||
sourceSlot.item = null;
|
||||
continue;
|
||||
// Check if the target acceptor can actually accept this item
|
||||
const destSlot = sourceSlot.cachedDestSlot;
|
||||
if (destSlot) {
|
||||
const targetAcceptorComp = targetEntity.components.ItemAcceptor;
|
||||
if (!targetAcceptorComp.canAcceptItem(destSlot.index, item)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Try to hand over the item
|
||||
if (this.tryPassOverItem(item, targetEntity, destSlot.index)) {
|
||||
// Handover successful, clear slot
|
||||
targetAcceptorComp.onItemAccepted(destSlot.index, destSlot.acceptedDirection, item);
|
||||
sourceSlot.item = null;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user