From a1cc0cc49c3eb24892b05412d8de09d5340dee6f Mon Sep 17 00:00:00 2001 From: RevosCZ <72229413+RevosCZ@users.noreply.github.com> Date: Thu, 3 Feb 2022 08:40:06 +0100 Subject: [PATCH 01/21] Update base-cz.yaml (#1366) Added translations for the new mod update. --- translations/base-cz.yaml | 86 +++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/translations/base-cz.yaml b/translations/base-cz.yaml index 7a907e97..b734ab22 100644 --- a/translations/base-cz.yaml +++ b/translations/base-cz.yaml @@ -77,9 +77,9 @@ mainMenu: puzzleDlcWishlist: Přidejte si nyní na seznam přání! puzzleDlcViewNow: Zobrazit DLC mods: - title: Active Mods - warningPuzzleDLC: Playing the Puzzle DLC is not possible with mods. Please - disable all mods to play the DLC. + title: Aktivní módy + warningPuzzleDLC: Nelze hrát Puzzle DLC společně s módy. Prosím + deaktivujte všechny módy, abyste mohli hrát DLC. dialogs: buttons: ok: OK @@ -257,12 +257,12 @@ dialogs: title: Smazat puzzle? desc: Jste si jisti, že chcete smazat ''? Tato akce je nevratná! modsDifference: - title: Mod Warning - desc: The currently installed mods differ from the mods the savegame was created - with. This might cause the savegame to break or not load at all. Are - you sure you want to continue? - missingMods: Missing Mods - newMods: Newly installed Mods + title: Varování o módech + desc: Aktuálně nainstalované módy se liší od módů, se kterými byla uložená hra + vytvořena. To může způsobit, že se uložená hra rozbije nebo se vůbec nenačte. + Jste si jisti, že chcete pokračovat? + missingMods: Chybějící módy + newMods: Nově nainstalované módy ingame: keybindingsOverlay: moveMap: Posun mapy @@ -468,7 +468,7 @@ ingame: titleRatingDesc: Vaše hodnocení nám pomůže podat vám v budoucnu lepší návrhy continueBtn: Hrát dál menuBtn: Menu - nextPuzzle: Next Puzzle + nextPuzzle: Další puzzle puzzleMetadata: author: Autor shortKey: Krátký klíč @@ -1007,12 +1007,12 @@ settings: title: Velikost zdrojů na mapě description: Určuje velikost ikon tvarů na náhledu mapy (při oddálení). shapeTooltipAlwaysOn: - title: Shape Tooltip - Show Always - description: Whether to always show the shape tooltip when hovering buildings, - instead of having to hold 'ALT'. + title: Popisek tvaru – Zobrazit vždy + description: Určuje, zda se má vždy zobrazovat nápověda tvaru při najetí na budovy, + místo toho, abyste museli držet „ALT“. rangeSliderPercentage: <amount> % tickrateHz: <amount> Hz - newBadge: New! + newBadge: Nové! keybindings: title: Klávesové zkratky hint: "Tip: Nezapomeňte používat CTRL, SHIFT a ALT! Díky nim můžete měnit způsob @@ -1026,7 +1026,7 @@ keybindings: massSelect: Hromadný výběr buildings: Zkratky pro stavbu placementModifiers: Modifikátory umístění - mods: Provided by Mods + mods: Poskytnuto z módů mappings: confirm: Potvrdit back: Zpět @@ -1095,7 +1095,7 @@ keybindings: goal_acceptor: Přijemce cílů block: Blok massSelectClear: Vymazat pásy - showShapeTooltip: Show shape output tooltip + showShapeTooltip: Zobrazit popisek výstupu tvaru about: title: O hře body: >- @@ -1233,24 +1233,24 @@ puzzleMenu: easy: Lehká medium: Střední hard: Těžká - unknown: Unrated + unknown: Nehodnoceno dlcHint: Již jste toto DLC zakoupili? Ujistěte se, že je aktivováno kliknutím pravého tlačítka na shapez.io ve své knihovně, vybráním Vlastnosti > DLC. search: - action: Search - placeholder: Enter a puzzle or author name - includeCompleted: Include Completed + action: Hledat + placeholder: Vložte název puzzlu nebo jméno autora + includeCompleted: Včetně dokončených difficulties: - any: Any Difficulty - easy: Easy - medium: Medium - hard: Hard + any: Jakákoli obtížnost + easy: Lehká + medium: Střední + hard: Těžká durations: - any: Any Duration - short: Short (< 2 min) - medium: Normal - long: Long (> 10 min) + any: Jakákoli doba trvání + short: Krátká (< 2 min) + medium: Normální + long: Dlouhá (> 10 min) backendErrors: ratelimit: Provádíte své akce příliš často. Počkejte prosím. invalid-api-key: Komunikace s back-endem se nezdařila, prosím zkuste @@ -1278,19 +1278,19 @@ backendErrors: přesto chcete odstranit, kontaktujte nás prosím na support@shapez.io! no-permission: K provedení této akce nemáte oprávnění. mods: - title: Mods - author: Author - version: Version - modWebsite: Website - openFolder: Open Mods Folder - folderOnlyStandalone: Opening the mod folder is only possible when running the standalone. - browseMods: Browse Mods - modsInfo: To install and manage mods, copy them to the mods folder within the - game directory. You can also use the 'Open Mods Folder' button on the - top right. - noModSupport: You need the standalone version on Steam to install mods. + title: Módy + author: Autor + version: Verze + modWebsite: Webová stránka + openFolder: Otevřít složku s módy + folderOnlyStandalone: Otevření složky s módy je možné pouze v samostatné verzi hry. + browseMods: Procházet módy + modsInfo: Chcete-li nainstalovat a spravovat módy, zkopírujte je do složky mods + v adresáři hry. Můžete také použít tlačítko 'Otevřít složku s módy' + vpravo nahoře. + noModSupport: K instalaci módů potřebujete samostatnou verzi hry na Steamu. togglingComingSoon: - title: Coming Soon - description: Enabling or disabling mods is currently only possible by copying - the mod file from or to the mods/ folder. However, being able to - toggle them here is planned for a future update! + title: Již brzy + description: Aktivace či deaktivace módů je v současné době možná pouze kopírováním + souboru módu z nebo do mods/ složky. Nicméně, možnost správy módů přímo + ze hry je plánována pro budoucí aktualizaci! From 10fb7ddb5c67961f2663c7688bc80938447a485d Mon Sep 17 00:00:00 2001 From: Bagel03 <70449196+Bagel03@users.noreply.github.com> Date: Thu, 3 Feb 2022 02:40:24 -0500 Subject: [PATCH 02/21] Whoops shouldn't have forgotten that (#1367) Yea, should not have forgotten that :P --- gulp/webpack.production.config.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gulp/webpack.production.config.js b/gulp/webpack.production.config.js index fdd477b9..567ca38c 100644 --- a/gulp/webpack.production.config.js +++ b/gulp/webpack.production.config.js @@ -230,6 +230,9 @@ module.exports = ({ { pattern: /globalConfig\.debug/g, replacement: () => "''" }, ], }), + { + loader: path.resolve(__dirname, "mod.js"), + }, ], }, { From edd57b39567e6140772d83a98b9ef3198b9d6c7a Mon Sep 17 00:00:00 2001 From: WaffleDevsAlt <81845843+WaffleDevsAlt@users.noreply.github.com> Date: Thu, 3 Feb 2022 02:40:32 -0500 Subject: [PATCH 03/21] Fixed extremely unimportant typo. (#1368) 'ot' to 'to' --- electron/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/electron/index.js b/electron/index.js index 03fb4278..4ea7b9b9 100644 --- a/electron/index.js +++ b/electron/index.js @@ -373,7 +373,7 @@ try { mods = loadMods(); console.log("Loaded", mods.length, "mods"); } catch (ex) { - console.error("Failed ot load mods"); + console.error("Failed to load mods"); dialog.showErrorBox("Failed to load mods:", ex); } From 8e38ef070869cb3ac0c3f0dd1405d11b8d322ec0 Mon Sep 17 00:00:00 2001 From: "Thomas (DJ1TJOO)" <44841260+DJ1TJOO@users.noreply.github.com> Date: Thu, 3 Feb 2022 20:03:02 +0100 Subject: [PATCH 04/21] Modloader custom items fix (#1369) * Added item register and resolver for savegames * Changed new item type example to register * Fixed typings --- mod_examples/new_item_type.js | 26 ++++++++++++++------------ src/js/game/base_item.js | 2 +- src/js/game/item_resolver.js | 6 ++++++ src/js/mods/mod_interface.js | 13 ++++++++++++- src/js/savegame/serialization.js | 2 +- 5 files changed, 34 insertions(+), 15 deletions(-) diff --git a/mod_examples/new_item_type.js b/mod_examples/new_item_type.js index 3cd52cef..3f47d4d2 100644 --- a/mod_examples/new_item_type.js +++ b/mod_examples/new_item_type.js @@ -120,19 +120,21 @@ class Mod extends shapez.Mod { this.modInterface.registerSprite("sprites/fluids/water.png", RESOURCES["water.png"]); // Make the item spawn on the map - this.modInterface.runAfterMethod(shapez.MapChunk, "generatePatches", function ({ - rng, - chunkCenter, - distanceToOriginInChunks, - }) { - // Generate a simple patch - // ALWAYS use rng and NEVER use Math.random() otherwise the map will look different - // every time you resume the game - if (rng.next() > 0.8) { - const fluidType = rng.choice(Array.from(Object.keys(enumFluidType))); - this.internalGeneratePatch(rng, 4, FLUID_ITEM_SINGLETONS[fluidType]); + this.modInterface.runAfterMethod( + shapez.MapChunk, + "generatePatches", + function ({ rng, chunkCenter, distanceToOriginInChunks }) { + // Generate a simple patch + // ALWAYS use rng and NEVER use Math.random() otherwise the map will look different + // every time you resume the game + if (rng.next() > 0.8) { + const fluidType = rng.choice(Array.from(Object.keys(enumFluidType))); + this.internalGeneratePatch(rng, 4, FLUID_ITEM_SINGLETONS[fluidType]); + } } - }); + ); + + this.modInterface.registerItem(FluidItem, itemData => FLUID_ITEM_SINGLETONS[itemData]); } } diff --git a/src/js/game/base_item.js b/src/js/game/base_item.js index ae569ddf..f6ed1672 100644 --- a/src/js/game/base_item.js +++ b/src/js/game/base_item.js @@ -15,7 +15,7 @@ export class BaseItem extends BasicSerializableObject { return "base_item"; } - /** @returns {object} */ + /** @returns {import("../savegame/serialization").Schema} */ static getSchema() { return {}; } diff --git a/src/js/game/item_resolver.js b/src/js/game/item_resolver.js index da15fa0c..ff91b0a3 100644 --- a/src/js/game/item_resolver.js +++ b/src/js/game/item_resolver.js @@ -4,6 +4,8 @@ import { BooleanItem, BOOL_TRUE_SINGLETON, BOOL_FALSE_SINGLETON } from "./items/ import { ShapeItem } from "./items/shape_item"; import { ColorItem, COLOR_ITEM_SINGLETONS } from "./items/color_item"; +export const MODS_ADDITIONAL_ITEMS = {}; + /** * Resolves items so we share instances * @param {import("../savegame/savegame_serializer").GameRoot} root @@ -13,6 +15,10 @@ export function itemResolverSingleton(root, data) { const itemType = data.$; const itemData = data.data; + if (MODS_ADDITIONAL_ITEMS[itemType]) { + return MODS_ADDITIONAL_ITEMS[itemType](itemData); + } + switch (itemType) { case BooleanItem.getId(): { return itemData ? BOOL_TRUE_SINGLETON : BOOL_FALSE_SINGLETON; diff --git a/src/js/mods/mod_interface.js b/src/js/mods/mod_interface.js index 13bdb9d2..295014ca 100644 --- a/src/js/mods/mod_interface.js +++ b/src/js/mods/mod_interface.js @@ -17,7 +17,7 @@ import { Loader } from "../core/loader"; import { LANGUAGES } from "../languages"; import { matchDataRecursive, T } from "../translations"; import { gBuildingVariants, registerBuildingVariant } from "../game/building_codes"; -import { gComponentRegistry, gMetaBuildingRegistry } from "../core/global_registries"; +import { gComponentRegistry, gItemRegistry, gMetaBuildingRegistry } from "../core/global_registries"; import { MODS_ADDITIONAL_SHAPE_MAP_WEIGHTS } from "../game/map_chunk"; import { MODS_ADDITIONAL_SYSTEMS } from "../game/game_system_manager"; import { MOD_CHUNK_DRAW_HOOKS } from "../game/map_chunk_view"; @@ -28,6 +28,8 @@ import { ModMetaBuilding } from "./mod_meta_building"; import { BaseHUDPart } from "../game/hud/base_hud_part"; import { Vector } from "../core/vector"; import { GameRoot } from "../game/root"; +import { BaseItem } from "../game/base_item"; +import { MODS_ADDITIONAL_ITEMS } from "../game/item_resolver"; /** * @typedef {{new(...args: any[]): any, prototype: any}} constructable @@ -190,6 +192,15 @@ export class ModInterface { } } + /** + * @param {typeof BaseItem} item + * @param {(itemData: any) => BaseItem} resolver + */ + registerItem(item, resolver) { + gItemRegistry.register(item); + MODS_ADDITIONAL_ITEMS[item.getId()] = resolver; + } + /** * * @param {typeof Component} component diff --git a/src/js/savegame/serialization.js b/src/js/savegame/serialization.js index 770f166f..682558b6 100644 --- a/src/js/savegame/serialization.js +++ b/src/js/savegame/serialization.js @@ -192,7 +192,7 @@ export class BasicSerializableObject { return schema; } - /** @returns {object} */ + /** @returns {object | string | number} */ serialize() { return serializeSchema( this, From aa8d105e141f2183a1447a79e47a2d868dde9110 Mon Sep 17 00:00:00 2001 From: tobspr <tobias.springer1@googlemail.com> Date: Thu, 3 Feb 2022 20:26:29 +0100 Subject: [PATCH 05/21] Revert being able to override exports since it breaks in prod --- gulp/webpack.config.js | 3 --- gulp/webpack.production.config.js | 3 --- src/js/mods/modloader.js | 5 ++--- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/gulp/webpack.config.js b/gulp/webpack.config.js index 3c07d7cc..7db0bf0b 100644 --- a/gulp/webpack.config.js +++ b/gulp/webpack.config.js @@ -93,9 +93,6 @@ module.exports = ({ watch = false, standalone = false, chineseVersion = false, w end: "typehints:end", }, }, - { - loader: path.resolve(__dirname, "mod.js"), - }, ], }, { diff --git a/gulp/webpack.production.config.js b/gulp/webpack.production.config.js index 567ca38c..fdd477b9 100644 --- a/gulp/webpack.production.config.js +++ b/gulp/webpack.production.config.js @@ -230,9 +230,6 @@ module.exports = ({ { pattern: /globalConfig\.debug/g, replacement: () => "''" }, ], }), - { - loader: path.resolve(__dirname, "mod.js"), - }, ], }, { diff --git a/src/js/mods/modloader.js b/src/js/mods/modloader.js index 356b7d6b..daf0766e 100644 --- a/src/js/mods/modloader.js +++ b/src/js/mods/modloader.js @@ -112,8 +112,7 @@ export class ModLoader { // @ts-ignore const module = modules(key); for (const member in module) { - if (member === "default" || member === "$s") { - // Setter + if (member === "default") { continue; } if (exports[member]) { @@ -125,7 +124,7 @@ export class ModLoader { return module[member]; }, set(v) { - module["$s"](member, v); + throw new Error("Overriding the shapez exports is currently not possible"); }, }); } From c0d034520ab84c54281e18af2b061ad72b0604e0 Mon Sep 17 00:00:00 2001 From: tobspr <tobias.springer1@googlemail.com> Date: Fri, 4 Feb 2022 09:53:44 +0100 Subject: [PATCH 06/21] Fix wrong if clause --- electron/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/electron/index.js b/electron/index.js index 4ea7b9b9..41831bdd 100644 --- a/electron/index.js +++ b/electron/index.js @@ -383,6 +383,7 @@ ipcMain.handle("get-mods", async () => { steam.init(isDev); -if (mods) { +// Only allow achievements and puzzle DLC if no mods are loaded +if (mods.length === 0) { steam.listen(); } From 71ac87bfac3ab9ec5819850f481d7014c7ee0a77 Mon Sep 17 00:00:00 2001 From: tobspr <tobias.springer1@googlemail.com> Date: Fri, 4 Feb 2022 17:33:37 +0100 Subject: [PATCH 07/21] Update mod examples readme --- mod_examples/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/mod_examples/README.md b/mod_examples/README.md index 04702576..6711df06 100644 --- a/mod_examples/README.md +++ b/mod_examples/README.md @@ -7,8 +7,6 @@ Currently there are two options to develop mods for shapez.io: 1. Writing single file mods, which doesn't require any additional tools and can be loaded directly in the game 2. Using the [create-shapezio-mod](https://www.npmjs.com/package/create-shapezio-mod) package. This package is still in development but allows you to pack multiple files and images into a single mod file, so you don't have to base64 encode your images etc. -Since the `create-shapezio-mod` package is still in development, the current recommended way is to write single file mods, which I'll explain now. - ## Mod Developer Discord A great place to get help with mod development is the official [shapez.io modloader discord](https://discord.gg/xq5v8uyMue). From 86b104080f5460b57564ccbe5844d3059a30547a Mon Sep 17 00:00:00 2001 From: tobspr <tobias.springer1@googlemail.com> Date: Fri, 4 Feb 2022 17:56:17 +0100 Subject: [PATCH 08/21] Simplify readme link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4a042cd9..2b8d208b 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ This is the source code for shapez.io, an open source base building game inspired by Factorio. Your goal is to produce shapes by cutting, rotating, merging and painting parts of shapes. -- [Steam Page](https://steam.shapez.io) +- [Steam Page](https://get.shapez.io/ghr) - [Official Discord](https://discord.com/invite/HN7EVzV) <- _Highly recommended to join!_ - [Trello Board & Roadmap](https://trello.com/b/ISQncpJP/shapezio) - [itch.io Page](https://tobspr.itch.io/shapezio) From 41c6b1c59508c48f6f172601efbd4ea960260275 Mon Sep 17 00:00:00 2001 From: "Thomas (DJ1TJOO)" <44841260+DJ1TJOO@users.noreply.github.com> Date: Sun, 13 Feb 2022 21:05:58 +0100 Subject: [PATCH 09/21] Added mod processing requirements (#1371) * Added mod processing requirements * Added missing bind * Renamed to mods --- src/js/game/systems/item_processor.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/js/game/systems/item_processor.js b/src/js/game/systems/item_processor.js index 6e1032c9..e9e2d298 100644 --- a/src/js/game/systems/item_processor.js +++ b/src/js/game/systems/item_processor.js @@ -38,11 +38,25 @@ const MAX_QUEUED_CHARGES = 2; * }} ProcessorImplementationPayload */ +/** + * Type of a processor implementation + * @typedef {{ + * entity: Entity, + * item: BaseItem, + * slotIndex: number + * }} ProccessingRequirementsImplementationPayload + */ + /** * @type {Object<string, (ProcessorImplementationPayload) => void>} */ export const MOD_ITEM_PROCESSOR_HANDLERS = {}; +/** + * @type {Object<string, (ProccessingRequirementsImplementationPayload) => boolean>} + */ +export const MODS_PROCESSING_REQUIREMENTS = {}; + export class ItemProcessorSystem extends GameSystemWithFilter { constructor(root) { super(root, [ItemProcessorComponent]); @@ -163,6 +177,14 @@ export class ItemProcessorSystem extends GameSystemWithFilter { const itemProcessorComp = entity.components.ItemProcessor; const pinsComp = entity.components.WiredPins; + if (MODS_PROCESSING_REQUIREMENTS[itemProcessorComp.processingRequirement]) { + return MODS_PROCESSING_REQUIREMENTS[itemProcessorComp.processingRequirement].bind(this)({ + entity, + item, + slotIndex, + }); + } + switch (itemProcessorComp.processingRequirement) { case enumItemProcessorRequirements.painterQuad: { if (slotIndex === 0) { From e5742fd577613b2a43792819432ed8303ac4c4fc Mon Sep 17 00:00:00 2001 From: "Thomas (DJ1TJOO)" <44841260+DJ1TJOO@users.noreply.github.com> Date: Sun, 13 Feb 2022 21:06:10 +0100 Subject: [PATCH 10/21] Added constant signal resolver hook (#1372) * Added constant signal resolver hook * Added apply --- src/js/game/hud/parts/constant_signal_edit.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/js/game/hud/parts/constant_signal_edit.js b/src/js/game/hud/parts/constant_signal_edit.js index a6e7501d..f7099046 100644 --- a/src/js/game/hud/parts/constant_signal_edit.js +++ b/src/js/game/hud/parts/constant_signal_edit.js @@ -15,6 +15,11 @@ import trim from "trim"; import { enumColors } from "../../colors"; import { ShapeDefinition } from "../../shape_definition"; +/** @type {{ + * [x: string]: (entity: Entity) => BaseItem + * }} */ +export const MODS_ADDITIONAL_CONSTANT_SIGNAL_RESOLVER = {}; + export class HUDConstantSignalEdit extends BaseHUDPart { initialize() { this.root.camera.downPreHandler.add(this.downPreHandler, this); @@ -190,6 +195,10 @@ export class HUDConstantSignalEdit extends BaseHUDPart { code = trim(code); const codeLower = code.toLowerCase(); + if (MODS_ADDITIONAL_CONSTANT_SIGNAL_RESOLVER[codeLower]) { + return MODS_ADDITIONAL_CONSTANT_SIGNAL_RESOLVER[codeLower].apply(this, [entity]); + } + if (enumColors[codeLower]) { return COLOR_ITEM_SINGLETONS[codeLower]; } From 65ae26cb5332a534bec649a579d20c62e078ccc0 Mon Sep 17 00:00:00 2001 From: "Thomas (DJ1TJOO)" <44841260+DJ1TJOO@users.noreply.github.com> Date: Sun, 13 Feb 2022 21:06:24 +0100 Subject: [PATCH 11/21] Added hook for storage can accept item (#1373) * Added hook for storage can accept item * Fixed order --- src/js/game/components/storage.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/js/game/components/storage.js b/src/js/game/components/storage.js index be243a44..46305929 100644 --- a/src/js/game/components/storage.js +++ b/src/js/game/components/storage.js @@ -5,6 +5,10 @@ import { typeItemSingleton } from "../item_resolver"; import { ColorItem } from "../items/color_item"; import { ShapeItem } from "../items/shape_item"; +/** @type {{ + * [x: string]: (item: BaseItem) => Boolean + * }} */ +export const MODS_ADDITIONAL_STORAGE_ITEM_RESOLVER = {}; export class StorageComponent extends Component { static getId() { return "Storage"; @@ -56,11 +60,15 @@ export class StorageComponent extends Component { const itemType = item.getItemType(); - // Check type matches if (itemType !== this.storedItem.getItemType()) { + // Check type matches return false; } + if (MODS_ADDITIONAL_STORAGE_ITEM_RESOLVER[itemType]) { + return MODS_ADDITIONAL_STORAGE_ITEM_RESOLVER[itemType].apply(this, [item]); + } + if (itemType === "color") { return /** @type {ColorItem} */ (this.storedItem).color === /** @type {ColorItem} */ (item).color; } From 4466821557d246e5926b5ef07cef161dacbb8f84 Mon Sep 17 00:00:00 2001 From: "Thomas (DJ1TJOO)" <44841260+DJ1TJOO@users.noreply.github.com> Date: Sun, 13 Feb 2022 21:06:42 +0100 Subject: [PATCH 12/21] Added display hook for getting the signelton and the drawing (#1374) --- src/js/game/systems/display.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/js/game/systems/display.js b/src/js/game/systems/display.js index 65cb3a5c..a54c7a10 100644 --- a/src/js/game/systems/display.js +++ b/src/js/game/systems/display.js @@ -7,6 +7,15 @@ import { isTrueItem } from "../items/boolean_item"; import { ColorItem, COLOR_ITEM_SINGLETONS } from "../items/color_item"; import { MapChunkView } from "../map_chunk_view"; +/** @type {{ + * [x: string]: (item: BaseItem) => BaseItem + * }} */ +export const MODS_ADDITIONAL_DISPLAY_ITEM_RESOLVER = {}; + +/** @type {{ + * [x: string]: (parameters: import("../../core/draw_parameters").DrawParameters, entity: import("../entity").Entity, item: BaseItem) => BaseItem + * }} */ +export const MODS_ADDITIONAL_DISPLAY_ITEM_DRAW = {}; export class DisplaySystem extends GameSystem { constructor(root) { super(root); @@ -32,6 +41,10 @@ export class DisplaySystem extends GameSystem { return null; } + if (MODS_ADDITIONAL_DISPLAY_ITEM_RESOLVER[value.getItemType()]) { + return MODS_ADDITIONAL_DISPLAY_ITEM_RESOLVER[value.getItemType()].apply(this, [value]); + } + switch (value.getItemType()) { case "boolean": { return isTrueItem(value) ? COLOR_ITEM_SINGLETONS[enumColors.white] : null; @@ -74,6 +87,14 @@ export class DisplaySystem extends GameSystem { continue; } + if (MODS_ADDITIONAL_DISPLAY_ITEM_DRAW[value.getItemType()]) { + return MODS_ADDITIONAL_DISPLAY_ITEM_DRAW[value.getItemType()].apply(this, [ + parameters, + entity, + value, + ]); + } + const origin = entity.components.StaticMapEntity.origin; if (value.getItemType() === "color") { this.displaySprites[/** @type {ColorItem} */ (value).color].drawCachedCentered( From dab4aa9cda19eaf069227ab3a104a87bb2b35a70 Mon Sep 17 00:00:00 2001 From: Emerald Block <69981203+EmeraldBlock@users.noreply.github.com> Date: Sun, 13 Feb 2022 14:07:02 -0600 Subject: [PATCH 13/21] fix fs-job sanitization (#1375) --- electron/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/electron/index.js b/electron/index.js index 41831bdd..264aa581 100644 --- a/electron/index.js +++ b/electron/index.js @@ -316,7 +316,7 @@ async function writeFileSafe(filename, contents) { } ipcMain.handle("fs-job", async (event, job) => { - const filenameSafe = job.filename.replace(/[^a-z\.\-_0-9]/i, "_"); + const filenameSafe = job.filename.replace(/[^a-z\.\-_0-9]/gi, "_"); const fname = path.join(storePath, filenameSafe); switch (job.type) { case "read": { From f534a88f80f7dbc09b13910f6aca65dac0fffa27 Mon Sep 17 00:00:00 2001 From: Bagel03 <70449196+Bagel03@users.noreply.github.com> Date: Sun, 13 Feb 2022 15:09:41 -0500 Subject: [PATCH 14/21] Fix that whole export debacle (#1370) * Re-add setting exports * Update webpack.production.config.js * Update mod.js * Slight change * Update mod.js * Update webpack.production.config.js * Update webpack.config.js --- gulp/mod.js | 40 +++++++++++++++++++++++++++++-- gulp/webpack.config.js | 4 ++++ gulp/webpack.production.config.js | 4 ++++ src/js/mods/modloader.js | 5 ++-- 4 files changed, 49 insertions(+), 4 deletions(-) diff --git a/gulp/mod.js b/gulp/mod.js index 87912bb3..ad6cd4ae 100644 --- a/gulp/mod.js +++ b/gulp/mod.js @@ -1,3 +1,39 @@ -module.exports = function (source, map) { - return source + `\nexport let $s=(n,v)=>eval(n+"=v")`; +const oneExport = exp => { + return `${exp}=v`; // No checks needed +}; + +const twoExports = (exp1, exp2) => { + return `n=="${exp1}"?${exp1}=v:${exp2}=v`; +}; + +const multiExports = exps => { + exps = exps.map(exp => `case "${exp}":${exp}=v;break;`); + + return `switch(n){${exps.toString().replaceAll(";,", ";")} }`; +}; + +const defineFnBody = source => { + const regex = /export (?:let|class) (?<name>\w+)/g; + let names = [...source.matchAll(regex)].map(n => n.groups.name); + switch (names.length) { + case 0: + return false; + case 1: + return oneExport(names[0]); + case 2: + return twoExports(names[0], names[1]); + default: + return multiExports(names); + } +}; +/** + * + * @param {string} source + * @param {*} map + * @returns + */ +module.exports = function (source, map) { + const body = defineFnBody(source); + if (!body) return source; + return source + `\nexport const __$S__=(n,v)=>{${body}}`; }; diff --git a/gulp/webpack.config.js b/gulp/webpack.config.js index 7db0bf0b..c696d2bd 100644 --- a/gulp/webpack.config.js +++ b/gulp/webpack.config.js @@ -93,6 +93,10 @@ module.exports = ({ watch = false, standalone = false, chineseVersion = false, w end: "typehints:end", }, }, + { + loader: path.resolve(__dirname, "mod.js"), + }, + ], ], }, { diff --git a/gulp/webpack.production.config.js b/gulp/webpack.production.config.js index fdd477b9..f56ae609 100644 --- a/gulp/webpack.production.config.js +++ b/gulp/webpack.production.config.js @@ -131,6 +131,7 @@ module.exports = ({ warnings: true, }, mangle: { + reserved: ["__$S__"], eval: true, keep_classnames: !minifyNames, keep_fnames: !minifyNames, @@ -210,6 +211,9 @@ module.exports = ({ test: /\.js$/, use: [ // "thread-loader", + { + loader: path.resolve(__dirname, "mod.js"), + }, { loader: "babel-loader?cacheDirectory", options: { diff --git a/src/js/mods/modloader.js b/src/js/mods/modloader.js index daf0766e..3d0985d5 100644 --- a/src/js/mods/modloader.js +++ b/src/js/mods/modloader.js @@ -112,7 +112,8 @@ export class ModLoader { // @ts-ignore const module = modules(key); for (const member in module) { - if (member === "default") { + if (member === "default" || member === "__$S__") { + // Setter continue; } if (exports[member]) { @@ -124,7 +125,7 @@ export class ModLoader { return module[member]; }, set(v) { - throw new Error("Overriding the shapez exports is currently not possible"); + module.__$S__(member, v); }, }); } From 93b9340ab70554c113e23071c14913067d3d53e2 Mon Sep 17 00:00:00 2001 From: Pimak <37274338+Pimak@users.noreply.github.com> Date: Sun, 13 Feb 2022 21:09:56 +0100 Subject: [PATCH 15/21] Update README.md (#1376) Small mistake --- mod_examples/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod_examples/README.md b/mod_examples/README.md index 6711df06..c0b101e4 100644 --- a/mod_examples/README.md +++ b/mod_examples/README.md @@ -38,7 +38,7 @@ To get into shapez.io modding, I highly recommend checking out all of the exampl | [mod_settings.js](mod_settings.js) | Shows a dialog counting how often the mod has been launched | Reading and storing mod settings | | [storing_data_in_savegame.js](storing_data_in_savegame.js) | Shows how to store custom (structured) data in the savegame | Storing custom data in savegame | | [modify_existing_building.js](modify_existing_building.js) | Makes the rotator building always unlocked and adds a new statistic to the building panel | Modifying a builtin building, replacing builtin methods | -| [modify_ui.js](modify_ui.js) | Shows how to add custom IU elements to builtin game states (the Main Menu in this case) | Extending builtin UI states, Adding CSS | +| [modify_ui.js](modify_ui.js) | Shows how to add custom UI elements to builtin game states (the Main Menu in this case) | Extending builtin UI states, Adding CSS | | [pasting.js](pasting.js) | Shows a dialog when pasting text in the game | Listening to paste events | | [sandbox.js](sandbox.js) | Makes blueprints free and always unlocked | Overriding builtin methods | From b7bc2ac1b7aae772753005ba4dc1cdb6d21f21fd Mon Sep 17 00:00:00 2001 From: jbelbaz <32191774+jbelbaz@users.noreply.github.com> Date: Sun, 13 Feb 2022 21:10:11 +0100 Subject: [PATCH 16/21] Update base-fr.yaml (#1328) Change of a few lines in English. I was unable to verify in-game integration ... I hope my work will fit. glad to help :D --- translations/base-fr.yaml | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/translations/base-fr.yaml b/translations/base-fr.yaml index a0ec9066..3fda381a 100644 --- a/translations/base-fr.yaml +++ b/translations/base-fr.yaml @@ -454,8 +454,9 @@ ingame: clearItems: Supprimer les objets share: Partager report: Signaler - clearBuildings: Effacer les batiments - resetPuzzle: Reset Puzzle + clearBuildings: Effacer les Constructions + resetPuzzle: Réinitialiser le Puzzle + puzzleEditorControls: title: Créateur de Puzzles instructions: @@ -475,6 +476,7 @@ ingame: - 6. Une fois publié <strong>tous les batiments seront supprimés</strong> sauf les générateurs et les récepteurs - C'est la partie ou le joueur est censé se débrouiller seul :) + puzzleCompletion: title: Puzzle Résolu ! titleLike: "Cliquez sur le cœur si vous avez aimé le Puzzle:" @@ -485,7 +487,7 @@ ingame: nextPuzzle: Puzzle suivant puzzleMetadata: author: Auteur - shortKey: Clée courte + shortKey: Raccourci clavier rating: Niveau de difficulté averageDuration: Durée moyenne completionRate: Taux de réussite @@ -1073,7 +1075,7 @@ settings: visible en dézoomant. shapeTooltipAlwaysOn: title: Info-bulle de forme - Toujours afficher - description: Si activé une info-bule s'affiche quand vous survolez un batiment + description: Si activé, une info-bule s'affiche quand vous survolez un batiment sinon il faut maintenir 'ALT'. tickrateHz: <amount> Hz newBadge: New! @@ -1152,10 +1154,10 @@ keybindings: placementDisableAutoOrientation: Désactiver l’orientation automatique placeMultiple: Rester en mode placement placeInverse: Inverser l’orientation des convoyeurs - rotateToUp: "Rotate: Point Up" - rotateToDown: "Rotate: Point Down" - rotateToRight: "Rotate: Point Right" - rotateToLeft: "Rotate: Point Left" + rotateToUp: "Rotation : pointer vers le haut" + rotateToDown: "Rotation : pointer vers le bas" + rotateToRight: "Rotation : pointer vers le droite" + rotateToLeft: "Rotation : pointer vers le gauche" constant_producer: Producteur Constant goal_acceptor: Récepteur block: Bloc @@ -1311,16 +1313,16 @@ puzzleMenu: un clic droit sur shapez.io dans votre bibliothèque, en sélectionnant Propriétés > DLC. search: - action: Chercher + action: Recherche placeholder: Entrez un puzzle ou un nom d'auteur - includeCompleted: Inclure les puzzles terminés + includeCompleted: Inclure terminé difficulties: - any: Toutes difficultés + any: Toute difficulté easy: Facile - medium: Moyen - hard: Difficile + medium: Medium + hard: Dificile durations: - any: Toutes durées + any: Toute durée short: Court (< 2 min) medium: Normal long: Long (> 10 min) From dee4f23b7ec696eaa69fe7298dfa5e3e4765af06 Mon Sep 17 00:00:00 2001 From: Sense101 <67970865+Sense101@users.noreply.github.com> Date: Sun, 13 Feb 2022 20:11:02 +0000 Subject: [PATCH 17/21] Fix method for adding variants to an existing building (#1378) --- src/js/mods/mod_interface.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/js/mods/mod_interface.js b/src/js/mods/mod_interface.js index 295014ca..8130dc5a 100644 --- a/src/js/mods/mod_interface.js +++ b/src/js/mods/mod_interface.js @@ -594,8 +594,8 @@ export class ModInterface { * @param {string=} payload.name * @param {string=} payload.description * @param {Vector=} payload.dimensions - * @param {(root: GameRoot) => [string, string][]} payload.additionalStatistics - * @param {(root: GameRoot) => boolean[]} payload.isUnlocked + * @param {(root: GameRoot) => [string, string][]=} payload.additionalStatistics + * @param {(root: GameRoot) => boolean[]=} payload.isUnlocked */ addVariantToExistingBuilding(metaClass, variant, payload) { if (!payload.rotationVariants) { @@ -671,9 +671,14 @@ export class ModInterface { })); } - // Register our variant finally + // Register our variant finally, with rotation variants payload.rotationVariants.forEach(rotationVariant => - shapez.registerBuildingVariant(internalId, metaClass, variant, rotationVariant) + shapez.registerBuildingVariant( + rotationVariant ? internalId + "-" + rotationVariant : internalId, + metaClass, + variant, + rotationVariant + ) ); } } From cb5c3f798a29c667acd2c4586a976937f534047a Mon Sep 17 00:00:00 2001 From: Pimak <37274338+Pimak@users.noreply.github.com> Date: Sun, 13 Feb 2022 21:11:16 +0100 Subject: [PATCH 18/21] Update base-fr.yaml for mods translation (#1377) --- translations/base-fr.yaml | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/translations/base-fr.yaml b/translations/base-fr.yaml index 3fda381a..e1371279 100644 --- a/translations/base-fr.yaml +++ b/translations/base-fr.yaml @@ -1355,18 +1355,17 @@ backendErrors: no-permission: Vous n'êtes pas autorisé à effectuer cette action. mods: title: Mods - author: Author + author: Auteur version: Version - modWebsite: Website - openFolder: Open Mods Folder - folderOnlyStandalone: Opening the mod folder is only possible when running the standalone. - browseMods: Browse Mods - modsInfo: To install and manage mods, copy them to the mods folder within the - game directory. You can also use the 'Open Mods Folder' button on the - top right. - noModSupport: You need the standalone version on Steam to install mods. + modWebsite: Page web + openFolder: Ouvrir le dossier des mods + folderOnlyStandalone: Ouvrir le dossier des mods est uniquement possible avec la version complète + browseMods: Chercher les Mods + modsInfo: Pour installer et gérer les mods, copier-les dans le dossier Mods dans le répertoire du jeu. + Vous pouvez aussi utiliser le bouton 'Ouvrir le dossier des Mods' en haut à droite + noModSupport: Vous avez besoin de la version complète sur Steam pour installer des mods. togglingComingSoon: - title: Coming Soon - description: Enabling or disabling mods is currently only possible by copying - the mod file from or to the mods/ folder. However, being able to - toggle them here is planned for a future update! + title: Bientôt disponible + description: Activer ou désactiver un mod est pour le moment possible qu'en + copiant le fichier du mod depuis ou vers le dossier des mods. Cependant, + activer ou désactiver un mod est prévu pour une mise à jour future ! From c4f26320a45450d6bc66a5fa746b1c881a4d94b2 Mon Sep 17 00:00:00 2001 From: dobidon <35607008+dobidon@users.noreply.github.com> Date: Sun, 13 Feb 2022 23:11:38 +0300 Subject: [PATCH 19/21] Translating new keys (#1380) --- translations/base-tr.yaml | 52 +++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/translations/base-tr.yaml b/translations/base-tr.yaml index 0a2a7a6d..472269a8 100644 --- a/translations/base-tr.yaml +++ b/translations/base-tr.yaml @@ -79,9 +79,9 @@ mainMenu: puzzleDlcWishlist: İstek listene ekle! puzzleDlcViewNow: Paketi (DLC) görüntüle mods: - title: Active Mods - warningPuzzleDLC: Playing the Puzzle DLC is not possible with mods. Please - disable all mods to play the DLC. + title: Aktif Modlar + warningPuzzleDLC: Modlarla Yapboz DLC'sini oynamak mümkün değil. Lütfen + Yapboz DLC'sini oynayabilmek için bütün modları devre dışı bırakınız. dialogs: buttons: ok: OK @@ -263,12 +263,12 @@ dialogs: desc: "'<title>' yapbozunu silmek istediğinize emin misiniz? Bu işlem geri alınamaz!" modsDifference: - title: Mod Warning - desc: The currently installed mods differ from the mods the savegame was created - with. This might cause the savegame to break or not load at all. Are - you sure you want to continue? - missingMods: Missing Mods - newMods: Newly installed Mods + title: Mod Uyarısı + desc: Halihazırda kullanılan modlar, kayıtlı oyunun yaratıldığı modlardan farklıdır. + Bu işlem kayıtlı oyunun bozulmasına veya hiç yüklenmemesine neden olabilir. Devam + etmek istediğinize emin misiniz? + missingMods: Eksik Modlar + newMods: Yeni yüklenen Modlar ingame: keybindingsOverlay: moveMap: Hareket Et @@ -1038,7 +1038,7 @@ settings: description: Şekil ipuçlarını 'ALT' tuşuna basarak göstermek yerine her zaman gösterir. tickrateHz: <amount> Hz - newBadge: New! + newBadge: Yeni! keybindings: title: Tuş Atamaları hint: "İpucu: CTRL, SHIFT ve ALT tuşlarından yararlanın! Farklı yerleştirme @@ -1052,7 +1052,7 @@ keybindings: massSelect: Çoklu Seçİm buildings: Yapı Kısayolları placementModifiers: Yerleştİrme Özellİklerİ - mods: Provided by Mods + mods: Modlar tarafından sağlandı mappings: confirm: Kabul back: Geri @@ -1307,19 +1307,19 @@ backendErrors: istiyorsanız support@shapez.io ile iletişime geçiniz! no-permission: Bu işlemi yapmak için izniniz yok. mods: - title: Mods - author: Author - version: Version - modWebsite: Website - openFolder: Open Mods Folder - folderOnlyStandalone: Opening the mod folder is only possible when running the standalone. - browseMods: Browse Mods - modsInfo: To install and manage mods, copy them to the mods folder within the - game directory. You can also use the 'Open Mods Folder' button on the - top right. - noModSupport: You need the standalone version on Steam to install mods. + title: Modlar + author: Sahibi + version: Sürüm + modWebsite: İnternet sitesi + openFolder: Mod Klasörünü Aç + folderOnlyStandalone: Mod klasörünü açmak sadece tam sürümü çalıştırıyorken mümkün. + browseMods: Modlara Gözat + modsInfo: Modları yüklemek ve yönetmek için, bunları oyun dizini içerisindeki Modlar + klasörüne kopyalayın. Ayrıca sağ üstteki 'Modlar Klasörünü Aç' düğmesini de + kullanabilirsiniz. + noModSupport: Mod yükleyebilmek için tam sürümü çalıştırmalısınız. togglingComingSoon: - title: Coming Soon - description: Enabling or disabling mods is currently only possible by copying - the mod file from or to the mods/ folder. However, being able to - toggle them here is planned for a future update! + title: Yakında Gelecek + description: Modları etkinleştirmek veya devre dışı bırakmak şu anda yalnızca + dosyaları Mod klasörüne kopyalayarak mümkündür. Ancak modları burada + değiştirmek gelecekteki bir güncelleme için planlanmıştır! From 3f3a2e0981135b9ec63d7d58c4fec14f01feed05 Mon Sep 17 00:00:00 2001 From: Daan Breur <git@daanbreur.systems> Date: Sun, 13 Feb 2022 21:11:52 +0100 Subject: [PATCH 20/21] NL Translations for Mods and puzzleDLC (#1381) * [NL] Mods and puzzleDLC * Update base-nl.yaml * Update base-nl.yaml --- translations/base-nl.yaml | 63 ++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 34 deletions(-) diff --git a/translations/base-nl.yaml b/translations/base-nl.yaml index 9154e6ca..24bdc9e2 100644 --- a/translations/base-nl.yaml +++ b/translations/base-nl.yaml @@ -81,9 +81,9 @@ mainMenu: puzzleDlcWishlist: Voeg nu toe aan je verlanglijst! puzzleDlcViewNow: Bekijk DLC mods: - title: Active Mods - warningPuzzleDLC: Playing the Puzzle DLC is not possible with mods. Please - disable all mods to play the DLC. + title: Actieve Mods + warningPuzzleDLC: Het spelen van de Puzzle DLC is niet mogelijk met mods. Schakel + alsjeblieft alle mods uit om de DLC te spelen. dialogs: buttons: ok: OK @@ -270,12 +270,12 @@ dialogs: desc: Weet je zeker dat je '<title>' wilt verwijderen? Dit kan niet ongedaan gemaakt worden! modsDifference: - title: Mod Warning + title: Mod Waarschuwing desc: The currently installed mods differ from the mods the savegame was created with. This might cause the savegame to break or not load at all. Are you sure you want to continue? - missingMods: Missing Mods - newMods: Newly installed Mods + missingMods: Missende Mods + newMods: Nieuw geïnstalleerde Mods ingame: keybindingsOverlay: moveMap: Beweeg rond de wereld @@ -1188,10 +1188,8 @@ tips: - Knippers knippen altijd verticaal, ongeacht hun oriëntatie. - De opslagbuffer geeft prioriteit aan de eerste uitvoer. - Investeer tijd om herhaalbare ontwerpen te maken - het is het waard! - - Invest time to build repeatable designs - it's worth it! - Je kunt <b>ALT</b> ingedrukt houden om de richting van de geplaatste lopende banden om te keren. - - You can hold <b>ALT</b> to invert the direction of placed belts. - Vormontginningen die verder van de HUB verwijderd zijn, zijn complexer. - Machines hebben een beperkte snelheid, verdeel ze voor maximale efficiëntie. @@ -1214,7 +1212,6 @@ tips: mannen. - Maak een aparte blueprint fabriek. Ze zijn belangrijk voor modules. - Bekijk de kleurenmixer eens wat beter, en je vragen worden beantwoord. - - Have a closer look at the color mixer, and your questions will be answered. - Use <b>CTRL</b> + Click to select an area. - Met het speldpictogram naast elke vorm in de upgradelijst zet deze vast op het scherm. @@ -1234,7 +1231,6 @@ tips: - Druk twee keer op F4 om de tegel van je muis en camera weer te geven. - Je kan aan de linkerkant op een vastgezette vorm klikken om deze los te maken. - - You can click a pinned shape on the left side to unpin it. puzzleMenu: play: Spelen edit: Bewerken @@ -1280,21 +1276,21 @@ puzzleMenu: easy: Makkelijk medium: Medium hard: Moeilijk - unknown: Unrated + unknown: Onbeoordeeld search: - action: Search - placeholder: Enter a puzzle or author name - includeCompleted: Include Completed + action: Zoeken + placeholder: Voer een puzzel- of auteursnaam in + includeCompleted: Inclusief Voltooide difficulties: - any: Any Difficulty - easy: Easy + any: Elke Moeilijkheidsgraad + easy: Makkelijk medium: Medium - hard: Hard + hard: Moeilijk durations: - any: Any Duration - short: Short (< 2 min) - medium: Normal - long: Long (> 10 min) + any: Elke Tijd + short: Kort (< 2 min) + medium: Normaal + long: Lang (> 10 min) backendErrors: ratelimit: Je voert je handelingen te vaak uit. Wacht alstublieft even. invalid-api-key: Kan niet communiceren met de servers, probeer alstublieft het @@ -1323,18 +1319,17 @@ backendErrors: no-permission: Je bent niet gemachtigd om deze actie uit te voeren. mods: title: Mods - author: Author - version: Version + author: Auteur + version: Versie modWebsite: Website - openFolder: Open Mods Folder - folderOnlyStandalone: Opening the mod folder is only possible when running the standalone. - browseMods: Browse Mods - modsInfo: To install and manage mods, copy them to the mods folder within the - game directory. You can also use the 'Open Mods Folder' button on the - top right. - noModSupport: You need the standalone version on Steam to install mods. + openFolder: Open Mods Map + folderOnlyStandalone: Het openen van de mod map is alleen mogelijk bij het gebruiken van de zelfstandige versie. + browseMods: Door mods bladeren + modsInfo: Om mods te installeren en te beheren, kopieert u ze naar de map mods in de + spel map. U kunt ook de knop 'Open Mods Map' gebruiken rechtsboven. + noModSupport: Je hebt de zelfstandige versie op Steam nodig om mods te installeren. togglingComingSoon: - title: Coming Soon - description: Enabling or disabling mods is currently only possible by copying - the mod file from or to the mods/ folder. However, being able to - toggle them here is planned for a future update! + title: Binnenkort Beschikbaar + description: Mods in- of uitschakelen is momenteel alleen mogelijk door + het mod-bestand van of naar de mods map te kopiëren. Echter, in staat zijn om + ze hier in- of uitteschakelen is gepland voor een toekomstige update! From 4f0af32a5e964905d89eab76be12387ec27bb308 Mon Sep 17 00:00:00 2001 From: Ved_s <53968411+Ved-s@users.noreply.github.com> Date: Mon, 14 Feb 2022 07:14:34 +1100 Subject: [PATCH 21/21] Update base-ru.yaml (#1312) * Update base-ru.yaml I think other's comments about the game should stay in English, as Russian translation cannot precisely describe this * Update base-ru.yaml --- translations/base-ru.yaml | 54 +++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/translations/base-ru.yaml b/translations/base-ru.yaml index f93423da..f3bb7c95 100644 --- a/translations/base-ru.yaml +++ b/translations/base-ru.yaml @@ -95,9 +95,9 @@ dialogs: viewUpdate: Посмотреть Обновление showUpgrades: Показать Улучшения showKeybindings: Показать Управление (Привязку клавиш) - retry: Retry - continue: Continue - playOffline: Play Offline + retry: Заново + continue: Подолжить + playOffline: Играть оффлайн importSavegameError: title: Ошибка импортирования text: Не удалось импортировать сохранение игры. @@ -245,7 +245,7 @@ dialogs: puzzleShare: title: Короткий ключ скопирован desc: Короткий ключ головоломки (<key>) был скопирован в буфер обмена! Он может - быть введен в меню головолом для доступа к головоломке. + быть введен в меню головоломок для доступа к головоломке. puzzleReport: title: Жалоба на головоломку options: @@ -292,7 +292,7 @@ ingame: clearSelection: Отменить pipette: Пипетка switchLayers: Переключить слои - clearBelts: Clear belts + clearBelts: Очистить конвейеры colors: red: Красный green: Зеленый @@ -451,8 +451,8 @@ ingame: clearItems: Очистить предметы share: Поделиться report: Пожаловаться - clearBuildings: Clear Buildings - resetPuzzle: Reset Puzzle + clearBuildings: Очистить постройки + resetPuzzle: Сброс головоломки puzzleEditorControls: title: Редактор головоломок instructions: @@ -479,7 +479,7 @@ ingame: titleRatingDesc: Ваша оценка поможет мне в будущем делать вам лучшие предложения continueBtn: Продолжить игру menuBtn: Меню - nextPuzzle: Next Puzzle + nextPuzzle: Следующая головоломка puzzleMetadata: author: Автор shortKey: Короткий ключ @@ -709,8 +709,8 @@ buildings: description: Доставьте фигуру в приемник, чтобы установить их в качестве цели. block: default: - name: Block - description: Allows you to block a tile. + name: Блок + description: Блокирует это место от установки чего-либо storyRewards: reward_cutter_and_trash: title: Разрезание Фигур @@ -1044,11 +1044,11 @@ settings: title: Размер ресурсов на карте description: Устанавливает размер фигур на карте (когда вид достаточно отдалён). shapeTooltipAlwaysOn: - title: Shape Tooltip - Show Always - description: Whether to always show the shape tooltip when hovering buildings, - instead of having to hold 'ALT'. - tickrateHz: <amount> Hz - newBadge: New! + + title: Показывать подсказку фигуры + description: Показывать ли подсказку фигуры всегда или только при удержании 'ALT'. + tickrateHz: <amount> Гц + newBadge: Новое! keybindings: title: Настройки управления hint: "Подсказка: Обязательно используйте CTRL, SHIFT и ALT! Они дают разные @@ -1131,7 +1131,7 @@ keybindings: goal_acceptor: Приёмник предметов block: Блок massSelectClear: Очистить конвейеры - showShapeTooltip: Show shape output tooltip + showShapeTooltip: Показывать подсказку фигуры на выходе about: title: Об игре body: >- @@ -1272,19 +1272,19 @@ puzzleMenu: dlcHint: Уже купили DLC? Проверьте, что оно активировано, нажав правый клик на shapez.io в своей библиотеке, и далее Свойства > Доп. Контент search: - action: Search - placeholder: Enter a puzzle or author name - includeCompleted: Include Completed + action: Поиск + placeholder: Введите название головоломки или имя автора + includeCompleted: Показывать завершённые difficulties: - any: Any Difficulty - easy: Easy - medium: Medium - hard: Hard + any: Любая сложность + easy: Легко + medium: Средне + hard: Сложно durations: - any: Any Duration - short: Short (< 2 min) - medium: Normal - long: Long (> 10 min) + any: Любая длительность + short: Короткие (< 2 мин.) + medium: Средние + long: Долгие (> 10 мин.) backendErrors: ratelimit: Вы слишком часто выполняете свои действия. Подождите немного. invalid-api-key: Не удалось связаться с сервером, попробуйте