From 2c8f11ff7f31c03f152161beb565a5767027701b Mon Sep 17 00:00:00 2001 From: tobspr Date: Sun, 16 Jan 2022 11:19:22 +0100 Subject: [PATCH] Refactor building registry, make it easier for mods to add new buildings --- mod_examples/add_building_basic.js | 28 +-- mod_examples/add_building_flipper.js | 28 +-- src/js/game/building_codes.js | 3 + src/js/game/buildings/analyzer.js | 11 +- src/js/game/buildings/balancer.js | 25 +++ src/js/game/buildings/belt.js | 22 +- src/js/game/buildings/block.js | 11 +- src/js/game/buildings/comparator.js | 11 +- src/js/game/buildings/constant_producer.js | 11 +- src/js/game/buildings/constant_signal.js | 11 +- src/js/game/buildings/cutter.js | 13 ++ src/js/game/buildings/display.js | 11 +- src/js/game/buildings/filter.js | 11 +- src/js/game/buildings/goal_acceptor.js | 11 +- src/js/game/buildings/hub.js | 11 +- src/js/game/buildings/item_producer.js | 11 +- src/js/game/buildings/lever.js | 11 +- src/js/game/buildings/logic_gate.js | 21 ++ src/js/game/buildings/miner.js | 13 ++ src/js/game/buildings/mixer.js | 11 +- src/js/game/buildings/painter.js | 21 ++ src/js/game/buildings/reader.js | 11 +- src/js/game/buildings/rotater.js | 17 ++ src/js/game/buildings/stacker.js | 11 +- src/js/game/buildings/storage.js | 11 +- src/js/game/buildings/transistor.js | 13 ++ src/js/game/buildings/trash.js | 11 +- src/js/game/buildings/underground_belt.js | 25 +++ src/js/game/buildings/virtual_processor.js | 25 +++ src/js/game/buildings/wire.js | 45 ++++ src/js/game/buildings/wire_tunnel.js | 11 +- src/js/game/meta_building.js | 10 + src/js/game/meta_building_registry.js | 227 ++++++--------------- src/js/mods/mod_interface.js | 42 ++-- src/js/mods/mod_meta_building.js | 18 ++ 35 files changed, 545 insertions(+), 238 deletions(-) create mode 100644 src/js/mods/mod_meta_building.js diff --git a/mod_examples/add_building_basic.js b/mod_examples/add_building_basic.js index 532455a1..b7c1a6bb 100644 --- a/mod_examples/add_building_basic.js +++ b/mod_examples/add_building_basic.js @@ -4,11 +4,25 @@ * the advanced example */ registerMod(() => { - class MetaDemoModBuilding extends shapez.MetaBuilding { + class MetaDemoModBuilding extends shapez.ModMetaBuilding { constructor() { super("demoModBuilding"); } + static getAllVariantCombinations() { + return [ + { + variant: shapez.defaultBuildingVariant, + name: "A test name", + description: "A test building", + + regularImageBase64: RESOURCES["demoBuilding.png"], + blueprintImageBase64: RESOURCES["demoBuildingBlueprint.png"], + tutorialImageBase64: RESOURCES["demoBuildingBlueprint.png"], + }, + ]; + } + getSilhouetteColor() { return "red"; } @@ -41,18 +55,6 @@ registerMod(() => { this.modInterface.registerNewBuilding({ metaClass: MetaDemoModBuilding, buildingIconBase64: RESOURCES["demoBuilding.png"], - - variantsAndRotations: [ - { - name: "A test name", - description: "A test building", - variant: shapez.defaultBuildingVariant, - - regularImageBase64: RESOURCES["demoBuilding.png"], - blueprintImageBase64: RESOURCES["demoBuildingBlueprint.png"], - tutorialImageBase64: RESOURCES["demoBuildingBlueprint.png"], - }, - ], }); // Add it to the regular toolbar diff --git a/mod_examples/add_building_flipper.js b/mod_examples/add_building_flipper.js index 1174823b..f216f31b 100644 --- a/mod_examples/add_building_flipper.js +++ b/mod_examples/add_building_flipper.js @@ -35,11 +35,25 @@ registerMod(() => { }; // Create the building - class MetaModFlipperBuilding extends shapez.MetaBuilding { + class MetaModFlipperBuilding extends shapez.ModMetaBuilding { constructor() { super("modFlipperBuilding"); } + static getAllVariantCombinations() { + return [ + { + name: "Flipper", + description: "Flipps/Mirrors shapez from top to bottom", + variant: shapez.defaultBuildingVariant, + + regularImageBase64: RESOURCES["flipper.png"], + blueprintImageBase64: RESOURCES["flipper.png"], + tutorialImageBase64: RESOURCES["flipper.png"], + }, + ]; + } + getSilhouetteColor() { return "red"; } @@ -106,18 +120,6 @@ registerMod(() => { this.modInterface.registerNewBuilding({ metaClass: MetaModFlipperBuilding, buildingIconBase64: RESOURCES["flipper.png"], - - variantsAndRotations: [ - { - name: "Flipper", - description: "Flipps/Mirrors shapez from top to bottom", - variant: shapez.defaultBuildingVariant, - - regularImageBase64: RESOURCES["flipper.png"], - blueprintImageBase64: RESOURCES["flipper.png"], - tutorialImageBase64: RESOURCES["flipper.png"], - }, - ], }); // Add it to the regular toolbar diff --git a/src/js/game/building_codes.js b/src/js/game/building_codes.js index 5e2b717b..1d178daf 100644 --- a/src/js/game/building_codes.js +++ b/src/js/game/building_codes.js @@ -4,6 +4,8 @@ import { AtlasSprite } from "../core/sprites"; import { Vector } from "../core/vector"; /* typehints:end */ +import { gMetaBuildingRegistry } from "../core/global_registries"; + /** * @typedef {{ * metaClass: typeof MetaBuilding, @@ -47,6 +49,7 @@ export function registerBuildingVariant( assert(!gBuildingVariants[code], "Duplicate id: " + code); gBuildingVariants[code] = { metaClass: meta, + metaInstance: gMetaBuildingRegistry.findByClass(meta), variant, rotationVariant, // @ts-ignore diff --git a/src/js/game/buildings/analyzer.js b/src/js/game/buildings/analyzer.js index 8335f730..13597d7b 100644 --- a/src/js/game/buildings/analyzer.js +++ b/src/js/game/buildings/analyzer.js @@ -3,7 +3,7 @@ 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 { defaultBuildingVariant, MetaBuilding } from "../meta_building"; import { GameRoot } from "../root"; import { enumHubGoalRewards } from "../tutorial_goals"; @@ -14,6 +14,15 @@ export class MetaAnalyzerBuilding extends MetaBuilding { super("analyzer"); } + static getAllVariantCombinations() { + return [ + { + internalId: 43, + variant: defaultBuildingVariant, + }, + ]; + } + getSilhouetteColor() { return "#3a52bc"; } diff --git a/src/js/game/buildings/balancer.js b/src/js/game/buildings/balancer.js index 38a568e1..0948338c 100644 --- a/src/js/game/buildings/balancer.js +++ b/src/js/game/buildings/balancer.js @@ -31,6 +31,31 @@ export class MetaBalancerBuilding extends MetaBuilding { super("balancer"); } + static getAllVariantCombinations() { + return [ + { + internalId: 4, + variant: defaultBuildingVariant, + }, + { + internalId: 5, + variant: enumBalancerVariants.merger, + }, + { + internalId: 6, + variant: enumBalancerVariants.mergerInverse, + }, + { + internalId: 47, + variant: enumBalancerVariants.splitter, + }, + { + internalId: 48, + variant: enumBalancerVariants.splitterInverse, + }, + ]; + } + getDimensions(variant) { switch (variant) { case defaultBuildingVariant: diff --git a/src/js/game/buildings/belt.js b/src/js/game/buildings/belt.js index f4e31ba9..11a53cdf 100644 --- a/src/js/game/buildings/belt.js +++ b/src/js/game/buildings/belt.js @@ -5,7 +5,7 @@ import { SOUNDS } from "../../platform/sound"; import { T } from "../../translations"; import { BeltComponent } from "../components/belt"; import { Entity } from "../entity"; -import { MetaBuilding } from "../meta_building"; +import { defaultBuildingVariant, MetaBuilding } from "../meta_building"; import { GameRoot } from "../root"; import { THEME } from "../theme"; @@ -22,6 +22,26 @@ export class MetaBeltBuilding extends MetaBuilding { super("belt"); } + static getAllVariantCombinations() { + return [ + { + internalId: 1, + variant: defaultBuildingVariant, + rotationVariant: 0, + }, + { + internalId: 2, + variant: defaultBuildingVariant, + rotationVariant: 1, + }, + { + internalId: 3, + variant: defaultBuildingVariant, + rotationVariant: 2, + }, + ]; + } + getSilhouetteColor() { return THEME.map.chunkOverview.beltColor; } diff --git a/src/js/game/buildings/block.js b/src/js/game/buildings/block.js index d6499648..024c6322 100644 --- a/src/js/game/buildings/block.js +++ b/src/js/game/buildings/block.js @@ -2,13 +2,22 @@ import { Entity } from "../entity"; /* typehints:end */ -import { MetaBuilding } from "../meta_building"; +import { defaultBuildingVariant, MetaBuilding } from "../meta_building"; export class MetaBlockBuilding extends MetaBuilding { constructor() { super("block"); } + static getAllVariantCombinations() { + return [ + { + internalId: 64, + variant: defaultBuildingVariant, + }, + ]; + } + getSilhouetteColor() { return "#333"; } diff --git a/src/js/game/buildings/comparator.js b/src/js/game/buildings/comparator.js index 6738d514..1f45dbbb 100644 --- a/src/js/game/buildings/comparator.js +++ b/src/js/game/buildings/comparator.js @@ -2,7 +2,7 @@ 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 { defaultBuildingVariant, MetaBuilding } from "../meta_building"; import { GameRoot } from "../root"; import { enumHubGoalRewards } from "../tutorial_goals"; @@ -11,6 +11,15 @@ export class MetaComparatorBuilding extends MetaBuilding { super("comparator"); } + static getAllVariantCombinations() { + return [ + { + internalId: 46, + variant: defaultBuildingVariant, + }, + ]; + } + getSilhouetteColor() { return "#823cab"; } diff --git a/src/js/game/buildings/constant_producer.js b/src/js/game/buildings/constant_producer.js index c1c502d0..5c19a6ed 100644 --- a/src/js/game/buildings/constant_producer.js +++ b/src/js/game/buildings/constant_producer.js @@ -6,13 +6,22 @@ import { enumDirection, Vector } from "../../core/vector"; import { ConstantSignalComponent } from "../components/constant_signal"; import { ItemEjectorComponent } from "../components/item_ejector"; import { ItemProducerComponent } from "../components/item_producer"; -import { MetaBuilding } from "../meta_building"; +import { defaultBuildingVariant, MetaBuilding } from "../meta_building"; export class MetaConstantProducerBuilding extends MetaBuilding { constructor() { super("constant_producer"); } + static getAllVariantCombinations() { + return [ + { + internalId: 62, + variant: defaultBuildingVariant, + }, + ]; + } + getSilhouetteColor() { return "#bfd630"; } diff --git a/src/js/game/buildings/constant_signal.js b/src/js/game/buildings/constant_signal.js index 983594cb..2bb72def 100644 --- a/src/js/game/buildings/constant_signal.js +++ b/src/js/game/buildings/constant_signal.js @@ -1,7 +1,7 @@ import { enumDirection, Vector } from "../../core/vector"; import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins"; import { Entity } from "../entity"; -import { MetaBuilding } from "../meta_building"; +import { defaultBuildingVariant, MetaBuilding } from "../meta_building"; import { GameRoot } from "../root"; import { ConstantSignalComponent } from "../components/constant_signal"; import { generateMatrixRotations } from "../../core/utils"; @@ -14,6 +14,15 @@ export class MetaConstantSignalBuilding extends MetaBuilding { super("constant_signal"); } + static getAllVariantCombinations() { + return [ + { + internalId: 31, + variant: defaultBuildingVariant, + }, + ]; + } + getSilhouetteColor() { return "#2b84fd"; } diff --git a/src/js/game/buildings/cutter.js b/src/js/game/buildings/cutter.js index 37264c9d..4950f786 100644 --- a/src/js/game/buildings/cutter.js +++ b/src/js/game/buildings/cutter.js @@ -17,6 +17,19 @@ export class MetaCutterBuilding extends MetaBuilding { super("cutter"); } + static getAllVariantCombinations() { + return [ + { + internalId: 9, + variant: defaultBuildingVariant, + }, + { + internalId: 10, + variant: enumCutterVariants.quad, + }, + ]; + } + getSilhouetteColor() { return "#7dcda2"; } diff --git a/src/js/game/buildings/display.js b/src/js/game/buildings/display.js index 422bea81..7c1277c2 100644 --- a/src/js/game/buildings/display.js +++ b/src/js/game/buildings/display.js @@ -1,7 +1,7 @@ import { enumDirection, Vector } from "../../core/vector"; import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins"; import { Entity } from "../entity"; -import { MetaBuilding } from "../meta_building"; +import { defaultBuildingVariant, MetaBuilding } from "../meta_building"; import { GameRoot } from "../root"; import { DisplayComponent } from "../components/display"; import { enumHubGoalRewards } from "../tutorial_goals"; @@ -11,6 +11,15 @@ export class MetaDisplayBuilding extends MetaBuilding { super("display"); } + static getAllVariantCombinations() { + return [ + { + internalId: 40, + variant: defaultBuildingVariant, + }, + ]; + } + getSilhouetteColor() { return "#aaaaaa"; } diff --git a/src/js/game/buildings/filter.js b/src/js/game/buildings/filter.js index 08296853..bf4c5f19 100644 --- a/src/js/game/buildings/filter.js +++ b/src/js/game/buildings/filter.js @@ -6,7 +6,7 @@ import { ItemAcceptorComponent } from "../components/item_acceptor"; import { ItemEjectorComponent } from "../components/item_ejector"; import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins"; import { Entity } from "../entity"; -import { MetaBuilding } from "../meta_building"; +import { defaultBuildingVariant, MetaBuilding } from "../meta_building"; import { GameRoot } from "../root"; import { enumHubGoalRewards } from "../tutorial_goals"; @@ -15,6 +15,15 @@ export class MetaFilterBuilding extends MetaBuilding { super("filter"); } + static getAllVariantCombinations() { + return [ + { + internalId: 37, + variant: defaultBuildingVariant, + }, + ]; + } + getSilhouetteColor() { return "#c45c2e"; } diff --git a/src/js/game/buildings/goal_acceptor.js b/src/js/game/buildings/goal_acceptor.js index dde720e3..cb51a6d2 100644 --- a/src/js/game/buildings/goal_acceptor.js +++ b/src/js/game/buildings/goal_acceptor.js @@ -6,13 +6,22 @@ import { enumDirection, Vector } from "../../core/vector"; import { GoalAcceptorComponent } from "../components/goal_acceptor"; import { ItemAcceptorComponent } from "../components/item_acceptor"; import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor"; -import { MetaBuilding } from "../meta_building"; +import { defaultBuildingVariant, MetaBuilding } from "../meta_building"; export class MetaGoalAcceptorBuilding extends MetaBuilding { constructor() { super("goal_acceptor"); } + static getAllVariantCombinations() { + return [ + { + internalId: 63, + variant: defaultBuildingVariant, + }, + ]; + } + getSilhouetteColor() { return "#ce418a"; } diff --git a/src/js/game/buildings/hub.js b/src/js/game/buildings/hub.js index b9929b31..3a543cf0 100644 --- a/src/js/game/buildings/hub.js +++ b/src/js/game/buildings/hub.js @@ -3,7 +3,7 @@ import { HubComponent } from "../components/hub"; import { ItemAcceptorComponent } from "../components/item_acceptor"; import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor"; import { Entity } from "../entity"; -import { MetaBuilding } from "../meta_building"; +import { defaultBuildingVariant, MetaBuilding } from "../meta_building"; import { WiredPinsComponent, enumPinSlotType } from "../components/wired_pins"; export class MetaHubBuilding extends MetaBuilding { @@ -11,6 +11,15 @@ export class MetaHubBuilding extends MetaBuilding { super("hub"); } + static getAllVariantCombinations() { + return [ + { + internalId: 26, + variant: defaultBuildingVariant, + }, + ]; + } + getDimensions() { return new Vector(4, 4); } diff --git a/src/js/game/buildings/item_producer.js b/src/js/game/buildings/item_producer.js index 1140c8f1..a367beae 100644 --- a/src/js/game/buildings/item_producer.js +++ b/src/js/game/buildings/item_producer.js @@ -3,13 +3,22 @@ import { ItemEjectorComponent } from "../components/item_ejector"; import { ItemProducerComponent } from "../components/item_producer"; import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins"; import { Entity } from "../entity"; -import { MetaBuilding } from "../meta_building"; +import { defaultBuildingVariant, MetaBuilding } from "../meta_building"; export class MetaItemProducerBuilding extends MetaBuilding { constructor() { super("item_producer"); } + static getAllVariantCombinations() { + return [ + { + internalId: 61, + variant: defaultBuildingVariant, + }, + ]; + } + getSilhouetteColor() { return "#b37dcd"; } diff --git a/src/js/game/buildings/lever.js b/src/js/game/buildings/lever.js index 7ddaf65f..970a4bc6 100644 --- a/src/js/game/buildings/lever.js +++ b/src/js/game/buildings/lever.js @@ -1,7 +1,7 @@ import { enumDirection, Vector } from "../../core/vector"; import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins"; import { Entity } from "../entity"; -import { MetaBuilding } from "../meta_building"; +import { defaultBuildingVariant, MetaBuilding } from "../meta_building"; import { GameRoot } from "../root"; import { LeverComponent } from "../components/lever"; import { enumHubGoalRewards } from "../tutorial_goals"; @@ -11,6 +11,15 @@ export class MetaLeverBuilding extends MetaBuilding { super("lever"); } + static getAllVariantCombinations() { + return [ + { + internalId: 33, + variant: defaultBuildingVariant, + }, + ]; + } + getSilhouetteColor() { // @todo: Render differently based on if its activated or not return "#1a678b"; diff --git a/src/js/game/buildings/logic_gate.js b/src/js/game/buildings/logic_gate.js index a0e63c06..bd5e1940 100644 --- a/src/js/game/buildings/logic_gate.js +++ b/src/js/game/buildings/logic_gate.js @@ -41,6 +41,27 @@ export class MetaLogicGateBuilding extends MetaBuilding { super("logic_gate"); } + static getAllVariantCombinations() { + return [ + { + internalId: 32, + variant: defaultBuildingVariant, + }, + { + internalId: 34, + variant: enumLogicGateVariants.not, + }, + { + internalId: 35, + variant: enumLogicGateVariants.xor, + }, + { + internalId: 36, + variant: enumLogicGateVariants.or, + }, + ]; + } + getSilhouetteColor(variant) { return colors[variant]; } diff --git a/src/js/game/buildings/miner.js b/src/js/game/buildings/miner.js index 473aa262..b086a562 100644 --- a/src/js/game/buildings/miner.js +++ b/src/js/game/buildings/miner.js @@ -21,6 +21,19 @@ export class MetaMinerBuilding extends MetaBuilding { super("miner"); } + static getAllVariantCombinations() { + return [ + { + internalId: 7, + variant: defaultBuildingVariant, + }, + { + internalId: 8, + variant: enumMinerVariants.chainable, + }, + ]; + } + getSilhouetteColor() { return "#b37dcd"; } diff --git a/src/js/game/buildings/mixer.js b/src/js/game/buildings/mixer.js index e572bbba..db8d867a 100644 --- a/src/js/game/buildings/mixer.js +++ b/src/js/game/buildings/mixer.js @@ -5,7 +5,7 @@ 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 { defaultBuildingVariant, MetaBuilding } from "../meta_building"; import { GameRoot } from "../root"; import { enumHubGoalRewards } from "../tutorial_goals"; @@ -14,6 +14,15 @@ export class MetaMixerBuilding extends MetaBuilding { super("mixer"); } + static getAllVariantCombinations() { + return [ + { + internalId: 15, + variant: defaultBuildingVariant, + }, + ]; + } + getDimensions() { return new Vector(2, 1); } diff --git a/src/js/game/buildings/painter.js b/src/js/game/buildings/painter.js index e7a0b72d..79ae86ac 100644 --- a/src/js/game/buildings/painter.js +++ b/src/js/game/buildings/painter.js @@ -22,6 +22,27 @@ export class MetaPainterBuilding extends MetaBuilding { super("painter"); } + static getAllVariantCombinations() { + return [ + { + internalId: 16, + variant: defaultBuildingVariant, + }, + { + internalId: 17, + variant: enumPainterVariants.mirrored, + }, + { + internalId: 18, + variant: enumPainterVariants.double, + }, + { + internalId: 19, + variant: enumPainterVariants.quad, + }, + ]; + } + getDimensions(variant) { switch (variant) { case defaultBuildingVariant: diff --git a/src/js/game/buildings/reader.js b/src/js/game/buildings/reader.js index 006d6582..951c7e8a 100644 --- a/src/js/game/buildings/reader.js +++ b/src/js/game/buildings/reader.js @@ -4,7 +4,7 @@ import { ItemEjectorComponent } from "../components/item_ejector"; import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor"; import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins"; import { Entity } from "../entity"; -import { MetaBuilding } from "../meta_building"; +import { defaultBuildingVariant, MetaBuilding } from "../meta_building"; import { GameRoot } from "../root"; import { BeltUnderlaysComponent } from "../components/belt_underlays"; import { BeltReaderComponent } from "../components/belt_reader"; @@ -18,6 +18,15 @@ export class MetaReaderBuilding extends MetaBuilding { super("reader"); } + static getAllVariantCombinations() { + return [ + { + internalId: 49, + variant: defaultBuildingVariant, + }, + ]; + } + getSilhouetteColor() { return "#25fff2"; } diff --git a/src/js/game/buildings/rotater.js b/src/js/game/buildings/rotater.js index f24fee14..428ab08a 100644 --- a/src/js/game/buildings/rotater.js +++ b/src/js/game/buildings/rotater.js @@ -23,6 +23,23 @@ export class MetaRotaterBuilding extends MetaBuilding { super("rotater"); } + static getAllVariantCombinations() { + return [ + { + internalId: 11, + variant: defaultBuildingVariant, + }, + { + internalId: 12, + variant: enumRotaterVariants.ccw, + }, + { + internalId: 13, + variant: enumRotaterVariants.rotate180, + }, + ]; + } + getSilhouetteColor() { return "#7dc6cd"; } diff --git a/src/js/game/buildings/stacker.js b/src/js/game/buildings/stacker.js index 6b70365d..ad1a7bc7 100644 --- a/src/js/game/buildings/stacker.js +++ b/src/js/game/buildings/stacker.js @@ -5,7 +5,7 @@ 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 { defaultBuildingVariant, MetaBuilding } from "../meta_building"; import { GameRoot } from "../root"; import { enumHubGoalRewards } from "../tutorial_goals"; @@ -14,6 +14,15 @@ export class MetaStackerBuilding extends MetaBuilding { super("stacker"); } + static getAllVariantCombinations() { + return [ + { + internalId: 14, + variant: defaultBuildingVariant, + }, + ]; + } + getSilhouetteColor() { return "#9fcd7d"; } diff --git a/src/js/game/buildings/storage.js b/src/js/game/buildings/storage.js index 5574e137..b63adc01 100644 --- a/src/js/game/buildings/storage.js +++ b/src/js/game/buildings/storage.js @@ -6,7 +6,7 @@ import { ItemEjectorComponent } from "../components/item_ejector"; import { StorageComponent } from "../components/storage"; import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins"; import { Entity } from "../entity"; -import { MetaBuilding } from "../meta_building"; +import { defaultBuildingVariant, MetaBuilding } from "../meta_building"; import { GameRoot } from "../root"; import { enumHubGoalRewards } from "../tutorial_goals"; @@ -17,6 +17,15 @@ export class MetaStorageBuilding extends MetaBuilding { super("storage"); } + static getAllVariantCombinations() { + return [ + { + internalId: 21, + variant: defaultBuildingVariant, + }, + ]; + } + getSilhouetteColor() { return "#bbdf6d"; } diff --git a/src/js/game/buildings/transistor.js b/src/js/game/buildings/transistor.js index ebcfeac3..1505903a 100644 --- a/src/js/game/buildings/transistor.js +++ b/src/js/game/buildings/transistor.js @@ -22,6 +22,19 @@ export class MetaTransistorBuilding extends MetaBuilding { super("transistor"); } + static getAllVariantCombinations() { + return [ + { + internalId: 38, + variant: defaultBuildingVariant, + }, + { + internalId: 60, + variant: enumTransistorVariants.mirrored, + }, + ]; + } + getSilhouetteColor() { return "#bc3a61"; } diff --git a/src/js/game/buildings/trash.js b/src/js/game/buildings/trash.js index 0ad5bfd7..3085bc55 100644 --- a/src/js/game/buildings/trash.js +++ b/src/js/game/buildings/trash.js @@ -4,7 +4,7 @@ import { ACHIEVEMENTS } from "../../platform/achievement_provider"; import { ItemAcceptorComponent } from "../components/item_acceptor"; import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor"; import { Entity } from "../entity"; -import { MetaBuilding } from "../meta_building"; +import { defaultBuildingVariant, MetaBuilding } from "../meta_building"; import { GameRoot } from "../root"; import { enumHubGoalRewards } from "../tutorial_goals"; @@ -15,6 +15,15 @@ export class MetaTrashBuilding extends MetaBuilding { super("trash"); } + static getAllVariantCombinations() { + return [ + { + internalId: 20, + variant: defaultBuildingVariant, + }, + ]; + } + getIsRotateable() { return false; } diff --git a/src/js/game/buildings/underground_belt.js b/src/js/game/buildings/underground_belt.js index 12e887c9..0f02863f 100644 --- a/src/js/game/buildings/underground_belt.js +++ b/src/js/game/buildings/underground_belt.js @@ -40,6 +40,31 @@ export class MetaUndergroundBeltBuilding extends MetaBuilding { super("underground_belt"); } + static getAllVariantCombinations() { + return [ + { + internalId: 22, + variant: defaultBuildingVariant, + rotationVariant: 0, + }, + { + internalId: 23, + variant: defaultBuildingVariant, + rotationVariant: 1, + }, + { + internalId: 24, + variant: enumUndergroundBeltVariants.tier2, + rotationVariant: 0, + }, + { + internalId: 25, + variant: enumUndergroundBeltVariants.tier2, + rotationVariant: 1, + }, + ]; + } + getSilhouetteColor(variant, rotationVariant) { return colorsByRotationVariant[rotationVariant]; } diff --git a/src/js/game/buildings/virtual_processor.js b/src/js/game/buildings/virtual_processor.js index ab32a0d3..b42ceb5d 100644 --- a/src/js/game/buildings/virtual_processor.js +++ b/src/js/game/buildings/virtual_processor.js @@ -40,6 +40,31 @@ export class MetaVirtualProcessorBuilding extends MetaBuilding { super("virtual_processor"); } + static getAllVariantCombinations() { + return [ + { + internalId: 42, + variant: defaultBuildingVariant, + }, + { + internalId: 44, + variant: enumVirtualProcessorVariants.rotater, + }, + { + internalId: 45, + variant: enumVirtualProcessorVariants.unstacker, + }, + { + internalId: 50, + variant: enumVirtualProcessorVariants.stacker, + }, + { + internalId: 51, + variant: enumVirtualProcessorVariants.painter, + }, + ]; + } + getSilhouetteColor(variant) { return colors[variant]; } diff --git a/src/js/game/buildings/wire.js b/src/js/game/buildings/wire.js index 61b75073..c69dbfa1 100644 --- a/src/js/game/buildings/wire.js +++ b/src/js/game/buildings/wire.js @@ -37,6 +37,51 @@ export class MetaWireBuilding extends MetaBuilding { super("wire"); } + static getAllVariantCombinations() { + return [ + { + internalId: 27, + variant: defaultBuildingVariant, + rotationVariant: 0, + }, + { + internalId: 28, + variant: defaultBuildingVariant, + rotationVariant: 1, + }, + { + internalId: 29, + variant: defaultBuildingVariant, + rotationVariant: 2, + }, + { + internalId: 30, + variant: defaultBuildingVariant, + rotationVariant: 3, + }, + { + internalId: 52, + variant: enumWireVariant.second, + rotationVariant: 0, + }, + { + internalId: 53, + variant: enumWireVariant.second, + rotationVariant: 1, + }, + { + internalId: 54, + variant: enumWireVariant.second, + rotationVariant: 2, + }, + { + internalId: 55, + variant: enumWireVariant.second, + rotationVariant: 3, + }, + ]; + } + getHasDirectionLockAvailable() { return true; } diff --git a/src/js/game/buildings/wire_tunnel.js b/src/js/game/buildings/wire_tunnel.js index 2626dd12..80faa9df 100644 --- a/src/js/game/buildings/wire_tunnel.js +++ b/src/js/game/buildings/wire_tunnel.js @@ -2,7 +2,7 @@ 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 { defaultBuildingVariant, MetaBuilding } from "../meta_building"; import { GameRoot } from "../root"; import { enumHubGoalRewards } from "../tutorial_goals"; @@ -13,6 +13,15 @@ export class MetaWireTunnelBuilding extends MetaBuilding { super("wire_tunnel"); } + static getAllVariantCombinations() { + return [ + { + internalId: 39, + variant: defaultBuildingVariant, + }, + ]; + } + getSilhouetteColor() { return "#777a86"; } diff --git a/src/js/game/meta_building.js b/src/js/game/meta_building.js index 7bfbce25..0e92d3d9 100644 --- a/src/js/game/meta_building.js +++ b/src/js/game/meta_building.js @@ -18,6 +18,16 @@ export class MetaBuilding { this.id = id; } + /** + * Should return all possible variants of this building, no matter + * if they are already available or will be unlocked later on + * + * @returns {Array<{ variant: string, rotationVariant?: number, internalId?: number|string }>} + */ + static getAllVariantCombinations() { + throw new Error("implement getAllVariantCombinations"); + } + /** * Returns the id of this building */ diff --git a/src/js/game/meta_building_registry.js b/src/js/game/meta_building_registry.js index 193d60e5..55bc46d4 100644 --- a/src/js/game/meta_building_registry.js +++ b/src/js/game/meta_building_registry.js @@ -2,202 +2,89 @@ 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 { MetaBalancerBuilding } from "./buildings/balancer"; import { MetaBeltBuilding } from "./buildings/belt"; import { MetaBlockBuilding } from "./buildings/block"; import { MetaComparatorBuilding } from "./buildings/comparator"; import { MetaConstantProducerBuilding } from "./buildings/constant_producer"; import { MetaConstantSignalBuilding } from "./buildings/constant_signal"; -import { enumCutterVariants, MetaCutterBuilding } from "./buildings/cutter"; +import { MetaCutterBuilding } from "./buildings/cutter"; import { MetaDisplayBuilding } from "./buildings/display"; import { MetaFilterBuilding } from "./buildings/filter"; import { MetaGoalAcceptorBuilding } from "./buildings/goal_acceptor"; import { MetaHubBuilding } from "./buildings/hub"; import { MetaItemProducerBuilding } from "./buildings/item_producer"; import { MetaLeverBuilding } from "./buildings/lever"; -import { enumLogicGateVariants, MetaLogicGateBuilding } from "./buildings/logic_gate"; -import { enumMinerVariants, MetaMinerBuilding } from "./buildings/miner"; +import { MetaLogicGateBuilding } from "./buildings/logic_gate"; +import { MetaMinerBuilding } from "./buildings/miner"; import { MetaMixerBuilding } from "./buildings/mixer"; -import { enumPainterVariants, MetaPainterBuilding } from "./buildings/painter"; +import { MetaPainterBuilding } from "./buildings/painter"; import { MetaReaderBuilding } from "./buildings/reader"; -import { enumRotaterVariants, MetaRotaterBuilding } from "./buildings/rotater"; +import { MetaRotaterBuilding } from "./buildings/rotater"; import { MetaStackerBuilding } from "./buildings/stacker"; import { MetaStorageBuilding } from "./buildings/storage"; -import { enumTransistorVariants, MetaTransistorBuilding } from "./buildings/transistor"; +import { MetaTransistorBuilding } from "./buildings/transistor"; import { MetaTrashBuilding } from "./buildings/trash"; -import { enumUndergroundBeltVariants, MetaUndergroundBeltBuilding } from "./buildings/underground_belt"; -import { enumVirtualProcessorVariants, MetaVirtualProcessorBuilding } from "./buildings/virtual_processor"; +import { MetaUndergroundBeltBuilding } from "./buildings/underground_belt"; +import { MetaVirtualProcessorBuilding } from "./buildings/virtual_processor"; import { MetaWireBuilding } from "./buildings/wire"; import { MetaWireTunnelBuilding } from "./buildings/wire_tunnel"; import { buildBuildingCodeCache, gBuildingVariants, registerBuildingVariant } from "./building_codes"; -import { enumWireVariant } from "./components/wire"; import { KEYMAPPINGS } from "./key_action_mapper"; -import { defaultBuildingVariant } from "./meta_building"; +import { defaultBuildingVariant, MetaBuilding } from "./meta_building"; const logger = createLogger("building_registry"); -export function initMetaBuildingRegistry() { - gMetaBuildingRegistry.register(MetaBalancerBuilding); - gMetaBuildingRegistry.register(MetaMinerBuilding); - gMetaBuildingRegistry.register(MetaCutterBuilding); - gMetaBuildingRegistry.register(MetaRotaterBuilding); - gMetaBuildingRegistry.register(MetaStackerBuilding); - gMetaBuildingRegistry.register(MetaMixerBuilding); - gMetaBuildingRegistry.register(MetaPainterBuilding); - gMetaBuildingRegistry.register(MetaTrashBuilding); - gMetaBuildingRegistry.register(MetaStorageBuilding); - gMetaBuildingRegistry.register(MetaBeltBuilding); - gMetaBuildingRegistry.register(MetaUndergroundBeltBuilding); - gMetaBuildingRegistry.register(MetaGoalAcceptorBuilding); - gMetaBuildingRegistry.register(MetaHubBuilding); - gMetaBuildingRegistry.register(MetaWireBuilding); - gMetaBuildingRegistry.register(MetaConstantSignalBuilding); - gMetaBuildingRegistry.register(MetaLogicGateBuilding); - gMetaBuildingRegistry.register(MetaLeverBuilding); - gMetaBuildingRegistry.register(MetaFilterBuilding); - gMetaBuildingRegistry.register(MetaWireTunnelBuilding); - gMetaBuildingRegistry.register(MetaDisplayBuilding); - gMetaBuildingRegistry.register(MetaVirtualProcessorBuilding); - gMetaBuildingRegistry.register(MetaReaderBuilding); - gMetaBuildingRegistry.register(MetaTransistorBuilding); - gMetaBuildingRegistry.register(MetaAnalyzerBuilding); - gMetaBuildingRegistry.register(MetaComparatorBuilding); - gMetaBuildingRegistry.register(MetaItemProducerBuilding); - gMetaBuildingRegistry.register(MetaConstantProducerBuilding); - gMetaBuildingRegistry.register(MetaBlockBuilding); - - // Belt - registerBuildingVariant(1, MetaBeltBuilding, defaultBuildingVariant, 0); - registerBuildingVariant(2, MetaBeltBuilding, defaultBuildingVariant, 1); - registerBuildingVariant(3, MetaBeltBuilding, defaultBuildingVariant, 2); - - // Balancer - registerBuildingVariant(4, MetaBalancerBuilding); - registerBuildingVariant(5, MetaBalancerBuilding, enumBalancerVariants.merger); - registerBuildingVariant(6, MetaBalancerBuilding, enumBalancerVariants.mergerInverse); - registerBuildingVariant(47, MetaBalancerBuilding, enumBalancerVariants.splitter); - registerBuildingVariant(48, MetaBalancerBuilding, enumBalancerVariants.splitterInverse); - - // Miner - registerBuildingVariant(7, MetaMinerBuilding); - registerBuildingVariant(8, MetaMinerBuilding, enumMinerVariants.chainable); - - // Cutter - registerBuildingVariant(9, MetaCutterBuilding); - registerBuildingVariant(10, MetaCutterBuilding, enumCutterVariants.quad); - - // Rotater - registerBuildingVariant(11, MetaRotaterBuilding); - registerBuildingVariant(12, MetaRotaterBuilding, enumRotaterVariants.ccw); - registerBuildingVariant(13, MetaRotaterBuilding, enumRotaterVariants.rotate180); - - // Stacker - registerBuildingVariant(14, MetaStackerBuilding); - - // Mixer - registerBuildingVariant(15, MetaMixerBuilding); - - // Painter - registerBuildingVariant(16, MetaPainterBuilding); - registerBuildingVariant(17, MetaPainterBuilding, enumPainterVariants.mirrored); - registerBuildingVariant(18, MetaPainterBuilding, enumPainterVariants.double); - registerBuildingVariant(19, MetaPainterBuilding, enumPainterVariants.quad); - - // Trash - registerBuildingVariant(20, MetaTrashBuilding); - - // Storage - registerBuildingVariant(21, MetaStorageBuilding); - - // Underground belt - registerBuildingVariant(22, MetaUndergroundBeltBuilding, defaultBuildingVariant, 0); - registerBuildingVariant(23, MetaUndergroundBeltBuilding, defaultBuildingVariant, 1); - registerBuildingVariant(24, MetaUndergroundBeltBuilding, enumUndergroundBeltVariants.tier2, 0); - registerBuildingVariant(25, MetaUndergroundBeltBuilding, enumUndergroundBeltVariants.tier2, 1); - - // Hub - registerBuildingVariant(26, MetaHubBuilding); - - // Wire - registerBuildingVariant(27, MetaWireBuilding, defaultBuildingVariant, 0); - registerBuildingVariant(28, MetaWireBuilding, defaultBuildingVariant, 1); - 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); - - // Constant signal - registerBuildingVariant(31, MetaConstantSignalBuilding); - - // Logic gate - registerBuildingVariant(32, MetaLogicGateBuilding); - registerBuildingVariant(34, MetaLogicGateBuilding, enumLogicGateVariants.not); - registerBuildingVariant(35, MetaLogicGateBuilding, enumLogicGateVariants.xor); - registerBuildingVariant(36, MetaLogicGateBuilding, enumLogicGateVariants.or); - - // Transistor - registerBuildingVariant(38, MetaTransistorBuilding, defaultBuildingVariant); - registerBuildingVariant(60, MetaTransistorBuilding, enumTransistorVariants.mirrored); - - // Lever - registerBuildingVariant(33, MetaLeverBuilding); - - // Filter - registerBuildingVariant(37, MetaFilterBuilding); - - // Wire tunnel - registerBuildingVariant(39, MetaWireTunnelBuilding); - - // Display - registerBuildingVariant(40, MetaDisplayBuilding); - - // Virtual Processor - registerBuildingVariant(42, MetaVirtualProcessorBuilding); - registerBuildingVariant(44, MetaVirtualProcessorBuilding, enumVirtualProcessorVariants.rotater); - registerBuildingVariant(45, MetaVirtualProcessorBuilding, enumVirtualProcessorVariants.unstacker); - registerBuildingVariant(50, MetaVirtualProcessorBuilding, enumVirtualProcessorVariants.stacker); - registerBuildingVariant(51, MetaVirtualProcessorBuilding, enumVirtualProcessorVariants.painter); - - // Analyzer - registerBuildingVariant(46, MetaComparatorBuilding); - registerBuildingVariant(43, MetaAnalyzerBuilding); - - // Reader - registerBuildingVariant(49, MetaReaderBuilding); - - // Item producer - registerBuildingVariant(61, MetaItemProducerBuilding); - - // Constant producer - registerBuildingVariant(62, MetaConstantProducerBuilding); - - // Goal acceptor - registerBuildingVariant(63, MetaGoalAcceptorBuilding); - - // Block - registerBuildingVariant(64, MetaBlockBuilding); - - // Propagate instances - for (const key in gBuildingVariants) { - gBuildingVariants[key].metaInstance = gMetaBuildingRegistry.findByClass( - gBuildingVariants[key].metaClass +/** + * + * @param {typeof MetaBuilding} metaBuilding + */ +export function registerBuildingVariants(metaBuilding) { + gMetaBuildingRegistry.register(metaBuilding); + const combinations = metaBuilding.getAllVariantCombinations(); + combinations.forEach(combination => { + registerBuildingVariant( + combination.internalId, + metaBuilding, + combination.variant || defaultBuildingVariant, + combination.rotationVariant || 0 ); - } + }); +} - for (const key in gBuildingVariants) { - const variant = gBuildingVariants[key]; - assert(variant.metaClass, "Variant has no meta: " + key); +export function initMetaBuildingRegistry() { + const buildings = [ + MetaBalancerBuilding, + MetaMinerBuilding, + MetaCutterBuilding, + MetaRotaterBuilding, + MetaStackerBuilding, + MetaMixerBuilding, + MetaPainterBuilding, + MetaTrashBuilding, + MetaStorageBuilding, + MetaBeltBuilding, + MetaUndergroundBeltBuilding, + MetaGoalAcceptorBuilding, + MetaHubBuilding, + MetaWireBuilding, + MetaConstantSignalBuilding, + MetaLogicGateBuilding, + MetaLeverBuilding, + MetaFilterBuilding, + MetaWireTunnelBuilding, + MetaDisplayBuilding, + MetaVirtualProcessorBuilding, + MetaReaderBuilding, + MetaTransistorBuilding, + MetaAnalyzerBuilding, + MetaComparatorBuilding, + MetaItemProducerBuilding, + MetaConstantProducerBuilding, + MetaBlockBuilding, + ]; - if (typeof variant.rotationVariant === "undefined") { - variant.rotationVariant = 0; - } - if (typeof variant.variant === "undefined") { - variant.variant = defaultBuildingVariant; - } - } + buildings.forEach(registerBuildingVariants); // Check for valid keycodes if (G_IS_DEV) { diff --git a/src/js/mods/mod_interface.js b/src/js/mods/mod_interface.js index eb27df21..f7db8b95 100644 --- a/src/js/mods/mod_interface.js +++ b/src/js/mods/mod_interface.js @@ -24,6 +24,7 @@ import { MOD_CHUNK_DRAW_HOOKS } from "../game/map_chunk_view"; import { KEYMAPPINGS } from "../game/key_action_mapper"; import { HUDModalDialogs } from "../game/hud/parts/modal_dialogs"; import { THEMES } from "../game/theme"; +import { ModMetaBuilding } from "./mod_meta_building"; export class ModInterface { /** @@ -190,54 +191,47 @@ export class ModInterface { /** * * @param {object} param0 - * @param {typeof MetaBuilding} param0.metaClass + * @param {typeof ModMetaBuilding} param0.metaClass * @param {string=} param0.buildingIconBase64 - * @param {({ - * variant?: string; - * rotationVariant?: number; - * name: string; - * description: string; - * blueprintImageBase64?: string; - * regularImageBase64?: string; - * tutorialImageBase64?: string; - * }[])} param0.variantsAndRotations */ - registerNewBuilding({ metaClass, variantsAndRotations, buildingIconBase64 }) { - const id = new /** @type {new () => MetaBuilding} */ (metaClass)().getId(); + registerNewBuilding({ metaClass, buildingIconBase64 }) { + const id = new /** @type {new (...args) => ModMetaBuilding} */ (metaClass)().getId(); if (gMetaBuildingRegistry.hasId(id)) { throw new Error("Tried to register building twice: " + id); } gMetaBuildingRegistry.register(metaClass); const metaInstance = gMetaBuildingRegistry.findByClass(metaClass); - T.buildings[id] = {}; - variantsAndRotations.forEach(payload => { - const actualVariant = payload.variant || defaultBuildingVariant; - registerBuildingVariant(id, metaClass, actualVariant, payload.rotationVariant || 0); + + metaClass.getAllVariantCombinations().forEach(combination => { + const actualVariant = combination.variant || defaultBuildingVariant; + registerBuildingVariant(id, metaClass, actualVariant, combination.rotationVariant || 0); gBuildingVariants[id].metaInstance = metaInstance; T.buildings[id][actualVariant] = { - name: payload.name, - description: payload.description, + name: combination.name || "Name", + description: combination.description || "Description", }; const buildingIdentifier = id + (actualVariant === defaultBuildingVariant ? "" : "-" + actualVariant); - if (payload.regularImageBase64) { + + if (combination.regularImageBase64) { this.registerSprite( "sprites/buildings/" + buildingIdentifier + ".png", - payload.regularImageBase64 + combination.regularImageBase64 ); } - if (payload.blueprintImageBase64) { + + if (combination.blueprintImageBase64) { this.registerSprite( "sprites/blueprints/" + buildingIdentifier + ".png", - payload.blueprintImageBase64 + combination.blueprintImageBase64 ); } - if (payload.tutorialImageBase64) { - this.setBuildingTutorialImage(id, actualVariant, payload.tutorialImageBase64); + if (combination.tutorialImageBase64) { + this.setBuildingTutorialImage(id, actualVariant, combination.tutorialImageBase64); } }); diff --git a/src/js/mods/mod_meta_building.js b/src/js/mods/mod_meta_building.js new file mode 100644 index 00000000..0d8f215a --- /dev/null +++ b/src/js/mods/mod_meta_building.js @@ -0,0 +1,18 @@ +import { MetaBuilding } from "../game/meta_building"; + +export class ModMetaBuilding extends MetaBuilding { + /** + * @returns {({ + * variant: string; + * rotationVariant?: number; + * name: string; + * description: string; + * blueprintImageBase64?: string; + * regularImageBase64?: string; + * tutorialImageBase64?: string; + * }[])} + */ + static getAllVariantCombinations() { + throw new Error("Implement getAllVariantCombinations"); + } +}