1
0
mirror of https://github.com/tobspr/shapez.io.git synced 2026-03-02 03:39:21 +00:00

Initial commit

This commit is contained in:
Tobias Springer
2020-05-09 16:45:23 +02:00
commit 93c6ea683d
304 changed files with 56031 additions and 0 deletions

View File

@@ -0,0 +1,204 @@
import { Loader } from "../../core/loader";
import { enumAngleToDirection, enumDirection, Vector } from "../../core/vector";
import { BeltComponent } from "../components/belt";
import { ItemAcceptorComponent } from "../components/item_acceptor";
import { ItemEjectorComponent } from "../components/item_ejector";
import { ReplaceableMapEntityComponent } from "../components/replaceable_map_entity";
import { Entity } from "../entity";
import { MetaBuilding } from "../meta_building";
import { GameRoot } from "../root";
export const arrayBeltVariantToRotation = [enumDirection.top, enumDirection.left, enumDirection.right];
export class MetaBeltBaseBuilding extends MetaBuilding {
constructor() {
super("belt");
}
getSilhouetteColor() {
return "#777";
}
/**
* Creates the entity at the given location
* @param {Entity} entity
*/
setupEntityComponents(entity) {
entity.addComponent(
new BeltComponent({
direction: enumDirection.top, // updated later
})
);
entity.addComponent(
new ItemAcceptorComponent({
slots: [
{
pos: new Vector(0, 0),
directions: [enumDirection.bottom],
},
],
})
);
entity.addComponent(
new ItemEjectorComponent({
slots: [
{
pos: new Vector(0, 0),
direction: enumDirection.top, // updated later
},
],
instantEject: true,
})
);
// Make this entity replaceabel
entity.addComponent(new ReplaceableMapEntityComponent());
}
/**
*
* @param {Entity} entity
* @param {number} rotationVariant
*/
updateRotationVariant(entity, rotationVariant) {
entity.components.Belt.direction = arrayBeltVariantToRotation[rotationVariant];
entity.components.ItemEjector.slots[0].direction = arrayBeltVariantToRotation[rotationVariant];
entity.components.StaticMapEntity.spriteKey = null;
}
/**
* Computes optimal belt rotation variant
* @param {GameRoot} root
* @param {Vector} tile
* @param {number} rotation
* @return {{ rotation: number, rotationVariant: number }}
*/
computeOptimalDirectionAndRotationVariantAtTile(root, tile, rotation) {
const topDirection = enumAngleToDirection[rotation];
const rightDirection = enumAngleToDirection[(rotation + 90) % 360];
const bottomDirection = enumAngleToDirection[(rotation + 180) % 360];
const leftDirection = enumAngleToDirection[(rotation + 270) % 360];
const { ejectors, acceptors } = root.logic.getEjectorsAndAcceptorsAtTile(tile);
let hasBottomEjector = false;
let hasLeftEjector = false;
let hasRightEjector = false;
let hasTopAcceptor = false;
let hasLeftAcceptor = false;
let hasRightAcceptor = false;
// Check all ejectors
for (let i = 0; i < ejectors.length; ++i) {
const ejector = ejectors[i];
if (ejector.toDirection === topDirection) {
hasBottomEjector = true;
} else if (ejector.toDirection === leftDirection) {
hasLeftEjector = true;
} else if (ejector.toDirection === rightDirection) {
hasRightEjector = true;
}
}
// Check all acceptors
for (let i = 0; i < acceptors.length; ++i) {
const acceptor = acceptors[i];
if (acceptor.fromDirection === bottomDirection) {
hasTopAcceptor = true;
} else if (acceptor.fromDirection === rightDirection) {
hasLeftAcceptor = true;
} else if (acceptor.fromDirection === leftDirection) {
hasRightAcceptor = true;
}
}
// Soo .. if there is any ejector below us we always prioritize
// this ejector
if (!hasBottomEjector) {
// When something ejects to us from the left and nothing from the right,
// do a curve from the left to the top
if (hasLeftEjector && !hasRightEjector) {
return {
rotation: (rotation + 270) % 360,
rotationVariant: 2,
};
}
// When something ejects to us from the right and nothing from the left,
// do a curve from the right to the top
if (hasRightEjector && !hasLeftEjector) {
return {
rotation: (rotation + 90) % 360,
rotationVariant: 1,
};
}
}
// When there is a top acceptor, ignore sides
// NOTICE: This makes the belt prefer side turns *way* too much!
// if (!hasTopAcceptor) {
// // When there is an acceptor to the right but no acceptor to the left,
// // do a turn to the right
// if (hasRightAcceptor && !hasLeftAcceptor) {
// return {
// rotation,
// rotationVariant: 2,
// };
// }
// // When there is an acceptor to the left but no acceptor to the right,
// // do a turn to the left
// if (hasLeftAcceptor && !hasRightAcceptor) {
// return {
// rotation,
// rotationVariant: 1,
// };
// }
// }
return {
rotation,
rotationVariant: 0,
};
}
getName() {
return "Belt";
}
getDescription() {
return "Transports items, hold and drag to place multiple, press 'R' to rotate.";
}
getPreviewSprite(rotationVariant) {
switch (arrayBeltVariantToRotation[rotationVariant]) {
case enumDirection.top: {
return Loader.getSprite("sprites/belt/forward_0.png");
}
case enumDirection.left: {
return Loader.getSprite("sprites/belt/left_0.png");
}
case enumDirection.right: {
return Loader.getSprite("sprites/belt/right_0.png");
}
default: {
assertAlways(false, "Invalid belt rotation variant");
}
}
}
getStayInPlacementMode() {
return true;
}
/**
* Can be overridden
*/
internalGetBeltDirection(rotationVariant) {
return enumDirection.top;
}
}

