mirror of
https://github.com/tobspr/shapez.io.git
synced 2026-03-02 03:39:21 +00:00
Restructure buildings
This commit is contained in:
79
src/js/game/buildings/analyzer.js
Normal file
79
src/js/game/buildings/analyzer.js
Normal file
@@ -0,0 +1,79 @@
|
||||
import { generateMatrixRotations } from "../../core/utils";
|
||||
import { enumDirection, Vector } from "../../core/vector";
|
||||
import { enumLogicGateType, LogicGateComponent } from "../components/logic_gate";
|
||||
import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
|
||||
import { Entity } from "../entity";
|
||||
import { MetaBuilding } from "../meta_building";
|
||||
import { GameRoot } from "../root";
|
||||
|
||||
const overlayMatrix = generateMatrixRotations([1, 1, 0, 1, 1, 1, 0, 1, 0]);
|
||||
|
||||
export class MetaAnalyzerBuilding extends MetaBuilding {
|
||||
constructor() {
|
||||
super("analyzer");
|
||||
}
|
||||
|
||||
getSilhouetteColor() {
|
||||
return "#3a52bc";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {GameRoot} root
|
||||
*/
|
||||
getIsUnlocked(root) {
|
||||
// @todo
|
||||
return true;
|
||||
}
|
||||
|
||||
/** @returns {"wires"} **/
|
||||
getLayer() {
|
||||
return "wires";
|
||||
}
|
||||
|
||||
getDimensions() {
|
||||
return new Vector(1, 1);
|
||||
}
|
||||
|
||||
getRenderPins() {
|
||||
// We already have it included
|
||||
return false;
|
||||
}
|
||||
|
||||
getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant) {
|
||||
return overlayMatrix[rotation];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the entity at the given location
|
||||
* @param {Entity} entity
|
||||
*/
|
||||
setupEntityComponents(entity) {
|
||||
entity.addComponent(
|
||||
new WiredPinsComponent({
|
||||
slots: [
|
||||
{
|
||||
pos: new Vector(0, 0),
|
||||
direction: enumDirection.left,
|
||||
type: enumPinSlotType.logicalEjector,
|
||||
},
|
||||
{
|
||||
pos: new Vector(0, 0),
|
||||
direction: enumDirection.right,
|
||||
type: enumPinSlotType.logicalEjector,
|
||||
},
|
||||
{
|
||||
pos: new Vector(0, 0),
|
||||
direction: enumDirection.bottom,
|
||||
type: enumPinSlotType.logicalAcceptor,
|
||||
},
|
||||
],
|
||||
})
|
||||
);
|
||||
|
||||
entity.addComponent(
|
||||
new LogicGateComponent({
|
||||
type: enumLogicGateType.analyzer,
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
72
src/js/game/buildings/comparator.js
Normal file
72
src/js/game/buildings/comparator.js
Normal file
@@ -0,0 +1,72 @@
|
||||
import { enumDirection, Vector } from "../../core/vector";
|
||||
import { enumLogicGateType, LogicGateComponent } from "../components/logic_gate";
|
||||
import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
|
||||
import { Entity } from "../entity";
|
||||
import { MetaBuilding } from "../meta_building";
|
||||
import { GameRoot } from "../root";
|
||||
|
||||
export class MetaComparatorBuilding extends MetaBuilding {
|
||||
constructor() {
|
||||
super("comparator");
|
||||
}
|
||||
|
||||
getSilhouetteColor() {
|
||||
return "#823cab";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {GameRoot} root
|
||||
*/
|
||||
getIsUnlocked(root) {
|
||||
// @todo
|
||||
return true;
|
||||
}
|
||||
|
||||
/** @returns {"wires"} **/
|
||||
getLayer() {
|
||||
return "wires";
|
||||
}
|
||||
|
||||
getDimensions() {
|
||||
return new Vector(1, 1);
|
||||
}
|
||||
|
||||
getRenderPins() {
|
||||
// We already have it included
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the entity at the given location
|
||||
* @param {Entity} entity
|
||||
*/
|
||||
setupEntityComponents(entity) {
|
||||
entity.addComponent(
|
||||
new WiredPinsComponent({
|
||||
slots: [
|
||||
{
|
||||
pos: new Vector(0, 0),
|
||||
direction: enumDirection.top,
|
||||
type: enumPinSlotType.logicalEjector,
|
||||
},
|
||||
{
|
||||
pos: new Vector(0, 0),
|
||||
direction: enumDirection.left,
|
||||
type: enumPinSlotType.logicalAcceptor,
|
||||
},
|
||||
{
|
||||
pos: new Vector(0, 0),
|
||||
direction: enumDirection.right,
|
||||
type: enumPinSlotType.logicalAcceptor,
|
||||
},
|
||||
],
|
||||
})
|
||||
);
|
||||
|
||||
entity.addComponent(
|
||||
new LogicGateComponent({
|
||||
type: enumLogicGateType.compare,
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,9 @@ import { Entity } from "../entity";
|
||||
import { MetaBuilding } from "../meta_building";
|
||||
import { GameRoot } from "../root";
|
||||
import { ConstantSignalComponent } from "../components/constant_signal";
|
||||
import { generateMatrixRotations } from "../../core/utils";
|
||||
|
||||
const overlayMatrix = generateMatrixRotations([0, 1, 0, 1, 1, 1, 1, 1, 1]);
|
||||
|
||||
export class MetaConstantSignalBuilding extends MetaBuilding {
|
||||
constructor() {
|
||||
@@ -11,7 +14,7 @@ export class MetaConstantSignalBuilding extends MetaBuilding {
|
||||
}
|
||||
|
||||
getSilhouetteColor() {
|
||||
return "#2bafda";
|
||||
return "#2b84fd";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -35,6 +38,10 @@ export class MetaConstantSignalBuilding extends MetaBuilding {
|
||||
return false;
|
||||
}
|
||||
|
||||
getSpecialOverlayRenderMatrix(rotation) {
|
||||
return overlayMatrix[rotation];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the entity at the given location
|
||||
* @param {Entity} entity
|
||||
|
||||
@@ -1,155 +1,151 @@
|
||||
import { enumDirection, Vector } from "../../core/vector";
|
||||
import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
|
||||
import { Entity } from "../entity";
|
||||
import { MetaBuilding, defaultBuildingVariant } from "../meta_building";
|
||||
import { GameRoot } from "../root";
|
||||
import { enumLogicGateType, LogicGateComponent } from "../components/logic_gate";
|
||||
|
||||
/** @enum {string} */
|
||||
export const enumLogicGateVariants = {
|
||||
not: "not",
|
||||
xor: "xor",
|
||||
or: "or",
|
||||
transistor: "transistor",
|
||||
};
|
||||
|
||||
/** @enum {string} */
|
||||
export const enumVariantToGate = {
|
||||
[defaultBuildingVariant]: enumLogicGateType.and,
|
||||
[enumLogicGateVariants.not]: enumLogicGateType.not,
|
||||
[enumLogicGateVariants.xor]: enumLogicGateType.xor,
|
||||
[enumLogicGateVariants.or]: enumLogicGateType.or,
|
||||
[enumLogicGateVariants.transistor]: enumLogicGateType.transistor,
|
||||
};
|
||||
|
||||
export class MetaLogicGateBuilding extends MetaBuilding {
|
||||
constructor() {
|
||||
super("logic_gate");
|
||||
}
|
||||
|
||||
getSilhouetteColor() {
|
||||
return "#89dc60";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {GameRoot} root
|
||||
*/
|
||||
getIsUnlocked(root) {
|
||||
// @todo
|
||||
return true;
|
||||
}
|
||||
|
||||
/** @returns {"wires"} **/
|
||||
getLayer() {
|
||||
return "wires";
|
||||
}
|
||||
|
||||
getDimensions() {
|
||||
return new Vector(1, 1);
|
||||
}
|
||||
|
||||
getAvailableVariants() {
|
||||
return [
|
||||
defaultBuildingVariant,
|
||||
enumLogicGateVariants.not,
|
||||
enumLogicGateVariants.xor,
|
||||
enumLogicGateVariants.or,
|
||||
enumLogicGateVariants.transistor,
|
||||
];
|
||||
}
|
||||
|
||||
getRenderPins() {
|
||||
// We already have it included
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Entity} entity
|
||||
* @param {number} rotationVariant
|
||||
*/
|
||||
updateVariants(entity, rotationVariant, variant) {
|
||||
const gateType = enumVariantToGate[variant];
|
||||
entity.components.LogicGate.type = gateType;
|
||||
|
||||
const pinComp = entity.components.WiredPins;
|
||||
|
||||
switch (gateType) {
|
||||
case enumLogicGateType.and:
|
||||
case enumLogicGateType.xor:
|
||||
case enumLogicGateType.or: {
|
||||
pinComp.setSlots([
|
||||
{
|
||||
pos: new Vector(0, 0),
|
||||
direction: enumDirection.top,
|
||||
type: enumPinSlotType.logicalEjector,
|
||||
},
|
||||
{
|
||||
pos: new Vector(0, 0),
|
||||
direction: enumDirection.left,
|
||||
type: enumPinSlotType.logicalAcceptor,
|
||||
},
|
||||
{
|
||||
pos: new Vector(0, 0),
|
||||
direction: enumDirection.right,
|
||||
type: enumPinSlotType.logicalAcceptor,
|
||||
},
|
||||
]);
|
||||
break;
|
||||
}
|
||||
case enumLogicGateType.transistor: {
|
||||
pinComp.setSlots([
|
||||
{
|
||||
pos: new Vector(0, 0),
|
||||
direction: enumDirection.top,
|
||||
type: enumPinSlotType.logicalEjector,
|
||||
},
|
||||
{
|
||||
pos: new Vector(0, 0),
|
||||
direction: enumDirection.left,
|
||||
type: enumPinSlotType.logicalAcceptor,
|
||||
},
|
||||
{
|
||||
pos: new Vector(0, 0),
|
||||
direction: enumDirection.bottom,
|
||||
type: enumPinSlotType.logicalAcceptor,
|
||||
},
|
||||
]);
|
||||
break;
|
||||
}
|
||||
|
||||
case enumLogicGateType.not: {
|
||||
pinComp.setSlots([
|
||||
{
|
||||
pos: new Vector(0, 0),
|
||||
direction: enumDirection.top,
|
||||
type: enumPinSlotType.logicalEjector,
|
||||
},
|
||||
{
|
||||
pos: new Vector(0, 0),
|
||||
direction: enumDirection.bottom,
|
||||
type: enumPinSlotType.logicalAcceptor,
|
||||
},
|
||||
]);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
assertAlways("unknown logic gate type: " + gateType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the entity at the given location
|
||||
* @param {Entity} entity
|
||||
*/
|
||||
setupEntityComponents(entity) {
|
||||
entity.addComponent(
|
||||
new WiredPinsComponent({
|
||||
slots: [],
|
||||
})
|
||||
);
|
||||
|
||||
entity.addComponent(new LogicGateComponent({}));
|
||||
}
|
||||
}
|
||||
import { enumDirection, Vector } from "../../core/vector";
|
||||
import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
|
||||
import { Entity } from "../entity";
|
||||
import { MetaBuilding, defaultBuildingVariant } from "../meta_building";
|
||||
import { GameRoot } from "../root";
|
||||
import { enumLogicGateType, LogicGateComponent } from "../components/logic_gate";
|
||||
import { generateMatrixRotations } from "../../core/utils";
|
||||
|
||||
/** @enum {string} */
|
||||
export const enumLogicGateVariants = {
|
||||
not: "not",
|
||||
xor: "xor",
|
||||
or: "or",
|
||||
};
|
||||
|
||||
/** @enum {string} */
|
||||
export const enumVariantToGate = {
|
||||
[defaultBuildingVariant]: enumLogicGateType.and,
|
||||
[enumLogicGateVariants.not]: enumLogicGateType.not,
|
||||
[enumLogicGateVariants.xor]: enumLogicGateType.xor,
|
||||
[enumLogicGateVariants.or]: enumLogicGateType.or,
|
||||
};
|
||||
|
||||
const overlayMatrices = {
|
||||
[defaultBuildingVariant]: generateMatrixRotations([0, 1, 0, 1, 1, 1, 0, 1, 1]),
|
||||
[enumLogicGateVariants.xor]: generateMatrixRotations([0, 1, 0, 1, 1, 1, 0, 1, 1]),
|
||||
[enumLogicGateVariants.or]: generateMatrixRotations([0, 1, 0, 1, 1, 1, 0, 1, 1]),
|
||||
[enumLogicGateVariants.not]: generateMatrixRotations([0, 1, 0, 0, 1, 0, 0, 1, 0]),
|
||||
};
|
||||
|
||||
const colors = {
|
||||
[defaultBuildingVariant]: "#f48d41",
|
||||
[enumLogicGateVariants.xor]: "#f4a241",
|
||||
[enumLogicGateVariants.or]: "#f4d041",
|
||||
[enumLogicGateVariants.not]: "#f44184",
|
||||
};
|
||||
|
||||
export class MetaLogicGateBuilding extends MetaBuilding {
|
||||
constructor() {
|
||||
super("logic_gate");
|
||||
}
|
||||
|
||||
getSilhouetteColor(variant) {
|
||||
return colors[variant];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {GameRoot} root
|
||||
*/
|
||||
getIsUnlocked(root) {
|
||||
// @todo
|
||||
return true;
|
||||
}
|
||||
|
||||
/** @returns {"wires"} **/
|
||||
getLayer() {
|
||||
return "wires";
|
||||
}
|
||||
|
||||
getDimensions() {
|
||||
return new Vector(1, 1);
|
||||
}
|
||||
|
||||
getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant) {
|
||||
return overlayMatrices[variant][rotation];
|
||||
}
|
||||
|
||||
getAvailableVariants() {
|
||||
return [
|
||||
defaultBuildingVariant,
|
||||
enumLogicGateVariants.or,
|
||||
enumLogicGateVariants.not,
|
||||
enumLogicGateVariants.xor,
|
||||
];
|
||||
}
|
||||
|
||||
getRenderPins() {
|
||||
// We already have it included
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Entity} entity
|
||||
* @param {number} rotationVariant
|
||||
*/
|
||||
updateVariants(entity, rotationVariant, variant) {
|
||||
const gateType = enumVariantToGate[variant];
|
||||
entity.components.LogicGate.type = gateType;
|
||||
|
||||
const pinComp = entity.components.WiredPins;
|
||||
|
||||
switch (gateType) {
|
||||
case enumLogicGateType.and:
|
||||
case enumLogicGateType.xor:
|
||||
case enumLogicGateType.or: {
|
||||
pinComp.setSlots([
|
||||
{
|
||||
pos: new Vector(0, 0),
|
||||
direction: enumDirection.top,
|
||||
type: enumPinSlotType.logicalEjector,
|
||||
},
|
||||
{
|
||||
pos: new Vector(0, 0),
|
||||
direction: enumDirection.left,
|
||||
type: enumPinSlotType.logicalAcceptor,
|
||||
},
|
||||
{
|
||||
pos: new Vector(0, 0),
|
||||
direction: enumDirection.right,
|
||||
type: enumPinSlotType.logicalAcceptor,
|
||||
},
|
||||
]);
|
||||
break;
|
||||
}
|
||||
|
||||
case enumLogicGateType.not: {
|
||||
pinComp.setSlots([
|
||||
{
|
||||
pos: new Vector(0, 0),
|
||||
direction: enumDirection.top,
|
||||
type: enumPinSlotType.logicalEjector,
|
||||
},
|
||||
{
|
||||
pos: new Vector(0, 0),
|
||||
direction: enumDirection.bottom,
|
||||
type: enumPinSlotType.logicalAcceptor,
|
||||
},
|
||||
]);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
assertAlways("unknown logic gate type: " + gateType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the entity at the given location
|
||||
* @param {Entity} entity
|
||||
*/
|
||||
setupEntityComponents(entity) {
|
||||
entity.addComponent(
|
||||
new WiredPinsComponent({
|
||||
slots: [],
|
||||
})
|
||||
);
|
||||
|
||||
entity.addComponent(new LogicGateComponent({}));
|
||||
}
|
||||
}
|
||||
|
||||
101
src/js/game/buildings/transistor.js
Normal file
101
src/js/game/buildings/transistor.js
Normal file
@@ -0,0 +1,101 @@
|
||||
import { generateMatrixRotations } from "../../core/utils";
|
||||
import { enumDirection, Vector } from "../../core/vector";
|
||||
import { enumLogicGateType, LogicGateComponent } from "../components/logic_gate";
|
||||
import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
|
||||
import { Entity } from "../entity";
|
||||
import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
|
||||
import { GameRoot } from "../root";
|
||||
|
||||
/** @enum {string} */
|
||||
export const enumTransistorVariants = {
|
||||
mirrored: "mirrored",
|
||||
};
|
||||
|
||||
const overlayMatrices = {
|
||||
[defaultBuildingVariant]: generateMatrixRotations([0, 1, 0, 1, 1, 0, 0, 1, 0]),
|
||||
[enumTransistorVariants.mirrored]: generateMatrixRotations([0, 1, 0, 0, 1, 1, 0, 1, 0]),
|
||||
};
|
||||
|
||||
export class MetaTransistorBuilding extends MetaBuilding {
|
||||
constructor() {
|
||||
super("transistor");
|
||||
}
|
||||
|
||||
getSilhouetteColor() {
|
||||
return "#bc3a61";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {GameRoot} root
|
||||
*/
|
||||
getIsUnlocked(root) {
|
||||
// @todo
|
||||
return true;
|
||||
}
|
||||
|
||||
/** @returns {"wires"} **/
|
||||
getLayer() {
|
||||
return "wires";
|
||||
}
|
||||
|
||||
getDimensions() {
|
||||
return new Vector(1, 1);
|
||||
}
|
||||
|
||||
getAvailableVariants() {
|
||||
return [defaultBuildingVariant, enumTransistorVariants.mirrored];
|
||||
}
|
||||
|
||||
getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant) {
|
||||
return overlayMatrices[variant][rotation];
|
||||
}
|
||||
|
||||
getRenderPins() {
|
||||
// We already have it included
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Entity} entity
|
||||
* @param {number} rotationVariant
|
||||
*/
|
||||
updateVariants(entity, rotationVariant, variant) {
|
||||
entity.components.WiredPins.slots[1].direction =
|
||||
variant === enumTransistorVariants.mirrored ? enumDirection.right : enumDirection.left;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the entity at the given location
|
||||
* @param {Entity} entity
|
||||
*/
|
||||
setupEntityComponents(entity) {
|
||||
entity.addComponent(
|
||||
new WiredPinsComponent({
|
||||
slots: [
|
||||
{
|
||||
pos: new Vector(0, 0),
|
||||
direction: enumDirection.top,
|
||||
type: enumPinSlotType.logicalEjector,
|
||||
},
|
||||
{
|
||||
pos: new Vector(0, 0),
|
||||
direction: enumDirection.left,
|
||||
type: enumPinSlotType.logicalAcceptor,
|
||||
},
|
||||
{
|
||||
pos: new Vector(0, 0),
|
||||
direction: enumDirection.bottom,
|
||||
type: enumPinSlotType.logicalAcceptor,
|
||||
},
|
||||
],
|
||||
})
|
||||
);
|
||||
|
||||
entity.addComponent(
|
||||
new LogicGateComponent({
|
||||
type: enumLogicGateType.transistor,
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -4,13 +4,15 @@ import { WiredPinsComponent, enumPinSlotType } from "../components/wired_pins";
|
||||
import { Entity } from "../entity";
|
||||
import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
|
||||
import { GameRoot } from "../root";
|
||||
import { MetaCutterBuilding } from "./cutter";
|
||||
import { MetaPainterBuilding } from "./painter";
|
||||
import { MetaRotaterBuilding } from "./rotater";
|
||||
import { MetaStackerBuilding } from "./stacker";
|
||||
|
||||
/** @enum {string} */
|
||||
export const enumVirtualProcessorVariants = {
|
||||
analyzer: "analyzer",
|
||||
rotater: "rotater",
|
||||
unstacker: "unstacker",
|
||||
shapecompare: "shapecompare",
|
||||
stacker: "stacker",
|
||||
painter: "painter",
|
||||
};
|
||||
@@ -18,21 +20,27 @@ export const enumVirtualProcessorVariants = {
|
||||
/** @enum {string} */
|
||||
export const enumVariantToGate = {
|
||||
[defaultBuildingVariant]: enumLogicGateType.cutter,
|
||||
[enumVirtualProcessorVariants.analyzer]: enumLogicGateType.analyzer,
|
||||
[enumVirtualProcessorVariants.rotater]: enumLogicGateType.rotater,
|
||||
[enumVirtualProcessorVariants.unstacker]: enumLogicGateType.unstacker,
|
||||
[enumVirtualProcessorVariants.shapecompare]: enumLogicGateType.shapecompare,
|
||||
[enumVirtualProcessorVariants.stacker]: enumLogicGateType.stacker,
|
||||
[enumVirtualProcessorVariants.painter]: enumLogicGateType.painter,
|
||||
};
|
||||
|
||||
const colors = {
|
||||
[defaultBuildingVariant]: new MetaCutterBuilding().getSilhouetteColor(),
|
||||
[enumVirtualProcessorVariants.rotater]: new MetaRotaterBuilding().getSilhouetteColor(),
|
||||
[enumVirtualProcessorVariants.unstacker]: new MetaStackerBuilding().getSilhouetteColor(),
|
||||
[enumVirtualProcessorVariants.stacker]: new MetaStackerBuilding().getSilhouetteColor(),
|
||||
[enumVirtualProcessorVariants.painter]: new MetaPainterBuilding().getSilhouetteColor(),
|
||||
};
|
||||
|
||||
export class MetaVirtualProcessorBuilding extends MetaBuilding {
|
||||
constructor() {
|
||||
super("virtual_processor");
|
||||
}
|
||||
|
||||
getSilhouetteColor() {
|
||||
return "#823cab";
|
||||
getSilhouetteColor(variant) {
|
||||
return colors[variant];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,11 +64,9 @@ export class MetaVirtualProcessorBuilding extends MetaBuilding {
|
||||
return [
|
||||
defaultBuildingVariant,
|
||||
enumVirtualProcessorVariants.rotater,
|
||||
enumVirtualProcessorVariants.unstacker,
|
||||
enumVirtualProcessorVariants.analyzer,
|
||||
enumVirtualProcessorVariants.stacker,
|
||||
enumVirtualProcessorVariants.painter,
|
||||
enumVirtualProcessorVariants.shapecompare,
|
||||
enumVirtualProcessorVariants.unstacker,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -80,7 +86,6 @@ export class MetaVirtualProcessorBuilding extends MetaBuilding {
|
||||
const pinComp = entity.components.WiredPins;
|
||||
switch (gateType) {
|
||||
case enumLogicGateType.cutter:
|
||||
case enumLogicGateType.analyzer:
|
||||
case enumLogicGateType.unstacker: {
|
||||
pinComp.setSlots([
|
||||
{
|
||||
@@ -116,26 +121,6 @@ export class MetaVirtualProcessorBuilding extends MetaBuilding {
|
||||
]);
|
||||
break;
|
||||
}
|
||||
case enumLogicGateType.shapecompare: {
|
||||
pinComp.setSlots([
|
||||
{
|
||||
pos: new Vector(0, 0),
|
||||
direction: enumDirection.top,
|
||||
type: enumPinSlotType.logicalEjector,
|
||||
},
|
||||
{
|
||||
pos: new Vector(0, 0),
|
||||
direction: enumDirection.left,
|
||||
type: enumPinSlotType.logicalAcceptor,
|
||||
},
|
||||
{
|
||||
pos: new Vector(0, 0),
|
||||
direction: enumDirection.right,
|
||||
type: enumPinSlotType.logicalAcceptor,
|
||||
},
|
||||
]);
|
||||
break;
|
||||
}
|
||||
case enumLogicGateType.stacker:
|
||||
case enumLogicGateType.painter: {
|
||||
pinComp.setSlots([
|
||||
|
||||
@@ -1,263 +1,272 @@
|
||||
import { Loader } from "../../core/loader";
|
||||
import { generateMatrixRotations } from "../../core/utils";
|
||||
import { enumDirection, enumDirectionToAngle, enumDirectionToVector, Vector } from "../../core/vector";
|
||||
import { SOUNDS } from "../../platform/sound";
|
||||
import { enumWireType, WireComponent } from "../components/wire";
|
||||
import { Entity } from "../entity";
|
||||
import { MetaBuilding } from "../meta_building";
|
||||
import { GameRoot } from "../root";
|
||||
|
||||
export const arrayWireRotationVariantToType = [
|
||||
enumWireType.regular,
|
||||
enumWireType.turn,
|
||||
enumWireType.split,
|
||||
enumWireType.cross,
|
||||
];
|
||||
|
||||
export const wireOverlayMatrices = {
|
||||
[enumWireType.regular]: generateMatrixRotations([0, 1, 0, 0, 1, 0, 0, 1, 0]),
|
||||
[enumWireType.split]: generateMatrixRotations([0, 0, 0, 1, 1, 1, 0, 1, 0]),
|
||||
[enumWireType.turn]: generateMatrixRotations([0, 0, 0, 0, 1, 1, 0, 1, 0]),
|
||||
[enumWireType.cross]: generateMatrixRotations([0, 1, 0, 1, 1, 1, 0, 1, 0]),
|
||||
};
|
||||
|
||||
export class MetaWireBuilding extends MetaBuilding {
|
||||
constructor() {
|
||||
super("wire");
|
||||
}
|
||||
|
||||
getHasDirectionLockAvailable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
getSilhouetteColor() {
|
||||
return "#25fff2";
|
||||
}
|
||||
|
||||
getDimensions() {
|
||||
return new Vector(1, 1);
|
||||
}
|
||||
|
||||
getStayInPlacementMode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
getPlacementSound() {
|
||||
return SOUNDS.placeBelt;
|
||||
}
|
||||
|
||||
getRotateAutomaticallyWhilePlacing() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/** @returns {"wires"} **/
|
||||
getLayer() {
|
||||
return "wires";
|
||||
}
|
||||
|
||||
getSprite() {
|
||||
return null;
|
||||
}
|
||||
|
||||
getIsReplaceable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {GameRoot} root
|
||||
*/
|
||||
getIsUnlocked(root) {
|
||||
// @todo
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the entity at the given location
|
||||
* @param {Entity} entity
|
||||
*/
|
||||
setupEntityComponents(entity) {
|
||||
// @todo
|
||||
entity.addComponent(new WireComponent({}));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Entity} entity
|
||||
* @param {number} rotationVariant
|
||||
*/
|
||||
updateVariants(entity, rotationVariant) {
|
||||
entity.components.Wire.type = arrayWireRotationVariantToType[rotationVariant];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {number} rotation
|
||||
* @param {number} rotationVariant
|
||||
* @param {string} variant
|
||||
* @param {Entity} entity
|
||||
*/
|
||||
getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) {
|
||||
return wireOverlayMatrices[entity.components.Wire.type][rotation];
|
||||
}
|
||||
|
||||
getPreviewSprite(rotationVariant) {
|
||||
switch (arrayWireRotationVariantToType[rotationVariant]) {
|
||||
case enumWireType.regular: {
|
||||
return Loader.getSprite("sprites/buildings/wire.png");
|
||||
}
|
||||
case enumWireType.turn: {
|
||||
return Loader.getSprite("sprites/buildings/wire-turn.png");
|
||||
}
|
||||
case enumWireType.split: {
|
||||
return Loader.getSprite("sprites/buildings/wire-split.png");
|
||||
}
|
||||
case enumWireType.cross: {
|
||||
return Loader.getSprite("sprites/buildings/wire-cross.png");
|
||||
}
|
||||
default: {
|
||||
assertAlways(false, "Invalid wire rotation variant");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getBlueprintSprite(rotationVariant) {
|
||||
switch (arrayWireRotationVariantToType[rotationVariant]) {
|
||||
case enumWireType.regular: {
|
||||
return Loader.getSprite("sprites/blueprints/wire.png");
|
||||
}
|
||||
case enumWireType.turn: {
|
||||
return Loader.getSprite("sprites/blueprints/wire-turn.png");
|
||||
}
|
||||
case enumWireType.split: {
|
||||
return Loader.getSprite("sprites/blueprints/wire-split.png");
|
||||
}
|
||||
case enumWireType.cross: {
|
||||
return Loader.getSprite("sprites/blueprints/wire-cross.png");
|
||||
}
|
||||
default: {
|
||||
assertAlways(false, "Invalid wire rotation variant");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Should compute the optimal rotation variant on the given tile
|
||||
* @param {object} param0
|
||||
* @param {GameRoot} param0.root
|
||||
* @param {Vector} param0.tile
|
||||
* @param {number} param0.rotation
|
||||
* @param {string} param0.variant
|
||||
* @param {string} param0.layer
|
||||
* @return {{ rotation: number, rotationVariant: number, connectedEntities?: Array<Entity> }}
|
||||
*/
|
||||
computeOptimalDirectionAndRotationVariantAtTile({ root, tile, rotation, variant, layer }) {
|
||||
const connections = {
|
||||
top: root.logic.computeWireEdgeStatus({ tile, rotation, edge: enumDirection.top }),
|
||||
right: root.logic.computeWireEdgeStatus({ tile, rotation, edge: enumDirection.right }),
|
||||
bottom: root.logic.computeWireEdgeStatus({ tile, rotation, edge: enumDirection.bottom }),
|
||||
left: root.logic.computeWireEdgeStatus({ tile, rotation, edge: enumDirection.left }),
|
||||
};
|
||||
|
||||
let flag = 0;
|
||||
flag |= connections.top ? 0x1000 : 0;
|
||||
flag |= connections.right ? 0x100 : 0;
|
||||
flag |= connections.bottom ? 0x10 : 0;
|
||||
flag |= connections.left ? 0x1 : 0;
|
||||
|
||||
let targetType = enumWireType.regular;
|
||||
|
||||
// First, reset rotation
|
||||
rotation = 0;
|
||||
|
||||
switch (flag) {
|
||||
case 0x0000:
|
||||
// Nothing
|
||||
break;
|
||||
|
||||
case 0x0001:
|
||||
// Left
|
||||
rotation += 90;
|
||||
break;
|
||||
|
||||
case 0x0010:
|
||||
// Bottom
|
||||
// END
|
||||
break;
|
||||
|
||||
case 0x0011:
|
||||
// Bottom | Left
|
||||
targetType = enumWireType.turn;
|
||||
rotation += 90;
|
||||
break;
|
||||
|
||||
case 0x0100:
|
||||
// Right
|
||||
rotation += 90;
|
||||
break;
|
||||
|
||||
case 0x0101:
|
||||
// Right | Left
|
||||
rotation += 90;
|
||||
break;
|
||||
|
||||
case 0x0110:
|
||||
// Right | Bottom
|
||||
targetType = enumWireType.turn;
|
||||
break;
|
||||
|
||||
case 0x0111:
|
||||
// Right | Bottom | Left
|
||||
targetType = enumWireType.split;
|
||||
break;
|
||||
|
||||
case 0x1000:
|
||||
// Top
|
||||
break;
|
||||
|
||||
case 0x1001:
|
||||
// Top | Left
|
||||
targetType = enumWireType.turn;
|
||||
rotation += 180;
|
||||
break;
|
||||
|
||||
case 0x1010:
|
||||
// Top | Bottom
|
||||
break;
|
||||
|
||||
case 0x1011:
|
||||
// Top | Bottom | Left
|
||||
targetType = enumWireType.split;
|
||||
rotation += 90;
|
||||
break;
|
||||
|
||||
case 0x1100:
|
||||
// Top | Right
|
||||
targetType = enumWireType.turn;
|
||||
rotation -= 90;
|
||||
break;
|
||||
|
||||
case 0x1101:
|
||||
// Top | Right | Left
|
||||
targetType = enumWireType.split;
|
||||
rotation += 180;
|
||||
break;
|
||||
|
||||
case 0x1110:
|
||||
// Top | Right | Bottom
|
||||
targetType = enumWireType.split;
|
||||
rotation -= 90;
|
||||
break;
|
||||
|
||||
case 0x1111:
|
||||
// Top | Right | Bottom | Left
|
||||
targetType = enumWireType.cross;
|
||||
break;
|
||||
}
|
||||
|
||||
return {
|
||||
// Clamp rotation
|
||||
rotation: (rotation + 360 * 10) % 360,
|
||||
rotationVariant: arrayWireRotationVariantToType.indexOf(targetType),
|
||||
};
|
||||
}
|
||||
}
|
||||
import { Loader } from "../../core/loader";
|
||||
import { generateMatrixRotations } from "../../core/utils";
|
||||
import { enumDirection, Vector } from "../../core/vector";
|
||||
import { SOUNDS } from "../../platform/sound";
|
||||
import { enumWireType, enumWireVariant, WireComponent } from "../components/wire";
|
||||
import { Entity } from "../entity";
|
||||
import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
|
||||
import { GameRoot } from "../root";
|
||||
|
||||
export const arrayWireRotationVariantToType = [
|
||||
enumWireType.forward,
|
||||
enumWireType.turn,
|
||||
enumWireType.split,
|
||||
enumWireType.cross,
|
||||
];
|
||||
|
||||
export const wireOverlayMatrices = {
|
||||
[enumWireType.forward]: generateMatrixRotations([0, 1, 0, 0, 1, 0, 0, 1, 0]),
|
||||
[enumWireType.split]: generateMatrixRotations([0, 0, 0, 1, 1, 1, 0, 1, 0]),
|
||||
[enumWireType.turn]: generateMatrixRotations([0, 0, 0, 0, 1, 1, 0, 1, 0]),
|
||||
[enumWireType.cross]: generateMatrixRotations([0, 1, 0, 1, 1, 1, 0, 1, 0]),
|
||||
};
|
||||
|
||||
/** @enum {string} */
|
||||
export const wireVariants = {
|
||||
second: "second",
|
||||
third: "third",
|
||||
};
|
||||
|
||||
const enumWireVariantToVariant = {
|
||||
[defaultBuildingVariant]: enumWireVariant.first,
|
||||
[wireVariants.second]: enumWireVariant.second,
|
||||
[wireVariants.third]: enumWireVariant.third,
|
||||
};
|
||||
|
||||
export class MetaWireBuilding extends MetaBuilding {
|
||||
constructor() {
|
||||
super("wire");
|
||||
}
|
||||
|
||||
getHasDirectionLockAvailable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
getSilhouetteColor() {
|
||||
return "#61ef6f";
|
||||
}
|
||||
|
||||
getAvailableVariants() {
|
||||
return [defaultBuildingVariant, wireVariants.second, wireVariants.third];
|
||||
}
|
||||
|
||||
getDimensions() {
|
||||
return new Vector(1, 1);
|
||||
}
|
||||
|
||||
getStayInPlacementMode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
getPlacementSound() {
|
||||
return SOUNDS.placeBelt;
|
||||
}
|
||||
|
||||
getRotateAutomaticallyWhilePlacing() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/** @returns {"wires"} **/
|
||||
getLayer() {
|
||||
return "wires";
|
||||
}
|
||||
|
||||
getSprite() {
|
||||
return null;
|
||||
}
|
||||
|
||||
getIsReplaceable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {GameRoot} root
|
||||
*/
|
||||
getIsUnlocked(root) {
|
||||
// @todo
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the entity at the given location
|
||||
* @param {Entity} entity
|
||||
*/
|
||||
setupEntityComponents(entity) {
|
||||
entity.addComponent(new WireComponent({}));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Entity} entity
|
||||
* @param {number} rotationVariant
|
||||
* @param {string} variant
|
||||
*/
|
||||
updateVariants(entity, rotationVariant, variant) {
|
||||
entity.components.Wire.type = arrayWireRotationVariantToType[rotationVariant];
|
||||
entity.components.Wire.variant = enumWireVariantToVariant[variant];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {number} rotation
|
||||
* @param {number} rotationVariant
|
||||
* @param {string} variant
|
||||
* @param {Entity} entity
|
||||
*/
|
||||
getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) {
|
||||
return wireOverlayMatrices[entity.components.Wire.type][rotation];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {number} rotationVariant
|
||||
* @param {string} variant
|
||||
* @returns {import("../../core/draw_utils").AtlasSprite}
|
||||
*/
|
||||
getPreviewSprite(rotationVariant, variant) {
|
||||
const wireVariant = enumWireVariantToVariant[variant];
|
||||
switch (arrayWireRotationVariantToType[rotationVariant]) {
|
||||
case enumWireType.forward: {
|
||||
return Loader.getSprite("sprites/wires/sets/" + wireVariant + "_forward.png");
|
||||
}
|
||||
case enumWireType.turn: {
|
||||
return Loader.getSprite("sprites/wires/sets/" + wireVariant + "_turn.png");
|
||||
}
|
||||
case enumWireType.split: {
|
||||
return Loader.getSprite("sprites/wires/sets/" + wireVariant + "_split.png");
|
||||
}
|
||||
case enumWireType.cross: {
|
||||
return Loader.getSprite("sprites/wires/sets/" + wireVariant + "_cross.png");
|
||||
}
|
||||
default: {
|
||||
assertAlways(false, "Invalid wire rotation variant");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getBlueprintSprite(rotationVariant, variant) {
|
||||
return this.getPreviewSprite(rotationVariant, variant);
|
||||
}
|
||||
|
||||
/**
|
||||
* Should compute the optimal rotation variant on the given tile
|
||||
* @param {object} param0
|
||||
* @param {GameRoot} param0.root
|
||||
* @param {Vector} param0.tile
|
||||
* @param {number} param0.rotation
|
||||
* @param {string} param0.variant
|
||||
* @param {string} param0.layer
|
||||
* @return {{ rotation: number, rotationVariant: number, connectedEntities?: Array<Entity> }}
|
||||
*/
|
||||
computeOptimalDirectionAndRotationVariantAtTile({ root, tile, rotation, variant, layer }) {
|
||||
const wireVariant = enumWireVariantToVariant[variant];
|
||||
const connections = {
|
||||
top: root.logic.computeWireEdgeStatus({ tile, wireVariant, edge: enumDirection.top }),
|
||||
right: root.logic.computeWireEdgeStatus({ tile, wireVariant, edge: enumDirection.right }),
|
||||
bottom: root.logic.computeWireEdgeStatus({ tile, wireVariant, edge: enumDirection.bottom }),
|
||||
left: root.logic.computeWireEdgeStatus({ tile, wireVariant, edge: enumDirection.left }),
|
||||
};
|
||||
|
||||
let flag = 0;
|
||||
flag |= connections.top ? 0x1000 : 0;
|
||||
flag |= connections.right ? 0x100 : 0;
|
||||
flag |= connections.bottom ? 0x10 : 0;
|
||||
flag |= connections.left ? 0x1 : 0;
|
||||
|
||||
let targetType = enumWireType.forward;
|
||||
|
||||
// First, reset rotation
|
||||
rotation = 0;
|
||||
|
||||
switch (flag) {
|
||||
case 0x0000:
|
||||
// Nothing
|
||||
break;
|
||||
|
||||
case 0x0001:
|
||||
// Left
|
||||
rotation += 90;
|
||||
break;
|
||||
|
||||
case 0x0010:
|
||||
// Bottom
|
||||
// END
|
||||
break;
|
||||
|
||||
case 0x0011:
|
||||
// Bottom | Left
|
||||
targetType = enumWireType.turn;
|
||||
rotation += 90;
|
||||
break;
|
||||
|
||||
case 0x0100:
|
||||
// Right
|
||||
rotation += 90;
|
||||
break;
|
||||
|
||||
case 0x0101:
|
||||
// Right | Left
|
||||
rotation += 90;
|
||||
break;
|
||||
|
||||
case 0x0110:
|
||||
// Right | Bottom
|
||||
targetType = enumWireType.turn;
|
||||
break;
|
||||
|
||||
case 0x0111:
|
||||
// Right | Bottom | Left
|
||||
targetType = enumWireType.split;
|
||||
break;
|
||||
|
||||
case 0x1000:
|
||||
// Top
|
||||
break;
|
||||
|
||||
case 0x1001:
|
||||
// Top | Left
|
||||
targetType = enumWireType.turn;
|
||||
rotation += 180;
|
||||
break;
|
||||
|
||||
case 0x1010:
|
||||
// Top | Bottom
|
||||
break;
|
||||
|
||||
case 0x1011:
|
||||
// Top | Bottom | Left
|
||||
targetType = enumWireType.split;
|
||||
rotation += 90;
|
||||
break;
|
||||
|
||||
case 0x1100:
|
||||
// Top | Right
|
||||
targetType = enumWireType.turn;
|
||||
rotation -= 90;
|
||||
break;
|
||||
|
||||
case 0x1101:
|
||||
// Top | Right | Left
|
||||
targetType = enumWireType.split;
|
||||
rotation += 180;
|
||||
break;
|
||||
|
||||
case 0x1110:
|
||||
// Top | Right | Bottom
|
||||
targetType = enumWireType.split;
|
||||
rotation -= 90;
|
||||
break;
|
||||
|
||||
case 0x1111:
|
||||
// Top | Right | Bottom | Left
|
||||
targetType = enumWireType.cross;
|
||||
break;
|
||||
}
|
||||
|
||||
return {
|
||||
// Clamp rotation
|
||||
rotation: (rotation + 360 * 10) % 360,
|
||||
rotationVariant: arrayWireRotationVariantToType.indexOf(targetType),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,87 +1,58 @@
|
||||
import { Vector } from "../../core/vector";
|
||||
import { Entity } from "../entity";
|
||||
import { MetaBuilding, defaultBuildingVariant } from "../meta_building";
|
||||
import { GameRoot } from "../root";
|
||||
import { WireTunnelComponent } from "../components/wire_tunnel";
|
||||
import { generateMatrixRotations } from "../../core/utils";
|
||||
|
||||
/** @enum {string} */
|
||||
export const enumWireTunnelVariants = {
|
||||
coating: "coating",
|
||||
};
|
||||
|
||||
const wireTunnelOverlayMatrices = {
|
||||
[defaultBuildingVariant]: generateMatrixRotations([0, 1, 0, 1, 1, 1, 0, 1, 0]),
|
||||
[enumWireTunnelVariants.coating]: generateMatrixRotations([0, 1, 0, 0, 1, 0, 0, 1, 0]),
|
||||
};
|
||||
|
||||
export class MetaWireTunnelBuilding extends MetaBuilding {
|
||||
constructor() {
|
||||
super("wire_tunnel");
|
||||
}
|
||||
|
||||
getSilhouetteColor() {
|
||||
return "#777a86";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {GameRoot} root
|
||||
*/
|
||||
getIsUnlocked(root) {
|
||||
// @todo
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {number} rotation
|
||||
* @param {number} rotationVariant
|
||||
* @param {string} variant
|
||||
* @param {Entity} entity
|
||||
*/
|
||||
getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) {
|
||||
return wireTunnelOverlayMatrices[variant][rotation];
|
||||
}
|
||||
|
||||
getIsRotateable(variant) {
|
||||
return variant !== defaultBuildingVariant;
|
||||
}
|
||||
|
||||
getDimensions() {
|
||||
return new Vector(1, 1);
|
||||
}
|
||||
|
||||
getAvailableVariants() {
|
||||
return [defaultBuildingVariant, enumWireTunnelVariants.coating];
|
||||
}
|
||||
|
||||
/** @returns {"wires"} **/
|
||||
getLayer() {
|
||||
return "wires";
|
||||
}
|
||||
|
||||
getRotateAutomaticallyWhilePlacing() {
|
||||
return true;
|
||||
}
|
||||
|
||||
getStayInPlacementMode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the entity at the given location
|
||||
* @param {Entity} entity
|
||||
*/
|
||||
setupEntityComponents(entity) {
|
||||
entity.addComponent(new WireTunnelComponent({}));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Entity} entity
|
||||
* @param {number} rotationVariant
|
||||
* @param {string} variant
|
||||
*/
|
||||
updateVariants(entity, rotationVariant, variant) {
|
||||
entity.components.WireTunnel.multipleDirections = variant === defaultBuildingVariant;
|
||||
}
|
||||
}
|
||||
import { generateMatrixRotations } from "../../core/utils";
|
||||
import { Vector } from "../../core/vector";
|
||||
import { WireTunnelComponent } from "../components/wire_tunnel";
|
||||
import { Entity } from "../entity";
|
||||
import { MetaBuilding } from "../meta_building";
|
||||
import { GameRoot } from "../root";
|
||||
import { enumHubGoalRewards } from "../tutorial_goals";
|
||||
|
||||
const wireTunnelOverlayMatrix = generateMatrixRotations([0, 1, 0, 1, 1, 1, 0, 1, 0]);
|
||||
|
||||
export class MetaWireTunnelBuilding extends MetaBuilding {
|
||||
constructor() {
|
||||
super("wire_tunnel");
|
||||
}
|
||||
|
||||
getSilhouetteColor() {
|
||||
return "#777a86";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {GameRoot} root
|
||||
*/
|
||||
getIsUnlocked(root) {
|
||||
return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_wires_filters_and_levers);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {number} rotation
|
||||
* @param {number} rotationVariant
|
||||
* @param {string} variant
|
||||
* @param {Entity} entity
|
||||
*/
|
||||
getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) {
|
||||
return wireTunnelOverlayMatrix[rotation];
|
||||
}
|
||||
|
||||
getIsRotateable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
getDimensions() {
|
||||
return new Vector(1, 1);
|
||||
}
|
||||
|
||||
/** @returns {"wires"} **/
|
||||
getLayer() {
|
||||
return "wires";
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the entity at the given location
|
||||
* @param {Entity} entity
|
||||
*/
|
||||
setupEntityComponents(entity) {
|
||||
entity.addComponent(new WireTunnelComponent({}));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ export const enumLogicGateType = {
|
||||
rotater: "rotater",
|
||||
unstacker: "unstacker",
|
||||
cutter: "cutter",
|
||||
shapecompare: "shapecompare",
|
||||
compare: "compare",
|
||||
stacker: "stacker",
|
||||
painter: "painter",
|
||||
};
|
||||
|
||||
@@ -63,6 +63,14 @@ export class StaticMapEntityComponent extends Component {
|
||||
return getBuildingDataFromCode(this.code).metaInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the buildings variant
|
||||
* @returns {string}
|
||||
*/
|
||||
getVariant() {
|
||||
return getBuildingDataFromCode(this.code).variant;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the current state to another component
|
||||
* @param {Component} otherComponent
|
||||
|
||||
@@ -2,12 +2,19 @@ import { Component } from "../component";
|
||||
|
||||
/** @enum {string} */
|
||||
export const enumWireType = {
|
||||
regular: "regular",
|
||||
forward: "forward",
|
||||
turn: "turn",
|
||||
split: "split",
|
||||
cross: "cross",
|
||||
};
|
||||
|
||||
/** @enum {string} */
|
||||
export const enumWireVariant = {
|
||||
first: "first",
|
||||
second: "second",
|
||||
third: "third",
|
||||
};
|
||||
|
||||
export class WireComponent extends Component {
|
||||
static getId() {
|
||||
return "Wire";
|
||||
@@ -16,54 +23,21 @@ export class WireComponent extends Component {
|
||||
/**
|
||||
* @param {object} param0
|
||||
* @param {enumWireType=} param0.type
|
||||
* @param {enumWireVariant=} param0.variant
|
||||
*/
|
||||
constructor({ type = enumWireType.regular }) {
|
||||
constructor({ type = enumWireType.forward, variant = enumWireVariant.first }) {
|
||||
super();
|
||||
this.type = type;
|
||||
|
||||
/**
|
||||
* The variant of the wire, different variants do not connect
|
||||
* @type {enumWireVariant}
|
||||
*/
|
||||
this.variant = variant;
|
||||
|
||||
/**
|
||||
* @type {import("../systems/wire").WireNetwork}
|
||||
*/
|
||||
this.linkedNetwork = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the local connections
|
||||
* @returns {import("../../core/utils").DirectionalObject}
|
||||
*/
|
||||
getLocalConnections() {
|
||||
return {
|
||||
top: true,
|
||||
right: false,
|
||||
bottom: true,
|
||||
left: false,
|
||||
};
|
||||
|
||||
// switch (this.type) {
|
||||
// case enumWireType.regular:
|
||||
// return {
|
||||
// top: true,
|
||||
// right: false,
|
||||
// bottom: true,
|
||||
// left: false,
|
||||
// };
|
||||
// case enumWireType.turn:
|
||||
// return {
|
||||
// top: false,
|
||||
// right: true,
|
||||
// bottom: true,
|
||||
// left: false,
|
||||
// };
|
||||
// case enumWireType.split:
|
||||
// return {
|
||||
// top: false,
|
||||
// right: true,
|
||||
// bottom: true,
|
||||
// left: true,
|
||||
// };
|
||||
|
||||
// default:
|
||||
// assertAlways(false, "Invalid wire type: " + this.type);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,13 +5,8 @@ export class WireTunnelComponent extends Component {
|
||||
return "WireTunnel";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {object} param0
|
||||
* @param {boolean=} param0.multipleDirections
|
||||
*/
|
||||
constructor({ multipleDirections = true }) {
|
||||
constructor() {
|
||||
super();
|
||||
this.multipleDirections = multipleDirections;
|
||||
|
||||
/**
|
||||
* Linked network, only if its not multiple directions
|
||||
|
||||
@@ -5,6 +5,9 @@ import { MetaLogicGateBuilding } from "../../buildings/logic_gate";
|
||||
import { MetaLeverBuilding } from "../../buildings/lever";
|
||||
import { MetaWireTunnelBuilding } from "../../buildings/wire_tunnel";
|
||||
import { MetaVirtualProcessorBuilding } from "../../buildings/virtual_processor";
|
||||
import { MetaTransistorBuilding } from "../../buildings/transistor";
|
||||
import { MetaAnalyzerBuilding } from "../../buildings/analyzer";
|
||||
import { MetaComparatorBuilding } from "../../buildings/comparator";
|
||||
|
||||
export class HUDWiresToolbar extends HUDBaseToolbar {
|
||||
constructor(root) {
|
||||
@@ -13,9 +16,12 @@ export class HUDWiresToolbar extends HUDBaseToolbar {
|
||||
MetaWireBuilding,
|
||||
MetaWireTunnelBuilding,
|
||||
MetaConstantSignalBuilding,
|
||||
MetaTransistorBuilding,
|
||||
MetaLogicGateBuilding,
|
||||
MetaAnalyzerBuilding,
|
||||
MetaLeverBuilding,
|
||||
MetaVirtualProcessorBuilding,
|
||||
MetaComparatorBuilding,
|
||||
],
|
||||
visibilityCondition: () =>
|
||||
!this.root.camera.getIsMapOverlayActive() && this.root.currentLayer === "wires",
|
||||
|
||||
@@ -64,8 +64,11 @@ export const KEYMAPPINGS = {
|
||||
wire: { keyCode: key("1") },
|
||||
wire_tunnel: { keyCode: key("2") },
|
||||
constant_signal: { keyCode: key("3") },
|
||||
transistor: { keyCode: key("6") },
|
||||
logic_gate: { keyCode: key("4") },
|
||||
virtual_processor: { keyCode: key("5") },
|
||||
analyzer: { keyCode: key("7") },
|
||||
comparator: { keyCode: key("8") },
|
||||
},
|
||||
|
||||
placement: {
|
||||
|
||||
@@ -1,23 +1,18 @@
|
||||
import { globalConfig } from "../core/config";
|
||||
import { createLogger } from "../core/logging";
|
||||
import { STOP_PROPAGATION } from "../core/signal";
|
||||
import { round2Digits } from "../core/utils";
|
||||
import { enumDirection, enumDirectionToVector, enumInvertedDirections, Vector } from "../core/vector";
|
||||
import { getBuildingDataFromCode } from "./building_codes";
|
||||
import { enumWireVariant } from "./components/wire";
|
||||
import { Entity } from "./entity";
|
||||
import { CHUNK_OVERLAY_RES } from "./map_chunk_view";
|
||||
import { MetaBuilding } from "./meta_building";
|
||||
import { GameRoot } from "./root";
|
||||
import { WireNetwork } from "./systems/wire";
|
||||
import { globalConfig } from "../core/config";
|
||||
import { CHUNK_OVERLAY_RES } from "./map_chunk_view";
|
||||
|
||||
const logger = createLogger("ingame/logic");
|
||||
|
||||
/** @enum {number} */
|
||||
export const enumWireEdgeFlag = {
|
||||
empty: 0,
|
||||
connected: 2,
|
||||
};
|
||||
|
||||
/**
|
||||
* Typing helper
|
||||
* @typedef {Array<{
|
||||
@@ -193,28 +188,72 @@ export class GameLogic {
|
||||
*
|
||||
* Computes the flag for a given tile
|
||||
* @param {object} param0
|
||||
* @param {enumWireVariant} param0.wireVariant
|
||||
* @param {Vector} param0.tile The tile to check at
|
||||
* @param {enumDirection} param0.edge The edge to check for
|
||||
* @param {number} param0.rotation The local tiles base rotation
|
||||
*/
|
||||
computeWireEdgeStatus({ tile, edge, rotation }) {
|
||||
computeWireEdgeStatus({ wireVariant, tile, edge }) {
|
||||
const offset = enumDirectionToVector[edge];
|
||||
const refTile = tile.add(offset);
|
||||
// const angle = enumDirectionToAngle[edge];
|
||||
const targetTile = tile.add(offset);
|
||||
|
||||
// // First, check if this edge can be connected from locally
|
||||
// const canConnectLocally = rotation === angle || (rotation + 180) % 360 === angle;
|
||||
// Search for relevant pins
|
||||
const pinEntities = this.root.map.getLayersContentsMultipleXY(targetTile.x, targetTile.y);
|
||||
|
||||
const neighbourStatus = this.getWireEdgeFlag(refTile, edge);
|
||||
// Go over all entities which could have a pin
|
||||
for (let i = 0; i < pinEntities.length; ++i) {
|
||||
const pinEntity = pinEntities[i];
|
||||
const pinComp = pinEntity.components.WiredPins;
|
||||
const staticComp = pinEntity.components.StaticMapEntity;
|
||||
|
||||
if (neighbourStatus === enumWireEdgeFlag.empty) {
|
||||
// It's empty, no point in connecting
|
||||
// Skip those who don't have pins
|
||||
if (!pinComp) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Go over all pins
|
||||
const pins = pinComp.slots;
|
||||
for (let k = 0; k < pinComp.slots.length; ++k) {
|
||||
const pinSlot = pins[k];
|
||||
const pinLocation = staticComp.localTileToWorld(pinSlot.pos);
|
||||
const pinDirection = staticComp.localDirectionToWorld(pinSlot.direction);
|
||||
|
||||
// Check if the pin has the right location
|
||||
if (!pinLocation.equals(targetTile)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if the pin has the right direction
|
||||
if (pinDirection !== enumInvertedDirections[edge]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Found a pin!
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Now check if there's a connectable entity on the wires layer
|
||||
const targetEntity = this.root.map.getTileContent(targetTile, "wires");
|
||||
if (!targetEntity) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (neighbourStatus === enumWireEdgeFlag.connected) {
|
||||
const targetStaticComp = targetEntity.components.StaticMapEntity;
|
||||
|
||||
// Check if its a crossing
|
||||
const wireTunnelComp = targetEntity.components.WireTunnel;
|
||||
if (wireTunnelComp) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if its a wire
|
||||
const wiresComp = targetEntity.components.Wire;
|
||||
if (!wiresComp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// It's connected if its the same variant
|
||||
return wiresComp.variant === wireVariant;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -303,85 +342,7 @@ export class GameLogic {
|
||||
return !!overlayMatrix[localPosition.x + localPosition.y * 3];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the flag at the given tile
|
||||
* @param {Vector} tile
|
||||
* @param {enumDirection} edge
|
||||
* @returns {enumWireEdgeFlag}
|
||||
*/
|
||||
getWireEdgeFlag(tile, edge) {
|
||||
// Search for relevant pins
|
||||
const pinEntities = this.root.map.getLayersContentsMultipleXY(tile.x, tile.y);
|
||||
|
||||
// Go over all entities which could have a pin
|
||||
for (let i = 0; i < pinEntities.length; ++i) {
|
||||
const pinEntity = pinEntities[i];
|
||||
const pinComp = pinEntity.components.WiredPins;
|
||||
const staticComp = pinEntity.components.StaticMapEntity;
|
||||
|
||||
// Skip those who don't have pins
|
||||
if (!pinComp) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Go over all pins
|
||||
const pins = pinComp.slots;
|
||||
for (let k = 0; k < pinComp.slots.length; ++k) {
|
||||
const pinSlot = pins[k];
|
||||
const pinLocation = staticComp.localTileToWorld(pinSlot.pos);
|
||||
const pinDirection = staticComp.localDirectionToWorld(pinSlot.direction);
|
||||
|
||||
// Check if the pin has the right location
|
||||
if (!pinLocation.equals(tile)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if the pin has the right direction
|
||||
if (pinDirection !== enumInvertedDirections[edge]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Found a pin!
|
||||
return enumWireEdgeFlag.connected;
|
||||
}
|
||||
}
|
||||
|
||||
// Now check if there's a connectable wire
|
||||
const targetEntity = this.root.map.getTileContent(tile, "wires");
|
||||
if (!targetEntity) {
|
||||
return enumWireEdgeFlag.empty;
|
||||
}
|
||||
|
||||
const targetStaticComp = targetEntity.components.StaticMapEntity;
|
||||
|
||||
// Check if its a crossing
|
||||
const wireTunnelComp = targetEntity.components.WireTunnel;
|
||||
if (wireTunnelComp) {
|
||||
// Check if the crossing is connected
|
||||
if (wireTunnelComp.multipleDirections) {
|
||||
return enumWireEdgeFlag.connected;
|
||||
} else {
|
||||
// Its a coating, check if it matches the direction
|
||||
const referenceDirection = targetStaticComp.localDirectionToWorld(enumDirection.top);
|
||||
return referenceDirection === edge || enumInvertedDirections[referenceDirection] === edge
|
||||
? enumWireEdgeFlag.connected
|
||||
: enumWireEdgeFlag.empty;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if its a wire
|
||||
const wiresComp = targetEntity.components.Wire;
|
||||
if (!wiresComp) {
|
||||
return enumWireEdgeFlag.empty;
|
||||
}
|
||||
|
||||
// const refAngle = enumDirectionToAngle[edge];
|
||||
// const refRotation = targetEntity.components.StaticMapEntity.originalRotation;
|
||||
// const canConnectRemotely = refRotation === refAngle || (refRotation + 180) % 360 === refAngle;
|
||||
|
||||
// Actually connected
|
||||
return enumWireEdgeFlag.connected;
|
||||
}
|
||||
g(tile, edge) {}
|
||||
|
||||
/**
|
||||
* Returns the acceptors and ejectors which affect the current tile
|
||||
|
||||
@@ -1,30 +1,34 @@
|
||||
import { gMetaBuildingRegistry } from "../core/global_registries";
|
||||
import { createLogger } from "../core/logging";
|
||||
import { T } from "../translations";
|
||||
import { MetaAnalyzerBuilding } from "./buildings/analyzer";
|
||||
import { enumBalancerVariants, MetaBalancerBuilding } from "./buildings/balancer";
|
||||
import { MetaBeltBuilding } from "./buildings/belt";
|
||||
import { MetaComparatorBuilding } from "./buildings/comparator";
|
||||
import { MetaConstantSignalBuilding } from "./buildings/constant_signal";
|
||||
import { enumCutterVariants, MetaCutterBuilding } from "./buildings/cutter";
|
||||
import { MetaDisplayBuilding } from "./buildings/display";
|
||||
import { MetaFilterBuilding } from "./buildings/filter";
|
||||
import { MetaHubBuilding } from "./buildings/hub";
|
||||
import { MetaLeverBuilding } from "./buildings/lever";
|
||||
import { enumLogicGateVariants, MetaLogicGateBuilding } from "./buildings/logic_gate";
|
||||
import { enumMinerVariants, MetaMinerBuilding } from "./buildings/miner";
|
||||
import { MetaMixerBuilding } from "./buildings/mixer";
|
||||
import { enumPainterVariants, MetaPainterBuilding } from "./buildings/painter";
|
||||
import { MetaReaderBuilding } from "./buildings/reader";
|
||||
import { enumRotaterVariants, MetaRotaterBuilding } from "./buildings/rotater";
|
||||
import { enumBalancerVariants, MetaBalancerBuilding } from "./buildings/balancer";
|
||||
import { MetaStackerBuilding } from "./buildings/stacker";
|
||||
import { MetaStorageBuilding } from "./buildings/storage";
|
||||
import { MetaTransistorBuilding, enumTransistorVariants } from "./buildings/transistor";
|
||||
import { MetaTrashBuilding } from "./buildings/trash";
|
||||
import { enumUndergroundBeltVariants, MetaUndergroundBeltBuilding } from "./buildings/underground_belt";
|
||||
import { enumVirtualProcessorVariants, MetaVirtualProcessorBuilding } from "./buildings/virtual_processor";
|
||||
import { MetaWireBuilding } from "./buildings/wire";
|
||||
import { MetaWireTunnelBuilding } from "./buildings/wire_tunnel";
|
||||
import { buildBuildingCodeCache, gBuildingVariants, registerBuildingVariant } from "./building_codes";
|
||||
import { defaultBuildingVariant } from "./meta_building";
|
||||
import { MetaConstantSignalBuilding } from "./buildings/constant_signal";
|
||||
import { MetaLogicGateBuilding, enumLogicGateVariants } from "./buildings/logic_gate";
|
||||
import { MetaLeverBuilding } from "./buildings/lever";
|
||||
import { MetaFilterBuilding } from "./buildings/filter";
|
||||
import { MetaWireTunnelBuilding, enumWireTunnelVariants } from "./buildings/wire_tunnel";
|
||||
import { MetaDisplayBuilding } from "./buildings/display";
|
||||
import { MetaVirtualProcessorBuilding, enumVirtualProcessorVariants } from "./buildings/virtual_processor";
|
||||
import { MetaReaderBuilding } from "./buildings/reader";
|
||||
import { MetaStorageBuilding } from "./buildings/storage";
|
||||
import { enumWireVariant } from "./components/wire";
|
||||
import { KEYMAPPINGS } from "./key_action_mapper";
|
||||
import { T } from "../translations";
|
||||
import { defaultBuildingVariant } from "./meta_building";
|
||||
|
||||
const logger = createLogger("building_registry");
|
||||
|
||||
@@ -50,6 +54,9 @@ export function initMetaBuildingRegistry() {
|
||||
gMetaBuildingRegistry.register(MetaDisplayBuilding);
|
||||
gMetaBuildingRegistry.register(MetaVirtualProcessorBuilding);
|
||||
gMetaBuildingRegistry.register(MetaReaderBuilding);
|
||||
gMetaBuildingRegistry.register(MetaTransistorBuilding);
|
||||
gMetaBuildingRegistry.register(MetaAnalyzerBuilding);
|
||||
gMetaBuildingRegistry.register(MetaComparatorBuilding);
|
||||
|
||||
// Belt
|
||||
registerBuildingVariant(1, MetaBeltBuilding, defaultBuildingVariant, 0);
|
||||
@@ -109,6 +116,16 @@ export function initMetaBuildingRegistry() {
|
||||
registerBuildingVariant(29, MetaWireBuilding, defaultBuildingVariant, 2);
|
||||
registerBuildingVariant(30, MetaWireBuilding, defaultBuildingVariant, 3);
|
||||
|
||||
registerBuildingVariant(52, MetaWireBuilding, enumWireVariant.second, 0);
|
||||
registerBuildingVariant(53, MetaWireBuilding, enumWireVariant.second, 1);
|
||||
registerBuildingVariant(54, MetaWireBuilding, enumWireVariant.second, 2);
|
||||
registerBuildingVariant(55, MetaWireBuilding, enumWireVariant.second, 3);
|
||||
|
||||
registerBuildingVariant(56, MetaWireBuilding, enumWireVariant.third, 0);
|
||||
registerBuildingVariant(57, MetaWireBuilding, enumWireVariant.third, 1);
|
||||
registerBuildingVariant(58, MetaWireBuilding, enumWireVariant.third, 2);
|
||||
registerBuildingVariant(59, MetaWireBuilding, enumWireVariant.third, 3);
|
||||
|
||||
// Constant signal
|
||||
registerBuildingVariant(31, MetaConstantSignalBuilding);
|
||||
|
||||
@@ -117,7 +134,10 @@ export function initMetaBuildingRegistry() {
|
||||
registerBuildingVariant(34, MetaLogicGateBuilding, enumLogicGateVariants.not);
|
||||
registerBuildingVariant(35, MetaLogicGateBuilding, enumLogicGateVariants.xor);
|
||||
registerBuildingVariant(36, MetaLogicGateBuilding, enumLogicGateVariants.or);
|
||||
registerBuildingVariant(38, MetaLogicGateBuilding, enumLogicGateVariants.transistor);
|
||||
|
||||
// Transistor
|
||||
registerBuildingVariant(38, MetaTransistorBuilding, defaultBuildingVariant);
|
||||
registerBuildingVariant(60, MetaTransistorBuilding, enumTransistorVariants.mirrored);
|
||||
|
||||
// Lever
|
||||
registerBuildingVariant(33, MetaLeverBuilding);
|
||||
@@ -127,20 +147,21 @@ export function initMetaBuildingRegistry() {
|
||||
|
||||
// Wire tunnel
|
||||
registerBuildingVariant(39, MetaWireTunnelBuilding);
|
||||
registerBuildingVariant(41, MetaWireTunnelBuilding, enumWireTunnelVariants.coating);
|
||||
|
||||
// Display
|
||||
registerBuildingVariant(40, MetaDisplayBuilding);
|
||||
|
||||
// Virtual Processor
|
||||
registerBuildingVariant(42, MetaVirtualProcessorBuilding);
|
||||
registerBuildingVariant(43, MetaVirtualProcessorBuilding, enumVirtualProcessorVariants.analyzer);
|
||||
registerBuildingVariant(44, MetaVirtualProcessorBuilding, enumVirtualProcessorVariants.rotater);
|
||||
registerBuildingVariant(45, MetaVirtualProcessorBuilding, enumVirtualProcessorVariants.unstacker);
|
||||
registerBuildingVariant(46, MetaVirtualProcessorBuilding, enumVirtualProcessorVariants.shapecompare);
|
||||
registerBuildingVariant(50, MetaVirtualProcessorBuilding, enumVirtualProcessorVariants.stacker);
|
||||
registerBuildingVariant(51, MetaVirtualProcessorBuilding, enumVirtualProcessorVariants.painter);
|
||||
|
||||
// Analyzer
|
||||
registerBuildingVariant(46, MetaComparatorBuilding);
|
||||
registerBuildingVariant(43, MetaAnalyzerBuilding);
|
||||
|
||||
// Reader
|
||||
registerBuildingVariant(49, MetaReaderBuilding);
|
||||
|
||||
|
||||
@@ -3,11 +3,9 @@ import { enumColors } from "../colors";
|
||||
import { enumLogicGateType, LogicGateComponent } from "../components/logic_gate";
|
||||
import { enumPinSlotType } from "../components/wired_pins";
|
||||
import { GameSystemWithFilter } from "../game_system_with_filter";
|
||||
import { BOOL_FALSE_SINGLETON, BOOL_TRUE_SINGLETON, isTruthyItem, BooleanItem } from "../items/boolean_item";
|
||||
import { COLOR_ITEM_SINGLETONS, ColorItem } from "../items/color_item";
|
||||
import { BOOL_FALSE_SINGLETON, BOOL_TRUE_SINGLETON, isTruthyItem } from "../items/boolean_item";
|
||||
import { COLOR_ITEM_SINGLETONS } from "../items/color_item";
|
||||
import { ShapeDefinition } from "../shape_definition";
|
||||
import { ShapeItem } from "../items/shape_item";
|
||||
import { enumInvertedDirections } from "../../core/vector";
|
||||
|
||||
export class LogicGateSystem extends GameSystemWithFilter {
|
||||
constructor(root) {
|
||||
@@ -24,7 +22,7 @@ export class LogicGateSystem extends GameSystemWithFilter {
|
||||
[enumLogicGateType.analyzer]: this.compute_ANALYZE.bind(this),
|
||||
[enumLogicGateType.cutter]: this.compute_CUT.bind(this),
|
||||
[enumLogicGateType.unstacker]: this.compute_UNSTACK.bind(this),
|
||||
[enumLogicGateType.shapecompare]: this.compute_SHAPECOMPARE.bind(this),
|
||||
[enumLogicGateType.compare]: this.compute_COMPARE.bind(this),
|
||||
[enumLogicGateType.stacker]: this.compute_STACKER.bind(this),
|
||||
[enumLogicGateType.painter]: this.compute_PAINTER.bind(this),
|
||||
};
|
||||
@@ -318,7 +316,7 @@ export class LogicGateSystem extends GameSystemWithFilter {
|
||||
* @param {Array<BaseItem|null>} parameters
|
||||
* @returns {BaseItem}
|
||||
*/
|
||||
compute_SHAPECOMPARE(parameters) {
|
||||
compute_COMPARE(parameters) {
|
||||
const itemA = parameters[0];
|
||||
const itemB = parameters[1];
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import { gMetaBuildingRegistry } from "../../core/global_registries";
|
||||
import { Loader } from "../../core/loader";
|
||||
import { createLogger } from "../../core/logging";
|
||||
import { Rectangle } from "../../core/rectangle";
|
||||
import { AtlasSprite } from "../../core/sprites";
|
||||
import { StaleAreaDetector } from "../../core/stale_area_detector";
|
||||
import { fastArrayDeleteValueIfContained } from "../../core/utils";
|
||||
import {
|
||||
@@ -13,16 +14,15 @@ import {
|
||||
Vector,
|
||||
} from "../../core/vector";
|
||||
import { BaseItem } from "../base_item";
|
||||
import { isTrueItem } from "../items/boolean_item";
|
||||
import { arrayWireRotationVariantToType, MetaWireBuilding } from "../buildings/wire";
|
||||
import { getCodeFromBuildingData } from "../building_codes";
|
||||
import { enumWireType, WireComponent } from "../components/wire";
|
||||
import { enumWireType, enumWireVariant, WireComponent } from "../components/wire";
|
||||
import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
|
||||
import { WireTunnelComponent } from "../components/wire_tunnel";
|
||||
import { Entity } from "../entity";
|
||||
import { GameSystemWithFilter } from "../game_system_with_filter";
|
||||
import { isTruthyItem } from "../items/boolean_item";
|
||||
import { MapChunkView } from "../map_chunk_view";
|
||||
import { defaultBuildingVariant } from "../meta_building";
|
||||
|
||||
const logger = createLogger("wires");
|
||||
|
||||
@@ -93,32 +93,22 @@ export class WireSystem extends GameSystemWithFilter {
|
||||
constructor(root) {
|
||||
super(root, [WireComponent]);
|
||||
|
||||
this.wireSprites = {
|
||||
regular: {
|
||||
[enumWireType.regular]: Loader.getSprite("sprites/wires/sets/regular_forward.png"),
|
||||
[enumWireType.turn]: Loader.getSprite("sprites/wires/sets/regular_turn.png"),
|
||||
[enumWireType.split]: Loader.getSprite("sprites/wires/sets/regular_split.png"),
|
||||
[enumWireType.cross]: Loader.getSprite("sprites/wires/sets/regular_cross.png"),
|
||||
},
|
||||
conflict: {
|
||||
[enumWireType.regular]: Loader.getSprite("sprites/wires/sets/conflict_forward.png"),
|
||||
[enumWireType.turn]: Loader.getSprite("sprites/wires/sets/conflict_turn.png"),
|
||||
[enumWireType.split]: Loader.getSprite("sprites/wires/sets/conflict_split.png"),
|
||||
[enumWireType.cross]: Loader.getSprite("sprites/wires/sets/conflict_cross.png"),
|
||||
},
|
||||
shape: {
|
||||
[enumWireType.regular]: Loader.getSprite("sprites/wires/sets/shape_forward.png"),
|
||||
[enumWireType.turn]: Loader.getSprite("sprites/wires/sets/shape_turn.png"),
|
||||
[enumWireType.split]: Loader.getSprite("sprites/wires/sets/shape_split.png"),
|
||||
[enumWireType.cross]: Loader.getSprite("sprites/wires/sets/shape_cross.png"),
|
||||
},
|
||||
color: {
|
||||
[enumWireType.regular]: Loader.getSprite("sprites/wires/sets/color_forward.png"),
|
||||
[enumWireType.turn]: Loader.getSprite("sprites/wires/sets/color_turn.png"),
|
||||
[enumWireType.split]: Loader.getSprite("sprites/wires/sets/color_split.png"),
|
||||
[enumWireType.cross]: Loader.getSprite("sprites/wires/sets/color_cross.png"),
|
||||
},
|
||||
};
|
||||
/**
|
||||
* @type {Object<enumWireVariant, Object<enumWireType, AtlasSprite>>}
|
||||
*/
|
||||
this.wireSprites = {};
|
||||
|
||||
const variants = ["conflict", ...Object.keys(enumWireVariant)];
|
||||
for (let i = 0; i < variants.length; ++i) {
|
||||
const wireVariant = variants[i];
|
||||
const sprites = {};
|
||||
for (const wireType in enumWireType) {
|
||||
sprites[wireType] = Loader.getSprite(
|
||||
"sprites/wires/sets/" + wireVariant + "_" + wireType + ".png"
|
||||
);
|
||||
}
|
||||
this.wireSprites[wireVariant] = sprites;
|
||||
}
|
||||
|
||||
this.root.signals.entityDestroyed.add(this.queuePlacementUpdate, this);
|
||||
this.root.signals.entityAdded.add(this.queuePlacementUpdate, this);
|
||||
@@ -230,6 +220,13 @@ export class WireSystem extends GameSystemWithFilter {
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* Once we occur a wire, we store its variant so we don't connect to
|
||||
* mismatching ones
|
||||
* @type {enumWireVariant}
|
||||
*/
|
||||
let variantMask = null;
|
||||
|
||||
while (entitiesToVisit.length > 0) {
|
||||
const nextData = entitiesToVisit.pop();
|
||||
const nextEntity = nextData.entity;
|
||||
@@ -257,13 +254,18 @@ export class WireSystem extends GameSystemWithFilter {
|
||||
);
|
||||
|
||||
if (!wireComp.linkedNetwork) {
|
||||
// This one is new! :D
|
||||
VERBOSE_WIRES && logger.log(" Visited new wire:", staticComp.origin.toString());
|
||||
wireComp.linkedNetwork = currentNetwork;
|
||||
currentNetwork.wires.push(nextEntity);
|
||||
if (variantMask && wireComp.variant !== variantMask) {
|
||||
// Mismatching variant
|
||||
} else {
|
||||
// This one is new! :D
|
||||
VERBOSE_WIRES && logger.log(" Visited new wire:", staticComp.origin.toString());
|
||||
wireComp.linkedNetwork = currentNetwork;
|
||||
currentNetwork.wires.push(nextEntity);
|
||||
|
||||
newSearchDirections = arrayAllDirections;
|
||||
newSearchTile = nextEntity.components.StaticMapEntity.origin;
|
||||
newSearchDirections = arrayAllDirections;
|
||||
newSearchTile = nextEntity.components.StaticMapEntity.origin;
|
||||
variantMask = wireComp.variant;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -319,7 +321,8 @@ export class WireSystem extends GameSystemWithFilter {
|
||||
const newTargets = this.findSurroundingWireTargets(
|
||||
newSearchTile,
|
||||
newSearchDirections,
|
||||
currentNetwork
|
||||
currentNetwork,
|
||||
variantMask
|
||||
);
|
||||
|
||||
VERBOSE_WIRES && logger.log(" Found", newTargets, "new targets to visit!");
|
||||
@@ -361,13 +364,21 @@ export class WireSystem extends GameSystemWithFilter {
|
||||
* @param {Vector} initialTile
|
||||
* @param {Array<enumDirection>} directions
|
||||
* @param {WireNetwork} network
|
||||
* @param {enumWireVariant=} variantMask Only accept connections to this mask
|
||||
* @returns {Array<any>}
|
||||
*/
|
||||
findSurroundingWireTargets(initialTile, directions, network) {
|
||||
findSurroundingWireTargets(initialTile, directions, network, variantMask = null) {
|
||||
let result = [];
|
||||
|
||||
VERBOSE_WIRES &&
|
||||
logger.log(" Searching for new targets at", initialTile.toString(), "and d=", directions);
|
||||
logger.log(
|
||||
" Searching for new targets at",
|
||||
initialTile.toString(),
|
||||
"and d=",
|
||||
directions,
|
||||
"with mask=",
|
||||
variantMask
|
||||
);
|
||||
|
||||
// Go over all directions we should search for
|
||||
for (let i = 0; i < directions.length; ++i) {
|
||||
@@ -399,7 +410,11 @@ export class WireSystem extends GameSystemWithFilter {
|
||||
const wireComp = entity.components.Wire;
|
||||
|
||||
// Check for wire
|
||||
if (wireComp && !wireComp.linkedNetwork) {
|
||||
if (
|
||||
wireComp &&
|
||||
!wireComp.linkedNetwork &&
|
||||
(!variantMask || wireComp.variant === variantMask)
|
||||
) {
|
||||
// Wires accept connections from everywhere
|
||||
result.push({
|
||||
entity,
|
||||
@@ -449,17 +464,6 @@ export class WireSystem extends GameSystemWithFilter {
|
||||
|
||||
const staticComp = entity.components.StaticMapEntity;
|
||||
|
||||
if (
|
||||
!tunnelComp.multipleDirections &&
|
||||
!(
|
||||
direction === staticComp.localDirectionToWorld(enumDirection.top) ||
|
||||
direction === staticComp.localDirectionToWorld(enumDirection.bottom)
|
||||
)
|
||||
) {
|
||||
// It's a coating, and it doesn't connect here
|
||||
continue;
|
||||
}
|
||||
|
||||
// Compute where this tunnel connects to
|
||||
const forwardedTile = staticComp.origin.add(offset);
|
||||
VERBOSE_WIRES &&
|
||||
@@ -570,8 +574,8 @@ export class WireSystem extends GameSystemWithFilter {
|
||||
if (!wireComp.linkedNetwork) {
|
||||
// There is no network, it's empty
|
||||
return {
|
||||
spriteSet: this.wireSprites.regular,
|
||||
opacity: 0.3,
|
||||
spriteSet: this.wireSprites[wireComp.variant],
|
||||
opacity: 0.5,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -584,38 +588,9 @@ export class WireSystem extends GameSystemWithFilter {
|
||||
};
|
||||
}
|
||||
|
||||
const value = network.currentValue;
|
||||
if (!value) {
|
||||
// There is no value stored
|
||||
return {
|
||||
spriteSet: this.wireSprites.regular,
|
||||
opacity: 0.3,
|
||||
};
|
||||
}
|
||||
|
||||
const valueType = value.getItemType();
|
||||
if (valueType === "shape") {
|
||||
return {
|
||||
spriteSet: this.wireSprites.shape,
|
||||
opacity: 1,
|
||||
};
|
||||
} else if (valueType === "color") {
|
||||
return {
|
||||
spriteSet: this.wireSprites.color,
|
||||
opacity: 1,
|
||||
};
|
||||
} else if (valueType === "boolean") {
|
||||
return {
|
||||
spriteSet: this.wireSprites.regular,
|
||||
opacity: isTrueItem(value) ? 1 : 0.5,
|
||||
};
|
||||
} else {
|
||||
assertAlways(false, "Unknown item type: " + valueType);
|
||||
}
|
||||
|
||||
return {
|
||||
spriteSet: this.wireSprites.regular,
|
||||
opacity: 1,
|
||||
spriteSet: this.wireSprites[wireComp.variant],
|
||||
opacity: isTruthyItem(network.currentValue) ? 1 : 0.5,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -641,9 +616,10 @@ export class WireSystem extends GameSystemWithFilter {
|
||||
const staticComp = entity.components.StaticMapEntity;
|
||||
parameters.context.globalAlpha = opacity;
|
||||
staticComp.drawSpriteOnBoundsClipped(parameters, sprite, 0);
|
||||
parameters.context.globalAlpha = 1;
|
||||
|
||||
// DEBUG Rendering
|
||||
if (G_IS_DEV && globalConfig.debug.renderWireRotations) {
|
||||
parameters.context.globalAlpha = 1;
|
||||
parameters.context.fillStyle = "red";
|
||||
parameters.context.font = "5px Tahoma";
|
||||
parameters.context.fillText(
|
||||
@@ -691,6 +667,8 @@ export class WireSystem extends GameSystemWithFilter {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parameters.context.globalAlpha = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -746,6 +724,8 @@ export class WireSystem extends GameSystemWithFilter {
|
||||
continue;
|
||||
}
|
||||
|
||||
const variant = targetStaticComp.getVariant();
|
||||
|
||||
const {
|
||||
rotation,
|
||||
rotationVariant,
|
||||
@@ -753,7 +733,7 @@ export class WireSystem extends GameSystemWithFilter {
|
||||
root: this.root,
|
||||
tile: new Vector(x, y),
|
||||
rotation: targetStaticComp.originalRotation,
|
||||
variant: defaultBuildingVariant,
|
||||
variant,
|
||||
layer: targetEntity.layer,
|
||||
});
|
||||
|
||||
@@ -763,14 +743,10 @@ export class WireSystem extends GameSystemWithFilter {
|
||||
if (targetStaticComp.rotation !== rotation || newType !== targetWireComp.type) {
|
||||
// Change stuff
|
||||
targetStaticComp.rotation = rotation;
|
||||
metaWire.updateVariants(targetEntity, rotationVariant, defaultBuildingVariant);
|
||||
metaWire.updateVariants(targetEntity, rotationVariant, variant);
|
||||
|
||||
// Update code as well
|
||||
targetStaticComp.code = getCodeFromBuildingData(
|
||||
metaWire,
|
||||
defaultBuildingVariant,
|
||||
rotationVariant
|
||||
);
|
||||
targetStaticComp.code = getCodeFromBuildingData(metaWire, variant, rotationVariant);
|
||||
|
||||
// Make sure the chunks know about the update
|
||||
this.root.signals.entityChanged.dispatch(targetEntity);
|
||||
|
||||
Reference in New Issue
Block a user