From 83a4928be55e41151c7fec2aa2c89b8f5202e747 Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Tue, 16 Jun 2020 16:02:29 -0400 Subject: [PATCH 01/51] Make miners cache mined item Saves two chunk+tile lookups per update, and one chunk+tile lookup per draw. --- src/js/game/buildings/miner.js | 10 ++++++++-- src/js/game/components/miner.js | 11 ++++++++++- src/js/game/systems/miner.js | 33 ++++++++------------------------- 3 files changed, 26 insertions(+), 28 deletions(-) diff --git a/src/js/game/buildings/miner.js b/src/js/game/buildings/miner.js index ed87bc85..2baf3fd4 100644 --- a/src/js/game/buildings/miner.js +++ b/src/js/game/buildings/miner.js @@ -44,9 +44,15 @@ export class MetaMinerBuilding extends MetaBuilding { /** * Creates the entity at the given location * @param {Entity} entity + * @param {GameRoot} root */ - setupEntityComponents(entity) { - entity.addComponent(new MinerComponent({})); + setupEntityComponents(entity, root) { + let itemBelow = null; + if (root) { + const staticComp = entity.components.StaticMapEntity; + itemBelow = root.map.getLowerLayerContentXY(staticComp.origin.x, staticComp.origin.y); + } + entity.addComponent(new MinerComponent({ minedItem: itemBelow })); entity.addComponent( new ItemEjectorComponent({ slots: [{ pos: new Vector(0, 0), direction: enumDirection.top }], diff --git a/src/js/game/components/miner.js b/src/js/game/components/miner.js index 57de7e2f..7a4d77dd 100644 --- a/src/js/game/components/miner.js +++ b/src/js/game/components/miner.js @@ -15,6 +15,7 @@ export class MinerComponent extends Component { return { lastMiningTime: types.ufloat, chainable: types.bool, + minedItem: types.nullable(types.obj(gItemRegistry)), itemChainBuffer: types.array(types.obj(gItemRegistry)), }; } @@ -22,12 +23,15 @@ export class MinerComponent extends Component { duplicateWithoutContents() { return new MinerComponent({ chainable: this.chainable, + minedItem: this.minedItem }); } /** + * + * @param {{chainable?: boolean, minedItem?: BaseItem}} param0 */ - constructor({ chainable = false }) { + constructor({ chainable = false, minedItem = null }) { super(); this.lastMiningTime = 0; this.chainable = chainable; @@ -38,6 +42,11 @@ export class MinerComponent extends Component { * @type {Array} */ this.itemChainBuffer = []; + + /** + * @type {BaseItem} + */ + this.minedItem = minedItem; } /** diff --git a/src/js/game/systems/miner.js b/src/js/game/systems/miner.js index 78223516..41786603 100644 --- a/src/js/game/systems/miner.js +++ b/src/js/game/systems/miner.js @@ -24,10 +24,8 @@ export class MinerSystem extends GameSystemWithFilter { // Check if miner is above an actual tile const minerComp = entity.components.Miner; - const staticComp = entity.components.StaticMapEntity; - const tileBelow = this.root.map.getLowerLayerContentXY(staticComp.origin.x, staticComp.origin.y); - if (!tileBelow) { + if (!minerComp.minedItem) { continue; } @@ -40,20 +38,9 @@ export class MinerSystem extends GameSystemWithFilter { } if (this.root.time.isIngameTimerExpired(minerComp.lastMiningTime, 1 / miningSpeed)) { - const lowerLayerItem = this.root.map.getLowerLayerContentXY( - staticComp.origin.x, - staticComp.origin.y - ); - - // TODO: Should not be required actually - if (!lowerLayerItem) { - // Nothing below; - continue; - } - - if (this.tryPerformMinerEject(entity, lowerLayerItem)) { + if (this.tryPerformMinerEject(entity, minerComp.minedItem)) { // Analytics hook - this.root.signals.itemProduced.dispatch(lowerLayerItem); + this.root.signals.itemProduced.dispatch(minerComp.minedItem); // Actually mine minerComp.lastMiningTime = this.root.time.now(); @@ -114,18 +101,14 @@ export class MinerSystem extends GameSystemWithFilter { if (entity && entity.components.Miner) { const staticComp = entity.components.StaticMapEntity; + const minerComp = entity.components.Miner; if (!staticComp.shouldBeDrawn(parameters)) { continue; } - const lowerLayerItem = this.root.map.getLowerLayerContentXY( - staticComp.origin.x, - staticComp.origin.y - ); - - if (lowerLayerItem) { + if (minerComp.minedItem) { const padding = 3; - parameters.context.fillStyle = lowerLayerItem.getBackgroundColorAsResource(); + parameters.context.fillStyle = minerComp.minedItem.getBackgroundColorAsResource(); parameters.context.fillRect( staticComp.origin.x * globalConfig.tileSize + padding, staticComp.origin.y * globalConfig.tileSize + padding, @@ -134,8 +117,8 @@ export class MinerSystem extends GameSystemWithFilter { ); } - if (lowerLayerItem) { - lowerLayerItem.draw( + if (minerComp.minedItem) { + minerComp.minedItem.draw( (0.5 + staticComp.origin.x) * globalConfig.tileSize, (0.5 + staticComp.origin.y) * globalConfig.tileSize, parameters From d4fc2e6dcde2239d86a609756273b53e2b52d437 Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Tue, 16 Jun 2020 16:21:45 -0400 Subject: [PATCH 02/51] Fix lint errors --- src/js/game/components/miner.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/js/game/components/miner.js b/src/js/game/components/miner.js index 7a4d77dd..ae64223a 100644 --- a/src/js/game/components/miner.js +++ b/src/js/game/components/miner.js @@ -23,13 +23,12 @@ export class MinerComponent extends Component { duplicateWithoutContents() { return new MinerComponent({ chainable: this.chainable, - minedItem: this.minedItem + minedItem: this.minedItem, }); } /** - * - * @param {{chainable?: boolean, minedItem?: BaseItem}} param0 + * @param {{chainable?: boolean, minedItem?: BaseItem}} param0 */ constructor({ chainable = false, minedItem = null }) { super(); From 7f3221640445cde5a853f71665c3233717d087fd Mon Sep 17 00:00:00 2001 From: dengr1065 Date: Wed, 17 Jun 2020 02:20:09 +0300 Subject: [PATCH 03/51] Main Menu dark theme --- src/css/states/main_menu.scss | 40 +++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/css/states/main_menu.scss b/src/css/states/main_menu.scss index a10390b8..f2cf120e 100644 --- a/src/css/states/main_menu.scss +++ b/src/css/states/main_menu.scss @@ -401,4 +401,44 @@ } } } + + @include DarkThemeOverride { + background: #53565e center center / cover !important; + + .topButtons { + filter: invert(1); + + .languageChoose { + filter: invert(1); + } + } + + .mainContainer { + background: #4b4c50; + + .savegames .savegame { + background: #62646a; + color: white; + } + } + + .footer { + > a { + background: #4b4c50; + color: #eee; + } + + .author { + color: #bdbdbd; + + > a { + color: white; + } + } + + .thirdpartyLogo.githubLogo { + filter: invert(1); + } + } + } } From 97c52169daef3161c6980091aeec2c6f309e6082 Mon Sep 17 00:00:00 2001 From: dengr1065 Date: Wed, 17 Jun 2020 02:55:13 +0300 Subject: [PATCH 04/51] Changelog, support for dark theme in document root --- src/css/common.scss | 4 ++++ src/css/mixins.scss | 2 +- src/css/textual_game_state.scss | 17 +++++++++++++++++ src/js/profile/application_settings.js | 2 +- 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/css/common.scss b/src/css/common.scss index 22b39cb9..0c1cbae4 100644 --- a/src/css/common.scss +++ b/src/css/common.scss @@ -38,6 +38,10 @@ html { right: 0; background: #dee1ea; + + @include DarkThemeOverride { + background: #5c606c; + } } body { diff --git a/src/css/mixins.scss b/src/css/mixins.scss index dc5eeb86..ee0a9752 100644 --- a/src/css/mixins.scss +++ b/src/css/mixins.scss @@ -350,7 +350,7 @@ button, } @mixin DarkThemeOverride { - @at-root body[data-theme="dark"] &, + @at-root html[data-theme="dark"] &, &[data-theme="dark"] { @content; } diff --git a/src/css/textual_game_state.scss b/src/css/textual_game_state.scss index 897c379a..1f9dc356 100644 --- a/src/css/textual_game_state.scss +++ b/src/css/textual_game_state.scss @@ -61,4 +61,21 @@ } } } + + @include DarkThemeOverride { + .headerBar { + h1 { + color: #cfceca; + } + + .backButton { + filter: invert(1); + } + } + + > .container > .content { + background: #4b4c50; + color: #eee; + } + } } diff --git a/src/js/profile/application_settings.js b/src/js/profile/application_settings.js index df2cddda..005e3c0a 100644 --- a/src/js/profile/application_settings.js +++ b/src/js/profile/application_settings.js @@ -160,7 +160,7 @@ export const allApplicationSettings = [ */ (app, id) => { applyGameTheme(id); - document.body.setAttribute("data-theme", id); + document.documentElement.setAttribute("data-theme", id); }, enabled: !IS_DEMO, }), From 1bee130dfe1afed02c54ddc9a74cc2518b300f93 Mon Sep 17 00:00:00 2001 From: dengr1065 Date: Wed, 17 Jun 2020 03:19:22 +0300 Subject: [PATCH 05/51] Dark theme for settings --- src/css/states/settings.scss | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/css/states/settings.scss b/src/css/states/settings.scss index e52152c3..6c3df736 100644 --- a/src/css/states/settings.scss +++ b/src/css/states/settings.scss @@ -88,4 +88,26 @@ } } } + + @include DarkThemeOverride { + .content { + .setting { + background: #424345; + + .value.enum { + // dirty but works + filter: invert(0.8); + color: #222; + } + + .value.checkbox { + background-color: #74767b; + + &.checked { + background-color: #605b7d; + } + } + } + } + } } From b9e31049b6fcdc90e58b54b20d9daed52741ae6a Mon Sep 17 00:00:00 2001 From: dengr1065 Date: Wed, 17 Jun 2020 03:49:50 +0300 Subject: [PATCH 06/51] "Dark keybindings" --- src/css/states/keybindings.scss | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/css/states/keybindings.scss b/src/css/states/keybindings.scss index f5ee3170..cf211403 100644 --- a/src/css/states/keybindings.scss +++ b/src/css/states/keybindings.scss @@ -51,4 +51,21 @@ } } } + + @include DarkThemeOverride { + .content { + .hint { + background: #3b3d40; + } + + .category .entry { + color: #c0c4c8; + border-bottom-color: #888; + + button { + filter: invert(1); + } + } + } + } } From 59bae80ab72a1ea618ec129ed04416f79c54646a Mon Sep 17 00:00:00 2001 From: dengr1065 Date: Wed, 17 Jun 2020 04:30:01 +0300 Subject: [PATCH 07/51] dark theme for option chooser dialogs --- src/css/ingame_hud/dialogs.scss | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/css/ingame_hud/dialogs.scss b/src/css/ingame_hud/dialogs.scss index 366ab8ce..cd681a9e 100644 --- a/src/css/ingame_hud/dialogs.scss +++ b/src/css/ingame_hud/dialogs.scss @@ -32,6 +32,21 @@ background-color: rgba(#33363d, 0.9); } } + + > .dialogInner.optionChooserDialog .optionParent { + .option { + background: #3d3f42; + + &:hover { + background-color: #424348; + } + + &.active { + background: $colorBlueBright; + color: #fff; + } + } + } } &.visible { From 05ce8ff4304a3615710d52a10bfed97bdc77b513 Mon Sep 17 00:00:00 2001 From: dengr1065 Date: Wed, 17 Jun 2020 04:39:08 +0300 Subject: [PATCH 08/51] dark theme for game loading --- src/css/common.scss | 4 ++++ src/css/states/ingame.scss | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/src/css/common.scss b/src/css/common.scss index 0c1cbae4..f616eace 100644 --- a/src/css/common.scss +++ b/src/css/common.scss @@ -417,6 +417,10 @@ canvas { display: inline-block; vertical-align: middle; } + + @include DarkThemeOverride { + color: #fff; + } } .prefab_LoadingTextWithAnimDelayed { diff --git a/src/css/states/ingame.scss b/src/css/states/ingame.scss index 8b0a614c..614cdf6a 100644 --- a/src/css/states/ingame.scss +++ b/src/css/states/ingame.scss @@ -28,4 +28,10 @@ right: 0; bottom: 0; } + + @include DarkThemeOverride { + .gameLoadingOverlay { + background: #56565c; + } + } } From 7ec53506def01769222d3d95331ac14a4386a14a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pascal=20Gross=C3=A9?= Date: Wed, 17 Jun 2020 15:17:09 +0200 Subject: [PATCH 09/51] Updated the french translation --- translations/base-fr.yaml | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/translations/base-fr.yaml b/translations/base-fr.yaml index 836d53ef..149b96b4 100644 --- a/translations/base-fr.yaml +++ b/translations/base-fr.yaml @@ -154,9 +154,9 @@ mainMenu: showInfo: Voir contestOver: Ce concours est terminé - Rejoignez le serveur discord pour être tenu au courant des prochains concours ! - continue: Continue - newGame: New Game - madeBy: Made by + continue: Continuer + newGame: Nouvelle partie + madeBy: Écrit par dialogs: buttons: @@ -275,7 +275,7 @@ ingame: # every situation keybindingsOverlay: moveMap: Déplacer - selectBuildings: Sélection de la zone + selectBuildings: Sélection d'une zone stopPlacement: Arrêter le placement rotateBuilding: Tourner le bâtiment placeMultiple: Placement multiple @@ -286,8 +286,8 @@ ingame: createMarker: Créer une balise delete: Supprimer pasteLastBlueprint: Copier le dernier patron - lockBeltDirection: Enable belt planner - plannerSwitchSide: Flip planner side + lockBeltDirection: Utiliser le plannificateur de convoyeurs + plannerSwitchSide: Échanger la direction du plannificateur # Everything related to placing buildings (I.e. as soon as you selected a building # from the toolbar) @@ -682,15 +682,14 @@ settings: super_fast: Très rapide extremely_fast: Extrêmement rapide enableTunnelSmartplace: - title: Smart Tunnels + title: Tunnels intelligents description: >- - When enabled, placing tunnels will automatically remove unnecessary belts. - This also enables to drag tunnels and excess tunnels will get removed. + Si cette option est sélectionnée, placer des tunnels effacera automatiquement les convoyeurs inutiles. + Cela permet aussi d'étirer les tunnels et les tunnels en surnombre seront effacés. vignette: - title: Vignette + title: Effet de vignette description: >- - Enables the vignette which darkens the screen corners and makes text easier - to read. + Permet l'affichage de l'effet de vignette qui assombrit les coins de l'écran afin de rendre le texte plus facile à lire. keybindings: title: Contrôles @@ -756,8 +755,8 @@ keybindings: massSelectCut: Couper la sélection exportScreenshot: Exporter toute la base en tant qu'image. mapMoveFaster: Se déplacer plus vite - lockBeltDirection: Enable belt planner - switchDirectionLockSide: 'Planner: Switch side' + lockBeltDirection: Utiliser le plannificateur de convoyeurs + switchDirectionLockSide: 'Plannificateur: changer de côté' about: title: À propos de ce jeu From a5e5cd9e4f59b69b0ce0e99ff12b6305625c5946 Mon Sep 17 00:00:00 2001 From: xSparfuchs Date: Wed, 17 Jun 2020 19:44:53 +0200 Subject: [PATCH 10/51] fix large screenshots --- src/js/game/hud/parts/screenshot_exporter.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/js/game/hud/parts/screenshot_exporter.js b/src/js/game/hud/parts/screenshot_exporter.js index dfdd8224..fe1a52df 100644 --- a/src/js/game/hud/parts/screenshot_exporter.js +++ b/src/js/game/hud/parts/screenshot_exporter.js @@ -55,8 +55,18 @@ export class HUDScreenshotExporter extends BaseHUDPart { const dimensions = maxChunk.sub(minChunk); logger.log("Dimensions:", dimensions); - - const chunkSizePixels = 128; + + let chunkSizePixels = 128; + + if (dimensions.x + dimensions.y > 256) { + if (dimensions.x > dimensions.y) { + chunkSizePixels = Math.floor(128 * (128 / dimensions.x)); + }else{ + chunkSizePixels = Math.floor(128 * (128 / dimensions.y)); + } + logger.log("ChunkSizePixels:", chunkSizePixels); + } + const chunkScale = chunkSizePixels / (globalConfig.mapChunkSize * globalConfig.tileSize); logger.log("Scale:", chunkScale); From c1ef4e85af41d15d43f309c5454f1e42026d7fce Mon Sep 17 00:00:00 2001 From: xSparfuchs Date: Wed, 17 Jun 2020 20:11:55 +0200 Subject: [PATCH 11/51] whitespaces --- src/js/game/hud/parts/screenshot_exporter.js | 24 ++++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/js/game/hud/parts/screenshot_exporter.js b/src/js/game/hud/parts/screenshot_exporter.js index fe1a52df..4bd4865e 100644 --- a/src/js/game/hud/parts/screenshot_exporter.js +++ b/src/js/game/hud/parts/screenshot_exporter.js @@ -55,18 +55,18 @@ export class HUDScreenshotExporter extends BaseHUDPart { const dimensions = maxChunk.sub(minChunk); logger.log("Dimensions:", dimensions); - - let chunkSizePixels = 128; - - if (dimensions.x + dimensions.y > 256) { - if (dimensions.x > dimensions.y) { - chunkSizePixels = Math.floor(128 * (128 / dimensions.x)); - }else{ - chunkSizePixels = Math.floor(128 * (128 / dimensions.y)); - } - logger.log("ChunkSizePixels:", chunkSizePixels); - } - + + let chunkSizePixels = 128; + + if (dimensions.x + dimensions.y > 256) { + if (dimensions.x > dimensions.y) { + chunkSizePixels = Math.floor(128 * (128 / dimensions.x)); + }else{ + chunkSizePixels = Math.floor(128 * (128 / dimensions.y)); + } + logger.log("ChunkSizePixels:", chunkSizePixels); + } + const chunkScale = chunkSizePixels / (globalConfig.mapChunkSize * globalConfig.tileSize); logger.log("Scale:", chunkScale); From 8372293d5d653800ab7dd20198932e5432b7be78 Mon Sep 17 00:00:00 2001 From: xSparfuchs Date: Wed, 17 Jun 2020 20:16:37 +0200 Subject: [PATCH 12/51] Update screenshot_exporter.js --- src/js/game/hud/parts/screenshot_exporter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/game/hud/parts/screenshot_exporter.js b/src/js/game/hud/parts/screenshot_exporter.js index 4bd4865e..41f506a1 100644 --- a/src/js/game/hud/parts/screenshot_exporter.js +++ b/src/js/game/hud/parts/screenshot_exporter.js @@ -61,7 +61,7 @@ export class HUDScreenshotExporter extends BaseHUDPart { if (dimensions.x + dimensions.y > 256) { if (dimensions.x > dimensions.y) { chunkSizePixels = Math.floor(128 * (128 / dimensions.x)); - }else{ + } else { chunkSizePixels = Math.floor(128 * (128 / dimensions.y)); } logger.log("ChunkSizePixels:", chunkSizePixels); From e63638f364f2d4173c76f71a5d4965f61a44a647 Mon Sep 17 00:00:00 2001 From: xSparfuchs Date: Wed, 17 Jun 2020 20:17:23 +0200 Subject: [PATCH 13/51] Update screenshot_exporter.js --- src/js/game/hud/parts/screenshot_exporter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/game/hud/parts/screenshot_exporter.js b/src/js/game/hud/parts/screenshot_exporter.js index 41f506a1..528bc485 100644 --- a/src/js/game/hud/parts/screenshot_exporter.js +++ b/src/js/game/hud/parts/screenshot_exporter.js @@ -64,7 +64,7 @@ export class HUDScreenshotExporter extends BaseHUDPart { } else { chunkSizePixels = Math.floor(128 * (128 / dimensions.y)); } - logger.log("ChunkSizePixels:", chunkSizePixels); + logger.log("ChunkSizePixels:", chunkSizePixels); } const chunkScale = chunkSizePixels / (globalConfig.mapChunkSize * globalConfig.tileSize); From 1b85c32b3b8e1d3efbc1df1d1caeb17147039d31 Mon Sep 17 00:00:00 2001 From: xSparfuchs Date: Wed, 17 Jun 2020 20:31:39 +0200 Subject: [PATCH 14/51] prettier --- src/js/game/hud/parts/screenshot_exporter.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/js/game/hud/parts/screenshot_exporter.js b/src/js/game/hud/parts/screenshot_exporter.js index 528bc485..2b72dd7b 100644 --- a/src/js/game/hud/parts/screenshot_exporter.js +++ b/src/js/game/hud/parts/screenshot_exporter.js @@ -57,15 +57,12 @@ export class HUDScreenshotExporter extends BaseHUDPart { logger.log("Dimensions:", dimensions); let chunkSizePixels = 128; - - if (dimensions.x + dimensions.y > 256) { - if (dimensions.x > dimensions.y) { - chunkSizePixels = Math.floor(128 * (128 / dimensions.x)); - } else { - chunkSizePixels = Math.floor(128 * (128 / dimensions.y)); - } - logger.log("ChunkSizePixels:", chunkSizePixels); + const maxDimensions = Math.max(dimensions.x, dimensions.y); + + if (maxDimensions > 128) { + chunkSizePixels = Math.floor(128 * (128 / Math.max(dimensions.x, dimensions.y))); } + logger.log("ChunkSizePixels:", chunkSizePixels); const chunkScale = chunkSizePixels / (globalConfig.mapChunkSize * globalConfig.tileSize); logger.log("Scale:", chunkScale); From 889e22ea69942b31040d816f0cb57270f0353ff9 Mon Sep 17 00:00:00 2001 From: xSparfuchs Date: Wed, 17 Jun 2020 20:33:20 +0200 Subject: [PATCH 15/51] Update screenshot_exporter.js --- src/js/game/hud/parts/screenshot_exporter.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/js/game/hud/parts/screenshot_exporter.js b/src/js/game/hud/parts/screenshot_exporter.js index 2b72dd7b..7d388087 100644 --- a/src/js/game/hud/parts/screenshot_exporter.js +++ b/src/js/game/hud/parts/screenshot_exporter.js @@ -58,9 +58,9 @@ export class HUDScreenshotExporter extends BaseHUDPart { let chunkSizePixels = 128; const maxDimensions = Math.max(dimensions.x, dimensions.y); - + if (maxDimensions > 128) { - chunkSizePixels = Math.floor(128 * (128 / Math.max(dimensions.x, dimensions.y))); + chunkSizePixels = Math.floor(128 * (128 / maxDimensions)); } logger.log("ChunkSizePixels:", chunkSizePixels); From 8d21c1dfafde61d622e2c3ce9e8ad7d59acbacee Mon Sep 17 00:00:00 2001 From: xSparfuchs Date: Wed, 17 Jun 2020 20:38:11 +0200 Subject: [PATCH 16/51] fine --- src/js/game/hud/parts/screenshot_exporter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/game/hud/parts/screenshot_exporter.js b/src/js/game/hud/parts/screenshot_exporter.js index 7d388087..6b1ad67b 100644 --- a/src/js/game/hud/parts/screenshot_exporter.js +++ b/src/js/game/hud/parts/screenshot_exporter.js @@ -60,7 +60,7 @@ export class HUDScreenshotExporter extends BaseHUDPart { const maxDimensions = Math.max(dimensions.x, dimensions.y); if (maxDimensions > 128) { - chunkSizePixels = Math.floor(128 * (128 / maxDimensions)); + chunkSizePixels = Math.floor(128 * (128 / maxDimensions)); } logger.log("ChunkSizePixels:", chunkSizePixels); From ea29384b6b2859a47c9ded79426b0209047edf52 Mon Sep 17 00:00:00 2001 From: DerFeldspatz <57270769+DerFeldspatz@users.noreply.github.com> Date: Wed, 17 Jun 2020 20:50:55 +0200 Subject: [PATCH 17/51] Update base-de.yaml Update translation to recent version. Minor typo/grammar --- translations/base-de.yaml | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/translations/base-de.yaml b/translations/base-de.yaml index d1f53b57..73efe45c 100644 --- a/translations/base-de.yaml +++ b/translations/base-de.yaml @@ -239,7 +239,7 @@ dialogs: blueprintsNotUnlocked: title: Noch nicht freigeschaltet desc: >- - Blueprints werden erst in Level 12 freigeschalten! + Blueprints werden erst in Level 12 freigeschaltet! keybindingsIntroduction: title: Nützliche Hotkeys @@ -282,15 +282,15 @@ ingame: createMarker: Marker erstellen delete: Löschen pasteLastBlueprint: Letzte Blaupause einfügen - lockBeltDirection: Enable belt planner - plannerSwitchSide: Flip planner side + lockBeltDirection: Bandplaner aktivieren + plannerSwitchSide: 'Planer: Seite wechseln' # Everything related to placing buildings (I.e. as soon as you selected a building # from the toolbar) buildingPlacement: # Buildings can have different variants which are unlocked at later levels, # and this is the hint shown when there are multiple variants available. - cycleBuildingVariants: Drücke um zwischen den Varianten zu wählen. + cycleBuildingVariants: Drücke , um zwischen den Varianten zu wählen. # Shows the hotkey in the ui, e.g. "Hotkey: Q" hotkeyLabel: >- @@ -538,7 +538,7 @@ storyRewards: desc: Der Tunnel wurde freigeschaltet! Du kannst Items nun unter Gebäuden oder Förderbändern hindurchleiten! reward_rotater_ccw: - title: gUZS Rotieren + title: Gegen UZS Rotieren desc: Du hast eine zweite Variante des Rotierers freigeschaltet! Damit können Items gegen den Uhrzeigensinn gedreht werden. Wähle den Rotierer aus und drücke 'T', um auf verschiedene Varianten zuzugreifen! reward_miner_chainable: @@ -678,20 +678,20 @@ settings: super_fast: Sehr schnell extremely_fast: Extrem schnell enableTunnelSmartplace: - title: Smart Tunnels + title: Intelligente Tunnel description: >- - When enabled, placing tunnels will automatically remove unnecessary belts. - This also enables to drag tunnels and excess tunnels will get removed. + Aktiviert das automatische Entfernen von überflüssigen Förderbändern bei der Platzierung von Tunneln. + Außerdem funktioniert das Ziehen von Tunneln und überschüssige werden ebenfalls entfernt. vignette: title: Vignette description: >- - Enables the vignette which darkens the screen corners and makes text easier - to read. + Aktiviert den Vignetteneffekt, der den Rand des Bildschirms zunehmend verdunkelt + und das Lesen der Textfelder vereinfacht. keybindings: title: Tastenbelegung hint: >- - Tipp: Benutze STRG, UMSCH and ALT! Sie aktivieren verschiedene Platzierungsoptionen! + Tipp: Benutze STRG, UMSCH and ALT! Sie aktivieren verschiedene Platzierungsoptionen. resetKeybindings: Tastenbelegung zurücksetzen. @@ -741,7 +741,7 @@ keybindings: confirmMassDelete: Massenlöschung bestätigen cycleBuildings: Gebäude rotieren - massSelectStart: Halten und ziehen zum beginnen + massSelectStart: Halten und ziehen zum Beginnen massSelectSelectMultiple: Mehrere Areale markieren massSelectCopy: Areal kopieren @@ -752,8 +752,8 @@ keybindings: massSelectCut: Areal ausschneiden exportScreenshot: Ganze Fabrik als Foto exportieren mapMoveFaster: Schneller bewegen - lockBeltDirection: Enable belt planner - switchDirectionLockSide: 'Planner: Switch side' + lockBeltDirection: Bandplaner aktivieren + switchDirectionLockSide: 'Planer: Seite wechseln' about: title: Über dieses Spiel From f15cd5bcffbbdd27332e1ff6c4a68e8f860e6947 Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Wed, 17 Jun 2020 15:36:53 -0400 Subject: [PATCH 18/51] Rework to cache instead of serialize Using lessons from other PRs --- src/js/game/buildings/miner.js | 10 ++-------- src/js/game/components/miner.js | 10 +++------- src/js/game/systems/miner.js | 27 +++++++++++++++++++-------- 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/js/game/buildings/miner.js b/src/js/game/buildings/miner.js index 2baf3fd4..ed87bc85 100644 --- a/src/js/game/buildings/miner.js +++ b/src/js/game/buildings/miner.js @@ -44,15 +44,9 @@ export class MetaMinerBuilding extends MetaBuilding { /** * Creates the entity at the given location * @param {Entity} entity - * @param {GameRoot} root */ - setupEntityComponents(entity, root) { - let itemBelow = null; - if (root) { - const staticComp = entity.components.StaticMapEntity; - itemBelow = root.map.getLowerLayerContentXY(staticComp.origin.x, staticComp.origin.y); - } - entity.addComponent(new MinerComponent({ minedItem: itemBelow })); + setupEntityComponents(entity) { + entity.addComponent(new MinerComponent({})); entity.addComponent( new ItemEjectorComponent({ slots: [{ pos: new Vector(0, 0), direction: enumDirection.top }], diff --git a/src/js/game/components/miner.js b/src/js/game/components/miner.js index ae64223a..74a4b616 100644 --- a/src/js/game/components/miner.js +++ b/src/js/game/components/miner.js @@ -12,10 +12,10 @@ export class MinerComponent extends Component { } static getSchema() { + // cachedMinedItem is not serialized. return { lastMiningTime: types.ufloat, chainable: types.bool, - minedItem: types.nullable(types.obj(gItemRegistry)), itemChainBuffer: types.array(types.obj(gItemRegistry)), }; } @@ -23,14 +23,10 @@ export class MinerComponent extends Component { duplicateWithoutContents() { return new MinerComponent({ chainable: this.chainable, - minedItem: this.minedItem, }); } - /** - * @param {{chainable?: boolean, minedItem?: BaseItem}} param0 - */ - constructor({ chainable = false, minedItem = null }) { + constructor({ chainable = false }) { super(); this.lastMiningTime = 0; this.chainable = chainable; @@ -45,7 +41,7 @@ export class MinerComponent extends Component { /** * @type {BaseItem} */ - this.minedItem = minedItem; + this.cachedMinedItem = null; } /** diff --git a/src/js/game/systems/miner.js b/src/js/game/systems/miner.js index 41786603..b195e6ab 100644 --- a/src/js/game/systems/miner.js +++ b/src/js/game/systems/miner.js @@ -25,8 +25,16 @@ export class MinerSystem extends GameSystemWithFilter { const minerComp = entity.components.Miner; - if (!minerComp.minedItem) { - continue; + if (!minerComp.cachedMinedItem) { + const staticComp = entity.components.StaticMapEntity; + const tileBelow = this.root.map.getLowerLayerContentXY( + staticComp.origin.x, + staticComp.origin.y + ); + if (!tileBelow) { + continue; + } + minerComp.cachedMinedItem = tileBelow; } // First, try to get rid of chained items @@ -38,9 +46,9 @@ export class MinerSystem extends GameSystemWithFilter { } if (this.root.time.isIngameTimerExpired(minerComp.lastMiningTime, 1 / miningSpeed)) { - if (this.tryPerformMinerEject(entity, minerComp.minedItem)) { + if (this.tryPerformMinerEject(entity, minerComp.cachedMinedItem)) { // Analytics hook - this.root.signals.itemProduced.dispatch(minerComp.minedItem); + this.root.signals.itemProduced.dispatch(minerComp.cachedMinedItem); // Actually mine minerComp.lastMiningTime = this.root.time.now(); @@ -105,10 +113,13 @@ export class MinerSystem extends GameSystemWithFilter { if (!staticComp.shouldBeDrawn(parameters)) { continue; } + if (!minerComp.cachedMinedItem) { + continue; + } - if (minerComp.minedItem) { + if (minerComp.cachedMinedItem) { const padding = 3; - parameters.context.fillStyle = minerComp.minedItem.getBackgroundColorAsResource(); + parameters.context.fillStyle = minerComp.cachedMinedItem.getBackgroundColorAsResource(); parameters.context.fillRect( staticComp.origin.x * globalConfig.tileSize + padding, staticComp.origin.y * globalConfig.tileSize + padding, @@ -117,8 +128,8 @@ export class MinerSystem extends GameSystemWithFilter { ); } - if (minerComp.minedItem) { - minerComp.minedItem.draw( + if (minerComp.cachedMinedItem) { + minerComp.cachedMinedItem.draw( (0.5 + staticComp.origin.x) * globalConfig.tileSize, (0.5 + staticComp.origin.y) * globalConfig.tileSize, parameters From 60baf4476f0931b8686eeee0faae03e8bee58271 Mon Sep 17 00:00:00 2001 From: David Burhans Date: Wed, 17 Jun 2020 19:35:02 -0500 Subject: [PATCH 19/51] clear ClickDetector.clickDownPosition on right-click to prevent detecting subsequent left-clicks as double-clicks --- src/js/core/click_detector.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/js/core/click_detector.js b/src/js/core/click_detector.js index 5f6816f7..add9c267 100644 --- a/src/js/core/click_detector.js +++ b/src/js/core/click_detector.js @@ -316,6 +316,7 @@ export class ClickDetector { // Ignore right clicks this.rightClick.dispatch(position, event); this.cancelled = true; + this.clickDownPosition = null; return; } } From 1adf7d09f917b5f33847d99ee016e228ffa73d30 Mon Sep 17 00:00:00 2001 From: findaldudu Date: Wed, 17 Jun 2020 21:13:50 -0500 Subject: [PATCH 20/51] add simplified Chinese translation (75%) --- res/ui/languages/zh-CN.svg | 42 ++ src/css/icons.scss | 2 +- src/js/languages.js | 6 + translations/base-zh-CN.yaml | 798 ++++++++++++++++++++--------------- 4 files changed, 495 insertions(+), 353 deletions(-) create mode 100644 res/ui/languages/zh-CN.svg diff --git a/res/ui/languages/zh-CN.svg b/res/ui/languages/zh-CN.svg new file mode 100644 index 00000000..f89219a0 --- /dev/null +++ b/res/ui/languages/zh-CN.svg @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/css/icons.scss b/src/css/icons.scss index c66b87ae..2128fde3 100644 --- a/src/css/icons.scss +++ b/src/css/icons.scss @@ -27,7 +27,7 @@ $icons: notification_saved, notification_success, notification_upgrade; } } -$languages: en, de, cs, da, et, es-419, fr, it, pt-BR, sv, tr, el, ru, uk, zh-TW, nb, mt-MT, ar, nl, vi, th, +$languages: en, de, cs, da, et, es-419, fr, it, pt-BR, sv, tr, el, ru, uk, zh-TW, zh-CN, nb, mt-MT, ar, nl, vi, th, hu, pl, ja, kor, no, pt-PT; @each $language in $languages { diff --git a/src/js/languages.js b/src/js/languages.js index 19e88f5a..2d40037b 100644 --- a/src/js/languages.js +++ b/src/js/languages.js @@ -80,4 +80,10 @@ export const LANGUAGES = { code: "no", region: "", }, + "zh-CN": { + name: "简体中文", + data: require("./built-temp/base-zh-CN.json"), + code: "zh", + region: "CN", + }, }; diff --git a/translations/base-zh-CN.yaml b/translations/base-zh-CN.yaml index 8ce591dd..8ad79ee4 100644 --- a/translations/base-zh-CN.yaml +++ b/translations/base-zh-CN.yaml @@ -19,10 +19,37 @@ # the basic structure so the game also detects it. # +# Chinese translation dictionary: +# Standalone:独立版 +# Demo:演示版 +# Level:关/关卡 +# Shape:图形 +# tile:格子/格 +# Keybind:按键设置 +# Menu:主界面 +# Center/Hub:基地 +# Upgrade:建筑升级/升级 +# Efficiency:效率 +# Building:建筑 +# Variant:建筑变体 +# Belt: 传送带 +# Balancer:平衡机 +# Compact Balancer:小型合流机 +# Merger:合并机 +# Tunnel:隧道 +# Extractor:开采机 +# Cutter:切割机 +# Rotate:旋转机 +# Stacker:堆叠机 +# Color Mixer:混色机 +# Painter:上色机 +# Trash:垃圾桶 + steamPage: # This is the short text appearing on the steam page - shortText: shapez.io is a game about building factories to automate the creation and combination of increasingly complex shapes within an infinite map. - + shortText: shapez.io 是一个关于建造工厂is a game about building factories to automate the creation and combination of increasingly complex shapes within an infinite map. + # shortText: shapez.io is a game about building factories to automate the creation and combination of increasingly complex shapes within an infinite map. + # This is the long description for the steam page - It is contained here so you can help to translate it, and I will regulary update the store page. # NOTICE: # - Do not translate the first line (This is the gif image at the start of the store) @@ -36,71 +63,74 @@ steamPage: Since shapes can get boring soon you need to mix colors and paint your shapes with it - Combine red, green and blue color resources to produce different colors and paint shapes with it to satisfy the demand. - This game features 18 levels (Which should keep you busy for hours already!) but I'm constantly adding new content - There is a lot planned! + This game features 18 levels (Which should keep you busy for hours already!) but I'm constantly adding new content - There is a lot planned! + - - [b]Standalone Advantages[/b] + [b]独立版优势[/b] [list] - [*] Waypoints - [*] Unlimited Savegames - [*] Dark Mode - [*] More settings - [*] Allow me to further develop shapez.io ❤️ - [*] More features in the future! + [*] 地图标记 + [*] 无限存档 + [*] 深色模式 + [*] 更多设置 + [*] 支持作者继续开发shapez.io❤️ + [*] 更多新功能 [/list] - [b]Planned features & Community suggestions[/b] - This game is open source - Anybody can contribute! Besides of that, I listen [b]a lot[/b] to the community! I try to read all suggestions and take as much feedback into account as possible. + [b]开发计划与玩家建议[/b] + + 本游戏已开源,所有人都能贡献游戏内容!除此以外,我[b]非常重视[/b]玩家社区的反馈!我会阅读每一条建议并尽量顾及所有建议。 [list] - [*] Story mode where buildings cost shapes - [*] More levels & buildings (standalone exclusive) - [*] Different maps, and maybe map obstacles + [*] 故事模式,建筑将消耗形状 + [*] 更多的独立版关卡和建筑 + [*] 不同的地图与障碍物 [*] Configurable map creation (Edit number and size of patches, seed, and more) - [*] More types of shapes + [*] 更多形状 [*] More performance improvements (Although the game already runs pretty good!) - [*] Color blind mode - [*] And much more! + [*] 色盲模式 + [*] 以及更多其他的功能! [/list] - + Be sure to check out my trello board for the full roadmap! https://trello.com/b/ISQncpJP/shapezio global: - loading: Loading - error: Error + loading: 加载中 + error: 错误 + # Chinese translation: There is typically no divider used for numbers. # How big numbers are rendered, e.g. "10,000" - thousandsDivider: "," + thousandsDivider: "" + # TODO: Chinese translation: suffix changes every 10000 in Chinese numbering system. # The suffix for large numbers, e.g. 1.3k, 400.2M, etc. suffix: - thousands: k + thousands: K millions: M billions: B trillions: T # Shown for infinitely big numbers - infinite: inf + infinite: 无限 time: # Used for formatting past time dates - oneSecondAgo: one second ago - xSecondsAgo: seconds ago - oneMinuteAgo: one minute ago - xMinutesAgo: minutes ago - oneHourAgo: one hour ago - xHoursAgo: hours ago - oneDayAgo: one day ago - xDaysAgo: days ago + oneSecondAgo: 1秒前 + xSecondsAgo: 秒前 + oneMinuteAgo: 1分钟前 + xMinutesAgo: 分钟前 + oneHourAgo: 1小时前 + xHoursAgo: 小时前 + oneDayAgo: 1天前 + xDaysAgo: 天前 # Short formats for times, e.g. '5h 23m' - secondsShort: s - minutesAndSecondsShort: m s - hoursAndMinutesShort: h s + secondsShort: 秒 + minutesAndSecondsShort: 秒 + hoursAndMinutesShort: 小时 秒 - xMinutes: minutes + xMinutes: 分钟 keys: tab: TAB @@ -108,33 +138,34 @@ global: alt: ALT escape: ESC shift: SHIFT - space: SPACE + space: 空格 demoBanners: # This is the "advertisement" shown in the main menu and other various places - title: Demo Version + title: 演示版 intro: >- - Get the standalone to unlock all features! + 获取独立版以解锁所有功能! mainMenu: - play: Play - changelog: Changelog - importSavegame: Import - openSourceHint: This game is open source! - discordLink: Official Discord Server - helpTranslate: Help translate! + play: 开始游戏 + changelog: 更新日志 + importSavegame: 导入 + openSourceHint: 本游戏已开源! + discordLink: 官方Discord服务器 + helpTranslate: 帮助我们翻译! # This is shown when using firefox and other browsers which are not supported. browserWarning: >- - Sorry, but the game is known to run slow on your browser! Get the standalone version or download chrome for the full experience. + 很抱歉, 本游戏在当前浏览器上可能运行缓慢! 使用chrome或者获取独立版以得到更好的体验。 - savegameLevel: Level - savegameLevelUnknown: Unknown Level + savegameLevel: 第关 + savegameLevelUnknown: 未知关卡 contests: contest_01_03062020: - title: "Contest #01" + title: "竞赛 #01" desc: Win $25 for the coolest base! + #desc: Win $25 for the coolest base! longDesc: >- To give something back to you, I thought it would be cool to make weekly contests!

@@ -151,336 +182,377 @@ mainMenu:
I'm looking forward to seeing your awesome creations! - showInfo: View - contestOver: This contest has ended - Join the discord to get noticed about new contests! - continue: Continue - newGame: New Game - madeBy: Made by + showInfo: 详细信息 + contestOver: 本次竞赛已结束。加入官方Discord以收到关于新竞赛的提醒! + # contestOver: This contest has ended - Join the discord to get noticed about new contests! + continue: 继续游戏 + newGame: 新游戏 + madeBy: 作者: dialogs: buttons: - ok: OK - delete: Delete - cancel: Cancel - later: Later - restart: Restart - reset: Reset - getStandalone: Get Standalone - deleteGame: I know what I do - viewUpdate: View Update - showUpgrades: Show Upgrades - showKeybindings: Show Keybindings + ok: 确认 # 好 完成 + delete: 删除 # Delete + cancel: 取消 # Cancel + later: 以后 # Later + restart: 重启游戏 + reset: 重置 + getStandalone: 获取独立版 + deleteGame: 我知道我在做什么 + viewUpdate: 查看更新 + showUpgrades: 显示建筑升级 + showKeybindings: 显示按键设置 importSavegameError: - title: Import Error + title: 导入错误 text: >- - Failed to import your savegame: + 未能导入你的存档: importSavegameSuccess: - title: Savegame Imported + title: 导入成功 text: >- - Your savegame has been successfully imported. + 存档被成功导入 gameLoadFailure: - title: Game is broken + title: 存档损坏 text: >- - Failed to load your savegame: + 未能导入你的存档: confirmSavegameDelete: - title: Confirm deletion + title: 确认删除 text: >- - Are you sure you want to delete the game? + 你确定要删除这个存档吗? savegameDeletionError: - title: Failed to delete + title: 删除错误 text: >- - Failed to delete the savegame: + 未能删除你的存档 restartRequired: - title: Restart required + title: 需要重启游戏 text: >- - You need to restart the game to apply the settings. + 你需要重启游戏以应用变更的设置。 editKeybinding: - title: Change Keybinding - desc: Press the key or mouse button you want to assign, or escape to cancel. + title: 更改按键设置 + desc: 请按下你想要使用的按键,或者按下ESC键来取消设置。 resetKeybindingsConfirmation: - title: Reset keybindings - desc: This will reset all keybindings to their default values. Please confirm. - + title: 重置所有按键 + desc: 你将要重置所有按键,请确认。 + keybindingsResetOk: - title: Keybindings reset - desc: The keybindings have been reset to their respective defaults! - + title: 重置所有按键 + desc: 成功重置所有按键! + featureRestriction: - title: Demo Version - desc: You tried to access a feature () which is not available in the demo. Consider to get the standalone for the full experience! - + title: 演示版 + desc: 你尝试使用了 功能。该功能在演示版中不可用。请考虑购买独立版以获得更好的体验。 + oneSavegameLimit: - title: Limited savegames - desc: You can only have one savegame at a time in the demo version. Please remove the existing one or get the standalone! + title: 存档数量限制 + desc: 演示版中只能保存一份存档。 请删除旧存档或者获取独立版! updateSummary: - title: New update! + title: 更新啦! desc: >- - Here are the changes since you last played: + 以下为自上次游戏以来更新的内容: + upgradesIntroduction: - title: Unlock Upgrades + title: 解锁建筑升级 desc: >- - All shapes you produce can be used to unlock upgrades - Don't destroy your old factories! - The upgrades tab can be found on the top right corner of the screen. + 不要销毁你之前建造的工厂!你生产过的所有形状都会被用来升级建筑。 + 升级菜单在屏幕右上角。 + # All shapes you produce can be used to unlock upgrades - Don't destroy your old factories! + # The upgrades tab can be found on the top right corner of the screen. massDeleteConfirm: - title: Confirm delete + title: 确认删除 desc: >- - You are deleting a lot of buildings ( to be exact)! Are you sure you want to do this? + 你将要删除很多建筑,准确来说有幢! 你确定要这么做吗? blueprintsNotUnlocked: - title: Not unlocked yet + title: 未解锁 desc: >- - Blueprints have not been unlocked yet! Complete more levels to unlock them. + 你还没有解锁蓝图功能!完成更多的关卡来解锁蓝图。 keybindingsIntroduction: - title: Useful keybindings + title: 实用按键 desc: >- - This game has a lot of keybindings which make it easier to build big factories. - Here are a few, but be sure to check out the keybindings!

- CTRL + Drag: Select area to copy / delete.
- SHIFT: Hold to place multiple of one building.
- ALT: Invert orientation of placed belts.
+ 这个游戏有很多能帮助搭建工厂的使用按键。 + 以下是其中的一些,记得在按键设置中查看其他的!

+ CTRL + 拖动:选择区域以复制或删除。
+ SHIFT: 按住以放置多个。
+ ALT: 反向放置传送带。
+ # desc: >- + # This game has a lot of keybindings which make it easier to build big factories. + # Here are a few, but be sure to check out the keybindings!

+ # CTRL + Drag: Select area to copy / delete.
+ # SHIFT: Hold to place multiple of one building.
+ # ALT: Invert orientation of placed belts.
createMarker: - title: New Marker - desc: Give it a meaningful name, you can also include a short key of a shape (Which you can generate here) + title: 创建地图标记 + desc: 给地图标记起一个的名字。你可以在名字中加入一个短代码以加入形状。(你可以在这里生成短代码。) + #desc: Give it a meaningful name, you can also include a short key of a shape (Which you can generate here) markerDemoLimit: - desc: You can only create two custom markers in the demo. Get the standalone for unlimited markers! + desc: 在演示版中你只能创建两个地图标记。请获取独立版以创建更多标记。 + #desc: You can only create two custom markers in the demo. Get the standalone for unlimited markers! massCutConfirm: - title: Confirm cut + title: 确认剪切 desc: >- - You are cutting a lot of buildings ( to be exact)! Are you sure you - want to do this? + 你将要剪切很多建筑,准确来说有幢! 你确定要这么做吗? + # desc: >- + # You are cutting a lot of buildings ( to be exact)! Are you sure you + # want to do this? exportScreenshotWarning: - title: Export screenshot + title: 工厂截图 desc: >- - You requested to export your base as a screenshot. Please note that this can - be quite slow for a big base and even crash your game! + 你将要导出你的工厂的截图。如果你的基地很大,截图过程将会很慢,且有可能导致游戏崩溃! + # desc: >- + # You requested to export your base as a screenshot. Please note that this can + # be quite slow for a big base and even crash your game! ingame: # This is shown in the top left corner and displays useful keybindings in # every situation keybindingsOverlay: - moveMap: Move - selectBuildings: Select area - stopPlacement: Stop placement - rotateBuilding: Rotate building - placeMultiple: Place multiple - reverseOrientation: Reverse orientation - disableAutoOrientation: Disable auto orientation - toggleHud: Toggle HUD - placeBuilding: Place building - createMarker: Create Marker - delete: Destroy - pasteLastBlueprint: Paste last blueprint - lockBeltDirection: Enable belt planner - plannerSwitchSide: Flip planner side + moveMap: 移动地图 + selectBuildings: 选择区域 + stopPlacement: 停止放置 + rotateBuilding: 转动建筑 + placeMultiple: 放置多个 + reverseOrientation: 反向放置 + disableAutoOrientation: 关闭自动定向 + toggleHud: 开关HUD + placeBuilding: 放置建筑 + createMarker: 创建地图标记 + delete: 销毁 + pasteLastBlueprint: 粘贴上一个蓝图 + lockBeltDirection: 启用传送带规划 + plannerSwitchSide: 规划器换边 + # moveMap: Move + # selectBuildings: Select area + # stopPlacement: Stop placement + # rotateBuilding: Rotate building + # placeMultiple: Place multiple + # reverseOrientation: Reverse orientation + # disableAutoOrientation: Disable auto orientation + # toggleHud: Toggle HUD + # placeBuilding: Place building + # createMarker: Create Marker + # delete: Destroy + # pasteLastBlueprint: Paste last blueprint + # lockBeltDirection: Enable belt planner + # plannerSwitchSide: Flip planner side # Everything related to placing buildings (I.e. as soon as you selected a building # from the toolbar) buildingPlacement: # Buildings can have different variants which are unlocked at later levels, # and this is the hint shown when there are multiple variants available. - cycleBuildingVariants: Press to cycle variants. + cycleBuildingVariants: 按键以选择建筑变体. # Shows the hotkey in the ui, e.g. "Hotkey: Q" hotkeyLabel: >- - Hotkey: + 快捷键: infoTexts: - speed: Speed - range: Range - storage: Storage - oneItemPerSecond: 1 item / second - itemsPerSecond: items / s - itemsPerSecondDouble: (x2) + speed: 效率 + range: 范围 + storage: 容量 + oneItemPerSecond: 1个/秒 + itemsPerSecond: 个/秒 + itemsPerSecondDouble: (2倍) - tiles: tiles + tiles: 格 # The notification when completing a level levelCompleteNotification: # is replaced by the actual level, so this gets 'Level 03' for example. - levelTitle: Level - completed: Completed - unlockText: Unlocked ! - buttonNextLevel: Next Level + levelTitle: 第关 + completed: 完成 + unlockText: 解锁! + buttonNextLevel: 下一关 # Notifications on the lower right notifications: - newUpgrade: A new upgrade is available! - gameSaved: Your game has been saved. + newUpgrade: 有新更新啦! + gameSaved: 游戏已保存。 # Mass select information, this is when you hold CTRL and then drag with your mouse # to select multiple buildings massSelect: - infoText: Press to cut, to copy, to remove and to cancel. + infoText: 剪切,复制,删除,取消. # The "Upgrades" window shop: - title: Upgrades - buttonUnlock: Upgrade + title: 建筑升级 + buttonUnlock: 升级 # Gets replaced to e.g. "Tier IX" - tier: Tier + tier: 级 # The roman number for each tier - tierLabels: [I, II, III, IV, V, VI, VII, VIII, IX, X] + # Chinese translation: Chinese characters for each tier + tierLabels: [一, 二, 三, 四, 五, 六, 七, 八, 九, 十] - maximumLevel: MAXIMUM LEVEL (Speed x) + maximumLevel: 最高级(倍效率) # The "Statistics" window statistics: - title: Statistics + title: 统计信息 dataSources: stored: - title: Stored - description: Displaying amount of stored shapes in your central building. + title: 储存 + description: 显示基地中每种图形储存的数量。 + # title: Stored + # description: Displaying amount of stored shapes in your central building. produced: - title: Produced - description: Displaying all shapes your whole factory produces, including intermediate products. + title: 生产 + description: 显示所有正在被生产的图形数量,包括中间产物。 + # title: Produced + # description: Displaying all shapes your whole factory produces, including intermediate products. delivered: - title: Delivered - description: Displaying shapes which are delivered to your central building. - noShapesProduced: No shapes have been produced so far. + title: 送达 + description: 显示形状送达基地的速度。 + # title: Delivered + # description: Displaying shapes which are delivered to your central building. + noShapesProduced: 你还没有生产任何形状。 + # noShapesProduced: No shapes have been produced so far. # Displays the shapes per minute, e.g. '523 / m' - shapesPerMinute: / m + shapesPerMinute: 个/分钟 + # shapesPerMinute: / m + # Settings menu, when you press "ESC" settingsMenu: - playtime: Playtime + playtime: 游戏时间 - buildingsPlaced: Buildings - beltsPlaced: Belts + buildingsPlaced: 建筑数量 + beltsPlaced: 传送带数量 buttons: - continue: Continue - settings: Settings - menu: Return to menu + continue: 继续 + settings: 设置 + menu: 回到主界面 # Bottom left tutorial hints tutorialHints: - title: Need help? - showHint: Show hint - hideHint: Close + title: 需要帮助? + showHint: 显示帮助 + hideHint: 关闭 # When placing a blueprint blueprintPlacer: - cost: Cost + cost: 需要 # Map markers waypoints: - waypoints: Markers - hub: HUB - description: Left-click a marker to jump to it, right-click to delete it.

Press to create a marker from the current view, or right-click to create a marker at the selected location. - creationSuccessNotification: Marker has been created. + waypoints: 地图标记 + hub: 基地 + description: 左键快速跳转到地图标记,右键删除地图标记。

从当前视图中创建地图标记,或者在选定的位置上使用右键创建地图标记。 + creationSuccessNotification: 成功创建地图标记。 # Interactive tutorial interactiveTutorial: - title: Tutorial + title: 教程 hints: - 1_1_extractor: Place an extractor on top of a circle shape to extract it! + 1_1_extractor: 在圆形矿脉上放一个开采机来获取圆形! 1_2_conveyor: >- - Connect the extractor with a conveyor belt to your hub!

Tip: Click and drag the belt with your mouse! + 用传送带将你的开采机连接到基地上!

提示:用你的鼠标按下并拖动传送带! 1_3_expand: >- - This is NOT an idle game! Build more extractors and belts to finish the goal quicker.

Tip: Hold SHIFT to place multiple extractors, and use R to rotate them. + 这不是一个挂机游戏!建造更多的开采机和传送带来更快地完成目标。

+ 提示:按住SHIFT键来放置多个开采机,用R键旋转它们。 # All shop upgrades shopUpgrades: belt: - name: Belts, Distributor & Tunnels - description: Speed x → x + name: 传送带、平衡机、隧道 + description: 效率 倍 → 倍 miner: - name: Extraction - description: Speed x → x + name: 开采 + description: 效率 倍 → 倍 processors: - name: Cutting, Rotating & Stacking - description: Speed x → x + name: 切割、旋转、堆叠 + description: 效率 倍 → 倍 painting: - name: Mixing & Painting - description: Speed x → x + name: 混色、上色 + description: 效率 倍 → 倍 # Buildings and their name / description buildings: belt: default: - name: &belt Conveyor Belt - description: Transports items, hold and drag to place multiple. + name: &belt 传送带 + description: 运送物品,按住并拖动来放置多个传送带。 miner: # Internal name for the Extractor default: - name: &miner Extractor - description: Place over a shape or color to extract it. + name: &miner 开采机 + description: 在形状或者颜色上放置来开采他们。 chainable: - name: Extractor (Chain) - description: Place over a shape or color to extract it. Can be chained. + name: 链式开采机 + description: 在形状或者颜色上放置来开采他们。可以被链接在一起。 underground_belt: # Internal name for the Tunnel default: - name: &underground_belt Tunnel - description: Allows to tunnel resources under buildings and belts. + name: &underground_belt 隧道 + description: 可以从其他传送带或建筑底下方运送物品。 tier2: - name: Tunnel Tier II - description: Allows to tunnel resources under buildings and belts. + name: 二级隧道 + description: 可以从其他传送带或建筑底下方运送物品。 splitter: # Internal name for the Balancer default: - name: &splitter Balancer - description: Multifunctional - Evenly distributes all inputs onto all outputs. + name: &splitter 平衡机 + description: 多功能——将所有输入平均分配到所有输出。 compact: - name: Merger (compact) - description: Merges two conveyor belts into one. + name: 小型合流机 + description: 把两个输入合并到一个输出上。 compact-inverse: - name: Merger (compact) - description: Merges two conveyor belts into one. + name: 小型合流机 + description: 把两个输入合并到一个输出上。 cutter: default: - name: &cutter Cutter - description: Cuts shapes from top to bottom and outputs both halfs. If you use only one part, be sure to destroy the other part or it will stall! + name: &cutter 切割机 + description: 将形状从上到下切开并输出。 如果你只需要其中一半,记得把另一半销毁掉,否则切割机会停止工作! quad: name: Cutter (Quad) description: Cuts shapes into four parts. If you use only one part, be sure to destroy the other part or it will stall! rotater: default: - name: &rotater Rotate - description: Rotates shapes clockwise by 90 degrees. + name: &rotater 旋转机 + description: 将图形顺时针旋转90度。 ccw: - name: Rotate (CCW) - description: Rotates shapes counter clockwise by 90 degrees. + name: 旋转机(逆时针) + description: 将图形逆时针旋转90度。 stacker: default: - name: &stacker Stacker - description: Stacks both items. If they can not be merged, the right item is placed above the left item. + name: &stacker 堆叠机 + description: 将输入的形状拼贴在一起。如果不能被直接拼贴,右边的形状会被堆叠在左边的形状上面. mixer: default: - name: &mixer Color Mixer - description: Mixes two colors using additive blending. + name: &mixer 混色机 + description: 将两个颜色混合在一起。(加法混合) painter: default: - name: &painter Painter - description: &painter_desc Colors the whole shape on the left input with the color from the right input. + name: &painter 上色机 + description: &painter_desc 将整个形状涂上输入的颜色。 double: name: Painter (Double) description: Colors the shapes on the left inputs with the color from the top input. @@ -493,64 +565,64 @@ buildings: trash: default: - name: &trash Trash - description: Accepts inputs from all sides and destroys them. Forever. + name: &trash 垃圾桶 + description: 从所有四个方向上输入物品并销毁它们。永远。 storage: - name: Storage - description: Stores excess items, up to a given capacity. Can be used as an overflow gate. + name: 仓库 + description: 储存多余的物品,有一定储存上限。可以被用来作为溢流门。 hub: - deliver: Deliver - toUnlock: to unlock + deliver: 交付 + toUnlock: 来解锁 levelShortcut: LVL storyRewards: # Those are the rewards gained from completing the store reward_cutter_and_trash: - title: Cutting Shapes - desc: You just unlocked the cutter - it cuts shapes half from top to bottom regardless of its orientation!

Be sure to get rid of the waste, or otherwise it will stall - For this purpose I gave you a trash, which destroys everything you put into it! + title: 切割图形 + desc: 切割机已解锁。不论切割机的方向,它都会把图形从上到下切成两半。

记得把不需要的部分处理掉,否则这个这个建筑会停止工作。为此我给你准备了垃圾桶,它会把所有放进去的物品销毁掉。 reward_rotater: - title: Rotating - desc: The rotater has been unlocked! It rotates shapes clockwise by 90 degrees. + title: 顺时针旋转 + desc: 旋转机已解锁。它会顺时针旋转输入的形状90度。 reward_painter: - title: Painting + title: 上色 desc: >- - The painter has been unlocked - Extract some color veins (just as you do with shapes) and combine it with a shape in the painter to color them!

PS: If you are colorblind, I'm working on a solution already! + 上色机已解锁。和形状一样,从颜色矿脉中开采颜色,然后将在上色机中将颜色涂在形状上。

PS:我们正在开发色盲模式! reward_mixer: - title: Color Mixing - desc: The mixer has been unlocked - Combine two colors using additive blending with this building! + title: 混合颜色 + desc: 混色机已解锁。在这个建筑中将两个颜色混合在一起(加法混合)。 reward_stacker: - title: Combiner - desc: You can now combine shapes with the combiner! Both inputs are combined, and if they can be put next to each other, they will be fused. If not, the right input is stacked on top of the left input! + title: 堆叠 + desc: 堆叠机已解锁。堆叠机会尝试把两个输入的形状拼贴在一起。如果有重叠的部分,右边的输入会被堆叠在左边的输入上方! reward_splitter: - title: Splitter/Merger - desc: The multifunctional balancer has been unlocked - It can be used to build bigger factories by splitting and merging items onto multiple belts!

+ title: 分离与合并 + desc: 平衡机已解锁。在大型工厂中,平衡机负责合并或分离多个传送带上的物品。

reward_tunnel: - title: Tunnel - desc: The tunnel has been unlocked - You can now pipe items through belts and buildings with it! + title: 隧道 + desc: 隧道已解锁。你现在可以从其他传送带或建筑底下运送物品了! reward_rotater_ccw: - title: CCW Rotating - desc: You have unlocked a variant of the rotater - It allows to rotate counter clockwise! To build it, select the rotater and press 'T' to cycle its variants! + title: 逆时针旋转 + desc: 旋转机逆时针变体已解锁。这个变体可以逆时针旋转形状。选择旋转机然后按“T”键来选取这个变体。 reward_miner_chainable: - title: Chaining Extractor - desc: You have unlocked the chaining extractor! It can forward its resources to other extractors so you can more efficiently extract resources! + title: 链式开采机 + desc: 链式开采机变体已解锁。它是开采机的一个变体。它可以将开采出来的资源传递给其他的开采机,使得资源提取更加高效! reward_underground_belt_tier_2: - title: Tunnel Tier II - desc: You have unlocked a new variant of the tunnel - It has a bigger range, and you can also mix-n-match those tunnels now! + title: 二级隧道 + desc: 二级隧道变体已解锁。这个隧道有更长的传输距离。你还可以混用不同的隧道变体! reward_splitter_compact: - title: Compact Balancer + title: 小型合流机 desc: >- - You have unlocked a compact variant of the balancer - It accepts two inputs and merges them into one! + 小型合流机变体已解锁。它可以把两个输入合并到一个输出上。 reward_cutter_quad: title: Quad Cutting @@ -565,162 +637,177 @@ storyRewards: desc: You have unlocked a variant of the painter - It allows to paint each part of the shape individually! reward_storage: - title: Storage Buffer - desc: You have unlocked a variant of the trash - It allows to store items up to a given capacity! + title: 仓库 + desc: 仓库变体已解锁。它可以暂时储存一些材料,有容量上限。 reward_freeplay: title: Freeplay desc: You did it! You unlocked the free-play mode! This means that shapes are now randomly generated! (No worries, more content is planned for the standalone!) reward_blueprints: - title: Blueprints - desc: You can now copy and paste parts of your factory! Select an area (Hold CTRL, then drag with your mouse), and press 'C' to copy it.

Pasting it is not free, you need to produce blueprint shapes to afford it! (Those you just delivered). + title: 蓝图 + desc: 你现在可以复制粘贴你的工厂的一部分了!按住CTRL键并拖动鼠标来选择一块区域,然后按C键复制。

粘贴并不是免费的,你需要使用蓝图形状来粘贴你的蓝图。蓝图形状是你刚刚交付的形状。 # Special reward, which is shown when there is no reward actually no_reward: - title: Next level + title: 下一关 desc: >- - This level gave you no reward, but the next one will!

PS: Better don't destroy your existing factory - You need all those shapes later again to unlock upgrades! + 这一关没有奖励,但是下一关有!

PS: 你生产过的所有形状都会被用来升级建筑。 no_reward_freeplay: - title: Next level + title: 下一关 desc: >- - Congratulations! By the way, more content is planned for the standalone! + 恭喜你!另外,我们已经计划在独立版中加入更多内容! settings: - title: Settings + title: 设置 categories: - game: Game - app: Application + game: 游戏内容 + app: 应用 versionBadges: - dev: Development - staging: Staging - prod: Production - buildDate: Built + dev: 开发版本 # Development + staging: 预览版本 # Staging + prod: 正式版本 # Production + buildDate: 于编译 labels: uiScale: - title: Interface scale + title: 用户界面大小 description: >- - Changes the size of the user interface. The interface will still scale based on your device resolution, but this setting controls the amount of scale. + 改变用户界面大小。用户界面会随着设备分辨率缩放,这个设置决定缩放比例。 scales: - super_small: Super small - small: Small - regular: Regular - large: Large - huge: Huge + super_small: 最小 + small: 较小 + regular: 正常 + large: 较大 + huge: 最大 scrollWheelSensitivity: - title: Zoom sensitivity + title: 缩放灵敏度 description: >- - Changes how sensitive the zoom is (Either mouse wheel or trackpad). + 改变缩放灵敏度(鼠标滚轮或者触控板)。 sensitivity: - super_slow: Super slow - slow: Slow - regular: Regular - fast: Fast - super_fast: Super fast + super_slow: 最低 + slow: 较低 + regular: 正常 + fast: 较高 + super_fast: 最高 language: - title: Language + title: 语言 description: >- - Change the language. All translations are user contributed and might be incomplete! + 改变语言。所有的翻译皆由玩家提供,且有可能正在施工中! fullscreen: - title: Fullscreen + title: 全屏 description: >- - It is recommended to play the game in fullscreen to get the best experience. Only available in the standalone. + 全屏以获得更好的游戏体验。仅在独立版中可用。 soundsMuted: - title: Mute Sounds + title: 关闭音效 description: >- - If enabled, mutes all sound effects. + 关闭所有音效。 musicMuted: - title: Mute Music + title: 关闭音乐 description: >- - If enabled, mutes all music. + 关闭所有音乐。 theme: - title: Game theme + title: 界面主题 description: >- - Choose the game theme (light / dark). + 选择界面主题(深色或浅色)。 themes: - dark: Dark - light: Light + dark: 深色 + light: 浅色 refreshRate: - title: Simulation Target + title: 模拟频率、刷新频率 description: >- - If you have a 144hz monitor, change the refresh rate here so the game will properly simulate at higher refresh rates. This might actually decrease the FPS if your computer is too slow. + 如果你的显示器是144hz的,请在这里更改刷新频率,这样游戏可以正确地根据你的屏幕进行模拟。但是如果你的电脑性能不佳,提高刷新频率可能降低帧数。 + # description: >- + # If you have a 144hz monitor, change the refresh rate here so the game will properly simulate at higher refresh rates. This might actually decrease the FPS if your computer is too slow. alwaysMultiplace: - title: Multiplace + title: 多重放置 description: >- - If enabled, all buildings will stay selected after placement until you cancel it. This is equivalent to holding SHIFT permanently. + 开启这个选项之后放下建筑将不会取消建筑选择。等同于一直按下SHIFT键。 + # description: >- + # If enabled, all buildings will stay selected after placement until you cancel it. This is equivalent to holding SHIFT permanently. offerHints: - title: Hints & Tutorials + title: 提示与教程 description: >- - Whether to offer hints and tutorials while playing. Also hides certain UI elements onto a given level to make it easier to get into the game. + 是否显示提示、教程以及一些其他的帮助理解游戏的UI元素。 + # description: >- + # Whether to offer hints and tutorials while playing. Also hides certain UI elements onto a given level to make it easier to get into the game. movementSpeed: - title: Movement speed - description: Changes how fast the view moves when using the keyboard. + title: 移动速度 + description: 改变摄像头移动速度 speeds: - super_slow: Super slow - slow: Slow - regular: Regular - fast: Fast - super_fast: Super Fast - extremely_fast: Extremely Fast + super_slow: 最慢 + slow: 较慢 + regular: 正常 + fast: 较快 + super_fast: 非常快 + extremely_fast: 最快 + enableTunnelSmartplace: - title: Smart Tunnels + title: 智能隧道放置 description: >- - When enabled, placing tunnels will automatically remove unnecessary belts. - This also enables to drag tunnels and excess tunnels will get removed. + 启用后,放置隧道时会将多余的传送带移除。 + 此外,拖动隧道可以快速铺设隧道,以及移除不必要的隧道。 vignette: - title: Vignette + title: 晕映 description: >- - Enables the vignette which darkens the screen corners and makes text easier - to read. + 启用晕映,将屏幕角落里的颜色变深,更容易阅读文本。 keybindings: - title: Keybindings + title: 按键设置 hint: >- - Tip: Be sure to make use of CTRL, SHIFT and ALT! They enable different placement options. + 提示:使用CTRL、SHIFT、ALT! 这些建在放置建筑时有不同的效果。 + # hint: >- + # Tip: Be sure to make use of CTRL, SHIFT and ALT! They enable different placement options. - resetKeybindings: Reset Keyinbindings + resetKeybindings: 重置按键设置 categoryLabels: - general: Application - ingame: Game - navigation: Navigating - placement: Placement - massSelect: Mass Select - buildings: Building Shortcuts - placementModifiers: Placement Modifiers + general: 通用 + ingame: 游戏 + navigation: 视角 + placement: 放置 + massSelect: 批量选择 + buildings: 建筑快捷键 + placementModifiers: 放置建筑修饰键 mappings: - confirm: Confirm - back: Back - mapMoveUp: Move Up - mapMoveRight: Move Right - mapMoveDown: Move Down - mapMoveLeft: Move Left - centerMap: Center Map + confirm: 确认 + back: 返回 + mapMoveUp: 上 + mapMoveRight: 右 + mapMoveDown: 下 + mapMoveLeft: 左 + centerMap: 回到基地 + # confirm: Confirm + # back: Back + # mapMoveUp: Move Up + # mapMoveRight: Move Right + # mapMoveDown: Move Down + # mapMoveLeft: Move Left + # centerMap: Center Map - mapZoomIn: Zoom in - mapZoomOut: Zoom out - createMarker: Create Marker + mapZoomIn: 放大 + mapZoomOut: 缩小 + createMarker: 创建地图标记 - menuOpenShop: Upgrades - menuOpenStats: Statistics + menuOpenShop: 升级菜单 + menuOpenStats: 统计菜单 - toggleHud: Toggle HUD - toggleFPSInfo: Toggle FPS and Debug Info + toggleHud: 开关HUD + toggleFPSInfo: 开关帧数与调试信息 belt: *belt splitter: *splitter underground_belt: *underground_belt @@ -732,30 +819,33 @@ keybindings: painter: *painter trash: *trash - abortBuildingPlacement: Abort Placement - rotateWhilePlacing: Rotate + abortBuildingPlacement: 取消放置 + rotateWhilePlacing: 顺时针旋转 rotateInverseModifier: >- - Modifier: Rotate CCW instead - cycleBuildingVariants: Cycle Variants - confirmMassDelete: Confirm Mass Delete - cycleBuildings: Cycle Buildings + 修饰键: 改为逆时针旋转 + cycleBuildingVariants: 选择建筑变体 + # cycleBuildingVariants: Cycle Variants + confirmMassDelete: 确认批量删除 + cycleBuildings: 选择建筑 + # cycleBuildings: Cycle Buildings + massSelectStart: 开始批量选择 + massSelectSelectMultiple: 选择多个区域 + massSelectCopy: 复制 - massSelectStart: Hold and drag to start - massSelectSelectMultiple: Select multiple areas - massSelectCopy: Copy area + placementDisableAutoOrientation: 取消自动定向 + placeMultiple: 继续放置 + placeInverse: 反向放置传送带 + pasteLastBlueprint: 粘贴上一张蓝图 + massSelectCut: 剪切 + exportScreenshot: 导出截图 + mapMoveFaster: 快速移动 - placementDisableAutoOrientation: Disable automatic orientation - placeMultiple: Stay in placement mode - placeInverse: Invert automatic belt orientation - pasteLastBlueprint: Paste last blueprint - massSelectCut: Cut area - exportScreenshot: Export whole Base as Image - mapMoveFaster: Move Faster - lockBeltDirection: Enable belt planner - switchDirectionLockSide: 'Planner: Switch side' + lockBeltDirection: 启用传送带规划 + switchDirectionLockSide: '规划器:换边' about: - title: About this Game + title: 关于游戏 + # title: About this Game body: >- This game is open source and developed by Tobias Springer (this is me).

@@ -775,14 +865,18 @@ about: factorio sessions this game would never have existed. changelog: - title: Changelog + title: 版本日志 demo: features: - restoringGames: Restoring savegames - importingGames: Importing savegames - oneGameLimit: Limited to one savegame - customizeKeybindings: Customizing Keybindings - exportingBase: Exporting whole Base as Image + restoringGames: 恢复存档 #中? + importingGames: 倒入存档 #中? + oneGameLimit: 存档最多只能有一个 + customizeKeybindings: 按键设置 + # customizeKeybindings: Customizing Keybindings + exportingBase: 导出工厂截图 + settingNotAvailable: 在演示版中不可用。 + + + - settingNotAvailable: Not available in the demo. From 76bbee0b7c07c0873e33a7139e4728d12111a841 Mon Sep 17 00:00:00 2001 From: findaldudu Date: Wed, 17 Jun 2020 23:27:35 -0500 Subject: [PATCH 21/51] finish simplified chinese translation for v1.15 --- translations/base-zh-CN.yaml | 106 ++++++++++++----------------------- 1 file changed, 36 insertions(+), 70 deletions(-) diff --git a/translations/base-zh-CN.yaml b/translations/base-zh-CN.yaml index 8ad79ee4..5fa54bdc 100644 --- a/translations/base-zh-CN.yaml +++ b/translations/base-zh-CN.yaml @@ -19,7 +19,7 @@ # the basic structure so the game also detects it. # -# Chinese translation dictionary: +# Chinese translation dictionary. TODO: better names for the buildings. # Standalone:独立版 # Demo:演示版 # Level:关/关卡 @@ -47,7 +47,7 @@ steamPage: # This is the short text appearing on the steam page - shortText: shapez.io 是一个关于建造工厂is a game about building factories to automate the creation and combination of increasingly complex shapes within an infinite map. + shortText: shapez.io 是一款在无边际的地图上建造工厂、自动化生产与组合愈加复杂的形状的游戏。 # shortText: shapez.io is a game about building factories to automate the creation and combination of increasingly complex shapes within an infinite map. # This is the long description for the steam page - It is contained here so you can help to translate it, and I will regulary update the store page. @@ -57,13 +57,13 @@ steamPage: longText: >- [img]{STEAM_APP_IMAGE}/extras/store_page_gif.gif[/img] - shapez.io is a game about building factories to automate the creation and combination of shapes. Deliver the requested, increasingly complex shapes to progress within the game and unlock upgrades to speed up your factory. + shapez.io 是一款在无边际的地图上建造工厂、自动化生产与组合愈加复杂的形状的游戏。 - Since the demand raises you will have to scale up your factory to fit the needs - Don't forget about resources though, you will have to expand in the [b]infinite map[/b]! + 你将会需要随着不断上升得需求扩大你的工厂。当然,不要忘记你可以在[b]无尽[/b]的地图上开采资源! - Since shapes can get boring soon you need to mix colors and paint your shapes with it - Combine red, green and blue color resources to produce different colors and paint shapes with it to satisfy the demand. + 只对形状进行加工可能会使得你感到无聊。我们为你准备了颜色资源——将红、绿、蓝三种颜色混合,生产更多不同的颜色并粉刷在形状上以满足需求。 - This game features 18 levels (Which should keep you busy for hours already!) but I'm constantly adding new content - There is a lot planned! + 这个游戏目前有18个关卡(这应该已经能让你忙碌几个小时了!),并且正在不断地更新中。很多新关卡已经在开发计划当中! [b]独立版优势[/b] @@ -80,20 +80,20 @@ steamPage: [b]开发计划与玩家建议[/b] - 本游戏已开源,所有人都能贡献游戏内容!除此以外,我[b]非常重视[/b]玩家社区的反馈!我会阅读每一条建议并尽量顾及所有建议。 + 本游戏已开源,所有人都能参与开发游戏内容!除此以外,我[b]非常重视[/b]玩家社区的反馈!我会阅读每一条建议并尽量顾及所有建议。 [list] [*] 故事模式,建筑将消耗形状 [*] 更多的独立版关卡和建筑 [*] 不同的地图与障碍物 - [*] Configurable map creation (Edit number and size of patches, seed, and more) + [*] 可配置的地图生成(矿脉密度与大小、 随机种子以及其他地图设置) [*] 更多形状 - [*] More performance improvements (Although the game already runs pretty good!) + [*] 更多的性能改进(当然,现在游戏已经非常流畅了!) [*] 色盲模式 [*] 以及更多其他的功能! [/list] - Be sure to check out my trello board for the full roadmap! https://trello.com/b/ISQncpJP/shapezio + 记得查看我的Trello看板!那里有所有的开发计划!https://trello.com/b/ISQncpJP/shapezio global: loading: 加载中 @@ -164,8 +164,7 @@ mainMenu: contests: contest_01_03062020: title: "竞赛 #01" - desc: Win $25 for the coolest base! - #desc: Win $25 for the coolest base! + desc: 最6的工厂将能赢得25美元的奖金! longDesc: >- To give something back to you, I thought it would be cool to make weekly contests!

@@ -295,26 +294,18 @@ dialogs: createMarker: title: 创建地图标记 desc: 给地图标记起一个的名字。你可以在名字中加入一个短代码以加入形状。(你可以在这里生成短代码。) - #desc: Give it a meaningful name, you can also include a short key of a shape (Which you can generate here) markerDemoLimit: desc: 在演示版中你只能创建两个地图标记。请获取独立版以创建更多标记。 - #desc: You can only create two custom markers in the demo. Get the standalone for unlimited markers! massCutConfirm: title: 确认剪切 desc: >- 你将要剪切很多建筑,准确来说有幢! 你确定要这么做吗? - # desc: >- - # You are cutting a lot of buildings ( to be exact)! Are you sure you - # want to do this? exportScreenshotWarning: title: 工厂截图 desc: >- 你将要导出你的工厂的截图。如果你的基地很大,截图过程将会很慢,且有可能导致游戏崩溃! - # desc: >- - # You requested to export your base as a screenshot. Please note that this can - # be quite slow for a big base and even crash your game! ingame: # This is shown in the top left corner and displays useful keybindings in @@ -334,20 +325,6 @@ ingame: pasteLastBlueprint: 粘贴上一个蓝图 lockBeltDirection: 启用传送带规划 plannerSwitchSide: 规划器换边 - # moveMap: Move - # selectBuildings: Select area - # stopPlacement: Stop placement - # rotateBuilding: Rotate building - # placeMultiple: Place multiple - # reverseOrientation: Reverse orientation - # disableAutoOrientation: Disable auto orientation - # toggleHud: Toggle HUD - # placeBuilding: Place building - # createMarker: Create Marker - # delete: Destroy - # pasteLastBlueprint: Paste last blueprint - # lockBeltDirection: Enable belt planner - # plannerSwitchSide: Flip planner side # Everything related to placing buildings (I.e. as soon as you selected a building # from the toolbar) @@ -409,24 +386,16 @@ ingame: stored: title: 储存 description: 显示基地中每种图形储存的数量。 - # title: Stored - # description: Displaying amount of stored shapes in your central building. produced: title: 生产 description: 显示所有正在被生产的图形数量,包括中间产物。 - # title: Produced - # description: Displaying all shapes your whole factory produces, including intermediate products. delivered: title: 送达 description: 显示形状送达基地的速度。 - # title: Delivered - # description: Displaying shapes which are delivered to your central building. noShapesProduced: 你还没有生产任何形状。 - # noShapesProduced: No shapes have been produced so far. # Displays the shapes per minute, e.g. '523 / m' shapesPerMinute: 个/分钟 - # shapesPerMinute: / m # Settings menu, when you press "ESC" @@ -528,8 +497,8 @@ buildings: name: &cutter 切割机 description: 将形状从上到下切开并输出。 如果你只需要其中一半,记得把另一半销毁掉,否则切割机会停止工作! quad: - name: Cutter (Quad) - description: Cuts shapes into four parts. If you use only one part, be sure to destroy the other part or it will stall! + name: 切割机(四分) + description: 将输入的形状切成四块。 如果你只需要其中一块,记得把其他的销毁掉,否则切割机会停止工作! rotater: default: @@ -554,11 +523,11 @@ buildings: name: &painter 上色机 description: &painter_desc 将整个形状涂上输入的颜色。 double: - name: Painter (Double) - description: Colors the shapes on the left inputs with the color from the top input. + name: 上色机(双倍) + description: 同时为两个输入的形状上色,每次上色只消耗一份颜色。 quad: - name: Painter (Quad) - description: Allows to color each quadrant of the shape with a different color. + name: 上色机(四向) + description: 为形状的四个角涂上不同的颜色。 mirrored: name: *painter description: *painter_desc @@ -625,24 +594,24 @@ storyRewards: 小型合流机变体已解锁。它可以把两个输入合并到一个输出上。 reward_cutter_quad: - title: Quad Cutting - desc: You have unlocked a variant of the cutter - It allows you to cut shapes in four parts instead of just two! + title: 四分切割机 + desc: 切割机四分变体已解锁。它可以将输入的形状切成四块而不只是左右两块。 reward_painter_double: - title: Double Painting - desc: You have unlocked a variant of the painter - It works as the regular painter but processes two shapes at once consuming just one color instead of two! + title: 双倍上色机 + desc: 上色机双倍变体已解锁。 它像普通上色机一样为形状上色,只是它可以同时为两个形状上色,每次只消耗一份颜色! reward_painter_quad: - title: Quad Painting - desc: You have unlocked a variant of the painter - It allows to paint each part of the shape individually! + title: 四向上色机 + desc: 上色机四向变体已解锁。它可以在一个形状的四个角上涂不同的颜色! reward_storage: title: 仓库 desc: 仓库变体已解锁。它可以暂时储存一些材料,有容量上限。 reward_freeplay: - title: Freeplay - desc: You did it! You unlocked the free-play mode! This means that shapes are now randomly generated! (No worries, more content is planned for the standalone!) + title: 自由模式 + desc: 恭喜你!你解锁了自由模式!现在形状将会是随机生成的!(不用担心,我计划在独立版本中加入更多内容!) reward_blueprints: title: 蓝图 @@ -847,23 +816,20 @@ about: title: 关于游戏 # title: About this Game body: >- - This game is open source and developed by Tobias Springer (this is me).

+ 本游戏由Tobias Springer(我)开发,并且已经开源。

- If you want to contribute, check out shapez.io on github.

+ 如果你想参与开发,请查看shapez.io on github

- This game wouldn't have been possible without the great discord community - around my games - You should really join the discord server!

+ 这个游戏的开发少不了热情的Discord社区。请加入我们的Discord 服务器

- The soundtrack was made by Peppsen - He's awesome.

- - Finally, huge thanks to my best friend Niklas - Without our - factorio sessions this game would never have existed. + 本游戏的音乐由Peppsen制作——他是个很棒的伙伴。

+ 最后,我想感谢我最好的朋友Niklas——如果没有与他的异星工厂(factorio)的游戏体验,shapez.io将不会存在。 changelog: title: 版本日志 @@ -871,7 +837,7 @@ demo: features: restoringGames: 恢复存档 #中? importingGames: 倒入存档 #中? - oneGameLimit: 存档最多只能有一个 + oneGameLimit: 最多一个存档 customizeKeybindings: 按键设置 # customizeKeybindings: Customizing Keybindings exportingBase: 导出工厂截图 From 759dae4107f9bc7307fa7404a98834dd22385f3e Mon Sep 17 00:00:00 2001 From: Wessel <66781896+Ryoncai@users.noreply.github.com> Date: Thu, 18 Jun 2020 18:39:58 +0200 Subject: [PATCH 22/51] Update base-nl.yaml Added new translations, fixed some small errors, reversed some unnecessary/confusing translations, made the translations of the other person more consistent with the rest of the text. --- translations/base-nl.yaml | 94 +++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 48 deletions(-) diff --git a/translations/base-nl.yaml b/translations/base-nl.yaml index 0faf9955..df5f7546 100644 --- a/translations/base-nl.yaml +++ b/translations/base-nl.yaml @@ -32,7 +32,7 @@ steamPage: shapez.io is een spel dat draait om het bouwen van fabrieken om steeds complexere vormen te produceren en deze productie te automatiseren. Lever de gevraagde, steeds complexere vormen, om verder te komen in het spel en om upgrades voor je fabrieken te ontgrendelen. - De vraag naar vormen wordt steeds hoger, wat betekent dat je fabriek moet blijven uitbreiden om dit tegemoet te komen. Om de juiste grondstoffen te delven zul je steeds verder in het [b]oneindig grote speelveld[/b] moeten gaan werken! + De vraag naar vormen wordt steeds groter, wat betekent dat je fabriek moet blijven uitbreiden om dit tegemoet te komen. Om de juiste grondstoffen te delven zul je steeds verder in het [b]oneindig grote speelveld[/b] moeten gaan werken! Omdat simpele vormen snel saai worden, moet je kleuren mengen om de vormen te verven - combineer rode, groene en blauwe grondstoffen om verschillende kleuren te produceren en gebruik deze om de vormen te verven, zodat je de vraag hiernaar tegemoet kan komen. @@ -76,10 +76,10 @@ global: # The suffix for large numbers, e.g. 1.3k, 400.2M, etc. suffix: - thousands: d + thousands: k millions: M - billions: MJ - trillions: B + billions: B + trillions: T # Shown for infinitely big numbers infinite: inf @@ -154,7 +154,7 @@ mainMenu: showInfo: Laat zien contestOver: Deze competitie is voorbij - word lid van de discord (engelstalig) om berichten te krijgen van nieuwe competities! continue: Verder - newGame: Niew Spel + newGame: Nieuw Spel madeBy: Gemaakt door dialogs: @@ -249,11 +249,11 @@ dialogs: Hier zijn er een aantal, maar zorg dat je kijkt naar de sneltoetsen!

CTRL + slepen: selecteer een gebied om te kopiëren / verwijderen.
SHIFT: Houd ingedrukt om meerdere van het zelfde gebouw te plaatsen.
- ALT: Draai de richting van geplaatste lopende banden om.
+ ALT: Houd ingedrukt om de richting van lopende banden om te draaien wanneer je ze plaatst.
createMarker: title: Nieuwe markering - desc: Give it a meaningful name, you can also include a short key of a shape (Which you can generate here) + desc: Geef het een betekenisvolle naam. Je kunt ook een icoontje van een vorm toevoegen (die je hier kunt maken) markerDemoLimit: desc: Je kunt maar twee markeringen plaatsen in de demo. Koop de standalone voor een ongelimiteerde hoeveelheid markeringen! @@ -263,10 +263,9 @@ dialogs: Je bent veel gebouwen aan het knippen ( om precies te zijn)! Weet je zeker dat je dit wil doen? exportScreenshotWarning: - title: Export screenshot + title: Exporteer screenshot desc: >- - You requested to export your base as a screenshot. Please note that this can - be quite slow for a big base and even crash your game! + Je hebt aangegeven dat je jouw basis wil exporteren als screenshot. Als je een grote basis hebt kan dit proces langzaam zijn en er zelfs voor zorgen dat je spel crasht! ingame: # This is shown in the top left corner and displays useful keybindings in @@ -275,7 +274,7 @@ ingame: moveMap: Beweeg speelveld selectBuildings: Selecteer gebied stopPlacement: Stop met plaatsen - rotateBuilding: Draai een gebouw + rotateBuilding: Draai gebouw placeMultiple: Plaats meerdere reverseOrientation: Omgekeerde oriëntatie disableAutoOrientation: Schakel auto-oriëntatie uit @@ -302,8 +301,8 @@ ingame: speed: Snelheid range: Bereik storage: Opslag - oneItemPerSecond: 1 item / seconde - itemsPerSecond: items / s + oneItemPerSecond: 1 voorwerp / s + itemsPerSecond: voorwerpen / s itemsPerSecondDouble: (x2) tiles: tegels @@ -324,7 +323,7 @@ ingame: # Mass select information, this is when you hold CTRL and then drag with your mouse # to select multiple buildings massSelect: - infoText: Druk op om te knippen, om te kopiëren, om te verwijderen en om de selectie te annuleren. + infoText: Druk op om te knippen, om te kopiëren, om te verwijderen en om te annuleren. # The "Upgrades" window shop: @@ -337,7 +336,7 @@ ingame: # The roman number for each tier tierLabels: [I, II, III, IV, V, VI, VII, VIII, IX, X] - maximumLevel: MAXIMUM LEVEL (Snelheid x) + maximumLevel: MAXIMAAL NIVEAU (Snelheid x) # The "Statistics" window statistics: @@ -390,12 +389,12 @@ ingame: interactiveTutorial: title: Tutorial hints: - 1_1_extractor: Plaats een ontginner op een cirkelvorm om deze te ontginnen! + 1_1_extractor: Plaats een ontginner op een cirkelvorm om deze te onttrekken! 1_2_conveyor: >- - Verbind de extractor met een lopende band aan je hub!

Tip: Klik en sleep de lopende band met je muis! + Verbind de ontginner met een lopende band aan je hub!

Tip: Klik en sleep de lopende band met je muis! 1_3_expand: >- - Dit is GEEN nietsdoen-spel! bouw meer extractors en lopende banden om het doel sneller te behalen.

Tip: Houd SHIFT ingedrukt om meerdere extractors te plaatsen en gebruik R om ze te draaien. + Dit is GEEN nietsdoen-spel! bouw meer ontginners en lopende banden om het doel sneller te behalen.

Tip: Houd SHIFT ingedrukt om meerdere ontginners te plaatsen en gebruik R om ze te draaien. # All shop upgrades shopUpgrades: @@ -422,11 +421,11 @@ buildings: miner: # Internal name for the Extractor default: name: &miner Ontginner - description: Plaats op een vorm of kleur om deze te ontginnen. + description: Plaats op een vorm of kleur om deze te onttrekken. chainable: name: Ontginner (Ketting) - description: Plaats op een vorm of kleur om deze te ontginnen. Kan achter elkaar worden geplaatst. + description: Plaats op een vorm of kleur om deze te onttrekken. Kan achter elkaar worden geplaatst. underground_belt: # Internal name for the Tunnel default: @@ -512,12 +511,12 @@ storyRewards: reward_rotater: title: Roteren - desc: De roteerder is ontgrendeld - ! Het draait vormen 90 graden met de klok mee. + desc: De roteerder is ontgrendeld - Het draait vormen 90 graden met de klok mee. reward_painter: title: Verven desc: >- - De verver is ontgrendeld - Onttrek wat kleurstoffen (net als met vormen) en combineer deze met een vorm in de verver om ze een kleur te geven!

PS: Ik werk aan een oplossing voor kleurenblinden! + De verver is ontgrendeld - Onttrek wat kleurstoffen (net als met vormen) en combineer deze met een vorm in de verver om de vorm een kleur te geven!

PS: Ik werk aan een oplossing voor kleurenblinden! reward_mixer: title: Kleuren mengen @@ -537,11 +536,11 @@ storyRewards: reward_rotater_ccw: title: Roteren (andersom) - desc: Je hebt een variant van de rotater ontgrendeld - Het roteert voorwerpen tegen de klok in! Om het te bouwen selecteer je de roteerder en druk je op 'T' om tussen varianten te wisselen! + desc: Je hebt een variant van de roteerder ontgrendeld - Het roteert voorwerpen tegen de klok in! Om het te bouwen selecteer je de roteerder en druk je op 'T' om tussen varianten te wisselen! reward_miner_chainable: - title: Ketting Extractor - desc: Je hebt de Ketting extractor ontgrendeld! Deze kan grondstoffen doorsturen naar andere extractors, waardoor je efficiënter grondstoffen kan onttrekken! + title: Ketting-ontginner + desc: Je hebt de Ketting-ontginner ontgrendeld! Deze kan grondstoffen doorsturen naar andere ontginners, waardoor je efficiënter grondstoffen kan onttrekken! reward_underground_belt_tier_2: title: Tunnel Niveau II @@ -585,7 +584,7 @@ storyRewards: no_reward_freeplay: title: Volgende level desc: >- - Gefeliciteerd! By the way, het spel wordt in de toekomst nog verder uitgebereid in de standalone! + Gefeliciteerd! Even tussendoor, het spel wordt in de toekomst nog verder uitgebereid in de standalone! settings: title: Opties @@ -677,15 +676,14 @@ settings: super_fast: Super snel extremely_fast: Extreem snel enableTunnelSmartplace: - title: Smart Tunnels + title: Slimme Tunnels description: >- - When enabled, placing tunnels will automatically remove unnecessary belts. - This also enables to drag tunnels and excess tunnels will get removed. + Wanneer dit aan staat zullen tunnels automatisch onnodige lopende banden verwijderen. + Ook kun je dan tunnels slepen en onnodige tunnels worden ook verwijderd. vignette: title: Vignette description: >- - Enables the vignette which darkens the screen corners and makes text easier - to read. + Schakelt de vignet in, wat de hoeken van het scherm donkerder maakt zodat de tekst makkelijker te lezen is. keybindings: title: Sneltoetsen @@ -749,30 +747,30 @@ keybindings: placeInverse: Omkeren richting lopende band pasteLastBlueprint: Plak laatst gekopiëerde blauwdruk massSelectCut: Knip geselecteerd gebied - exportScreenshot: Export whole Base as Image - mapMoveFaster: Move Faster - lockBeltDirection: Enable belt planner - switchDirectionLockSide: 'Planner: Switch side' + exportScreenshot: Exporteer volledige basis als afbeelding + mapMoveFaster: Beweeg sneller + lockBeltDirection: Schakel lopende band-planner in + switchDirectionLockSide: 'Planner: Wissel van kant' about: title: Over dit spel body: >- - This game is open source and developed by Tobias Springer (this is me).

+ Dit spel is open source en ontwikkeld door Tobias Springer (dit ben ik).

- If you want to contribute, check out shapez.io on github.

+ Als je ook bij wil dragen, ga dan naar shapez.io op github.

- This game wouldn't have been possible without the great discord community - around my games - You should really join the discord server!

+ Dit spel was niet mogelijk geweest zonder de geweldige discord community + rondom mijn spellen - Je zou eens lid moeten worden van de discord server (engelstalig)!

- The soundtrack was made by Peppsen - He's awesome.

+ De muziek is gemaakt door Peppsen - Hij is geweldig.

- Finally, huge thanks to my best friend Niklas - Without our - factorio sessions this game would never have existed. + Tot slot wil ik mijn beste vriend Niklas bedanken - Zonder onze + factorio-sessies zou dit spel nooit bestaan hebben. changelog: title: Changelog @@ -783,6 +781,6 @@ demo: importingGames: Savegames importeren oneGameLimit: Gelimiteerd tot één savegame customizeKeybindings: Custom sneltoetsen - exportingBase: Exporting whole Base as Image + exportingBase: Exporteer volledige basis als afbeelding settingNotAvailable: Niet beschikbaar in de demo. From 11749625bd8473416231b80f678a1189a7c6ea61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pascal=20Gross=C3=A9?= Date: Thu, 18 Jun 2020 18:46:23 +0200 Subject: [PATCH 23/51] Resolved merge conflict --- translations/base-fr.yaml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/translations/base-fr.yaml b/translations/base-fr.yaml index f2c20cca..9f43384f 100644 --- a/translations/base-fr.yaml +++ b/translations/base-fr.yaml @@ -156,11 +156,7 @@ mainMenu: contestOver: Ce concours est terminé - Rejoignez le serveur discord pour être tenu au courant des prochains concours ! continue: Continuer newGame: Nouvelle partie -<<<<<<< HEAD - madeBy: Écrit par -======= madeBy: Créé par ->>>>>>> d6c1cb15f6854d88490fb76d3f5fe4729b3477be dialogs: buttons: From 773aecca563df1885e8b87035fe675eebbfa8a07 Mon Sep 17 00:00:00 2001 From: Killgaru Date: Thu, 18 Jun 2020 20:01:14 +0300 Subject: [PATCH 24/51] Russian translation updated Some fixes. --- translations/base-ru.yaml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/translations/base-ru.yaml b/translations/base-ru.yaml index 1c4311fc..fbb27c6c 100644 --- a/translations/base-ru.yaml +++ b/translations/base-ru.yaml @@ -76,10 +76,10 @@ global: # The suffix for large numbers, e.g. 1.3k, 400.2M, etc. suffix: - thousands: тыс. - millions: млн - billions: млрд - trillions: трлн + thousands: ' тыс.' + millions: ' млн' + billions: ' млрд' + trillions: ' трлн' # Shown for infinitely big numbers infinite: ∞ @@ -120,7 +120,7 @@ demoBanners: mainMenu: play: Играть changelog: Список изменений - importSavegame: Импортировать сохраненную игру + importSavegame: Импорт openSourceHint: Это игра с открытым исходным кодом! discordLink: Оффициальный Дискорд Сервер helpTranslate: Помоги с переводом! @@ -156,7 +156,7 @@ mainMenu: contestOver: Этот конкурс закончился - присоединяйтесь в дискорде, чтобы получать уведомления о новых конкурсах! continue: Продолжить newGame: Новая Игра - madeBy: Создано + madeBy: Создал dialogs: buttons: @@ -476,8 +476,8 @@ buildings: mixer: default: - name: &mixer Смеситель - description: Смешивает два цвета с помощью аддитивного смешивания. + name: &mixer Смешиватель + description: Аддитивно смешивает цвета двух красителей. painter: default: @@ -523,7 +523,7 @@ storyRewards: reward_mixer: title: Смешивание Цветов - desc: Разблокирован смеситель! Объедините два цвета в этом здании, используя аддитивное смешивание! + desc: Разблокирован смешиватель! Объедините два цвета в этом здании, используя аддитивное смешивание! reward_stacker: title: Объединитель From 2b6a8e49d1417a3a2b751b57b66948a6b1d46e7e Mon Sep 17 00:00:00 2001 From: Joker_vD Date: Thu, 18 Jun 2020 22:26:15 +0300 Subject: [PATCH 25/51] Only 14 characters for labels? That's 1/10 of a twit! --- src/js/game/hud/parts/waypoints.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/js/game/hud/parts/waypoints.js b/src/js/game/hud/parts/waypoints.js index ebd8ec6a..2472e57a 100644 --- a/src/js/game/hud/parts/waypoints.js +++ b/src/js/game/hud/parts/waypoints.js @@ -28,6 +28,8 @@ import { ShapeDefinition } from "../../shape_definition"; */ const SHAPE_LABEL_PLACEHOLDER = " "; +const MAX_LABEL_LENGTH = 71; + export class HUDWaypoints extends BaseHUDPart { /** * Creates the overview of waypoints @@ -220,7 +222,8 @@ export class HUDWaypoints extends BaseHUDPart { id: "markerName", label: null, placeholder: "", - validator: val => val.length > 0 && (val.length < 15 || ShapeDefinition.isValidShortKey(val)), + validator: val => + val.length > 0 && (val.length < MAX_LABEL_LENGTH || ShapeDefinition.isValidShortKey(val)), }); const dialog = new DialogWithForm({ app: this.root.app, @@ -270,8 +273,8 @@ export class HUDWaypoints extends BaseHUDPart { return 1; } return this.getWaypointLabel(a) - .padEnd(20, "0") - .localeCompare(this.getWaypointLabel(b).padEnd(20, "0")); + .padEnd(MAX_LABEL_LENGTH, "0") + .localeCompare(this.getWaypointLabel(b).padEnd(MAX_LABEL_LENGTH, "0")); }); // Show notification about creation From 5dc31e7e4083cb4e2f2d18136f7fa97f248430de Mon Sep 17 00:00:00 2001 From: Keriew <59965174+Keriew@users.noreply.github.com> Date: Fri, 19 Jun 2020 03:58:54 +0200 Subject: [PATCH 26/51] Fix a bunch of typos in the Polish translation --- translations/base-pl.yaml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/translations/base-pl.yaml b/translations/base-pl.yaml index 73a3674d..882f22ac 100644 --- a/translations/base-pl.yaml +++ b/translations/base-pl.yaml @@ -36,7 +36,7 @@ steamPage: Same kształty mogą z czasem być nudne, dlatego gra będzie wymagała od Ciebie malowania kształtów różnymi kolorami - Połącz czerwoną, zieloną i niebieską farbę, a powstanie farba o innym kolorze. Korzystaj z farb by postępować z kolejnymi poziomami. - Na tą chwilę gra oferuje 18 poziomów (które powinny zagwarantować rozrywkę na conajmniej kilka godzin!) ale bez przerwy dodaję nowe - Jest naprawdę wiele do dodania! + Na tą chwilę gra oferuje 18 poziomów (które powinny zagwarantować rozrywkę na co najmniej kilka godzin!) ale bez przerwy dodaję nowe - Jest naprawdę wiele do dodania! [b]Zalety pełnej wersji[/b] @@ -52,15 +52,15 @@ steamPage: [b]Zaplanowana zawartość & Sugestie społeczności[/b] - Ta gra jest open-source - Kaźdy może pomóc w rozwoju! Poza tym, słucham tego co społeczność ma do powiedenia w kwestii gry! Staram się czytać wszystkie sugestie i odbierać jak najwięcej informacji zwrotnych na temat gry. + Ta gra jest open-source - Każdy może pomóc w rozwoju! Poza tym, słucham tego co społeczność ma do powiedzenia w kwestii gry! Staram się czytać wszystkie sugestie i odbierać jak najwięcej informacji zwrotnych na temat gry. [list] [*] Kampania, gdzie do budowy potrzeba kształtów [*] Więcej poziomów i budynków (tylko w pełnej wersji) [*] Inne mapy, może z przeszkodami - [*] Możliwość modyfikowania parametrów generowanjej mapy (Ilość i rozmiar surowców, ziarno świata, itd.) + [*] Możliwość modyfikowania parametrów generowanej mapy (Ilość i rozmiar surowców, ziarno świata, itd.) [*] Więcej rodzajów kształtów - [*] Optymalizacja (Mimo wszystko gra już działa dośc płynnie!) + [*] Optymalizacja (Mimo wszystko gra już działa dość płynnie!) [*] Tryb dla ślepoty barw [*] I wiele więcej! [/list] @@ -117,7 +117,7 @@ demoBanners: # This is the "advertisement" shown in the main menu and other various places title: Wersja demo intro: >- - Kup pełną wersję gry, by odblokować więcej funckji! + Kup pełną wersję gry, by odblokować więcej funkcji! mainMenu: play: Rozpocznij @@ -211,7 +211,7 @@ dialogs: resetKeybindingsConfirmation: title: Zresetuj klawiszologię - desc: Ta akcja zresetuje wszystkie ustawienia klawiszologii do domyśnych wartości. Proszę potwierdzić. + desc: Ta akcja zresetuje wszystkie ustawienia klawiszologii do domyślnych wartości. Proszę potwierdzić. keybindingsResetOk: title: Reset Klawiszologii @@ -271,7 +271,7 @@ dialogs: title: Tworzenie zrzutu fabryki desc: >- Zamierzasz wyeksportować swoją fabrykę jako zrzut ekranu. W przypadku dużej - fabryki ta akja może być bardzo wolna, a nawet może spowodować zawieszenie się lub awarię gry! + fabryki ta akcja może być bardzo wolna, a nawet może spowodować zawieszenie się lub awarię gry! Czy na pewno chcesz kontynuować? ingame: @@ -403,7 +403,7 @@ ingame: 1_2_conveyor: >- Połącz ekstraktor taśmociągiem do głównego budynku!

Porada: Kliknij i przeciągnij taśmociąg myszką! 1_3_expand: >- - To NIE JEST gra "do poczekania"! Buduj więcej taśmociągów i ekstraktorów by wydobywać szybciej.

Porada: Przytrzymaj SHIFT by postawić wiele ekstratkorów. Naciśnij R, by je obracać. + To NIE JEST gra "do poczekania"! Buduj więcej taśmociągów i ekstraktorów by wydobywać szybciej.

Porada: Przytrzymaj SHIFT by postawić wiele ekstraktorów. Naciśnij R, by je obracać. # All shop upgrades shopUpgrades: belt: @@ -500,7 +500,7 @@ buildings: description: Koloruje kształt za pomocą koloru dostarczonych od boku. Koloruje 2 kształty używając 1 barwnika. quad: name: Malarz (Poczwórny) - description: Koloruje każdą ćwiarkę kształtu na inny kolor, używając dostarczonych kolorów. + description: Koloruje każdą ćwiartkę kształtu na inny kolor, używając dostarczonych kolorów. mirrored: name: *painter description: *painter_desc @@ -556,7 +556,7 @@ storyRewards: reward_miner_chainable: title: Wydobycie Łańcuchowe - desc: Odblokowano nowy wariant ekstraktora! Może przekierować obiekty do ekstraktorów przed nim zwiększając efektywność wydbobycia! + desc: Odblokowano nowy wariant ekstraktora! Może przekierować obiekty do ekstraktorów przed nim zwiększając efektywność wydobycia! reward_underground_belt_tier_2: title: Tunel Poziomu II @@ -578,7 +578,7 @@ storyRewards: reward_painter_quad: title: Poczwórne malowanie - desc: Odblokowano nowy wariant Malarza - Pozwala malować każdą ćwiarkę kształtu na inny kolor! + desc: Odblokowano nowy wariant Malarza - Pozwala malować każdą ćwiartkę kształtu na inny kolor! reward_storage: title: Magazyn @@ -742,7 +742,7 @@ keybindings: menuOpenStats: Statystyki toggleHud: Przełącz widoczność interfejsu - toggleFPSInfo: Pokaż Licznik FPS i infomacje do debugowania + toggleFPSInfo: Pokaż Licznik FPS i informacje do debugowania belt: *belt splitter: *splitter underground_belt: *underground_belt From 25957c86b150a7bdc9bab720a36115a3923c587f Mon Sep 17 00:00:00 2001 From: ananbaobeichicun <47203967+ananbaobeichicun@users.noreply.github.com> Date: Fri, 19 Jun 2020 21:17:06 +0800 Subject: [PATCH 27/51] L1-100 translated --- translations/base-zh-CN.yaml | 69 ++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/translations/base-zh-CN.yaml b/translations/base-zh-CN.yaml index 8ce591dd..320544f7 100644 --- a/translations/base-zh-CN.yaml +++ b/translations/base-zh-CN.yaml @@ -21,7 +21,7 @@ steamPage: # This is the short text appearing on the steam page - shortText: shapez.io is a game about building factories to automate the creation and combination of increasingly complex shapes within an infinite map. + shortText: shapez.io 是一个关于在无限大的地图内建造工厂来自动化生产和合并越来越复杂的图形的游戏。 # This is the long description for the steam page - It is contained here so you can help to translate it, and I will regulary update the store page. # NOTICE: @@ -30,46 +30,47 @@ steamPage: longText: >- [img]{STEAM_APP_IMAGE}/extras/store_page_gif.gif[/img] - shapez.io is a game about building factories to automate the creation and combination of shapes. Deliver the requested, increasingly complex shapes to progress within the game and unlock upgrades to speed up your factory. + shapez.io 是一个关于建造工厂来自动化生产和合并越来越复杂的图形的游戏。提交任务,制造更复杂的流水线,解锁升级来提升您工厂的运作速度。 - Since the demand raises you will have to scale up your factory to fit the needs - Don't forget about resources though, you will have to expand in the [b]infinite map[/b]! + 当需求提出时,您需要扩大工厂的规模来满足需求 - 不过不要忘记资源,您会扩张[b]无限的地图[/b]! - Since shapes can get boring soon you need to mix colors and paint your shapes with it - Combine red, green and blue color resources to produce different colors and paint shapes with it to satisfy the demand. + 由于纯粹的图形组合很快就会变得无聊,您需要调色并且给您的图形染色 - 混合红黄蓝颜色来生产不同的颜色再给您的图形染色以满足要求。 - This game features 18 levels (Which should keep you busy for hours already!) but I'm constantly adding new content - There is a lot planned! + 本游戏共有18关(会让您忙活几个小时)但是我会不断增加新内容 - 有好多都在策划啦! - [b]Standalone Advantages[/b] + [b]单机版的优点[/b] [list] - [*] Waypoints - [*] Unlimited Savegames - [*] Dark Mode - [*] More settings - [*] Allow me to further develop shapez.io ❤️ - [*] More features in the future! + [*] 路径点 + [*] 无数量限制的存档 + [*] 暗色模式 + [*] 更多设置 + [*] 允许我在开发 shapez.io 的道路上走得更远❤️ + [*] 在以后还有更多特性 [/list] - [b]Planned features & Community suggestions[/b] + [b]计划中的特性&社区意见[/b] - This game is open source - Anybody can contribute! Besides of that, I listen [b]a lot[/b] to the community! I try to read all suggestions and take as much feedback into account as possible. + 本游戏是开源的 - 任何人都可以做贡献!除此以外, I listen [b]a lot[/b] to the community! I try to read all suggestions and take as much feedback into account as possible. [list] - [*] Story mode where buildings cost shapes - [*] More levels & buildings (standalone exclusive) - [*] Different maps, and maybe map obstacles - [*] Configurable map creation (Edit number and size of patches, seed, and more) - [*] More types of shapes - [*] More performance improvements (Although the game already runs pretty good!) - [*] Color blind mode - [*] And much more! + [*] 要消耗图形来造建筑的的故事模式 + [*] 更多关卡&建筑(单机版独有) + [*] 更多地图,也许会有障碍物 + [*] 可配置的地图(Edit number and size of patches, seed, and more) + #括号里不会翻译了 + [*] 更多图形 + [*] 更多性能优化(虽然游戏运行地已经很好了!) + [*] 对色盲友好 + [*] 还有好多好多!(快买) [/list] - Be sure to check out my trello board for the full roadmap! https://trello.com/b/ISQncpJP/shapezio + 务必看看我的 计划版(trello board) 了解我的全部计划! https://trello.com/b/ISQncpJP/shapezio global: - loading: Loading - error: Error + loading: 加载中 + error: 错误 # How big numbers are rendered, e.g. "10,000" thousandsDivider: "," @@ -82,18 +83,18 @@ global: trillions: T # Shown for infinitely big numbers - infinite: inf + infinite: 无限 time: # Used for formatting past time dates - oneSecondAgo: one second ago - xSecondsAgo: seconds ago - oneMinuteAgo: one minute ago - xMinutesAgo: minutes ago - oneHourAgo: one hour ago - xHoursAgo: hours ago - oneDayAgo: one day ago - xDaysAgo: days ago + oneSecondAgo: 一秒之前 + xSecondsAgo: 秒之前 + oneMinuteAgo: 一分钟之前 + xMinutesAgo: 分钟之前 + oneHourAgo: 一小时之前 + xHoursAgo: 小时之前 + oneDayAgo: 一天之前 + xDaysAgo: 天之前 # Short formats for times, e.g. '5h 23m' secondsShort: s From 169ff6c9de64e4e12307ec90429da67e227f8daf Mon Sep 17 00:00:00 2001 From: Killgaru Date: Fri, 19 Jun 2020 18:12:08 +0300 Subject: [PATCH 28/51] Russian translation updated Another fix --- translations/base-ru.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/translations/base-ru.yaml b/translations/base-ru.yaml index fbb27c6c..6935440d 100644 --- a/translations/base-ru.yaml +++ b/translations/base-ru.yaml @@ -340,7 +340,7 @@ ingame: # The roman number for each tier tierLabels: [I, II, III, IV, V, VI, VII, VIII, IX, X] - maximumLevel: МАКСИМАЛЬНЫЙ УРОВЕНЬ (Скорость x) + maximumLevel: Скорость x (макс.) # The "Statistics" window statistics: From 0c0feac26c5315df09e4fd800fdad736c8c71c9f Mon Sep 17 00:00:00 2001 From: tobspr Date: Sun, 21 Jun 2020 18:04:35 +0200 Subject: [PATCH 29/51] Add kroatian translation prefab --- translations/README.md | 1 + translations/base-hr.yaml | 783 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 784 insertions(+) create mode 100644 translations/base-hr.yaml diff --git a/translations/README.md b/translations/README.md index 434e3dab..e799926c 100644 --- a/translations/README.md +++ b/translations/README.md @@ -26,6 +26,7 @@ The base translation is `base-en.yaml`. It will always contain the latest phrase - [Lithuanian](base-lt.yaml) - [Arabic](base-ar.yaml) - [Norwegian](base-no.yaml) +- [Kroatian](base-hr.yaml) (If you want to translate into a new language, see below!) diff --git a/translations/base-hr.yaml b/translations/base-hr.yaml new file mode 100644 index 00000000..8321e20b --- /dev/null +++ b/translations/base-hr.yaml @@ -0,0 +1,783 @@ +# +# GAME TRANSLATIONS +# +# Contributing: +# +# If you want to contribute, please make a pull request on this respository +# and I will have a look. +# +# Placeholders: +# +# Do *not* replace placeholders! Placeholders have a special syntax like +# `Hotkey: `. They are encapsulated within angle brackets. The correct +# translation for this one in German for example would be: `Taste: ` (notice +# how the placeholder stayed '' and was not replaced!) +# +# Adding a new language: +# +# If you want to add a new language, ask me in the discord and I will setup +# the basic structure so the game also detects it. +# + +steamPage: + # This is the short text appearing on the steam page + shortText: shapez.io is a game about building factories to automate the creation and combination of increasingly complex shapes within an infinite map. + + # This is the long description for the steam page - It is contained here so you can help to translate it, and I will regulary update the store page. + # NOTICE: + # - Do not translate the first line (This is the gif image at the start of the store) + # - Please keep the markup (Stuff like [b], [list] etc) in the same format + longText: >- + [img]{STEAM_APP_IMAGE}/extras/store_page_gif.gif[/img] + + shapez.io is a game about building factories to automate the creation and combination of shapes. Deliver the requested, increasingly complex shapes to progress within the game and unlock upgrades to speed up your factory. + + Since the demand raises you will have to scale up your factory to fit the needs - Don't forget about resources though, you will have to expand in the [b]infinite map[/b]! + + Since shapes can get boring soon you need to mix colors and paint your shapes with it - Combine red, green and blue color resources to produce different colors and paint shapes with it to satisfy the demand. + + This game features 18 levels (Which should keep you busy for hours already!) but I'm constantly adding new content - There is a lot planned! + + + [b]Standalone Advantages[/b] + + [list] + [*] Waypoints + [*] Unlimited Savegames + [*] Dark Mode + [*] More settings + [*] Allow me to further develop shapez.io ❤️ + [*] More features in the future! + [/list] + + [b]Planned features & Community suggestions[/b] + + This game is open source - Anybody can contribute! Besides of that, I listen [b]a lot[/b] to the community! I try to read all suggestions and take as much feedback into account as possible. + + [list] + [*] Story mode where buildings cost shapes + [*] More levels & buildings (standalone exclusive) + [*] Different maps, and maybe map obstacles + [*] Configurable map creation (Edit number and size of patches, seed, and more) + [*] More types of shapes + [*] More performance improvements (Although the game already runs pretty good!) + [*] Color blind mode + [*] And much more! + [/list] + + Be sure to check out my trello board for the full roadmap! https://trello.com/b/ISQncpJP/shapezio + +global: + loading: Loading + error: Error + + # How big numbers are rendered, e.g. "10,000" + thousandsDivider: "," + + # The suffix for large numbers, e.g. 1.3k, 400.2M, etc. + suffix: + thousands: k + millions: M + billions: B + trillions: T + + # Shown for infinitely big numbers + infinite: inf + + time: + # Used for formatting past time dates + oneSecondAgo: one second ago + xSecondsAgo: seconds ago + oneMinuteAgo: one minute ago + xMinutesAgo: minutes ago + oneHourAgo: one hour ago + xHoursAgo: hours ago + oneDayAgo: one day ago + xDaysAgo: days ago + + # Short formats for times, e.g. '5h 23m' + secondsShort: s + minutesAndSecondsShort: m s + hoursAndMinutesShort: h m + + xMinutes: minutes + + keys: + tab: TAB + control: CTRL + alt: ALT + escape: ESC + shift: SHIFT + space: SPACE + +demoBanners: + # This is the "advertisement" shown in the main menu and other various places + title: Demo Version + intro: >- + Get the standalone to unlock all features! + +mainMenu: + play: Play + continue: Continue + newGame: New Game + changelog: Changelog + importSavegame: Import + openSourceHint: This game is open source! + discordLink: Official Discord Server + helpTranslate: Help translate! + madeBy: Made by + + # This is shown when using firefox and other browsers which are not supported. + browserWarning: >- + Sorry, but the game is known to run slow on your browser! Get the standalone version or download chrome for the full experience. + + savegameLevel: Level + savegameLevelUnknown: Unknown Level + + contests: + contest_01_03062020: + title: "Contest #01" + desc: Win $25 for the coolest base! + longDesc: >- + To give something back to you, I thought it would be cool to make weekly contests! +

+ This weeks topic: Build the coolest base! +

+ Here's the deal:
+
    +
  • Submit a screenshot of your base to contest@shapez.io
  • +
  • Bonus points if you share it on social media!
  • +
  • I will choose 5 screenshots and propose it to the discord community to vote.
  • +
  • The winner gets $25 (Paypal, Amazon Gift Card, whatever you prefer)
  • +
  • Deadline: 07.06.2020 12:00 AM CEST
  • +
+
+ I'm looking forward to seeing your awesome creations! + + showInfo: View + contestOver: This contest has ended - Join the discord to get noticed about new contests! + +dialogs: + buttons: + ok: OK + delete: Delete + cancel: Cancel + later: Later + restart: Restart + reset: Reset + getStandalone: Get Standalone + deleteGame: I know what I do + viewUpdate: View Update + showUpgrades: Show Upgrades + showKeybindings: Show Keybindings + + importSavegameError: + title: Import Error + text: >- + Failed to import your savegame: + + importSavegameSuccess: + title: Savegame Imported + text: >- + Your savegame has been successfully imported. + + gameLoadFailure: + title: Game is broken + text: >- + Failed to load your savegame: + + confirmSavegameDelete: + title: Confirm deletion + text: >- + Are you sure you want to delete the game? + + savegameDeletionError: + title: Failed to delete + text: >- + Failed to delete the savegame: + + restartRequired: + title: Restart required + text: >- + You need to restart the game to apply the settings. + + editKeybinding: + title: Change Keybinding + desc: Press the key or mouse button you want to assign, or escape to cancel. + + resetKeybindingsConfirmation: + title: Reset keybindings + desc: This will reset all keybindings to their default values. Please confirm. + + keybindingsResetOk: + title: Keybindings reset + desc: The keybindings have been reset to their respective defaults! + + featureRestriction: + title: Demo Version + desc: You tried to access a feature () which is not available in the demo. Consider to get the standalone for the full experience! + + oneSavegameLimit: + title: Limited savegames + desc: You can only have one savegame at a time in the demo version. Please remove the existing one or get the standalone! + + updateSummary: + title: New update! + desc: >- + Here are the changes since you last played: + + upgradesIntroduction: + title: Unlock Upgrades + desc: >- + All shapes you produce can be used to unlock upgrades - Don't destroy your old factories! + The upgrades tab can be found on the top right corner of the screen. + + massDeleteConfirm: + title: Confirm delete + desc: >- + You are deleting a lot of buildings ( to be exact)! Are you sure you want to do this? + + massCutConfirm: + title: Confirm cut + desc: >- + You are cutting a lot of buildings ( to be exact)! Are you sure you want to do this? + + blueprintsNotUnlocked: + title: Not unlocked yet + desc: >- + Complete level 12 to unlock Blueprints! + + keybindingsIntroduction: + title: Useful keybindings + desc: >- + This game has a lot of keybindings which make it easier to build big factories. + Here are a few, but be sure to check out the keybindings!

+ CTRL + Drag: Select an area.
+ SHIFT: Hold to place multiple of one building.
+ ALT: Invert orientation of placed belts.
+ + createMarker: + title: New Marker + desc: Give it a meaningful name, you can also include a short key of a shape (Which you can generate here) + + markerDemoLimit: + desc: You can only create two custom markers in the demo. Get the standalone for unlimited markers! + + exportScreenshotWarning: + title: Export screenshot + desc: You requested to export your base as a screenshot. Please note that this can be quite slow for a big base and even crash your game! + +ingame: + # This is shown in the top left corner and displays useful keybindings in + # every situation + keybindingsOverlay: + moveMap: Move + selectBuildings: Select area + stopPlacement: Stop placement + rotateBuilding: Rotate building + placeMultiple: Place multiple + reverseOrientation: Reverse orientation + disableAutoOrientation: Disable auto orientation + toggleHud: Toggle HUD + placeBuilding: Place building + createMarker: Create Marker + delete: Destroy + pasteLastBlueprint: Paste last blueprint + lockBeltDirection: Enable belt planner + plannerSwitchSide: Flip planner side + + # Everything related to placing buildings (I.e. as soon as you selected a building + # from the toolbar) + buildingPlacement: + # Buildings can have different variants which are unlocked at later levels, + # and this is the hint shown when there are multiple variants available. + cycleBuildingVariants: Press to cycle variants. + + # Shows the hotkey in the ui, e.g. "Hotkey: Q" + hotkeyLabel: >- + Hotkey: + + infoTexts: + speed: Speed + range: Range + storage: Storage + oneItemPerSecond: 1 item / second + itemsPerSecond: items / s + itemsPerSecondDouble: (x2) + + tiles: tiles + + # The notification when completing a level + levelCompleteNotification: + # is replaced by the actual level, so this gets 'Level 03' for example. + levelTitle: Level + completed: Completed + unlockText: Unlocked ! + buttonNextLevel: Next Level + + # Notifications on the lower right + notifications: + newUpgrade: A new upgrade is available! + gameSaved: Your game has been saved. + + # Mass select information, this is when you hold CTRL and then drag with your mouse + # to select multiple buildings + massSelect: + infoText: Press to cut, to copy, to remove and to cancel. + + # The "Upgrades" window + shop: + title: Upgrades + buttonUnlock: Upgrade + + # Gets replaced to e.g. "Tier IX" + tier: Tier + + # The roman number for each tier + tierLabels: [I, II, III, IV, V, VI, VII, VIII, IX, X] + + maximumLevel: MAXIMUM LEVEL (Speed x) + + # The "Statistics" window + statistics: + title: Statistics + dataSources: + stored: + title: Stored + description: Displaying amount of stored shapes in your central building. + produced: + title: Produced + description: Displaying all shapes your whole factory produces, including intermediate products. + delivered: + title: Delivered + description: Displaying shapes which are delivered to your central building. + noShapesProduced: No shapes have been produced so far. + + # Displays the shapes per minute, e.g. '523 / m' + shapesPerMinute: / m + + # Settings menu, when you press "ESC" + settingsMenu: + playtime: Playtime + + buildingsPlaced: Buildings + beltsPlaced: Belts + + buttons: + continue: Continue + settings: Settings + menu: Return to menu + + # Bottom left tutorial hints + tutorialHints: + title: Need help? + showHint: Show hint + hideHint: Close + + # When placing a blueprint + blueprintPlacer: + cost: Cost + + # Map markers + waypoints: + waypoints: Markers + hub: HUB + description: Left-click a marker to jump to it, right-click to delete it.

Press to create a marker from the current view, or right-click to create a marker at the selected location. + creationSuccessNotification: Marker has been created. + + # Interactive tutorial + interactiveTutorial: + title: Tutorial + hints: + 1_1_extractor: Place an extractor on top of a circle shape to extract it! + 1_2_conveyor: >- + Connect the extractor with a conveyor belt to your hub!

Tip: Click and drag the belt with your mouse! + + 1_3_expand: >- + This is NOT an idle game! Build more extractors and belts to finish the goal quicker.

Tip: Hold SHIFT to place multiple extractors, and use R to rotate them. + +# All shop upgrades +shopUpgrades: + belt: + name: Belts, Distributor & Tunnels + description: Speed x → x + miner: + name: Extraction + description: Speed x → x + processors: + name: Cutting, Rotating & Stacking + description: Speed x → x + painting: + name: Mixing & Painting + description: Speed x → x + +# Buildings and their name / description +buildings: + hub: + deliver: Deliver + toUnlock: to unlock + levelShortcut: LVL + + belt: + default: + name: &belt Conveyor Belt + description: Transports items, hold and drag to place multiple. + + miner: # Internal name for the Extractor + default: + name: &miner Extractor + description: Place over a shape or color to extract it. + + chainable: + name: Extractor (Chain) + description: Place over a shape or color to extract it. Can be chained. + + underground_belt: # Internal name for the Tunnel + default: + name: &underground_belt Tunnel + description: Allows to tunnel resources under buildings and belts. + + tier2: + name: Tunnel Tier II + description: Allows to tunnel resources under buildings and belts. + + splitter: # Internal name for the Balancer + default: + name: &splitter Balancer + description: Multifunctional - Evenly distributes all inputs onto all outputs. + + compact: + name: Merger (compact) + description: Merges two conveyor belts into one. + + compact-inverse: + name: Merger (compact) + description: Merges two conveyor belts into one. + + cutter: + default: + name: &cutter Cutter + description: Cuts shapes from top to bottom and outputs both halfs. If you use only one part, be sure to destroy the other part or it will stall! + quad: + name: Cutter (Quad) + description: Cuts shapes into four parts. If you use only one part, be sure to destroy the other parts or it will stall! + + rotater: + default: + name: &rotater Rotate + description: Rotates shapes clockwise by 90 degrees. + ccw: + name: Rotate (CCW) + description: Rotates shapes counter clockwise by 90 degrees. + + stacker: + default: + name: &stacker Stacker + description: Stacks both items. If they can not be merged, the right item is placed above the left item. + + mixer: + default: + name: &mixer Color Mixer + description: Mixes two colors using additive blending. + + painter: + default: + name: &painter Painter + description: &painter_desc Colors the whole shape on the left input with the color from the top input. + + mirrored: + name: *painter + description: *painter_desc + + double: + name: Painter (Double) + description: Colors the shapes on the left inputs with the color from the top input. + quad: + name: Painter (Quad) + description: Allows to color each quadrant of the shape with a different color. + + trash: + default: + name: &trash Trash + description: Accepts inputs from all sides and destroys them. Forever. + + storage: + name: Storage + description: Stores excess items, up to a given capacity. Can be used as an overflow gate. + +storyRewards: + # Those are the rewards gained from completing the store + reward_cutter_and_trash: + title: Cutting Shapes + desc: You just unlocked the cutter - it cuts shapes half from top to bottom regardless of its orientation!

Be sure to get rid of the waste, or otherwise it will stall - For this purpose I gave you a trash, which destroys everything you put into it! + + reward_rotater: + title: Rotating + desc: The rotater has been unlocked! It rotates shapes clockwise by 90 degrees. + + reward_painter: + title: Painting + desc: >- + The painter has been unlocked - Extract some color veins (just as you do with shapes) and combine it with a shape in the painter to color them!

PS: If you are colorblind, I'm working on a solution already! + + reward_mixer: + title: Color Mixing + desc: The mixer has been unlocked - Combine two colors using additive blending with this building! + + reward_stacker: + title: Combiner + desc: You can now combine shapes with the combiner! Both inputs are combined, and if they can be put next to each other, they will be fused. If not, the right input is stacked on top of the left input! + + reward_splitter: + title: Splitter/Merger + desc: The multifunctional balancer has been unlocked - It can be used to build bigger factories by splitting and merging items onto multiple belts!

+ + reward_tunnel: + title: Tunnel + desc: The tunnel has been unlocked - You can now tunnel items through belts and buildings with it! + + reward_rotater_ccw: + title: CCW Rotating + desc: You have unlocked a variant of the rotater - It allows to rotate counter clockwise! To build it, select the rotater and press 'T' to cycle its variants! + + reward_miner_chainable: + title: Chaining Extractor + desc: You have unlocked the chaining extractor! It can forward its resources to other extractors so you can more efficiently extract resources! + + reward_underground_belt_tier_2: + title: Tunnel Tier II + desc: You have unlocked a new variant of the tunnel - It has a bigger range, and you can also mix-n-match those tunnels now! + + reward_splitter_compact: + title: Compact Balancer + desc: >- + You have unlocked a compact variant of the balancer - It accepts two inputs and merges them into one! + + reward_cutter_quad: + title: Quad Cutting + desc: You have unlocked a variant of the cutter - It allows you to cut shapes in four parts instead of just two! + + reward_painter_double: + title: Double Painting + desc: You have unlocked a variant of the painter - It works as the regular painter but processes two shapes at once consuming just one color instead of two! + + reward_painter_quad: + title: Quad Painting + desc: You have unlocked a variant of the painter - It allows to paint each part of the shape individually! + + reward_storage: + title: Storage Buffer + desc: You have unlocked a variant of the trash - It allows to store items up to a given capacity! + + reward_freeplay: + title: Freeplay + desc: You did it! You unlocked the free-play mode! This means that shapes are now randomly generated! (No worries, more content is planned for the standalone!) + + reward_blueprints: + title: Blueprints + desc: You can now copy and paste parts of your factory! Select an area (Hold CTRL, then drag with your mouse), and press 'C' to copy it.

Pasting it is not free, you need to produce blueprint shapes to afford it! (Those you just delivered). + + # Special reward, which is shown when there is no reward actually + no_reward: + title: Next level + desc: >- + This level gave you no reward, but the next one will!

PS: Better don't destroy your existing factory - You need all those shapes later again to unlock upgrades! + + no_reward_freeplay: + title: Next level + desc: >- + Congratulations! By the way, more content is planned for the standalone! + +settings: + title: Settings + categories: + game: Game + app: Application + + versionBadges: + dev: Development + staging: Staging + prod: Production + buildDate: Built + + labels: + uiScale: + title: Interface scale + description: >- + Changes the size of the user interface. The interface will still scale based on your device resolution, but this setting controls the amount of scale. + scales: + super_small: Super small + small: Small + regular: Regular + large: Large + huge: Huge + + scrollWheelSensitivity: + title: Zoom sensitivity + description: >- + Changes how sensitive the zoom is (Either mouse wheel or trackpad). + sensitivity: + super_slow: Super slow + slow: Slow + regular: Regular + fast: Fast + super_fast: Super fast + + movementSpeed: + title: Movement speed + description: >- + Changes how fast the view moves when using the keyboard. + speeds: + super_slow: Super slow + slow: Slow + regular: Regular + fast: Fast + super_fast: Super Fast + extremely_fast: Extremely Fast + + language: + title: Language + description: >- + Change the language. All translations are user contributed and might be incomplete! + + fullscreen: + title: Fullscreen + description: >- + It is recommended to play the game in fullscreen to get the best experience. Only available in the standalone. + + soundsMuted: + title: Mute Sounds + description: >- + If enabled, mutes all sound effects. + + musicMuted: + title: Mute Music + description: >- + If enabled, mutes all music. + + theme: + title: Game theme + description: >- + Choose the game theme (light / dark). + themes: + dark: Dark + light: Light + + refreshRate: + title: Simulation Target + description: >- + If you have a 144hz monitor, change the refresh rate here so the game will properly simulate at higher refresh rates. This might actually decrease the FPS if your computer is too slow. + + alwaysMultiplace: + title: Multiplace + description: >- + If enabled, all buildings will stay selected after placement until you cancel it. This is equivalent to holding SHIFT permanently. + + offerHints: + title: Hints & Tutorials + description: >- + Whether to offer hints and tutorials while playing. Also hides certain UI elements onto a given level to make it easier to get into the game. + + enableTunnelSmartplace: + title: Smart Tunnels + description: >- + When enabled, placing tunnels will automatically remove unnecessary belts. This also enables to drag tunnels and excess tunnels will get removed. + + vignette: + title: Vignette + description: >- + Enables the vignette which darkens the screen corners and makes text easier to read. + +keybindings: + title: Keybindings + hint: >- + Tip: Be sure to make use of CTRL, SHIFT and ALT! They enable different placement options. + + resetKeybindings: Reset Keybindings + + categoryLabels: + general: Application + ingame: Game + navigation: Navigating + placement: Placement + massSelect: Mass Select + buildings: Building Shortcuts + placementModifiers: Placement Modifiers + + mappings: + confirm: Confirm + back: Back + mapMoveUp: Move Up + mapMoveRight: Move Right + mapMoveDown: Move Down + mapMoveLeft: Move Left + mapMoveFaster: Move Faster + centerMap: Center Map + + mapZoomIn: Zoom in + mapZoomOut: Zoom out + createMarker: Create Marker + + menuOpenShop: Upgrades + menuOpenStats: Statistics + + toggleHud: Toggle HUD + toggleFPSInfo: Toggle FPS and Debug Info + exportScreenshot: Export whole Base as Image + belt: *belt + splitter: *splitter + underground_belt: *underground_belt + miner: *miner + cutter: *cutter + rotater: *rotater + stacker: *stacker + mixer: *mixer + painter: *painter + trash: *trash + + abortBuildingPlacement: Abort Placement + rotateWhilePlacing: Rotate + rotateInverseModifier: >- + Modifier: Rotate CCW instead + cycleBuildingVariants: Cycle Variants + confirmMassDelete: Confirm Mass Delete + pasteLastBlueprint: Paste last blueprint + cycleBuildings: Cycle Buildings + lockBeltDirection: Enable belt planner + switchDirectionLockSide: >- + Planner: Switch side + + massSelectStart: Hold and drag to start + massSelectSelectMultiple: Select multiple areas + massSelectCopy: Copy area + massSelectCut: Cut area + + placementDisableAutoOrientation: Disable automatic orientation + placeMultiple: Stay in placement mode + placeInverse: Invert automatic belt orientation + +about: + title: About this Game + body: >- + This game is open source and developed by Tobias Springer (this is me).

+ + If you want to contribute, check out shapez.io on github.

+ + This game wouldn't have been possible without the great discord community around my games - You should really join the discord server!

+ + The soundtrack was made by Peppsen - He's awesome.

+ + Finally, huge thanks to my best friend Niklas - Without our factorio sessions this game would never have existed. + +changelog: + title: Changelog + +demo: + features: + restoringGames: Restoring savegames + importingGames: Importing savegames + oneGameLimit: Limited to one savegame + customizeKeybindings: Customizing Keybindings + exportingBase: Exporting whole Base as Image + + settingNotAvailable: Not available in the demo. From fd70130ec4a75e0fa9b727af45c0e8546bb7c2ec Mon Sep 17 00:00:00 2001 From: tobspr Date: Sun, 21 Jun 2020 18:11:10 +0200 Subject: [PATCH 30/51] Update artwork and sound --- artwork/steam/devlog.png | Bin 0 -> 16129 bytes artwork/steam/devlog.psd | 3 +++ artwork/wires/prefab.png | Bin 0 -> 134900 bytes artwork/wires/prefab.psd | 3 +++ res_raw/sounds/music/theme.mp3 | 3 --- res_raw/sounds/music/theme.wav | 3 +++ src/js/changelog.js | 5 ++++- 7 files changed, 13 insertions(+), 4 deletions(-) create mode 100644 artwork/steam/devlog.png create mode 100644 artwork/steam/devlog.psd create mode 100644 artwork/wires/prefab.png create mode 100644 artwork/wires/prefab.psd delete mode 100644 res_raw/sounds/music/theme.mp3 create mode 100644 res_raw/sounds/music/theme.wav diff --git a/artwork/steam/devlog.png b/artwork/steam/devlog.png new file mode 100644 index 0000000000000000000000000000000000000000..8e5c29e631271f2242b56014750672ac65cb031b GIT binary patch literal 16129 zcmdUW2UJtr)-IreihvDJ1VI!F5JC+Egd9OsM2eIUKuQP+ozOc0MdSd26;O&CP^5(} zy?3RzP^5$+z1L6zc{}LwdhfXB{^x)1{o{?t7{Rdi+_SAYzd6_3+dy^I+e}9}j?&Q3 zFe%-+sX;??fQN>Lw(2k)u=0jhIu`inh}|7sM;aQ&Q`8SFO=R>L;0wk=3*m%NxhIXn z+6W;{u_kCCHyb;Enug{&%*_sovO+uYn4rxpY-M>Di_3X=EKFs2btF`TRqPbd<`#E6 z9MGB`s#+)yD-_g}7beGZ-Ax)`V1sr-^0?Vp+d4|S$@1>=l?J|3m%+R|`y@_Qvb;B_ z0(lTB>O2Zq2Q-g_5Cnu05trbRgbIm3#KfUcK^{?I5h<{+6j($IBm$8Z7nT+k<@xc$ z3rKS?#Yk)1y!AsC@RuyFxs#KfG#Kpa>MG-fV>fWyFUNIS5IkTBJx zeL_>zPdYni2kU*|rYJDl8f}BNb#eq~MSju(UQ$u{N&auy+SvT0c63s70W|ty+rOoD z)N;2&gEi2OSZ4d9$54)(Puqj{OTK{Ji{6u5hxz z{Dna3m46~dyIK4NDfP-vQafn{2Q<!5|jTK^e4>VN9Sqo6>I6)4YD9Sd7itgGWS zs_j4SLEl6=p=EhRg++xy!Vr+KxR$7hw6LhOn79D&TUhuzsR|ICrbs8`KNE{cYKaO< z3rk3gO8yfu*3<&y{$G-sqNFic2OA`?cNR8CGc?%F)@)yzii)(7t)mmt7KK*2Da#9} zDr8|{DlI7vMN5bx(I62Kv?K^4DJ~8|ib^6uXe0`W5`&;5P*AZy@4tyfIaA|`djIzn zGsU6+9zQokS{!YHhC+}gASo#c2uMU!TnvPSnn;37C8VUFP$>~n5$Jc@0d3SAEPyOW zTK~$Gs+B3g(L_W-QdCsj1SE;Z0C|WK7Xg`|Q5Xj;) zULI=5Nbk$n1kejm03snFCh=ok-NFrRjksw6c+GKN5h<#u{af}g>Hcy_Ttb)%5Bq5< zeaFHP2t4;6fTM}F|MAV*f@eQ7rID!bMxdx6iZb_|ARfs9BFHY2I>)*_kZ6W5eO23hDbs{XkluuA;qB} zs3ckhgc21&iJ+yV(5BQ7`FHmG8({dKw+Dr_bwNA)5@B{o2P9Bd(GHHXych?p4G+@J z&e{UCpJ-qgThkxa>Su29IAMAIfkc1lH&e8O#V?WYtCXKA@cdtt_g}`{-vh?~7yAUJ zb`0Mk0sOCM@%`_c-<^4jx;^`qSo+`L!rzTVpfpPZK>ri^|9c?)T|V~z6zr*i^E0NT zwa{)(_mJ*D5dOdwd8FAt5au6r`!uRRyvp+4RD|DCyUlY^SQsb<|3X1!_sRV>Nlo=H*#28mD*yd`{H{3oA42}gw0)9an#Diw0yQ8Ep$7lmpNj*Q#1Pp`j7Gp>*?xmfP3)L5qUR+Q=(QQ7juZPJV|U*M?xU zO-~(qh*3Y0$<+2~YWVl6q*Lv`+eaxqIwLN!`FqmY2fVi~v>&_rl-WF(L*zHc27gt7 zUOJnqA>Qm>-i~4O9dwIZormF~!;q$S;?Vpaj@v6;h2%M#Chgop5p-VT+m7%>CGMZ}KX`dAH%cokbSd0~uNG*|dBE*WGoY z<>P5m8*g?=M9Nt;ACIeg!R+86i^LcY%Ix;~Y&B)bzMji!PXZx>56*3DQD%{u%Ty0{ z>9@(Zd#)TIwCe}k^qVQS9Vl3?WZ*tVs$!BHl6oXbN7w!42&q3pCoS?m`=`^39qKzo zkA54j!33;#V-(SI;;jPAGnU+yxHs2IF=?SVt&)10UE$!OsrVksmvhBscpXFg+Pr>S znH|{fD0{ivmu2w0etD}a`5eT$*ORzgm-;-Q!=Z-JsGwDDr^#J@;&j=>+S(f0XsZGE z%w*a&y;7B)_MN;w`G+6#j165U$)I2`y<{e(QK)#XrFa2e$RxN|wxvdN`g|eaTSR(_ zulKeXMLhGv`hsiB@}o%@rQ!ff6Xi-=dckZzDO=FBG#_TixnfKQ=j%A z`3@suY?443|5m<($d^=Ocb$%${TRE|WX8NZ=WjTDBS0`}6((y(e0FMn6xZqjPh77} z+}k^K<(=E87iC?INS<(-QHcoBDVx!*4&rhaYmiZunNNBjnnGAXmvp_vr9<(F^FLTR(_4aiOf4 z$#vEm9FHeh8LdW^xtbIC8ELH^(&L2|I@(zfMtdFXEHLuY*4_vMY%NZ;f39Xz*W5dw zxU6Jzw-%x0GJh`YtRktJd+Scm?&g`aleL(G=N2CkcXKn`*XLm6E*?d2B%`8aOTvbS zY3Ik(jItu*3?5Sw>7DyT5Uapl?_qR=!A8R?)rEKo8BZFln~in!ob z7S(B$D^6xQEOwORT0QlKK<~LTJ6^qs8<$z&t9R{zdylPT#_w){U z!Qn|NZrNOg?c{9jS+xxJZPMe{T){7Ool6gYw!0$QPo!xaSI_sAZDM}Wiy!s#Q3 z3kEShL+-VXcFP@M=WlS|ogWm`JAwd&5Hjn#-KIyU81Ta>0(*Q}A3hcHU)=R{4EG7K zsF+D=lq+T>Zx&95M~=*oUVAl~-*0CXM?MrBm=JJI(ssbTXYdx(fVBw`^Dz~3R$$F* z$Y~}yL@fr;{RqM@b*-M)IN`RYw4U<`>+P-Tz!y*1&%0|iYKTOJ4H|c7k3V%SP2GKo zf0&SZq7}itJSn?vKm;9JM>LAuehd+4!|`#u`6S!4Mr-&xzAq0Rz+7lkyPJ&7D;COj7My3h*Y}VE zX9ddDSU1&pmUBopXN@PLu?E$64?P`Sx5Tif8kHRZ*%5Ol#9K=KEZZ6J8 zTbBjvD*41hoy2F^@#1UJHLin3pUAbfu}gPbnN3^rp6XQS+0Ti@?#!7v?oG@P zQd?yxF2r(wr4MWJsrC zr;6`4CS$!&#A2TEh^zY^95IP;kAVEn5y;{GVS8%&)+cm=QT~%=nAjL=rUOS@m6VuhQRpb^{gHhwZvA-wEDwU z4DWz=o33o6zc?^GxM&jSLDV%HSF z4+_#+4LxrsZLJn5U#{mfP7v4~4TwD7_@&hmbvko9^Z>y|%VS*7%z_QR-C~dJ%^Z2% zQyy1IV|LYH(tGCBw7Hb!DgVH3$@0uFy=yRi;z%k+jj(PIWaxTaV6f91l04{Y;Db3H z?H!0pPkDm5V!S9z8$2SO097M)anx``_(~A4)3^FSgPjJwWU=c)VFtuF{|$kJZAdy( zgTAzjTCQQpyBrsslaNVr5B-PtE>W@^9r<=S+8^$FoG?ryFnjA5Nu1A{lQ|T-T5+2- zbJU7nsBo?0Y^~aUa7=6uQF1Z*bytlOW_Ppoi>~NB(hFNJ&~ot($Oz)JB--PPRCGM1 z;>SDEo1RKY=POB9O)$I%JZqIO60SyGpTF?UHK@ZsWt@ZJ)Cw}A0Y8Z0Qx1RNPS9Re z6xoL?z3Kk+ZyC@t?|s7-D69h=vV$kP^cE!mLp)SJ3@hh$ih1M;nQZrUBs(yE*k-=& zwER@DudW!L@kiI)Exik6yP^#mv9XAHxT*eFI?QNaYxp(kKj|p2$I2Bmd3CMC68jQ5c#$o?^UG798-rI~*2QNltLdNiiE$~KnuvY1Hu;)M z`!0)Rp6+!mbrZwlE_k?&i@(ZR=-rr#4Od&~T=ui4RLlxC@}u_A#wJ0>WV|O42wM8K z@_UlP&OX#q5h&W`fWGJF_|nMf6q5_PegWU8aw51!P{VdLYM$y@F2iK#l#|W{GgiGF zwKLnv$EiV>+Fva0gEOV7rwhtX@RTm>wlN0Ov!dMkqv+%-^{oV38m5imsG-p9^ILpr zfbY&0_3H~zTpHi{&#iIYfacon7{>3bHRzJOI{PS#5n-Tqj8CrohVQxEhVDkLa_EBzbE&nhTm?ijKr+WdPD|E;mzjW&}hm+9l^6YaB zC-S(N?sB`ZKU)v^oZtmi0;!3q_hytWpy!EjV-_E1d>dQtG~H2yVaS0^J_K5-{(j<+ zWa&QE`}<1F&|0Om9n|!*e?iZveycoNKw?E?*eFsi%ivxw6Rycx6=bB?;~#ApvakGM z1nPKZP|1_Rh0k|${F~kz^)aC>?(cMVv}?rGjbMzye4LfOVL78J)IbqDh!;7Gm|lJc zX@y=1&z0!cQL31k`gCkIlf?j1&t>1Zy&fV7-uJI^g?t4EtD?*4Xi(`uaUb(!wrAC~tHXlls?5*2)5K2#Gys%v@Is*vd@U6*&@9FzVdq@50$ns7SXs>SIQA61nU)Dp< zC~t0RoLNmzuaNuZRVC}$zw=BzHBU5_POQn(&h0>YyjpxuXb=z6JBgYM>swMw0 z(qKBiS-JHjfDSd2pWbo<4#LykAs*UF<-wHfrT}8r;@M5@w(O`2RPVC^t??mz^0%+aP4Ek)kI{nR?+znE zSY&n$8@&#AvLjv7oL_{k>~GQqW0gA|-afNs z#oamh6w>OxAI(7Mh0_YiD!*AhtZj0D6u#<54RM;l(!tf+?}~(yesB!Yt*|8esWm)r_y#c)9%)d+jh^Ed1dnRAIY0=G-eo?`T970f)>0mO~oHXQdH8bRsDEcjVTH8+mYPn|Ne>c0|&3 z|IUEdP&>gqt8p2AynBX+&-O7PRfn7Oatx5p2*}s_omQaz-sQ-*HQQnI8NqCsbt1;| z*{dCzYO>CapuDLaN!MOvz|GU=x)TJQDQvpez(3sj;ShdJaKua5>6E^4gr4|i;}Exs z6uuYoMP;w!@GWoYPF=a+1p1hm=qTs)!!racbsCNza8~m9i#}JxdYOgv%=mYP;Eph6=a?qXYK_Y_A z0t|m+XUYERw9=O{u{GpM;q4U<nf9PEno`1OuS-EwCHnq6(<=(-4p+Lw}(>Mr9ZR_l} zdM0-=N?GVH!#{k^7glLpFfkl$)x|# z?#api{GvJX@WF%l(9q1?%)Vh3&#Nd*dl2fG`%eE*p4;;15bPMmwJct4JxV3>yysk2 zGz-zTcz&Y4S{6>1LlO2`fpYKJrFq}m*U2P0$l0XIq>>(ABZ$mR@C002RJ?QVH*^F} zif1=IPUwlLsL@h~^<<6+6M`x9iqA3d2^Yo%otFjE^lX_9kbLFWO_c}n8`{tJRUL#Q zwy^ncGJV73Kw!PS(b@EJxf4}El1-@leSAaT5ZCS5$RU9&*NUH~V_mo#VqPA;l}m5J zaOzqISCt0Iz+^G3>G<_G1#jI}Q9JCX_8m_^IvZIHBddUtv=X%LX2OxR`86ghX|6-r zD+s8Sba-Ax$xBZa!a)L_y@5GeGqrbfFAbIJ&bBm1YcGmxM@T;m%nf@RCuWerR>)p- zUW|>3H>uTU?$7q97*^cX%C_oB_a3~K*rZeJETSg{l=q_h*ZLb&*F7%_QTP<6{U4yO zNX{-~Ludj!5mq!{kxZ=(&dbbFj)ny)h$eh%HLbH60wm?DkeKiu1WqI(=ckqQ|$7yR~|chc@RAVA6h^OvLe#Y=ifMO`-SJIv#GvEPo~pJ+^l^XU!5HL-kb z)W#jYnyVqFY0{N8KL1?qLT;I|M_maz?ajiM({Ep~?zkF4pPH8N>QwC^WD^;FTvKR!V6p@3X;EUDvd9A${DSq|@k#acR><-0-WiH08!JNOM_d$H(XtZE z13DRvK0Zz|^+cKmx>t?fp1LjflDW@$aiL5p>4v2m_=bR6)jklXNS_+_G`j04ZlYb+25O@kc^fdOU%wK@x zHlr!+`M-zHi~&}6KVn40brQ5$qsAtkMNoB3s;^)uK%M5EJ zF$N9L?W1VO17{d7ZEA2|c=VBs^RMz2gnXMY0s46=8Xh95q^_i z=gbRJl5d#3?*p|NPu!r^7d)-ReQp?OppLM6kOAMsmfuN=eu}Dy+-^QNE29Q0o&A_l z88mTUYHs9XYBH{qxK)`11XgLGMHih>d zOoa>I9pD<2-4NL+{&w9|df<5U)|uhoPhZ*BE;6{aC)#tNP|>#K3o~MR_e`SnJ8n*r zueP_pCULV)!{2m$hG14onWMe##m-UNNwn8{LHkl&s&%*K%B>XLqwIX-MY)~1oN+dN zEuT%GhUcdEAOC|opj@hsYs5`<@3fbam>rlu8GB8CatdpB6i2r|7aKeaKr{Zx>m291 zje0ns1Bmb*7eEKRX2|&}o(SuyeSMP{!Xy*J-30ZmG^a=?r0r%$lzpD5*q7B_n&-uWu(4DF_iy<7Qqg`Hf{##cK1G3va>RNR7Xpq*sd*r(1XxS1iJjXo}w zvd2N5w-`zt=GWF}q#db)QxeC_nGw)zPei21k%aLNz=(4g+S+Fp>+SIMO`AZ$Sg4E; zrB3q6kOi~SEHFkqcDoG7-7ECU@~1Y3{aA*86t49Y{l=cjex0)AIiIW3VyGMEL2hv^ z_Z;zOXLg%`I3=oi)e4B_-58!g?h3nf$T$E$}Lr0z8VIG)0 zFHg3^z8<=2_{Vc&%$lCUUAN7Vfb#V;Y)F+yK{8Rbr{%Etm;*a-Kh0qT4GkUJ{>Rt% z5Dj(dFP5p4Kd7mce^UR4<-f=GySS$Tr5k-23o!So#B+-~%cZY8DSzy?#TDB;N%~6>39s#^qHrpbDEhlW99d+K?CHi<3pi^LlX4M9-47@KGhm3l= zH8n)Yl5+y&)|Xk>w<>y~9cEnm7ngPy2bb0}yplgNyt5nqBC}YuqoZTs(5N!oQNHG5 zISNrMN?i}<%?Ge%{Gl3Men zi#aa6%S!sP_Omrco=XpReB4Meu!8ZAv^s72wp)+K>p4lU6X(|o>OqmK-~s1)8)DgZ z%0n*g0=x3P^$DNNn);%{E?H-cmY&60lbx#wWVH;bYvku;MnT^O&8|BxUV*J!1eTvt z?RthQK<+jZ7Z>grx^)G!NSW*I2x!FQ3k`U-vcPuKCMRE~I=0}jjl|r!O!m2wM%%zy zjhXnGC+{~)kB3rVauolOk9$>$?B+3t@JdS?oh^scbfPRv^P%Kd`DD_PLS+pb%i)9bPz+{U$7DSJ)NSZvlNjQwY?1NVV#k&Nv}Va z12{l-%4?&B_Soa@?QQo^GIVWVoG*nS zlDJ7Dtf4Dv^gK)c7g`3cY+??}Vf1Crj>u_jgi3KM$})1e0vuR-gLUH{6`gddrYzn8r>UB z)TrGS08{kFl={gBf>ECow^?!+P?jo=t;Z(|t3pcLS2L>CK{!YxYt)darpq59w>p;I zdM=b=e`l=C_>4G+xAQQvU$Ij7a-?TGGBy2k$>@j?$a84KKICRjWy_E+!J$_hDBPEI z37AhAq9zQ|U30euVMU)WDUvJ7(poa<;MN3q+1&Vrqg|HQpPb1|K?|e`ZF%M7l|&ZK z+V=io*(j#tRs+_~j8~g73C|oR8%t#x?XE;5*jDuEe9+BGmba^1WxF_ih_d-bDyXlv zWF9z1^BYLa&TBdA_{D30hP(&j72|@0a;M-_J=F0jdM@rL2I=%Nj~xp$>!FfDv{eLg z=9q}F$~vBO%=y8DbRO~$-qJK_JPD^Q;o6l_>+hN?YK39LW(4b2JzDj%=eZJHk?fH3 z*uE%Fy=*292k1!gN+hcStAUo&*94PLQ zzh&XDedF^smrTIr-vt93C1HR&0LA;Vs#(1Fm{fe@z2!z6JdCRzdsMD0@^Es(Eibb* zyPzhPI)QVHrpdZhX9mBjE!A4a-C5ObW~oz{VTxe9WGpe&lhEmyHc9KLQ(spF|CUYd z=MDztIyTmccE1xDZ%W#W49vQg_~ML5MM`%+CiLtv0ps!54zf%Bre3V&$((MQd-!Dr zv8N}3J(9tOE;wQ4t99_4&w@x!cm9_jQfa$34ulZM#!YNuWqb065zB@`+4!`|A?Z@u z)FS-+;$f%4QzEEQQvepM~g3NtHR<0 z+I9At91Jn|Op_0D1XT$f&}Kr{FY{U~8VdVG^Ktt7YJX53nCQd|*d{^jR)ms%o>ki9bGgT@$?w!&X*fqQS2H2)jSEt4s{-bIt zY<+!hEwn2Sn@@(yR|JvnRHiA-uvPW#zC|3#zkX?7ZIL$d^v%(bcKz{OJaG)xIw$!| zz9L29nplmmcHYX&XmHJPT+wpE<{=dU3FY2evaugspT&88Lky;g<+5tk2YNjHV)|9j zohD`k!FJOo^e#2jG#k@r=9ty-#B;9Zmh)g3RoT-7)2GJHYln6eyFT%5Dd!d-KXk4 zpNFg0=fzfFCUPP(1tL{$knt{Q#$;!OEK1yr%8TWWUd33zn!0NXjQxrw#9mI6z^&-$ z;87{LU1lx1gZ?bgt!KoxiHDk04|veVJr(K$+1uqMbOT7eTvR%rrfh`xmORZhjwxW11pK&LOU zHM1Zg{5~kwAVb2C^?trSV7@?I=Lw^4=UE&CXENMW9OjTZz2+22Z0qQ z7)}ko*{HTQIEYtowJvSWYwpk{-&$4dsBAh3%o9<+b3Mc8P|pFEbssd{&v%4Qo_wDC zk;O$~s++oB1kdx^stX4^Gwz@Wk$r2&?@M%RFNNgfa_m5s6L!hNb4-jA*7F=JIZT`F z51Z7Ze*bXb4d3a^j{4&b-vm@~HaR_tz;v$rQZPz2x2S8HUvA)&v;H6SVqpp_2yMGB z(JWk}#fOXC1RmTTmAHFPvL;@%X0Zb^*3G->=k2;?18ss>(xxs7@X`w_Uo~EreS)y& zcx^-Vt|=45>JI7Jxe~F&8?l~Kw5bbS{l^c$35Wf;tF(6}SR+^*^wM-6y*~4R*~>- z@3%Vu_q(t>0-R;u+2h+D3~t8waP`IEEzL7Ycl}{r(>^%ug3*yl-i)Ibj?+;f{b-KQ zWaBZ_7IS)h86b!WqP?KlLkG`6nQz>>PgUB^S<>nb*dwX9&ou{~qHqjBxM-al>OMs) zU>G^cg)@D6?LB8sN~H9y$4fp&PHREx-{kSSV!QKk+>SX6Vhmz1gh0eoTt&mZAheMa z$XG(|Nx|@kZeT7<*Znw{V2^q5`HNa^cnri7)e1m^`DGnWA9-^l?!7(*cB7?fa$(;6 z!wACo5XE;=$gt#69iDrDyt{}mwC%dggnD^6z_s2c|4Awv%X%z$M`rJ&a|0~DY@-%LL_iA=D0sZO_WJ107L)9-IdZi!Uu(ojk3C(WrF=Cze!+1lrSp&V*K4%)1vO&{w#mU_k#qrR++7kTac?mmMSM*Vo8zF{IPzv@2 zdX)gkxJd^e1l3E&0Qq6brI4l*Ox?F{!55XhQ^&}Mrr!oDagkL1R)zKI0D`A&spW|WRA)u=(#XP^Bo10A+UdlX5lmK;p0BwDZ5>=<_&Ya3*3 z?A(0zl>>jX20HwQ!p49n(b8jK8*3!?##B@G9dyj1(o(xVMOh9eom#VEc7(BorJLh` z6+~GIm^@StxeYc0XyW|r0)?*)K&o7xZ`Ye6C_*u)EKEqZ7u`eIGEyVH#lQL#-GG)(}SH8AG zRGQU(Z*x|Cg27WwFU?36C>ZuVsqb~=X;b?|zLgx*1CWpHvE}Xct&i0+-5%az>LsO7 z&1FmuQBQdN5Mw~|6eLlDe~y!m{E&*F?>wMIFq&OUxXN@Ztiw^GI+EL(%yRpJu>{V@ zxsly~5rKYoVKRiBs;7EQmniYM#vmW_^p%5SZn&`>%jdMIpLx2eqYRUDmhTYGfQEZHDFWz64yn*}#ErtyWLrqs%Bk9UjdlRz-PJe-e0Zmq0kxdigkH$w(p>%F*5|#$ z&9=gp^SrX}v!e#jo7omiNYh%)ZuUUQwK;NAUNkY^B2(N$s9d1B8%c^e%FLim?C=wgem+2P(3^*l7j4CYWX9rXvYDYqGu@ z%Spl1U>Fys1jsLpok@7%>b(kn0*y}pBXPNsnYgNyYiZ{hv8z(@$(tH> zIN{TU_2<1mEe8ndeY%RfqgrSKD;n6eO$)j?H7tR9ua)Wc<)!-MX`s3Ds0i{YpVMze zG5oPm7iaUbEgJlAUpRWBD%p)i-0Bks=EH7A8(EtRR5Zw#BpsYRW@RXU%Gzt`;bt_d zF`j^ri^RUk+a()UDl|ji2+=EJNPQ=Da=O4EDP<|3*I2Gl7uy1dgS3SwyuL$;VAkZI z=UA=3 za%5<0h{;O-{78B+%)2EwY&G}Mp-!behPucL192qlg4A)a?9#A;!mheyxZPhwDCBeVN8>z9T;{LA@(D}R2MN!%aagI`O-$rY^d@xV*u&; zfoMp%C7pF;@;C#%Xw*=&LQu7iqa1_WXE~*(;6sxPjJN8@H*%pp4WA07p^5RI8y@y? zBR*VzDh~{5=RLZ472_*;(3Q3BrQdh`P$J2`FkC-fZFj-6&FkFTP@M|PCB%3pgd-%( z;l+09j6y`@^}E(EgrtH0ldVY>ir~i606AqTOQ6ZmO76~iJl%txB-d@Kn-Q`1U2vIh zX2wAIGLcNC9dJE#0FG5z>56fohS#Ah>93DU{`SIOGz)TMz3N2cGoh8tWgvH*X|@U- z5wxi(je2?FgyO@Daur4)uf@-`<2$t12`S4jD>EDyL%tzJtSSTF7mUy&O5BuoAi1Q@ zptWlO=QC$Eo&{{CL|c|89ee3|Pv+ zeagR;*^Hp?)UaS=WYv`H4UP{cmEI#f@GxSHYTGo}E|=4vjSukg{I>FbmGNF9Nj)Jo zX5+mt&<3RhpE=nfp<{5LLMMla#ORys?m@z#AG9 zD5+|1cBJ_dwfm@QuUmcxG(oR)OP`qM0%MB-pihdD_yjc>Y=-fWf#Y&+!%$693Qp3T~so~x)g@zE*9W}!Cw8_0g>Y5 zMNQYQTNW}PCW)0UZ1*$DaClU)=MEOT#~iR)&E!hV8AbLlK0lT>gy}bM_1V^R z)#E^!B)ypQ%r{tPi@C8dDYss{^C<5v_ngU%j;CvHecVQj;XuoJ$1|(xaj-+Z4MlF} zBcqQEDRHr|(Y6>iZXx5Jbb9a7%_iyqu4OsGBipS^tPdA%*F^^}QL3KjT=Z`fE1YfV zS5Op}vG5Oaoo*?fDh$VBuM&|IOqTYv)&?M^PCi&B|qZ*2^P||BXj0p7@$pgo$ z1*h&fkN)13Uc7ihV4!T2H;{a$=W@*BPaFZ+9r6!L)`{JTw>2^4ie}IA?*Xl2=*D|& z9t})9-F~)ZMor#wt51QYHa50ky<0>}apZGG@kS)s3%Y}5ImCLF5qP&on>9=-vftCS zhI@49kq5YeWQ*vZ=zA?h2Pd#oAH*EGGH_pQ&|UA~nTA>G#JnPK9~}aK(O_=eEsXhxEgnO$nxQYn>s_ zY(2g$6fbZtjk($LTzdV=&RSdMgi$rA_k9#F_q#%!&o+e>+P7KN4L|5HaW4P{#~}Ue zN2I|yv64CW0Lr(AJLe9D+TA4$Sj8rS2GO_TgKm&V0?rpL*25agf3sN_FVgui{^gkD z;)Ky|w)LLC=3DzWmi1R;$L)jJv?DH;m5aWnguvXFCY&YnVEI|tZu~bV@5aBF$N#eY zcjxipKPLP?#`x61|DR+0U%36c{2!+KKbZWh?ElWt|L0?eKehM|;sB`l{&?d5N9BL< s71hyy;p|_Q|JAF%FrZ!%Hm0yQw>DGWXQa+j|C73sqUz0bdE-a_3v7X;y#N3J literal 0 HcmV?d00001 diff --git a/artwork/steam/devlog.psd b/artwork/steam/devlog.psd new file mode 100644 index 00000000..0c06ba5d --- /dev/null +++ b/artwork/steam/devlog.psd @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:746c6cf3f0284798a78c08f77d7e9d0c28b02323081fda42b5fa876a7ade29a0 +size 205925 diff --git a/artwork/wires/prefab.png b/artwork/wires/prefab.png new file mode 100644 index 0000000000000000000000000000000000000000..99df19b871b31babf38d14d9363c154f98e01675 GIT binary patch literal 134900 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

HLir90Giz@!zr>T?)WV-*6FNWB*i~Ebe?^ji$ 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

Q4{}t7l_I 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 ka(7;IjPQ80h@KaO%LhX4Qo literal 0 HcmV?d00001 diff --git a/artwork/wires/prefab.psd b/artwork/wires/prefab.psd new file mode 100644 index 00000000..71c38097 --- /dev/null +++ b/artwork/wires/prefab.psd @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:498dea7314b8720c40dcd8bdd64b1b4a7a35259b2ffe7e896fc3db22878d6414 +size 1954036 diff --git a/res_raw/sounds/music/theme.mp3 b/res_raw/sounds/music/theme.mp3 deleted file mode 100644 index 66b78e55..00000000 --- a/res_raw/sounds/music/theme.mp3 +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f61e851402fbc92d6909912fb203c63258fedbdea83e81f7ececb5091f4bee03 -size 3732550 diff --git a/res_raw/sounds/music/theme.wav b/res_raw/sounds/music/theme.wav new file mode 100644 index 00000000..a2014603 --- /dev/null +++ b/res_raw/sounds/music/theme.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8c334a9f100fce4647b4803d2a8270b30e26d53622b3717bdb81b3ea07f84aed +size 150286082 diff --git a/src/js/changelog.js b/src/js/changelog.js index 280ea50e..81024f86 100644 --- a/src/js/changelog.js +++ b/src/js/changelog.js @@ -2,7 +2,10 @@ export const CHANGELOG = [ { version: "1.1.16", date: "unreleased", - entries: ["Fix belt planner not placing the last belt"], + entries: [ + "The game soundtrack has been extended! There are now 4 songs with over 13 minutes of playtime from Peppsen!", + "Fix belt planner not placing the last belt", + ], }, { version: "1.1.15", From 2dec257dd9651cb44c9fd0055045121e8180d91f Mon Sep 17 00:00:00 2001 From: tobspr Date: Sun, 21 Jun 2020 18:11:41 +0200 Subject: [PATCH 31/51] Cleanup click detector code --- src/js/game/canvas_click_interceptor.js | 70 ------------------- src/js/game/core.js | 2 - .../game/hud/parts/building_placer_logic.js | 21 +++--- src/js/game/root.js | 4 -- 4 files changed, 8 insertions(+), 89 deletions(-) delete mode 100644 src/js/game/canvas_click_interceptor.js diff --git a/src/js/game/canvas_click_interceptor.js b/src/js/game/canvas_click_interceptor.js deleted file mode 100644 index 675c1387..00000000 --- a/src/js/game/canvas_click_interceptor.js +++ /dev/null @@ -1,70 +0,0 @@ -import { STOP_PROPAGATION } from "../core/signal"; -import { GameRoot } from "./root"; -import { ClickDetector } from "../core/click_detector"; -import { createLogger } from "../core/logging"; - -const logger = createLogger("canvas_click_interceptor"); - -export class CanvasClickInterceptor { - /** - * @param {GameRoot} root - */ - constructor(root) { - this.root = root; - - this.root.signals.postLoadHook.add(this.initialize, this); - this.root.signals.aboutToDestruct.add(this.cleanup, this); - - /** @type {Array} */ - this.interceptors = []; - } - - initialize() { - this.clickDetector = new ClickDetector(this.root.canvas, { - applyCssClass: null, - captureTouchmove: false, - targetOnly: true, - preventDefault: true, - maxDistance: 13, - clickSound: null, - }); - this.clickDetector.click.add(this.onCanvasClick, this); - this.clickDetector.rightClick.add(this.onCanvasRightClick, this); - - if (this.root.hud.parts.buildingPlacer) { - this.interceptors.push(this.root.hud.parts.buildingPlacer); - } - - logger.log("Registered", this.interceptors.length, "interceptors"); - } - - cleanup() { - if (this.clickDetector) { - this.clickDetector.cleanup(); - } - this.interceptors = []; - } - - onCanvasClick(position, event, cancelAction = false) { - if (!this.root.gameInitialized) { - logger.warn("Skipping click outside of game initiaization!"); - return; - } - - if (this.root.hud.hasBlockingOverlayOpen()) { - return; - } - - for (let i = 0; i < this.interceptors.length; ++i) { - const interceptor = this.interceptors[i]; - if (interceptor.onCanvasClick(position, cancelAction) === STOP_PROPAGATION) { - // log(this, "Interceptor", interceptor.constructor.name, "catched click"); - break; - } - } - } - - onCanvasRightClick(position, event) { - this.onCanvasClick(position, event, true); - } -} diff --git a/src/js/game/core.js b/src/js/game/core.js index 8b1c464d..3fc02397 100644 --- a/src/js/game/core.js +++ b/src/js/game/core.js @@ -17,7 +17,6 @@ import { SavegameSerializer } from "../savegame/savegame_serializer"; import { AutomaticSave } from "./automatic_save"; import { MetaHubBuilding } from "./buildings/hub"; import { Camera } from "./camera"; -import { CanvasClickInterceptor } from "./canvas_click_interceptor"; import { EntityManager } from "./entity_manager"; import { GameSystemManager } from "./game_system_manager"; import { HubGoals } from "./hub_goals"; @@ -98,7 +97,6 @@ export class GameCore { root.logic = new GameLogic(root); root.hud = new GameHUD(root); root.time = new GameTime(root); - root.canvasClickInterceptor = new CanvasClickInterceptor(root); root.automaticSave = new AutomaticSave(root); root.soundProxy = new SoundProxy(root); diff --git a/src/js/game/hud/parts/building_placer_logic.js b/src/js/game/hud/parts/building_placer_logic.js index 92ce44bd..647fe5b9 100644 --- a/src/js/game/hud/parts/building_placer_logic.js +++ b/src/js/game/hud/parts/building_placer_logic.js @@ -243,20 +243,10 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart { * @param {boolean} cancelAction */ onCanvasClick(mousePos, cancelAction = false) { - if (cancelAction) { - if (this.currentMetaBuilding.get()) { - this.currentMetaBuilding.set(null); - } else { - this.deleteBelowCursor(); - } + // Prevent any other canvas clicks + if (this.currentMetaBuilding.get()) { return STOP_PROPAGATION; } - - if (!this.currentMetaBuilding.get()) { - return; - } - - return STOP_PROPAGATION; } /** @@ -479,13 +469,18 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart { } // Deletion - if (button === enumMouseButton.right && !this.currentMetaBuilding.get()) { + if (button === enumMouseButton.right && !metaBuilding) { this.currentlyDragging = true; this.currentlyDeleting = true; this.lastDragTile = this.root.camera.screenToWorld(pos).toTileSpace(); this.currentMetaBuilding.set(null); return STOP_PROPAGATION; } + + // Cancel placement + if (button === enumMouseButton.right && metaBuilding) { + this.currentMetaBuilding.set(null); + } } /** diff --git a/src/js/game/root.js b/src/js/game/root.js index cc6007de..0456952c 100644 --- a/src/js/game/root.js +++ b/src/js/game/root.js @@ -19,7 +19,6 @@ import { SoundProxy } from "./sound_proxy"; import { Savegame } from "../savegame/savegame"; import { GameLogic } from "./logic"; import { ShapeDefinitionManager } from "./shape_definition_manager"; -import { CanvasClickInterceptor } from "./canvas_click_interceptor"; import { HubGoals } from "./hub_goals"; import { BufferMaintainer } from "../core/buffer_maintainer"; import { ProductionAnalytics } from "./production_analytics"; @@ -110,9 +109,6 @@ export class GameRoot { /** @type {BufferMaintainer} */ this.buffers = null; - /** @type {CanvasClickInterceptor} */ - this.canvasClickInterceptor = null; - /** @type {AutomaticSave} */ this.automaticSave = null; From daef0f1e4e4b31d71e259d8efaf4737c198026e0 Mon Sep 17 00:00:00 2001 From: tobspr Date: Sun, 21 Jun 2020 19:30:44 +0200 Subject: [PATCH 32/51] Refactor keybindings overlay to show more appropriate keybindings --- src/css/ingame_hud/keybindings_overlay.scss | 48 +-- src/css/ingame_hud/mass_selector.scss | 22 -- src/css/main.scss | 3 - src/js/changelog.js | 4 + src/js/game/hud/parts/keybinding_overlay.js | 390 +++++++++++++++----- src/js/game/hud/parts/mass_selector.js | 38 +- src/js/game/key_action_mapper.js | 10 +- translations/base-en.yaml | 8 +- 8 files changed, 316 insertions(+), 207 deletions(-) delete mode 100644 src/css/ingame_hud/mass_selector.scss diff --git a/src/css/ingame_hud/keybindings_overlay.scss b/src/css/ingame_hud/keybindings_overlay.scss index 6d0f99c8..38b560d8 100644 --- a/src/css/ingame_hud/keybindings_overlay.scss +++ b/src/css/ingame_hud/keybindings_overlay.scss @@ -14,6 +14,10 @@ } > .binding { + &:not(.visible) { + display: none !important; + } + display: inline-grid; @include PlainText; align-items: center; @@ -57,50 +61,6 @@ @include S(margin-left, 5px); } } - - &:not(.placementActive) .binding.placementOnly, - &.mapOverviewActive .binding.placementOnly { - display: none; - } - - &.placementActive:not(.mapOverviewActive) .noPlacementOnly { - display: none; - } - - &:not(.mapOverviewActive) .binding.overviewOnly { - display: none; - } - - &.mapOverviewActive .noOverviewOnly { - display: none; - } - - &:not(.hasDirectionLock) .binding.directionLock { - display: none; - } - - &.hasDirectionLock .noDirectionLock { - display: none; - } - - .binding.placementOnly, - &:not(.placementActive) .binding.noPlacementOnly { - transform-origin: 0% 50%; - @include InlineAnimation(0.3s ease-in-out) { - 0% { - color: $colorRedBright; - transform: scale(1.2); - } - } - } - - .keybinding.builtinKey { - transition: all 0.1s ease-in-out; - transition-property: background-color, color, border-color; - background: $colorRedBright; - border-color: $colorRedBright; - color: #fff; - } } body.uiHidden #ingame_HUD_KeybindingOverlay .binding:not(.hudToggle) { diff --git a/src/css/ingame_hud/mass_selector.scss b/src/css/ingame_hud/mass_selector.scss deleted file mode 100644 index ddd2d40a..00000000 --- a/src/css/ingame_hud/mass_selector.scss +++ /dev/null @@ -1,22 +0,0 @@ -#ingame_HUD_MassSelector { - position: absolute; - @include S(top, 50px); - left: 50%; - transform: translateX(-50%); - background: $ingameHudBg; - @include S(padding, 6px, 10px); - @include SuperSmallText; - color: #fff; - // color: #f77; - - .keybinding { - vertical-align: middle; - @include S(margin, 0, 1px); - position: relative; - top: unset; - left: unset; - right: unset; - bottom: unset; - @include S(margin-top, -2px); - } -} diff --git a/src/css/main.scss b/src/css/main.scss index 10bf384e..598e9e92 100644 --- a/src/css/main.scss +++ b/src/css/main.scss @@ -37,7 +37,6 @@ @import "ingame_hud/shop"; @import "ingame_hud/game_menu"; @import "ingame_hud/dialogs"; -@import "ingame_hud/mass_selector"; @import "ingame_hud/vignette_overlay"; @import "ingame_hud/statistics"; @import "ingame_hud/pinned_shapes"; @@ -67,7 +66,6 @@ ingame_HUD_PinnedShapes, ingame_HUD_GameMenu, ingame_HUD_KeybindingOverlay, ingame_HUD_Notifications, -ingame_HUD_MassSelector, ingame_HUD_DebugInfo, ingame_HUD_EntityDebugger, ingame_HUD_InteractiveTutorial, @@ -101,7 +99,6 @@ body.uiHidden { #ingame_HUD_buildings_toolbar, #ingame_HUD_PlacementHints, #ingame_HUD_GameMenu, - #ingame_HUD_MassSelector, #ingame_HUD_PinnedShapes, #ingame_HUD_Notifications, #ingame_HUD_TutorialHints, diff --git a/src/js/changelog.js b/src/js/changelog.js index 81024f86..d4316215 100644 --- a/src/js/changelog.js +++ b/src/js/changelog.js @@ -5,6 +5,10 @@ export const CHANGELOG = [ entries: [ "The game soundtrack has been extended! There are now 4 songs with over 13 minutes of playtime from Peppsen!", "Fix belt planner not placing the last belt", + "Refactor keybindings overlay to show more appropriate keybindings", + "Show keybindings for area-select in the upper left instead", + "Automatically deselect area when selecting a new building", + "Optimize performance by caching miner items (by Phlosioneer)", ], }, { diff --git a/src/js/game/hud/parts/keybinding_overlay.js b/src/js/game/hud/parts/keybinding_overlay.js index e469bcca..7aca3722 100644 --- a/src/js/game/hud/parts/keybinding_overlay.js +++ b/src/js/game/hud/parts/keybinding_overlay.js @@ -1,123 +1,309 @@ import { makeDiv } from "../../../core/utils"; import { T } from "../../../translations"; -import { getStringForKeyCode, KEYMAPPINGS } from "../../key_action_mapper"; +import { + getStringForKeyCode, + KEYCODE_LMB, + KEYCODE_MMB, + KEYCODE_RMB, + KEYMAPPINGS, +} from "../../key_action_mapper"; import { BaseHUDPart } from "../base_hud_part"; -import { TrackedState } from "../../../core/tracked_state"; -import { MetaBuilding } from "../../meta_building"; +import { DynamicDomAttach } from "../dynamic_dom_attach"; + +const DIVIDER_TOKEN = "/"; +const ADDER_TOKEN = "+"; + +/** + * @typedef {{ keyCode: number }} KeyCode + */ + +/** + * @typedef {{ + * condition: () => boolean, + * keys: Array, + * label: string, + * cachedElement?: HTMLElement, + * cachedVisibility?: boolean + * }} KeyBinding + */ export class HUDKeybindingOverlay extends BaseHUDPart { - initialize() { - this.root.hud.signals.selectedPlacementBuildingChanged.add( - this.onSelectedBuildingForPlacementChanged, - this - ); + initialize() {} - this.trackedMapOverviewActive = new TrackedState(this.applyCssClasses, this); + /** + * HELPER / Returns if there is a building selected for placement + * @returns {boolean} + */ + get buildingPlacementActive() { + const placer = this.root.hud.parts.buildingPlacer; + return !this.mapOverviewActive && placer && !!placer.currentMetaBuilding.get(); } - createElements(parent) { - const mapper = this.root.keyMapper; - - const getKeycode = id => { - return getStringForKeyCode(mapper.getBinding(id).keyCode); - }; - - this.element = makeDiv( - parent, - "ingame_HUD_KeybindingOverlay", - [], - ` - -
- - ${getKeycode(KEYMAPPINGS.navigation.mapMoveUp)} - ${getKeycode(KEYMAPPINGS.navigation.mapMoveLeft)} - ${getKeycode(KEYMAPPINGS.navigation.mapMoveDown)} - ${getKeycode(KEYMAPPINGS.navigation.mapMoveRight)} - -
- - - -
- - -
- -
- - -
- - -
- ${getKeycode( - KEYMAPPINGS.massSelect.massSelectStart - )}+ - - -
- -
- - -
- -
- - ${getKeycode(KEYMAPPINGS.placement.abortBuildingPlacement)} - -
- -
- ${getKeycode(KEYMAPPINGS.placement.rotateWhilePlacing)} - -
- - ` + - (this.root.app.settings.getAllSettings().alwaysMultiplace - ? "" - : ` -
- ${getKeycode( - KEYMAPPINGS.placementModifiers.placeMultiple - )} - -
`) + - ` - -
- ${getKeycode( - KEYMAPPINGS.placementModifiers.lockBeltDirection - )} - -
- -
- ${getKeycode(KEYMAPPINGS.placement.switchDirectionLockSide)} - -
- ` + /** + * HELPER / Returns if there is a building selected for placement and + * it supports the belt planner + * @returns {boolean} + */ + get buildingPlacementBeltPlanner() { + const placer = this.root.hud.parts.buildingPlacer; + return ( + !this.mapOverviewActive && + placer && + placer.currentMetaBuilding.get() && + placer.currentMetaBuilding.get().getHasDirectionLockAvailable() ); } /** - * - * @param {MetaBuilding} selectedMetaBuilding + * HELPER / Returns if there is a building selected for placement and + * it has multiplace enabled by default + * @returns {boolean} */ - onSelectedBuildingForPlacementChanged(selectedMetaBuilding) { - this.element.classList.toggle("placementActive", !!selectedMetaBuilding); - this.element.classList.toggle( - "hasDirectionLock", - selectedMetaBuilding && selectedMetaBuilding.getHasDirectionLockAvailable() + get buildingPlacementStaysInPlacement() { + const placer = this.root.hud.parts.buildingPlacer; + return ( + !this.mapOverviewActive && + placer && + placer.currentMetaBuilding.get() && + placer.currentMetaBuilding.get().getStayInPlacementMode() ); } - applyCssClasses() { - this.element.classList.toggle("mapOverviewActive", this.root.camera.getIsMapOverlayActive()); + /** + * HELPER / Returns if there is a blueprint selected for placement + * @returns {boolean} + */ + get blueprintPlacementActive() { + const placer = this.root.hud.parts.blueprintPlacer; + return placer && !!placer.currentBlueprint.get(); + } + + /** + * HELPER / Returns if the belt planner is currently active + * @returns {boolean} + */ + get beltPlannerActive() { + const placer = this.root.hud.parts.buildingPlacer; + return !this.mapOverviewActive && placer && placer.isDirectionLockActive; + } + + /** + * HELPER / Returns if there is a last blueprint available + * @returns {boolean} + */ + get lastBlueprintAvailable() { + const placer = this.root.hud.parts.blueprintPlacer; + return placer && !!placer.lastBlueprintUsed; + } + + /** + * HELPER / Returns if there is anything selected on the map + * @returns {boolean} + */ + get anythingSelectedOnMap() { + const selector = this.root.hud.parts.massSelector; + return selector && selector.selectedUids.size > 0; + } + + /** + * HELPER / Returns if there is a building or blueprint selected for placement + * @returns {boolean} + */ + get anyPlacementActive() { + return this.buildingPlacementActive || this.blueprintPlacementActive; + } + + /** + * HELPER / Returns if the map overview is active + * @returns {boolean} + */ + get mapOverviewActive() { + return this.root.camera.getIsMapOverlayActive(); + } + + /** + * Initializes the element + * @param {HTMLElement} parent + */ + createElements(parent) { + const mapper = this.root.keyMapper; + const k = KEYMAPPINGS; + + /** @type {Array} */ + this.keybindings = [ + { + // Move map - Including mouse + label: T.ingame.keybindingsOverlay.moveMap, + keys: [ + KEYCODE_LMB, + DIVIDER_TOKEN, + k.navigation.mapMoveUp, + k.navigation.mapMoveLeft, + k.navigation.mapMoveDown, + k.navigation.mapMoveRight, + ], + condition: () => !this.anyPlacementActive, + }, + + { + // Move map - No mouse + label: T.ingame.keybindingsOverlay.moveMap, + keys: [ + k.navigation.mapMoveUp, + k.navigation.mapMoveLeft, + k.navigation.mapMoveDown, + k.navigation.mapMoveRight, + ], + condition: () => this.anyPlacementActive, + }, + + { + // [OVERVIEW] Create marker with right click + label: T.ingame.keybindingsOverlay.createMarker, + keys: [KEYCODE_RMB], + condition: () => this.mapOverviewActive && !this.blueprintPlacementActive, + }, + + { + // Cancel placement + label: T.ingame.keybindingsOverlay.stopPlacement, + keys: [KEYCODE_RMB, DIVIDER_TOKEN, k.placement.abortBuildingPlacement], + condition: () => this.anyPlacementActive, + }, + + { + // Delete with right click + label: T.ingame.keybindingsOverlay.delete, + keys: [KEYCODE_RMB], + condition: () => + !this.anyPlacementActive && !this.mapOverviewActive && !this.anythingSelectedOnMap, + }, + + { + // Area select + label: T.ingame.keybindingsOverlay.selectBuildings, + keys: [k.massSelect.massSelectStart, ADDER_TOKEN, KEYCODE_LMB], + condition: () => !this.anyPlacementActive && !this.anythingSelectedOnMap, + }, + + { + // Place building + label: T.ingame.keybindingsOverlay.placeBuilding, + keys: [KEYCODE_LMB], + condition: () => this.anyPlacementActive, + }, + + { + // Rotate + label: T.ingame.keybindingsOverlay.rotateBuilding, + keys: [k.placement.rotateWhilePlacing], + condition: () => this.anyPlacementActive && !this.beltPlannerActive, + }, + + { + // [BELT PLANNER] Flip Side + label: T.ingame.keybindingsOverlay.plannerSwitchSide, + keys: [k.placement.switchDirectionLockSide], + condition: () => this.beltPlannerActive, + }, + + { + // Place last blueprint + label: T.ingame.keybindingsOverlay.pasteLastBlueprint, + keys: [k.massSelect.pasteLastBlueprint], + condition: () => !this.blueprintPlacementActive && this.lastBlueprintAvailable, + }, + + { + // Belt planner + label: T.ingame.keybindingsOverlay.lockBeltDirection, + keys: [k.placementModifiers.lockBeltDirection], + condition: () => this.buildingPlacementActive && !this.beltPlannerActive, + }, + + { + // [SELECTION] Destroy + label: T.ingame.keybindingsOverlay.delete, + keys: [k.massSelect.confirmMassDelete], + condition: () => this.anythingSelectedOnMap, + }, + + { + // [SELECTION] Cancel + label: T.ingame.keybindingsOverlay.clearSelection, + keys: [k.general.back], + condition: () => this.anythingSelectedOnMap, + }, + { + // [SELECTION] Cut + label: T.ingame.keybindingsOverlay.cutSelection, + keys: [k.massSelect.massSelectCut], + condition: () => this.anythingSelectedOnMap, + }, + + { + // [SELECTION] Copy + label: T.ingame.keybindingsOverlay.copySelection, + keys: [k.massSelect.massSelectCopy], + condition: () => this.anythingSelectedOnMap, + }, + ]; + + if (!this.root.app.settings.getAllSettings().alwaysMultiplace) { + this.keybindings.push({ + // Multiplace + label: T.ingame.keybindingsOverlay.placeMultiple, + keys: [k.placementModifiers.placeMultiple], + condition: () => this.anyPlacementActive && !this.buildingPlacementStaysInPlacement, + }); + } + + this.element = makeDiv(parent, "ingame_HUD_KeybindingOverlay", []); + + for (let i = 0; i < this.keybindings.length; ++i) { + let html = ""; + const handle = this.keybindings[i]; + + for (let k = 0; k < handle.keys.length; ++k) { + const key = handle.keys[k]; + + switch (key) { + case KEYCODE_LMB: + html += ``; + break; + case KEYCODE_RMB: + html += ``; + break; + case KEYCODE_MMB: + html += ``; + break; + case DIVIDER_TOKEN: + html += ``; + break; + case ADDER_TOKEN: + html += `+`; + break; + default: + html += `${getStringForKeyCode( + mapper.getBinding(/** @type {KeyCode} */ (key)).keyCode + )}`; + } + } + html += ``; + + handle.cachedElement = makeDiv(this.element, null, ["binding"], html); + handle.cachedVisibility = false; + } } update() { - this.trackedMapOverviewActive.set(this.root.camera.getIsMapOverlayActive()); + for (let i = 0; i < this.keybindings.length; ++i) { + const handle = this.keybindings[i]; + const visibility = handle.condition(); + if (visibility !== handle.cachedVisibility) { + handle.cachedVisibility = visibility; + handle.cachedElement.classList.toggle("visible", visibility); + } + } } } diff --git a/src/js/game/hud/parts/mass_selector.js b/src/js/game/hud/parts/mass_selector.js index 0dc872c5..7e6710c0 100644 --- a/src/js/game/hud/parts/mass_selector.js +++ b/src/js/game/hud/parts/mass_selector.js @@ -17,29 +17,7 @@ import { enumHubGoalRewards } from "../../tutorial_goals"; const logger = createLogger("hud/mass_selector"); export class HUDMassSelector extends BaseHUDPart { - createElements(parent) { - const removalKeybinding = this.root.keyMapper - .getBinding(KEYMAPPINGS.massSelect.confirmMassDelete) - .getKeyCodeString(); - const abortKeybinding = this.root.keyMapper.getBinding(KEYMAPPINGS.general.back).getKeyCodeString(); - const cutKeybinding = this.root.keyMapper - .getBinding(KEYMAPPINGS.massSelect.massSelectCut) - .getKeyCodeString(); - const copyKeybinding = this.root.keyMapper - .getBinding(KEYMAPPINGS.massSelect.massSelectCopy) - .getKeyCodeString(); - - this.element = makeDiv( - parent, - "ingame_HUD_MassSelector", - [], - T.ingame.massSelect.infoText - .replace("", `${removalKeybinding}`) - .replace("", `${cutKeybinding}`) - .replace("", `${copyKeybinding}`) - .replace("", `${abortKeybinding}`) - ); - } + createElements(parent) {} initialize() { this.deletionMarker = Loader.getSprite("sprites/misc/deletion_marker.png"); @@ -49,6 +27,7 @@ export class HUDMassSelector extends BaseHUDPart { this.selectedUids = new Set(); this.root.signals.entityQueuedForDestroy.add(this.onEntityDestroyed, this); + this.root.hud.signals.pasteBlueprintRequested.add(this.clearSelection, this); this.root.camera.downPreHandler.add(this.onMouseDown, this); this.root.camera.movePreHandler.add(this.onMouseMove, this); @@ -61,7 +40,7 @@ export class HUDMassSelector extends BaseHUDPart { this.root.keyMapper.getBinding(KEYMAPPINGS.massSelect.massSelectCut).add(this.confirmCut, this); this.root.keyMapper.getBinding(KEYMAPPINGS.massSelect.massSelectCopy).add(this.startCopy, this); - this.domAttach = new DynamicDomAttach(this.root, this.element); + this.root.hud.signals.selectedPlacementBuildingChanged.add(this.clearSelection, this); } /** @@ -83,6 +62,13 @@ export class HUDMassSelector extends BaseHUDPart { } } + /** + * Clears the entire selection + */ + clearSelection() { + this.selectedUids = new Set(); + } + confirmDelete() { if (this.selectedUids.size > 100) { const { ok } = this.root.hud.parts.dialogs.showWarning( @@ -230,10 +216,6 @@ export class HUDMassSelector extends BaseHUDPart { } } - update() { - this.domAttach.update(this.selectedUids.size > 0); - } - /** * * @param {DrawParameters} parameters diff --git a/src/js/game/key_action_mapper.js b/src/js/game/key_action_mapper.js index 6a1e265c..659f01e6 100644 --- a/src/js/game/key_action_mapper.js +++ b/src/js/game/key_action_mapper.js @@ -88,6 +88,10 @@ for (const categoryId in KEYMAPPINGS) { } } +export const KEYCODE_LMB = 1; +export const KEYCODE_MMB = 2; +export const KEYCODE_RMB = 3; + /** * Returns a keycode -> string * @param {number} code @@ -95,11 +99,11 @@ for (const categoryId in KEYMAPPINGS) { */ export function getStringForKeyCode(code) { switch (code) { - case 1: + case KEYCODE_LMB: return "LMB"; - case 2: + case KEYCODE_MMB: return "MMB"; - case 3: + case KEYCODE_RMB: return "RMB"; case 4: return "MB4"; diff --git a/translations/base-en.yaml b/translations/base-en.yaml index 8321e20b..afe4907d 100644 --- a/translations/base-en.yaml +++ b/translations/base-en.yaml @@ -285,6 +285,9 @@ ingame: pasteLastBlueprint: Paste last blueprint lockBeltDirection: Enable belt planner plannerSwitchSide: Flip planner side + cutSelection: Cut + copySelection: Copy + clearSelection: Clear Selection # Everything related to placing buildings (I.e. as soon as you selected a building # from the toolbar) @@ -320,11 +323,6 @@ ingame: newUpgrade: A new upgrade is available! gameSaved: Your game has been saved. - # Mass select information, this is when you hold CTRL and then drag with your mouse - # to select multiple buildings - massSelect: - infoText: Press to cut, to copy, to remove and to cancel. - # The "Upgrades" window shop: title: Upgrades From ece02e754526db8d33fc14136c0daaeff3bd554e Mon Sep 17 00:00:00 2001 From: tobspr Date: Sun, 21 Jun 2020 19:33:28 +0200 Subject: [PATCH 33/51] Update changelog --- src/js/changelog.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/js/changelog.js b/src/js/changelog.js index d4316215..8ea2b25b 100644 --- a/src/js/changelog.js +++ b/src/js/changelog.js @@ -9,6 +9,8 @@ export const CHANGELOG = [ "Show keybindings for area-select in the upper left instead", "Automatically deselect area when selecting a new building", "Optimize performance by caching miner items (by Phlosioneer)", + "Fix for exporting screenshots for huge bases (It was showing an empty file) (by xSparfuchs)", + "Update translations", ], }, { From cd36e9084ae8b0b84b07a72fdda8e6bcb5c1c7fa Mon Sep 17 00:00:00 2001 From: tobspr Date: Sun, 21 Jun 2020 19:33:58 +0200 Subject: [PATCH 34/51] Minor code style adjustments --- src/js/game/hud/parts/screenshot_exporter.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/js/game/hud/parts/screenshot_exporter.js b/src/js/game/hud/parts/screenshot_exporter.js index 6b1ad67b..8623f902 100644 --- a/src/js/game/hud/parts/screenshot_exporter.js +++ b/src/js/game/hud/parts/screenshot_exporter.js @@ -5,7 +5,7 @@ import { T } from "../../../translations"; import { createLogger } from "../../../core/logging"; import { StaticMapEntityComponent } from "../../components/static_map_entity"; import { Vector } from "../../../core/vector"; -import { Math_max, Math_min } from "../../../core/builtins"; +import { Math_max, Math_min, Math_floor } from "../../../core/builtins"; import { makeOffscreenBuffer } from "../../../core/buffer_utils"; import { DrawParameters } from "../../../core/draw_parameters"; import { Rectangle } from "../../../core/rectangle"; @@ -57,10 +57,10 @@ export class HUDScreenshotExporter extends BaseHUDPart { logger.log("Dimensions:", dimensions); let chunkSizePixels = 128; - const maxDimensions = Math.max(dimensions.x, dimensions.y); + const maxDimensions = Math_max(dimensions.x, dimensions.y); if (maxDimensions > 128) { - chunkSizePixels = Math.floor(128 * (128 / maxDimensions)); + chunkSizePixels = Math_max(1, Math_floor(128 * (128 / maxDimensions))); } logger.log("ChunkSizePixels:", chunkSizePixels); From 7a5094939df13c09a54e4fe035ea0217ef5ec316 Mon Sep 17 00:00:00 2001 From: findaldudu Date: Sun, 21 Jun 2020 12:56:55 -0500 Subject: [PATCH 35/51] chinese translation patch --- translations/base-zh-CN.yaml | 54 ++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/translations/base-zh-CN.yaml b/translations/base-zh-CN.yaml index ab7679b6..4263f618 100644 --- a/translations/base-zh-CN.yaml +++ b/translations/base-zh-CN.yaml @@ -47,7 +47,7 @@ steamPage: # This is the short text appearing on the steam page - shortText: shapez.io 是一款在无边际的地图上建造工厂、自动化生产与组合愈加复杂的形状的游戏。 + shortText: shapez.io 是一款在无边际的地图上建造工厂、自动化生产与组合愈加复杂的图形的游戏。 # shortText: shapez.io is a game about building factories to automate the creation and combination of increasingly complex shapes within an infinite map. # This is the long description for the steam page - It is contained here so you can help to translate it, and I will regulary update the store page. @@ -57,11 +57,11 @@ steamPage: longText: >- [img]{STEAM_APP_IMAGE}/extras/store_page_gif.gif[/img] - shapez.io 是一款在无边际的地图上建造工厂、自动化生产与组合愈加复杂的形状的游戏。提交任务,制造更复杂的流水线,解锁升级来提升您工厂的运作速度。 + shapez.io 是一款在无边际的地图上建造工厂、自动化生产与组合愈加复杂的图形的游戏。提交任务,制造更复杂的流水线,解锁升级来提升您工厂的运作速度。 你将会需要随着不断上升得需求扩大你的工厂。当然,不要忘记你可以在[b]无尽[/b]的地图上开采资源! - 只对形状进行加工可能会使你感到无聊。我们为你准备了颜色资源——将红、绿、蓝三种颜色混合,生产更多不同的颜色并粉刷在形状上以满足需求。 + 只对图形进行加工可能会使你感到无聊。我们为你准备了颜色资源——将红、绿、蓝三种颜色混合,生产更多不同的颜色并粉刷在图形上以满足需求。 这个游戏目前有18个关卡(这应该已经能让你忙碌几个小时了!),并且正在不断地更新中。很多新关卡已经在开发计划当中! @@ -83,11 +83,11 @@ steamPage: 本游戏已开源,所有人都能参与游戏内容的开发!除此以外,我[b]非常重视[/b]玩家社区的反馈!我会阅读每一条建议并尽量顾及所有建议。 [list] - [*] 要消耗形状来造建筑的的故事模式 + [*] 要消耗图形来造建筑的的故事模式 [*] 更多关卡&建筑(单机版独有) [*] 更多地图,也许会有障碍物 [*] 可配置的地图生成(矿脉密度与大小、 随机种子以及其他地图设置) - [*] 更多形状 + [*] 更多图形 [*] 更多的性能改进(当然,现在游戏已经非常流畅了!) [*] 色盲模式 [*] 以及更多其他的功能! @@ -261,7 +261,7 @@ dialogs: upgradesIntroduction: title: 解锁建筑升级 desc: >- - 不要销毁你之前建造的工厂!你生产过的所有形状都会被用来升级建筑。 + 不要销毁你之前建造的工厂!你生产过的所有图形都会被用来升级建筑。 升级菜单在屏幕右上角。 # All shapes you produce can be used to unlock upgrades - Don't destroy your old factories! # The upgrades tab can be found on the top right corner of the screen. @@ -293,7 +293,7 @@ dialogs: createMarker: title: 创建地图标记 - desc: 给地图标记起一个的名字。你可以在名字中加入一个短代码以加入形状。(你可以在这里生成短代码。) + desc: 给地图标记起一个的名字。你可以在名字中加入一个短代码以加入图形。(你可以在这里生成短代码。) markerDemoLimit: desc: 在演示版中你只能创建两个地图标记。请获取独立版以创建更多标记。 @@ -391,8 +391,8 @@ ingame: description: 显示所有正在被生产的图形数量,包括中间产物。 delivered: title: 送达 - description: 显示形状送达基地的速度。 - noShapesProduced: 你还没有生产任何形状。 + description: 显示图形送达基地的速度。 + noShapesProduced: 你还没有生产任何图形。 # Displays the shapes per minute, e.g. '523 / m' shapesPerMinute: 个/分钟 @@ -464,11 +464,11 @@ buildings: miner: # Internal name for the Extractor default: name: &miner 开采机 - description: 在形状或者颜色上放置来开采他们。 + description: 在图形或者颜色上放置来开采他们。 chainable: name: 链式开采机 - description: 在形状或者颜色上放置来开采他们。可以被链接在一起。 + description: 在图形或者颜色上放置来开采他们。可以被链接在一起。 underground_belt: # Internal name for the Tunnel default: @@ -495,10 +495,10 @@ buildings: cutter: default: name: &cutter 切割机 - description: 将形状从上到下切开并输出。 如果你只需要其中一半,记得把另一半销毁掉,否则切割机会停止工作! + description: 将图形从上到下切开并输出。 如果你只需要其中一半,记得把另一半销毁掉,否则切割机会停止工作! quad: name: 切割机(四分) - description: 将输入的形状切成四块。 如果你只需要其中一块,记得把其他的销毁掉,否则切割机会停止工作! + description: 将输入的图形切成四块。 如果你只需要其中一块,记得把其他的销毁掉,否则切割机会停止工作! rotater: default: @@ -511,7 +511,7 @@ buildings: stacker: default: name: &stacker 堆叠机 - description: 将输入的形状拼贴在一起。如果不能被直接拼贴,右边的形状会被堆叠在左边的形状上面. + description: 将输入的图形拼贴在一起。如果不能被直接拼贴,右边的图形会被堆叠在左边的图形上面. mixer: default: @@ -521,13 +521,13 @@ buildings: painter: default: name: &painter 上色机 - description: &painter_desc 将整个形状涂上输入的颜色。 + description: &painter_desc 将整个图形涂上输入的颜色。 double: name: 上色机(双倍) - description: 同时为两个输入的形状上色,每次上色只消耗一份颜色。 + description: 同时为两个输入的图形上色,每次上色只消耗一份颜色。 quad: name: 上色机(四向) - description: 为形状的四个角涂上不同的颜色。 + description: 为图形的四个角涂上不同的颜色。 mirrored: name: *painter description: *painter_desc @@ -553,12 +553,12 @@ storyRewards: reward_rotater: title: 顺时针旋转 - desc: 旋转机已解锁。它会顺时针旋转输入的形状90度。 + desc: 旋转机已解锁。它会顺时针旋转输入的图形90度。 reward_painter: title: 上色 desc: >- - 上色机已解锁。和形状一样,从颜色矿脉中开采颜色,然后将在上色机中将颜色涂在形状上。

PS:我们正在开发色盲模式! + 上色机已解锁。和图形一样,从颜色矿脉中开采颜色,然后将在上色机中将颜色涂在图形上。

PS:我们正在开发色盲模式! reward_mixer: title: 混合颜色 @@ -566,7 +566,7 @@ storyRewards: reward_stacker: title: 堆叠 - desc: 堆叠机已解锁。堆叠机会尝试把两个输入的形状拼贴在一起。如果有重叠的部分,右边的输入会被堆叠在左边的输入上方! + desc: 堆叠机已解锁。堆叠机会尝试把两个输入的图形拼贴在一起。如果有重叠的部分,右边的输入会被堆叠在左边的输入上方! reward_splitter: title: 分离与合并 @@ -578,7 +578,7 @@ storyRewards: reward_rotater_ccw: title: 逆时针旋转 - desc: 旋转机逆时针变体已解锁。这个变体可以逆时针旋转形状。选择旋转机然后按“T”键来选取这个变体。 + desc: 旋转机逆时针变体已解锁。这个变体可以逆时针旋转图形。选择旋转机然后按“T”键来选取这个变体。 reward_miner_chainable: title: 链式开采机 @@ -595,15 +595,15 @@ storyRewards: reward_cutter_quad: title: 四分切割机 - desc: 切割机四分变体已解锁。它可以将输入的形状切成四块而不只是左右两块。 + desc: 切割机四分变体已解锁。它可以将输入的图形切成四块而不只是左右两块。 reward_painter_double: title: 双倍上色机 - desc: 上色机双倍变体已解锁。 它像普通上色机一样为形状上色,只是它可以同时为两个形状上色,每次只消耗一份颜色! + desc: 上色机双倍变体已解锁。 它像普通上色机一样为图形上色,只是它可以同时为两个图形上色,每次只消耗一份颜色! reward_painter_quad: title: 四向上色机 - desc: 上色机四向变体已解锁。它可以在一个形状的四个角上涂不同的颜色! + desc: 上色机四向变体已解锁。它可以在一个图形的四个角上涂不同的颜色! reward_storage: title: 仓库 @@ -611,17 +611,17 @@ storyRewards: reward_freeplay: title: 自由模式 - desc: 恭喜你!你解锁了自由模式!现在形状将会是随机生成的!(不用担心,我计划在独立版本中加入更多内容!) + desc: 恭喜你!你解锁了自由模式!现在图形将会是随机生成的!(不用担心,我计划在独立版本中加入更多内容!) reward_blueprints: title: 蓝图 - desc: 你现在可以复制粘贴你的工厂的一部分了!按住CTRL键并拖动鼠标来选择一块区域,然后按C键复制。

粘贴并不是免费的,你需要使用蓝图形状来粘贴你的蓝图。蓝图形状是你刚刚交付的形状。 + desc: 你现在可以复制粘贴你的工厂的一部分了!按住CTRL键并拖动鼠标来选择一块区域,然后按C键复制。

粘贴并不是免费的,你需要使用蓝图图形来粘贴你的蓝图。蓝图图形是你刚刚交付的图形。 # Special reward, which is shown when there is no reward actually no_reward: title: 下一关 desc: >- - 这一关没有奖励,但是下一关有!

PS: 你生产过的所有形状都会被用来升级建筑。 + 这一关没有奖励,但是下一关有!

PS: 你生产过的所有图形都会被用来升级建筑。 no_reward_freeplay: title: 下一关 From 1458e1aad0531f36b773a7e434dce7ff3a0ab6a4 Mon Sep 17 00:00:00 2001 From: tobspr Date: Sun, 21 Jun 2020 19:58:54 +0200 Subject: [PATCH 36/51] Update changelog --- src/js/changelog.js | 8 ++++++-- src/js/game/key_action_mapper.js | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/js/changelog.js b/src/js/changelog.js index 8ea2b25b..c5be2056 100644 --- a/src/js/changelog.js +++ b/src/js/changelog.js @@ -4,13 +4,17 @@ export const CHANGELOG = [ date: "unreleased", entries: [ "The game soundtrack has been extended! There are now 4 songs with over 13 minutes of playtime from Peppsen!", - "Fix belt planner not placing the last belt", "Refactor keybindings overlay to show more appropriate keybindings", "Show keybindings for area-select in the upper left instead", "Automatically deselect area when selecting a new building", + "Raise markers limit from 14 characters to 71 (by Joker-vD)", "Optimize performance by caching miner items (by Phlosioneer)", + "Fix belt planner not placing the last belt", + "Fix buildings getting deleted when right clicking while placing a blueprint", "Fix for exporting screenshots for huge bases (It was showing an empty file) (by xSparfuchs)", - "Update translations", + "Fix buttons not responding when using right click directly after left click (by davidburhans)", + "Added simplified chinese translations", + "Update translations (Thanks to all translators!)", ], }, { diff --git a/src/js/game/key_action_mapper.js b/src/js/game/key_action_mapper.js index 659f01e6..92117c0a 100644 --- a/src/js/game/key_action_mapper.js +++ b/src/js/game/key_action_mapper.js @@ -78,6 +78,7 @@ export const KEYMAPPINGS = { placementDisableAutoOrientation: { keyCode: 17 }, // CTRL placeMultiple: { keyCode: 16 }, // SHIFT placeInverse: { keyCode: 18 }, // ALT + cycleInverse: { keyCode: 16 }, // SHIFT }, }; From d1fe231bcb455593b929b2487e23163cbf6efab3 Mon Sep 17 00:00:00 2001 From: tobspr Date: Sun, 21 Jun 2020 20:17:03 +0200 Subject: [PATCH 37/51] Remove unused keybindings --- src/js/game/key_action_mapper.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/js/game/key_action_mapper.js b/src/js/game/key_action_mapper.js index 92117c0a..659f01e6 100644 --- a/src/js/game/key_action_mapper.js +++ b/src/js/game/key_action_mapper.js @@ -78,7 +78,6 @@ export const KEYMAPPINGS = { placementDisableAutoOrientation: { keyCode: 17 }, // CTRL placeMultiple: { keyCode: 16 }, // SHIFT placeInverse: { keyCode: 18 }, // ALT - cycleInverse: { keyCode: 16 }, // SHIFT }, }; From 1f136ba89260a51fb1d050e0046a442f54d37838 Mon Sep 17 00:00:00 2001 From: tobspr Date: Sun, 21 Jun 2020 20:27:39 +0200 Subject: [PATCH 38/51] Minor fixes for dark mode --- src/css/common.scss | 2 +- src/css/ingame_hud/dialogs.scss | 6 ++++-- src/css/main.scss | 2 +- src/css/states/settings.scss | 6 +++--- src/css/textual_game_state.scss | 4 ++-- src/css/variables.scss | 2 ++ src/js/changelog.js | 2 ++ 7 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/css/common.scss b/src/css/common.scss index f616eace..6a87012e 100644 --- a/src/css/common.scss +++ b/src/css/common.scss @@ -40,7 +40,7 @@ html { background: #dee1ea; @include DarkThemeOverride { - background: #5c606c; + background: $darkModeGameBackground; } } diff --git a/src/css/ingame_hud/dialogs.scss b/src/css/ingame_hud/dialogs.scss index cd681a9e..d72265e7 100644 --- a/src/css/ingame_hud/dialogs.scss +++ b/src/css/ingame_hud/dialogs.scss @@ -21,15 +21,17 @@ } } + $darkModeDialogBg: darken($darkModeGameBackground, 10); + @include DarkThemeOverride { - background: rgba(#33363d, 0.9); + background: rgba($darkModeDialogBg, 0.9); @include InlineAnimation(0.12s ease-in-out) { 0% { background-color: transparent; opacity: 0.5; } 100% { - background-color: rgba(#33363d, 0.9); + background-color: rgba($darkModeDialogBg, 0.9); } } diff --git a/src/css/main.scss b/src/css/main.scss index 598e9e92..178f398b 100644 --- a/src/css/main.scss +++ b/src/css/main.scss @@ -112,6 +112,6 @@ body.modalDialogActive, body.externalAdOpen, body.ingameDialogOpen { > *:not(.ingameDialog):not(.modalDialogParent):not(.loadingDialog):not(.gameLoadingOverlay):not(#ingame_HUD_ModalDialogs):not(.noBlur) { - filter: blur(5px) !important; + // filter: blur(5px) !important; } } diff --git a/src/css/states/settings.scss b/src/css/states/settings.scss index 6c3df736..f06c9b31 100644 --- a/src/css/states/settings.scss +++ b/src/css/states/settings.scss @@ -92,11 +92,11 @@ @include DarkThemeOverride { .content { .setting { - background: #424345; + background: darken($darkModeGameBackground, 10); .value.enum { // dirty but works - filter: invert(0.8); + filter: invert(0.85); color: #222; } @@ -104,7 +104,7 @@ background-color: #74767b; &.checked { - background-color: #605b7d; + background-color: $colorBlueBright; } } } diff --git a/src/css/textual_game_state.scss b/src/css/textual_game_state.scss index 1f9dc356..a8d7a31f 100644 --- a/src/css/textual_game_state.scss +++ b/src/css/textual_game_state.scss @@ -65,7 +65,7 @@ @include DarkThemeOverride { .headerBar { h1 { - color: #cfceca; + color: #e2e0db; } .backButton { @@ -74,7 +74,7 @@ } > .container > .content { - background: #4b4c50; + background: darken($darkModeGameBackground, 3); color: #eee; } } diff --git a/src/css/variables.scss b/src/css/variables.scss index 5f056a00..c1c69371 100644 --- a/src/css/variables.scss +++ b/src/css/variables.scss @@ -38,6 +38,8 @@ $ingameHudBg: rgba(#333438, 0.9); $text3dColor: #f4ffff; +$darkModeGameBackground: #5c606c; + // Dialog properties $modalDialogBg: rgba(160, 165, 180, 0.8); $dialogBgColor: lighten($mainBgColor, 10); diff --git a/src/js/changelog.js b/src/js/changelog.js index c5be2056..0d980695 100644 --- a/src/js/changelog.js +++ b/src/js/changelog.js @@ -9,10 +9,12 @@ export const CHANGELOG = [ "Automatically deselect area when selecting a new building", "Raise markers limit from 14 characters to 71 (by Joker-vD)", "Optimize performance by caching miner items (by Phlosioneer)", + "Apply dark theme to menu as well (by dengr1065)", "Fix belt planner not placing the last belt", "Fix buildings getting deleted when right clicking while placing a blueprint", "Fix for exporting screenshots for huge bases (It was showing an empty file) (by xSparfuchs)", "Fix buttons not responding when using right click directly after left click (by davidburhans)", + "Disable dialog background blur since it can cause performance issues", "Added simplified chinese translations", "Update translations (Thanks to all translators!)", ], From 47b3ed5cbffd37f645675184c12507d2aaffa516 Mon Sep 17 00:00:00 2001 From: tobspr Date: Sun, 21 Jun 2020 20:47:37 +0200 Subject: [PATCH 39/51] Add option to render info boxes compact --- src/css/ingame_hud/building_placer.scss | 13 +++++++++++++ src/js/changelog.js | 1 + src/js/game/hud/parts/building_placer.js | 4 ++++ src/js/profile/application_settings.js | 9 ++++++++- translations/base-en.yaml | 5 +++++ 5 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/css/ingame_hud/building_placer.scss b/src/css/ingame_hud/building_placer.scss index 99c4d654..e63868ab 100644 --- a/src/css/ingame_hud/building_placer.scss +++ b/src/css/ingame_hud/building_placer.scss @@ -75,6 +75,15 @@ @include StyleBelowWidth(700px) { display: none !important; } + + &.compact { + width: unset !important; + grid-template-columns: 1fr; + .buildingImage, + .description > .text { + display: none; + } + } } #ingame_HUD_PlacerVariants { @@ -86,6 +95,10 @@ flex-direction: column; align-items: flex-end; + &.compact { + @include S(top, 150px); + } + .explanation { text-transform: uppercase; grid-row: 1 / 2; diff --git a/src/js/changelog.js b/src/js/changelog.js index 0d980695..da5ec97c 100644 --- a/src/js/changelog.js +++ b/src/js/changelog.js @@ -9,6 +9,7 @@ export const CHANGELOG = [ "Automatically deselect area when selecting a new building", "Raise markers limit from 14 characters to 71 (by Joker-vD)", "Optimize performance by caching miner items (by Phlosioneer)", + "Added setting to enable compact building infos, which only show ratios and hide the image / description", "Apply dark theme to menu as well (by dengr1065)", "Fix belt planner not placing the last belt", "Fix buildings getting deleted when right clicking while placing a blueprint", diff --git a/src/js/game/hud/parts/building_placer.js b/src/js/game/hud/parts/building_placer.js index 3a8ed0db..5faec6ab 100644 --- a/src/js/game/hud/parts/building_placer.js +++ b/src/js/game/hud/parts/building_placer.js @@ -38,6 +38,10 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic { this.buildingInfoElements.tutorialImage = makeDiv(this.element, null, ["buildingImage"]); this.variantsElement = makeDiv(parent, "ingame_HUD_PlacerVariants"); + + const compact = this.root.app.settings.getAllSettings().compactBuildingInfo; + this.element.classList.toggle("compact", compact); + this.variantsElement.classList.toggle("compact", compact); } initialize() { diff --git a/src/js/profile/application_settings.js b/src/js/profile/application_settings.js index d1216c60..964fb885 100644 --- a/src/js/profile/application_settings.js +++ b/src/js/profile/application_settings.js @@ -200,6 +200,7 @@ export const allApplicationSettings = [ new BoolSetting("alwaysMultiplace", categoryGame, (app, value) => {}), new BoolSetting("enableTunnelSmartplace", categoryGame, (app, value) => {}), new BoolSetting("vignette", categoryGame, (app, value) => {}), + new BoolSetting("compactBuildingInfo", categoryGame, (app, value) => {}), ]; export function getApplicationSettingById(id) { @@ -223,6 +224,7 @@ class SettingsStorage { this.offerHints = true; this.enableTunnelSmartplace = true; this.vignette = true; + this.compactBuildingInfo = false; /** * @type {Object.} @@ -412,7 +414,7 @@ export class ApplicationSettings extends ReadWriteProxy { } getCurrentVersion() { - return 12; + return 13; } /** @param {{settings: SettingsStorage, version: number}} data */ @@ -459,6 +461,11 @@ export class ApplicationSettings extends ReadWriteProxy { data.version = 12; } + if (data.version < 13) { + data.settings.compactBuildingInfo = false; + data.version = 13; + } + return ExplainedResult.good(); } } diff --git a/translations/base-en.yaml b/translations/base-en.yaml index afe4907d..52f4ab3c 100644 --- a/translations/base-en.yaml +++ b/translations/base-en.yaml @@ -686,6 +686,11 @@ settings: description: >- Enables the vignette which darkens the screen corners and makes text easier to read. + compactBuildingInfo: + title: Compact Building Infos + description: >- + Shortens info boxes for buildings by only showing their ratios. Otherwise a description and image is shown. + keybindings: title: Keybindings hint: >- From 0b8f7cdf6557ed3f0a3e6b6ad162ee9f4e549c3c Mon Sep 17 00:00:00 2001 From: tobspr Date: Sun, 21 Jun 2020 20:54:48 +0200 Subject: [PATCH 40/51] update artwork --- artwork/steam/announcement.png | Bin 11975 -> 17994 bytes artwork/steam/announcement.psd | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/artwork/steam/announcement.png b/artwork/steam/announcement.png index 9a6b79f5d0c7266ad8da78081a8dc94fa75292c8..85c4f1b05d79df0f1c0a91377abab84abf34a9ff 100644 GIT binary patch literal 17994 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 literal 11975 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 diff --git a/artwork/steam/announcement.psd b/artwork/steam/announcement.psd index 6f0b201c..18f4442f 100644 --- a/artwork/steam/announcement.psd +++ b/artwork/steam/announcement.psd @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3c91adcd4e00006ffa4aed4db19d1530bf8c58935b1624d1640fc8e9465a2824 -size 176993 +oid sha256:bbac64f40b2bac1187c87efc97ac718c6e57349d304939c70d99a090e822b6dc +size 235135 From 2ca5dc97158436900294aaa01f35fefa1055f590 Mon Sep 17 00:00:00 2001 From: tobspr Date: Sun, 21 Jun 2020 21:05:51 +0200 Subject: [PATCH 41/51] Fix hub marker being hidden by building info panel --- src/css/ingame_hud/waypoints.scss | 2 +- src/js/changelog.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/css/ingame_hud/waypoints.scss b/src/css/ingame_hud/waypoints.scss index ab8fed39..fecb2c66 100644 --- a/src/css/ingame_hud/waypoints.scss +++ b/src/css/ingame_hud/waypoints.scss @@ -29,7 +29,7 @@ #ingame_HUD_Waypoints { position: absolute; @include S(right, 10px); - @include S(top, 60px); + @include S(top, 45px); display: flex; flex-direction: column; @include DarkThemeInvert(); diff --git a/src/js/changelog.js b/src/js/changelog.js index da5ec97c..85dbff69 100644 --- a/src/js/changelog.js +++ b/src/js/changelog.js @@ -8,13 +8,14 @@ export const CHANGELOG = [ "Show keybindings for area-select in the upper left instead", "Automatically deselect area when selecting a new building", "Raise markers limit from 14 characters to 71 (by Joker-vD)", - "Optimize performance by caching miner items (by Phlosioneer)", + "Optimize performance by caching extractor items (by Phlosioneer)", "Added setting to enable compact building infos, which only show ratios and hide the image / description", "Apply dark theme to menu as well (by dengr1065)", "Fix belt planner not placing the last belt", "Fix buildings getting deleted when right clicking while placing a blueprint", "Fix for exporting screenshots for huge bases (It was showing an empty file) (by xSparfuchs)", "Fix buttons not responding when using right click directly after left click (by davidburhans)", + "Fix hub marker being hidden by building info panel", "Disable dialog background blur since it can cause performance issues", "Added simplified chinese translations", "Update translations (Thanks to all translators!)", From 38114ff3f62aef13c288808fc8f66878560346ae Mon Sep 17 00:00:00 2001 From: tobspr Date: Sun, 21 Jun 2020 21:22:33 +0200 Subject: [PATCH 42/51] Fix right click to delete not working --- artwork/steam/announcement-cover.png | Bin 0 -> 64479 bytes src/css/states/main_menu.scss | 8 ++++---- src/js/game/hud/parts/building_placer_logic.js | 14 +------------- 3 files changed, 5 insertions(+), 17 deletions(-) create mode 100644 artwork/steam/announcement-cover.png diff --git a/artwork/steam/announcement-cover.png b/artwork/steam/announcement-cover.png new file mode 100644 index 0000000000000000000000000000000000000000..60af91006574e8d631108b5a56fd3f1ca15bec4c GIT binary patch literal 64479 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 K(m-Z%G56aRxbK%Z`#E9H+mnE^*a;d=_4*6S`B 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 kN}?=9e>Au)^J a { - background: #4b4c50; + background: darken($darkModeGameBackground, 10); color: #eee; } diff --git a/src/js/game/hud/parts/building_placer_logic.js b/src/js/game/hud/parts/building_placer_logic.js index 647fe5b9..15564e4d 100644 --- a/src/js/game/hud/parts/building_placer_logic.js +++ b/src/js/game/hud/parts/building_placer_logic.js @@ -237,18 +237,6 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart { } } - /** - * Canvas click handler - * @param {Vector} mousePos - * @param {boolean} cancelAction - */ - onCanvasClick(mousePos, cancelAction = false) { - // Prevent any other canvas clicks - if (this.currentMetaBuilding.get()) { - return STOP_PROPAGATION; - } - } - /** * Tries to place the current building at the given tile * @param {Vector} tile @@ -473,7 +461,7 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart { this.currentlyDragging = true; this.currentlyDeleting = true; this.lastDragTile = this.root.camera.screenToWorld(pos).toTileSpace(); - this.currentMetaBuilding.set(null); + this.deleteBelowCursor(); return STOP_PROPAGATION; } From 0b31ad0c7bb77cb6d393901428ef793dd3bef97f Mon Sep 17 00:00:00 2001 From: tobspr Date: Sun, 21 Jun 2020 21:44:53 +0200 Subject: [PATCH 43/51] Pipette --- src/css/states/ingame.scss | 2 +- src/js/game/hud/hud.js | 2 ++ src/js/game/hud/parts/blueprint_placer.js | 34 +++++++++++++++---- .../game/hud/parts/building_placer_logic.js | 4 +-- src/js/game/hud/parts/keybinding_overlay.js | 9 ++++- src/js/game/hud/parts/pipette_blueprint.js | 23 +++++++++++++ src/js/game/key_action_mapper.js | 4 +-- translations/base-en.yaml | 3 +- 8 files changed, 66 insertions(+), 15 deletions(-) create mode 100644 src/js/game/hud/parts/pipette_blueprint.js diff --git a/src/css/states/ingame.scss b/src/css/states/ingame.scss index 614cdf6a..3f220a5d 100644 --- a/src/css/states/ingame.scss +++ b/src/css/states/ingame.scss @@ -31,7 +31,7 @@ @include DarkThemeOverride { .gameLoadingOverlay { - background: #56565c; + background: $darkModeGameBackground; } } } diff --git a/src/js/game/hud/hud.js b/src/js/game/hud/hud.js index 40338600..5d99194e 100644 --- a/src/js/game/hud/hud.js +++ b/src/js/game/hud/hud.js @@ -34,6 +34,7 @@ import { HUDPartTutorialHints } from "./parts/tutorial_hints"; import { HUDWaypoints } from "./parts/waypoints"; import { HUDInteractiveTutorial } from "./parts/interactive_tutorial"; import { HUDScreenshotExporter } from "./parts/screenshot_exporter"; +import { Entity } from "../entity"; export class GameHUD { /** @@ -75,6 +76,7 @@ export class GameHUD { shapeUnpinRequested: /** @type {TypedSignal<[string]>} */ (new Signal()), notification: /** @type {TypedSignal<[string, enumNotificationType]>} */ (new Signal()), buildingsSelectedForCopy: /** @type {TypedSignal<[Array]>} */ (new Signal()), + pipetteExecuted: /** @type {TypedSignal<[Entity]>} */ (new Signal()), pasteBlueprintRequested: new Signal(), }; diff --git a/src/js/game/hud/parts/blueprint_placer.js b/src/js/game/hud/parts/blueprint_placer.js index fa9faca2..3831af99 100644 --- a/src/js/game/hud/parts/blueprint_placer.js +++ b/src/js/game/hud/parts/blueprint_placer.js @@ -10,6 +10,7 @@ import { makeDiv } from "../../../core/utils"; import { DynamicDomAttach } from "../dynamic_dom_attach"; import { blueprintShape } from "../../upgrades"; import { T } from "../../../translations"; +import { PipetteBlueprint } from "./pipette_blueprint"; export class HUDBlueprintPlacer extends BaseHUDPart { createElements(parent) { @@ -34,11 +35,9 @@ export class HUDBlueprintPlacer extends BaseHUDPart { const keyActionMapper = this.root.keyMapper; keyActionMapper.getBinding(KEYMAPPINGS.general.back).add(this.abortPlacement, this); - keyActionMapper - .getBinding(KEYMAPPINGS.placement.abortBuildingPlacement) - .add(this.abortPlacement, this); keyActionMapper.getBinding(KEYMAPPINGS.placement.rotateWhilePlacing).add(this.rotateBlueprint, this); keyActionMapper.getBinding(KEYMAPPINGS.massSelect.pasteLastBlueprint).add(this.pasteBlueprint, this); + keyActionMapper.getBinding(KEYMAPPINGS.placement.pipette).add(this.startPipette, this); this.root.camera.downPreHandler.add(this.onMouseDown, this); this.root.camera.movePreHandler.add(this.onMouseMove, this); @@ -57,15 +56,36 @@ export class HUDBlueprintPlacer extends BaseHUDPart { } } + /** + * Starts the pipette function + */ + startPipette() { + const mousePosition = this.root.app.mousePosition; + if (!mousePosition) { + // Not on screen + return; + } + + const worldPos = this.root.camera.screenToWorld(mousePosition); + const tile = worldPos.toTileSpace(); + const contents = this.root.map.getTileContent(tile); + if (contents) { + const blueprint = PipetteBlueprint.fromEntity(contents); + + // Notice: Order here matters, since pipetteExecuted clears the blueprint + this.root.hud.signals.pipetteExecuted.dispatch(contents); + this.currentBlueprint.set(blueprint); + } + } + onCanAffordChanged(canAfford) { this.costDisplayParent.classList.toggle("canAfford", canAfford); } update() { - this.domAttach.update(this.currentBlueprint.get()); - this.trackedCanAfford.set( - this.currentBlueprint.get() && this.currentBlueprint.get().canAfford(this.root) - ); + const currentBlueprint = this.currentBlueprint.get(); + this.domAttach.update(currentBlueprint && currentBlueprint.getCost() > 0); + this.trackedCanAfford.set(currentBlueprint && currentBlueprint.canAfford(this.root)); } /** diff --git a/src/js/game/hud/parts/building_placer_logic.js b/src/js/game/hud/parts/building_placer_logic.js index 15564e4d..3a41a3f2 100644 --- a/src/js/game/hud/parts/building_placer_logic.js +++ b/src/js/game/hud/parts/building_placer_logic.js @@ -97,15 +97,13 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart { keyActionMapper .getBinding(KEYMAPPINGS.placement.switchDirectionLockSide) .add(this.switchDirectionLockSide, this); - keyActionMapper - .getBinding(KEYMAPPINGS.placement.abortBuildingPlacement) - .add(this.abortPlacement, this); keyActionMapper.getBinding(KEYMAPPINGS.general.back).add(this.abortPlacement, this); this.root.gameState.inputReciever.keyup.add(this.checkForDirectionLockSwitch, this); // BINDINGS TO GAME EVENTS this.root.hud.signals.buildingsSelectedForCopy.add(this.abortPlacement, this); this.root.hud.signals.pasteBlueprintRequested.add(this.abortPlacement, this); + this.root.hud.signals.pipetteExecuted.add(this.abortPlacement, this); this.root.signals.storyGoalCompleted.add(() => this.signals.variantChanged.dispatch()); this.root.signals.upgradePurchased.add(() => this.signals.variantChanged.dispatch()); diff --git a/src/js/game/hud/parts/keybinding_overlay.js b/src/js/game/hud/parts/keybinding_overlay.js index 7aca3722..633dfcef 100644 --- a/src/js/game/hud/parts/keybinding_overlay.js +++ b/src/js/game/hud/parts/keybinding_overlay.js @@ -164,10 +164,17 @@ export class HUDKeybindingOverlay extends BaseHUDPart { condition: () => this.mapOverviewActive && !this.blueprintPlacementActive, }, + { + // Pipette + label: T.ingame.keybindingsOverlay.pipette, + keys: [k.placement.pipette], + condition: () => !this.mapOverviewActive, + }, + { // Cancel placement label: T.ingame.keybindingsOverlay.stopPlacement, - keys: [KEYCODE_RMB, DIVIDER_TOKEN, k.placement.abortBuildingPlacement], + keys: [KEYCODE_RMB], condition: () => this.anyPlacementActive, }, diff --git a/src/js/game/hud/parts/pipette_blueprint.js b/src/js/game/hud/parts/pipette_blueprint.js new file mode 100644 index 00000000..3be8a207 --- /dev/null +++ b/src/js/game/hud/parts/pipette_blueprint.js @@ -0,0 +1,23 @@ +import { Vector } from "../../../core/vector"; +import { Entity } from "../../entity"; +import { Blueprint } from "./blueprint"; + +export class PipetteBlueprint extends Blueprint { + /** + * @see Blueprint.getCost + */ + getCost() { + // Its free + return 0; + } + + /** + * Creates a new pipetted blueprint from a given entity + * @param {Entity} entity + */ + static fromEntity(entity) { + const clone = entity.duplicateWithoutContents(); + clone.components.StaticMapEntity.origin = new Vector(0, 0); + return new PipetteBlueprint([clone]); + } +} diff --git a/src/js/game/key_action_mapper.js b/src/js/game/key_action_mapper.js index 659f01e6..c514446d 100644 --- a/src/js/game/key_action_mapper.js +++ b/src/js/game/key_action_mapper.js @@ -24,7 +24,7 @@ export const KEYMAPPINGS = { menuOpenStats: { keyCode: key("G") }, toggleHud: { keyCode: 113 }, // F2 - exportScreenshot: { keyCode: 114 }, // F3 + exportScreenshot: { keyCode: 114 }, // F3PS toggleFPSInfo: { keyCode: 115 }, // F4 }, @@ -56,7 +56,7 @@ export const KEYMAPPINGS = { }, placement: { - abortBuildingPlacement: { keyCode: key("Q") }, + pipette: { keyCode: key("Q") }, rotateWhilePlacing: { keyCode: key("R") }, rotateInverseModifier: { keyCode: 16 }, // SHIFT cycleBuildingVariants: { keyCode: key("T") }, diff --git a/translations/base-en.yaml b/translations/base-en.yaml index 52f4ab3c..0b754e4b 100644 --- a/translations/base-en.yaml +++ b/translations/base-en.yaml @@ -288,6 +288,7 @@ ingame: cutSelection: Cut copySelection: Copy clearSelection: Clear Selection + pipette: Pipette # Everything related to placing buildings (I.e. as soon as you selected a building # from the toolbar) @@ -738,7 +739,7 @@ keybindings: painter: *painter trash: *trash - abortBuildingPlacement: Abort Placement + pipette: Pipette rotateWhilePlacing: Rotate rotateInverseModifier: >- Modifier: Rotate CCW instead From 76b619e4e75e837f8df0e631018a39dcd7b6cde1 Mon Sep 17 00:00:00 2001 From: tobspr Date: Sun, 21 Jun 2020 21:46:20 +0200 Subject: [PATCH 44/51] Allow deselecting with pipette --- src/js/game/hud/parts/blueprint_placer.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/js/game/hud/parts/blueprint_placer.js b/src/js/game/hud/parts/blueprint_placer.js index 3831af99..eb07ae18 100644 --- a/src/js/game/hud/parts/blueprint_placer.js +++ b/src/js/game/hud/parts/blueprint_placer.js @@ -75,6 +75,8 @@ export class HUDBlueprintPlacer extends BaseHUDPart { // Notice: Order here matters, since pipetteExecuted clears the blueprint this.root.hud.signals.pipetteExecuted.dispatch(contents); this.currentBlueprint.set(blueprint); + } else { + this.root.hud.signals.pipetteExecuted.dispatch(null); } } From ba52edf7a4178c141fc2b550c8dd2190886586da Mon Sep 17 00:00:00 2001 From: tobspr Date: Sun, 21 Jun 2020 21:59:35 +0200 Subject: [PATCH 45/51] Fixes for the pipette --- artwork/steam/announcement.png | Bin 17994 -> 17746 bytes artwork/steam/announcement.psd | 4 ++-- src/js/game/hud/parts/blueprint_placer.js | 9 ++++++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/artwork/steam/announcement.png b/artwork/steam/announcement.png index 85c4f1b05d79df0f1c0a91377abab84abf34a9ff..1aacc62e82392d1dbd962548936fc6408a526829 100644 GIT binary patch literal 17746 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 literal 17994 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 diff --git a/artwork/steam/announcement.psd b/artwork/steam/announcement.psd index 18f4442f..30dce1e6 100644 --- a/artwork/steam/announcement.psd +++ b/artwork/steam/announcement.psd @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bbac64f40b2bac1187c87efc97ac718c6e57349d304939c70d99a090e822b6dc -size 235135 +oid sha256:ebde52e75e54d2f4add0cf498c85f059082a0745212a23c4de7328a7d78b00a5 +size 238170 diff --git a/src/js/game/hud/parts/blueprint_placer.js b/src/js/game/hud/parts/blueprint_placer.js index eb07ae18..822e5c67 100644 --- a/src/js/game/hud/parts/blueprint_placer.js +++ b/src/js/game/hud/parts/blueprint_placer.js @@ -60,6 +60,11 @@ export class HUDBlueprintPlacer extends BaseHUDPart { * Starts the pipette function */ startPipette() { + // Disable in overview + if (this.root.camera.getIsMapOverlayActive()) { + return; + } + const mousePosition = this.root.app.mousePosition; if (!mousePosition) { // Not on screen @@ -69,7 +74,9 @@ export class HUDBlueprintPlacer extends BaseHUDPart { const worldPos = this.root.camera.screenToWorld(mousePosition); const tile = worldPos.toTileSpace(); const contents = this.root.map.getTileContent(tile); - if (contents) { + + // Make sure we selected something, and also make sure it's not a special entity + if (contents && !contents.components.Unremovable) { const blueprint = PipetteBlueprint.fromEntity(contents); // Notice: Order here matters, since pipetteExecuted clears the blueprint From 5b2df00cc7b90839e52685606c289487ec8e7127 Mon Sep 17 00:00:00 2001 From: tobspr Date: Sun, 21 Jun 2020 22:05:41 +0200 Subject: [PATCH 46/51] Fix pipetting belts --- src/js/game/hud/parts/blueprint_placer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/game/hud/parts/blueprint_placer.js b/src/js/game/hud/parts/blueprint_placer.js index 822e5c67..62ba4df1 100644 --- a/src/js/game/hud/parts/blueprint_placer.js +++ b/src/js/game/hud/parts/blueprint_placer.js @@ -76,7 +76,7 @@ export class HUDBlueprintPlacer extends BaseHUDPart { const contents = this.root.map.getTileContent(tile); // Make sure we selected something, and also make sure it's not a special entity - if (contents && !contents.components.Unremovable) { + if (contents && !contents.components.Unremovable && !contents.components.Belt) { const blueprint = PipetteBlueprint.fromEntity(contents); // Notice: Order here matters, since pipetteExecuted clears the blueprint From d907dbb191030835d992db94a0fa22abcedc36b5 Mon Sep 17 00:00:00 2001 From: tobspr Date: Sun, 21 Jun 2020 22:29:23 +0200 Subject: [PATCH 47/51] Improve pipette --- src/js/game/hud/hud.js | 1 - src/js/game/hud/parts/blueprint_placer.js | 43 +----- .../game/hud/parts/building_placer_logic.js | 123 +++++++++++++++++- src/js/game/hud/parts/pipette_blueprint.js | 23 ---- src/js/game/meta_building.js | 30 ++++- 5 files changed, 150 insertions(+), 70 deletions(-) delete mode 100644 src/js/game/hud/parts/pipette_blueprint.js diff --git a/src/js/game/hud/hud.js b/src/js/game/hud/hud.js index 5d99194e..c322c707 100644 --- a/src/js/game/hud/hud.js +++ b/src/js/game/hud/hud.js @@ -76,7 +76,6 @@ export class GameHUD { shapeUnpinRequested: /** @type {TypedSignal<[string]>} */ (new Signal()), notification: /** @type {TypedSignal<[string, enumNotificationType]>} */ (new Signal()), buildingsSelectedForCopy: /** @type {TypedSignal<[Array]>} */ (new Signal()), - pipetteExecuted: /** @type {TypedSignal<[Entity]>} */ (new Signal()), pasteBlueprintRequested: new Signal(), }; diff --git a/src/js/game/hud/parts/blueprint_placer.js b/src/js/game/hud/parts/blueprint_placer.js index 62ba4df1..59f8dfc2 100644 --- a/src/js/game/hud/parts/blueprint_placer.js +++ b/src/js/game/hud/parts/blueprint_placer.js @@ -1,16 +1,15 @@ import { DrawParameters } from "../../../core/draw_parameters"; import { STOP_PROPAGATION } from "../../../core/signal"; import { TrackedState } from "../../../core/tracked_state"; +import { makeDiv } from "../../../core/utils"; import { Vector } from "../../../core/vector"; +import { T } from "../../../translations"; import { enumMouseButton } from "../../camera"; import { KEYMAPPINGS } from "../../key_action_mapper"; -import { BaseHUDPart } from "../base_hud_part"; -import { Blueprint } from "./blueprint"; -import { makeDiv } from "../../../core/utils"; -import { DynamicDomAttach } from "../dynamic_dom_attach"; import { blueprintShape } from "../../upgrades"; -import { T } from "../../../translations"; -import { PipetteBlueprint } from "./pipette_blueprint"; +import { BaseHUDPart } from "../base_hud_part"; +import { DynamicDomAttach } from "../dynamic_dom_attach"; +import { Blueprint } from "./blueprint"; export class HUDBlueprintPlacer extends BaseHUDPart { createElements(parent) { @@ -37,7 +36,6 @@ export class HUDBlueprintPlacer extends BaseHUDPart { keyActionMapper.getBinding(KEYMAPPINGS.general.back).add(this.abortPlacement, this); keyActionMapper.getBinding(KEYMAPPINGS.placement.rotateWhilePlacing).add(this.rotateBlueprint, this); keyActionMapper.getBinding(KEYMAPPINGS.massSelect.pasteLastBlueprint).add(this.pasteBlueprint, this); - keyActionMapper.getBinding(KEYMAPPINGS.placement.pipette).add(this.startPipette, this); this.root.camera.downPreHandler.add(this.onMouseDown, this); this.root.camera.movePreHandler.add(this.onMouseMove, this); @@ -56,37 +54,6 @@ export class HUDBlueprintPlacer extends BaseHUDPart { } } - /** - * Starts the pipette function - */ - startPipette() { - // Disable in overview - if (this.root.camera.getIsMapOverlayActive()) { - return; - } - - const mousePosition = this.root.app.mousePosition; - if (!mousePosition) { - // Not on screen - return; - } - - const worldPos = this.root.camera.screenToWorld(mousePosition); - const tile = worldPos.toTileSpace(); - const contents = this.root.map.getTileContent(tile); - - // Make sure we selected something, and also make sure it's not a special entity - if (contents && !contents.components.Unremovable && !contents.components.Belt) { - const blueprint = PipetteBlueprint.fromEntity(contents); - - // Notice: Order here matters, since pipetteExecuted clears the blueprint - this.root.hud.signals.pipetteExecuted.dispatch(contents); - this.currentBlueprint.set(blueprint); - } else { - this.root.hud.signals.pipetteExecuted.dispatch(null); - } - } - onCanAffordChanged(canAfford) { this.costDisplayParent.classList.toggle("canAfford", canAfford); } diff --git a/src/js/game/hud/parts/building_placer_logic.js b/src/js/game/hud/parts/building_placer_logic.js index 3a41a3f2..0da81d4a 100644 --- a/src/js/game/hud/parts/building_placer_logic.js +++ b/src/js/game/hud/parts/building_placer_logic.js @@ -1,5 +1,6 @@ import { Math_abs, Math_degrees, Math_round } from "../../../core/builtins"; import { globalConfig } from "../../../core/config"; +import { gMetaBuildingRegistry } from "../../../core/global_registries"; import { Signal, STOP_PROPAGATION } from "../../../core/signal"; import { TrackedState } from "../../../core/tracked_state"; import { Vector } from "../../../core/vector"; @@ -9,7 +10,6 @@ import { Entity } from "../../entity"; import { KEYMAPPINGS } from "../../key_action_mapper"; import { defaultBuildingVariant, MetaBuilding } from "../../meta_building"; import { BaseHUDPart } from "../base_hud_part"; -import { lerp } from "../../../core/utils"; /** * Contains all logic for the building placer - this doesn't include the rendering @@ -98,12 +98,12 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart { .getBinding(KEYMAPPINGS.placement.switchDirectionLockSide) .add(this.switchDirectionLockSide, this); keyActionMapper.getBinding(KEYMAPPINGS.general.back).add(this.abortPlacement, this); + keyActionMapper.getBinding(KEYMAPPINGS.placement.pipette).add(this.startPipette, this); this.root.gameState.inputReciever.keyup.add(this.checkForDirectionLockSwitch, this); // BINDINGS TO GAME EVENTS this.root.hud.signals.buildingsSelectedForCopy.add(this.abortPlacement, this); this.root.hud.signals.pasteBlueprintRequested.add(this.abortPlacement, this); - this.root.hud.signals.pipetteExecuted.add(this.abortPlacement, this); this.root.signals.storyGoalCompleted.add(() => this.signals.variantChanged.dispatch()); this.root.signals.upgradePurchased.add(() => this.signals.variantChanged.dispatch()); @@ -218,6 +218,125 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart { } } + /** + * Starts the pipette function + */ + startPipette() { + // Disable in overview + if (this.root.camera.getIsMapOverlayActive()) { + return; + } + + const mousePosition = this.root.app.mousePosition; + if (!mousePosition) { + // Not on screen + return; + } + + const worldPos = this.root.camera.screenToWorld(mousePosition); + const tile = worldPos.toTileSpace(); + const contents = this.root.map.getTileContent(tile); + + if (!contents) { + this.currentMetaBuilding.set(null); + return; + } + + // Try to extract the building + const extracted = this.hack_reconstructMetaBuildingAndVariantFromBuilding(contents); + if (!extracted) { + this.currentMetaBuilding.set(null); + return; + } + + this.currentMetaBuilding.set(extracted.metaBuilding); + this.currentVariant.set(extracted.variant); + this.currentBaseRotation = contents.components.StaticMapEntity.rotation; + + // Make sure we selected something, and also make sure it's not a special entity + // if (contents && !contents.components.Unremovable) { + + // } + } + + /** + * HACK! + * + * This attempts to reconstruct the meta building and its variant from a given entity + * @param {Entity} entity + * @returns {{ metaBuilding: MetaBuilding, variant: string }} + */ + hack_reconstructMetaBuildingAndVariantFromBuilding(entity) { + if (entity.components.Hub) { + // Hub is not copyable + return null; + } + + const matches = []; + const metaBuildings = gMetaBuildingRegistry.entries; + for (let i = 0; i < metaBuildings.length; ++i) { + const metaBuilding = metaBuildings[i]; + const availableVariants = metaBuilding.getAvailableVariants(this.root); + checkVariant: for (let k = 0; k < availableVariants.length; ++k) { + const variant = availableVariants[k]; + let unplaced = metaBuilding.createEntity({ + root: this.root, + variant, + origin: new Vector(0, 0), + rotation: 0, + originalRotation: 0, + rotationVariant: 0, + }); + + // Compare if both entities share the same components + for (let component in entity.components) { + if ((entity.components[component] == null) !== (unplaced.components[component] == null)) { + continue checkVariant; + } + } + + // Check for same item processor + if ( + entity.components.ItemProcessor && + entity.components.ItemProcessor.type != unplaced.components.ItemProcessor.type + ) { + continue checkVariant; + } + + // Check for underground belt + if ( + entity.components.UndergroundBelt && + entity.components.UndergroundBelt.tier != unplaced.components.UndergroundBelt.tier + ) { + continue checkVariant; + } + + // Check for same sprite key - except for underground belts + // since the sprite may vary here + if ( + !entity.components.UndergroundBelt && + entity.components.StaticMapEntity.spriteKey != + unplaced.components.StaticMapEntity.spriteKey + ) { + continue checkVariant; + } + matches.push({ metaBuilding, variant }); + } + } + + if (matches.length == 1) { + const staticEntity = entity.components.StaticMapEntity; + const key = staticEntity.spriteKey || staticEntity.blueprintSpriteKey; + assert( + key && + key.includes(matches[0].metaBuilding.id) && + (matches[0].variant === defaultBuildingVariant || key.includes(matches[0].variant)) + ); + return matches[0]; + } + return null; + } + switchDirectionLockSide() { this.currentDirectionLockSide = 1 - this.currentDirectionLockSide; } diff --git a/src/js/game/hud/parts/pipette_blueprint.js b/src/js/game/hud/parts/pipette_blueprint.js deleted file mode 100644 index 3be8a207..00000000 --- a/src/js/game/hud/parts/pipette_blueprint.js +++ /dev/null @@ -1,23 +0,0 @@ -import { Vector } from "../../../core/vector"; -import { Entity } from "../../entity"; -import { Blueprint } from "./blueprint"; - -export class PipetteBlueprint extends Blueprint { - /** - * @see Blueprint.getCost - */ - getCost() { - // Its free - return 0; - } - - /** - * Creates a new pipetted blueprint from a given entity - * @param {Entity} entity - */ - static fromEntity(entity) { - const clone = entity.duplicateWithoutContents(); - clone.components.StaticMapEntity.origin = new Vector(0, 0); - return new PipetteBlueprint([clone]); - } -} diff --git a/src/js/game/meta_building.js b/src/js/game/meta_building.js index 723e854b..11da28f3 100644 --- a/src/js/game/meta_building.js +++ b/src/js/game/meta_building.js @@ -147,10 +147,32 @@ export class MetaBuilding { * @param {string} param0.variant */ createAndPlaceEntity({ root, origin, rotation, originalRotation, rotationVariant, variant }) { + const entity = this.createEntity({ + root, + origin, + rotation, + originalRotation, + rotationVariant, + variant, + }); + root.map.placeStaticEntity(entity); + root.entityMgr.registerEntity(entity); + return entity; + } + + /** + * Creates the entity without placing it + * @param {object} param0 + * @param {GameRoot} param0.root + * @param {Vector} param0.origin Origin tile + * @param {number=} param0.rotation Rotation + * @param {number} param0.originalRotation Original Rotation + * @param {number} param0.rotationVariant Rotation variant + * @param {string} param0.variant + */ + createEntity({ root, origin, rotation, originalRotation, rotationVariant, variant }) { const entity = new Entity(root); - const blueprintSprite = this.getBlueprintSprite(rotationVariant, variant); - entity.addComponent( new StaticMapEntityComponent({ spriteKey: @@ -166,12 +188,8 @@ export class MetaBuilding { blueprintSpriteKey: blueprintSprite ? blueprintSprite.spriteName : "", }) ); - this.setupEntityComponents(entity, root); this.updateVariants(entity, rotationVariant, variant); - - root.map.placeStaticEntity(entity); - root.entityMgr.registerEntity(entity); return entity; } From 597eefe968e6f2d481bb8b51a9ad3968a8e8713f Mon Sep 17 00:00:00 2001 From: tobspr Date: Sun, 21 Jun 2020 22:51:42 +0200 Subject: [PATCH 48/51] Deselect blueprint on pipette --- src/js/game/hud/parts/blueprint_placer.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/js/game/hud/parts/blueprint_placer.js b/src/js/game/hud/parts/blueprint_placer.js index 59f8dfc2..ef46f101 100644 --- a/src/js/game/hud/parts/blueprint_placer.js +++ b/src/js/game/hud/parts/blueprint_placer.js @@ -34,6 +34,7 @@ export class HUDBlueprintPlacer extends BaseHUDPart { const keyActionMapper = this.root.keyMapper; keyActionMapper.getBinding(KEYMAPPINGS.general.back).add(this.abortPlacement, this); + keyActionMapper.getBinding(KEYMAPPINGS.placement.pipette).add(this.abortPlacement, this); keyActionMapper.getBinding(KEYMAPPINGS.placement.rotateWhilePlacing).add(this.rotateBlueprint, this); keyActionMapper.getBinding(KEYMAPPINGS.massSelect.pasteLastBlueprint).add(this.pasteBlueprint, this); From e660fd2cafb63d8bf6873cc97928bf1baa18d2e2 Mon Sep 17 00:00:00 2001 From: tobspr Date: Sun, 21 Jun 2020 22:54:50 +0200 Subject: [PATCH 49/51] Update changelog --- src/js/changelog.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/js/changelog.js b/src/js/changelog.js index 85dbff69..fa41760b 100644 --- a/src/js/changelog.js +++ b/src/js/changelog.js @@ -1,8 +1,9 @@ export const CHANGELOG = [ { version: "1.1.16", - date: "unreleased", + date: "21.06.2020", entries: [ + "You can now pickup buildings below your cursor with 'Q'!", "The game soundtrack has been extended! There are now 4 songs with over 13 minutes of playtime from Peppsen!", "Refactor keybindings overlay to show more appropriate keybindings", "Show keybindings for area-select in the upper left instead", From 5e83c4642b4c882a74d26e973aad3e700f696e39 Mon Sep 17 00:00:00 2001 From: tobspr Date: Sun, 21 Jun 2020 22:56:38 +0200 Subject: [PATCH 50/51] Reduce sound volume --- gulp/sounds.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gulp/sounds.js b/gulp/sounds.js index 1b18278d..0e8dee12 100644 --- a/gulp/sounds.js +++ b/gulp/sounds.js @@ -29,7 +29,7 @@ function gulptasksSounds($, gulp, buildFolder) { .audioChannels(1) .audioFrequency(22050) .audioCodec("libmp3lame") - .audioFilters(["volume=0.3"]); + .audioFilters(["volume=0.15"]); }), { name: "music", From 969b7a74d44403e7aba5f8641048b172664bc635 Mon Sep 17 00:00:00 2001 From: tobspr Date: Sun, 21 Jun 2020 23:01:42 +0200 Subject: [PATCH 51/51] Fix belt planner shortcut being shown always --- src/js/game/hud/parts/keybinding_overlay.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/js/game/hud/parts/keybinding_overlay.js b/src/js/game/hud/parts/keybinding_overlay.js index 633dfcef..5b7f4a9d 100644 --- a/src/js/game/hud/parts/keybinding_overlay.js +++ b/src/js/game/hud/parts/keybinding_overlay.js @@ -44,7 +44,7 @@ export class HUDKeybindingOverlay extends BaseHUDPart { * it supports the belt planner * @returns {boolean} */ - get buildingPlacementBeltPlanner() { + get buildingPlacementSupportsBeltPlanner() { const placer = this.root.hud.parts.buildingPlacer; return ( !this.mapOverviewActive && @@ -225,7 +225,7 @@ export class HUDKeybindingOverlay extends BaseHUDPart { // Belt planner label: T.ingame.keybindingsOverlay.lockBeltDirection, keys: [k.placementModifiers.lockBeltDirection], - condition: () => this.buildingPlacementActive && !this.beltPlannerActive, + condition: () => this.buildingPlacementSupportsBeltPlanner && !this.beltPlannerActive, }, {