View File

@@ -0,0 +1,71 @@
import { globalConfig } from "../../core/config";
import { enumDirection, Vector } from "../../core/vector";
import { enumItemAcceptorItemFilter, ItemAcceptorComponent } from "../components/item_acceptor";
import { ItemEjectorComponent } from "../components/item_ejector";
import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor";
import { Entity } from "../entity";
import { MetaBuilding } from "../meta_building";
import { GameRoot } from "../root";
import { enumHubGoalRewards } from "../tutorial_goals";
export class MetaCutterBuilding extends MetaBuilding {
constructor() {
super("cutter");
}
getSilhouetteColor() {
return "#7dcda2";
}
getDimensions() {
return new Vector(2, 1);
}
getName() {
return "Cut Half";
}
getDescription() {
return "Cuts shapes from top to bottom and outputs both halfs. <strong>If you use only one part, be sure to destroy the other part or it will stall!</strong>";
}
/**
* @param {GameRoot} root
*/
getIsUnlocked(root) {
return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_cutter_and_trash);
}
/**
* Creates the entity at the given location
* @param {Entity} entity
*/
setupEntityComponents(entity) {
entity.addComponent(
new ItemProcessorComponent({
inputsPerCharge: 1,
processorType: enumItemProcessorTypes.cutter,
})
);
entity.addComponent(
new ItemEjectorComponent({
slots: [
{ pos: new Vector(0, 0), direction: enumDirection.top },
{ pos: new Vector(1, 0), direction: enumDirection.top },
],
})
);
entity.addComponent(
new ItemAcceptorComponent({
slots: [
{
pos: new Vector(0, 0),
directions: [enumDirection.bottom],
filter: enumItemAcceptorItemFilter.shape,
},
],
})
);
}
}

View File

