1
0
mirror of https://github.com/tobspr/shapez.io.git synced 2025-12-13 02:01:51 +00:00

Refactor item acceptor to allow only single direction slots

This commit is contained in:
tobspr 2022-01-21 09:43:21 +01:00
parent 511d0556e1
commit 7741d1590e
22 changed files with 159 additions and 219 deletions

View File

@ -80,7 +80,7 @@ class MetaModFlipperBuilding extends shapez.ModMetaBuilding {
slots: [
{
pos: new shapez.Vector(0, 0),
directions: [shapez.enumDirection.bottom],
direction: shapez.enumDirection.bottom,
filter: "shape",
},
],

View File

@ -179,11 +179,11 @@ export class MetaBalancerBuilding extends MetaBuilding {
entity.components.ItemAcceptor.setSlots([
{
pos: new Vector(0, 0),
directions: [enumDirection.bottom],
direction: enumDirection.bottom,
},
{
pos: new Vector(1, 0),
directions: [enumDirection.bottom],
direction: enumDirection.bottom,
},
]);
@ -204,15 +204,14 @@ export class MetaBalancerBuilding extends MetaBuilding {
entity.components.ItemAcceptor.setSlots([
{
pos: new Vector(0, 0),
directions: [enumDirection.bottom],
direction: enumDirection.bottom,
},
{
pos: new Vector(0, 0),
directions: [
direction:
variant === enumBalancerVariants.mergerInverse
? enumDirection.left
: enumDirection.right,
],
},
]);
@ -231,7 +230,7 @@ export class MetaBalancerBuilding extends MetaBuilding {
entity.components.ItemAcceptor.setSlots([
{
pos: new Vector(0, 0),
directions: [enumDirection.bottom],
direction: enumDirection.bottom,
},
]);

View File

@ -96,7 +96,7 @@ export class MetaCutterBuilding extends MetaBuilding {
slots: [
{
pos: new Vector(0, 0),
directions: [enumDirection.bottom],
direction: enumDirection.bottom,
filter: "shape",
},
],

View File

@ -78,7 +78,7 @@ export class MetaFilterBuilding extends MetaBuilding {
slots: [
{
pos: new Vector(0, 0),
directions: [enumDirection.bottom],
direction: enumDirection.bottom,
},
],
})

View File

@ -45,7 +45,7 @@ export class MetaGoalAcceptorBuilding extends MetaBuilding {
slots: [
{
pos: new Vector(0, 0),
directions: [enumDirection.bottom],
direction: enumDirection.bottom,
filter: "shape",
},
],

View File

@ -70,80 +70,22 @@ export class MetaHubBuilding extends MetaBuilding {
})
);
/**
* @type {Array<import("../components/item_acceptor").ItemAcceptorSlotConfig>}
*/
const slots = [];
for (let i = 0; i < 4; ++i) {
slots.push(
{ pos: new Vector(i, 0), direction: enumDirection.top, filter: "shape" },
{ pos: new Vector(i, 3), direction: enumDirection.bottom, filter: "shape" },
{ pos: new Vector(0, i), direction: enumDirection.left, filter: "shape" },
{ pos: new Vector(3, i), direction: enumDirection.right, filter: "shape" }
);
}
entity.addComponent(
new ItemAcceptorComponent({
slots: [
{
pos: new Vector(0, 0),
directions: [enumDirection.top, enumDirection.left],
filter: "shape",
},
{
pos: new Vector(1, 0),
directions: [enumDirection.top],
filter: "shape",
},
{
pos: new Vector(2, 0),
directions: [enumDirection.top],
filter: "shape",
},
{
pos: new Vector(3, 0),
directions: [enumDirection.top, enumDirection.right],
filter: "shape",
},
{
pos: new Vector(0, 3),
directions: [enumDirection.bottom, enumDirection.left],
filter: "shape",
},
{
pos: new Vector(1, 3),
directions: [enumDirection.bottom],
filter: "shape",
},
{
pos: new Vector(2, 3),
directions: [enumDirection.bottom],
filter: "shape",
},
{
pos: new Vector(3, 3),
directions: [enumDirection.bottom, enumDirection.right],
filter: "shape",
},
{
pos: new Vector(0, 1),
directions: [enumDirection.left],
filter: "shape",
},
{
pos: new Vector(0, 2),
directions: [enumDirection.left],
filter: "shape",
},
{
pos: new Vector(0, 3),
directions: [enumDirection.left],
filter: "shape",
},
{
pos: new Vector(3, 1),
directions: [enumDirection.right],
filter: "shape",
},
{
pos: new Vector(3, 2),
directions: [enumDirection.right],
filter: "shape",
},
{
pos: new Vector(3, 3),
directions: [enumDirection.right],
filter: "shape",
},
],
slots,
})
);
}

View File

@ -73,12 +73,12 @@ export class MetaMixerBuilding extends MetaBuilding {
slots: [
{
pos: new Vector(0, 0),
directions: [enumDirection.bottom],
direction: enumDirection.bottom,
filter: "color",
},
{
pos: new Vector(1, 0),
directions: [enumDirection.bottom],
direction: enumDirection.bottom,
filter: "color",
},
],

View File

@ -128,12 +128,12 @@ export class MetaPainterBuilding extends MetaBuilding {
slots: [
{
pos: new Vector(0, 0),
directions: [enumDirection.left],
direction: enumDirection.left,
filter: "shape",
},
{
pos: new Vector(1, 0),
directions: [enumDirection.top],
direction: enumDirection.top,
filter: "color",
},
],
@ -160,14 +160,13 @@ export class MetaPainterBuilding extends MetaBuilding {
entity.components.ItemAcceptor.setSlots([
{
pos: new Vector(0, 0),
directions: [enumDirection.left],
direction: enumDirection.left,
filter: "shape",
},
{
pos: new Vector(1, 0),
directions: [
direction:
variant === defaultBuildingVariant ? enumDirection.top : enumDirection.bottom,
],
filter: "color",
},
]);
@ -193,17 +192,17 @@ export class MetaPainterBuilding extends MetaBuilding {
entity.components.ItemAcceptor.setSlots([
{
pos: new Vector(0, 0),
directions: [enumDirection.left],
direction: enumDirection.left,
filter: "shape",
},
{
pos: new Vector(0, 1),
directions: [enumDirection.left],
direction: enumDirection.left,
filter: "shape",
},
{
pos: new Vector(1, 0),
directions: [enumDirection.top],
direction: enumDirection.top,
filter: "color",
},
]);
@ -251,27 +250,27 @@ export class MetaPainterBuilding extends MetaBuilding {
entity.components.ItemAcceptor.setSlots([
{
pos: new Vector(0, 0),
directions: [enumDirection.left],
direction: enumDirection.left,
filter: "shape",
},
{
pos: new Vector(0, 0),
directions: [enumDirection.bottom],
direction: enumDirection.bottom,
filter: "color",
},
{
pos: new Vector(1, 0),
directions: [enumDirection.bottom],
direction: enumDirection.bottom,
filter: "color",
},
{
pos: new Vector(2, 0),
directions: [enumDirection.bottom],
direction: enumDirection.bottom,
filter: "color",
},
{
pos: new Vector(3, 0),
directions: [enumDirection.bottom],
direction: enumDirection.bottom,
filter: "color",
},
]);

View File

@ -84,7 +84,7 @@ export class MetaReaderBuilding extends MetaBuilding {
slots: [
{
pos: new Vector(0, 0),
directions: [enumDirection.bottom],
direction: enumDirection.bottom,
},
],
})

View File

@ -128,7 +128,7 @@ export class MetaRotaterBuilding extends MetaBuilding {
slots: [
{
pos: new Vector(0, 0),
directions: [enumDirection.bottom],
direction: enumDirection.bottom,
filter: "shape",
},
],

View File

@ -73,12 +73,12 @@ export class MetaStackerBuilding extends MetaBuilding {
slots: [
{
pos: new Vector(0, 0),
directions: [enumDirection.bottom],
direction: enumDirection.bottom,
filter: "shape",
},
{
pos: new Vector(1, 0),
directions: [enumDirection.bottom],
direction: enumDirection.bottom,
filter: "shape",
},
],

View File

@ -74,11 +74,11 @@ export class MetaStorageBuilding extends MetaBuilding {
slots: [
{
pos: new Vector(0, 1),
directions: [enumDirection.bottom],
direction: enumDirection.bottom,
},
{
pos: new Vector(1, 1),
directions: [enumDirection.bottom],
direction: enumDirection.bottom,
},
],
})

View File

@ -76,12 +76,19 @@ export class MetaTrashBuilding extends MetaBuilding {
slots: [
{
pos: new Vector(0, 0),
directions: [
enumDirection.top,
enumDirection.right,
enumDirection.bottom,
enumDirection.left,
],
direction: enumDirection.top,
},
{
pos: new Vector(0, 0),
direction: enumDirection.right,
},
{
pos: new Vector(0, 0),
direction: enumDirection.bottom,
},
{
pos: new Vector(0, 0),
direction: enumDirection.left,
},
],
})

View File

@ -277,7 +277,7 @@ export class MetaUndergroundBeltBuilding extends MetaBuilding {
entity.components.ItemAcceptor.setSlots([
{
pos: new Vector(0, 0),
directions: [enumDirection.bottom],
direction: enumDirection.bottom,
},
]);
return;

View File

@ -8,7 +8,7 @@ export const curvedBeltLength = /* Math.PI / 4 */ 0.78;
/** @type {import("./item_acceptor").ItemAcceptorSlot} */
export const FAKE_BELT_ACCEPTOR_SLOT = {
pos: new Vector(0, 0),
directions: [enumDirection.bottom],
direction: enumDirection.bottom,
};
/** @type {Object<enumDirection, import("./item_ejector").ItemEjectorSlot>} */

View File

@ -3,9 +3,10 @@ import { types } from "../../savegame/serialization";
import { BaseItem } from "../base_item";
import { Component } from "../component";
/** @typedef {{
/**
* @typedef {{
* pos: Vector,
* directions: enumDirection[],
* direction: enumDirection,
* filter?: ItemType
* }} ItemAcceptorSlot */
@ -14,12 +15,12 @@ import { Component } from "../component";
* @typedef {{
* slot: ItemAcceptorSlot,
* index: number,
* acceptedDirection: enumDirection
* }} ItemAcceptorLocatedSlot */
/** @typedef {{
/**
* @typedef {{
* pos: Vector,
* directions: enumDirection[],
* direction: enumDirection,
* filter?: ItemType
* }} ItemAcceptorSlotConfig */
@ -64,7 +65,7 @@ export class ItemAcceptorComponent extends Component {
const slot = slots[i];
this.slots.push({
pos: slot.pos,
directions: slot.directions,
direction: slot.direction,
// Which type of item to accept (shape | color | all) @see ItemType
filter: slot.filter,
@ -122,15 +123,11 @@ export class ItemAcceptorComponent extends Component {
}
// Check if the acceptor slot accepts items from our direction
for (let i = 0; i < slot.directions.length; ++i) {
// const localDirection = targetStaticComp.localDirectionToWorld(slot.directions[l]);
if (desiredDirection === slot.directions[i]) {
return {
slot,
index: slotIndex,
acceptedDirection: desiredDirection,
};
}
if (desiredDirection === slot.direction) {
return {
slot,
index: slotIndex,
};
}
}

View File

@ -197,20 +197,18 @@ export class Entity extends BasicSerializableObject {
for (let i = 0; i < acceptorComp.slots.length; ++i) {
const slot = acceptorComp.slots[i];
const slotTile = staticComp.localTileToWorld(slot.pos);
for (let k = 0; k < slot.directions.length; ++k) {
const direction = staticComp.localDirectionToWorld(slot.directions[k]);
const directionVector = enumDirectionToVector[direction];
const angle = Math.radians(enumDirectionToAngle[direction] + 180);
context.globalAlpha = 0.4;
drawRotatedSprite({
parameters,
sprite: acceptorSprite,
x: (slotTile.x + 0.5 + directionVector.x * 0.37) * globalConfig.tileSize,
y: (slotTile.y + 0.5 + directionVector.y * 0.37) * globalConfig.tileSize,
angle,
size: globalConfig.tileSize * 0.25,
});
}
const direction = staticComp.localDirectionToWorld(slot.direction);
const directionVector = enumDirectionToVector[direction];
const angle = Math.radians(enumDirectionToAngle[direction] + 180);
context.globalAlpha = 0.4;
drawRotatedSprite({
parameters,
sprite: acceptorSprite,
x: (slotTile.x + 0.5 + directionVector.x * 0.37) * globalConfig.tileSize,
y: (slotTile.y + 0.5 + directionVector.y * 0.37) * globalConfig.tileSize,
angle,
size: globalConfig.tileSize * 0.25,
});
}
}

View File

@ -435,7 +435,7 @@ export class HubGoals extends BasicSerializableObject {
}
const randomColor = () => rng.choice(colors);
const randomShape = () => rng.choice(Object.values(enumSubShape));
const randomShape = () => rng.choice(availableShapes);
let anyIsMissingTwo = false;

View File

@ -530,7 +530,13 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic {
const offsetShift = 10;
/**
* @type {Array<import("../../components/item_acceptor").ItemAcceptorSlot>}
*/
let acceptorSlots = [];
/**
* @type {Array<import("../../components/item_ejector").ItemEjectorSlot>}
*/
let ejectorSlots = [];
if (ejectorComp) {
@ -548,71 +554,65 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic {
acceptorSlots.push(fakeAcceptorSlot);
}
for (let acceptorSlotIndex = 0; acceptorSlotIndex < acceptorSlots.length; ++acceptorSlotIndex) {
const slot = acceptorSlots[acceptorSlotIndex];
// Go over all slots
for (let i = 0; i < acceptorSlots.length; ++i) {
const slot = acceptorSlots[i];
const acceptorSlotWsTile = staticComp.localTileToWorld(slot.pos);
const acceptorSlotWsPos = acceptorSlotWsTile.toWorldSpaceCenterOfTile();
// Go over all slots
for (
let acceptorDirectionIndex = 0;
acceptorDirectionIndex < slot.directions.length;
++acceptorDirectionIndex
) {
const direction = slot.directions[acceptorDirectionIndex];
const worldDirection = staticComp.localDirectionToWorld(direction);
const direction = slot.direction;
const worldDirection = staticComp.localDirectionToWorld(direction);
// Figure out which tile ejects to this slot
const sourceTile = acceptorSlotWsTile.add(enumDirectionToVector[worldDirection]);
// Figure out which tile ejects to this slot
const sourceTile = acceptorSlotWsTile.add(enumDirectionToVector[worldDirection]);
let isBlocked = false;
let isConnected = false;
let isBlocked = false;
let isConnected = false;
// Find all entities which are on that tile
const sourceEntities = this.root.map.getLayersContentsMultipleXY(sourceTile.x, sourceTile.y);
// Find all entities which are on that tile
const sourceEntities = this.root.map.getLayersContentsMultipleXY(sourceTile.x, sourceTile.y);
// Check for every entity:
for (let i = 0; i < sourceEntities.length; ++i) {
const sourceEntity = sourceEntities[i];
const sourceEjector = sourceEntity.components.ItemEjector;
const sourceBeltComp = sourceEntity.components.Belt;
const sourceStaticComp = sourceEntity.components.StaticMapEntity;
const ejectorAcceptLocalTile = sourceStaticComp.worldToLocalTile(acceptorSlotWsTile);
// Check for every entity:
for (let j = 0; j < sourceEntities.length; ++j) {
const sourceEntity = sourceEntities[j];
const sourceEjector = sourceEntity.components.ItemEjector;
const sourceBeltComp = sourceEntity.components.Belt;
const sourceStaticComp = sourceEntity.components.StaticMapEntity;
const ejectorAcceptLocalTile = sourceStaticComp.worldToLocalTile(acceptorSlotWsTile);
// If this entity is on the same layer as the slot - if so, it can either be
// connected, or it can not be connected and thus block the input
if (sourceEjector && sourceEjector.anySlotEjectsToLocalTile(ejectorAcceptLocalTile)) {
// This one is connected, all good
isConnected = true;
} else if (
sourceBeltComp &&
sourceStaticComp.localDirectionToWorld(sourceBeltComp.direction) ===
enumInvertedDirections[worldDirection]
) {
// Belt connected
isConnected = true;
} else {
// This one is blocked
isBlocked = true;
}
// If this entity is on the same layer as the slot - if so, it can either be
// connected, or it can not be connected and thus block the input
if (sourceEjector && sourceEjector.anySlotEjectsToLocalTile(ejectorAcceptLocalTile)) {
// This one is connected, all good
isConnected = true;
} else if (
sourceBeltComp &&
sourceStaticComp.localDirectionToWorld(sourceBeltComp.direction) ===
enumInvertedDirections[worldDirection]
) {
// Belt connected
isConnected = true;
} else {
// This one is blocked
isBlocked = true;
}
const alpha = isConnected || isBlocked ? 1.0 : 0.3;
const sprite = isBlocked ? badArrowSprite : goodArrowSprite;
parameters.context.globalAlpha = alpha;
drawRotatedSprite({
parameters,
sprite,
x: acceptorSlotWsPos.x,
y: acceptorSlotWsPos.y,
angle: Math.radians(enumDirectionToAngle[enumInvertedDirections[worldDirection]]),
size: 13,
offsetY: offsetShift + 13,
});
parameters.context.globalAlpha = 1;
}
const alpha = isConnected || isBlocked ? 1.0 : 0.3;
const sprite = isBlocked ? badArrowSprite : goodArrowSprite;
parameters.context.globalAlpha = alpha;
drawRotatedSprite({
parameters,
sprite,
x: acceptorSlotWsPos.x,
y: acceptorSlotWsPos.y,
angle: Math.radians(enumDirectionToAngle[enumInvertedDirections[worldDirection]]),
size: 13,
offsetY: offsetShift + 13,
});
parameters.context.globalAlpha = 1;
}
// Go over all slots

View File

@ -395,7 +395,14 @@ export class GameLogic {
const entity = this.root.map.getLayerContentXY(tile.x + dx, tile.y + dy, "regular");
if (entity) {
/**
* @type {Array<import("./components/item_ejector").ItemEjectorSlot>}
*/
let ejectorSlots = [];
/**
* @type {Array<import("./components/item_acceptor").ItemAcceptorSlot>}
*/
let acceptorSlots = [];
const staticComp = entity.components.StaticMapEntity;
@ -436,19 +443,16 @@ export class GameLogic {
for (let acceptorSlot = 0; acceptorSlot < acceptorSlots.length; ++acceptorSlot) {
const slot = acceptorSlots[acceptorSlot];
const wsTile = staticComp.localTileToWorld(slot.pos);
for (let k = 0; k < slot.directions.length; ++k) {
const direction = slot.directions[k];
const wsDirection = staticComp.localDirectionToWorld(direction);
const sourceTile = wsTile.add(enumDirectionToVector[wsDirection]);
if (sourceTile.equals(tile)) {
acceptors.push({
entity,
slot,
toTile: wsTile,
fromDirection: wsDirection,
});
}
const direction = slot.direction;
const wsDirection = staticComp.localDirectionToWorld(direction);
const sourceTile = wsTile.add(enumDirectionToVector[wsDirection]);
if (sourceTile.equals(tile)) {
acceptors.push({
entity,
slot,
toTile: wsTile,
fromDirection: wsDirection,
});
}
}
}

View File

@ -113,12 +113,10 @@ export class BeltUnderlaysSystem extends GameSystem {
continue;
}
// Step 2: Check if any of the directions matches
for (let j = 0; j < slot.directions.length; ++j) {
const slotDirection = staticComp.localDirectionToWorld(slot.directions[j]);
if (slotDirection === fromDirection) {
return true;
}
// Step 2: Check if the direction matches
const slotDirection = staticComp.localDirectionToWorld(slot.direction);
if (slotDirection === fromDirection) {
return true;
}
}
}

View File

@ -203,11 +203,7 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
if (this.tryPassOverItem(item, destEntity, destSlot.index)) {
// Handover successful, clear slot
if (!this.root.app.settings.getAllSettings().simplifiedBelts) {
targetAcceptorComp.onItemAccepted(
destSlot.index,
destSlot.acceptedDirection,
item
);
targetAcceptorComp.onItemAccepted(destSlot.index, destSlot.slot.direction, item);
}
sourceSlot.item = null;
continue;