diff --git a/res/ui/building_icons/mixer.png b/res/ui/building_icons/mixer.png
index 9c0fd11c..1dd85b9b 100644
Binary files a/res/ui/building_icons/mixer.png and b/res/ui/building_icons/mixer.png differ
diff --git a/res/ui/building_icons/storage.png b/res/ui/building_icons/storage.png
new file mode 100644
index 00000000..5423513d
Binary files /dev/null and b/res/ui/building_icons/storage.png differ
diff --git a/res/ui/building_tutorials/trash-storage.png b/res/ui/building_tutorials/storage.png
similarity index 100%
rename from res/ui/building_tutorials/trash-storage.png
rename to res/ui/building_tutorials/storage.png
diff --git a/res_built/atlas/atlas0_hq.json b/res_built/atlas/atlas0_hq.json
index 50304df8..80dd87ea 100644
--- a/res_built/atlas/atlas0_hq.json
+++ b/res_built/atlas/atlas0_hq.json
@@ -584,7 +584,7 @@
"spriteSourceSize": {"x":13,"y":0,"w":261,"h":144},
"sourceSize": {"w":288,"h":144}
},
-"sprites/blueprints/trash-storage.png":
+"sprites/blueprints/storage.png":
{
"frame": {"x":4,"y":1001,"w":250,"h":288},
"rotated": false,
@@ -992,7 +992,7 @@
"spriteSourceSize": {"x":14,"y":0,"w":260,"h":143},
"sourceSize": {"w":288,"h":144}
},
-"sprites/buildings/trash-storage.png":
+"sprites/buildings/storage.png":
{
"frame": {"x":4,"y":1295,"w":248,"h":288},
"rotated": false,
@@ -1551,6 +1551,6 @@
"format": "RGBA8888",
"size": {"w":2048,"h":2048},
"scale": "0.75",
- "smartupdate": "$TexturePacker:SmartUpdate:c57f50d18c59efc0edbd4a3a732323a4:3fcf23da2ddc6370c437cf41f6d44ed0:908b89f5ca8ff73e331a35a3b14d0604$"
+ "smartupdate": "$TexturePacker:SmartUpdate:5aa559a5b0e7b321ad8bc0595f1e8ec0:3fcf23da2ddc6370c437cf41f6d44ed0:908b89f5ca8ff73e331a35a3b14d0604$"
}
}
diff --git a/res_built/atlas/atlas0_lq.json b/res_built/atlas/atlas0_lq.json
index 6aed36ff..3434f6d8 100644
--- a/res_built/atlas/atlas0_lq.json
+++ b/res_built/atlas/atlas0_lq.json
@@ -584,7 +584,7 @@
"spriteSourceSize": {"x":3,"y":0,"w":89,"h":48},
"sourceSize": {"w":96,"h":48}
},
-"sprites/blueprints/trash-storage.png":
+"sprites/blueprints/storage.png":
{
"frame": {"x":768,"y":112,"w":85,"h":96},
"rotated": false,
@@ -992,7 +992,7 @@
"spriteSourceSize": {"x":4,"y":0,"w":88,"h":48},
"sourceSize": {"w":96,"h":48}
},
-"sprites/buildings/trash-storage.png":
+"sprites/buildings/storage.png":
{
"frame": {"x":859,"y":112,"w":85,"h":96},
"rotated": false,
@@ -1551,6 +1551,6 @@
"format": "RGBA8888",
"size": {"w":1024,"h":1024},
"scale": "0.25",
- "smartupdate": "$TexturePacker:SmartUpdate:c57f50d18c59efc0edbd4a3a732323a4:3fcf23da2ddc6370c437cf41f6d44ed0:908b89f5ca8ff73e331a35a3b14d0604$"
+ "smartupdate": "$TexturePacker:SmartUpdate:5aa559a5b0e7b321ad8bc0595f1e8ec0:3fcf23da2ddc6370c437cf41f6d44ed0:908b89f5ca8ff73e331a35a3b14d0604$"
}
}
diff --git a/res_built/atlas/atlas0_mq.json b/res_built/atlas/atlas0_mq.json
index e9687dbb..8250e51d 100644
--- a/res_built/atlas/atlas0_mq.json
+++ b/res_built/atlas/atlas0_mq.json
@@ -584,7 +584,7 @@
"spriteSourceSize": {"x":8,"y":0,"w":175,"h":96},
"sourceSize": {"w":192,"h":96}
},
-"sprites/blueprints/trash-storage.png":
+"sprites/blueprints/storage.png":
{
"frame": {"x":574,"y":310,"w":167,"h":192},
"rotated": false,
@@ -992,7 +992,7 @@
"spriteSourceSize": {"x":9,"y":0,"w":174,"h":96},
"sourceSize": {"w":192,"h":96}
},
-"sprites/buildings/trash-storage.png":
+"sprites/buildings/storage.png":
{
"frame": {"x":574,"y":508,"w":166,"h":192},
"rotated": false,
@@ -1551,6 +1551,6 @@
"format": "RGBA8888",
"size": {"w":1024,"h":2048},
"scale": "0.5",
- "smartupdate": "$TexturePacker:SmartUpdate:c57f50d18c59efc0edbd4a3a732323a4:3fcf23da2ddc6370c437cf41f6d44ed0:908b89f5ca8ff73e331a35a3b14d0604$"
+ "smartupdate": "$TexturePacker:SmartUpdate:5aa559a5b0e7b321ad8bc0595f1e8ec0:3fcf23da2ddc6370c437cf41f6d44ed0:908b89f5ca8ff73e331a35a3b14d0604$"
}
}
diff --git a/res_raw/sprites/blueprints/trash-storage.png b/res_raw/sprites/blueprints/storage.png
similarity index 100%
rename from res_raw/sprites/blueprints/trash-storage.png
rename to res_raw/sprites/blueprints/storage.png
diff --git a/res_raw/sprites/buildings/trash-storage.png b/res_raw/sprites/buildings/storage.png
similarity index 100%
rename from res_raw/sprites/buildings/trash-storage.png
rename to res_raw/sprites/buildings/storage.png
diff --git a/src/css/icons.scss b/src/css/icons.scss
index 9636059a..46991c78 100644
--- a/src/css/icons.scss
+++ b/src/css/icons.scss
@@ -1,5 +1,5 @@
$buildings: belt, cutter, miner, mixer, painter, rotater, balancer, stacker, trash, underground_belt, wire,
- constant_signal, logic_gate, lever, filter, wire_tunnel, display, virtual_processor, reader;
+ constant_signal, logic_gate, lever, filter, wire_tunnel, display, virtual_processor, reader, storage;
@each $building in $buildings {
[data-icon="building_icons/#{$building}.png"] {
@@ -9,7 +9,7 @@ $buildings: belt, cutter, miner, mixer, painter, rotater, balancer, stacker, tra
$buildingsAndVariants: belt, balancer, balancer-merger, balancer-splitter, underground_belt,
underground_belt-tier2, miner, miner-chainable, cutter, cutter-quad, rotater, rotater-ccw, rotater-fl,
- stacker, mixer, painter, painter-double, painter-quad, trash, trash-storage;
+ stacker, mixer, painter, painter-double, painter-quad, trash, storage;
@each $building in $buildingsAndVariants {
[data-icon="building_tutorials/#{$building}.png"] {
background-image: uiResource("res/ui/building_tutorials/#{$building}.png") !important;
diff --git a/src/js/game/buildings/storage.js b/src/js/game/buildings/storage.js
new file mode 100644
index 00000000..5574e137
--- /dev/null
+++ b/src/js/game/buildings/storage.js
@@ -0,0 +1,101 @@
+import { formatBigNumber } from "../../core/utils";
+import { enumDirection, Vector } from "../../core/vector";
+import { T } from "../../translations";
+import { ItemAcceptorComponent } from "../components/item_acceptor";
+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 { GameRoot } from "../root";
+import { enumHubGoalRewards } from "../tutorial_goals";
+
+const storageSize = 5000;
+
+export class MetaStorageBuilding extends MetaBuilding {
+ constructor() {
+ super("storage");
+ }
+
+ getSilhouetteColor() {
+ return "#bbdf6d";
+ }
+
+ /**
+ * @returns {Array<[string, string]>}
+ */
+ getAdditionalStatistics(root, variant) {
+ return [[T.ingame.buildingPlacement.infoTexts.storage, formatBigNumber(storageSize)]];
+ }
+
+ getDimensions() {
+ return new Vector(2, 2);
+ }
+
+ /**
+ * @param {GameRoot} root
+ */
+ getIsUnlocked(root) {
+ return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_storage);
+ }
+
+ /**
+ * Creates the entity at the given location
+ * @param {Entity} entity
+ */
+ setupEntityComponents(entity) {
+ // Required, since the item processor needs this.
+ entity.addComponent(
+ new ItemEjectorComponent({
+ slots: [
+ {
+ pos: new Vector(0, 0),
+ direction: enumDirection.top,
+ },
+ {
+ pos: new Vector(1, 0),
+ direction: enumDirection.top,
+ },
+ ],
+ })
+ );
+
+ entity.addComponent(
+ new ItemAcceptorComponent({
+ slots: [
+ {
+ pos: new Vector(0, 1),
+ directions: [enumDirection.bottom],
+ },
+ {
+ pos: new Vector(1, 1),
+ directions: [enumDirection.bottom],
+ },
+ ],
+ })
+ );
+
+ entity.addComponent(
+ new StorageComponent({
+ maximumStorage: storageSize,
+ })
+ );
+
+ entity.addComponent(
+ new WiredPinsComponent({
+ slots: [
+ {
+ pos: new Vector(1, 1),
+ direction: enumDirection.right,
+ type: enumPinSlotType.logicalEjector,
+ },
+ {
+ pos: new Vector(0, 1),
+ direction: enumDirection.left,
+ type: enumPinSlotType.logicalEjector,
+ },
+ ],
+ })
+ );
+ }
+}
diff --git a/src/js/game/buildings/trash.js b/src/js/game/buildings/trash.js
index dfd47dfe..ca6018a7 100644
--- a/src/js/game/buildings/trash.js
+++ b/src/js/game/buildings/trash.js
@@ -1,65 +1,26 @@
-import { formatBigNumber } from "../../core/utils";
import { enumDirection, Vector } from "../../core/vector";
-import { T } from "../../translations";
import { ItemAcceptorComponent } from "../components/item_acceptor";
-import { ItemEjectorComponent } from "../components/item_ejector";
import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor";
-import { StorageComponent } from "../components/storage";
-import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
import { Entity } from "../entity";
-import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
+import { MetaBuilding } from "../meta_building";
import { GameRoot } from "../root";
import { enumHubGoalRewards } from "../tutorial_goals";
-/** @enum {string} */
-export const enumTrashVariants = { storage: "storage" };
-
-const trashSize = 5000;
-
export class MetaTrashBuilding extends MetaBuilding {
constructor() {
super("trash");
}
- getIsRotateable(variant) {
- return variant !== defaultBuildingVariant;
+ getIsRotateable() {
+ return false;
}
getSilhouetteColor() {
return "#cd7d86";
}
- /**
- * @param {GameRoot} root
- * @param {string} variant
- * @returns {Array<[string, string]>}
- */
- getAdditionalStatistics(root, variant) {
- if (variant === enumTrashVariants.storage) {
- return [[T.ingame.buildingPlacement.infoTexts.storage, formatBigNumber(trashSize)]];
- }
- return [];
- }
-
- getDimensions(variant) {
- switch (variant) {
- case defaultBuildingVariant:
- return new Vector(1, 1);
- case enumTrashVariants.storage:
- return new Vector(2, 2);
- default:
- assertAlways(false, "Unknown trash variant: " + variant);
- }
- }
-
- /**
- * @param {GameRoot} root
- */
- getAvailableVariants(root) {
- if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_storage)) {
- return [defaultBuildingVariant, enumTrashVariants.storage];
- }
- return super.getAvailableVariants(root);
+ getDimensions() {
+ return new Vector(1, 1);
}
/**
@@ -74,13 +35,6 @@ export class MetaTrashBuilding extends MetaBuilding {
* @param {Entity} entity
*/
setupEntityComponents(entity) {
- // Required, since the item processor needs this.
- entity.addComponent(
- new ItemEjectorComponent({
- slots: [],
- })
- );
-
entity.addComponent(
new ItemAcceptorComponent({
slots: [
@@ -96,99 +50,11 @@ export class MetaTrashBuilding extends MetaBuilding {
],
})
);
- }
-
- /**
- *
- * @param {Entity} entity
- * @param {number} rotationVariant
- * @param {string} variant
- */
- updateVariants(entity, rotationVariant, variant) {
- switch (variant) {
- case defaultBuildingVariant: {
- if (!entity.components.ItemProcessor) {
- entity.addComponent(
- new ItemProcessorComponent({
- inputsPerCharge: 1,
- processorType: enumItemProcessorTypes.trash,
- })
- );
- }
- if (entity.components.Storage) {
- entity.removeComponent(StorageComponent);
- }
- if (entity.components.WiredPins) {
- entity.removeComponent(WiredPinsComponent);
- }
-
- entity.components.ItemAcceptor.setSlots([
- {
- pos: new Vector(0, 0),
- directions: [
- enumDirection.top,
- enumDirection.right,
- enumDirection.bottom,
- enumDirection.left,
- ],
- },
- ]);
- entity.components.ItemEjector.setSlots([]);
- entity.components.ItemProcessor.type = enumItemProcessorTypes.trash;
- break;
- }
- case enumTrashVariants.storage: {
- if (entity.components.ItemProcessor) {
- entity.removeComponent(ItemProcessorComponent);
- }
- if (!entity.components.Storage) {
- entity.addComponent(new StorageComponent({}));
- }
- if (!entity.components.WiredPins) {
- entity.addComponent(
- new WiredPinsComponent({
- slots: [
- {
- pos: new Vector(1, 1),
- direction: enumDirection.right,
- type: enumPinSlotType.logicalEjector,
- },
- {
- pos: new Vector(0, 1),
- direction: enumDirection.left,
- type: enumPinSlotType.logicalEjector,
- },
- ],
- })
- );
- }
-
- entity.components.Storage.maximumStorage = trashSize;
- entity.components.ItemAcceptor.setSlots([
- {
- pos: new Vector(0, 1),
- directions: [enumDirection.bottom],
- },
- {
- pos: new Vector(1, 1),
- directions: [enumDirection.bottom],
- },
- ]);
-
- entity.components.ItemEjector.setSlots([
- {
- pos: new Vector(0, 0),
- direction: enumDirection.top,
- },
- {
- pos: new Vector(1, 0),
- direction: enumDirection.top,
- },
- ]);
- break;
- }
- default:
- assertAlways(false, "Unknown trash variant: " + variant);
- }
+ entity.addComponent(
+ new ItemProcessorComponent({
+ inputsPerCharge: 1,
+ processorType: enumItemProcessorTypes.trash,
+ })
+ );
}
}
diff --git a/src/js/game/hud/parts/buildings_toolbar.js b/src/js/game/hud/parts/buildings_toolbar.js
index 19754436..819a7bbb 100644
--- a/src/js/game/hud/parts/buildings_toolbar.js
+++ b/src/js/game/hud/parts/buildings_toolbar.js
@@ -13,6 +13,7 @@ import { MetaStackerBuilding } from "../../buildings/stacker";
import { MetaTrashBuilding } from "../../buildings/trash";
import { MetaUndergroundBeltBuilding } from "../../buildings/underground_belt";
import { HUDBaseToolbar } from "./base_toolbar";
+import { MetaStorageBuilding } from "../../buildings/storage";
const supportedBuildings = [
MetaBeltBuilding,
@@ -25,6 +26,7 @@ const supportedBuildings = [
MetaMixerBuilding,
MetaPainterBuilding,
MetaTrashBuilding,
+ MetaStorageBuilding,
MetaLeverBuilding,
MetaFilterBuilding,
MetaDisplayBuilding,
diff --git a/src/js/game/key_action_mapper.js b/src/js/game/key_action_mapper.js
index 074c4b84..4e2f4505 100644
--- a/src/js/game/key_action_mapper.js
+++ b/src/js/game/key_action_mapper.js
@@ -54,6 +54,7 @@ export const KEYMAPPINGS = {
mixer: { keyCode: key("8") },
painter: { keyCode: key("9") },
trash: { keyCode: key("0") },
+ storage: { keyCode: key("I") },
lever: { keyCode: key("L") },
filter: { keyCode: key("B") },
@@ -352,6 +353,13 @@ export class KeyActionMapper {
}
this.keybindings[key] = new Keybinding(this, this.root.app, payload);
+
+ if (G_IS_DEV) {
+ // Sanity
+ if (!T.keybindings.mappings[key]) {
+ assertAlways(false, "Keybinding " + key + " has no translation!");
+ }
+ }
}
}
diff --git a/src/js/game/meta_building_registry.js b/src/js/game/meta_building_registry.js
index 4b7095df..d3c0b0ed 100644
--- a/src/js/game/meta_building_registry.js
+++ b/src/js/game/meta_building_registry.js
@@ -9,7 +9,7 @@ import { enumPainterVariants, MetaPainterBuilding } from "./buildings/painter";
import { enumRotaterVariants, MetaRotaterBuilding } from "./buildings/rotater";
import { enumBalancerVariants, MetaBalancerBuilding } from "./buildings/balancer";
import { MetaStackerBuilding } from "./buildings/stacker";
-import { enumTrashVariants, MetaTrashBuilding } from "./buildings/trash";
+import { MetaTrashBuilding } from "./buildings/trash";
import { enumUndergroundBeltVariants, MetaUndergroundBeltBuilding } from "./buildings/underground_belt";
import { MetaWireBuilding } from "./buildings/wire";
import { buildBuildingCodeCache, gBuildingVariants, registerBuildingVariant } from "./building_codes";
@@ -22,6 +22,9 @@ import { MetaWireTunnelBuilding, enumWireTunnelVariants } from "./buildings/wire
import { MetaDisplayBuilding } from "./buildings/display";
import { MetaVirtualProcessorBuilding, enumVirtualProcessorVariants } from "./buildings/virtual_processor";
import { MetaReaderBuilding } from "./buildings/reader";
+import { MetaStorageBuilding } from "./buildings/storage";
+import { KEYMAPPINGS } from "./key_action_mapper";
+import { T } from "../translations";
const logger = createLogger("building_registry");
@@ -34,6 +37,7 @@ export function initMetaBuildingRegistry() {
gMetaBuildingRegistry.register(MetaMixerBuilding);
gMetaBuildingRegistry.register(MetaPainterBuilding);
gMetaBuildingRegistry.register(MetaTrashBuilding);
+ gMetaBuildingRegistry.register(MetaStorageBuilding);
gMetaBuildingRegistry.register(MetaBeltBuilding);
gMetaBuildingRegistry.register(MetaUndergroundBeltBuilding);
gMetaBuildingRegistry.register(MetaHubBuilding);
@@ -86,7 +90,9 @@ export function initMetaBuildingRegistry() {
// Trash
registerBuildingVariant(20, MetaTrashBuilding);
- registerBuildingVariant(21, MetaTrashBuilding, enumTrashVariants.storage);
+
+ // Storage
+ registerBuildingVariant(21, MetaStorageBuilding);
// Underground belt
registerBuildingVariant(22, MetaUndergroundBeltBuilding, defaultBuildingVariant, 0);
@@ -157,6 +163,29 @@ export function initMetaBuildingRegistry() {
}
}
+ // Check for valid keycodes
+ if (G_IS_DEV) {
+ gMetaBuildingRegistry.entries.forEach(metaBuilding => {
+ const id = metaBuilding.getId();
+ if (!["hub"].includes(id)) {
+ if (!KEYMAPPINGS.buildings[id]) {
+ assertAlways(
+ false,
+ "Building " + id + " has no keybinding assigned! Add it to key_action_mapper.js"
+ );
+ }
+
+ if (!T.buildings[id]) {
+ assertAlways(false, "Translation for building " + id + " missing!");
+ }
+
+ if (!T.buildings[id].default) {
+ assertAlways(false, "Translation for building " + id + " missing (default variant)!");
+ }
+ }
+ });
+ }
+
logger.log("Registered", gMetaBuildingRegistry.getNumEntries(), "buildings");
logger.log("Registered", Object.keys(gBuildingVariants).length, "building codes");
}
diff --git a/src/js/game/systems/item_processor.js b/src/js/game/systems/item_processor.js
index 7fc2819b..9775afde 100644
--- a/src/js/game/systems/item_processor.js
+++ b/src/js/game/systems/item_processor.js
@@ -94,6 +94,8 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
for (let j = 0; j < itemsToEject.length; ++j) {
const { item, requiredSlot, preferredSlot } = itemsToEject[j];
+ assert(ejectorComp, "To eject items, the building needs to have an ejector");
+
let slot = null;
if (requiredSlot !== null && requiredSlot !== undefined) {
// We have a slot override, check if that is free
@@ -306,6 +308,10 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
* @param {ProcessorImplementationPayload} payload
*/
process_BALANCER(payload) {
+ assert(
+ payload.entity.components.ItemEjector,
+ "To be a balancer, the building needs to have an ejector"
+ );
const availableSlots = payload.entity.components.ItemEjector.slots.length;
const processorComp = payload.entity.components.ItemProcessor;
diff --git a/src/js/game/tutorial_goals_mappings.js b/src/js/game/tutorial_goals_mappings.js
index aefdb172..98450c74 100644
--- a/src/js/game/tutorial_goals_mappings.js
+++ b/src/js/game/tutorial_goals_mappings.js
@@ -1,20 +1,19 @@
-import { MetaBuilding, defaultBuildingVariant } from "./meta_building";
-import { MetaCutterBuilding, enumCutterVariants } from "./buildings/cutter";
-import { MetaRotaterBuilding, enumRotaterVariants } from "./buildings/rotater";
-import { MetaPainterBuilding, enumPainterVariants } from "./buildings/painter";
+import { T } from "../translations";
+import { enumBalancerVariants, MetaBalancerBuilding } from "./buildings/balancer";
+import { MetaConstantSignalBuilding } from "./buildings/constant_signal";
+import { enumCutterVariants, MetaCutterBuilding } from "./buildings/cutter";
+import { MetaDisplayBuilding } from "./buildings/display";
+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 { MetaStackerBuilding } from "./buildings/stacker";
-import { MetaBalancerBuilding, enumBalancerVariants } from "./buildings/balancer";
-import { MetaUndergroundBeltBuilding, enumUndergroundBeltVariants } from "./buildings/underground_belt";
-import { MetaMinerBuilding, enumMinerVariants } from "./buildings/miner";
-import { MetaTrashBuilding, enumTrashVariants } from "./buildings/trash";
-
+import { MetaStorageBuilding } from "./buildings/storage";
+import { enumUndergroundBeltVariants, MetaUndergroundBeltBuilding } from "./buildings/underground_belt";
+import { defaultBuildingVariant, MetaBuilding } from "./meta_building";
/** @typedef {Array<[typeof MetaBuilding, string]>} TutorialGoalReward */
-
import { enumHubGoalRewards } from "./tutorial_goals";
-import { MetaReaderBuilding } from "./buildings/reader";
-import { MetaDisplayBuilding } from "./buildings/display";
-import { MetaConstantSignalBuilding } from "./buildings/constant_signal";
/**
* Helper method for proper types
@@ -46,7 +45,7 @@ export const enumHubGoalRewardsToContentUnlocked = {
[enumHubGoalRewards.reward_cutter_quad]: typed([[MetaCutterBuilding, enumCutterVariants.quad]]),
[enumHubGoalRewards.reward_painter_double]: typed([[MetaPainterBuilding, enumPainterVariants.double]]),
[enumHubGoalRewards.reward_painter_quad]: typed([[MetaPainterBuilding, enumPainterVariants.quad]]),
- [enumHubGoalRewards.reward_storage]: typed([[MetaTrashBuilding, enumTrashVariants.storage]]),
+ [enumHubGoalRewards.reward_storage]: typed([[MetaStorageBuilding]]),
[enumHubGoalRewards.reward_belt_reader]: typed([[MetaReaderBuilding, defaultBuildingVariant]]),
[enumHubGoalRewards.reward_display]: typed([[MetaDisplayBuilding, defaultBuildingVariant]]),
@@ -54,9 +53,31 @@ export const enumHubGoalRewardsToContentUnlocked = {
[MetaConstantSignalBuilding, defaultBuildingVariant],
]),
[enumHubGoalRewards.reward_second_wire]: null, // @TODO!
+ [enumHubGoalRewards.reward_logic_gates]: null, // @TODO!
+ [enumHubGoalRewards.reward_virtual_processing]: null, // @TODO!
[enumHubGoalRewards.reward_wires_filters_and_levers]: null,
[enumHubGoalRewards.reward_freeplay]: null,
+ [enumHubGoalRewards.reward_blueprints]: null,
[enumHubGoalRewards.no_reward]: null,
[enumHubGoalRewards.no_reward_freeplay]: null,
};
+
+if (G_IS_DEV) {
+ // Sanity check
+ for (const rewardId in enumHubGoalRewards) {
+ const mapping = enumHubGoalRewardsToContentUnlocked[rewardId];
+
+ if (typeof mapping === "undefined") {
+ assertAlways(
+ false,
+ "Please define a mapping for the reward " + rewardId + " in tutorial_goals_mappings.js"
+ );
+ }
+
+ const translation = T.storyRewards[rewardId];
+ if (!translation || !translation.title || !translation.desc) {
+ assertAlways(false, "Translation for reward " + rewardId + "missing");
+ }
+ }
+}
diff --git a/src/js/savegame/schemas/1006.js b/src/js/savegame/schemas/1006.js
index 422814c1..e6b2e263 100644
--- a/src/js/savegame/schemas/1006.js
+++ b/src/js/savegame/schemas/1006.js
@@ -1,5 +1,6 @@
import { gMetaBuildingRegistry } from "../../core/global_registries.js";
import { createLogger } from "../../core/logging.js";
+import { enumBalancerVariants, MetaBalancerBuilding } from "../../game/buildings/balancer.js";
import { MetaBeltBuilding } from "../../game/buildings/belt.js";
import { enumCutterVariants, MetaCutterBuilding } from "../../game/buildings/cutter.js";
import { MetaHubBuilding } from "../../game/buildings/hub.js";
@@ -7,9 +8,9 @@ import { enumMinerVariants, MetaMinerBuilding } from "../../game/buildings/miner
import { MetaMixerBuilding } from "../../game/buildings/mixer.js";
import { enumPainterVariants, MetaPainterBuilding } from "../../game/buildings/painter.js";
import { enumRotaterVariants, MetaRotaterBuilding } from "../../game/buildings/rotater.js";
-import { enumBalancerVariants, MetaBalancerBuilding } from "../../game/buildings/balancer.js";
import { MetaStackerBuilding } from "../../game/buildings/stacker.js";
-import { enumTrashVariants, MetaTrashBuilding } from "../../game/buildings/trash.js";
+import { MetaStorageBuilding } from "../../game/buildings/storage.js";
+import { MetaTrashBuilding } from "../../game/buildings/trash.js";
import {
enumUndergroundBeltVariants,
MetaUndergroundBeltBuilding,
@@ -126,9 +127,11 @@ export class SavegameInterface_V1006 extends SavegameInterface_V1005 {
),
"sprites/blueprints/painter-quad.png": findCode(MetaPainterBuilding, enumPainterVariants.quad),
- // Trash / Storage
+ // Trash
"sprites/blueprints/trash.png": findCode(MetaTrashBuilding),
- "sprites/blueprints/trash-storage.png": findCode(MetaTrashBuilding, enumTrashVariants.storage),
+
+ // Storage
+ "sprites/blueprints/trash-storage.png": findCode(MetaStorageBuilding),
};
}
diff --git a/translations/base-en.yaml b/translations/base-en.yaml
index 6dd958be..f950c3c3 100644
--- a/translations/base-en.yaml
+++ b/translations/base-en.yaml
@@ -557,8 +557,9 @@ buildings:
name: &trash Trash
description: Accepts inputs from all sides and destroys them. Forever.
- storage:
- name: Storage
+ storage:
+ default:
+ name: &storage Storage
description: Stores excess items, up to a given capacity. Can be used as an overflow gate.
wire:
@@ -726,7 +727,9 @@ storyRewards:
reward_storage:
title: Storage Buffer
- desc: You have unlocked a variant of the trash - It allows you to store items up to a given capacity!
+ desc: >-
+ You have unlocked the storage building - It allows you to store items up to a given capacity!
+ It priorities the left output, so you can also use it as an overflow gate!
reward_blueprints:
title: Blueprints
@@ -1030,6 +1033,7 @@ keybindings:
mixer: *mixer
painter: *painter
trash: *trash
+ storage: *storage
wire: *wire
constant_signal: *constant_signal
logic_gate: *logic_gate
@@ -1038,6 +1042,7 @@ keybindings:
wire_tunnel: *wire_tunnel
display: *display
reader: *reader
+ virtual_processor: *virtual_processor
# ---
pipette: Pipette