@@ -0,0 +1,125 @@
import { enumDirection, Vector } from "../../core/vector";
import { enumItemAcceptorItemFilter, ItemAcceptorComponent } from "../components/item_acceptor";
import { Entity } from "../entity";
import { MetaBuilding } from "../meta_building";
import { ItemProcessorComponent, enumItemProcessorTypes } from "../components/item_processor";
import { globalConfig } from "../../core/config";
import { UnremovableComponent } from "../components/unremovable";
import { HubComponent } from "../components/hub";
export class MetaHubBuilding extends MetaBuilding {
constructor() {
super("hub");
}
getDimensions() {
return new Vector(4, 4);
}
getSilhouetteColor() {
return "#eb5555";
}
getName() {
return "Hub";
}
getDescription() {
return "Your central hub, deliver shapes to it to unlock new buildings.";
}
isRotateable() {
return false;
}
/**
* Creates the entity at the given location
* @param {Entity} entity
*/
setupEntityComponents(entity) {
entity.addComponent(new HubComponent());
entity.addComponent(
new ItemProcessorComponent({
inputsPerCharge: 1,
processorType: enumItemProcessorTypes.hub,
})
);
entity.addComponent(new UnremovableComponent());
entity.addComponent(
new ItemAcceptorComponent({
slots: [
{
pos: new Vector(0, 0),
directions: [enumDirection.top, enumDirection.left],
filter: enumItemAcceptorItemFilter.shape,
},
{
pos: new Vector(1, 0),
directions: [enumDirection.top],
filter: enumItemAcceptorItemFilter.shape,
},
{
pos: new Vector(2, 0),
directions: [enumDirection.top],
filter: enumItemAcceptorItemFilter.shape,
},
{
pos: new Vector(3, 0),
directions: [enumDirection.top, enumDirection.right],
filter: enumItemAcceptorItemFilter.shape,
},
{
pos: new Vector(0, 3),
directions: [enumDirection.bottom, enumDirection.left],
filter: enumItemAcceptorItemFilter.shape,
},
{
pos: new Vector(1, 3),
directions: [enumDirection.bottom],
filter: enumItemAcceptorItemFilter.shape,
},
{
pos: new Vector(2, 3),
directions: [enumDirection.bottom],
filter: enumItemAcceptorItemFilter.shape,
},
{
pos: new Vector(3, 3),
directions: [enumDirection.bottom, enumDirection.right],
filter: enumItemAcceptorItemFilter.shape,
},
{
pos: new Vector(0, 1),
directions: [enumDirection.left],
filter: enumItemAcceptorItemFilter.shape,
},
{
pos: new Vector(0, 2),
directions: [enumDirection.left],
filter: enumItemAcceptorItemFilter.shape,
},
{
pos: new Vector(0, 3),
directions: [enumDirection.left],
filter: enumItemAcceptorItemFilter.shape,
},
{
pos: new Vector(3, 1),
directions: [enumDirection.right],
filter: enumItemAcceptorItemFilter.shape,
},
{
pos: new Vector(3, 2),
directions: [enumDirection.right],
filter: enumItemAcceptorItemFilter.shape,
},
{
pos: new Vector(3, 3),
directions: [enumDirection.right],
filter: enumItemAcceptorItemFilter.shape,
},
],
})
);
}
}

View File

@@ -0,0 +1,36 @@
import { enumDirection, Vector } from "../../core/vector";
import { ItemEjectorComponent } from "../components/item_ejector";
import { MinerComponent } from "../components/miner";
import { Entity } from "../entity";
import { MetaBuilding } from "../meta_building";
export class MetaMinerBuilding extends MetaBuilding {
constructor() {
super("miner");
}
getName() {
return "Extract";
}
getSilhouetteColor() {
return "#b37dcd";
}
getDescription() {
return "Place over a shape or color to extract it. Six extractors fill exactly one belt.";
}
/**
* Creates the entity at the given location
* @param {Entity} entity
*/
setupEntityComponents(entity) {
entity.addComponent(new MinerComponent({}));
entity.addComponent(
new ItemEjectorComponent({
slots: [{ pos: new Vector(0, 0), direction: enumDirection.top }],
})
);
}
}

View File

@@ -0,0 +1,73 @@
import { globalConfig } from "../../core/config";
import { enumDirection, Vector } from "../../core/vector";
import { ItemAcceptorComponent, enumItemAcceptorItemFilter } from "../components/item_acceptor";
import { ItemEjectorComponent } from "../components/item_ejector";
import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor";
import { Entity } from "../entity";
import { MetaBuilding } from "../meta_building";
import { GameRoot } from "../root";
import { enumHubGoalRewards } from "../tutorial_goals";
export class MetaMixerBuilding extends MetaBuilding {
constructor() {
super("mixer");
}
getDimensions() {
return new Vector(2, 1);
}
getName() {
return "Mix Colors";
}
getDescription() {
return "Mixes two colors using additive blending.";
}
getSilhouetteColor() {
return "#cdbb7d";
}
/**
* @param {GameRoot} root
*/
getIsUnlocked(root) {
return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_mixer);
}
/**
* Creates the entity at the given location
* @param {Entity} entity
*/
setupEntityComponents(entity) {
entity.addComponent(
new ItemProcessorComponent({
inputsPerCharge: 2,
processorType: enumItemProcessorTypes.mixer,
})
);
entity.addComponent(
new ItemEjectorComponent({
slots: [{ pos: new Vector(0, 0), direction: enumDirection.top }],
})
);
entity.addComponent(
new ItemAcceptorComponent({
slots: [
{
pos: new Vector(0, 0),
directions: [enumDirection.bottom],
filter: enumItemAcceptorItemFilter.color,
},
{
pos: new Vector(1, 0),
directions: [enumDirection.bottom],
filter: enumItemAcceptorItemFilter.color,
},
],
})
);
}
}

