mirror of
https://github.com/tobspr/shapez.io.git
synced 2026-03-02 03:39:21 +00:00
Initial take on wires
This commit is contained in:
@@ -9,7 +9,7 @@ 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";
|
||||
import { GameRoot, enumLayer } from "../root";
|
||||
|
||||
export const arrayBeltVariantToRotation = [enumDirection.top, enumDirection.left, enumDirection.right];
|
||||
|
||||
@@ -146,7 +146,7 @@ export class MetaBeltBaseBuilding extends MetaBuilding {
|
||||
const bottomDirection = enumAngleToDirection[(rotation + 180) % 360];
|
||||
const leftDirection = enumAngleToDirection[(rotation + 270) % 360];
|
||||
|
||||
const { ejectors, acceptors } = root.logic.getEjectorsAndAcceptorsAtTile(tile);
|
||||
const { ejectors, acceptors } = root.logic.getEjectorsAndAcceptorsAtTile(tile, enumLayer.regular);
|
||||
|
||||
let hasBottomEjector = false;
|
||||
let hasRightEjector = false;
|
||||
|
||||
@@ -2,11 +2,12 @@ import { enumDirection, Vector } from "../../core/vector";
|
||||
import { ItemAcceptorComponent } from "../components/item_acceptor";
|
||||
import { Entity } from "../entity";
|
||||
import { MetaBuilding } from "../meta_building";
|
||||
import { GameRoot } from "../root";
|
||||
import { GameRoot, enumLayer } from "../root";
|
||||
import { enumHubGoalRewards } from "../tutorial_goals";
|
||||
import { EnergyGeneratorComponent } from "../components/energy_generator";
|
||||
import { WiredPinsComponent, enumPinSlotType } from "../components/wired_pins";
|
||||
import { enumItemType } from "../base_item";
|
||||
import { ItemEjectorComponent } from "../components/item_ejector";
|
||||
|
||||
export class MetaEnergyGenerator extends MetaBuilding {
|
||||
constructor() {
|
||||
@@ -71,6 +72,25 @@ export class MetaEnergyGenerator extends MetaBuilding {
|
||||
directions: [enumDirection.bottom],
|
||||
filter: enumItemType.shape,
|
||||
},
|
||||
|
||||
{
|
||||
pos: new Vector(1, 0),
|
||||
directions: [enumDirection.top],
|
||||
layer: enumLayer.wires,
|
||||
filter: enumItemType.negativeEnergy,
|
||||
},
|
||||
],
|
||||
})
|
||||
);
|
||||
|
||||
entity.addComponent(
|
||||
new ItemEjectorComponent({
|
||||
slots: [
|
||||
{
|
||||
pos: new Vector(0, 0),
|
||||
direction: enumDirection.top,
|
||||
layer: enumLayer.wires,
|
||||
},
|
||||
],
|
||||
})
|
||||
);
|
||||
@@ -87,19 +107,13 @@ export class MetaEnergyGenerator extends MetaBuilding {
|
||||
slots: [
|
||||
{
|
||||
pos: new Vector(0, 0),
|
||||
type: enumPinSlotType.energyEjector,
|
||||
type: enumPinSlotType.positiveEnergyEjector,
|
||||
direction: enumDirection.top,
|
||||
},
|
||||
{
|
||||
pos: new Vector(1, 0),
|
||||
type: enumPinSlotType.energyEjector,
|
||||
},
|
||||
{
|
||||
pos: new Vector(0, 1),
|
||||
type: enumPinSlotType.energyEjector,
|
||||
},
|
||||
{
|
||||
pos: new Vector(1, 1),
|
||||
type: enumPinSlotType.energyEjector,
|
||||
type: enumPinSlotType.negativeEnergyAcceptor,
|
||||
direction: enumDirection.top,
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
@@ -5,7 +5,7 @@ import { ItemEjectorComponent } from "../components/item_ejector";
|
||||
import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor";
|
||||
import { Entity } from "../entity";
|
||||
import { MetaBuilding, defaultBuildingVariant } from "../meta_building";
|
||||
import { GameRoot } from "../root";
|
||||
import { GameRoot, enumLayer } from "../root";
|
||||
import { enumHubGoalRewards } from "../tutorial_goals";
|
||||
import { T } from "../../translations";
|
||||
import { formatItemsPerSecond } from "../../core/utils";
|
||||
@@ -128,8 +128,8 @@ export class MetaSplitterBuilding extends MetaBuilding {
|
||||
]);
|
||||
|
||||
entity.components.ItemAcceptor.beltUnderlays = [
|
||||
{ pos: new Vector(0, 0), direction: enumDirection.top },
|
||||
{ pos: new Vector(1, 0), direction: enumDirection.top },
|
||||
{ pos: new Vector(0, 0), direction: enumDirection.top, layer: enumLayer.regular },
|
||||
{ pos: new Vector(1, 0), direction: enumDirection.top, layer: enumLayer.regular },
|
||||
];
|
||||
|
||||
break;
|
||||
@@ -156,7 +156,7 @@ export class MetaSplitterBuilding extends MetaBuilding {
|
||||
]);
|
||||
|
||||
entity.components.ItemAcceptor.beltUnderlays = [
|
||||
{ pos: new Vector(0, 0), direction: enumDirection.top },
|
||||
{ pos: new Vector(0, 0), direction: enumDirection.top, layer: enumLayer.regular },
|
||||
];
|
||||
|
||||
break;
|
||||
|
||||
@@ -5,7 +5,7 @@ import { ItemEjectorComponent } from "../components/item_ejector";
|
||||
import { enumUndergroundBeltMode, UndergroundBeltComponent } from "../components/underground_belt";
|
||||
import { Entity } from "../entity";
|
||||
import { MetaBuilding, defaultBuildingVariant } from "../meta_building";
|
||||
import { GameRoot } from "../root";
|
||||
import { GameRoot, enumLayer } from "../root";
|
||||
import { globalConfig } from "../../core/config";
|
||||
import { enumHubGoalRewards } from "../tutorial_goals";
|
||||
import { formatItemsPerSecond } from "../../core/utils";
|
||||
@@ -152,7 +152,8 @@ export class MetaUndergroundBeltBuilding extends MetaBuilding {
|
||||
) {
|
||||
tile = tile.addScalars(searchVector.x, searchVector.y);
|
||||
|
||||
const contents = root.map.getTileContent(tile);
|
||||
/* WIRES: FIXME */
|
||||
const contents = root.map.getTileContent(tile, enumLayer.regular);
|
||||
if (contents) {
|
||||
const undergroundComp = contents.components.UndergroundBelt;
|
||||
if (undergroundComp && undergroundComp.tier === tier) {
|
||||
|
||||
226
src/js/game/buildings/wire_base.js
Normal file
226
src/js/game/buildings/wire_base.js
Normal file
@@ -0,0 +1,226 @@
|
||||
import { Loader } from "../../core/loader";
|
||||
import { enumAngleToDirection, enumDirection, Vector } from "../../core/vector";
|
||||
import { SOUNDS } from "../../platform/sound";
|
||||
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 { enumLayer, GameRoot } from "../root";
|
||||
|
||||
export const arrayBeltVariantToRotation = [enumDirection.top, enumDirection.left, enumDirection.right];
|
||||
|
||||
export class MetaWireBaseBuilding extends MetaBuilding {
|
||||
constructor() {
|
||||
super("wire");
|
||||
}
|
||||
|
||||
getSilhouetteColor() {
|
||||
return "#c425d7";
|
||||
}
|
||||
|
||||
getLayer() {
|
||||
return enumLayer.wires;
|
||||
}
|
||||
|
||||
getHasDirectionLockAvailable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
getPreviewSprite(rotationVariant) {
|
||||
switch (arrayBeltVariantToRotation[rotationVariant]) {
|
||||
case enumDirection.top: {
|
||||
return Loader.getSprite("sprites/buildings/wire_top.png");
|
||||
}
|
||||
case enumDirection.left: {
|
||||
return Loader.getSprite("sprites/buildings/wire_left.png");
|
||||
}
|
||||
case enumDirection.right: {
|
||||
return Loader.getSprite("sprites/buildings/wire_right.png");
|
||||
}
|
||||
default: {
|
||||
assertAlways(false, "Invalid belt rotation variant");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getBlueprintSprite(rotationVariant) {
|
||||
switch (arrayBeltVariantToRotation[rotationVariant]) {
|
||||
case enumDirection.top: {
|
||||
return Loader.getSprite("sprites/blueprints/wire_top.png");
|
||||
}
|
||||
case enumDirection.left: {
|
||||
return Loader.getSprite("sprites/blueprints/wire_left.png");
|
||||
}
|
||||
case enumDirection.right: {
|
||||
return Loader.getSprite("sprites/blueprints/wire_right.png");
|
||||
}
|
||||
default: {
|
||||
assertAlways(false, "Invalid belt rotation variant");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getStayInPlacementMode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
getRotateAutomaticallyWhilePlacing() {
|
||||
return true;
|
||||
}
|
||||
|
||||
getPlacementSound() {
|
||||
return SOUNDS.placeBelt;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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],
|
||||
layer: enumLayer.wires,
|
||||
},
|
||||
],
|
||||
animated: false,
|
||||
})
|
||||
);
|
||||
|
||||
entity.addComponent(
|
||||
new ItemEjectorComponent({
|
||||
slots: [
|
||||
{
|
||||
pos: new Vector(0, 0),
|
||||
direction: enumDirection.top, // updated later
|
||||
layer: enumLayer.wires,
|
||||
},
|
||||
],
|
||||
instantEject: true,
|
||||
})
|
||||
);
|
||||
// Make this entity replaceable
|
||||
entity.addComponent(new ReplaceableMapEntityComponent());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Entity} entity
|
||||
* @param {number} rotationVariant
|
||||
*/
|
||||
updateVariants(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
|
||||
* @param {string} variant
|
||||
* @return {{ rotation: number, rotationVariant: number }}
|
||||
*/
|
||||
computeOptimalDirectionAndRotationVariantAtTile(root, tile, rotation, variant) {
|
||||
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, enumLayer.wires);
|
||||
|
||||
let hasBottomEjector = false;
|
||||
let hasRightEjector = false;
|
||||
let hasLeftEjector = 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) {
|
||||
hasRightEjector = true;
|
||||
} else if (ejector.toDirection === rightDirection) {
|
||||
hasLeftEjector = 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 (hasRightEjector && !hasLeftEjector) {
|
||||
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 (hasLeftEjector && !hasRightEjector) {
|
||||
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,
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user