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 { MetaMixerBuilding } from "./buildings/mixer"; -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"; - -/** @typedef {Array<[typeof MetaBuilding, string]>} TutorialGoalReward */ - -import { enumHubGoalRewards } from "./tutorial_goals"; -import { MetaReaderBuilding } from "./buildings/reader"; -import { MetaDisplayBuilding } from "./buildings/display"; +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 { 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"; /** * 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