View File

@@ -0,0 +1,73 @@
import { globalConfig } from "../../core/config";
import { enumDirection, Vector } from "../../core/vector";
import { enumItemAcceptorItemFilter, ItemAcceptorComponent } from "../components/item_acceptor";
import { ItemEjectorComponent } from "../components/item_ejector";
import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor";
import { Entity } from "../entity";
import { MetaBuilding } from "../meta_building";
import { enumHubGoalRewards } from "../tutorial_goals";
import { GameRoot } from "../root";
export class MetaPainterBuilding extends MetaBuilding {
constructor() {
super("painter");
}
getDimensions() {
return new Vector(2, 1);
}
getName() {
return "Dye";
}
getDescription() {
return "Colors the whole shape on the left input with the color from the right input.";
}
getSilhouetteColor() {
return "#cd9b7d";
}
/**
* @param {GameRoot} root
*/
getIsUnlocked(root) {
return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_painter);
}
/**
* Creates the entity at the given location
* @param {Entity} entity
*/
setupEntityComponents(entity) {
entity.addComponent(
new ItemProcessorComponent({
inputsPerCharge: 2,
processorType: enumItemProcessorTypes.painter,
})
);
entity.addComponent(
new ItemEjectorComponent({
slots: [{ pos: new Vector(0, 0), direction: enumDirection.top }],
})
);
entity.addComponent(
new ItemAcceptorComponent({
slots: [
{
pos: new Vector(0, 0),
directions: [enumDirection.bottom],
filter: enumItemAcceptorItemFilter.shape,
},
{
pos: new Vector(1, 0),
directions: [enumDirection.bottom],
filter: enumItemAcceptorItemFilter.color,
},
],
})
);
}
}

View File

@@ -0,0 +1,64 @@
import { globalConfig } from "../../core/config";
import { enumDirection, Vector } from "../../core/vector";
import { ItemAcceptorComponent, enumItemAcceptorItemFilter } from "../components/item_acceptor";
import { ItemEjectorComponent } from "../components/item_ejector";
import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor";
import { Entity } from "../entity";
import { MetaBuilding } from "../meta_building";
import { enumHubGoalRewards } from "../tutorial_goals";
import { GameRoot } from "../root";
export class MetaRotaterBuilding extends MetaBuilding {
constructor() {
super("rotater");
}
getName() {
return "Rotate";
}
getDescription() {
return "Rotates shapes clockwise by 90 degrees.";
}
getSilhouetteColor() {
return "#7dc6cd";
}
/**
* @param {GameRoot} root
*/
getIsUnlocked(root) {
return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_rotater);
}
/**
* Creates the entity at the given location
* @param {Entity} entity
*/
setupEntityComponents(entity) {
entity.addComponent(
new ItemProcessorComponent({
inputsPerCharge: 1,
processorType: enumItemProcessorTypes.rotater,
})
);
entity.addComponent(
new ItemEjectorComponent({
slots: [{ pos: new Vector(0, 0), direction: enumDirection.top }],
})
);
entity.addComponent(
new ItemAcceptorComponent({
slots: [
{
pos: new Vector(0, 0),
directions: [enumDirection.bottom],
filter: enumItemAcceptorItemFilter.shape,
},
],
})
);
}
}

View File

