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

Fixed exceptions by checking acceptors and ejectors

This commit is contained in:
DJ1TJOO 2021-11-22 20:19:05 +01:00
parent 1022ea989c
commit 6c05a56e36
3 changed files with 83 additions and 14 deletions

View File

@ -16,6 +16,7 @@ export const enumClippedBeltUnderlayType = {
topOnly: "topOnly", topOnly: "topOnly",
topCorner: "topCorner", topCorner: "topCorner",
bottomCorner: "bottomCorner", bottomCorner: "bottomCorner",
cornerFull: "cornerFull",
none: "none", none: "none",
}; };

View File

@ -1,4 +1,4 @@
import { enumDirection, enumDirectionToVector, Vector } from "../../core/vector"; import { enumDirection, enumDirectionToVector, enumInvertedDirections, Vector } from "../../core/vector";
import { types } from "../../savegame/serialization"; import { types } from "../../savegame/serialization";
import { BaseItem } from "../base_item"; import { BaseItem } from "../base_item";
import { BeltPath } from "../belt_path"; import { BeltPath } from "../belt_path";
@ -151,4 +151,33 @@ export class ItemEjectorComponent extends Component {
slot.progress = 0.0; slot.progress = 0.0;
return item; return item;
} }
/**
* Tries to find a slot which ejects the current item
* @param {Vector} targetLocalTile
* @param {enumDirection} fromLocalDirection
* @returns {ItemEjectorSlot|null}
*/
findMatchingSlot(targetLocalTile, fromLocalDirection) {
// We need to invert our direction since the ejector specifies *from* which direction
// it ejects items, but the acceptor specifies *into* which direction it accepts items.
// E.g.: Acceptor ejects into "right" direction but ejector accepts from "left" direction.
const desiredDirection = enumInvertedDirections[fromLocalDirection];
// Go over all slots and try to find a target slot
for (let slotIndex = 0; slotIndex < this.slots.length; ++slotIndex) {
const slot = this.slots[slotIndex];
// Make sure the acceptor slot is on the right position
if (!slot.pos.equals(targetLocalTile)) {
continue;
}
if (desiredDirection === slot.direction) {
return slot;
}
}
return null;
}
} }

View File

@ -31,6 +31,7 @@ const enumUnderlayTypeToClipRect = {
[enumClippedBeltUnderlayType.bottomOnly]: new Rectangle(0, 0.5, 1, 0.5), [enumClippedBeltUnderlayType.bottomOnly]: new Rectangle(0, 0.5, 1, 0.5),
[enumClippedBeltUnderlayType.topCorner]: new Rectangle(0, 0, 1, 0.04), [enumClippedBeltUnderlayType.topCorner]: new Rectangle(0, 0, 1, 0.04),
[enumClippedBeltUnderlayType.bottomCorner]: new Rectangle(0, 0.96, 1, 0.04), [enumClippedBeltUnderlayType.bottomCorner]: new Rectangle(0, 0.96, 1, 0.04),
[enumClippedBeltUnderlayType.cornerFull]: new Rectangle(0, 0, 0, 0),
}; };
export class BeltUnderlaysSystem extends GameSystemWithFilter { export class BeltUnderlaysSystem extends GameSystemWithFilter {
@ -194,21 +195,36 @@ export class BeltUnderlaysSystem extends GameSystemWithFilter {
const worldDirectionVector = enumDirectionToVector[worldDirection]; const worldDirectionVector = enumDirectionToVector[worldDirection];
// Figure out if there is anything connected at the top // Figure out if there is anything connected at the top
const connectedTop = this.checkIsAcceptorConnected( let connectedTop = this.checkIsAcceptorConnected(
transformedPos.add(worldDirectionVector), transformedPos.add(worldDirectionVector),
enumInvertedDirections[worldDirection] enumInvertedDirections[worldDirection]
); );
const ejectorComp = entity.components.ItemEjector;
if (ejectorComp) {
const ejectorSlot = ejectorComp.findMatchingSlot(
underlayTile.pos,
enumInvertedDirections[underlayTile.direction]
);
if (!ejectorSlot) connectedTop = false;
}
// Figure out if there is anything connected at the bottom // Figure out if there is anything connected at the bottom
const connectedBottom = this.checkIsEjectorConnected( let connectedBottom = this.checkIsEjectorConnected(
transformedPos.sub(worldDirectionVector), transformedPos.sub(worldDirectionVector),
worldDirection worldDirection
); );
const acceptorComp = entity.components.ItemAcceptor;
if (acceptorComp) {
const acceptorSlot = acceptorComp.findMatchingSlot(underlayTile.pos, underlayTile.direction);
if (!acceptorSlot) connectedBottom = false;
}
let flag = enumClippedBeltUnderlayType.none; let flag = enumClippedBeltUnderlayType.none;
if (connectedTop && connectedBottom) { if (connectedTop && connectedBottom) {
flag = enumClippedBeltUnderlayType.full; flag = underlayTile.corner
? enumClippedBeltUnderlayType.cornerFull
: enumClippedBeltUnderlayType.full;
} else if (connectedTop) { } else if (connectedTop) {
flag = underlayTile.corner flag = underlayTile.corner
? enumClippedBeltUnderlayType.topCorner ? enumClippedBeltUnderlayType.topCorner
@ -288,6 +304,28 @@ export class BeltUnderlaysSystem extends GameSystemWithFilter {
); );
parameters.context.translate(x, y); parameters.context.translate(x, y);
parameters.context.rotate(angleRadians); parameters.context.rotate(angleRadians);
if (underlayType === enumClippedBeltUnderlayType.cornerFull) {
this.underlayBeltSprites[
animationIndex % this.underlayBeltSprites.length
].drawCachedWithClipRect(
parameters,
-globalConfig.halfTileSize,
-globalConfig.halfTileSize,
globalConfig.tileSize,
globalConfig.tileSize,
enumUnderlayTypeToClipRect[enumClippedBeltUnderlayType.topCorner]
);
this.underlayBeltSprites[
animationIndex % this.underlayBeltSprites.length
].drawCachedWithClipRect(
parameters,
-globalConfig.halfTileSize,
-globalConfig.halfTileSize,
globalConfig.tileSize,
globalConfig.tileSize,
enumUnderlayTypeToClipRect[enumClippedBeltUnderlayType.bottomCorner]
);
} else {
this.underlayBeltSprites[ this.underlayBeltSprites[
animationIndex % this.underlayBeltSprites.length animationIndex % this.underlayBeltSprites.length
].drawCachedWithClipRect( ].drawCachedWithClipRect(
@ -298,6 +336,7 @@ export class BeltUnderlaysSystem extends GameSystemWithFilter {
globalConfig.tileSize, globalConfig.tileSize,
clipRect clipRect
); );
}
parameters.context.rotate(-angleRadians); parameters.context.rotate(-angleRadians);
parameters.context.translate(-x, -y); parameters.context.translate(-x, -y);
} }