@@ -0,0 +1,80 @@
import { globalConfig } from "../../core/config";
import { enumDirection, Vector } from "../../core/vector";
import { ItemAcceptorComponent } from "../components/item_acceptor";
import { ItemEjectorComponent } from "../components/item_ejector";
import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor";
import { Entity } from "../entity";
import { MetaBuilding } from "../meta_building";
import { GameRoot } from "../root";
import { enumHubGoalRewards } from "../tutorial_goals";
export class MetaSplitterBuilding extends MetaBuilding {
constructor() {
super("splitter");
}
getDimensions() {
return new Vector(2, 1);
}
getName() {
return "Distribute";
}
getSilhouetteColor() {
return "#444";
}
getDescription() {
return "Accepts up to two inputs and evenly distributes them on the outputs. Can also be used to merge two inputs into one output.";
}
/**
* @param {GameRoot} root
*/
getIsUnlocked(root) {
return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_splitter);
}
/**
* Creates the entity at the given location
* @param {Entity} entity
*/
setupEntityComponents(entity) {
entity.addComponent(
new ItemAcceptorComponent({
slots: [
{
pos: new Vector(0, 0),
directions: [enumDirection.bottom],
},
{
pos: new Vector(1, 0),
directions: [enumDirection.bottom],
},
],
})
);
entity.addComponent(
new ItemProcessorComponent({
inputsPerCharge: 1,
processorType: enumItemProcessorTypes.splitter,
beltUnderlays: [
{ pos: new Vector(0, 0), direction: enumDirection.top },
{ pos: new Vector(1, 0), direction: enumDirection.top },
],
})
);
entity.addComponent(
new ItemEjectorComponent({
slots: [
{ pos: new Vector(0, 0), direction: enumDirection.top },
{ pos: new Vector(1, 0), direction: enumDirection.top },
],
})
);
}
}

View File

@@ -0,0 +1,73 @@
import { globalConfig } from "../../core/config";
import { enumDirection, Vector } from "../../core/vector";
import { ItemAcceptorComponent, enumItemAcceptorItemFilter } from "../components/item_acceptor";
import { ItemEjectorComponent } from "../components/item_ejector";
import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor";
import { Entity } from "../entity";
import { MetaBuilding } from "../meta_building";
import { GameRoot } from "../root";
import { enumHubGoalRewards } from "../tutorial_goals";
export class MetaStackerBuilding extends MetaBuilding {
constructor() {
super("stacker");
}
getName() {
return "Combine";
}
getSilhouetteColor() {
return "#9fcd7d";
}
getDescription() {
return "Combines both items. If they can not be merged, the right item is placed above the left item.";
}
getDimensions() {
return new Vector(2, 1);
}
/**
* @param {GameRoot} root
*/
getIsUnlocked(root) {
return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_stacker);
}
/**
* Creates the entity at the given location
* @param {Entity} entity
*/
setupEntityComponents(entity) {
entity.addComponent(
new ItemProcessorComponent({
inputsPerCharge: 2,
processorType: enumItemProcessorTypes.stacker,
})
);
entity.addComponent(
new ItemEjectorComponent({
slots: [{ pos: new Vector(0, 0), direction: enumDirection.top }],
})
);
entity.addComponent(
new ItemAcceptorComponent({
slots: [
{
pos: new Vector(0, 0),
directions: [enumDirection.bottom],
filter: enumItemAcceptorItemFilter.shape,
},
{
pos: new Vector(1, 0),
directions: [enumDirection.bottom],
filter: enumItemAcceptorItemFilter.shape,
},
],
})
);
}
}

View File

@@ -0,0 +1,73 @@
import { enumDirection, Vector } from "../../core/vector";
import { ItemAcceptorComponent } from "../components/item_acceptor";
import { ItemEjectorComponent } from "../components/item_ejector";
import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor";
import { Entity } from "../entity";
import { MetaBuilding } from "../meta_building";
import { enumHubGoalRewards } from "../tutorial_goals";
import { GameRoot } from "../root";
export class MetaTrashBuilding extends MetaBuilding {
constructor() {
super("trash");
}
getName() {
return "Destroyer";
}
getDescription() {
return "Accepts inputs from all sides and destroys them. Forever.";
}
isRotateable() {
return false;
}
getSilhouetteColor() {
return "#cd7d86";
}
/**
* @param {GameRoot} root
*/
getIsUnlocked(root) {
return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_cutter_and_trash);
}
/**
* Creates the entity at the given location
* @param {Entity} entity
*/
setupEntityComponents(entity) {
entity.addComponent(
new ItemProcessorComponent({
inputsPerCharge: 1,
processorType: enumItemProcessorTypes.trash,
})
);
// Required, since the item processor needs this.
entity.addComponent(
new ItemEjectorComponent({
slots: [],
})
);
entity.addComponent(
new ItemAcceptorComponent({
slots: [
{
pos: new Vector(0, 0),
directions: [
enumDirection.top,
enumDirection.right,
enumDirection.bottom,
enumDirection.left,
],
},
],
})
);
}
}

View File

@@ -0,0 +1,158 @@
import { Loader } from "../../core/loader";
import { enumDirection, Vector, enumAngleToDirection, enumDirectionToVector } from "../../core/vector";
import { ItemAcceptorComponent } from "../components/item_acceptor";
import { ItemEjectorComponent } from "../components/item_ejector";
import { enumUndergroundBeltMode, UndergroundBeltComponent } from "../components/underground_belt";
import { Entity } from "../entity";
import { MetaBuilding } from "../meta_building";
import { GameRoot } from "../root";
import { globalConfig } from "../../core/config";
import { enumHubGoalRewards } from "../tutorial_goals";
/** @enum {string} */
export const arrayUndergroundRotationVariantToMode = [
enumUndergroundBeltMode.sender,
enumUndergroundBeltMode.receiver,
];
export class MetaUndergroundBeltBuilding extends MetaBuilding {
constructor() {
super("underground_belt");
}
getName() {
return "Tunnel";
}
getSilhouetteColor() {
return "#555";
}
getDescription() {
return "Allows to tunnel resources under buildings and belts.";
}
getFlipOrientationAfterPlacement() {
return true;
}
getStayInPlacementMode() {
return true;
}
getPreviewSprite(rotationVariant) {
switch (arrayUndergroundRotationVariantToMode[rotationVariant]) {
case enumUndergroundBeltMode.sender:
return Loader.getSprite("sprites/buildings/underground_belt_entry.png");
case enumUndergroundBeltMode.receiver:
return Loader.getSprite("sprites/buildings/underground_belt_exit.png");
default:
assertAlways(false, "Invalid rotation variant");
}
}
/**
* @param {GameRoot} root
*/
getIsUnlocked(root) {
return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_tunnel);
}
/**
* Creates the entity at the given location
* @param {Entity} entity
*/
setupEntityComponents(entity) {
// Required, since the item processor needs this.
entity.addComponent(
new ItemEjectorComponent({
slots: [],
})
);
entity.addComponent(new UndergroundBeltComponent({}));
entity.addComponent(
new ItemAcceptorComponent({
slots: [],
})
);
}
/**
* @param {GameRoot} root
* @param {Vector} tile
* @param {number} rotation
* @return {{ rotation: number, rotationVariant: number, connectedEntities?: Array<Entity> }}
*/
computeOptimalDirectionAndRotationVariantAtTile(root, tile, rotation) {
const searchDirection = enumAngleToDirection[rotation];
const searchVector = enumDirectionToVector[searchDirection];
const targetRotation = (rotation + 180) % 360;
for (let searchOffset = 1; searchOffset <= globalConfig.undergroundBeltMaxTiles; ++searchOffset) {
tile = tile.addScalars(searchVector.x, searchVector.y);
const contents = root.map.getTileContent(tile);
if (contents) {
const undergroundComp = contents.components.UndergroundBelt;
if (undergroundComp) {
const staticComp = contents.components.StaticMapEntity;
if (staticComp.rotationDegrees === targetRotation) {
if (undergroundComp.mode !== enumUndergroundBeltMode.sender) {
// If we encounter an underground receiver on our way which is also faced in our direction, we don't accept that
break;
}
// console.log("GOT IT! rotation is", rotation, "and target is", staticComp.rotationDegrees);
return {
rotation: targetRotation,
rotationVariant: 1,
connectedEntities: [contents],
};
}
}
}
}
return {
rotation,
rotationVariant: 0,
};
}
/**
* @param {Entity} entity
* @param {number} rotationVariant
*/
updateRotationVariant(entity, rotationVariant) {
entity.components.StaticMapEntity.spriteKey = this.getPreviewSprite(rotationVariant).spriteName;
switch (arrayUndergroundRotationVariantToMode[rotationVariant]) {
case enumUndergroundBeltMode.sender: {
entity.components.UndergroundBelt.mode = enumUndergroundBeltMode.sender;
entity.components.ItemEjector.setSlots([]);
entity.components.ItemAcceptor.setSlots([
{
pos: new Vector(0, 0),
directions: [enumDirection.bottom],
},
]);
return;
}
case enumUndergroundBeltMode.receiver: {
entity.components.UndergroundBelt.mode = enumUndergroundBeltMode.receiver;
entity.components.ItemAcceptor.setSlots([]);
entity.components.ItemEjector.setSlots([
{
pos: new Vector(0, 0),
direction: enumDirection.top,
},
]);
return;
}
default:
assertAlways(false, "Invalid rotation variant");
}
}
}