1
0
mirror of https://github.com/tobspr/shapez.io.git synced 2025-12-17 04:01:51 +00:00

Updated to 1.4.4

This commit is contained in:
DJ1TJOO 2021-09-01 17:55:44 +02:00
commit aed74cd263
106 changed files with 4930 additions and 2547 deletions

View File

@ -39,7 +39,7 @@ You can use [Gitpod](https://www.gitpod.io/) (an Online Open Source VS Code-like
- install all of the dependencies. - install all of the dependencies.
- start `gulp` in `gulp/` directory. - start `gulp` in `gulp/` directory.
[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/from-referrer/) [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/tobspr/shapez.io)
## Helping translate ## Helping translate

View File

@ -0,0 +1 @@
To build, place the lib64 folder from the wegame sdk for electron 13 in `wegame_sdk` and run the `wegame.main.standalone` gulp task.

View File

@ -51,8 +51,9 @@ function createWindow() {
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true,
webSecurity: false, webSecurity: false,
contextIsolation: false,
}, },
// allowRunningInsecureContent: false, allowRunningInsecureContent: false,
}); });
if (isLocal) { if (isLocal) {

View File

@ -10,7 +10,7 @@
"start": "electron --disable-direct-composition --in-process-gpu ." "start": "electron --disable-direct-composition --in-process-gpu ."
}, },
"devDependencies": { "devDependencies": {
"electron": "3.1.13" "electron": "^13.1.6"
}, },
"dependencies": { "dependencies": {
"async-lock": "^1.2.8" "async-lock": "^1.2.8"

View File

@ -1,5 +1,5 @@
const railsdk = require("./wegame_sdk/railsdk.js"); const railsdk = require("./wegame_sdk/railsdk.js");
const { dialog } = require("electron"); const { dialog, app, remote, ipcMain } = require("electron");
function init(isDev) { function init(isDev) {
console.log("Step 1: wegame: init"); console.log("Step 1: wegame: init");
@ -39,7 +39,7 @@ function init(isDev) {
event.state === railsdk.RailSystemState.kSystemStatePlatformExit || event.state === railsdk.RailSystemState.kSystemStatePlatformExit ||
event.state === railsdk.RailSystemState.kSystemStateGameExitByAntiAddiction event.state === railsdk.RailSystemState.kSystemStateGameExitByAntiAddiction
) { ) {
remote.app.exit(); app.exit();
} }
} }
}); });
@ -47,6 +47,17 @@ function init(isDev) {
function listen() { function listen() {
console.log("wegame: listen"); console.log("wegame: listen");
ipcMain.handle("profanity-check", async (event, data) => {
if (data.length === 0) {
return "";
}
const result = railsdk.RailUtils.DirtyWordsFilter(data, true);
if (result.check_result.dirty_type !== 0 /** kRailDirtyWordsTypeNormalAllowWords */) {
return result.check_result.replace_string;
}
return data;
});
} }
module.exports = { init, listen }; module.exports = { init, listen };

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 297 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 993 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 809 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 531 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 502 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 575 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 776 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

@ -137,16 +137,20 @@
button.continue { button.continue {
background: #555; background: #555;
@include S(margin-right, 10px);
} }
button.menu { button.menu {
background: #555;
}
button.nextPuzzle {
background-color: $colorGreenBright; background-color: $colorGreenBright;
} }
> button { > button {
@include S(min-width, 100px); @include S(min-width, 100px);
@include S(padding, 10px, 20px); @include S(padding, 8px, 16px);
@include S(margin, 0, 6px);
@include IncreasedClickArea(0px); @include IncreasedClickArea(0px);
} }
} }

View File

@ -0,0 +1,41 @@
#ingame_HUD_PuzzleNextPuzzle {
position: absolute;
@include S(top, 17px);
@include S(right, 10px);
display: flex;
flex-direction: column;
align-items: flex-end;
backdrop-filter: blur(D(1px));
padding: D(3px);
> .button {
@include ButtonText;
@include IncreasedClickArea(0px);
pointer-events: all;
cursor: pointer;
position: relative;
color: #333438;
transition: all 0.12s ease-in-out;
text-transform: uppercase;
transition-property: opacity, transform;
@include PlainText;
@include S(padding-right, 25px);
opacity: 1;
@include DarkThemeInvert;
&:hover {
opacity: 0.9 !important;
}
&.pressed {
transform: scale(0.95) !important;
}
& {
/* @load-async */
background: uiResource("icons/state_next_button.png") right center / D(15px) no-repeat;
}
}
}

View File

@ -21,6 +21,7 @@
@import "adinplay"; @import "adinplay";
@import "changelog_skins"; @import "changelog_skins";
@import "states/wegame_splash";
@import "states/preload"; @import "states/preload";
@import "states/main_menu"; @import "states/main_menu";
@import "states/ingame"; @import "states/ingame";
@ -64,6 +65,7 @@
@import "ingame_hud/puzzle_play_settings"; @import "ingame_hud/puzzle_play_settings";
@import "ingame_hud/puzzle_play_metadata"; @import "ingame_hud/puzzle_play_metadata";
@import "ingame_hud/puzzle_complete_notification"; @import "ingame_hud/puzzle_complete_notification";
@import "ingame_hud/puzzle_next";
// prettier-ignore // prettier-ignore
$elements: $elements:
@ -82,6 +84,7 @@ ingame_HUD_PinnedShapes,
ingame_HUD_GameMenu, ingame_HUD_GameMenu,
ingame_HUD_KeybindingOverlay, ingame_HUD_KeybindingOverlay,
ingame_HUD_PuzzleBackToMenu, ingame_HUD_PuzzleBackToMenu,
ingame_HUD_PuzzleNextPuzzle,
ingame_HUD_PuzzleEditorReview, ingame_HUD_PuzzleEditorReview,
ingame_HUD_PuzzleEditorControls, ingame_HUD_PuzzleEditorControls,
ingame_HUD_PuzzleEditorTitle, ingame_HUD_PuzzleEditorTitle,
@ -133,6 +136,7 @@ body.uiHidden {
#ingame_HUD_GameMenu, #ingame_HUD_GameMenu,
#ingame_HUD_PinnedShapes, #ingame_HUD_PinnedShapes,
#ingame_HUD_PuzzleBackToMenu, #ingame_HUD_PuzzleBackToMenu,
#ingame_HUD_PuzzleNextPuzzle,
#ingame_HUD_PuzzleEditorReview, #ingame_HUD_PuzzleEditorReview,
#ingame_HUD_Notifications, #ingame_HUD_Notifications,
#ingame_HUD_TutorialHints, #ingame_HUD_TutorialHints,

View File

@ -550,6 +550,16 @@
} }
} }
#crosspromo {
position: absolute;
@include S(bottom, 50px);
@include S(right, 20px);
@include S(width, 190px);
@include S(height, 100px);
pointer-events: all;
border: 0;
}
.footer { .footer {
display: grid; display: grid;
flex-grow: 1; flex-grow: 1;
@ -561,10 +571,45 @@
box-sizing: border-box; box-sizing: border-box;
@include S(grid-gap, 4px); @include S(grid-gap, 4px);
&.china { &.noLinks {
grid-template-columns: auto 1fr; grid-template-columns: auto 1fr;
} }
&.wegameDisclaimer {
@include SuperSmallText;
display: grid;
justify-content: center;
grid-template-columns: 1fr auto 1fr;
text-align: center;
> .disclaimer {
grid-column: 2 / 3;
@include DarkThemeOverride {
color: #fff;
}
}
> .rating {
grid-column: 3 / 4;
justify-self: end;
align-self: end;
@include S(width, 32px);
@include S(height, 40px);
background: green;
cursor: pointer !important;
pointer-events: all;
@include S(border-radius, 4px);
overflow: hidden;
& {
/* @load-async */
background: #fff uiResource("wegame_isbn_rating.jpg") center center / contain no-repeat;
}
}
}
.author { .author {
flex-grow: 1; flex-grow: 1;
text-align: right; text-align: right;

View File

@ -15,8 +15,81 @@
} }
> .container { > .container {
.searchForm {
display: flex;
align-items: center;
justify-content: center;
color: #333;
background: $accentColorBright;
@include S(padding, 5px);
@include S(border-radius, $globalBorderRadius);
flex-wrap: wrap;
@include DarkThemeOverride {
background: $accentColorDark;
}
input.search {
color: #333;
margin: 0;
display: inline-block;
flex-grow: 1;
@include S(padding, 5px, 10px);
@include S(min-width, 50px);
&::placeholder {
color: #aaa;
}
}
select {
color: #333;
border: 0;
@include S(padding, 5px);
@include S(border-radius, $globalBorderRadius);
@include S(padding, 7px, 10px);
@include S(margin-left, 5px);
@include PlainText;
}
.filterCompleted {
@include S(margin-left, 20px);
pointer-events: all;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
text-transform: uppercase;
@include PlainText;
@include S(margin-right, 10px);
@include DarkThemeOverride {
color: #bbbbc4;
}
input {
@include S(width, 15px);
@include S(height, 15px);
@include S(margin-right, 5px);
@include S(border-radius, $globalBorderRadius);
border: 0;
}
}
button[type="submit"] {
@include S(padding, 7px, 10px, 5px);
@include S(margin-left, 20px);
@include S(margin-top, 4px);
@include S(margin-bottom, 4px);
margin-left: auto;
}
}
> .mainContent { > .mainContent {
overflow: hidden; overflow: hidden;
display: flex;
flex-direction: column;
> .categoryChooser { > .categoryChooser {
> .categories { > .categories {
@ -79,8 +152,8 @@
@include S(grid-gap, 7px); @include S(grid-gap, 7px);
@include S(margin-top, 10px); @include S(margin-top, 10px);
@include S(padding-right, 4px); @include S(padding-right, 4px);
@include S(height, 320px);
overflow-y: scroll; overflow-y: scroll;
flex-grow: 1;
pointer-events: all; pointer-events: all;
position: relative; position: relative;
@ -246,6 +319,9 @@
&.stage--hard { &.stage--hard {
color: $colorRedBright; color: $colorRedBright;
} }
&.stage--unknown {
color: #888;
}
} }
} }

View File

@ -50,7 +50,8 @@
} }
button.categoryButton, button.categoryButton,
button.about { button.about,
button.privacy {
background-color: $colorCategoryButton; background-color: $colorCategoryButton;
color: #777a7f; color: #777a7f;
@ -68,6 +69,10 @@
} }
} }
button.privacy {
@include S(margin-top, 4px);
}
.versionbar { .versionbar {
@include S(margin-top, 10px); @include S(margin-top, 10px);
@ -180,7 +185,8 @@
.container .content { .container .content {
.sidebar { .sidebar {
button.categoryButton, button.categoryButton,
button.about { button.about,
button.privacy {
color: #ccc; color: #ccc;
background-color: darken($darkModeControlsBackground, 5); background-color: darken($darkModeControlsBackground, 5);

View File

@ -0,0 +1,38 @@
#state_WegameSplashState {
background: #000 !important;
display: flex;
align-items: center;
justify-content: center;
.wrapper {
opacity: 0;
@include InlineAnimation(5.9s ease-in-out) {
0% {
opacity: 0;
}
20% {
opacity: 1;
}
90% {
opacity: 1;
}
100% {
opacity: 0;
}
}
text-align: center;
color: #fff;
@include Heading;
strong {
display: block;
@include SuperHeading;
@include S(margin-bottom, 20px);
}
div {
@include S(margin-bottom, 10px);
}
}
}

View File

@ -34,6 +34,7 @@ import { RestrictionManager } from "./core/restriction_manager";
import { PuzzleMenuState } from "./states/puzzle_menu"; import { PuzzleMenuState } from "./states/puzzle_menu";
import { ClientAPI } from "./platform/api"; import { ClientAPI } from "./platform/api";
import { LoginState } from "./states/login"; import { LoginState } from "./states/login";
import { WegameSplashState } from "./states/wegame_splash";
/** /**
* @typedef {import("./platform/achievement_provider").AchievementProviderInterface} AchievementProviderInterface * @typedef {import("./platform/achievement_provider").AchievementProviderInterface} AchievementProviderInterface
@ -155,6 +156,7 @@ export class Application {
registerStates() { registerStates() {
/** @type {Array<typeof GameState>} */ /** @type {Array<typeof GameState>} */
const states = [ const states = [
WegameSplashState,
PreloadState, PreloadState,
MobileWarningState, MobileWarningState,
MainMenuState, MainMenuState,
@ -330,8 +332,12 @@ export class Application {
Loader.linkAppAfterBoot(this); Loader.linkAppAfterBoot(this);
if (G_WEGAME_VERSION) {
this.stateMgr.moveToState("WegameSplashState");
}
// Check for mobile // Check for mobile
if (IS_MOBILE) { else if (IS_MOBILE) {
this.stateMgr.moveToState("MobileWarningState"); this.stateMgr.moveToState("MobileWarningState");
} else { } else {
this.stateMgr.moveToState("PreloadState"); this.stateMgr.moveToState("PreloadState");

View File

@ -1,4 +1,27 @@
export const CHANGELOG = [ export const CHANGELOG = [
{
version: "1.4.4",
date: "29.08.2021",
entries: [
"Hotfix: Fixed the balancer not distributing items evenly, caused by the 1.4.3 update. Sorry for any inconveniences!",
],
},
{
version: "1.4.3",
date: "28.08.2021",
entries: [
"You can now hold 'ALT' while hovering a building to see its output! (Thanks to Sense101) (PS: There is now a setting to have it always on!)",
"The map overview should now be much more performant! As a consequence, you can now zoom out farther! (Thanks to PFedak)",
"Puzzle DLC: There is now a 'next puzzle' button!",
"Puzzle DLC: There is now a search function!",
"Edit signal dialog now has the previous signal filled (Thanks to EmeraldBlock)",
"Further performance improvements (Thanks to PFedak)",
"Improved puzzle validation (Thanks to Sense101)",
"Input fields in dialogs should now automatically focus",
"Fix selected building being deselected at level up (Thanks to EmeraldBlock)",
"Updated translations",
],
},
{ {
version: "1.4.2", version: "1.4.2",
date: "24.06.2021", date: "24.06.2021",

View File

@ -167,4 +167,25 @@ export class BufferMaintainer {
}); });
return canvas; return canvas;
} }
/**
* @param {object} param0
* @param {string} param0.key
* @param {string} param0.subKey
* @returns {HTMLCanvasElement?}
*
*/
getForKeyOrNullNoUpdate({ key, subKey }) {
let parent = this.cache.get(key);
if (!parent) {
return null;
}
// Now search for sub key
const cacheHit = parent.get(subKey);
if (cacheHit) {
return cacheHit.canvas;
}
return null;
}
} }

View File

@ -7,7 +7,7 @@ export const IS_DEBUG =
export const SUPPORT_TOUCH = false; export const SUPPORT_TOUCH = false;
export const IS_MAC = navigator.platform.toLowerCase().indexOf("mac") >= 0; export const IS_MAC = navigator.platform.toLowerCase().indexOf("mac") >= 0 && !G_IS_DEV;
const smoothCanvas = true; const smoothCanvas = true;
@ -17,6 +17,8 @@ export const THIRDPARTY_URLS = {
reddit: "https://www.reddit.com/r/shapezio", reddit: "https://www.reddit.com/r/shapezio",
shapeViewer: "https://viewer.shapez.io", shapeViewer: "https://viewer.shapez.io",
privacyPolicy: "https://tobspr.io/privacy.html",
standaloneStorePage: "https://store.steampowered.com/app/1318690/shapezio/", standaloneStorePage: "https://store.steampowered.com/app/1318690/shapezio/",
stanaloneCampaignLink: "https://get.shapez.io", stanaloneCampaignLink: "https://get.shapez.io",
puzzleDlcStorePage: "https://store.steampowered.com/app/1625400/shapezio__Puzzle_DLC", puzzleDlcStorePage: "https://store.steampowered.com/app/1625400/shapezio__Puzzle_DLC",
@ -55,6 +57,7 @@ export const globalConfig = {
// Map // Map
mapChunkSize: 16, mapChunkSize: 16,
chunkAggregateSize: 4,
mapChunkOverviewMinZoom: 0.9, mapChunkOverviewMinZoom: 0.9,
mapChunkWorldSize: null, // COMPUTED mapChunkWorldSize: null, // COMPUTED

View File

@ -53,7 +53,7 @@ export default {
// Replace all translations with emojis to see which texts are translateable // Replace all translations with emojis to see which texts are translateable
// testTranslations: true, // testTranslations: true,
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
// Enables an inspector which shows information about the entity below the curosr // Enables an inspector which shows information about the entity below the cursor
// enableEntityInspector: true, // enableEntityInspector: true,
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
// Enables ads in the local build (normally they are deactivated there) // Enables ads in the local build (normally they are deactivated there)

View File

@ -123,6 +123,4 @@ function catchErrors(message, source, lineno, colno, error) {
return true; return true;
} }
if (!G_IS_DEV) { window.onerror = catchErrors;
window.onerror = catchErrors;
}

View File

@ -91,26 +91,6 @@ export class GameState {
} }
} }
/**
*
* @param {string} nextStateId
* @param {object=} nextStatePayload
*/
watchAdAndMoveToState(nextStateId, nextStatePayload = {}) {
if (this.app.adProvider.getCanShowVideoAd() && this.app.isRenderable()) {
this.moveToState(
"WatchAdState",
{
nextStateId,
nextStatePayload,
},
true
);
} else {
this.moveToState(nextStateId, nextStatePayload);
}
}
/** /**
* Tracks clicks on a given element and calls the given callback *on this state*. * Tracks clicks on a given element and calls the given callback *on this state*.
* If you want to call another function wrap it inside a lambda. * If you want to call another function wrap it inside a lambda.

View File

@ -1,6 +1,7 @@
import { BaseItem } from "../game/base_item"; import { BaseItem } from "../game/base_item";
import { ClickDetector } from "./click_detector"; import { ClickDetector } from "./click_detector";
import { Signal } from "./signal"; import { Signal } from "./signal";
import { getIPCRenderer } from "./utils";
/* /*
* *************************************************** * ***************************************************
@ -107,6 +108,19 @@ export class FormElementInput extends FormElement {
updateErrorState() { updateErrorState() {
this.element.classList.toggle("errored", !this.isValid()); this.element.classList.toggle("errored", !this.isValid());
// profanity filter
if (G_WEGAME_VERSION) {
const value = String(this.element.value);
getIPCRenderer()
.invoke("profanity-check", value)
.then(newValue => {
if (value !== newValue && this.element) {
this.element.value = newValue;
}
});
}
} }
isValid() { isValid() {
@ -124,6 +138,7 @@ export class FormElementInput extends FormElement {
focus() { focus() {
this.element.focus(); this.element.focus();
this.element.select();
} }
} }

View File

@ -89,6 +89,11 @@ export class RestrictionManager extends ReadWriteProxy {
return false; return false;
} }
if (queryParamOptions.embedProvider === "gamedistribution") {
// also full version on gamedistribution
return false;
}
if (G_IS_DEV) { if (G_IS_DEV) {
return typeof window !== "undefined" && window.location.search.indexOf("demo") >= 0; return typeof window !== "undefined" && window.location.search.indexOf("demo") >= 0;
} }

View File

@ -734,6 +734,10 @@ const romanLiteralsCache = ["0"];
* @returns {string} * @returns {string}
*/ */
export function getRomanNumber(number) { export function getRomanNumber(number) {
if (G_WEGAME_VERSION) {
return String(number);
}
number = Math.max(0, Math.round(number)); number = Math.max(0, Math.round(number));
if (romanLiteralsCache[number]) { if (romanLiteralsCache[number]) {
return romanLiteralsCache[number]; return romanLiteralsCache[number];

View File

@ -11,6 +11,7 @@ import { typeItemSingleton } from "../item_resolver";
* pos: Vector, * pos: Vector,
* direction: enumDirection, * direction: enumDirection,
* item: BaseItem, * item: BaseItem,
* lastItem: BaseItem,
* progress: number?, * progress: number?,
* cachedDestSlot?: import("./item_acceptor").ItemAcceptorLocatedSlot, * cachedDestSlot?: import("./item_acceptor").ItemAcceptorLocatedSlot,
* cachedBeltPath?: BeltPath, * cachedBeltPath?: BeltPath,
@ -51,6 +52,7 @@ export class ItemEjectorComponent extends Component {
clear() { clear() {
for (const slot of this.slots) { for (const slot of this.slots) {
slot.item = null; slot.item = null;
slot.lastItem = null;
slot.progress = 0; slot.progress = 0;
} }
} }
@ -67,6 +69,7 @@ export class ItemEjectorComponent extends Component {
pos: slot.pos, pos: slot.pos,
direction: slot.direction, direction: slot.direction,
item: null, item: null,
lastItem: null,
progress: 0, progress: 0,
cachedDestSlot: null, cachedDestSlot: null,
cachedTargetEntity: null, cachedTargetEntity: null,
@ -131,6 +134,7 @@ export class ItemEjectorComponent extends Component {
return false; return false;
} }
this.slots[slotIndex].item = item; this.slots[slotIndex].item = item;
this.slots[slotIndex].lastItem = item;
this.slots[slotIndex].progress = 0; this.slots[slotIndex].progress = 0;
return true; return true;
} }

View File

@ -73,6 +73,12 @@ export class ItemProcessorComponent extends Component {
// Type of processing requirement // Type of processing requirement
this.processingRequirement = processingRequirement; this.processingRequirement = processingRequirement;
/**
* Our current inputs
* @type {Map<number, BaseItem>}
*/
this.inputSlots = new Map();
this.clear(); this.clear();
} }
@ -82,11 +88,13 @@ export class ItemProcessorComponent extends Component {
// sure the outputs always match // sure the outputs always match
this.nextOutputSlot = 0; this.nextOutputSlot = 0;
this.inputSlots.clear();
/** /**
* Our current inputs * Current input count
* @type {Array<{ item: BaseItem, sourceSlot: number }>} * @type {number}
*/ */
this.inputSlots = []; this.inputCount = 0;
/** /**
* What we are currently processing, empty if we don't produce anything rn * What we are currently processing, empty if we don't produce anything rn
@ -115,19 +123,17 @@ export class ItemProcessorComponent extends Component {
this.type === enumItemProcessorTypes.goal this.type === enumItemProcessorTypes.goal
) { ) {
// Hub has special logic .. not really nice but efficient. // Hub has special logic .. not really nice but efficient.
this.inputSlots.push({ item, sourceSlot }); this.inputSlots.set(this.inputCount, item);
this.inputCount++;
return true; return true;
} }
// Check that we only take one item per slot // Check that we only take one item per slot
for (let i = 0; i < this.inputSlots.length; ++i) { if (this.inputSlots.has(sourceSlot)) {
const slot = this.inputSlots[i]; return false;
if (slot.sourceSlot === sourceSlot) {
return false;
}
} }
this.inputSlots.set(sourceSlot, item);
this.inputSlots.push({ item, sourceSlot }); this.inputCount++;
return true; return true;
} }
} }

View File

@ -119,7 +119,7 @@ export class GameMode extends BasicSerializableObject {
/** @returns {number} */ /** @returns {number} */
getMinimumZoom() { getMinimumZoom() {
return 0.1; return 0.06;
} }
/** @returns {number} */ /** @returns {number} */

View File

@ -16,6 +16,7 @@ import { HUDEntityDebugger } from "./parts/entity_debugger";
import { HUDModalDialogs } from "./parts/modal_dialogs"; import { HUDModalDialogs } from "./parts/modal_dialogs";
import { enumNotificationType } from "./parts/notifications"; import { enumNotificationType } from "./parts/notifications";
import { HUDSettingsMenu } from "./parts/settings_menu"; import { HUDSettingsMenu } from "./parts/settings_menu";
import { HUDShapeTooltip } from "./parts/shape_tooltip";
import { HUDVignetteOverlay } from "./parts/vignette_overlay"; import { HUDVignetteOverlay } from "./parts/vignette_overlay";
import { TrailerMaker } from "./trailer_maker"; import { TrailerMaker } from "./trailer_maker";
@ -49,6 +50,8 @@ export class GameHUD {
blueprintPlacer: new HUDBlueprintPlacer(this.root), blueprintPlacer: new HUDBlueprintPlacer(this.root),
buildingPlacer: new HUDBuildingPlacer(this.root), buildingPlacer: new HUDBuildingPlacer(this.root),
shapeTooltip: new HUDShapeTooltip(this.root),
// Must always exist // Must always exist
settingsMenu: new HUDSettingsMenu(this.root), settingsMenu: new HUDSettingsMenu(this.root),
debugInfo: new HUDDebugInfo(this.root), debugInfo: new HUDDebugInfo(this.root),
@ -189,6 +192,7 @@ export class GameHUD {
"colorBlindHelper", "colorBlindHelper",
"changesDebugger", "changesDebugger",
"minerHighlight", "minerHighlight",
"shapeTooltip",
]; ];
for (let i = 0; i < partsOrder.length; ++i) { for (let i = 0; i < partsOrder.length; ++i) {

View File

@ -0,0 +1,25 @@
import { makeDiv } from "../../../core/utils";
import { T } from "../../../translations";
import { PuzzlePlayGameMode } from "../../modes/puzzle_play";
import { BaseHUDPart } from "../base_hud_part";
export class HUDPuzzleNextPuzzle extends BaseHUDPart {
createElements(parent) {
this.element = makeDiv(parent, "ingame_HUD_PuzzleNextPuzzle");
this.button = document.createElement("button");
this.button.classList.add("button");
this.button.innerText = T.ingame.puzzleCompletion.nextPuzzle;
this.element.appendChild(this.button);
this.trackClicks(this.button, this.nextPuzzle);
}
initialize() {}
nextPuzzle() {
const gameMode = /** @type {PuzzlePlayGameMode} */ (this.root.gameMode);
this.root.gameState.moveToState("PuzzleMenuState", {
continueQueue: gameMode.nextPuzzles,
});
}
}

View File

@ -128,7 +128,6 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart {
this.root.hud.signals.buildingsSelectedForCopy.add(this.abortPlacement, this); this.root.hud.signals.buildingsSelectedForCopy.add(this.abortPlacement, this);
this.root.hud.signals.pasteBlueprintRequested.add(this.abortPlacement, this); this.root.hud.signals.pasteBlueprintRequested.add(this.abortPlacement, this);
this.root.signals.storyGoalCompleted.add(() => this.signals.variantChanged.dispatch()); this.root.signals.storyGoalCompleted.add(() => this.signals.variantChanged.dispatch());
this.root.signals.storyGoalCompleted.add(() => this.currentMetaBuilding.set(null));
this.root.signals.upgradePurchased.add(() => this.signals.variantChanged.dispatch()); this.root.signals.upgradePurchased.add(() => this.signals.variantChanged.dispatch());
this.root.signals.editModeChanged.add(this.onEditModeChanged, this); this.root.signals.editModeChanged.add(this.onEditModeChanged, this);

View File

@ -158,8 +158,13 @@ export class HUDInteractiveTutorial extends BaseHUDPart {
onHintChanged(hintId) { onHintChanged(hintId) {
this.elementDescription.innerHTML = T.ingame.interactiveTutorial.hints[hintId]; this.elementDescription.innerHTML = T.ingame.interactiveTutorial.hints[hintId];
const folder = G_WEGAME_VERSION
? "interactive_tutorial.cn.noinline"
: "interactive_tutorial.noinline";
this.elementGif.style.backgroundImage = this.elementGif.style.backgroundImage =
"url('" + cachebust("res/ui/interactive_tutorial.noinline/" + hintId + ".gif") + "')"; "url('" + cachebust("res/ui/" + folder + "/" + hintId + ".gif") + "')";
this.element.classList.toggle("animEven"); this.element.classList.toggle("animEven");
this.element.classList.toggle("animOdd"); this.element.classList.toggle("animOdd");
} }

View File

@ -6,13 +6,8 @@ import { InputReceiver } from "../../../core/input_receiver";
import { makeDiv } from "../../../core/utils"; import { makeDiv } from "../../../core/utils";
import { SOUNDS } from "../../../platform/sound"; import { SOUNDS } from "../../../platform/sound";
import { T } from "../../../translations"; import { T } from "../../../translations";
import { enumColors } from "../../colors";
import { ColorItem } from "../../items/color_item";
import { finalGameShape, rocketShape } from "../../modes/regular";
import { BaseHUDPart } from "../base_hud_part"; import { BaseHUDPart } from "../base_hud_part";
import { DynamicDomAttach } from "../dynamic_dom_attach"; import { DynamicDomAttach } from "../dynamic_dom_attach";
import { ShapeItem } from "../../items/shape_item";
import { ShapeDefinition } from "../../shape_definition";
export class HUDPuzzleCompleteNotification extends BaseHUDPart { export class HUDPuzzleCompleteNotification extends BaseHUDPart {
initialize() { initialize() {
@ -68,10 +63,21 @@ export class HUDPuzzleCompleteNotification extends BaseHUDPart {
this.menuBtn.classList.add("menu", "styledButton"); this.menuBtn.classList.add("menu", "styledButton");
this.menuBtn.innerText = T.ingame.puzzleCompletion.menuBtn; this.menuBtn.innerText = T.ingame.puzzleCompletion.menuBtn;
buttonBar.appendChild(this.menuBtn); buttonBar.appendChild(this.menuBtn);
this.trackClicks(this.menuBtn, () => { this.trackClicks(this.menuBtn, () => {
this.close(true); this.close(true);
}); });
const gameMode = /** @type {PuzzlePlayGameMode} */ (this.root.gameMode);
if (gameMode.nextPuzzles.length > 0) {
this.nextPuzzleBtn = document.createElement("button");
this.nextPuzzleBtn.classList.add("nextPuzzle", "styledButton");
this.nextPuzzleBtn.innerText = T.ingame.puzzleCompletion.nextPuzzle;
buttonBar.appendChild(this.nextPuzzleBtn);
this.trackClicks(this.nextPuzzleBtn, () => {
this.nextPuzzle();
});
}
} }
updateState() { updateState() {
@ -93,6 +99,15 @@ export class HUDPuzzleCompleteNotification extends BaseHUDPart {
return this.visible; return this.visible;
} }
nextPuzzle() {
const gameMode = /** @type {PuzzlePlayGameMode} */ (this.root.gameMode);
gameMode.trackCompleted(this.userDidLikePuzzle, Math.round(this.timeOfCompletion)).then(() => {
this.root.gameState.moveToState("PuzzleMenuState", {
continueQueue: gameMode.nextPuzzles,
});
});
}
close(toMenu) { close(toMenu) {
/** @type {PuzzlePlayGameMode} */ (this.root.gameMode) /** @type {PuzzlePlayGameMode} */ (this.root.gameMode)
.trackCompleted(this.userDidLikePuzzle, Math.round(this.timeOfCompletion)) .trackCompleted(this.userDidLikePuzzle, Math.round(this.timeOfCompletion))

View File

@ -81,7 +81,7 @@ export class HUDPuzzleEditorReview extends BaseHUDPart {
closeLoading(); closeLoading();
//if it took so little ticks that it must have autocompeted //if it took so little ticks that it must have autocompeted
if (simulatedTicks <= 300) { if (simulatedTicks <= 500) {
this.root.hud.parts.dialogs.showWarning( this.root.hud.parts.dialogs.showWarning(
T.puzzleMenu.validation.title, T.puzzleMenu.validation.title,
T.puzzleMenu.validation.autoComplete T.puzzleMenu.validation.autoComplete

View File

@ -149,8 +149,9 @@ export class HUDPuzzleEditorSettings extends BaseHUDPart {
assertAlways(false, "Failed to re-place building in trim"); assertAlways(false, "Failed to re-place building in trim");
} }
if (building.components.ConstantSignal) { for (const key in building.components) {
result.components.ConstantSignal.signal = building.components.ConstantSignal.signal; /** @type {import("../../../core/global_registries").Component} */ (building
.components[key]).copyAdditionalStateTo(result.components[key]);
} }
} }
}); });

View File

@ -0,0 +1,100 @@
import { DrawParameters } from "../../../core/draw_parameters";
import { enumDirectionToVector, Vector } from "../../../core/vector";
import { Entity } from "../../entity";
import { KEYMAPPINGS } from "../../key_action_mapper";
import { THEME } from "../../theme";
import { BaseHUDPart } from "../base_hud_part";
export class HUDShapeTooltip extends BaseHUDPart {
createElements(parent) {}
initialize() {
/** @type {Vector} */
this.currentTile = new Vector(0, 0);
/** @type {Entity} */
this.currentEntity = null;
this.isPlacingBuilding = false;
this.root.signals.entityQueuedForDestroy.add(() => {
this.currentEntity = null;
}, this);
this.root.hud.signals.selectedPlacementBuildingChanged.add(metaBuilding => {
this.isPlacingBuilding = metaBuilding;
}, this);
}
isActive() {
const hudParts = this.root.hud.parts;
const active =
this.root.app.settings.getSetting("shapeTooltipAlwaysOn") ||
this.root.keyMapper.getBinding(KEYMAPPINGS.ingame.showShapeTooltip).pressed;
// return false if any other placer is active
return (
active &&
!this.isPlacingBuilding &&
!hudParts.massSelector.currentSelectionStartWorld &&
hudParts.massSelector.selectedUids.size < 1 &&
!hudParts.blueprintPlacer.currentBlueprint.get()
);
}
/**
*
* @param {DrawParameters} parameters
*/
draw(parameters) {
if (this.isActive()) {
const mousePos = this.root.app.mousePosition;
if (mousePos) {
const tile = this.root.camera.screenToWorld(mousePos.copy()).toTileSpace();
if (!tile.equals(this.currentTile)) {
this.currentTile = tile;
const entity = this.root.map.getLayerContentXY(tile.x, tile.y, this.root.currentLayer);
if (entity && entity.components.ItemProcessor && entity.components.ItemEjector) {
this.currentEntity = entity;
} else {
this.currentEntity = null;
}
}
}
if (!this.currentEntity) {
return;
}
const ejectorComp = this.currentEntity.components.ItemEjector;
const staticComp = this.currentEntity.components.StaticMapEntity;
const bounds = staticComp.getTileSize();
const totalArea = bounds.x * bounds.y;
const maxSlots = totalArea < 2 ? 1 : 1e10;
let slotsDrawn = 0;
for (let i = 0; i < ejectorComp.slots.length; ++i) {
const slot = ejectorComp.slots[i];
if (!slot.lastItem) {
continue;
}
if (++slotsDrawn > maxSlots) {
continue;
}
/** @type {Vector} */
const drawPos = staticComp.localTileToWorld(slot.pos).toWorldSpaceCenterOfTile();
slot.lastItem.drawItemCenteredClipped(drawPos.x, drawPos.y, parameters, 25);
}
}
}
}

View File

@ -45,7 +45,7 @@ export class HUDWaypoints extends BaseHUDPart {
*/ */
createElements(parent) { createElements(parent) {
// Create the helper box on the lower right when zooming out // Create the helper box on the lower right when zooming out
if (this.root.app.settings.getAllSettings().offerHints) { if (this.root.app.settings.getAllSettings().offerHints && !G_WEGAME_VERSION) {
this.hintElement = makeDiv( this.hintElement = makeDiv(
parent, parent,
"ingame_HUD_Waypoints_Hint", "ingame_HUD_Waypoints_Hint",
@ -121,10 +121,12 @@ export class HUDWaypoints extends BaseHUDPart {
} }
// Catch mouse and key events // Catch mouse and key events
this.root.camera.downPreHandler.add(this.onMouseDown, this); if (!G_WEGAME_VERSION) {
this.root.keyMapper this.root.camera.downPreHandler.add(this.onMouseDown, this);
.getBinding(KEYMAPPINGS.navigation.createMarker) this.root.keyMapper
.add(() => this.requestSaveMarker({})); .getBinding(KEYMAPPINGS.navigation.createMarker)
.add(() => this.requestSaveMarker({}));
}
/** /**
* Stores at how much opacity the markers should be rendered on the map. * Stores at how much opacity the markers should be rendered on the map.

View File

@ -32,6 +32,8 @@ export const KEYMAPPINGS = {
toggleFPSInfo: { keyCode: 115 }, // F4 toggleFPSInfo: { keyCode: 115 }, // F4
switchLayers: { keyCode: key("E") }, switchLayers: { keyCode: key("E") },
showShapeTooltip: { keyCode: 18 }, // ALT
}, },
navigation: { navigation: {

View File

@ -80,6 +80,15 @@ export class GameLogic {
} }
// Perform additional placement checks // Perform additional placement checks
if (this.root.gameMode.getIsEditor()) {
const toolbar = this.root.hud.parts.buildingsToolbar;
const id = entity.components.StaticMapEntity.getMetaBuilding().getId();
if (toolbar.buildingHandles[id].puzzleLocked) {
return false;
}
}
if (this.root.signals.prePlacementCheck.dispatch(entity, offset) === STOP_PROPAGATION) { if (this.root.signals.prePlacementCheck.dispatch(entity, offset) === STOP_PROPAGATION) {
return false; return false;
} }

View File

@ -3,6 +3,7 @@ import { Vector } from "../core/vector";
import { BasicSerializableObject, types } from "../savegame/serialization"; import { BasicSerializableObject, types } from "../savegame/serialization";
import { BaseItem } from "./base_item"; import { BaseItem } from "./base_item";
import { Entity } from "./entity"; import { Entity } from "./entity";
import { MapChunkAggregate } from "./map_chunk_aggregate";
import { MapChunkView } from "./map_chunk_view"; import { MapChunkView } from "./map_chunk_view";
import { GameRoot } from "./root"; import { GameRoot } from "./root";
@ -31,6 +32,11 @@ export class BaseMap extends BasicSerializableObject {
* Mapping of 'X|Y' to chunk * Mapping of 'X|Y' to chunk
* @type {Map<string, MapChunkView>} */ * @type {Map<string, MapChunkView>} */
this.chunksById = new Map(); this.chunksById = new Map();
/**
* Mapping of 'X|Y' to chunk aggregate
* @type {Map<string, MapChunkAggregate>} */
this.aggregatesById = new Map();
} }
/** /**
@ -55,6 +61,39 @@ export class BaseMap extends BasicSerializableObject {
return null; return null;
} }
/**
* Returns the chunk aggregate containing a given chunk
* @param {number} chunkX
* @param {number} chunkY
*/
getAggregateForChunk(chunkX, chunkY, createIfNotExistent = false) {
const aggX = Math.floor(chunkX / globalConfig.chunkAggregateSize);
const aggY = Math.floor(chunkY / globalConfig.chunkAggregateSize);
return this.getAggregate(aggX, aggY, createIfNotExistent);
}
/**
* Returns the given chunk aggregate by index
* @param {number} aggX
* @param {number} aggY
*/
getAggregate(aggX, aggY, createIfNotExistent = false) {
const aggIdentifier = aggX + "|" + aggY;
let storedAggregate;
if ((storedAggregate = this.aggregatesById.get(aggIdentifier))) {
return storedAggregate;
}
if (createIfNotExistent) {
const instance = new MapChunkAggregate(this.root, aggX, aggY);
this.aggregatesById.set(aggIdentifier, instance);
return instance;
}
return null;
}
/** /**
* Gets or creates a new chunk if not existent for the given tile * Gets or creates a new chunk if not existent for the given tile
* @param {number} tileX * @param {number} tileX

View File

@ -0,0 +1,154 @@
import { globalConfig } from "../core/config";
import { DrawParameters } from "../core/draw_parameters";
import { drawSpriteClipped } from "../core/draw_utils";
import { safeModulo } from "../core/utils";
import { GameRoot } from "./root";
export const CHUNK_OVERLAY_RES = 3;
export class MapChunkAggregate {
/**
*
* @param {GameRoot} root
* @param {number} x
* @param {number} y
*/
constructor(root, x, y) {
this.root = root;
this.x = x;
this.y = y;
/**
* Whenever something changes, we increase this number - so we know we need to redraw
*/
this.renderIteration = 0;
this.dirty = false;
/** @type {Array<boolean>} */
this.dirtyList = new Array(globalConfig.chunkAggregateSize ** 2).fill(true);
this.markDirty(0, 0);
}
/**
* Marks this chunk as dirty, rerendering all caches
* @param {number} chunkX
* @param {number} chunkY
*/
markDirty(chunkX, chunkY) {
const relX = safeModulo(chunkX, globalConfig.chunkAggregateSize);
const relY = safeModulo(chunkY, globalConfig.chunkAggregateSize);
this.dirtyList[relY * globalConfig.chunkAggregateSize + relX] = true;
if (this.dirty) {
return;
}
this.dirty = true;
++this.renderIteration;
this.renderKey = this.x + "/" + this.y + "@" + this.renderIteration;
}
/**
*
* @param {HTMLCanvasElement} canvas
* @param {CanvasRenderingContext2D} context
* @param {number} w
* @param {number} h
* @param {number} dpi
*/
generateOverlayBuffer(canvas, context, w, h, dpi) {
const prevKey = this.x + "/" + this.y + "@" + (this.renderIteration - 1);
const prevBuffer = this.root.buffers.getForKeyOrNullNoUpdate({
key: "agg@" + this.root.currentLayer,
subKey: prevKey,
});
const overlaySize = globalConfig.mapChunkSize * CHUNK_OVERLAY_RES;
let onlyDirty = false;
if (prevBuffer) {
context.drawImage(prevBuffer, 0, 0);
onlyDirty = true;
}
for (let x = 0; x < globalConfig.chunkAggregateSize; x++) {
for (let y = 0; y < globalConfig.chunkAggregateSize; y++) {
if (onlyDirty && !this.dirtyList[globalConfig.chunkAggregateSize * y + x]) continue;
this.root.map
.getChunk(
this.x * globalConfig.chunkAggregateSize + x,
this.y * globalConfig.chunkAggregateSize + y,
true
)
.generateOverlayBuffer(
context,
overlaySize,
overlaySize,
x * overlaySize,
y * overlaySize
);
}
}
this.dirty = false;
this.dirtyList.fill(false);
}
/**
* Overlay
* @param {DrawParameters} parameters
*/
drawOverlay(parameters) {
const aggregateOverlaySize =
globalConfig.mapChunkSize * globalConfig.chunkAggregateSize * CHUNK_OVERLAY_RES;
const sprite = this.root.buffers.getForKey({
key: "agg@" + this.root.currentLayer,
subKey: this.renderKey,
w: aggregateOverlaySize,
h: aggregateOverlaySize,
dpi: 1,
redrawMethod: this.generateOverlayBuffer.bind(this),
});
const dims = globalConfig.mapChunkWorldSize * globalConfig.chunkAggregateSize;
const extrude = 0.05;
// Draw chunk "pixel" art
parameters.context.imageSmoothingEnabled = false;
drawSpriteClipped({
parameters,
sprite,
x: this.x * dims - extrude,
y: this.y * dims - extrude,
w: dims + 2 * extrude,
h: dims + 2 * extrude,
originalW: aggregateOverlaySize,
originalH: aggregateOverlaySize,
});
parameters.context.imageSmoothingEnabled = true;
const resourcesScale = this.root.app.settings.getAllSettings().mapResourcesScale;
// Draw patch items
if (
this.root.currentLayer === "regular" &&
resourcesScale > 0.05 &&
this.root.camera.zoomLevel > 0.1
) {
const diameter = (70 / Math.pow(parameters.zoomLevel, 0.35)) * (0.2 + 2 * resourcesScale);
for (let x = 0; x < globalConfig.chunkAggregateSize; x++) {
for (let y = 0; y < globalConfig.chunkAggregateSize; y++) {
this.root.map
.getChunk(
this.x * globalConfig.chunkAggregateSize + x,
this.y * globalConfig.chunkAggregateSize + y,
true
)
.drawOverlayPatches(
parameters,
this.x * dims + x * globalConfig.mapChunkWorldSize,
this.y * dims + y * globalConfig.mapChunkWorldSize,
diameter
);
}
}
}
}
}

View File

@ -33,6 +33,7 @@ export class MapChunkView extends MapChunk {
markDirty() { markDirty() {
++this.renderIteration; ++this.renderIteration;
this.renderKey = this.x + "/" + this.y + "@" + this.renderIteration; this.renderKey = this.x + "/" + this.y + "@" + this.renderIteration;
this.root.map.getAggregateForChunk(this.x, this.y, true).markDirty(this.x, this.y);
} }
/** /**
@ -82,73 +83,41 @@ export class MapChunkView extends MapChunk {
} }
/** /**
* Overlay
* @param {DrawParameters} parameters * @param {DrawParameters} parameters
* @param {number} xoffs
* @param {number} yoffs
* @param {number} diameter
*/ */
drawOverlay(parameters) { drawOverlayPatches(parameters, xoffs, yoffs, diameter) {
const overlaySize = globalConfig.mapChunkSize * CHUNK_OVERLAY_RES; for (let i = 0; i < this.patches.length; ++i) {
const sprite = this.root.buffers.getForKey({ const patch = this.patches[i];
key: "chunk@" + this.root.currentLayer, if (patch.item.getItemType() === "shape") {
subKey: this.renderKey, const destX = xoffs + patch.pos.x * globalConfig.tileSize;
w: overlaySize, const destY = yoffs + patch.pos.y * globalConfig.tileSize;
h: overlaySize, patch.item.drawItemCenteredClipped(destX, destY, parameters, diameter);
dpi: 1,
redrawMethod: this.generateOverlayBuffer.bind(this),
});
const dims = globalConfig.mapChunkWorldSize;
const extrude = 0.05;
// Draw chunk "pixel" art
parameters.context.imageSmoothingEnabled = false;
drawSpriteClipped({
parameters,
sprite,
x: this.x * dims - extrude,
y: this.y * dims - extrude,
w: dims + 2 * extrude,
h: dims + 2 * extrude,
originalW: overlaySize,
originalH: overlaySize,
});
parameters.context.imageSmoothingEnabled = true;
const resourcesScale = this.root.app.settings.getAllSettings().mapResourcesScale;
// Draw patch items
if (this.root.currentLayer === "regular" && resourcesScale > 0.05) {
const diameter = (70 / Math.pow(parameters.zoomLevel, 0.35)) * (0.2 + 2 * resourcesScale);
for (let i = 0; i < this.patches.length; ++i) {
const patch = this.patches[i];
if (patch.item.getItemType() === "shape") {
const destX = this.x * dims + patch.pos.x * globalConfig.tileSize;
const destY = this.y * dims + patch.pos.y * globalConfig.tileSize;
patch.item.drawItemCenteredClipped(destX, destY, parameters, diameter);
}
} }
} }
} }
/** /**
* *
* @param {HTMLCanvasElement} canvas
* @param {CanvasRenderingContext2D} context * @param {CanvasRenderingContext2D} context
* @param {number} w * @param {number} w
* @param {number} h * @param {number} h
* @param {number} dpi * @param {number=} xoffs
* @param {number=} yoffs
*/ */
generateOverlayBuffer(canvas, context, w, h, dpi) { generateOverlayBuffer(context, w, h, xoffs, yoffs) {
context.fillStyle = context.fillStyle =
this.containedEntities.length > 0 this.containedEntities.length > 0
? THEME.map.chunkOverview.filled ? THEME.map.chunkOverview.filled
: THEME.map.chunkOverview.empty; : THEME.map.chunkOverview.empty;
context.fillRect(0, 0, w, h); context.fillRect(xoffs, yoffs, w, h);
if (this.root.app.settings.getAllSettings().displayChunkBorders) { if (this.root.app.settings.getAllSettings().displayChunkBorders) {
context.fillStyle = THEME.map.chunkBorders; context.fillStyle = THEME.map.chunkBorders;
context.fillRect(0, 0, w, 1); context.fillRect(xoffs, yoffs, w, 1);
context.fillRect(0, 1, 1, h); context.fillRect(xoffs, yoffs + 1, 1, h);
} }
for (let x = 0; x < globalConfig.mapChunkSize; ++x) { for (let x = 0; x < globalConfig.mapChunkSize; ++x) {
@ -174,8 +143,8 @@ export class MapChunkView extends MapChunk {
if (lowerContent) { if (lowerContent) {
context.fillStyle = lowerContent.getBackgroundColorAsResource(); context.fillStyle = lowerContent.getBackgroundColorAsResource();
context.fillRect( context.fillRect(
x * CHUNK_OVERLAY_RES, xoffs + x * CHUNK_OVERLAY_RES,
y * CHUNK_OVERLAY_RES, yoffs + y * CHUNK_OVERLAY_RES,
CHUNK_OVERLAY_RES, CHUNK_OVERLAY_RES,
CHUNK_OVERLAY_RES CHUNK_OVERLAY_RES
); );
@ -190,8 +159,8 @@ export class MapChunkView extends MapChunk {
const isFilled = overlayMatrix[dx + dy * 3]; const isFilled = overlayMatrix[dx + dy * 3];
if (isFilled) { if (isFilled) {
context.fillRect( context.fillRect(
x * CHUNK_OVERLAY_RES + dx, xoffs + x * CHUNK_OVERLAY_RES + dx,
y * CHUNK_OVERLAY_RES + dy, yoffs + y * CHUNK_OVERLAY_RES + dy,
1, 1,
1 1
); );
@ -206,8 +175,8 @@ export class MapChunkView extends MapChunk {
data.rotationVariant data.rotationVariant
); );
context.fillRect( context.fillRect(
x * CHUNK_OVERLAY_RES, xoffs + x * CHUNK_OVERLAY_RES,
y * CHUNK_OVERLAY_RES, yoffs + y * CHUNK_OVERLAY_RES,
CHUNK_OVERLAY_RES, CHUNK_OVERLAY_RES,
CHUNK_OVERLAY_RES CHUNK_OVERLAY_RES
); );
@ -220,8 +189,8 @@ export class MapChunkView extends MapChunk {
if (lowerContent) { if (lowerContent) {
context.fillStyle = lowerContent.getBackgroundColorAsResource(); context.fillStyle = lowerContent.getBackgroundColorAsResource();
context.fillRect( context.fillRect(
x * CHUNK_OVERLAY_RES, xoffs + x * CHUNK_OVERLAY_RES,
y * CHUNK_OVERLAY_RES, yoffs + y * CHUNK_OVERLAY_RES,
CHUNK_OVERLAY_RES, CHUNK_OVERLAY_RES,
CHUNK_OVERLAY_RES CHUNK_OVERLAY_RES
); );
@ -233,7 +202,7 @@ export class MapChunkView extends MapChunk {
// Draw wires overlay // Draw wires overlay
context.fillStyle = THEME.map.wires.overlayColor; context.fillStyle = THEME.map.wires.overlayColor;
context.fillRect(0, 0, w, h); context.fillRect(xoffs, yoffs, w, h);
for (let x = 0; x < globalConfig.mapChunkSize; ++x) { for (let x = 0; x < globalConfig.mapChunkSize; ++x) {
const wiresArray = this.wireContents[x]; const wiresArray = this.wireContents[x];
@ -244,8 +213,8 @@ export class MapChunkView extends MapChunk {
} }
MapChunkView.drawSingleWiresOverviewTile({ MapChunkView.drawSingleWiresOverviewTile({
context, context,
x: x * CHUNK_OVERLAY_RES, x: xoffs + x * CHUNK_OVERLAY_RES,
y: y * CHUNK_OVERLAY_RES, y: yoffs + y * CHUNK_OVERLAY_RES,
entity: content, entity: content,
tileSizePixels: CHUNK_OVERLAY_RES, tileSizePixels: CHUNK_OVERLAY_RES,
}); });

View File

@ -5,6 +5,7 @@ import { freeCanvas, makeOffscreenBuffer } from "../core/buffer_utils";
import { Entity } from "./entity"; import { Entity } from "./entity";
import { THEME } from "./theme"; import { THEME } from "./theme";
import { MapChunkView } from "./map_chunk_view"; import { MapChunkView } from "./map_chunk_view";
import { MapChunkAggregate } from "./map_chunk_aggregate";
/** /**
* This is the view of the map, it extends the map which is the raw model and allows * This is the view of the map, it extends the map which is the raw model and allows
@ -164,6 +165,40 @@ export class MapView extends BaseMap {
} }
} }
/**
* Calls a given method on all given chunks
* @param {DrawParameters} parameters
* @param {function} method
*/
drawVisibleAggregates(parameters, method) {
const cullRange = parameters.visibleRect.allScaled(1 / globalConfig.tileSize);
const top = cullRange.top();
const right = cullRange.right();
const bottom = cullRange.bottom();
const left = cullRange.left();
const border = 0;
const minY = top - border;
const maxY = bottom + border;
const minX = left - border;
const maxX = right + border;
const aggregateTiles = globalConfig.chunkAggregateSize * globalConfig.mapChunkSize;
const aggStartX = Math.floor(minX / aggregateTiles);
const aggStartY = Math.floor(minY / aggregateTiles);
const aggEndX = Math.floor(maxX / aggregateTiles);
const aggEndY = Math.floor(maxY / aggregateTiles);
// Render y from top down for proper blending
for (let aggX = aggStartX; aggX <= aggEndX; ++aggX) {
for (let aggY = aggStartY; aggY <= aggEndY; ++aggY) {
const aggregate = this.root.map.getAggregate(aggX, aggY, true);
method.call(aggregate, parameters);
}
}
}
/** /**
* Draws the wires foreground * Draws the wires foreground
* @param {DrawParameters} parameters * @param {DrawParameters} parameters
@ -177,7 +212,7 @@ export class MapView extends BaseMap {
* @param {DrawParameters} parameters * @param {DrawParameters} parameters
*/ */
drawOverlay(parameters) { drawOverlay(parameters) {
this.drawVisibleChunks(parameters, MapChunkView.prototype.drawOverlay); this.drawVisibleAggregates(parameters, MapChunkAggregate.prototype.drawOverlay);
} }
/** /**

View File

@ -30,6 +30,7 @@ import { HUDPuzzlePlaySettings } from "../hud/parts/puzzle_play_settings";
import { MetaBlockBuilding } from "../buildings/block"; import { MetaBlockBuilding } from "../buildings/block";
import { MetaBuilding } from "../meta_building"; import { MetaBuilding } from "../meta_building";
import { gMetaBuildingRegistry } from "../../core/global_registries"; import { gMetaBuildingRegistry } from "../../core/global_registries";
import { HUDPuzzleNextPuzzle } from "../hud/parts/HUDPuzzleNextPuzzle";
const logger = createLogger("puzzle-play"); const logger = createLogger("puzzle-play");
const copy = require("clipboard-copy"); const copy = require("clipboard-copy");
@ -43,8 +44,9 @@ export class PuzzlePlayGameMode extends PuzzleGameMode {
* @param {GameRoot} root * @param {GameRoot} root
* @param {object} payload * @param {object} payload
* @param {import("../../savegame/savegame_typedefs").PuzzleFullData} payload.puzzle * @param {import("../../savegame/savegame_typedefs").PuzzleFullData} payload.puzzle
* @param {Array<number> | undefined} payload.nextPuzzles
*/ */
constructor(root, { puzzle }) { constructor(root, { puzzle, nextPuzzles }) {
super(root); super(root);
/** @type {Array<typeof MetaBuilding>} */ /** @type {Array<typeof MetaBuilding>} */
@ -95,6 +97,15 @@ export class PuzzlePlayGameMode extends PuzzleGameMode {
root.signals.postLoadHook.add(this.loadPuzzle, this); root.signals.postLoadHook.add(this.loadPuzzle, this);
this.puzzle = puzzle; this.puzzle = puzzle;
/**
* @type {Array<number>}
*/
this.nextPuzzles = nextPuzzles || [];
if (this.nextPuzzles.length > 0) {
this.additionalHudParts.puzzleNext = HUDPuzzleNextPuzzle;
}
} }
loadPuzzle() { loadPuzzle() {

View File

@ -344,61 +344,61 @@ export function generateLevelDefinitions(limitedVersion = false) {
reward: enumHubGoalRewards.reward_rotater_ccw, reward: enumHubGoalRewards.reward_rotater_ccw,
}, },
// 8
{
shapes: [{ key: "RbRb----", amount: 480 }], // painter t2
reward: enumHubGoalRewards.reward_mixer,
},
// 9
// Mixing (purple)
{
shapes: [{ key: "CpCpCpCp", amount: 600 }], // belts t3
reward: enumHubGoalRewards.reward_merger,
},
// 10
// STACKER: Star shapes + cyan
{
shapes: [{ key: "ScScScSc", amount: 800 }], // miners t3
reward: enumHubGoalRewards.reward_stacker,
},
// 11
// Chainable miner
{
shapes: [{ key: "CgScScCg", amount: 1000 }], // processors t3
reward: enumHubGoalRewards.reward_miner_chainable,
},
// 12
// Blueprints
{
shapes: [{ key: "CbCbCbRb:CwCwCwCw", amount: 1000 }],
reward: enumHubGoalRewards.reward_blueprints,
},
// 13
// Tunnel Tier 2
{
shapes: [{ key: chinaShapes ? "CuCuCuCu:CwCwCwCw:Sb--Sr--" : "RpRpRpRp:CwCwCwCw", amount: 3800 }], // painting t3
reward: enumHubGoalRewards.reward_underground_belt_tier_2,
},
// DEMO STOPS HERE // DEMO STOPS HERE
...(limitedVersion ...(limitedVersion
? [ ? [
{ {
shapes: [ shapes: [{ key: "CrCrCrCr", amount: 0 }],
{
key: chinaShapes ? "CuCuCuCu:CwCwCwCw:Sb--Sr--" : "RpRpRpRp:CwCwCwCw",
amount: 0,
},
],
reward: enumHubGoalRewards.reward_demo_end, reward: enumHubGoalRewards.reward_demo_end,
}, },
] ]
: [ : [
// 8
{
shapes: [{ key: "RbRb----", amount: 480 }], // painter t2
reward: enumHubGoalRewards.reward_mixer,
},
// 9
// Mixing (purple)
{
shapes: [{ key: "CpCpCpCp", amount: 600 }], // belts t3
reward: enumHubGoalRewards.reward_merger,
},
// 10
// STACKER: Star shapes + cyan
{
shapes: [{ key: "ScScScSc", amount: 800 }], // miners t3
reward: enumHubGoalRewards.reward_stacker,
},
// 11
// Chainable miner
{
shapes: [{ key: "CgScScCg", amount: 1000 }], // processors t3
reward: enumHubGoalRewards.reward_miner_chainable,
},
// 12
// Blueprints
{
shapes: [{ key: "CbCbCbRb:CwCwCwCw", amount: 1000 }],
reward: enumHubGoalRewards.reward_blueprints,
},
// 13
// Tunnel Tier 2
{
shapes: [
{
key: chinaShapes ? "CuCuCuCu:CwCwCwCw:Sb--Sr--" : "RpRpRpRp:CwCwCwCw",
amount: 3800,
},
], // painting t3
reward: enumHubGoalRewards.reward_underground_belt_tier_2,
},
// 14 // 14
// Belt reader // Belt reader
{ {
@ -585,7 +585,9 @@ export class RegularGameMode extends GameMode {
} }
if (this.root.app.settings.getAllSettings().offerHints) { if (this.root.app.settings.getAllSettings().offerHints) {
this.additionalHudParts.tutorialHints = HUDPartTutorialHints; if (!G_WEGAME_VERSION) {
this.additionalHudParts.tutorialHints = HUDPartTutorialHints;
}
this.additionalHudParts.interactiveTutorial = HUDInteractiveTutorial; this.additionalHudParts.interactiveTutorial = HUDInteractiveTutorial;
} }
@ -595,12 +597,12 @@ export class RegularGameMode extends GameMode {
} }
/** @type {(typeof MetaBuilding)[]} */ /** @type {(typeof MetaBuilding)[]} */
this.hiddenBuildings = [ this.hiddenBuildings = [MetaConstantProducerBuilding, MetaGoalAcceptorBuilding, MetaBlockBuilding];
MetaConstantProducerBuilding,
MetaGoalAcceptorBuilding, // @ts-expect-error
MetaBlockBuilding, if (!(G_IS_DEV || window.sandboxMode || queryParamOptions.sandboxMode)) {
MetaItemProducerBuilding, this.hiddenBuildings.push(MetaItemProducerBuilding);
]; }
} }
/** /**

View File

@ -49,11 +49,12 @@ export class ConstantSignalSystem extends GameSystemWithFilter {
// Ok, query, but also save the uid because it could get stale // Ok, query, but also save the uid because it could get stale
const uid = entity.uid; const uid = entity.uid;
const signal = entity.components.ConstantSignal.signal;
const signalValueInput = new FormElementInput({ const signalValueInput = new FormElementInput({
id: "signalValue", id: "signalValue",
label: fillInLinkIntoTranslation(T.dialogs.editSignal.descShortKey, THIRDPARTY_URLS.shapeViewer), label: fillInLinkIntoTranslation(T.dialogs.editSignal.descShortKey, THIRDPARTY_URLS.shapeViewer),
placeholder: "", placeholder: "",
defaultValue: "", defaultValue: signal ? signal.getAsCopyableKey() : "",
validator: val => this.parseSignalCode(entity, val), validator: val => this.parseSignalCode(entity, val),
}); });

View File

@ -32,8 +32,8 @@ const MAX_QUEUED_CHARGES = 2;
* Type of a processor implementation * Type of a processor implementation
* @typedef {{ * @typedef {{
* entity: Entity, * entity: Entity,
* items: Array<{ item: BaseItem, sourceSlot: number }>, * items: Map<number, BaseItem>,
* itemsBySlot: Object<number, BaseItem>, * inputCount: number,
* outItems: Array<ProducedItem> * outItems: Array<ProducedItem>
* }} ProcessorImplementationPayload * }} ProcessorImplementationPayload
*/ */
@ -189,7 +189,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
// DEFAULT // DEFAULT
// By default, we can start processing once all inputs are there // By default, we can start processing once all inputs are there
case null: { case null: {
return processorComp.inputSlots.length >= processorComp.inputsPerCharge; return processorComp.inputCount >= processorComp.inputsPerCharge;
} }
// QUAD PAINTER // QUAD PAINTER
@ -197,18 +197,12 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
case enumItemProcessorRequirements.painterQuad: { case enumItemProcessorRequirements.painterQuad: {
const pinsComp = entity.components.WiredPins; const pinsComp = entity.components.WiredPins;
/** @type {Object.<number, { item: BaseItem, sourceSlot: number }>} */
const itemsBySlot = {};
for (let i = 0; i < processorComp.inputSlots.length; ++i) {
itemsBySlot[processorComp.inputSlots[i].sourceSlot] = processorComp.inputSlots[i];
}
// First slot is the shape, so if it's not there we can't do anything // First slot is the shape, so if it's not there we can't do anything
if (!itemsBySlot[0]) { const shapeItem = /** @type {ShapeItem} */ (processorComp.inputSlots.get(0));
if (!shapeItem) {
return false; return false;
} }
const shapeItem = /** @type {ShapeItem} */ (itemsBySlot[0].item);
const slotStatus = []; const slotStatus = [];
// Check which slots are enabled // Check which slots are enabled
@ -233,7 +227,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
// Check if all colors of the enabled slots are there // Check if all colors of the enabled slots are there
for (let i = 0; i < slotStatus.length; ++i) { for (let i = 0; i < slotStatus.length; ++i) {
if (slotStatus[i] && !itemsBySlot[1 + i]) { if (slotStatus[i] && !processorComp.inputSlots.get(1 + i)) {
// A slot which is enabled wasn't enabled. Make sure if there is anything on the quadrant, // A slot which is enabled wasn't enabled. Make sure if there is anything on the quadrant,
// it is not possible to paint, but if there is nothing we can ignore it // it is not possible to paint, but if there is nothing we can ignore it
for (let j = 0; j < 4; ++j) { for (let j = 0; j < 4; ++j) {
@ -262,13 +256,6 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
// First, take items // First, take items
const items = processorComp.inputSlots; const items = processorComp.inputSlots;
processorComp.inputSlots = [];
/** @type {Object<string, BaseItem>} */
const itemsBySlot = {};
for (let i = 0; i < items.length; ++i) {
itemsBySlot[items[i].sourceSlot] = items[i].item;
}
/** @type {Array<ProducedItem>} */ /** @type {Array<ProducedItem>} */
const outItems = []; const outItems = [];
@ -281,8 +268,8 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
handler({ handler({
entity, entity,
items, items,
itemsBySlot,
outItems, outItems,
inputCount: processorComp.inputCount,
}); });
// Track produced items // Track produced items
@ -304,6 +291,9 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
items: outItems, items: outItems,
remainingTime: timeToProcess, remainingTime: timeToProcess,
}); });
processorComp.inputSlots.clear();
processorComp.inputCount = 0;
} }
/** /**
@ -317,12 +307,14 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
const availableSlots = payload.entity.components.ItemEjector.slots.length; const availableSlots = payload.entity.components.ItemEjector.slots.length;
const processorComp = payload.entity.components.ItemProcessor; const processorComp = payload.entity.components.ItemProcessor;
const nextSlot = processorComp.nextOutputSlot++ % availableSlots; for (let i = 0; i < 2; ++i) {
const item = payload.items.get(i);
for (let i = 0; i < payload.items.length; ++i) { if (!item) {
continue;
}
payload.outItems.push({ payload.outItems.push({
item: payload.items[i].item, item,
preferredSlot: (nextSlot + i) % availableSlots, preferredSlot: processorComp.nextOutputSlot++ % availableSlots,
doNotTrack: true, doNotTrack: true,
}); });
} }
@ -333,20 +325,25 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
* @param {ProcessorImplementationPayload} payload * @param {ProcessorImplementationPayload} payload
*/ */
process_CUTTER(payload) { process_CUTTER(payload) {
const inputItem = /** @type {ShapeItem} */ (payload.items[0].item); const inputItem = /** @type {ShapeItem} */ (payload.items.get(0));
assert(inputItem instanceof ShapeItem, "Input for cut is not a shape"); assert(inputItem instanceof ShapeItem, "Input for cut is not a shape");
const inputDefinition = inputItem.definition; const inputDefinition = inputItem.definition;
const cutDefinitions = this.root.shapeDefinitionMgr.shapeActionCutHalf(inputDefinition); const cutDefinitions = this.root.shapeDefinitionMgr.shapeActionCutHalf(inputDefinition);
const ejectorComp = payload.entity.components.ItemEjector;
for (let i = 0; i < cutDefinitions.length; ++i) { for (let i = 0; i < cutDefinitions.length; ++i) {
const definition = cutDefinitions[i]; const definition = cutDefinitions[i];
if (!definition.isEntirelyEmpty()) {
payload.outItems.push({ if (definition.isEntirelyEmpty()) {
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(definition), ejectorComp.slots[i].lastItem = null;
requiredSlot: i, continue;
});
} }
payload.outItems.push({
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(definition),
requiredSlot: i,
});
} }
} }
@ -354,20 +351,25 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
* @param {ProcessorImplementationPayload} payload * @param {ProcessorImplementationPayload} payload
*/ */
process_CUTTER_QUAD(payload) { process_CUTTER_QUAD(payload) {
const inputItem = /** @type {ShapeItem} */ (payload.items[0].item); const inputItem = /** @type {ShapeItem} */ (payload.items.get(0));
assert(inputItem instanceof ShapeItem, "Input for cut is not a shape"); assert(inputItem instanceof ShapeItem, "Input for cut is not a shape");
const inputDefinition = inputItem.definition; const inputDefinition = inputItem.definition;
const cutDefinitions = this.root.shapeDefinitionMgr.shapeActionCutQuad(inputDefinition); const cutDefinitions = this.root.shapeDefinitionMgr.shapeActionCutQuad(inputDefinition);
const ejectorComp = payload.entity.components.ItemEjector;
for (let i = 0; i < cutDefinitions.length; ++i) { for (let i = 0; i < cutDefinitions.length; ++i) {
const definition = cutDefinitions[i]; const definition = cutDefinitions[i];
if (!definition.isEntirelyEmpty()) {
payload.outItems.push({ if (definition.isEntirelyEmpty()) {
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(definition), ejectorComp.slots[i].lastItem = null;
requiredSlot: i, continue;
});
} }
payload.outItems.push({
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(definition),
requiredSlot: i,
});
} }
} }
@ -375,7 +377,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
* @param {ProcessorImplementationPayload} payload * @param {ProcessorImplementationPayload} payload
*/ */
process_ROTATER(payload) { process_ROTATER(payload) {
const inputItem = /** @type {ShapeItem} */ (payload.items[0].item); const inputItem = /** @type {ShapeItem} */ (payload.items.get(0));
assert(inputItem instanceof ShapeItem, "Input for rotation is not a shape"); assert(inputItem instanceof ShapeItem, "Input for rotation is not a shape");
const inputDefinition = inputItem.definition; const inputDefinition = inputItem.definition;
@ -389,7 +391,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
* @param {ProcessorImplementationPayload} payload * @param {ProcessorImplementationPayload} payload
*/ */
process_ROTATER_CCW(payload) { process_ROTATER_CCW(payload) {
const inputItem = /** @type {ShapeItem} */ (payload.items[0].item); const inputItem = /** @type {ShapeItem} */ (payload.items.get(0));
assert(inputItem instanceof ShapeItem, "Input for rotation is not a shape"); assert(inputItem instanceof ShapeItem, "Input for rotation is not a shape");
const inputDefinition = inputItem.definition; const inputDefinition = inputItem.definition;
@ -403,7 +405,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
* @param {ProcessorImplementationPayload} payload * @param {ProcessorImplementationPayload} payload
*/ */
process_ROTATER_180(payload) { process_ROTATER_180(payload) {
const inputItem = /** @type {ShapeItem} */ (payload.items[0].item); const inputItem = /** @type {ShapeItem} */ (payload.items.get(0));
assert(inputItem instanceof ShapeItem, "Input for rotation is not a shape"); assert(inputItem instanceof ShapeItem, "Input for rotation is not a shape");
const inputDefinition = inputItem.definition; const inputDefinition = inputItem.definition;
@ -417,8 +419,8 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
* @param {ProcessorImplementationPayload} payload * @param {ProcessorImplementationPayload} payload
*/ */
process_STACKER(payload) { process_STACKER(payload) {
const lowerItem = /** @type {ShapeItem} */ (payload.itemsBySlot[0]); const lowerItem = /** @type {ShapeItem} */ (payload.items.get(0));
const upperItem = /** @type {ShapeItem} */ (payload.itemsBySlot[1]); const upperItem = /** @type {ShapeItem} */ (payload.items.get(1));
assert(lowerItem instanceof ShapeItem, "Input for lower stack is not a shape"); assert(lowerItem instanceof ShapeItem, "Input for lower stack is not a shape");
assert(upperItem instanceof ShapeItem, "Input for upper stack is not a shape"); assert(upperItem instanceof ShapeItem, "Input for upper stack is not a shape");
@ -444,8 +446,8 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
*/ */
process_MIXER(payload) { process_MIXER(payload) {
// Find both colors and combine them // Find both colors and combine them
const item1 = /** @type {ColorItem} */ (payload.items[0].item); const item1 = /** @type {ColorItem} */ (payload.items.get(0));
const item2 = /** @type {ColorItem} */ (payload.items[1].item); const item2 = /** @type {ColorItem} */ (payload.items.get(1));
assert(item1 instanceof ColorItem, "Input for color mixer is not a color"); assert(item1 instanceof ColorItem, "Input for color mixer is not a color");
assert(item2 instanceof ColorItem, "Input for color mixer is not a color"); assert(item2 instanceof ColorItem, "Input for color mixer is not a color");
@ -467,8 +469,8 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
* @param {ProcessorImplementationPayload} payload * @param {ProcessorImplementationPayload} payload
*/ */
process_PAINTER(payload) { process_PAINTER(payload) {
const shapeItem = /** @type {ShapeItem} */ (payload.itemsBySlot[0]); const shapeItem = /** @type {ShapeItem} */ (payload.items.get(0));
const colorItem = /** @type {ColorItem} */ (payload.itemsBySlot[1]); const colorItem = /** @type {ColorItem} */ (payload.items.get(1));
const colorizedDefinition = this.root.shapeDefinitionMgr.shapeActionPaintWith( const colorizedDefinition = this.root.shapeDefinitionMgr.shapeActionPaintWith(
shapeItem.definition, shapeItem.definition,
@ -484,9 +486,9 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
* @param {ProcessorImplementationPayload} payload * @param {ProcessorImplementationPayload} payload
*/ */
process_PAINTER_DOUBLE(payload) { process_PAINTER_DOUBLE(payload) {
const shapeItem1 = /** @type {ShapeItem} */ (payload.itemsBySlot[0]); const shapeItem1 = /** @type {ShapeItem} */ (payload.items.get(0));
const shapeItem2 = /** @type {ShapeItem} */ (payload.itemsBySlot[1]); const shapeItem2 = /** @type {ShapeItem} */ (payload.items.get(1));
const colorItem = /** @type {ColorItem} */ (payload.itemsBySlot[2]); const colorItem = /** @type {ColorItem} */ (payload.items.get(2));
assert(shapeItem1 instanceof ShapeItem, "Input for painter is not a shape"); assert(shapeItem1 instanceof ShapeItem, "Input for painter is not a shape");
assert(shapeItem2 instanceof ShapeItem, "Input for painter is not a shape"); assert(shapeItem2 instanceof ShapeItem, "Input for painter is not a shape");
@ -514,14 +516,15 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
* @param {ProcessorImplementationPayload} payload * @param {ProcessorImplementationPayload} payload
*/ */
process_PAINTER_QUAD(payload) { process_PAINTER_QUAD(payload) {
const shapeItem = /** @type {ShapeItem} */ (payload.itemsBySlot[0]); const shapeItem = /** @type {ShapeItem} */ (payload.items.get(0));
assert(shapeItem instanceof ShapeItem, "Input for painter is not a shape"); assert(shapeItem instanceof ShapeItem, "Input for painter is not a shape");
/** @type {Array<enumColors>} */ /** @type {Array<enumColors>} */
const colors = [null, null, null, null]; const colors = [null, null, null, null];
for (let i = 0; i < 4; ++i) { for (let i = 0; i < 4; ++i) {
if (payload.itemsBySlot[i + 1]) { const colorItem = /** @type {ColorItem} */ (payload.items.get(i + 1));
colors[i] = /** @type {ColorItem} */ (payload.itemsBySlot[i + 1]).color; if (colorItem) {
colors[i] = colorItem.color;
} }
} }
@ -540,7 +543,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
*/ */
process_READER(payload) { process_READER(payload) {
// Pass through the item // Pass through the item
const item = payload.itemsBySlot[0]; const item = payload.items.get(0);
payload.outItems.push({ payload.outItems.push({
item, item,
doNotTrack: true, doNotTrack: true,
@ -559,8 +562,12 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
const hubComponent = payload.entity.components.Hub; const hubComponent = payload.entity.components.Hub;
assert(hubComponent, "Hub item processor has no hub component"); assert(hubComponent, "Hub item processor has no hub component");
for (let i = 0; i < payload.items.length; ++i) { // Hardcoded
const item = /** @type {ShapeItem} */ (payload.items[i].item); for (let i = 0; i < payload.inputCount; ++i) {
const item = /** @type {ShapeItem} */ (payload.items.get(i));
if (!item) {
continue;
}
this.root.hubGoals.handleDefinitionDelivered(item.definition); this.root.hubGoals.handleDefinitionDelivered(item.definition);
} }
} }
@ -570,7 +577,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
*/ */
process_GOAL(payload) { process_GOAL(payload) {
const goalComp = payload.entity.components.GoalAcceptor; const goalComp = payload.entity.components.GoalAcceptor;
const item = payload.items[0].item; const item = payload.items.get(0);
const now = this.root.time.now(); const now = this.root.time.now();
if (goalComp.item && !item.equals(goalComp.item)) { if (goalComp.item && !item.equals(goalComp.item)) {
@ -584,7 +591,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
if (this.root.gameMode.getIsEditor()) { if (this.root.gameMode.getIsEditor()) {
// while playing in editor, assign the item // while playing in editor, assign the item
goalComp.item = payload.items[0].item; goalComp.item = item;
} }
goalComp.lastDelivery = { goalComp.lastDelivery = {

View File

@ -59,5 +59,10 @@
"outline": "#111418", "outline": "#111418",
"outlineWidth": 0.75, "outlineWidth": 0.75,
"circleBackground": "rgba(20, 30, 40, 0.3)" "circleBackground": "rgba(20, 30, 40, 0.3)"
},
"shapeTooltip": {
"background": "rgba(242, 245, 254, 0.9)",
"outline": "#44464e"
} }
} }

View File

@ -60,5 +60,10 @@
"outline": "#55575a", "outline": "#55575a",
"outlineWidth": 0.75, "outlineWidth": 0.75,
"circleBackground": "rgba(40, 50, 65, 0.1)" "circleBackground": "rgba(40, 50, 65, 0.1)"
},
"shapeTooltip": {
"background": "#dee1ea",
"outline": "#54565e"
} }
} }

View File

@ -12,7 +12,9 @@ export const LANGUAGES = {
"zh-CN": { "zh-CN": {
// simplified chinese // simplified chinese
name: "简体中文", name: "简体中文",
data: require("./built-temp/base-zh-CN.json"), data: G_WEGAME_VERSION
? require("./built-temp/base-zh-CN-ISBN.json")
: require("./built-temp/base-zh-CN.json"),
code: "zh", code: "zh",
region: "CN", region: "CN",
}, },

View File

@ -95,6 +95,10 @@ export class GamedistributionAdProvider extends AdProviderInterface {
document.body.classList.add("externalAdOpen"); document.body.classList.add("externalAdOpen");
logger.log("Set sound volume to 0");
this.app.sound.setMusicVolume(0);
this.app.sound.setSoundVolume(0);
return new Promise(resolve => { return new Promise(resolve => {
// So, wait for the remove call but also remove after N seconds // So, wait for the remove call but also remove after N seconds
this.videoAdResolveFunction = () => { this.videoAdResolveFunction = () => {
@ -119,6 +123,11 @@ export class GamedistributionAdProvider extends AdProviderInterface {
}) })
.then(() => { .then(() => {
document.body.classList.remove("externalAdOpen"); document.body.classList.remove("externalAdOpen");
logger.log("Restored sound volume");
this.app.sound.setMusicVolume(this.app.settings.getSetting("musicVolume"));
this.app.sound.setSoundVolume(this.app.settings.getSetting("soundVolume"));
}); });
} }
} }

View File

@ -143,6 +143,20 @@ export class ClientAPI {
return this._request("/v1/puzzles/list/" + category, {}); return this._request("/v1/puzzles/list/" + category, {});
} }
/**
* @param {{ searchTerm: string; difficulty: string; duration: string }} searchOptions
* @returns {Promise<import("../savegame/savegame_typedefs").PuzzleMetadata[]>}
*/
apiSearchPuzzles(searchOptions) {
if (!this.isLoggedIn()) {
return Promise.reject("not-logged-in");
}
return this._request("/v1/puzzles/search", {
method: "POST",
body: searchOptions,
});
}
/** /**
* @param {number} puzzleId * @param {number} puzzleId
* @returns {Promise<import("../savegame/savegame_typedefs").PuzzleFullData>} * @returns {Promise<import("../savegame/savegame_typedefs").PuzzleFullData>}
@ -169,7 +183,7 @@ export class ClientAPI {
} }
/** /**
* @param {number} shortKey * @param {string} shortKey
* @returns {Promise<import("../savegame/savegame_typedefs").PuzzleFullData>} * @returns {Promise<import("../savegame/savegame_typedefs").PuzzleFullData>}
*/ */
apiDownloadPuzzleByKey(shortKey) { apiDownloadPuzzleByKey(shortKey) {

View File

@ -111,6 +111,10 @@ export class ShapezGameAnalytics extends GameAnalyticsInterface {
* @returns {Promise<any>} * @returns {Promise<any>}
*/ */
sendToApi(endpoint, data) { sendToApi(endpoint, data) {
if (G_WEGAME_VERSION) {
return Promise.resolve();
}
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const timeout = setTimeout(() => reject("Request to " + endpoint + " timed out"), 20000); const timeout = setTimeout(() => reject("Request to " + endpoint + " timed out"), 20000);

View File

@ -135,15 +135,7 @@ export class PlatformWrapperImplBrowser extends PlatformWrapperInterface {
openExternalLink(url, force = false) { openExternalLink(url, force = false) {
logger.log("Opening external:", url); logger.log("Opening external:", url);
if (force || this.embedProvider.externalLinks) { window.open(url);
window.open(url);
} else {
// Do nothing
alert(
"This platform does not allow opening external links. You can play on https://shapez.io directly to open them.\n\nClicked Link: " +
url
);
}
} }
performRestart() { performRestart() {

View File

@ -257,6 +257,7 @@ export const allApplicationSettings = [
}), }),
new BoolSetting("enableMousePan", enumCategories.advanced, (app, value) => {}), new BoolSetting("enableMousePan", enumCategories.advanced, (app, value) => {}),
new BoolSetting("shapeTooltipAlwaysOn", enumCategories.advanced, (app, value) => {}),
new BoolSetting("alwaysMultiplace", enumCategories.advanced, (app, value) => {}), new BoolSetting("alwaysMultiplace", enumCategories.advanced, (app, value) => {}),
new BoolSetting("zoomToCursor", enumCategories.advanced, (app, value) => {}), new BoolSetting("zoomToCursor", enumCategories.advanced, (app, value) => {}),
new BoolSetting("clearCursorOnDeleteWhilePlacing", enumCategories.advanced, (app, value) => {}), new BoolSetting("clearCursorOnDeleteWhilePlacing", enumCategories.advanced, (app, value) => {}),
@ -272,7 +273,7 @@ export const allApplicationSettings = [
new EnumSetting("refreshRate", { new EnumSetting("refreshRate", {
options: refreshRateOptions, options: refreshRateOptions,
valueGetter: rate => rate, valueGetter: rate => rate,
textGetter: rate => rate + " Hz", textGetter: rate => T.settings.tickrateHz.replace("<amount>", rate),
category: enumCategories.performance, category: enumCategories.performance,
restartRequired: false, restartRequired: false,
changeCb: (app, id) => {}, changeCb: (app, id) => {},
@ -307,6 +308,7 @@ class SettingsStorage {
this.autosaveInterval = "two_minutes"; this.autosaveInterval = "two_minutes";
this.alwaysMultiplace = false; this.alwaysMultiplace = false;
this.shapeTooltipAlwaysOn = false;
this.offerHints = true; this.offerHints = true;
this.enableTunnelSmartplace = true; this.enableTunnelSmartplace = true;
this.vignette = true; this.vignette = true;
@ -536,7 +538,7 @@ export class ApplicationSettings extends ReadWriteProxy {
} }
getCurrentVersion() { getCurrentVersion() {
return 30; return 31;
} }
/** @param {{settings: SettingsStorage, version: number}} data */ /** @param {{settings: SettingsStorage, version: number}} data */
@ -683,6 +685,11 @@ export class ApplicationSettings extends ReadWriteProxy {
data.version = 30; data.version = 30;
} }
if (data.version < 31) {
data.settings.shapeTooltipAlwaysOn = false;
data.version = 31;
}
return ExplainedResult.good(); return ExplainedResult.good();
} }
} }

View File

@ -64,6 +64,24 @@ export class Savegame extends ReadWriteProxy {
return savegameInterfaces[Savegame.getCurrentVersion()]; return savegameInterfaces[Savegame.getCurrentVersion()];
} }
/**
*
* @param {Application} app
* @returns
*/
static createPuzzleSavegame(app) {
return new Savegame(app, {
internalId: "puzzle",
metaDataRef: {
internalId: "puzzle",
lastUpdate: 0,
version: 0,
level: 0,
name: "puzzle",
},
});
}
/** /**
* @returns {number} * @returns {number}
*/ */

View File

@ -17,6 +17,7 @@ import {
waitNextFrame, waitNextFrame,
} from "../core/utils"; } from "../core/utils";
import { HUDModalDialogs } from "../game/hud/parts/modal_dialogs"; import { HUDModalDialogs } from "../game/hud/parts/modal_dialogs";
import { PlatformWrapperImplBrowser } from "../platform/browser/wrapper";
import { PlatformWrapperImplElectron } from "../platform/electron/wrapper"; import { PlatformWrapperImplElectron } from "../platform/electron/wrapper";
import { getApplicationSettingById } from "../profile/application_settings"; import { getApplicationSettingById } from "../profile/application_settings";
import { T } from "../translations"; import { T } from "../translations";
@ -34,35 +35,57 @@ export class MainMenuState extends GameState {
} }
getInnerHTML() { getInnerHTML() {
const showLanguageIcon = !G_CHINA_VERSION && !G_WEGAME_VERSION;
const showExitAppButton = G_IS_STANDALONE;
const showUpdateLabel = !G_WEGAME_VERSION;
const showBrowserWarning = !G_IS_STANDALONE && !isSupportedBrowser();
const showPuzzleDLC = !G_WEGAME_VERSION && (G_IS_STANDALONE || G_IS_DEV);
const showWegameFooter = G_WEGAME_VERSION;
let showExternalLinks = true;
if (G_IS_STANDALONE) {
if (G_WEGAME_VERSION || G_CHINA_VERSION) {
showExternalLinks = false;
}
} else {
const wrapper = /** @type {PlatformWrapperImplBrowser} */ (this.app.platformWrapper);
if (!wrapper.embedProvider.externalLinks) {
showExternalLinks = false;
}
}
let showDiscordLink = showExternalLinks;
if (G_CHINA_VERSION) {
showDiscordLink = true;
}
const showCrosspromo = !G_IS_STANDALONE && showExternalLinks;
const showDemoAdvertisement =
showExternalLinks && this.app.restrictionMgr.getIsStandaloneMarketingActive();
const ownsPuzzleDLC =
G_IS_DEV ||
(G_IS_STANDALONE &&
/** @type { PlatformWrapperImplElectron}*/ (this.app.platformWrapper).dlcs.puzzle);
const bannerHtml = ` const bannerHtml = `
<h3>${T.demoBanners.title}</h3> <h3>${T.demoBanners.title}</h3>
<p>${T.demoBanners.intro}</p> <p>${T.demoBanners.intro}</p>
<a href="#" class="steamLink ${A_B_TESTING_LINK_TYPE}" target="_blank">Get the shapez.io standalone!</a>
<a href="#" class="steamLink ${A_B_TESTING_LINK_TYPE}" target="_blank">Get the shapez.io standalone!</a>
`; `;
const showDemoBadges = this.app.restrictionMgr.getIsStandaloneMarketingActive();
const puzzleDlc =
G_IS_STANDALONE &&
/** @type { PlatformWrapperImplElectron
}*/ (this.app.platformWrapper).dlcs.puzzle;
return ` return `
<div class="topButtons"> <div class="topButtons">
${ ${
G_CHINA_VERSION || G_WEGAME_VERSION showLanguageIcon
? "" ? `<button class="languageChoose" data-languageicon="${this.app.settings.getLanguage()}"></button>`
: `<button class="languageChoose" data-languageicon="${this.app.settings.getLanguage()}"></button>` : ""
} }
<button class="settingsButton"></button> <button class="settingsButton"></button>
${ ${showExitAppButton ? `<button class="exitAppButton"></button>` : ""}
G_IS_STANDALONE || G_IS_DEV
? `
<button class="exitAppButton"></button>
`
: ""
}
</div> </div>
<video autoplay muted loop class="fullscreenBackgroundVideo"> <video autoplay muted loop class="fullscreenBackgroundVideo">
@ -71,27 +94,25 @@ export class MainMenuState extends GameState {
<div class="logo"> <div class="logo">
<img src="${cachebust("res/" + getLogoSprite())}" alt="shapez.io Logo"> <img src="${cachebust("res/" + getLogoSprite())}" alt="shapez.io Logo">
${G_WEGAME_VERSION ? "" : `<span class="updateLabel">v${G_BUILD_VERSION}!</span>`} ${showUpdateLabel ? `<span class="updateLabel">v${G_BUILD_VERSION}!</span>` : ""}
</div> </div>
<div class="mainWrapper ${showDemoBadges ? "demo" : "noDemo"}" data-columns="${ <div class="mainWrapper" data-columns="${showDemoAdvertisement || showPuzzleDLC ? 2 : 1}">
G_IS_STANDALONE ? 2 : showDemoBadges ? 2 : 1
}">
<div class="sideContainer"> <div class="sideContainer">
${showDemoBadges ? `<div class="standaloneBanner">${bannerHtml}</div>` : ""} ${showDemoAdvertisement ? `<div class="standaloneBanner">${bannerHtml}</div>` : ""}
</div> </div>
<div class="mainContainer"> <div class="mainContainer">
${ ${
G_IS_STANDALONE || isSupportedBrowser() showBrowserWarning
? "" ? `<div class="browserWarning">${T.mainMenu.browserWarning}</div>`
: `<div class="browserWarning">${T.mainMenu.browserWarning}</div>` : ""
} }
<div class="buttons"></div> <div class="buttons"></div>
</div> </div>
${ ${
(!G_WEGAME_VERSION && G_IS_STANDALONE && puzzleDlc) || G_IS_DEV showPuzzleDLC && ownsPuzzleDLC
? ` ? `
<div class="puzzleContainer"> <div class="puzzleContainer">
<img class="dlcLogo" src="${cachebust( <img class="dlcLogo" src="${cachebust(
@ -105,7 +126,7 @@ export class MainMenuState extends GameState {
} }
${ ${
!G_WEGAME_VERSION && G_IS_STANDALONE && !puzzleDlc showPuzzleDLC && !ownsPuzzleDLC
? ` ? `
<div class="puzzleContainer notOwned"> <div class="puzzleContainer notOwned">
<span class="badge"> <span class="badge">
@ -129,40 +150,60 @@ export class MainMenuState extends GameState {
</div> </div>
${ ${
G_WEGAME_VERSION showWegameFooter
? "<div class='footer wegame'></div>" ? `
<div class='footer wegameDisclaimer'>
<div class="disclaimer">
健康游戏忠告
<br>
抵制不良游戏,拒绝盗版游戏注意自我保护,谨防受骗上当<br>
适度游戏益脑,沉迷游戏伤身合理安排时间,享受健康生活
</div>
<div class="rating"></div>
</div>
`
: ` : `
<div class="footer ${G_CHINA_VERSION ? "china" : ""} ">
${ <div class="footer ${showExternalLinks ? "" : "noLinks"} ">
G_CHINA_VERSION ${
? "" showExternalLinks
: ` ? `
<a class="githubLink boxLink" target="_blank"> <a class="githubLink boxLink" target="_blank">
${T.mainMenu.openSourceHint} ${T.mainMenu.openSourceHint}
<span class="thirdpartyLogo githubLogo"></span> <span class="thirdpartyLogo githubLogo"></span>
</a>` </a>`
} : ""
}
<a class="discordLink boxLink" target="_blank"> ${
${T.mainMenu.discordLink} showDiscordLink
<span class="thirdpartyLogo discordLogo"></span> ? `<a class="discordLink boxLink" target="_blank">
</a>
<div class="sidelinks"> ${T.mainMenu.discordLink}
${G_CHINA_VERSION ? "" : `<a class="redditLink">${T.mainMenu.subreddit}</a>`} <span class="thirdpartyLogo discordLogo"></span>
</a>`
: ""
}
${G_CHINA_VERSION ? "" : `<a class="changelog">${T.changelog.title}</a>`} <div class="sidelinks">
${showExternalLinks ? `<a class="redditLink">${T.mainMenu.subreddit}</a>` : ""}
${G_CHINA_VERSION ? "" : `<a class="helpTranslate">${T.mainMenu.helpTranslate}</a>`} ${showExternalLinks ? `<a class="changelog">${T.changelog.title}</a>` : ""}
${showExternalLinks ? `<a class="helpTranslate">${T.mainMenu.helpTranslate}</a>` : ""}
</div>
<div class="author">${T.mainMenu.madeBy.replace(
"<author-link>",
'<a class="producerLink" target="_blank">Tobias Springer</a>'
)}</div>
</div> </div>
${
<div class="author">${T.mainMenu.madeBy.replace( showCrosspromo
"<author-link>", ? `<iframe id="crosspromo" src="https://crosspromo.tobspr.io?src=shapez_web"></iframe>`
'<a class="producerLink" target="_blank">Tobias Springer</a>' : ""
)}</div> }
</div>
` `
} }
`; `;
@ -251,8 +292,6 @@ export class MainMenuState extends GameState {
); );
} }
const qs = this.htmlElement.querySelector.bind(this.htmlElement);
if (G_IS_DEV && globalConfig.debug.testPuzzleMode) { if (G_IS_DEV && globalConfig.debug.testPuzzleMode) {
this.onPuzzleModeButtonClicked(true); this.onPuzzleModeButtonClicked(true);
return; return;
@ -276,71 +315,38 @@ export class MainMenuState extends GameState {
} }
}); });
this.trackClicks(qs(".settingsButton"), this.onSettingsButtonClicked); const clickHandling = {
".settingsButton": this.onSettingsButtonClicked,
".languageChoose": this.onLanguageChooseClicked,
".redditLink": this.onRedditClicked,
".changelog": this.onChangelogClicked,
".helpTranslate": this.onTranslationHelpLinkClicked,
".exitAppButton": this.onExitAppButtonClicked,
".steamLink": this.onSteamLinkClicked,
".discordLink": () => {
this.app.analytics.trackUiClick("main_menu_link_discord");
this.app.platformWrapper.openExternalLink(THIRDPARTY_URLS.discord);
},
".githubLink": () => {
this.app.analytics.trackUiClick("main_menu_link_github");
this.app.platformWrapper.openExternalLink(THIRDPARTY_URLS.github);
},
".producerLink": () => this.app.platformWrapper.openExternalLink("https://tobspr.io"),
".puzzleDlcPlayButton": this.onPuzzleModeButtonClicked,
".puzzleDlcGetButton": this.onPuzzleWishlistButtonClicked,
".wegameDisclaimer > .rating": this.onWegameRatingClicked,
};
if (!G_CHINA_VERSION && !G_WEGAME_VERSION) { for (const key in clickHandling) {
this.trackClicks(qs(".languageChoose"), this.onLanguageChooseClicked); const handler = clickHandling[key];
this.trackClicks(qs(".redditLink"), this.onRedditClicked); const element = this.htmlElement.querySelector(key);
this.trackClicks(qs(".changelog"), this.onChangelogClicked); if (element) {
this.trackClicks(qs(".helpTranslate"), this.onTranslationHelpLinkClicked); this.trackClicks(element, handler, { preventClick: true });
} }
if (G_IS_STANDALONE) {
this.trackClicks(qs(".exitAppButton"), this.onExitAppButtonClicked);
} }
this.renderMainMenu(); this.renderMainMenu();
this.renderSavegames(); this.renderSavegames();
const steamLink = this.htmlElement.querySelector(".steamLink");
if (steamLink) {
this.trackClicks(steamLink, () => this.onSteamLinkClicked(), { preventClick: true });
}
const discordLink = this.htmlElement.querySelector(".discordLink");
if (discordLink) {
this.trackClicks(
discordLink,
() => {
this.app.analytics.trackUiClick("main_menu_link_discord");
this.app.platformWrapper.openExternalLink(THIRDPARTY_URLS.discord);
},
{ preventClick: true }
);
}
const githubLink = this.htmlElement.querySelector(".githubLink");
if (githubLink) {
this.trackClicks(
githubLink,
() => {
this.app.analytics.trackUiClick("main_menu_link_github");
this.app.platformWrapper.openExternalLink(THIRDPARTY_URLS.github);
},
{ preventClick: true }
);
}
const producerLink = this.htmlElement.querySelector(".producerLink");
if (producerLink) {
this.trackClicks(
producerLink,
() => this.app.platformWrapper.openExternalLink("https://tobspr.io"),
{
preventClick: true,
}
);
}
const puzzleModeButton = qs(".puzzleDlcPlayButton");
if (puzzleModeButton) {
this.trackClicks(puzzleModeButton, () => this.onPuzzleModeButtonClicked());
}
const puzzleWishlistButton = qs(".puzzleDlcGetButton");
if (puzzleWishlistButton) {
this.trackClicks(puzzleWishlistButton, () => this.onPuzzleWishlistButtonClicked());
}
} }
renderMainMenu() { renderMainMenu() {
@ -511,9 +517,12 @@ export class MainMenuState extends GameState {
downloadButton.classList.add("styledButton", "downloadGame"); downloadButton.classList.add("styledButton", "downloadGame");
elem.appendChild(downloadButton); elem.appendChild(downloadButton);
const renameButton = document.createElement("button"); if (!G_WEGAME_VERSION) {
renameButton.classList.add("styledButton", "renameGame"); const renameButton = document.createElement("button");
name.appendChild(renameButton); renameButton.classList.add("styledButton", "renameGame");
name.appendChild(renameButton);
this.trackClicks(renameButton, () => this.requestRenameSavegame(games[i]));
}
const resumeButton = document.createElement("button"); const resumeButton = document.createElement("button");
resumeButton.classList.add("styledButton", "resumeGame"); resumeButton.classList.add("styledButton", "resumeGame");
@ -522,7 +531,6 @@ export class MainMenuState extends GameState {
this.trackClicks(deleteButton, () => this.deleteGame(games[i])); this.trackClicks(deleteButton, () => this.deleteGame(games[i]));
this.trackClicks(downloadButton, () => this.downloadGame(games[i])); this.trackClicks(downloadButton, () => this.downloadGame(games[i]));
this.trackClicks(resumeButton, () => this.resumeGame(games[i])); this.trackClicks(resumeButton, () => this.resumeGame(games[i]));
this.trackClicks(renameButton, () => this.requestRenameSavegame(games[i]));
} }
} }
} }
@ -675,6 +683,18 @@ export class MainMenuState extends GameState {
}); });
} }
onWegameRatingClicked() {
this.dialogs.showInfo(
"提示说明",
`
1本游戏是一款休闲建造类单机游戏画面简洁而乐趣充足适用于年满8周岁及以上的用户建议未成年人在家长监护下使用游戏产品<br>
2本游戏模拟简单的生产流水线剧情简单且积极向上没有基于真实历史和现实事件的改编内容游戏玩法为摆放简单的部件完成生产目标游戏为单机作品没有基于文字和语音的陌生人社交系统<br>
3本游戏中有用户实名认证系统认证为未成年人的用户将接受以下管理未满8周岁的用户不能付费8周岁以上未满16周岁的未成年人用户单次充值金额不得超过50元人民币每月充值金额累计不得超过200元人民币16周岁以上的未成年人用户单次充值金额不得超过100元人民币每月充值金额累计不得超过400元人民币未成年人用户每日22点到次日8点不得使用法定节假日每天不得使用超过3小时其他时间每天不得使用超过1.5小时<br>
4游戏功能说明一款关于传送带自动化生产特定形状产品的工厂流水线模拟游戏画面简洁而乐趣充足可以让玩家在轻松愉快的氛围下获得各种游戏乐趣体验完成目标的成就感游戏没有失败功能自动存档不存在较强的挫折体验
`
);
}
onContinueButtonClicked() { onContinueButtonClicked() {
let latestLastUpdate = 0; let latestLastUpdate = 0;
let latestInternalId; let latestInternalId;
@ -686,11 +706,14 @@ export class MainMenuState extends GameState {
}); });
const savegame = this.app.savegameMgr.getSavegameById(latestInternalId); const savegame = this.app.savegameMgr.getSavegameById(latestInternalId);
savegame.readAsync().then(() => { savegame
this.moveToState("InGameState", { .readAsync()
savegame, .then(() => this.app.adProvider.showVideoAd())
.then(() => {
this.moveToState("InGameState", {
savegame,
});
}); });
});
} }
onLeave() { onLeave() {

View File

@ -81,9 +81,11 @@ export class PreloadState extends GameState {
} catch (ex) { } catch (ex) {
logger.error("Failed to read/write local storage:", ex); logger.error("Failed to read/write local storage:", ex);
return new Promise(() => { return new Promise(() => {
alert(`Your brower does not support thirdparty cookies or you have disabled it in your security settings.\n\n alert(
In Chrome this setting is called "Block third-party cookies and site data".\n\n "Your brower does not support thirdparty cookies or you have disabled it in your security settings.\n\n" +
Please allow third party cookies and then reload the page.`); "In Chrome this setting is called 'Block third-party cookies and site data'.\n\n" +
"Please allow third party cookies and then reload the page."
);
// Never return // Never return
}); });
} }

View File

@ -13,17 +13,30 @@ const navigation = {
categories: ["official", "top-rated", "trending", "trending-weekly", "new"], categories: ["official", "top-rated", "trending", "trending-weekly", "new"],
difficulties: ["easy", "medium", "hard"], difficulties: ["easy", "medium", "hard"],
account: ["mine", "completed"], account: ["mine", "completed"],
search: ["search"],
}; };
const logger = createLogger("puzzle-menu"); const logger = createLogger("puzzle-menu");
let lastCategory = "official"; let lastCategory = "official";
let lastSearchOptions = {
searchTerm: "",
difficulty: "any",
duration: "any",
includeCompleted: false,
};
export class PuzzleMenuState extends TextualGameState { export class PuzzleMenuState extends TextualGameState {
constructor() { constructor() {
super("PuzzleMenuState"); super("PuzzleMenuState");
this.loading = false; this.loading = false;
this.activeCategory = ""; this.activeCategory = "";
/**
* @type {Array<import("../savegame/savegame_typedefs").PuzzleMetadata>}
*/
this.puzzles = [];
} }
getThemeMusic() { getThemeMusic() {
@ -99,13 +112,23 @@ export class PuzzleMenuState extends TextualGameState {
activeCategory.classList.remove("active"); activeCategory.classList.remove("active");
} }
this.htmlElement.querySelector(`[data-category="${category}"]`).classList.add("active"); const categoryElement = this.htmlElement.querySelector(`[data-category="${category}"]`);
if (categoryElement) {
categoryElement.classList.add("active");
}
const container = this.htmlElement.querySelector("#mainContainer"); const container = this.htmlElement.querySelector("#mainContainer");
while (container.firstChild) { while (container.firstChild) {
container.removeChild(container.firstChild); container.removeChild(container.firstChild);
} }
if (category === "search") {
this.loading = false;
this.startSearch();
return;
}
const loadingElement = document.createElement("div"); const loadingElement = document.createElement("div");
loadingElement.classList.add("loader"); loadingElement.classList.add("loader");
loadingElement.innerText = T.global.loading + "..."; loadingElement.innerText = T.global.loading + "...";
@ -160,23 +183,148 @@ export class PuzzleMenuState extends TextualGameState {
} }
const children = navigation[rootCategory]; const children = navigation[rootCategory];
for (const category of children) { if (children.length > 1) {
const button = document.createElement("button"); for (const category of children) {
button.setAttribute("data-category", category); const button = document.createElement("button");
button.classList.add("styledButton", "category", "child"); button.setAttribute("data-category", category);
button.innerText = T.puzzleMenu.categories[category]; button.classList.add("styledButton", "category", "child");
this.trackClicks(button, () => this.selectCategory(category)); button.innerText = T.puzzleMenu.categories[category];
subContainer.appendChild(button); this.trackClicks(button, () => this.selectCategory(category));
subContainer.appendChild(button);
}
}
if (rootCategory === "search") {
this.renderSearchForm(subContainer);
} }
this.selectCategory(subCategory); this.selectCategory(subCategory);
} }
renderSearchForm(parent) {
const container = document.createElement("form");
container.classList.add("searchForm");
// Search
const searchField = document.createElement("input");
searchField.value = lastSearchOptions.searchTerm;
searchField.classList.add("search");
searchField.setAttribute("type", "text");
searchField.setAttribute("placeholder", T.puzzleMenu.search.placeholder);
searchField.addEventListener("input", () => {
lastSearchOptions.searchTerm = searchField.value.trim();
});
container.appendChild(searchField);
// Difficulty
const difficultyFilter = document.createElement("select");
for (const difficulty of ["any", "easy", "medium", "hard"]) {
const option = document.createElement("option");
option.value = difficulty;
option.innerText = T.puzzleMenu.search.difficulties[difficulty];
if (option.value === lastSearchOptions.difficulty) {
option.setAttribute("selected", "selected");
}
difficultyFilter.appendChild(option);
}
difficultyFilter.addEventListener("change", () => {
const option = difficultyFilter.value;
lastSearchOptions.difficulty = option;
});
container.appendChild(difficultyFilter);
// Duration
const durationFilter = document.createElement("select");
for (const duration of ["any", "short", "medium", "long"]) {
const option = document.createElement("option");
option.value = duration;
option.innerText = T.puzzleMenu.search.durations[duration];
if (option.value === lastSearchOptions.duration) {
option.setAttribute("selected", "selected");
}
durationFilter.appendChild(option);
}
durationFilter.addEventListener("change", () => {
const option = durationFilter.value;
lastSearchOptions.duration = option;
});
container.appendChild(durationFilter);
// Include completed
const labelCompleted = document.createElement("label");
labelCompleted.classList.add("filterCompleted");
const inputCompleted = document.createElement("input");
inputCompleted.setAttribute("type", "checkbox");
if (lastSearchOptions.includeCompleted) {
inputCompleted.setAttribute("checked", "checked");
}
inputCompleted.addEventListener("change", () => {
lastSearchOptions.includeCompleted = inputCompleted.checked;
});
labelCompleted.appendChild(inputCompleted);
const text = document.createTextNode(T.puzzleMenu.search.includeCompleted);
labelCompleted.appendChild(text);
container.appendChild(labelCompleted);
// Submit
const submitButton = document.createElement("button");
submitButton.classList.add("styledButton");
submitButton.setAttribute("type", "submit");
submitButton.innerText = T.puzzleMenu.search.action;
container.appendChild(submitButton);
container.addEventListener("submit", event => {
event.preventDefault();
console.log("Search:", searchField.value.trim());
this.startSearch();
});
parent.appendChild(container);
}
startSearch() {
if (this.loading) {
return;
}
this.loading = true;
const container = this.htmlElement.querySelector("#mainContainer");
while (container.firstChild) {
container.removeChild(container.firstChild);
}
const loadingElement = document.createElement("div");
loadingElement.classList.add("loader");
loadingElement.innerText = T.global.loading + "...";
container.appendChild(loadingElement);
this.asyncChannel
.watch(this.app.clientApi.apiSearchPuzzles(lastSearchOptions))
.then(
puzzles => this.renderPuzzles(puzzles),
error => {
this.dialogs.showWarning(
T.dialogs.puzzleLoadFailed.title,
T.dialogs.puzzleLoadFailed.desc + " " + error
);
this.renderPuzzles([]);
}
)
.then(() => (this.loading = false));
}
/** /**
* *
* @param {import("../savegame/savegame_typedefs").PuzzleMetadata[]} puzzles * @param {import("../savegame/savegame_typedefs").PuzzleMetadata[]} puzzles
*/ */
renderPuzzles(puzzles) { renderPuzzles(puzzles) {
this.puzzles = puzzles;
const container = this.htmlElement.querySelector("#mainContainer"); const container = this.htmlElement.querySelector("#mainContainer");
while (container.firstChild) { while (container.firstChild) {
container.removeChild(container.firstChild); container.removeChild(container.firstChild);
@ -209,10 +357,7 @@ export class PuzzleMenuState extends TextualGameState {
stats.classList.add("stats"); stats.classList.add("stats");
elem.appendChild(stats); elem.appendChild(stats);
if ( if (!["official", "easy", "medium", "hard"].includes(this.activeCategory)) {
puzzle.downloads > 3 &&
!["official", "easy", "medium", "hard"].includes(this.activeCategory)
) {
const difficulty = document.createElement("div"); const difficulty = document.createElement("div");
difficulty.classList.add("difficulty"); difficulty.classList.add("difficulty");
@ -223,15 +368,18 @@ export class PuzzleMenuState extends TextualGameState {
difficulty.innerText = completionPercentage + "%"; difficulty.innerText = completionPercentage + "%";
stats.appendChild(difficulty); stats.appendChild(difficulty);
if (completionPercentage < 40) { if (puzzle.difficulty === null) {
difficulty.classList.add("stage--hard"); difficulty.classList.add("stage--unknown");
difficulty.innerText = T.puzzleMenu.difficulties.hard; difficulty.innerText = T.puzzleMenu.difficulties.unknown;
} else if (completionPercentage < 80) { } else if (puzzle.difficulty < 0.2) {
difficulty.classList.add("stage--medium");
difficulty.innerText = T.puzzleMenu.difficulties.medium;
} else {
difficulty.classList.add("stage--easy"); difficulty.classList.add("stage--easy");
difficulty.innerText = T.puzzleMenu.difficulties.easy; difficulty.innerText = T.puzzleMenu.difficulties.easy;
} else if (puzzle.difficulty > 0.6) {
difficulty.classList.add("stage--hard");
difficulty.innerText = T.puzzleMenu.difficulties.hard;
} else {
difficulty.classList.add("stage--medium");
difficulty.innerText = T.puzzleMenu.difficulties.medium;
} }
} }
@ -275,7 +423,7 @@ export class PuzzleMenuState extends TextualGameState {
container.appendChild(elem); container.appendChild(elem);
this.trackClicks(elem, () => this.playPuzzle(puzzle)); this.trackClicks(elem, () => this.playPuzzle(puzzle.id));
} }
if (puzzles.length === 0) { if (puzzles.length === 0) {
@ -328,20 +476,26 @@ export class PuzzleMenuState extends TextualGameState {
/** /**
* *
* @param {import("../savegame/savegame_typedefs").PuzzleMetadata} puzzle * @param {number} puzzleId
* @param {Array<number>=} nextPuzzles
*/ */
playPuzzle(puzzle) { playPuzzle(puzzleId, nextPuzzles) {
const closeLoading = this.dialogs.showLoadingDialog(); const closeLoading = this.dialogs.showLoadingDialog();
this.app.clientApi.apiDownloadPuzzle(puzzle.id).then( this.asyncChannel.watch(this.app.clientApi.apiDownloadPuzzle(puzzleId)).then(
puzzleData => { puzzleData => {
closeLoading(); closeLoading();
logger.log("Got puzzle:", puzzleData);
this.startLoadedPuzzle(puzzleData); nextPuzzles =
nextPuzzles || this.puzzles.filter(puzzle => !puzzle.completed).map(puzzle => puzzle.id);
nextPuzzles = nextPuzzles.filter(id => id !== puzzleId);
logger.log("Got puzzle:", puzzleData, "next puzzles:", nextPuzzles);
this.startLoadedPuzzle(puzzleData, nextPuzzles);
}, },
err => { err => {
closeLoading(); closeLoading();
logger.error("Failed to download puzzle", puzzle.id, ":", err); logger.error("Failed to download puzzle", puzzleId, ":", err);
this.dialogs.showWarning( this.dialogs.showWarning(
T.dialogs.puzzleDownloadError.title, T.dialogs.puzzleDownloadError.title,
T.dialogs.puzzleDownloadError.desc + " " + err T.dialogs.puzzleDownloadError.desc + " " + err
@ -353,19 +507,26 @@ export class PuzzleMenuState extends TextualGameState {
/** /**
* *
* @param {import("../savegame/savegame_typedefs").PuzzleFullData} puzzle * @param {import("../savegame/savegame_typedefs").PuzzleFullData} puzzle
* @param {Array<number>=} nextPuzzles
*/ */
startLoadedPuzzle(puzzle) { startLoadedPuzzle(puzzle, nextPuzzles) {
const savegame = this.createEmptySavegame(); const savegame = Savegame.createPuzzleSavegame(this.app);
this.moveToState("InGameState", { this.moveToState("InGameState", {
gameModeId: enumGameModeIds.puzzlePlay, gameModeId: enumGameModeIds.puzzlePlay,
gameModeParameters: { gameModeParameters: {
puzzle, puzzle,
nextPuzzles,
}, },
savegame, savegame,
}); });
} }
onEnter(payload) { onEnter(payload) {
if (payload.continueQueue) {
logger.log("Continuing puzzle queue:", payload);
this.playPuzzle(payload.continueQueue[0], payload.continueQueue.slice(1));
}
// Find old category // Find old category
let rootCategory = "categories"; let rootCategory = "categories";
for (const [id, children] of Object.entries(navigation)) { for (const [id, children] of Object.entries(navigation)) {
@ -390,26 +551,13 @@ export class PuzzleMenuState extends TextualGameState {
this.trackClicks(this.htmlElement.querySelector("button.loadPuzzle"), () => this.loadPuzzle()); this.trackClicks(this.htmlElement.querySelector("button.loadPuzzle"), () => this.loadPuzzle());
} }
createEmptySavegame() {
return new Savegame(this.app, {
internalId: "puzzle",
metaDataRef: {
internalId: "puzzle",
lastUpdate: 0,
version: 0,
level: 0,
name: "puzzle",
},
});
}
loadPuzzle() { loadPuzzle() {
const shortKeyInput = new FormElementInput({ const shortKeyInput = new FormElementInput({
id: "shortKey", id: "shortKey",
label: null, label: null,
placeholder: "", placeholder: "",
defaultValue: "", defaultValue: "",
validator: val => ShapeDefinition.isValidShortKey(val), validator: val => ShapeDefinition.isValidShortKey(val) || val.startsWith("/"),
}); });
const dialog = new DialogWithForm({ const dialog = new DialogWithForm({
@ -422,9 +570,16 @@ export class PuzzleMenuState extends TextualGameState {
this.dialogs.internalShowDialog(dialog); this.dialogs.internalShowDialog(dialog);
dialog.buttonSignals.ok.add(() => { dialog.buttonSignals.ok.add(() => {
const searchTerm = shortKeyInput.getValue();
if (searchTerm === "/apikey") {
alert("Your api key is: " + this.app.clientApi.token);
return;
}
const closeLoading = this.dialogs.showLoadingDialog(); const closeLoading = this.dialogs.showLoadingDialog();
this.app.clientApi.apiDownloadPuzzleByKey(shortKeyInput.getValue()).then( this.app.clientApi.apiDownloadPuzzleByKey(searchTerm).then(
puzzle => { puzzle => {
closeLoading(); closeLoading();
this.startLoadedPuzzle(puzzle); this.startLoadedPuzzle(puzzle);
@ -451,7 +606,7 @@ export class PuzzleMenuState extends TextualGameState {
return; return;
} }
const savegame = this.createEmptySavegame(); const savegame = Savegame.createPuzzleSavegame(this.app);
this.moveToState("InGameState", { this.moveToState("InGameState", {
gameModeId: enumGameModeIds.puzzleEdit, gameModeId: enumGameModeIds.puzzleEdit,
savegame, savegame,

View File

@ -1,3 +1,4 @@
import { THIRDPARTY_URLS } from "../core/config";
import { TextualGameState } from "../core/textual_game_state"; import { TextualGameState } from "../core/textual_game_state";
import { formatSecondsToTimeAgo } from "../core/utils"; import { formatSecondsToTimeAgo } from "../core/utils";
import { allApplicationSettings, enumCategories } from "../profile/application_settings"; import { allApplicationSettings, enumCategories } from "../profile/application_settings";
@ -34,6 +35,8 @@ export class SettingsState extends TextualGameState {
? "" ? ""
: ` : `
<button class="styledButton about">${T.about.title}</button> <button class="styledButton about">${T.about.title}</button>
<button class="styledButton privacy">Privacy Policy</button>
` `
} }
<div class="versionbar"> <div class="versionbar">
@ -109,6 +112,9 @@ export class SettingsState extends TextualGameState {
this.trackClicks(this.htmlElement.querySelector(".about"), this.onAboutClicked, { this.trackClicks(this.htmlElement.querySelector(".about"), this.onAboutClicked, {
preventDefault: false, preventDefault: false,
}); });
this.trackClicks(this.htmlElement.querySelector(".privacy"), this.onPrivacyClicked, {
preventDefault: false,
});
} }
const keybindingsButton = this.htmlElement.querySelector(".editKeybindings"); const keybindingsButton = this.htmlElement.querySelector(".editKeybindings");
@ -180,6 +186,10 @@ export class SettingsState extends TextualGameState {
this.moveToStateAddGoBack("AboutState"); this.moveToStateAddGoBack("AboutState");
} }
onPrivacyClicked() {
this.app.platformWrapper.openExternalLink(THIRDPARTY_URLS.privacyPolicy);
}
onKeybindingsClicked() { onKeybindingsClicked() {
this.moveToStateAddGoBack("KeybindingsState"); this.moveToStateAddGoBack("KeybindingsState");
} }

View File

@ -0,0 +1,27 @@
import { GameState } from "../core/game_state";
export class WegameSplashState extends GameState {
constructor() {
super("WegameSplashState");
}
getInnerHTML() {
return `
<div class="wrapper">
<strong>健康游戏忠告</strong>
<div>抵制不良游戏,拒绝盗版游戏</div>
<div>注意自我保护,谨防受骗上当</div>
<div>适度游戏益脑,沉迷游戏伤身</div>
<div>合理安排时间,享受健康生活</div>
</div>
`;
}
onEnter() {
setTimeout(
() => {
this.app.stateMgr.moveToState("PreloadState");
},
G_IS_DEV ? 1 : 6000
);
}
}

View File

@ -456,6 +456,7 @@ ingame:
titleRatingDesc: Your rating will help me to make you better suggestions in the future titleRatingDesc: Your rating will help me to make you better suggestions in the future
continueBtn: Keep Playing continueBtn: Keep Playing
menuBtn: Menu menuBtn: Menu
nextPuzzle: Next Puzzle
puzzleMetadata: puzzleMetadata:
author: Author author: Author
shortKey: Short Key shortKey: Short Key
@ -1003,7 +1004,12 @@ settings:
title: Map Resources Size title: Map Resources Size
description: Controls the size of the shapes on the map overview (when zooming description: Controls the size of the shapes on the map overview (when zooming
out). out).
shapeTooltipAlwaysOn:
title: Shape Tooltip - Show Always
description: Whether to always show the shape tooltip when hovering buildings,
instead of having to hold 'ALT'.
rangeSliderPercentage: <amount> % rangeSliderPercentage: <amount> %
tickrateHz: <amount> Hz
keybindings: keybindings:
title: Keybindings title: Keybindings
hint: "Tip: Be sure to make use of CTRL, SHIFT and ALT! They enable different hint: "Tip: Be sure to make use of CTRL, SHIFT and ALT! They enable different
@ -1085,6 +1091,7 @@ keybindings:
goal_acceptor: Goal Acceptor goal_acceptor: Goal Acceptor
block: Block block: Block
massSelectClear: Clear belts massSelectClear: Clear belts
showShapeTooltip: Show shape output tooltip
about: about:
title: About this Game title: About this Game
body: >- body: >-
@ -1212,8 +1219,23 @@ puzzleMenu:
easy: Easy easy: Easy
medium: Medium medium: Medium
hard: Hard hard: Hard
unknown: Unrated
dlcHint: Purchased the DLC already? Make sure it is activated by right clicking dlcHint: Purchased the DLC already? Make sure it is activated by right clicking
shapez.io in your library, selecting Properties > DLCs. shapez.io in your library, selecting Properties > DLCs.
search:
action: Search
placeholder: Enter a puzzle or author name
includeCompleted: Include Completed
difficulties:
any: Any Difficulty
easy: Easy
medium: Medium
hard: Hard
durations:
any: Any Duration
short: Short (< 2 min)
medium: Normal
long: Long (> 10 min)
backendErrors: backendErrors:
ratelimit: You are performing your actions too frequent. Please wait a bit. ratelimit: You are performing your actions too frequent. Please wait a bit.
invalid-api-key: Failed to communicate with the backend, please try to invalid-api-key: Failed to communicate with the backend, please try to

View File

@ -466,6 +466,7 @@ ingame:
titleRatingDesc: Your rating will help me to make you better suggestions in the future titleRatingDesc: Your rating will help me to make you better suggestions in the future
continueBtn: Keep Playing continueBtn: Keep Playing
menuBtn: Menu menuBtn: Menu
nextPuzzle: Next Puzzle
puzzleMetadata: puzzleMetadata:
author: Author author: Author
shortKey: Short Key shortKey: Short Key
@ -1030,7 +1031,12 @@ settings:
title: Map Resources Size title: Map Resources Size
description: Controls the size of the shapes on the map overview (when zooming description: Controls the size of the shapes on the map overview (when zooming
out). out).
shapeTooltipAlwaysOn:
title: Shape Tooltip - Show Always
description: Whether to always show the shape tooltip when hovering buildings,
instead of having to hold 'ALT'.
rangeSliderPercentage: <amount> % rangeSliderPercentage: <amount> %
tickrateHz: <amount> Hz
keybindings: keybindings:
title: Combinacions de tecles title: Combinacions de tecles
hint: "Tip: Assegura't d'emprar CTRL, SHIFT i ALT! Et permeten col·locar hint: "Tip: Assegura't d'emprar CTRL, SHIFT i ALT! Et permeten col·locar
@ -1112,6 +1118,7 @@ keybindings:
goal_acceptor: Goal Acceptor goal_acceptor: Goal Acceptor
block: Block block: Block
massSelectClear: Clear belts massSelectClear: Clear belts
showShapeTooltip: Show shape output tooltip
about: about:
title: Sobre aquest Joc title: Sobre aquest Joc
body: >- body: >-
@ -1254,8 +1261,23 @@ puzzleMenu:
easy: Easy easy: Easy
medium: Medium medium: Medium
hard: Hard hard: Hard
unknown: Unrated
dlcHint: Purchased the DLC already? Make sure it is activated by right clicking dlcHint: Purchased the DLC already? Make sure it is activated by right clicking
shapez.io in your library, selecting Properties > DLCs. shapez.io in your library, selecting Properties > DLCs.
search:
action: Search
placeholder: Enter a puzzle or author name
includeCompleted: Include Completed
difficulties:
any: Any Difficulty
easy: Easy
medium: Medium
hard: Hard
durations:
any: Any Duration
short: Short (< 2 min)
medium: Normal
long: Long (> 10 min)
backendErrors: backendErrors:
ratelimit: You are performing your actions too frequent. Please wait a bit. ratelimit: You are performing your actions too frequent. Please wait a bit.
invalid-api-key: Failed to communicate with the backend, please try to invalid-api-key: Failed to communicate with the backend, please try to

View File

@ -457,6 +457,7 @@ ingame:
titleRatingDesc: Vaše hodnocení nám pomůže podat vám v budoucnu lepší návrhy titleRatingDesc: Vaše hodnocení nám pomůže podat vám v budoucnu lepší návrhy
continueBtn: Hrát dál continueBtn: Hrát dál
menuBtn: Menu menuBtn: Menu
nextPuzzle: Next Puzzle
puzzleMetadata: puzzleMetadata:
author: Autor author: Autor
shortKey: Krátký klíč shortKey: Krátký klíč
@ -994,7 +995,12 @@ settings:
mapResourcesScale: mapResourcesScale:
title: Velikost zdrojů na mapě title: Velikost zdrojů na mapě
description: Určuje velikost ikon tvarů na náhledu mapy (při oddálení). 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'.
rangeSliderPercentage: <amount> % rangeSliderPercentage: <amount> %
tickrateHz: <amount> Hz
keybindings: keybindings:
title: Klávesové zkratky title: Klávesové zkratky
hint: "Tip: Nezapomeňte používat CTRL, SHIFT a ALT! Díky nim můžete měnit způsob hint: "Tip: Nezapomeňte používat CTRL, SHIFT a ALT! Díky nim můžete měnit způsob
@ -1076,6 +1082,7 @@ keybindings:
goal_acceptor: Přijemce cílů goal_acceptor: Přijemce cílů
block: Blok block: Blok
massSelectClear: Vymazat pásy massSelectClear: Vymazat pásy
showShapeTooltip: Show shape output tooltip
about: about:
title: O hře title: O hře
body: >- body: >-
@ -1213,8 +1220,24 @@ puzzleMenu:
easy: Lehká easy: Lehká
medium: Střední medium: Střední
hard: Těžká hard: Těžká
unknown: Unrated
dlcHint: Již jste toto DLC zakoupili? Ujistěte se, že je aktivováno kliknutím 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. 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
difficulties:
any: Any Difficulty
easy: Easy
medium: Medium
hard: Hard
durations:
any: Any Duration
short: Short (< 2 min)
medium: Normal
long: Long (> 10 min)
backendErrors: backendErrors:
ratelimit: Provádíte své akce příliš často. Počkejte prosím. 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 invalid-api-key: Komunikace s back-endem se nezdařila, prosím zkuste

File diff suppressed because it is too large Load Diff

View File

@ -22,7 +22,6 @@ steamPage:
steam_review_comment: This game has stolen my life and I don't want it back. steam_review_comment: This game has stolen my life and I don't want it back.
Very chill factory game that won't let me stop making my lines more Very chill factory game that won't let me stop making my lines more
efficient. efficient.
global: global:
loading: Laden loading: Laden
error: Fehler error: Fehler
@ -55,7 +54,6 @@ global:
escape: ESC escape: ESC
shift: UMSCH shift: UMSCH
space: LEER space: LEER
demoBanners: demoBanners:
title: Demoversion title: Demoversion
intro: Kauf die Vollversion für alle Features! intro: Kauf die Vollversion für alle Features!
@ -71,7 +69,8 @@ mainMenu:
helpTranslate: Hilf beim Übersetzen! helpTranslate: Hilf beim Übersetzen!
madeBy: Ein Spiel von <author-link> madeBy: Ein Spiel von <author-link>
browserWarning: Sorry, aber das Spiel wird in deinem Browser langsamer laufen! browserWarning: Sorry, aber das Spiel wird in deinem Browser langsamer laufen!
Kaufe die Vollversion oder verwende Google Chrome für die beste Erfahrung. Kaufe die Vollversion oder verwende Google Chrome für die beste
Erfahrung.
savegameLevel: Level <x> savegameLevel: Level <x>
savegameLevelUnknown: Unbekanntes Level savegameLevelUnknown: Unbekanntes Level
savegameUnnamed: Unbenannt savegameUnnamed: Unbenannt
@ -81,7 +80,6 @@ mainMenu:
zu machen? Hol dir das Puzzle-DLC auf Steam für noch mehr Spaß! zu machen? Hol dir das Puzzle-DLC auf Steam für noch mehr Spaß!
puzzleDlcWishlist: Jetzt zur Wunschliste hinzufügen! puzzleDlcWishlist: Jetzt zur Wunschliste hinzufügen!
puzzleDlcViewNow: DLC anzeigen puzzleDlcViewNow: DLC anzeigen
puzzleMenu: puzzleMenu:
play: Spielen play: Spielen
edit: Bearbeiten edit: Bearbeiten
@ -92,9 +90,9 @@ puzzleMenu:
validatingPuzzle: Puzzle wird überprüft validatingPuzzle: Puzzle wird überprüft
submittingPuzzle: Puzzle wird veröffentlicht submittingPuzzle: Puzzle wird veröffentlicht
noPuzzles: Hier gibt es bisher noch keine Puzzles. noPuzzles: Hier gibt es bisher noch keine Puzzles.
dlcHint: DLC schon gekauft? Stelle sicher, dass es aktiviert ist, indem du in der Steam-Bibliothek dlcHint: DLC schon gekauft? Stelle sicher, dass es aktiviert ist, indem du in
shapez.io rechtsklickst und es unter Eigenschaften > Zusatzinhalte (DLC) aktivierst. der Steam-Bibliothek shapez.io rechtsklickst und es unter Eigenschaften
> Zusatzinhalte (DLC) aktivierst.
categories: categories:
levels: Levels levels: Levels
new: Neu new: Neu
@ -111,26 +109,38 @@ puzzleMenu:
difficulties: Nach Schwierigkeit difficulties: Nach Schwierigkeit
account: Meine Puzzles account: Meine Puzzles
search: Suche search: Suche
difficulties: difficulties:
easy: Einfach easy: Einfach
medium: Mittel medium: Mittel
hard: Schwer hard: Schwer
unknown: Unrated
validation: validation:
title: Ungültiges Puzzle title: Ungültiges Puzzle
noProducers: Bitte platziere einen Itemproduzent! noProducers: Bitte platziere einen Itemproduzent!
noGoalAcceptors: Bitte platziere einen Zielakzeptor! noGoalAcceptors: Bitte platziere einen Zielakzeptor!
goalAcceptorNoItem: Ein oder mehrere Zielakzeptoren haben noch kein goalAcceptorNoItem: Ein oder mehrere Zielakzeptoren haben noch kein zugewiesenes
zugewiesenes Item. Beliefere sie mit einer Form, um ein Ziel zu Item. Beliefere sie mit einer Form, um ein Ziel zu setzen.
setzen. goalAcceptorRateNotMet: Ein oder mehrere Zielakzeptoren bekommen nicht genügend
goalAcceptorRateNotMet: Ein oder mehrere Zielakzeptoren bekommen nicht Items. Stelle sicher, dass alle ihre Indikatoren grün leuchten.
genügend Items. Stelle sicher, dass alle ihre Indikatoren grün leuchten.
buildingOutOfBounds: Ein oder mehrere Gebäude befinden sich außerhalb des buildingOutOfBounds: Ein oder mehrere Gebäude befinden sich außerhalb des
bebaubaren Bereichs. Vergrößere den Bereich oder entferne die Gebäude. bebaubaren Bereichs. Vergrößere den Bereich oder entferne die
Gebäude.
autoComplete: Dein Puzzle schließt sich selbst ab! Bitte stelle sicher, dass autoComplete: Dein Puzzle schließt sich selbst ab! Bitte stelle sicher, dass
deine Itemproduzenten nicht direkt an deine Zielakzeptoren liefern. deine Itemproduzenten nicht direkt an deine Zielakzeptoren liefern.
search:
action: Search
placeholder: Enter a puzzle or author name
includeCompleted: Include Completed
difficulties:
any: Any Difficulty
easy: Easy
medium: Medium
hard: Hard
durations:
any: Any Duration
short: Short (< 2 min)
medium: Normal
long: Long (> 10 min)
dialogs: dialogs:
buttons: buttons:
ok: OK ok: OK
@ -190,9 +200,10 @@ dialogs:
desc: "Hier sind die Änderungen, seitdem du das letzte Mal gespielt hast:" desc: "Hier sind die Änderungen, seitdem du das letzte Mal gespielt hast:"
upgradesIntroduction: upgradesIntroduction:
title: Upgrades freischalten title: Upgrades freischalten
desc: Viele deiner Formen können noch benutzt werden, um Upgrades freizuschalten, also desc: Viele deiner Formen können noch benutzt werden, um Upgrades
<strong>zerstöre deine alten Fabriken nicht!</strong> Den freizuschalten, also <strong>zerstöre deine alten Fabriken
Upgrade-Tab findest du oben rechts im Bildschirm. nicht!</strong> Den Upgrade-Tab findest du oben rechts im
Bildschirm.
massDeleteConfirm: massDeleteConfirm:
title: Löschen bestätigen title: Löschen bestätigen
desc: Du löscht viele Gebäude (<count> um genau zu sein)! Bist du dir sicher? desc: Du löscht viele Gebäude (<count> um genau zu sein)! Bist du dir sicher?
@ -212,7 +223,8 @@ dialogs:
desc: >- desc: >-
Dieses Spiel hat viele Hotkeys, die den Bau von Fabriken Dieses Spiel hat viele Hotkeys, die den Bau von Fabriken
vereinfachen und beschleunigen. Hier sind ein paar Beispiele, aber vereinfachen und beschleunigen. Hier sind ein paar Beispiele, aber
prüfe am besten die <strong>Tastenbelegung</strong> in den Einstellungen!<br><br> prüfe am besten die <strong>Tastenbelegung</strong> in den
Einstellungen!<br><br>
<code class='keybinding'>STRG</code> + Ziehen: Wähle Bereich aus.<br> <code class='keybinding'>STRG</code> + Ziehen: Wähle Bereich aus.<br>
<code class='keybinding'>UMSCH</code>: Halten, um mehrere Gebäude zu platzieren.<br> <code class='keybinding'>UMSCH</code>: Halten, um mehrere Gebäude zu platzieren.<br>
<code class='keybinding'>ALT</code>: Invertiere die Platzierungsrichtung der Fließbänder.<br> <code class='keybinding'>ALT</code>: Invertiere die Platzierungsrichtung der Fließbänder.<br>
@ -220,16 +232,18 @@ dialogs:
title: Neue Markierung title: Neue Markierung
titleEdit: Markierung bearbeiten titleEdit: Markierung bearbeiten
desc: Gib ihm einen griffigen Namen. Du kannst auch den desc: Gib ihm einen griffigen Namen. Du kannst auch den
<strong>Kurzschlüssel</strong> einer Form eingeben (<link>Hier</link> geht es zum Generator). <strong>Kurzschlüssel</strong> einer Form eingeben
(<link>Hier</link> geht es zum Generator).
editSignal: editSignal:
title: Signal setzen title: Signal setzen
descItems: "Wähle ein vordefiniertes Item:" descItems: "Wähle ein vordefiniertes Item:"
descShortKey: ... oder gib den <strong>Kurzschlüssel</strong> einer Form an (<link>Hier</link> geht es zum Generator). descShortKey: ... oder gib den <strong>Kurzschlüssel</strong> einer Form an
(<link>Hier</link> geht es zum Generator).
editConstantProducer: editConstantProducer:
title: Item wählen title: Item wählen
markerDemoLimit: markerDemoLimit:
desc: Du kannst nur 2 Markierungen in der Demo benutzen. Hole dir die Vollversion, um desc: Du kannst nur 2 Markierungen in der Demo benutzen. Hole dir die
unbegrenzt viele Markierungen zu setzen! Vollversion, um unbegrenzt viele Markierungen zu setzen!
exportScreenshotWarning: exportScreenshotWarning:
title: Bildschirmfoto exportieren title: Bildschirmfoto exportieren
desc: Hier kannst du ein Bildschirmfoto von deiner ganzen Fabrik erstellen. Für desc: Hier kannst du ein Bildschirmfoto von deiner ganzen Fabrik erstellen. Für
@ -240,7 +254,8 @@ dialogs:
desc: Hier kannst du deinen Speicherstand umbenennen. desc: Hier kannst du deinen Speicherstand umbenennen.
tutorialVideoAvailable: tutorialVideoAvailable:
title: Tutorial verfügbar title: Tutorial verfügbar
desc: Für dieses Level ist ein Anleitungsvideo verfügbar. Willst du es anschauen? desc: Für dieses Level ist ein Anleitungsvideo verfügbar. Willst du es
anschauen?
tutorialVideoAvailableForeignLanguage: tutorialVideoAvailableForeignLanguage:
title: Tutorial verfügbar title: Tutorial verfügbar
desc: Für dieses Level ist ein Anleitungsvideo verfügbar, allerdings nur auf desc: Für dieses Level ist ein Anleitungsvideo verfügbar, allerdings nur auf
@ -264,8 +279,9 @@ dialogs:
desc: "Das Puzzle konnte nicht geladen werden:" desc: "Das Puzzle konnte nicht geladen werden:"
offlineMode: offlineMode:
title: Offlinemodus title: Offlinemodus
desc: Die Server konnten nicht erreicht werden, daher läuft das Spiel im Offlinemodus. desc: Die Server konnten nicht erreicht werden, daher läuft das Spiel im
Bitte stelle sicher, dass du eine aktive Internetverbindung hast. Offlinemodus. Bitte stelle sicher, dass du eine aktive
Internetverbindung hast.
puzzleDownloadError: puzzleDownloadError:
title: Downloadfehler title: Downloadfehler
desc: "Der Download des Puzzles ist fehlgeschlagen:" desc: "Der Download des Puzzles ist fehlgeschlagen:"
@ -275,17 +291,17 @@ dialogs:
puzzleSubmitOk: puzzleSubmitOk:
title: Puzzle veröffentlicht title: Puzzle veröffentlicht
desc: Herzlichen Glückwunsch! Dein Puzzle wurde veröffentlicht und kann nun von desc: Herzlichen Glückwunsch! Dein Puzzle wurde veröffentlicht und kann nun von
anderen gespielt werden. Du kannst es jetzt im Bereich "Meine Puzzles" finden. anderen gespielt werden. Du kannst es jetzt im Bereich "Meine
Puzzles" finden.
puzzleCreateOffline: puzzleCreateOffline:
title: Offlinemodus title: Offlinemodus
desc: Da du offline bist, kannst du dein Puzzle nicht speichern desc: Da du offline bist, kannst du dein Puzzle nicht speichern und/oder
und/oder veröffentlichen. Möchtest du trotzdem fortfahren? veröffentlichen. Möchtest du trotzdem fortfahren?
puzzlePlayRegularRecommendation: puzzlePlayRegularRecommendation:
title: Empfehlung title: Empfehlung
desc: Ich empfehle dir <strong>sehr</strong>, bis Level 12 zu desc: Ich empfehle dir <strong>sehr</strong>, bis Level 12 zu spielen, bevor du
spielen, bevor du dich an das Puzzle-DLC wagst. Du stößt sonst dich an das Puzzle-DLC wagst. Du stößt sonst möglicherweise auf dir
möglicherweise auf dir noch nicht bekannte Mechaniken. Möchtest du noch nicht bekannte Mechaniken. Möchtest du trotzdem fortfahren?
trotzdem fortfahren?
puzzleShare: puzzleShare:
title: Kurzschlüssel kopiert title: Kurzschlüssel kopiert
desc: Der Kurzschlüssel des Puzzles (<key>) wurde in die Zwischenablage kopiert! desc: Der Kurzschlüssel des Puzzles (<key>) wurde in die Zwischenablage kopiert!
@ -309,7 +325,6 @@ dialogs:
title: Puzzle löschen? title: Puzzle löschen?
desc: Bist du sicher, dass du '<title>' löschen möchtest? Dies kann nicht desc: Bist du sicher, dass du '<title>' löschen möchtest? Dies kann nicht
rückgängig gemacht werden! rückgängig gemacht werden!
ingame: ingame:
keybindingsOverlay: keybindingsOverlay:
moveMap: Bewegen moveMap: Bewegen
@ -397,9 +412,9 @@ ingame:
waypoints: waypoints:
waypoints: Markierungen waypoints: Markierungen
hub: Hub hub: Hub
description: Linksklick auf eine Markierung, um dort hinzugelangen. Rechtsklick, um description: Linksklick auf eine Markierung, um dort hinzugelangen. Rechtsklick,
sie zu löschen.<br><br>Drücke <keybinding>, um eine Markierung aus um sie zu löschen.<br><br>Drücke <keybinding>, um eine Markierung
deinem Blickwinkel, oder <strong>rechtsklicke</strong>, um eine aus deinem Blickwinkel, oder <strong>rechtsklicke</strong>, um eine
Markierung auf der ausgewählten Position zu erschaffen. Markierung auf der ausgewählten Position zu erschaffen.
creationSuccessNotification: Markierung wurde erstellt. creationSuccessNotification: Markierung wurde erstellt.
shapeViewer: shapeViewer:
@ -419,15 +434,16 @@ ingame:
Halte <strong>UMSCH</strong>, um mehrere Gebäude zu platzieren Halte <strong>UMSCH</strong>, um mehrere Gebäude zu platzieren
und nutze <strong>R</strong>, um sie zu rotieren." und nutze <strong>R</strong>, um sie zu rotieren."
2_1_place_cutter: "Platziere nun einen <strong>Schneider</strong>, um die Kreise 2_1_place_cutter: "Platziere nun einen <strong>Schneider</strong>, um die Kreise
zu halbieren.<br><br> Übrigens: Der Schneider zu halbieren.<br><br> Übrigens: Der Schneider teilt Items immer
teilt Items immer von <strong>oben nach unten</strong>, unabhängig von von <strong>oben nach unten</strong>, unabhängig von seiner
seiner Orientierung!" Orientierung!"
2_2_place_trash: Der Schneider kann <strong>verstopfen</strong>!<br><br>Benutze 2_2_place_trash: Der Schneider kann <strong>verstopfen</strong>!<br><br>Benutze
einen <strong>Mülleimer</strong> um den aktuell (!) nicht einen <strong>Mülleimer</strong> um den aktuell (!) nicht
benötigten Rest loszuwerden. benötigten Rest loszuwerden.
2_3_more_cutters: "Gut gemacht! Platziere noch <strong>zwei andere Schneider</strong> 2_3_more_cutters: "Gut gemacht! Platziere noch <strong>zwei andere
um das Ganze zu beschleunigen.<br><br> Übrigens: Benutze die Schneider</strong> um das Ganze zu beschleunigen.<br><br>
<strong>Hotkeys 0-9</strong> um Gebäude schneller auszuwählen!" Übrigens: Benutze die <strong>Hotkeys 0-9</strong> um Gebäude
schneller auszuwählen!"
3_1_rectangles: "Lass uns ein paar Quadrate extrahieren! <strong>Baue vier 3_1_rectangles: "Lass uns ein paar Quadrate extrahieren! <strong>Baue vier
Extraktoren</strong> und verbinde sie mit deinem Hub.<br><br> Extraktoren</strong> und verbinde sie mit deinem Hub.<br><br>
PS: Halte <strong>SHIFT</strong>, während du ein Fließband PS: Halte <strong>SHIFT</strong>, während du ein Fließband
@ -441,8 +457,9 @@ ingame:
21_3_place_button: Perfekt! Platziere jetzt einen <strong>Schalter</strong> und 21_3_place_button: Perfekt! Platziere jetzt einen <strong>Schalter</strong> und
verbinde ihn mit Signalkabeln. verbinde ihn mit Signalkabeln.
21_4_press_button: "Drücke den Schalter, damit er ein <strong>wahres 21_4_press_button: "Drücke den Schalter, damit er ein <strong>wahres
Signal</strong> ausgibt und den Färber aktiviert.<br><br> Signal</strong> ausgibt und den Färber aktiviert.<br><br> PS: Du
PS: Du musst nicht alle Eingänge verbinden! Probiere es auch mal mit zwei." musst nicht alle Eingänge verbinden! Probiere es auch mal mit
zwei."
connectedMiners: connectedMiners:
one_miner: Ein Extraktor one_miner: Ein Extraktor
n_miners: <amount> Extraktoren n_miners: <amount> Extraktoren
@ -492,12 +509,21 @@ ingame:
puzzleEditorControls: puzzleEditorControls:
title: Puzzle-Editor title: Puzzle-Editor
instructions: instructions:
- 1. Platziere einen <strong>Itemproduzenten</strong> um Formen und Farben für den Spieler bereitzustellen - 1. Platziere einen <strong>Itemproduzenten</strong> um Formen und
- 2. Produziere eine oder mehrere Formen, die der Spieler herstellen soll und liefere diese zu einem oder mehreren <strong>Zielakzeptoren</strong> Farben für den Spieler bereitzustellen
- 3. Sobald ein Zielakzeptor eine Form für eine gewisse Zeit erhält, <strong>speichert dieser sie als Ziel</strong> (Angezeigt durch den <strong>grünen Punkt</strong>). - 2. Produziere eine oder mehrere Formen, die der Spieler herstellen
- 4. Klicke auf das <strong>Schloss</strong>, um ein Gebäude für den Spieler zu sperren. soll und liefere diese zu einem oder mehreren
- 5. Sobald du auf Überprüfen gedrückt hast, wird dein Puzzle `validiert und du kannst es veröffentlichen. <strong>Zielakzeptoren</strong>
- 6. Bei der Freigabe werden <strong>alle Gebäude entfernt</strong>. Ausgenommen sind die Produzenten und Akzeptoren. Den Rest soll der Spieler schließlich selbst herausfinden :) - 3. Sobald ein Zielakzeptor eine Form für eine gewisse Zeit erhält,
<strong>speichert dieser sie als Ziel</strong> (Angezeigt durch
den <strong>grünen Punkt</strong>).
- 4. Klicke auf das <strong>Schloss</strong>, um ein Gebäude für den
Spieler zu sperren.
- 5. Sobald du auf Überprüfen gedrückt hast, wird dein Puzzle
`validiert und du kannst es veröffentlichen.
- 6. Bei der Freigabe werden <strong>alle Gebäude entfernt</strong>.
Ausgenommen sind die Produzenten und Akzeptoren. Den Rest soll der
Spieler schließlich selbst herausfinden :)
puzzleCompletion: puzzleCompletion:
title: Puzzle geschafft! title: Puzzle geschafft!
titleLike: "Klicke auf das Herz, wenn dir das Puzzle gefallen hat:" titleLike: "Klicke auf das Herz, wenn dir das Puzzle gefallen hat:"
@ -505,13 +531,13 @@ ingame:
titleRatingDesc: Deine Bewertung hilft mir, in Zukunft bessere Vorschläge zu machen titleRatingDesc: Deine Bewertung hilft mir, in Zukunft bessere Vorschläge zu machen
continueBtn: Weiterspielen continueBtn: Weiterspielen
menuBtn: Menü menuBtn: Menü
nextPuzzle: Next Puzzle
puzzleMetadata: puzzleMetadata:
author: Ersteller author: Ersteller
shortKey: Kurzschlüssel shortKey: Kurzschlüssel
rating: Schwierigkeitsgrad rating: Schwierigkeitsgrad
averageDuration: Durchschnittliche Dauer averageDuration: Durchschnittliche Dauer
completionRate: Abschlussrate completionRate: Abschlussrate
shopUpgrades: shopUpgrades:
belt: belt:
name: Fließbänder, Verteiler & Tunnel name: Fließbänder, Verteiler & Tunnel
@ -525,7 +551,6 @@ shopUpgrades:
painting: painting:
name: Mischer & Färber name: Mischer & Färber
description: Geschw. x<currentMult> → x<newMult> description: Geschw. x<currentMult> → x<newMult>
buildings: buildings:
hub: hub:
deliver: Liefere deliver: Liefere
@ -693,9 +718,9 @@ buildings:
reader: reader:
default: default:
name: Fließbandkontrolle name: Fließbandkontrolle
description: Misst den gemittelten Durchsatz des Fließbandes. Gibt zusätzlich den description: Misst den gemittelten Durchsatz des Fließbandes. Gibt zusätzlich
zuletzt passierten Gegenstand auf der Wires-Ebene aus (sobald den zuletzt passierten Gegenstand auf der Wires-Ebene aus
freigeschaltet). (sobald freigeschaltet).
analyzer: analyzer:
default: default:
name: Formanalyse name: Formanalyse
@ -741,13 +766,15 @@ buildings:
default: default:
name: Sperrblock name: Sperrblock
description: Ermöglicht das Blockieren einer Kachel. description: Ermöglicht das Blockieren einer Kachel.
storyRewards: storyRewards:
reward_cutter_and_trash: reward_cutter_and_trash:
title: Formen zerschneiden title: Formen zerschneiden
desc: Du hast gerade den <strong>Schneider</strong> freigeschaltet, der Formen vertikal halbiert, <b>unabhängig von seiner Orientierung</b>!<br><br> desc: Du hast gerade den <strong>Schneider</strong> freigeschaltet, der Formen
Achte darauf, die Überreste loszuwerden, sonst <b>verstopft und blockiert er</b> - Zu diesem Zweck habe ich vertikal halbiert, <b>unabhängig von seiner
dir den <strong>Mülleimer</strong> gegeben. Er entsorgt alles, was du ihm fütterst! Orientierung</b>!<br><br> Achte darauf, die Überreste loszuwerden,
sonst <b>verstopft und blockiert er</b> - Zu diesem Zweck habe ich
dir den <strong>Mülleimer</strong> gegeben. Er entsorgt alles, was
du ihm fütterst!
reward_rotater: reward_rotater:
title: Rotieren title: Rotieren
desc: Der <strong>Rotierer</strong> wurde freigeschaltet! Er rotiert Formen im desc: Der <strong>Rotierer</strong> wurde freigeschaltet! Er rotiert Formen im
@ -772,8 +799,8 @@ storyRewards:
reward_balancer: reward_balancer:
title: Verteiler title: Verteiler
desc: Der multifunktionale <strong>Verteiler</strong> wurde freigeschaltet! desc: Der multifunktionale <strong>Verteiler</strong> wurde freigeschaltet!
Damit kannst du nun endlich größere Fabriken bauen. Er kann Fließbänder Damit kannst du nun endlich größere Fabriken bauen. Er kann
<strong>aufteilen oder zusammenlegen</strong>! Fließbänder <strong>aufteilen oder zusammenlegen</strong>!
reward_tunnel: reward_tunnel:
title: Tunnel title: Tunnel
desc: Der <strong>Tunnel</strong> wurde freigeschaltet! Du kannst Items nun desc: Der <strong>Tunnel</strong> wurde freigeschaltet! Du kannst Items nun
@ -787,9 +814,9 @@ storyRewards:
reward_miner_chainable: reward_miner_chainable:
title: Extraktor (Kette) title: Extraktor (Kette)
desc: "Du hast den <strong>Kettenextraktor</strong> freigeschaltet! Er kann desc: "Du hast den <strong>Kettenextraktor</strong> freigeschaltet! Er kann
seine Ressourcen an andere Extraktoren seine Ressourcen an andere Extraktoren <strong>weitergeben</strong>.
<strong>weitergeben</strong>. <br><br> PS: Der alte Extraktor <br><br> PS: Der alte Extraktor wurde jetzt in deiner Symbolleiste
wurde jetzt in deiner Symbolleiste ersetzt!" ersetzt!"
reward_underground_belt_tier_2: reward_underground_belt_tier_2:
title: Tunnel Stufe II title: Tunnel Stufe II
desc: Du hast eine neue Variante des <strong>Tunnels</strong> freigeschaltet! desc: Du hast eine neue Variante des <strong>Tunnels</strong> freigeschaltet!
@ -848,8 +875,8 @@ storyRewards:
<strong>vierfachen Färber</strong>. Schließe die Eingänge, mit denen <strong>vierfachen Färber</strong>. Schließe die Eingänge, mit denen
du die Quadranten färben möchtest, an ein Signalkabel auf der du die Quadranten färben möchtest, an ein Signalkabel auf der
Wires-Ebene an!<br><br> Mit <strong>E</strong> wechselst du zwischen Wires-Ebene an!<br><br> Mit <strong>E</strong> wechselst du zwischen
den Ebenen. <br><br>PS: <strong>Aktiviere die Hinweise</strong> in den den Ebenen. <br><br>PS: <strong>Aktiviere die Hinweise</strong> in
Einstellungen, um das Tutorial anzuzeigen!" den Einstellungen, um das Tutorial anzuzeigen!"
reward_filter: reward_filter:
title: Itemfilter title: Itemfilter
desc: Du hast den <strong>Itemfilter</strong> freigeschaltet! Items, die dem desc: Du hast den <strong>Itemfilter</strong> freigeschaltet! Items, die dem
@ -910,11 +937,11 @@ storyRewards:
jetzt einen bestimmten <strong>Durchsatz</strong> benötigt, empfehle jetzt einen bestimmten <strong>Durchsatz</strong> benötigt, empfehle
ich dringend, eine Maschine zu bauen, die automatisch die gewünschte ich dringend, eine Maschine zu bauen, die automatisch die gewünschte
Form liefert!<br><br> Der Hub gibt die gewünschte Form auf der Form liefert!<br><br> Der Hub gibt die gewünschte Form auf der
Wires-Ebene aus, also musst du sie nur analysieren und deine Fabrik dementsprechend konfigurieren (lassen). Wires-Ebene aus, also musst du sie nur analysieren und deine Fabrik
dementsprechend konfigurieren (lassen).
reward_demo_end: reward_demo_end:
title: Ende der Demo title: Ende der Demo
desc: Du bist am Ende der Demo angekommen! desc: Du bist am Ende der Demo angekommen!
settings: settings:
title: Einstellungen title: Einstellungen
categories: categories:
@ -1022,11 +1049,13 @@ settings:
title: Intelligente Tunnel title: Intelligente Tunnel
description: Aktiviert das automatische Entfernen von überflüssigen Fließbändern description: Aktiviert das automatische Entfernen von überflüssigen Fließbändern
bei der Platzierung von Tunneln. Außerdem funktioniert das bei der Platzierung von Tunneln. Außerdem funktioniert das
Ziehen von Tunneln und überschüssige Tunnel werden ebenfalls entfernt. Ziehen von Tunneln und überschüssige Tunnel werden ebenfalls
entfernt.
vignette: vignette:
title: Vignette title: Vignette
description: Aktiviert den Vignetteneffekt, der den Rand des Bildschirms description: Aktiviert den Vignetteneffekt, der den Rand des Bildschirms
zunehmend verdunkelt und damit das Lesen der Textfelder vereinfacht. zunehmend verdunkelt und damit das Lesen der Textfelder
vereinfacht.
rotationByBuilding: rotationByBuilding:
title: Rotation pro Gebäudetyp title: Rotation pro Gebäudetyp
description: Jeder Gebäudetyp merkt sich eigenständig, in welche Richtung er description: Jeder Gebäudetyp merkt sich eigenständig, in welche Richtung er
@ -1052,10 +1081,10 @@ settings:
Außerdem vereinfacht es die Darstellung! Außerdem vereinfacht es die Darstellung!
clearCursorOnDeleteWhilePlacing: clearCursorOnDeleteWhilePlacing:
title: Abwählen mit Rechtsklick title: Abwählen mit Rechtsklick
description: Ist standardmäßig eingeschaltet und wählt das aktuell description: Ist standardmäßig eingeschaltet und wählt das aktuell ausgewählte
ausgewählte Gebäude ab, wenn du die rechte Maustaste drückst. Gebäude ab, wenn du die rechte Maustaste drückst. Wenn du es
Wenn du es abschaltest, kannst du mit der rechten Maustaste abschaltest, kannst du mit der rechten Maustaste Gebäude
Gebäude löschen, während du im Platzierungsmodus bist. löschen, während du im Platzierungsmodus bist.
lowQualityTextures: lowQualityTextures:
title: Niedrige Texturqualität (Unschön) title: Niedrige Texturqualität (Unschön)
description: Das Spiel verwendet eine niedrigere Auflösung bei den Texturen. description: Das Spiel verwendet eine niedrigere Auflösung bei den Texturen.
@ -1067,8 +1096,9 @@ settings:
anzeigen. anzeigen.
pickMinerOnPatch: pickMinerOnPatch:
title: Automatisch Extraktor auswählen title: Automatisch Extraktor auswählen
description: Ist standardmäßig eingeschaltet und du wählst automatisch den Extraktor, description: Ist standardmäßig eingeschaltet und du wählst automatisch den
wenn du mit der Pipette auf einen Ressourcenfleck zeigst. Extraktor, wenn du mit der Pipette auf einen Ressourcenfleck
zeigst.
simplifiedBelts: simplifiedBelts:
title: Minimalistische Fließbänder (Unschön) title: Minimalistische Fließbänder (Unschön)
description: Zur Verbesserung der Leistung werden die Items auf Fließbändern nur description: Zur Verbesserung der Leistung werden die Items auf Fließbändern nur
@ -1088,7 +1118,11 @@ settings:
title: Größe der Ressourcen auf der Karte title: Größe der Ressourcen auf der Karte
description: Legt die Größe der Ressourcen auf der Karte (beim Herauszoomen) description: Legt die Größe der Ressourcen auf der Karte (beim Herauszoomen)
fest. fest.
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
keybindings: keybindings:
title: Tastenbelegung title: Tastenbelegung
hint: "Tipp: Benutze STRG, UMSCH and ALT! Sie aktivieren verschiedene hint: "Tipp: Benutze STRG, UMSCH and ALT! Sie aktivieren verschiedene
@ -1170,10 +1204,11 @@ keybindings:
placementDisableAutoOrientation: Automatische Orientierung deaktivieren placementDisableAutoOrientation: Automatische Orientierung deaktivieren
placeMultiple: Im Platzierungsmodus bleiben placeMultiple: Im Platzierungsmodus bleiben
placeInverse: Automatische Fließbandorientierung invertieren placeInverse: Automatische Fließbandorientierung invertieren
showShapeTooltip: Show shape output tooltip
about: about:
title: Über dieses Spiel title: Über dieses Spiel
body: Dieses Spiel ist quelloffen (Open Source) und wurde von <a href="https://github.com/tobspr" target="_blank">Tobias Springer</a> body: Dieses Spiel ist quelloffen (Open Source) und wurde von <a
href="https://github.com/tobspr" target="_blank">Tobias Springer</a>
(das bin ich!) entwickelt.<br><br> Wenn du etwas zum Spiel beitragen (das bin ich!) entwickelt.<br><br> Wenn du etwas zum Spiel beitragen
möchtest, dann schaue dir <a href="<githublink>" möchtest, dann schaue dir <a href="<githublink>"
target="_blank">shapez.io auf GitHub</a> an.<br><br> Das Spiel wurde target="_blank">shapez.io auf GitHub</a> an.<br><br> Das Spiel wurde
@ -1185,10 +1220,8 @@ about:
möchte ich meinem Kumpel <a href="https://github.com/niklas-dahl" möchte ich meinem Kumpel <a href="https://github.com/niklas-dahl"
target="_blank">Niklas</a> danken! Ohne unsere etlichen gemeinsamen target="_blank">Niklas</a> danken! Ohne unsere etlichen gemeinsamen
Stunden in Factorio wäre dieses Projekt nie zustande gekommen. Stunden in Factorio wäre dieses Projekt nie zustande gekommen.
changelog: changelog:
title: Änderungsprotokoll title: Änderungsprotokoll
demo: demo:
features: features:
restoringGames: Spielstände wiederherstellen restoringGames: Spielstände wiederherstellen
@ -1197,15 +1230,14 @@ demo:
customizeKeybindings: Tastenbelegung anpassen customizeKeybindings: Tastenbelegung anpassen
exportingBase: Ganze Fabrik als Foto exportieren exportingBase: Ganze Fabrik als Foto exportieren
settingNotAvailable: Nicht verfügbar in der Demo. settingNotAvailable: Nicht verfügbar in der Demo.
backendErrors: backendErrors:
ratelimit: Du führst deine Aktionen zu schnell aus. Bitte warte kurz. ratelimit: Du führst deine Aktionen zu schnell aus. Bitte warte kurz.
invalid-api-key: Kommunikation mit dem Back-End fehlgeschlagen. Versuche das invalid-api-key: Kommunikation mit dem Back-End fehlgeschlagen. Versuche das
Spiel neu zu starten oder zu updaten (Ungültiger Api-Schlüssel). Spiel neu zu starten oder zu updaten (Ungültiger Api-Schlüssel).
unauthorized: Kommunikation mit dem Back-End fehlgeschlagen. Versuche das Spiel unauthorized: Kommunikation mit dem Back-End fehlgeschlagen. Versuche das Spiel
neu zu starten oder zu updaten (Nicht autorisiert). neu zu starten oder zu updaten (Nicht autorisiert).
bad-token: Kommunikation mit dem Back-End fehlgeschlagen. Versuche das Spiel bad-token: Kommunikation mit dem Back-End fehlgeschlagen. Versuche das Spiel neu
neu zu starten oder zu updaten (Ungültiger Token). zu starten oder zu updaten (Ungültiger Token).
bad-id: Ungültige Puzzle-ID. bad-id: Ungültige Puzzle-ID.
not-found: Das Puzzle konnte nicht gefunden werden. not-found: Das Puzzle konnte nicht gefunden werden.
bad-category: Die Kategorie konnte nicht gefunden werden. bad-category: Die Kategorie konnte nicht gefunden werden.
@ -1224,7 +1256,6 @@ backendErrors:
too-many-likes-already: Dieses Puzzle ist in der Community sehr beliebt. Wenn du too-many-likes-already: Dieses Puzzle ist in der Community sehr beliebt. Wenn du
es trotzdem löschen möchtest, wende dich bitte an support@shapez.io! es trotzdem löschen möchtest, wende dich bitte an support@shapez.io!
no-permission: Dir fehlt die Berechtigung, um diese Aktion auszuführen. no-permission: Dir fehlt die Berechtigung, um diese Aktion auszuführen.
tips: tips:
- Der Hub akzeptiert alle Formen, nicht nur die aktuell geforderten! - Der Hub akzeptiert alle Formen, nicht nur die aktuell geforderten!
- Stelle sicher, dass deine Fabriken modular sind. Es zahlt sich irgendwann - Stelle sicher, dass deine Fabriken modular sind. Es zahlt sich irgendwann
@ -1290,7 +1321,8 @@ tips:
- Mische alle drei Grundfarben, um Weiß zu erhalten! - Mische alle drei Grundfarben, um Weiß zu erhalten!
- Du hast eine unendlich große Karte, nutze den Platz und expandiere! - Du hast eine unendlich große Karte, nutze den Platz und expandiere!
- Probier auch mal Factorio! Es ist mein Lieblingsspiel. - Probier auch mal Factorio! Es ist mein Lieblingsspiel.
- Der vierfache Schneider schneidet im Uhrzeigersinn von oben rechts beginnend! - Der vierfache Schneider schneidet im Uhrzeigersinn von oben rechts
beginnend!
- Du kannst deine Speicherstände im Hauptmenü herunterladen! - Du kannst deine Speicherstände im Hauptmenü herunterladen!
- Diese Spiel hat viele nützliche Tastenbelegungen! Schau sie dir in den - Diese Spiel hat viele nützliche Tastenbelegungen! Schau sie dir in den
Einstellungen an. Einstellungen an.

View File

@ -475,6 +475,7 @@ ingame:
titleRatingDesc: Your rating will help me to make you better suggestions in the future titleRatingDesc: Your rating will help me to make you better suggestions in the future
continueBtn: Keep Playing continueBtn: Keep Playing
menuBtn: Menu menuBtn: Menu
nextPuzzle: Next Puzzle
puzzleMetadata: puzzleMetadata:
author: Author author: Author
shortKey: Short Key shortKey: Short Key
@ -1038,7 +1039,12 @@ settings:
title: Map Resources Size title: Map Resources Size
description: Controls the size of the shapes on the map overview (when zooming description: Controls the size of the shapes on the map overview (when zooming
out). out).
shapeTooltipAlwaysOn:
title: Shape Tooltip - Show Always
description: Whether to always show the shape tooltip when hovering buildings,
instead of having to hold 'ALT'.
rangeSliderPercentage: <amount> % rangeSliderPercentage: <amount> %
tickrateHz: <amount> Hz
keybindings: keybindings:
title: Συνδιασμοί πλήκτρων title: Συνδιασμοί πλήκτρων
hint: "Συμβουλή: Φρόντισε να χρησιμοποιήσεις τα πλήκτρα CTRL, SHIFT και ALT! hint: "Συμβουλή: Φρόντισε να χρησιμοποιήσεις τα πλήκτρα CTRL, SHIFT και ALT!
@ -1120,6 +1126,7 @@ keybindings:
goal_acceptor: Goal Acceptor goal_acceptor: Goal Acceptor
block: Block block: Block
massSelectClear: Clear belts massSelectClear: Clear belts
showShapeTooltip: Show shape output tooltip
about: about:
title: Σχετικά με αυτό το παιχνίδι title: Σχετικά με αυτό το παιχνίδι
body: >- body: >-
@ -1254,8 +1261,23 @@ puzzleMenu:
easy: Easy easy: Easy
medium: Medium medium: Medium
hard: Hard hard: Hard
unknown: Unrated
dlcHint: Purchased the DLC already? Make sure it is activated by right clicking dlcHint: Purchased the DLC already? Make sure it is activated by right clicking
shapez.io in your library, selecting Properties > DLCs. shapez.io in your library, selecting Properties > DLCs.
search:
action: Search
placeholder: Enter a puzzle or author name
includeCompleted: Include Completed
difficulties:
any: Any Difficulty
easy: Easy
medium: Medium
hard: Hard
durations:
any: Any Duration
short: Short (< 2 min)
medium: Normal
long: Long (> 10 min)
backendErrors: backendErrors:
ratelimit: You are performing your actions too frequent. Please wait a bit. ratelimit: You are performing your actions too frequent. Please wait a bit.
invalid-api-key: Failed to communicate with the backend, please try to invalid-api-key: Failed to communicate with the backend, please try to

View File

@ -155,10 +155,28 @@ puzzleMenu:
account: My Puzzles account: My Puzzles
search: Search search: Search
search:
action: Search
placeholder: Enter a puzzle or author name
includeCompleted: Include Completed
difficulties:
any: Any Difficulty
easy: Easy
medium: Medium
hard: Hard
durations:
any: Any Duration
short: Short (< 2 min)
medium: Normal
long: Long (> 10 min)
difficulties: difficulties:
easy: Easy easy: Easy
medium: Medium medium: Medium
hard: Hard hard: Hard
unknown: Unrated
validation: validation:
title: Invalid Puzzle title: Invalid Puzzle
@ -657,6 +675,7 @@ ingame:
continueBtn: Keep Playing continueBtn: Keep Playing
menuBtn: Menu menuBtn: Menu
nextPuzzle: Next Puzzle
puzzleMetadata: puzzleMetadata:
author: Author author: Author
@ -1080,7 +1099,7 @@ settings:
staging: Staging staging: Staging
prod: Production prod: Production
buildDate: Built <at-date> buildDate: Built <at-date>
tickrateHz: <amount> Hz
rangeSliderPercentage: <amount> % rangeSliderPercentage: <amount> %
labels: labels:
@ -1267,6 +1286,11 @@ settings:
description: >- description: >-
Controls the size of the shapes on the map overview (when zooming out). Controls the size of the shapes on the map overview (when zooming out).
shapeTooltipAlwaysOn:
title: Shape Tooltip - Show Always
description: >-
Whether to always show the shape tooltip when hovering buildings, instead of having to hold 'ALT'.
keybindings: keybindings:
title: Keybindings title: Keybindings
hint: >- hint: >-
@ -1363,6 +1387,8 @@ keybindings:
placeMultiple: Stay in placement mode placeMultiple: Stay in placement mode
placeInverse: Invert automatic belt orientation placeInverse: Invert automatic belt orientation
showShapeTooltip: Show shape output tooltip
about: about:
title: About this Game title: About this Game
body: >- body: >-

View File

@ -25,8 +25,8 @@ steamPage:
global: global:
loading: Cargando loading: Cargando
error: Error error: Error
thousandsDivider: "," thousandsDivider: .
decimalSeparator: . decimalSeparator: ","
suffix: suffix:
thousands: k thousands: k
millions: M millions: M
@ -78,7 +78,7 @@ mainMenu:
puzzleDlcText: ¿Disfrutas compactando y optimizando fábricas? ¡Consigue ahora el puzzleDlcText: ¿Disfrutas compactando y optimizando fábricas? ¡Consigue ahora el
DLC de Puzles en Steam para aún más diversión! DLC de Puzles en Steam para aún más diversión!
puzzleDlcWishlist: ¡Añádelo ahora a tu lista de deseos! puzzleDlcWishlist: ¡Añádelo ahora a tu lista de deseos!
puzzleDlcViewNow: View Dlc puzzleDlcViewNow: Ver Dlc
dialogs: dialogs:
buttons: buttons:
ok: OK ok: OK
@ -198,7 +198,7 @@ dialogs:
desc: Hay un video tutorial disponible para este nivel, pero solo está desc: Hay un video tutorial disponible para este nivel, pero solo está
disponible en inglés ¿Te gustaría verlo? disponible en inglés ¿Te gustaría verlo?
editConstantProducer: editConstantProducer:
title: Set Item title: Elegir item
puzzleLoadFailed: puzzleLoadFailed:
title: Fallo al cargar los Puzles title: Fallo al cargar los Puzles
desc: Desafortunadamente, no se pudieron cargar los puzles. desc: Desafortunadamente, no se pudieron cargar los puzles.
@ -248,12 +248,12 @@ dialogs:
puzzleReport: puzzleReport:
title: Reportar Puzle title: Reportar Puzle
options: options:
profane: Lenguaje soez profane: Profanidades
unsolvable: Imposible de resolver unsolvable: Imposible de resolver
trolling: Troll trolling: Troll
puzzleReportComplete: puzzleReportComplete:
title: ¡Gracias por tu aporte! title: ¡Gracias por tu aporte!
desc: El puzle ha sido marcado como abuso. desc: El puzle ha sido reportado exitosamente.
puzzleReportError: puzzleReportError:
title: No se pudo reportar title: No se pudo reportar
desc: "No pudimos procesar tu informe:" desc: "No pudimos procesar tu informe:"
@ -261,8 +261,8 @@ dialogs:
title: Introducir clave title: Introducir clave
desc: Introduce la clave del puzle para cargarlo. desc: Introduce la clave del puzle para cargarlo.
puzzleDelete: puzzleDelete:
title: Delete Puzzle? title: ¿Eliminar Puzle?
desc: Are you sure you want to delete '<title>'? This can not be undone! desc: ¿Estas seguro de querer eliminar '<title>'? ¡Esto no se puede deshacer!
ingame: ingame:
keybindingsOverlay: keybindingsOverlay:
moveMap: Mover moveMap: Mover
@ -284,7 +284,7 @@ ingame:
clearSelection: Limpiar selección clearSelection: Limpiar selección
pipette: Cuentagotas pipette: Cuentagotas
switchLayers: Cambiar capas switchLayers: Cambiar capas
clearBelts: Clear belts clearBelts: Borrar cintas
colors: colors:
red: Rojo red: Rojo
green: Verde green: Verde
@ -473,6 +473,7 @@ ingame:
titleRatingDesc: Tu puntuación me ayudará a hacerte mejores sugerencias en el futuro titleRatingDesc: Tu puntuación me ayudará a hacerte mejores sugerencias en el futuro
continueBtn: Continuar Jugando continueBtn: Continuar Jugando
menuBtn: Menú menuBtn: Menú
nextPuzzle: Next Puzzle
puzzleMetadata: puzzleMetadata:
author: Autor author: Autor
shortKey: Clave shortKey: Clave
@ -621,29 +622,29 @@ buildings:
default: default:
name: Puerta AND name: Puerta AND
description: Emite el valor booleano "1" si ambas entradas son verdaderas. description: Emite el valor booleano "1" si ambas entradas son verdaderas.
(Verdadeas significa una forma, color o valor booleano "1") (Verdaderas significa una forma, color o valor booleano "1")
not: not:
name: Puerta NOT name: Puerta NOT
description: Emite el valor booleano "1" si ambas entradas no son verdaderas. description: Emite el valor booleano "1" si ambas entradas no son verdaderas.
(Verdadeas significa una forma, color o valor booleano "1") (Verdaderas significa una forma, color o valor booleano "1")
xor: xor:
name: Puerta XOR name: Puerta XOR
description: Emite el valor booleano "1" si una de las entradas es verdadera, description: Emite el valor booleano "1" si una de las entradas es verdadera,
pero no si ambas lo son. (Verdadeas significa una forma, color o pero no si ambas lo son. (Verdaderas significa una forma, color
valor booleano "1") o valor booleano "1")
or: or:
name: Puerta OR name: Puerta OR
description: Emite el valor booleano "1" Si una de las entradas es verdadera. description: Emite el valor booleano "1" Si una de las entradas es verdadera.
(Verdadeas significa una forma, color o valor booleano "1") (Verdaderas significa una forma, color o valor booleano "1")
transistor: transistor:
default: default:
name: Transistor name: Transistor
description: Envia la señal de abajo si la señal del costado es verdadera description: Envia la señal de abajo si la señal del costado es verdadera
(Verdadeas significa una forma, color o valor booleano "1"). (Verdaderas significa una forma, color o valor booleano "1").
mirrored: mirrored:
name: Transistor name: Transistor
description: Envia la señal de abajo si la señal del costado es verdadera description: Envia la señal de abajo si la señal del costado es verdadera
(Verdadeas significa una forma, color o valor booleano "1"). (Verdaderas significa una forma, color o valor booleano "1").
filter: filter:
default: default:
name: Filtro name: Filtro
@ -664,7 +665,7 @@ buildings:
analyzer: analyzer:
default: default:
name: Analizador de formas name: Analizador de formas
description: analiza el cuadrante de arriba a la derecha de la capa más baja de description: Analiza el cuadrante de arriba a la derecha de la capa más baja de
la forma y devuelve su figura y color. la forma y devuelve su figura y color.
comparator: comparator:
default: default:
@ -1046,7 +1047,12 @@ settings:
title: Tamaño de recursos en el mapa title: Tamaño de recursos en el mapa
description: Controla el tamaño de los recursos en la vista de aérea del mapa description: Controla el tamaño de los recursos en la vista de aérea del mapa
(Al hacer zoom mínimo). (Al hacer zoom mínimo).
shapeTooltipAlwaysOn:
title: Shape Tooltip - Show Always
description: Whether to always show the shape tooltip when hovering buildings,
instead of having to hold 'ALT'.
rangeSliderPercentage: <amount> % rangeSliderPercentage: <amount> %
tickrateHz: <amount> Hz
keybindings: keybindings:
title: Atajos de teclado title: Atajos de teclado
hint: "Pista: ¡Asegúrate de usar CTRL, SHIFT y ALT! Habilitan distintas opciones hint: "Pista: ¡Asegúrate de usar CTRL, SHIFT y ALT! Habilitan distintas opciones
@ -1128,6 +1134,7 @@ keybindings:
goal_acceptor: Goal Acceptor goal_acceptor: Goal Acceptor
block: Block block: Block
massSelectClear: Clear belts massSelectClear: Clear belts
showShapeTooltip: Show shape output tooltip
about: about:
title: Sobre el juego title: Sobre el juego
body: >- body: >-
@ -1244,22 +1251,22 @@ puzzleMenu:
levels: Niveles levels: Niveles
new: Nuevos new: Nuevos
top-rated: Los mejor valorados top-rated: Los mejor valorados
mine: Mis Puzles mine: Mios
easy: Fáciles easy: Fáciles
hard: Difíciles hard: Difíciles
completed: Completados completed: Completados
medium: Medium medium: Medios
official: Official official: Oficiales
trending: Trending today trending: Tendencias de hoy
trending-weekly: Trending weekly trending-weekly: Tendencias de la semana
categories: Categories categories: Categorías
difficulties: By Difficulty difficulties: Por dificultad
account: My Puzzles account: Mis puzles
search: Search search: Buscar
validation: validation:
title: Puzle no válido title: Puzle no válido
noProducers: Por favor, ¡pon un Productor de una sola pieza! noProducers: Por favor, ¡Pon un Productor de una sola pieza!
noGoalAcceptors: Por favor , ¡pon un Aceptador de objetivos! noGoalAcceptors: Por favor, ¡Pon un Aceptador de objetivos!
goalAcceptorNoItem: Uno o más aceptadores de objetivos no tienen asignado un goalAcceptorNoItem: Uno o más aceptadores de objetivos no tienen asignado un
elemento. Transporta una forma hacia ellos para poner un objetivo. elemento. Transporta una forma hacia ellos para poner un objetivo.
goalAcceptorRateNotMet: Uno o más aceptadores de objetivos no están recibiendo goalAcceptorRateNotMet: Uno o más aceptadores de objetivos no están recibiendo
@ -1271,11 +1278,26 @@ puzzleMenu:
solo elemento no están conectados directamente a tus aceptadores de solo elemento no están conectados directamente a tus aceptadores de
objetivos. objetivos.
difficulties: difficulties:
easy: Easy easy: Fácil
medium: Medium medium: Medio
hard: Hard hard: Dificil
dlcHint: Purchased the DLC already? Make sure it is activated by right clicking unknown: Unrated
shapez.io in your library, selecting Properties > DLCs. dlcHint: ¿Ya compraste el DLC? Asegurate de tenerlo activado haciendo click
derecho a shapez.io en tu biblioteca, selecionando propiedades > DLCs.
search:
action: Search
placeholder: Enter a puzzle or author name
includeCompleted: Include Completed
difficulties:
any: Any Difficulty
easy: Easy
medium: Medium
hard: Hard
durations:
any: Any Duration
short: Short (< 2 min)
medium: Normal
long: Long (> 10 min)
backendErrors: backendErrors:
ratelimit: Estás haciendo tus acciones con demasiada frecuencia. Por favor, ratelimit: Estás haciendo tus acciones con demasiada frecuencia. Por favor,
espera un poco. espera un poco.
@ -1289,7 +1311,7 @@ backendErrors:
not-found: No pudimos encontrar ese puzle. not-found: No pudimos encontrar ese puzle.
bad-category: No pudimos encontar esa categoría. bad-category: No pudimos encontar esa categoría.
bad-short-key: La clave que nos diste no es válida. bad-short-key: La clave que nos diste no es válida.
profane-title: El título de tu puzle contiene lenguaje soez. profane-title: El título de tu puzle contiene lenguaje profano.
bad-title-too-many-spaces: El título de tu puzle es demasiado breve. bad-title-too-many-spaces: El título de tu puzle es demasiado breve.
bad-shape-key-in-emitter: Un productor de un solo elemento tiene un elemento no válido. bad-shape-key-in-emitter: Un productor de un solo elemento tiene un elemento no válido.
bad-shape-key-in-goal: Un aceptador de objetivos tiene un elemento no válido. bad-shape-key-in-goal: Un aceptador de objetivos tiene un elemento no válido.
@ -1300,6 +1322,7 @@ backendErrors:
bad-payload: La petición contiene datos no válidos. bad-payload: La petición contiene datos no válidos.
bad-building-placement: Tu puzle contiene edificios en posiciones no válidas. bad-building-placement: Tu puzle contiene edificios en posiciones no válidas.
timeout: El tiempo para la solicitud ha expirado. timeout: El tiempo para la solicitud ha expirado.
too-many-likes-already: The puzzle alreay got too many likes. If you still want too-many-likes-already: El puzle ha recibido demasiados me gusta ¡Si todavía
to remove it, please contact support@shapez.io! quieres eliminarlo, por favor contacta a support@shapez.io! (Solo
no-permission: You do not have the permission to perform this action. inglés)
no-permission: No tienes los permisos necesarios para llevar a cabo esta acción.

View File

@ -458,6 +458,7 @@ ingame:
titleRatingDesc: Your rating will help me to make you better suggestions in the future titleRatingDesc: Your rating will help me to make you better suggestions in the future
continueBtn: Keep Playing continueBtn: Keep Playing
menuBtn: Menu menuBtn: Menu
nextPuzzle: Next Puzzle
puzzleMetadata: puzzleMetadata:
author: Author author: Author
shortKey: Short Key shortKey: Short Key
@ -1004,7 +1005,12 @@ settings:
mapResourcesScale: mapResourcesScale:
title: Kartan resurssien koko title: Kartan resurssien koko
description: Määrittää muotojen koon kartalla (loitonnettaessa). description: Määrittää muotojen koon kartalla (loitonnettaessa).
shapeTooltipAlwaysOn:
title: Shape Tooltip - Show Always
description: Whether to always show the shape tooltip when hovering buildings,
instead of having to hold 'ALT'.
rangeSliderPercentage: <amount> % rangeSliderPercentage: <amount> %
tickrateHz: <amount> Hz
keybindings: keybindings:
title: Pikanäppäimet title: Pikanäppäimet
hint: "Vinkki: Muista käyttää CTRL, SHIFT ja ALT! Ne ottavat käyttöön erilaisia hint: "Vinkki: Muista käyttää CTRL, SHIFT ja ALT! Ne ottavat käyttöön erilaisia
@ -1086,6 +1092,7 @@ keybindings:
goal_acceptor: Goal Acceptor goal_acceptor: Goal Acceptor
block: Block block: Block
massSelectClear: Clear belts massSelectClear: Clear belts
showShapeTooltip: Show shape output tooltip
about: about:
title: Tietoja tästä pelistä title: Tietoja tästä pelistä
body: >- body: >-
@ -1214,8 +1221,23 @@ puzzleMenu:
easy: Easy easy: Easy
medium: Medium medium: Medium
hard: Hard hard: Hard
unknown: Unrated
dlcHint: Purchased the DLC already? Make sure it is activated by right clicking dlcHint: Purchased the DLC already? Make sure it is activated by right clicking
shapez.io in your library, selecting Properties > DLCs. shapez.io in your library, selecting Properties > DLCs.
search:
action: Search
placeholder: Enter a puzzle or author name
includeCompleted: Include Completed
difficulties:
any: Any Difficulty
easy: Easy
medium: Medium
hard: Hard
durations:
any: Any Duration
short: Short (< 2 min)
medium: Normal
long: Long (> 10 min)
backendErrors: backendErrors:
ratelimit: You are performing your actions too frequent. Please wait a bit. ratelimit: You are performing your actions too frequent. Please wait a bit.
invalid-api-key: Failed to communicate with the backend, please try to invalid-api-key: Failed to communicate with the backend, please try to

View File

@ -11,14 +11,14 @@ steamPage:
Et en plus, vous devrez aussi produire de plus en plus pour satisfaire la demande. La seule solution est de construire en plus grand! Au début vous ne ferez que découper les formes, mais plus tard vous devrez les peindre  et pour ça vous devrez extraire et mélanger des couleurs! Et en plus, vous devrez aussi produire de plus en plus pour satisfaire la demande. La seule solution est de construire en plus grand! Au début vous ne ferez que découper les formes, mais plus tard vous devrez les peindre  et pour ça vous devrez extraire et mélanger des couleurs!
En achetant le jeu sur Steam, vous aurez accès à la version complète, mais vous pouvez aussi jouer à une démo sur shapez.io et vous décider ensuite! En achetant le jeu sur Steam, vous aurez accès à la version complète, mais vous pouvez aussi jouer à une démo sur shapez.io et vous décider ensuite!
what_others_say: Ce que les gens pensent de shapez.io what_others_say: Ce que les gens pensent de Shapez.io
nothernlion_comment: This game is great - I'm having a wonderful time playing, nothernlion_comment: Ce jeu est génial - Je passe un merveilleux moment à jouer,
and time has flown by. et le temps s'est envolé.
notch_comment: Mince ! Je devrais vraiment me coucher, mais je crois que j'ai notch_comment: Mince ! Je devrais vraiment me coucher, mais je crois que j'ai
trouvé comment faire un ordinateur dans shapez.io trouvé comment faire un ordinateur dans Shapez.io
steam_review_comment: This game has stolen my life and I don't want it back. steam_review_comment: Ce jeu a volé ma vie et je ne veux pas la récupérer. Jeu
Very chill factory game that won't let me stop making my lines more d'usine très cool qui ne me laissera pas arrêter de rendre mes lignes
efficient. plus efficaces.
global: global:
loading: Chargement loading: Chargement
error: Erreur error: Erreur
@ -71,11 +71,11 @@ mainMenu:
savegameLevel: Niveau <x> savegameLevel: Niveau <x>
savegameLevelUnknown: Niveau inconnu savegameLevelUnknown: Niveau inconnu
savegameUnnamed: Sans titre savegameUnnamed: Sans titre
puzzleMode: Puzzle Mode puzzleMode: Mode Puzzle
back: Back back: Retour
puzzleDlcText: Vous aimez compacter et optimiser vos usines ? Achetez le DLC sur puzzleDlcText: Vous aimez compacter et optimiser vos usines ? Achetez le DLC sur
Steam dés maintenant pour encore plus d'amusement ! Steam dès maintenant pour encore plus d'amusement!
puzzleDlcWishlist: Wishlist now! puzzleDlcWishlist: Ajoute à ta liste de souhaits maintenant !
puzzleDlcViewNow: View Dlc puzzleDlcViewNow: View Dlc
dialogs: dialogs:
buttons: buttons:
@ -90,7 +90,7 @@ dialogs:
viewUpdate: Voir les mises à jour viewUpdate: Voir les mises à jour
showUpgrades: Montrer les améliorations showUpgrades: Montrer les améliorations
showKeybindings: Montrer les raccourcis showKeybindings: Montrer les raccourcis
retry: Réesayer retry: Réessayer
continue: Continuer continue: Continuer
playOffline: Jouer Hors-ligne playOffline: Jouer Hors-ligne
importSavegameError: importSavegameError:
@ -200,63 +200,66 @@ dialogs:
desc: "Malheuresement, le puzzle n'a pas pu être chargé :" desc: "Malheuresement, le puzzle n'a pas pu être chargé :"
submitPuzzle: submitPuzzle:
title: Envoyer le Puzzle title: Envoyer le Puzzle
descName: "Donnez un nom à votre puzzle :" descName: "Donnez un nom à votre puzzle:"
descIcon: "Please enter a unique short key, which will be shown as the icon of descIcon: "Veuillez entrer un raccourci de forme unique, qui sera affichée comme
your puzzle (You can generate them <link>here</link>, or choose one icône de votre puzzle (Vous pouvez générer le raccourci d'une forme
of the randomly suggested shapes below):" <link>ici</link>, ou en choisir une parmi les formes suggérées
placeholderName: Puzzle Title alétoirement ci-dessous):"
placeholderName: Titre du Puzzle
puzzleResizeBadBuildings: puzzleResizeBadBuildings:
title: Resize not possible title: Impossible de redimensionner
desc: You can't make the zone any smaller, because then some buildings would be desc: Vous ne pouvez pas rétrécir la zone, car certains bâtiments seraient en
outside the zone. dehors de la zone
puzzleLoadError: puzzleLoadError:
title: Mauvais Puzzle title: Mauvais Puzzle
desc: "Le chargement du puzzle a échoué :" desc: "Le chargement du puzzle a échoué:"
offlineMode: offlineMode:
title: Mode hors-ligne title: Mode hors-ligne
desc: We couldn't reach the servers, so the game has to run in offline mode. desc: Nous n'avons pas pu atteindre les serveurs, donc le jeu doit être mis en
Please make sure you have an active internet connection. mode hors ligne. Veuillez vous assurez que vous disposez d'une
connexion Internet active.
puzzleDownloadError: puzzleDownloadError:
title: Erreur de téléchargment title: Erreur de téléchargment
desc: "Le téléchargement à échoué :" desc: "Le téléchargement a échoué:"
puzzleSubmitError: puzzleSubmitError:
title: Erreur d'envoi title: Erreur d'envoi
desc: "L'envoi à échoué :" desc: "L'envoi a échoué:"
puzzleSubmitOk: puzzleSubmitOk:
title: Puzzle envoyé title: Puzzle envoyé
desc: Félicitation ! Votre puzzle à été envoyé et peut maintenant être joué. desc: Félicitations ! Votre puzzle a été envoyé et peut maintenant être joué.
Vous pouvez maintenant le retrouver dans la section "Mes Puzzles". Vous pouvez maintenant le retrouver dans la section "Mes Puzzles".
puzzleCreateOffline: puzzleCreateOffline:
title: Mode Hors-ligne title: Mode Hors-ligne
desc: Since you are offline, you will not be able to save and/or publish your desc: Puisque vous êtes hors ligne, vous ne pourrez pas enregistrer et/ou
puzzle. Would you still like to continue? publier votre puzzle. Souhaitez-vous toujours continuer ?
puzzlePlayRegularRecommendation: puzzlePlayRegularRecommendation:
title: Recommendation title: Recommandation
desc: I <strong>strongly</strong> recommend playing the normal game to level 12 desc: Je recommande <strong>fortement</strong> de jouer au jeu normal jusqu'au
before attempting the puzzle DLC, otherwise you may encounter niveau 12 avant d'essayer le Puzzle DLC, sinon vous risqez de
mechanics not yet introduced. Do you still want to continue? rencontrer des méchanismes pas encore introduits. Voulez-vous
toujours continuer ?
puzzleShare: puzzleShare:
title: Short Key Copied title: Code copié
desc: The short key of the puzzle (<key>) has been copied to your clipboard! It desc: Le code du puzzle (<key>) a été copié dans ton presse-papiers ! Il peut
can be entered in the puzzle menu to access the puzzle. être entré dans le menu des puzzles pour accéder au puzzle.
puzzleReport: puzzleReport:
title: Report Puzzle title: Signaler le Puzzle
options: options:
profane: Profane profane: Profane
unsolvable: Not solvable unsolvable: Irrésolvable
trolling: Trolling trolling: Troll
puzzleReportComplete: puzzleReportComplete:
title: Merci pour votre retour ! title: Merci pour votre retour!
desc: Le puzzle a été marqué. desc: Le puzzle a été marqué.
puzzleReportError: puzzleReportError:
title: Failed to report title: Échec du signalement
desc: "Your report could not get processed:" desc: "Votre signalement n'a pas pu être effectué:"
puzzleLoadShortKey: puzzleLoadShortKey:
title: Enter short key title: Entrer un code
desc: Enter the short key of the puzzle to load it. desc: Entrer le code du puzzle pour le charger.
puzzleDelete: puzzleDelete:
title: Delete Puzzle? title: Supprimer le puzzle ?
desc: Are you sure you want to delete '<title>'? This can not be undone! desc: Êtes-vous sûr de vouloir supprimer '<title>' ? Cela sera irréversible !
ingame: ingame:
keybindingsOverlay: keybindingsOverlay:
moveMap: Déplacer moveMap: Déplacer
@ -430,28 +433,30 @@ ingame:
title: Me soutenir title: Me soutenir
desc: Je le développe pendant mon temps libre! desc: Je le développe pendant mon temps libre!
achievements: achievements:
title: Achievements title: Succès
desc: Hunt them all! desc: Débloquez-les tous !
puzzleEditorSettings: puzzleEditorSettings:
zoneTitle: Zone zoneTitle: Zone
zoneWidth: Width zoneWidth: Largeur
zoneHeight: Height zoneHeight: Hauteur
trimZone: Trim trimZone: Optimiser la taille
clearItems: Clear Items clearItems: Supprimer les objets
share: Share share: Partager
report: Report report: Signaler
clearBuildings: Clear Buildings clearBuildings: Clear Buildings
resetPuzzle: Reset Puzzle resetPuzzle: Reset Puzzle
puzzleEditorControls: puzzleEditorControls:
title: Puzzle Creator title: Créateur de Puzzles
instructions: instructions:
- 1. Place <strong>Constant Producers</strong> to provide shapes and - 1. Placez des <strong>Producteurs Constants</strong> pour fournir
colors to the player des formes et des couleurs au joueur
- 2. Build one or more shapes you want the player to build later and - 2. Fabriquez une ou plusieurs formes que vous voulez que le joueur
deliver it to one or more <strong>Goal Acceptors</strong> fabrique plus tard et délivrez-la/les à un ou plusieurs
- 3. Once a Goal Acceptor receives a shape for a certain amount of <strong>Récepteurs d'Objectif</strong>
time, it <strong>saves it as a goal</strong> that the player must - 3. Une fois qu'un Récépteur d'Objectif a reçu une forme pendant un
produce later (Indicated by the <strong>green badge</strong>). certain temps, il <strong>l'enregistre zn tant
qu'objectif</strong> que le joueur devra produire plus tard
(Indiqué par le <strong>badge vert</strong>).
- 4. Click the <strong>lock button</strong> on a building to disable - 4. Click the <strong>lock button</strong> on a building to disable
it. it.
- 5. Once you click review, your puzzle will be validated and you - 5. Once you click review, your puzzle will be validated and you
@ -460,18 +465,19 @@ ingame:
except for the Producers and Goal Acceptors - That's the part that except for the Producers and Goal Acceptors - That's the part that
the player is supposed to figure out for themselves, after all :) the player is supposed to figure out for themselves, after all :)
puzzleCompletion: puzzleCompletion:
title: Puzzle Completed! title: Puzzle Résolu !
titleLike: "Click the heart if you liked the puzzle:" titleLike: "Cliquez sur le cœur si vous avez aimé le Puzzle:"
titleRating: How difficult did you find the puzzle? titleRating: À quel point avez-vous trouvé le puzzle diffcile ?
titleRatingDesc: Your rating will help me to make you better suggestions in the future titleRatingDesc: Votre note m'aidera à vous faire de meilleures suggestions à l'avenir
continueBtn: Keep Playing continueBtn: Continuer à jouer
menuBtn: Menu menuBtn: Menu
nextPuzzle: Next Puzzle
puzzleMetadata: puzzleMetadata:
author: Author author: Auteur
shortKey: Short Key shortKey: Short Key
rating: Difficulty score rating: Niveau de difficulté
averageDuration: Avg. Duration averageDuration: Durée moyenne
completionRate: Completion rate completionRate: Taux de réussite
shopUpgrades: shopUpgrades:
belt: belt:
name: Convoyeurs, distributeurs et tunnels name: Convoyeurs, distributeurs et tunnels
@ -691,25 +697,26 @@ buildings:
calque de câblage sur le calque normal. calque de câblage sur le calque normal.
constant_producer: constant_producer:
default: default:
name: Constant Producer name: Producteur Constabnt
description: Constantly outputs a specified shape or color. description: Sort constamment une forme ou une couleur spécifiée.
goal_acceptor: goal_acceptor:
default: default:
name: Goal Acceptor name: Récepteur d'Objetcif
description: Deliver shapes to the goal acceptor to set them as a goal. description: Délivrez des formes au récepteur d'objectif pour les définir comme
objectif.
block: block:
default: default:
name: Block name: Bloc
description: Allows you to block a tile. description: Permet de bloquer une case.
storyRewards: storyRewards:
reward_cutter_and_trash: reward_cutter_and_trash:
title: Découpage de formes title: Découpage de formes
desc: You just unlocked the <strong>cutter</strong>, which cuts shapes in half desc: Vous venez de déverrouiller le <strong>découpeur</strong>, qui coupe les
from top to bottom <strong>regardless of its formes en deux de haut en bas <strong>indépendamment de son
orientation</strong>!<br><br>Be sure to get rid of the waste, or orientation</strong>!<br><br>Assurez-vous de vous débarrasser des
otherwise <strong>it will clog and stall</strong> - For this purpose déchets, ou sinon <strong>il se bouchera et se bloquera</strong> - À
I have given you the <strong>trash</strong>, which destroys cet effet, Je vous ai donné la <strong>poubelle</strong>, qui
everything you put into it! détruit tout ce que vous mettez dedans !
reward_rotater: reward_rotater:
title: Rotation title: Rotation
desc: Le <strong>pivoteur</strong> a été débloqué! Il pivote les formes de 90 desc: Le <strong>pivoteur</strong> a été débloqué! Il pivote les formes de 90
@ -735,9 +742,10 @@ storyRewards:
<strong>placée au-dessus</strong> de la forme de gauche. <strong>placée au-dessus</strong> de la forme de gauche.
reward_balancer: reward_balancer:
title: Répartiteur title: Répartiteur
desc: The multifunctional <strong>balancer</strong> has been unlocked - It can desc: Le <strong>répartiteur</strong> multifonctionnel a été débloqué - Il peut
be used to build bigger factories by <strong>splitting and merging être utilisé pour construire de plus grandes usines en
items</strong> onto multiple belts! <strong>divisant et en rassemblant des objets</strong> sur plusieurs
convoyeurs !
reward_tunnel: reward_tunnel:
title: Tunnel title: Tunnel
desc: Le <strong>tunnel</strong> a été débloqué. Vous pouvez maintenant faire desc: Le <strong>tunnel</strong> a été débloqué. Vous pouvez maintenant faire
@ -843,14 +851,17 @@ storyRewards:
gâteau : je vous donne aussi le <strong>transistor</strong>!" gâteau : je vous donne aussi le <strong>transistor</strong>!"
reward_virtual_processing: reward_virtual_processing:
title: Traitement virtuel title: Traitement virtuel
desc: I just gave a whole bunch of new buildings which allow you to desc: Je viens de vous donner tout un tas de nouveaux bâtiments qui vous
<strong>simulate the processing of shapes</strong>!<br><br> You can permettent de <strong>simuler le traitement des
now simulate a cutter, rotator, stacker and more on the wires layer! formes</strong>!<br><br> Vous pouvez maintenant simuler un
With this you now have three options to continue the game:<br><br> - découpeur, un pivoteur, un assembleur et plus encore sur la couche
Build an <strong>automated machine</strong> to create any possible des fils ! Avec cela vous avez maintenant trois options pour
shape requested by the HUB (I recommend to try it!).<br><br> - Build continuer le jeu:<br><br> - Construire une <strong>machine
something cool with wires.<br><br> - Continue to play automatique</strong> pour créer toute forme possible demandée par le
normally.<br><br> Whatever you choose, remember to have fun! HUB (Je recommande d'essayer de le faire !).<br><br> - Construire
quelque chose de cool avec les fils.<br><br> - Continuer à jouer
normalement.<br><br> Quoi que vous choisissiez, n'oubliez pas de
vous amuser !
no_reward: no_reward:
title: Niveau suivant title: Niveau suivant
desc: "Ce niveau na pas de récompense mais le prochain, si!<br><br> PS : Ne desc: "Ce niveau na pas de récompense mais le prochain, si!<br><br> PS : Ne
@ -1049,6 +1060,11 @@ settings:
title: Taille des ressources sur la carte title: Taille des ressources sur la carte
description: Contrôle la taille des formes sur la vue densemble de la carte description: Contrôle la taille des formes sur la vue densemble de la carte
visible en dézoomant. visible en dézoomant.
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
keybindings: keybindings:
title: Contrôles title: Contrôles
hint: "Astuce : Noubliez pas dutiliser CTRL, MAJ et ALT! Ces touches activent hint: "Astuce : Noubliez pas dutiliser CTRL, MAJ et ALT! Ces touches activent
@ -1127,10 +1143,11 @@ keybindings:
rotateToDown: "Rotate: Point Down" rotateToDown: "Rotate: Point Down"
rotateToRight: "Rotate: Point Right" rotateToRight: "Rotate: Point Right"
rotateToLeft: "Rotate: Point Left" rotateToLeft: "Rotate: Point Left"
constant_producer: Constant Producer constant_producer: Producteur Constant
goal_acceptor: Goal Acceptor goal_acceptor: Récepteur d'Objectif
block: Block block: Bloc
massSelectClear: Clear belts massSelectClear: Vider les convoyeurs
showShapeTooltip: Show shape output tooltip
about: about:
title: À propos de ce jeu title: À propos de ce jeu
body: >- body: >-
@ -1156,7 +1173,7 @@ demo:
exportingBase: Exporter une image de toute la base exportingBase: Exporter une image de toute la base
settingNotAvailable: Indisponible dans la démo. settingNotAvailable: Indisponible dans la démo.
tips: tips:
- Le centre nimporte quelle forme, pas seulement la forme actuelle! - Le centre accepte nimporte quelle forme, pas seulement la forme actuelle!
- Assurez-vous que vos usines soient modulaires, cela paiera! - Assurez-vous que vos usines soient modulaires, cela paiera!
- Ne construisez pas trop près du centre, ou ce sera un énorme chaos! - Ne construisez pas trop près du centre, ou ce sera un énorme chaos!
- Si lempilement ne fonctionne pas, essayez déchanger les entrées. - Si lempilement ne fonctionne pas, essayez déchanger les entrées.
@ -1237,7 +1254,7 @@ puzzleMenu:
edit: Éditer edit: Éditer
title: Mode Puzzle title: Mode Puzzle
createPuzzle: Créer un Puzzle createPuzzle: Créer un Puzzle
loadPuzzle: charger loadPuzzle: Charger
reviewPuzzle: Revoir & Publier reviewPuzzle: Revoir & Publier
validatingPuzzle: Validation du Puzzle validatingPuzzle: Validation du Puzzle
submittingPuzzle: Publication du Puzzle submittingPuzzle: Publication du Puzzle
@ -1245,19 +1262,19 @@ puzzleMenu:
categories: categories:
levels: Niveaux levels: Niveaux
new: Nouveau new: Nouveau
top-rated: Les-mieux notés top-rated: Les mieux notés
mine: Mes puzzles mine: Mes puzzles
easy: Facile easy: Facile
hard: Difficile hard: Difficile
completed: Complété completed: Complété
medium: Medium medium: Medium
official: Official official: Officiel
trending: Trending today trending: Trending today
trending-weekly: Trending weekly trending-weekly: Trending weekly
categories: Categories categories: Catégories
difficulties: By Difficulty difficulties: Par Difficulté
account: My Puzzles account: Mes Puzzles
search: Search search: Rechercher
validation: validation:
title: Puzzle invalide title: Puzzle invalide
noProducers: Veuillez placer un producteur constant ! noProducers: Veuillez placer un producteur constant !
@ -1276,8 +1293,23 @@ puzzleMenu:
easy: Easy easy: Easy
medium: Medium medium: Medium
hard: Hard hard: Hard
unknown: Unrated
dlcHint: Purchased the DLC already? Make sure it is activated by right clicking dlcHint: Purchased the DLC already? Make sure it is activated by right clicking
shapez.io in your library, selecting Properties > DLCs. shapez.io in your library, selecting Properties > DLCs.
search:
action: Search
placeholder: Enter a puzzle or author name
includeCompleted: Include Completed
difficulties:
any: Any Difficulty
easy: Easy
medium: Medium
hard: Hard
durations:
any: Any Duration
short: Short (< 2 min)
medium: Normal
long: Long (> 10 min)
backendErrors: backendErrors:
ratelimit: Vous effectuez vos actions trop fréquemment. Veuillez attendre un peu ratelimit: Vous effectuez vos actions trop fréquemment. Veuillez attendre un peu
s'il vous plait. s'il vous plait.
@ -1302,6 +1334,6 @@ backendErrors:
bad-payload: La demande contient des données invalides. bad-payload: La demande contient des données invalides.
bad-building-placement: Votre puzzle contient des bâtiments placés non valides. bad-building-placement: Votre puzzle contient des bâtiments placés non valides.
timeout: La demande a expiré. timeout: La demande a expiré.
too-many-likes-already: The puzzle alreay got too many likes. If you still want too-many-likes-already: The puzzle already got too many likes. If you still want
to remove it, please contact support@shapez.io! to remove it, please contact support@shapez.io!
no-permission: You do not have the permission to perform this action. no-permission: You do not have the permission to perform this action.

View File

@ -444,6 +444,7 @@ ingame:
titleRatingDesc: Your rating will help me to make you better suggestions in the future titleRatingDesc: Your rating will help me to make you better suggestions in the future
continueBtn: Keep Playing continueBtn: Keep Playing
menuBtn: Menu menuBtn: Menu
nextPuzzle: Next Puzzle
puzzleMetadata: puzzleMetadata:
author: Author author: Author
shortKey: Short Key shortKey: Short Key
@ -952,6 +953,11 @@ settings:
mapResourcesScale: mapResourcesScale:
title: גודל המשאבים במפה title: גודל המשאבים במפה
description: .שולט על הגודל של הצורות על המפה (בתצוגה המוקטנת) 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
keybindings: keybindings:
title: מקשים title: מקשים
hint: ".הם מאפשרים הרבה אפשרויות השמה !ALTו SHIFT ,CTRLטיפ: השתמש ב" hint: ".הם מאפשרים הרבה אפשרויות השמה !ALTו SHIFT ,CTRLטיפ: השתמש ב"
@ -1032,6 +1038,7 @@ keybindings:
goal_acceptor: Goal Acceptor goal_acceptor: Goal Acceptor
block: Block block: Block
massSelectClear: Clear belts massSelectClear: Clear belts
showShapeTooltip: Show shape output tooltip
about: about:
title: בנוגע למשחק הזה title: בנוגע למשחק הזה
body: >- body: >-
@ -1157,8 +1164,23 @@ puzzleMenu:
easy: Easy easy: Easy
medium: Medium medium: Medium
hard: Hard hard: Hard
unknown: Unrated
dlcHint: Purchased the DLC already? Make sure it is activated by right clicking dlcHint: Purchased the DLC already? Make sure it is activated by right clicking
shapez.io in your library, selecting Properties > DLCs. shapez.io in your library, selecting Properties > DLCs.
search:
action: Search
placeholder: Enter a puzzle or author name
includeCompleted: Include Completed
difficulties:
any: Any Difficulty
easy: Easy
medium: Medium
hard: Hard
durations:
any: Any Duration
short: Short (< 2 min)
medium: Normal
long: Long (> 10 min)
backendErrors: backendErrors:
ratelimit: You are performing your actions too frequent. Please wait a bit. ratelimit: You are performing your actions too frequent. Please wait a bit.
invalid-api-key: Failed to communicate with the backend, please try to invalid-api-key: Failed to communicate with the backend, please try to

View File

@ -458,6 +458,7 @@ ingame:
titleRatingDesc: Your rating will help me to make you better suggestions in the future titleRatingDesc: Your rating will help me to make you better suggestions in the future
continueBtn: Keep Playing continueBtn: Keep Playing
menuBtn: Menu menuBtn: Menu
nextPuzzle: Next Puzzle
puzzleMetadata: puzzleMetadata:
author: Author author: Author
shortKey: Short Key shortKey: Short Key
@ -998,7 +999,12 @@ settings:
title: Map Resources Size title: Map Resources Size
description: Controls the size of the shapes on the map overview (when zooming description: Controls the size of the shapes on the map overview (when zooming
out). out).
shapeTooltipAlwaysOn:
title: Shape Tooltip - Show Always
description: Whether to always show the shape tooltip when hovering buildings,
instead of having to hold 'ALT'.
rangeSliderPercentage: <amount> % rangeSliderPercentage: <amount> %
tickrateHz: <amount> Hz
keybindings: keybindings:
title: Tipka title: Tipka
hint: "Savjet: Be sure to make use of CTRL, SHIFT and ALT! They enable different hint: "Savjet: Be sure to make use of CTRL, SHIFT and ALT! They enable different
@ -1080,6 +1086,7 @@ keybindings:
goal_acceptor: Goal Acceptor goal_acceptor: Goal Acceptor
block: Block block: Block
massSelectClear: Clear belts massSelectClear: Clear belts
showShapeTooltip: Show shape output tooltip
about: about:
title: O Igri title: O Igri
body: >- body: >-
@ -1207,8 +1214,23 @@ puzzleMenu:
easy: Easy easy: Easy
medium: Medium medium: Medium
hard: Hard hard: Hard
unknown: Unrated
dlcHint: Purchased the DLC already? Make sure it is activated by right clicking dlcHint: Purchased the DLC already? Make sure it is activated by right clicking
shapez.io in your library, selecting Properties > DLCs. shapez.io in your library, selecting Properties > DLCs.
search:
action: Search
placeholder: Enter a puzzle or author name
includeCompleted: Include Completed
difficulties:
any: Any Difficulty
easy: Easy
medium: Medium
hard: Hard
durations:
any: Any Duration
short: Short (< 2 min)
medium: Normal
long: Long (> 10 min)
backendErrors: backendErrors:
ratelimit: You are performing your actions too frequent. Please wait a bit. ratelimit: You are performing your actions too frequent. Please wait a bit.
invalid-api-key: Failed to communicate with the backend, please try to invalid-api-key: Failed to communicate with the backend, please try to

View File

@ -464,6 +464,7 @@ ingame:
jövőben jövőben
continueBtn: Játék Folytatása continueBtn: Játék Folytatása
menuBtn: Menü menuBtn: Menü
nextPuzzle: Next Puzzle
puzzleMetadata: puzzleMetadata:
author: Szerző author: Szerző
shortKey: Gyorskód shortKey: Gyorskód
@ -1025,7 +1026,12 @@ settings:
title: Erőforrások Mérete a Térképen title: Erőforrások Mérete a Térképen
description: Kizoomolt állapotban a térképen megjelenő erőforrások (alakzatok és description: Kizoomolt állapotban a térképen megjelenő erőforrások (alakzatok és
színek) méretét állítja. színek) méretét állítja.
shapeTooltipAlwaysOn:
title: Shape Tooltip - Show Always
description: Whether to always show the shape tooltip when hovering buildings,
instead of having to hold 'ALT'.
rangeSliderPercentage: <amount> % rangeSliderPercentage: <amount> %
tickrateHz: <amount> Hz
keybindings: keybindings:
title: Gyorsbillentyűk title: Gyorsbillentyűk
hint: "Tipp: Használd ki a CTRL, SHIFT és ALT billentyűket, amelyek különféle hint: "Tipp: Használd ki a CTRL, SHIFT és ALT billentyűket, amelyek különféle
@ -1107,6 +1113,7 @@ keybindings:
goal_acceptor: Elfogadó goal_acceptor: Elfogadó
block: Blokkolás block: Blokkolás
massSelectClear: Futószalagok Kiürítése massSelectClear: Futószalagok Kiürítése
showShapeTooltip: Show shape output tooltip
about: about:
title: A Játékról title: A Játékról
body: >- body: >-
@ -1242,8 +1249,23 @@ puzzleMenu:
easy: Easy easy: Easy
medium: Medium medium: Medium
hard: Hard hard: Hard
unknown: Unrated
dlcHint: Purchased the DLC already? Make sure it is activated by right clicking dlcHint: Purchased the DLC already? Make sure it is activated by right clicking
shapez.io in your library, selecting Properties > DLCs. shapez.io in your library, selecting Properties > DLCs.
search:
action: Search
placeholder: Enter a puzzle or author name
includeCompleted: Include Completed
difficulties:
any: Any Difficulty
easy: Easy
medium: Medium
hard: Hard
durations:
any: Any Duration
short: Short (< 2 min)
medium: Normal
long: Long (> 10 min)
backendErrors: backendErrors:
ratelimit: Túl gyorsan csinálsz dolgokat. Kérlek, várj egy kicsit. ratelimit: Túl gyorsan csinálsz dolgokat. Kérlek, várj egy kicsit.
invalid-api-key: Valami nem oké a játékkal. Próbáld meg frissíteni vagy invalid-api-key: Valami nem oké a játékkal. Próbáld meg frissíteni vagy

View File

@ -467,6 +467,7 @@ ingame:
titleRatingDesc: Your rating will help me to make you better suggestions in the future titleRatingDesc: Your rating will help me to make you better suggestions in the future
continueBtn: Keep Playing continueBtn: Keep Playing
menuBtn: Menu menuBtn: Menu
nextPuzzle: Next Puzzle
puzzleMetadata: puzzleMetadata:
author: Author author: Author
shortKey: Short Key shortKey: Short Key
@ -1057,7 +1058,12 @@ settings:
title: Ukuran Sumber Daya Peta title: Ukuran Sumber Daya Peta
description: Mengontrol ukuran bentuk-bentuk pada gambaran peta (ketika zoom description: Mengontrol ukuran bentuk-bentuk pada gambaran peta (ketika zoom
out). out).
shapeTooltipAlwaysOn:
title: Shape Tooltip - Show Always
description: Whether to always show the shape tooltip when hovering buildings,
instead of having to hold 'ALT'.
rangeSliderPercentage: <amount> % rangeSliderPercentage: <amount> %
tickrateHz: <amount> Hz
keybindings: keybindings:
title: Tombol Pintas title: Tombol Pintas
hint: "Petunjuk: Pastikan kamu menggunakan CTRL, SHIFT and ALT! Mereka hint: "Petunjuk: Pastikan kamu menggunakan CTRL, SHIFT and ALT! Mereka
@ -1139,6 +1145,7 @@ keybindings:
goal_acceptor: Goal Acceptor goal_acceptor: Goal Acceptor
block: Block block: Block
massSelectClear: Clear belts massSelectClear: Clear belts
showShapeTooltip: Show shape output tooltip
about: about:
title: Tentang permainan ini title: Tentang permainan ini
body: >- body: >-
@ -1288,8 +1295,23 @@ puzzleMenu:
easy: Easy easy: Easy
medium: Medium medium: Medium
hard: Hard hard: Hard
unknown: Unrated
dlcHint: Purchased the DLC already? Make sure it is activated by right clicking dlcHint: Purchased the DLC already? Make sure it is activated by right clicking
shapez.io in your library, selecting Properties > DLCs. shapez.io in your library, selecting Properties > DLCs.
search:
action: Search
placeholder: Enter a puzzle or author name
includeCompleted: Include Completed
difficulties:
any: Any Difficulty
easy: Easy
medium: Medium
hard: Hard
durations:
any: Any Duration
short: Short (< 2 min)
medium: Normal
long: Long (> 10 min)
backendErrors: backendErrors:
ratelimit: You are performing your actions too frequent. Please wait a bit. ratelimit: You are performing your actions too frequent. Please wait a bit.
invalid-api-key: Failed to communicate with the backend, please try to invalid-api-key: Failed to communicate with the backend, please try to

View File

@ -447,7 +447,7 @@ ingame:
clearItems: Elimina oggetti clearItems: Elimina oggetti
share: Condividi share: Condividi
report: Segnala report: Segnala
clearBuildings: Clear Buildings clearBuildings: Cancella edifici
resetPuzzle: Reset Puzzle resetPuzzle: Reset Puzzle
puzzleEditorControls: puzzleEditorControls:
title: Creazione puzzle title: Creazione puzzle
@ -477,6 +477,7 @@ ingame:
in futuro in futuro
continueBtn: Continua a giocare continueBtn: Continua a giocare
menuBtn: Menù menuBtn: Menù
nextPuzzle: Puzzle successivo
puzzleMetadata: puzzleMetadata:
author: Autore author: Autore
shortKey: Codice shortKey: Codice
@ -745,7 +746,7 @@ storyRewards:
reward_rotater_ccw: reward_rotater_ccw:
title: Rotazione antioraria title: Rotazione antioraria
desc: Hai sbloccato una variante del <strong>ruotatore</strong>! Consente di desc: Hai sbloccato una variante del <strong>ruotatore</strong>! Consente di
ruotare in senso antiorario! Per costruirla, seleziona la ruotatrice ruotare in senso antiorario! Per costruirla, seleziona il ruotatore
e <strong>premi 'T' per cambiare variante</strong>! e <strong>premi 'T' per cambiare variante</strong>!
reward_miner_chainable: reward_miner_chainable:
title: Estrattore a catena title: Estrattore a catena
@ -823,7 +824,7 @@ storyRewards:
la portata di un nastro.<br><br>E aspetta di sbloccare i cavi, la portata di un nastro.<br><br>E aspetta di sbloccare i cavi,
allora sì che sarà molto utile! allora sì che sarà molto utile!
reward_rotater_180: reward_rotater_180:
title: Ruotatrice (180 gradi) title: Ruotatore (180 gradi)
desc: Hai appena sbloccato il <strong>ruotatore</strong> a 180 gradi! Consente desc: Hai appena sbloccato il <strong>ruotatore</strong> a 180 gradi! Consente
di ruotare una forma di 180 gradi (Sorpresa! :D) di ruotare una forma di 180 gradi (Sorpresa! :D)
reward_display: reward_display:
@ -833,7 +834,7 @@ storyRewards:
lettore di nastri e il magazzino mostrano l'ultimo oggetto da loro lettore di nastri e il magazzino mostrano l'ultimo oggetto da loro
letto? Prova a mostrarlo su di un display!" letto? Prova a mostrarlo su di un display!"
reward_constant_signal: reward_constant_signal:
title: Sengale costante title: Segnale costante
desc: Hai sbloccato l'edificio <strong>segnale costante</strong> sul livello desc: Hai sbloccato l'edificio <strong>segnale costante</strong> sul livello
elettrico! È utile collegarlo ai <strong>filtri di oggetti</strong> elettrico! È utile collegarlo ai <strong>filtri di oggetti</strong>
per esempio.<br><br> Il segnale costante può emettere una per esempio.<br><br> Il segnale costante può emettere una
@ -859,7 +860,7 @@ storyRewards:
normalmente. <br><br> Qualsiasi cosa tu scelga, ricordati di normalmente. <br><br> Qualsiasi cosa tu scelga, ricordati di
divertirti! divertirti!
reward_wires_painter_and_levers: reward_wires_painter_and_levers:
title: Cavi e Verniciatrice quadrupla title: Cavi e Verniciatore quadruplo
desc: "Hai appena sbloccato il <strong>Livello Elettrico</strong>: è un livello desc: "Hai appena sbloccato il <strong>Livello Elettrico</strong>: è un livello
separato dal livelo normale e introduce molte altre meccaniche di separato dal livelo normale e introduce molte altre meccaniche di
gioco!<br><br> Per il momento ti ho sbloccato il gioco!<br><br> Per il momento ti ho sbloccato il
@ -1048,7 +1049,12 @@ settings:
title: Grandezza delle Risorse sulla Mappa title: Grandezza delle Risorse sulla Mappa
description: Controlla la grandezza delle forme visualizzate sulla mappa (quando description: Controlla la grandezza delle forme visualizzate sulla mappa (quando
si fa lo zoom indietro). si fa lo zoom indietro).
shapeTooltipAlwaysOn:
title: Shape Tooltip - Show Always
description: Determina se mostrare sempre la forma in uscita da un edificio quando si passa sopra di esso col cursore,
invece di dover premere 'ALT'.
rangeSliderPercentage: <amount> % rangeSliderPercentage: <amount> %
tickrateHz: <amount> Hz
keybindings: keybindings:
title: Comandi title: Comandi
hint: "Suggerimento: Usa spesso CTRL, MAIUSC e ALT! Abilitano opzioni di hint: "Suggerimento: Usa spesso CTRL, MAIUSC e ALT! Abilitano opzioni di
@ -1065,7 +1071,7 @@ keybindings:
mappings: mappings:
confirm: Conferma confirm: Conferma
back: Indietro back: Indietro
mapMoveUp: Spostati sù mapMoveUp: Spostati su
mapMoveRight: Spostati a destra mapMoveRight: Spostati a destra
mapMoveDown: Spostati giù mapMoveDown: Spostati giù
mapMoveLeft: Spostati a sinistra mapMoveLeft: Spostati a sinistra
@ -1130,6 +1136,7 @@ keybindings:
goal_acceptor: Accettore di obiettivi goal_acceptor: Accettore di obiettivi
block: Blocco block: Blocco
massSelectClear: Sgombra nastri massSelectClear: Sgombra nastri
showShapeTooltip: Mostra forma di uscita di un edificio
about: about:
title: Riguardo questo gioco title: Riguardo questo gioco
body: >- body: >-
@ -1272,8 +1279,23 @@ puzzleMenu:
easy: Facile easy: Facile
medium: Medio medium: Medio
hard: Difficile hard: Difficile
dlcHint: Purchased the DLC already? Make sure it is activated by right clicking unknown: Non classificato
shapez.io in your library, selecting Properties > DLCs. dlcHint: Hai già acquistato il DLC? Assicurati che sia attivo facendo clic destro
su shapez.io nella tua libreria e selezionando Proprietà > DLC.
search:
action: Cerca
placeholder: Inserisci il nome di un puzzle o di un autore
includeCompleted: Include Completed
difficulties:
any: Qualsiasi difficoltà
easy: Facile
medium: Medio
hard: Difficile
durations:
any: Qualsiasi durata
short: Breve (< 2 minuti)
medium: Normale
long: Lunga (> 10 minuti)
backendErrors: backendErrors:
ratelimit: Stai facendo troppe azioni velocemente. Per favore attendi un attimo. ratelimit: Stai facendo troppe azioni velocemente. Per favore attendi un attimo.
invalid-api-key: Comunicazione con il backend fallita, per favore prova ad invalid-api-key: Comunicazione con il backend fallita, per favore prova ad

View File

@ -422,6 +422,7 @@ ingame:
titleRatingDesc: Your rating will help me to make you better suggestions in the future titleRatingDesc: Your rating will help me to make you better suggestions in the future
continueBtn: Keep Playing continueBtn: Keep Playing
menuBtn: Menu menuBtn: Menu
nextPuzzle: Next Puzzle
puzzleMetadata: puzzleMetadata:
author: Author author: Author
shortKey: Short Key shortKey: Short Key
@ -868,6 +869,11 @@ settings:
mapResourcesScale: mapResourcesScale:
title: 資源アイコンのサイズ title: 資源アイコンのサイズ
description: ズームアウトしたときの図形のサイズを調節します。 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
keybindings: keybindings:
title: キー設定 title: キー設定
hint: "Tip: CTRL, SHIFT, ALTを活用してください。建造物配置の際の追加機能がそれぞれ割り当てられています。" hint: "Tip: CTRL, SHIFT, ALTを活用してください。建造物配置の際の追加機能がそれぞれ割り当てられています。"
@ -948,6 +954,7 @@ keybindings:
goal_acceptor: Goal Acceptor goal_acceptor: Goal Acceptor
block: Block block: Block
massSelectClear: Clear belts massSelectClear: Clear belts
showShapeTooltip: Show shape output tooltip
about: about:
title: このゲームについて title: このゲームについて
body: >- body: >-
@ -1070,8 +1077,23 @@ puzzleMenu:
easy: Easy easy: Easy
medium: Medium medium: Medium
hard: Hard hard: Hard
unknown: Unrated
dlcHint: Purchased the DLC already? Make sure it is activated by right clicking dlcHint: Purchased the DLC already? Make sure it is activated by right clicking
shapez.io in your library, selecting Properties > DLCs. shapez.io in your library, selecting Properties > DLCs.
search:
action: Search
placeholder: Enter a puzzle or author name
includeCompleted: Include Completed
difficulties:
any: Any Difficulty
easy: Easy
medium: Medium
hard: Hard
durations:
any: Any Duration
short: Short (< 2 min)
medium: Normal
long: Long (> 10 min)
backendErrors: backendErrors:
ratelimit: You are performing your actions too frequent. Please wait a bit. ratelimit: You are performing your actions too frequent. Please wait a bit.
invalid-api-key: Failed to communicate with the backend, please try to invalid-api-key: Failed to communicate with the backend, please try to

View File

@ -58,8 +58,7 @@ mainMenu:
openSourceHint: 이 게임은 오픈 소스입니다! openSourceHint: 이 게임은 오픈 소스입니다!
discordLink: 공식 디스코드 서버 discordLink: 공식 디스코드 서버
helpTranslate: 번역을 도와주세요! helpTranslate: 번역을 도와주세요!
browserWarning: browserWarning: 이 게임은 현재 브라우저에서 느리게 작동하는 것으로 알려져 있습니다! 더 좋은 성능을 위해 정식 버전을 구매하거나
이 게임은 현재 브라우저에서 느리게 작동하는 것으로 알려져 있습니다! 더 좋은 성능을 위해 정식 버전을 구매하거나
Google Chrome 브라우저를 다운로드하세요. Google Chrome 브라우저를 다운로드하세요.
savegameLevel: 레벨 <x> savegameLevel: 레벨 <x>
savegameLevelUnknown: 미확인 레벨 savegameLevelUnknown: 미확인 레벨
@ -128,8 +127,7 @@ dialogs:
desc: 지난번 플레이 이후 변경 사항은 다음과 같습니다. desc: 지난번 플레이 이후 변경 사항은 다음과 같습니다.
upgradesIntroduction: upgradesIntroduction:
title: 업그레이드 하기 title: 업그레이드 하기
desc: desc: <strong>기존의 공장을 허물지 마세요!</strong> 여러분이 그동안 만들어 수집한 모든 도형은 업그레이드에 사용됩니다.
<strong>기존의 공장을 허물지 마세요!</strong> 여러분이 그동안 만들어 수집한 모든 도형은 업그레이드에 사용됩니다.
업그레이드 버튼은 화면의 오른쪽 위에 있습니다. 업그레이드 버튼은 화면의 오른쪽 위에 있습니다.
massDeleteConfirm: massDeleteConfirm:
title: 삭제 확인 title: 삭제 확인
@ -142,8 +140,7 @@ dialogs:
desc: 12 레벨부터 청사진 기능이 해금됩니다! desc: 12 레벨부터 청사진 기능이 해금됩니다!
keybindingsIntroduction: keybindingsIntroduction:
title: 유용한 조작법 title: 유용한 조작법
desc: desc: "이 게임에는 거대한 공장을 수월하게 세우기 위한 많은 조작법이 있습니다. 아래는 그 대표적인 것이며, 자세한 조작법은
"이 게임에는 거대한 공장을 수월하게 세우기 위한 많은 조작법이 있습니다. 아래는 그 대표적인 것이며, 자세한 조작법은
<strong>조작법 설정</strong>을 참고해주세요!<br><br> <code <strong>조작법 설정</strong>을 참고해주세요!<br><br> <code
class='keybinding'>CTRL</code> + 드래그: 영역을 선택합니다.<br> <code class='keybinding'>CTRL</code> + 드래그: 영역을 선택합니다.<br> <code
class='keybinding'>SHIFT</code>: 누르는 동안 같은 건물을 여러개 배치할 수 있습니다.<br> class='keybinding'>SHIFT</code>: 누르는 동안 같은 건물을 여러개 배치할 수 있습니다.<br>
@ -157,8 +154,7 @@ dialogs:
desc: 체험판 버전에서는 마커를 2개 까지만 배치할 수 있습니다. 정식 버전을 구입하면 마커를 무제한으로 배치할 수 있습니다! desc: 체험판 버전에서는 마커를 2개 까지만 배치할 수 있습니다. 정식 버전을 구입하면 마커를 무제한으로 배치할 수 있습니다!
exportScreenshotWarning: exportScreenshotWarning:
title: 스크린샷 내보내기 title: 스크린샷 내보내기
desc: desc: 당신의 공장을 스크린샷으로 내보내려 합니다. 매우 거대한 크기의 공장이라면 그 처리 시간이 상당히 오래 걸릴 것이며, 최악의 경우
당신의 공장을 스크린샷으로 내보내려 합니다. 매우 거대한 크기의 공장이라면 그 처리 시간이 상당히 오래 걸릴 것이며, 최악의 경우
게임이 중단될 수 있습니다! 게임이 중단될 수 있습니다!
massCutInsufficientConfirm: massCutInsufficientConfirm:
title: 자르기 확인 title: 자르기 확인
@ -184,8 +180,7 @@ dialogs:
submitPuzzle: submitPuzzle:
title: 퍼즐 보내기 title: 퍼즐 보내기
descName: "퍼즐에 이름을 지어 주세요:" descName: "퍼즐에 이름을 지어 주세요:"
descIcon: descIcon: "퍼즐의 아이콘으로 보여지게 될 짧은 단어를 지정해 주세요. (<link>이곳</link>에서 생성하시거나, 아래 랜덤한 모양
"퍼즐의 아이콘으로 보여지게 될 짧은 단어를 지정해 주세요. (<link>이곳</link>에서 생성하시거나, 아래 랜덤한 모양
중 하나를 선택하세요):" 중 하나를 선택하세요):"
placeholderName: 퍼즐 제목 placeholderName: 퍼즐 제목
puzzleResizeBadBuildings: puzzleResizeBadBuildings:
@ -211,8 +206,7 @@ dialogs:
desc: 오프라인 모드임으로 퍼즐을 저장하거나 업로드할 수 없습니다. 그래도 계속하시겠습니까? desc: 오프라인 모드임으로 퍼즐을 저장하거나 업로드할 수 없습니다. 그래도 계속하시겠습니까?
puzzlePlayRegularRecommendation: puzzlePlayRegularRecommendation:
title: 권장 사항 title: 권장 사항
desc: desc: 퍼즐 DLC 플레이시 소개되지 않은 요소를 접하시게 될 수 있으므로, 적어도 일반 게임을 12레벨까지 플레이하시는것을
퍼즐 DLC 플레이시 소개되지 않은 요소를 접하시게 될 수 있으므로, 적어도 일반 게임을 12레벨까지 플레이하시는것을
<strong>강력히</strong> 권장드립니다. 그래도 계속하시겠습니까? <strong>강력히</strong> 권장드립니다. 그래도 계속하시겠습니까?
puzzleShare: puzzleShare:
title: 짧은 키 복사됨 title: 짧은 키 복사됨
@ -256,7 +250,7 @@ ingame:
clearSelection: 지우기 clearSelection: 지우기
pipette: 피펫 pipette: 피펫
switchLayers: 레이어 전환 switchLayers: 레이어 전환
clearBelts: Clear belts clearBelts: 벨트 청소하기
buildingPlacement: buildingPlacement:
cycleBuildingVariants: <key> 키를 눌러 변형 전환 cycleBuildingVariants: <key> 키를 눌러 변형 전환
hotkeyLabel: "단축키: <key>" hotkeyLabel: "단축키: <key>"
@ -312,31 +306,25 @@ ingame:
waypoints: waypoints:
waypoints: 마커 waypoints: 마커
hub: 허브 hub: 허브
description: description: 마커를 좌클릭하여 그곳으로 이동하고, 우클릭으로 삭제할 수 있습니다.<br><br>마커를 배치하기 위해
마커를 좌클릭하여 그곳으로 이동하고, 우클릭으로 삭제할 수 있습니다.<br><br>마커를 배치하기 위해
<keybinding> 키로 지금 있는 위치에, 또는 <strong>우클릭</strong>하여 원하는 위치에 배치할 수 <keybinding> 키로 지금 있는 위치에, 또는 <strong>우클릭</strong>하여 원하는 위치에 배치할 수
있습니다. 있습니다.
creationSuccessNotification: 마커가 성공적으로 생성되었습니다. creationSuccessNotification: 마커가 성공적으로 생성되었습니다.
interactiveTutorial: interactiveTutorial:
title: 튜토리얼 title: 튜토리얼
hints: hints:
1_1_extractor: 1_1_extractor: <strong>원형 도형</strong>을 추출하기 위해 그 위에 <strong>추출기</strong>를 선택한 뒤
<strong>원형 도형</strong>을 추출하기 위해 그 위에 <strong>추출기</strong>를 선택한 뒤
배치하여 추출하세요! 배치하여 추출하세요!
1_2_conveyor: 1_2_conveyor: "이제 <strong>컨베이어 벨트</strong>를 추출기와 허브를 서로 연결하세요!<br><br> 팁: 벨트를
"이제 <strong>컨베이어 벨트</strong>를 추출기와 허브를 서로 연결하세요!<br><br> 팁: 벨트를
마우스로 <strong>클릭한 뒤 드래그</strong>하세요!" 마우스로 <strong>클릭한 뒤 드래그</strong>하세요!"
1_3_expand: 1_3_expand: "이 게임은 방치형 게임이 <strong>아닙니다</strong>! 더 많은 추출기와 벨트를 만들어 지정된 목표를 빨리
"이 게임은 방치형 게임이 <strong>아닙니다</strong>! 더 많은 추출기와 벨트를 만들어 지정된 목표를 빨리
달성하세요.<br><br> 팁: <strong>SHIFT</strong> 키를 누른 상태에서는 빠르게 배치할 수 달성하세요.<br><br> 팁: <strong>SHIFT</strong> 키를 누른 상태에서는 빠르게 배치할 수
있고, <strong>R</strong> 키를 눌러 회전할 수 있습니다." 있고, <strong>R</strong> 키를 눌러 회전할 수 있습니다."
2_1_place_cutter: 2_1_place_cutter: "이제 <strong>절단기</strong>를 배치해 원형 도형을 반으로 잘라보세요!<br><br> 참고:
"이제 <strong>절단기</strong>를 배치해 원형 도형을 반으로 잘라보세요!<br><br> 참고:
절단기는 놓는 방향에 상관없이 항상 <strong>위에서 아래로만</strong> 자릅니다." 절단기는 놓는 방향에 상관없이 항상 <strong>위에서 아래로만</strong> 자릅니다."
2_2_place_trash: 절단기가 <strong>막히거나 멈출 수 있습니다</strong>!<br><br> 2_2_place_trash: 절단기가 <strong>막히거나 멈출 수 있습니다</strong>!<br><br>
<strong>휴지통</strong>을 사용하여 현재 필요없는 쓰레기 도형 (!)을 제거하세요. <strong>휴지통</strong>을 사용하여 현재 필요없는 쓰레기 도형 (!)을 제거하세요.
2_3_more_cutters: 2_3_more_cutters: "잘하셨습니다! 느린 처리 속도를 보완하기 위해 <strong>절단기를 두 개</strong> 이상
"잘하셨습니다! 느린 처리 속도를 보완하기 위해 <strong>절단기를 두 개</strong> 이상
배치해보세요!<br><br> 추신: <strong>상단 숫자 단축키 (0~9)</strong>를 사용하여 건물을 배치해보세요!<br><br> 추신: <strong>상단 숫자 단축키 (0~9)</strong>를 사용하여 건물을
빠르게 선택할 수 있습니다!" 빠르게 선택할 수 있습니다!"
3_1_rectangles: "이제 사각형 도형을 추출해 볼까요! <strong>추출기 네 개를 배치</strong>하고 허브와 3_1_rectangles: "이제 사각형 도형을 추출해 볼까요! <strong>추출기 네 개를 배치</strong>하고 허브와
@ -344,12 +332,10 @@ ingame:
누른 채 드래그하세요!" 누른 채 드래그하세요!"
21_1_place_quad_painter: <strong>4단 색칠기</strong>를 배치하여 <strong>흰색</strong>과 21_1_place_quad_painter: <strong>4단 색칠기</strong>를 배치하여 <strong>흰색</strong>과
<strong>빨간색</strong>이 칠해진 <strong>원형 도형</strong>을 만들어보세요! <strong>빨간색</strong>이 칠해진 <strong>원형 도형</strong>을 만들어보세요!
21_2_switch_to_wires: 21_2_switch_to_wires: <strong>E 키</strong>를 눌러 전선 레이어 로 전환하세요!<br><br> 그 후 색칠기의
<strong>E 키</strong>를 눌러 전선 레이어 로 전환하세요!<br><br> 그 후 색칠기의
<strong>네 입력 부분</strong>을 모두 케이블로 연결하세요! <strong>네 입력 부분</strong>을 모두 케이블로 연결하세요!
21_3_place_button: 훌륭해요! 이제 <strong>스위치</strong>를 배치하고 전선으로 연결하세요! 21_3_place_button: 훌륭해요! 이제 <strong>스위치</strong>를 배치하고 전선으로 연결하세요!
21_4_press_button: 21_4_press_button: "스위치를 눌러서 색칠기에 <strong>참 신호를 보내</strong> 활성화해보세요.<br><br> 추신:
"스위치를 눌러서 색칠기에 <strong>참 신호를 보내</strong> 활성화해보세요.<br><br> 추신:
모든 입력을 연결할 필요는 없습니다! 두개만 연결해 보세요." 모든 입력을 연결할 필요는 없습니다! 두개만 연결해 보세요."
colors: colors:
red: 빨간색 red: 빨간색
@ -429,6 +415,7 @@ ingame:
titleRatingDesc: 당신의 평가는 제가 미래에 더 나은 평가를 만들수 있도록 도울 수 있습니다. titleRatingDesc: 당신의 평가는 제가 미래에 더 나은 평가를 만들수 있도록 도울 수 있습니다.
continueBtn: 계속 플레이하기 continueBtn: 계속 플레이하기
menuBtn: 메뉴 menuBtn: 메뉴
nextPuzzle: Next Puzzle
puzzleMetadata: puzzleMetadata:
author: 제작자 author: 제작자
shortKey: 짧은 키 shortKey: 짧은 키
@ -475,13 +462,11 @@ buildings:
cutter: cutter:
default: default:
name: 절단기 name: 절단기
description: description: 도형을 수직으로 잘라 두 가지 도형으로 나눕니다. <strong>한쪽만 사용할 경우라면 다른 부분을 파괴하지 않을 경우
도형을 수직으로 잘라 두 가지 도형으로 나눕니다. <strong>한쪽만 사용할 경우라면 다른 부분을 파괴하지 않을 경우
절단기가 막혀 멈추게 됩니다!</strong> 절단기가 막혀 멈추게 됩니다!</strong>
quad: quad:
name: 4단 절단기 name: 4단 절단기
description: description: 도형을 즉시 네 개로 자릅니다. <strong>한쪽만 사용할 경우라면 다른 부분을 파괴하지 않을 경우 절단기가 막혀
도형을 즉시 네 개로 자릅니다. <strong>한쪽만 사용할 경우라면 다른 부분을 파괴하지 않을 경우 절단기가 막혀
멈추게 됩니다!</strong> 멈추게 됩니다!</strong>
rotater: rotater:
default: default:
@ -496,8 +481,7 @@ buildings:
stacker: stacker:
default: default:
name: 결합기 name: 결합기
description: description: 도형을 서로 결합하고 쌓습니다. 서로 결합할 수 있다면 두 도형을 붙여 하나로 만들고, 그렇지 않으면 오른쪽 도형이 왼쪽
도형을 서로 결합하고 쌓습니다. 서로 결합할 수 있다면 두 도형을 붙여 하나로 만들고, 그렇지 않으면 오른쪽 도형이 왼쪽
도형 위에 쌓이게 됩니다. 도형 위에 쌓이게 됩니다.
mixer: mixer:
default: default:
@ -512,8 +496,7 @@ buildings:
description: 색소를 이용해 도형을 색칠합니다. 위쪽에서 받는 색소로 왼쪽에서 받는 도형 전체를 색칠합니다. description: 색소를 이용해 도형을 색칠합니다. 위쪽에서 받는 색소로 왼쪽에서 받는 도형 전체를 색칠합니다.
quad: quad:
name: 4단 색칠기 name: 4단 색칠기
description: description: 도형의 각 사분면에 개별적으로 색상을 칠할 수 있습니다. 전선 레이어를 통해 <strong>참 신호</strong>가
도형의 각 사분면에 개별적으로 색상을 칠할 수 있습니다. 전선 레이어를 통해 <strong>참 신호</strong>가
있는 슬롯만 칠해집니다! 있는 슬롯만 칠해집니다!
mirrored: mirrored:
name: 색칠기 name: 색칠기
@ -560,8 +543,7 @@ buildings:
lever: lever:
default: default:
name: 스위치 name: 스위치
description: description: 전선 레이어에서 불 값 (1 또는 0)을 방출하도록 전환할 수 있으며, 그 후 아이템 선별같은 구성 요소를 제어하는 데
전선 레이어에서 불 값 (1 또는 0)을 방출하도록 전환할 수 있으며, 그 후 아이템 선별같은 구성 요소를 제어하는 데
사용될 수 있습니다. 사용될 수 있습니다.
logic_gate: logic_gate:
default: default:
@ -572,8 +554,7 @@ buildings:
description: 입력이 거짓일 경우 불 값 "1"을 내보냅니다 (참은 도형, 색상, 불 값 "1"을 의미합니다). description: 입력이 거짓일 경우 불 값 "1"을 내보냅니다 (참은 도형, 색상, 불 값 "1"을 의미합니다).
xor: xor:
name: XOR 회로 name: XOR 회로
description: description: 입력 중 하나만 참이고 둘 다 같지 않을 경우 불 값 "1"을 내보냅니다 (참은 도형, 색상, 불 값 "1"을
입력 중 하나만 참이고 둘 다 같지 않을 경우 불 값 "1"을 내보냅니다 (참은 도형, 색상, 불 값 "1"을
의미합니다). 의미합니다).
or: or:
name: OR 회로 name: OR 회로
@ -640,8 +621,7 @@ buildings:
storyRewards: storyRewards:
reward_cutter_and_trash: reward_cutter_and_trash:
title: 절단기 title: 절단기
desc: desc: <strong>절단기</strong>가 잠금 해제되었습니다! 절단기는 들어오는 도형이 어떤 모양을 하고 있던 수직으로 잘라
<strong>절단기</strong>가 잠금 해제되었습니다! 절단기는 들어오는 도형이 어떤 모양을 하고 있던 수직으로 잘라
<strong>반으로 나눕니다</strong>!<br><br> 쓰지 않는 도형은 쓰레기로 처리하세요, 그렇지 않으면 <strong>반으로 나눕니다</strong>!<br><br> 쓰지 않는 도형은 쓰레기로 처리하세요, 그렇지 않으면
<strong>작동을 멈출 것입니다</strong>! 이러한 목적을 위해 <strong>휴지통</strong>도 함께 <strong>작동을 멈출 것입니다</strong>! 이러한 목적을 위해 <strong>휴지통</strong>도 함께
지급되었습니다. 휴지통에 들어간 것은 모두 파괴됩니다! 지급되었습니다. 휴지통에 들어간 것은 모두 파괴됩니다!
@ -650,8 +630,7 @@ storyRewards:
desc: <strong>회전기</strong>가 잠금 해제되었습니다! 회전기는 들어오는 도형을 시계 방향으로 90도 회전시켜줍니다. desc: <strong>회전기</strong>가 잠금 해제되었습니다! 회전기는 들어오는 도형을 시계 방향으로 90도 회전시켜줍니다.
reward_painter: reward_painter:
title: 색칠기 title: 색칠기
desc: desc: "<strong>색칠기</strong>가 잠금 해제되었습니다! 도형과 마찬가지로 색소를 추출하고 색칠기에 넣거 도형과 결합하여 색칠된
"<strong>색칠기</strong>가 잠금 해제되었습니다! 도형과 마찬가지로 색소를 추출하고 색칠기에 넣거 도형과 결합하여 색칠된
도형을 만들도록 하세요!<br><br>추신: 만약 당신이 색맹이라면, 설정에서 <strong>색맹 모드</strong>를 도형을 만들도록 하세요!<br><br>추신: 만약 당신이 색맹이라면, 설정에서 <strong>색맹 모드</strong>를
활성화하세요!" 활성화하세요!"
reward_mixer: reward_mixer:
@ -660,28 +639,24 @@ storyRewards:
색소</strong>를 얻을 수 있습니다! 색소</strong>를 얻을 수 있습니다!
reward_stacker: reward_stacker:
title: 결합기 title: 결합기
desc: desc: <strong>결합기</strong>가 잠금 해제되었습니다! 이제 결합기를 통해 여러 도형을 붙이고 결합할 수 있습니다! 들어오는 두
<strong>결합기</strong>가 잠금 해제되었습니다! 이제 결합기를 통해 여러 도형을 붙이고 결합할 수 있습니다! 들어오는 두
도형의 모양이 서로 나란히 붙일 수 있다면, 하나의 도형으로 <strong>결합</strong>됩니다. 만약 서로 도형의 모양이 서로 나란히 붙일 수 있다면, 하나의 도형으로 <strong>결합</strong>됩니다. 만약 서로
겹쳐진다면, 오른쪽 도형이 왼쪽 도형의 <strong>위에 쌓이게</strong> 됩니다! 겹쳐진다면, 오른쪽 도형이 왼쪽 도형의 <strong>위에 쌓이게</strong> 됩니다!
reward_splitter: reward_splitter:
title: 압축형 분배기 title: 압축형 분배기
desc: desc: <strong>밸런서</strong>의 새로운 형태인 <strong>분배기</strong>가 잠금 해제되었습니다! 이제 벨트 한 줄을
<strong>밸런서</strong>의 새로운 형태인 <strong>분배기</strong>가 잠금 해제되었습니다! 이제 벨트 한 줄을
즉시 두 줄로 분배합니다! 즉시 두 줄로 분배합니다!
reward_tunnel: reward_tunnel:
title: 터널 title: 터널
desc: <strong>터널</strong>이 잠금 해제되었습니다! 이제 벨트와 건물 아래로 공간을 만들어내 옮길 수 있습니다! desc: <strong>터널</strong>이 잠금 해제되었습니다! 이제 벨트와 건물 아래로 공간을 만들어내 옮길 수 있습니다!
reward_rotater_ccw: reward_rotater_ccw:
title: 반시계 방향 회전기 title: 반시계 방향 회전기
desc: desc: <strong>반시계 방향 회전기</strong>가 잠금 해제되었습니다! 반시계 방향 회전기는 회전기의 다른 형태로, 이름처럼
<strong>반시계 방향 회전기</strong>가 잠금 해제되었습니다! 반시계 방향 회전기는 회전기의 다른 형태로, 이름처럼
들어오는 도형을 반시계 방향으로 90도만큼 회전시킵니다! 제작하려면 회전기를 선택한 후 <strong>'T' 키를 눌러 들어오는 도형을 반시계 방향으로 90도만큼 회전시킵니다! 제작하려면 회전기를 선택한 후 <strong>'T' 키를 눌러
다른 형태로 전환</strong>하세요! 다른 형태로 전환</strong>하세요!
reward_miner_chainable: reward_miner_chainable:
title: 연쇄 추출기 title: 연쇄 추출기
desc: desc: "<strong>연쇄 추출기</strong>가 잠금 해제되었습니다! 자원을 보다 더욱 효율적으로 추출할 수 있도록 <strong>앞에
"<strong>연쇄 추출기</strong>가 잠금 해제되었습니다! 자원을 보다 더욱 효율적으로 추출할 수 있도록 <strong>앞에
있는 추출기로 자원을 보낼 수 있습니다</strong>!<br><br> 추신: 이제 툴바에 있는 기존 추출기는 연쇄 있는 추출기로 자원을 보낼 수 있습니다</strong>!<br><br> 추신: 이제 툴바에 있는 기존 추출기는 연쇄
추출기로 대체되었습니다!" 추출기로 대체되었습니다!"
reward_underground_belt_tier_2: reward_underground_belt_tier_2:
@ -690,18 +665,15 @@ storyRewards:
거리</strong>를 운송할 수 있고 기존 터널과 겹쳐지지 않고도 자원을 보낼 수 있습니다! 거리</strong>를 운송할 수 있고 기존 터널과 겹쳐지지 않고도 자원을 보낼 수 있습니다!
reward_cutter_quad: reward_cutter_quad:
title: 4단 절단기 title: 4단 절단기
desc: desc: 새로운 종류의 <strong>절단기</strong>가 잠금 해제되었습니다! 4단 절단기는 도형을 두 조각이 아닌 <strong>네
새로운 종류의 <strong>절단기</strong>가 잠금 해제되었습니다! 4단 절단기는 도형을 두 조각이 아닌 <strong>네
조각</strong>으로 자를 수 있습니다! 조각</strong>으로 자를 수 있습니다!
reward_painter_double: reward_painter_double:
title: 2단 색칠기 title: 2단 색칠기
desc: desc: 새로운 종류의 <strong>절단기</strong>가 잠금 해제되었습니다! 일반적인 색칠기와 거의 동일하지만, 하나의 색소를 사용하여
새로운 종류의 <strong>절단기</strong>가 잠금 해제되었습니다! 일반적인 색칠기와 거의 동일하지만, 하나의 색소를 사용하여
<strong>동시에 두 개의 도형을 색칠</strong>할 수 있습니다! <strong>동시에 두 개의 도형을 색칠</strong>할 수 있습니다!
reward_storage: reward_storage:
title: 저장고 title: 저장고
desc: desc: <strong>저장고</strong>가 잠금 해제되었습니다! 저장고는 최대 용량까지 도형을 저장할 수 있습니다!<br><br> 왼쪽
<strong>저장고</strong>가 잠금 해제되었습니다! 저장고는 최대 용량까지 도형을 저장할 수 있습니다!<br><br> 왼쪽
출력이 우선되므로 <strong>오버플로 회로</strong>로도 활용될 수 있습니다! 출력이 우선되므로 <strong>오버플로 회로</strong>로도 활용될 수 있습니다!
reward_freeplay: reward_freeplay:
title: 자유플레이 title: 자유플레이
@ -711,38 +683,32 @@ storyRewards:
레이어를 통해 내보내므로 이를 분석하는 구조를 기반으로 하여 공장을 자동으로 구성하기만 하면 됩니다. 레이어를 통해 내보내므로 이를 분석하는 구조를 기반으로 하여 공장을 자동으로 구성하기만 하면 됩니다.
reward_blueprints: reward_blueprints:
title: 청사진 title: 청사진
desc: desc: 이제 공장의 일부를 <strong>복사하고 붙여넣는 기능</strong>을 사용할 수 있습니다! 영역을 선택 (CTRL 키를 누른 채
이제 공장의 일부를 <strong>복사하고 붙여넣는 기능</strong>을 사용할 수 있습니다! 영역을 선택 (CTRL 키를 누른 채
마우스로 드래그)한 뒤 'C' 키를 눌러 복사할 수 있습니다.<br><br>하지만 <strong>공짜는 마우스로 드래그)한 뒤 'C' 키를 눌러 복사할 수 있습니다.<br><br>하지만 <strong>공짜는
아닙니다</strong>, <strong>청사진 모양 도형</strong>을 허브에 저장하고 그것을 일부 사용해 붙여넣기 아닙니다</strong>, <strong>청사진 모양 도형</strong>을 허브에 저장하고 그것을 일부 사용해 붙여넣기
기능을 사용할 수 있습니다! (방금 당신이 만든 것입니다.) 기능을 사용할 수 있습니다! (방금 당신이 만든 것입니다.)
no_reward: no_reward:
title: 다음 레벨 title: 다음 레벨
desc: desc: "이번 레벨의 보상은 없네요. 대신 다음 레벨에서 줄겁니다!<br><br> 추신: 기존 공장을 파괴하지는 마세요. 후에
"이번 레벨의 보상은 없네요. 대신 다음 레벨에서 줄겁니다!<br><br> 추신: 기존 공장을 파괴하지는 마세요. 후에
<strong>업그레이드 잠금 해제</strong>되면 <strong>기존의 모든</strong> 도형이 필요합니다!" <strong>업그레이드 잠금 해제</strong>되면 <strong>기존의 모든</strong> 도형이 필요합니다!"
no_reward_freeplay: no_reward_freeplay:
title: 다음 레벨 title: 다음 레벨
desc: 축하드립니다! desc: 축하드립니다!
reward_balancer: reward_balancer:
title: 밸런서 title: 밸런서
desc: desc: <strong>밸런서</strong>가 잠금 해제되었습니다! 다목적 밸런서를 통해 여러 벨트의 아이템을 서로 <strong>다른
<strong>밸런서</strong>가 잠금 해제되었습니다! 다목적 밸런서를 통해 여러 벨트의 아이템을 서로 <strong>다른
벨트로 분할하거나 합침</strong>으로써 더욱 거대한 공장을 만들 수 있습니다! 벨트로 분할하거나 합침</strong>으로써 더욱 거대한 공장을 만들 수 있습니다!
reward_merger: reward_merger:
title: 압축형 병합기 title: 압축형 병합기
desc: desc: <strong>밸런서</strong>의 새로운 형태인 <strong>병합기</strong>가 잠금 해제되었습니다! 이제 벨트 두 줄을
<strong>밸런서</strong>의 새로운 형태인 <strong>병합기</strong>가 잠금 해제되었습니다! 이제 벨트 두 줄을
즉시 한 줄로 병합합니다! 즉시 한 줄로 병합합니다!
reward_belt_reader: reward_belt_reader:
title: 벨트 판독기 title: 벨트 판독기
desc: desc: <strong>벨트 판독기</strong>가 잠금 해제되었습니다! 이제 벨트의 처리량을 확인할 수 있습니다.<br><br>그리고,
<strong>벨트 판독기</strong>가 잠금 해제되었습니다! 이제 벨트의 처리량을 확인할 수 있습니다.<br><br>그리고,
전선이 잠금 해제될 때 까지 기다리신다면 정말 유용하게 사용할 수 있을 겁니다! 전선이 잠금 해제될 때 까지 기다리신다면 정말 유용하게 사용할 수 있을 겁니다!
reward_rotater_180: reward_rotater_180:
title: 180도 회전기 title: 180도 회전기
desc: desc: <strong>180도 회전기</strong>가 잠금 해제되었습니다! 이제 도형을 바로 180도로 회전시킬 수 있습니다. (짜잔!
<strong>180도 회전기</strong>가 잠금 해제되었습니다! 이제 도형을 바로 180도로 회전시킬 수 있습니다. (짜잔!
:D) :D)
reward_display: reward_display:
title: 디스플레이 title: 디스플레이
@ -750,37 +716,32 @@ storyRewards:
있습니다.<br><br> 추신: 벨트 판독기와 저장고가 마지막으로 읽은 아이템을 출력했나요? 디스플레이로 한번 봐보세요!" 있습니다.<br><br> 추신: 벨트 판독기와 저장고가 마지막으로 읽은 아이템을 출력했나요? 디스플레이로 한번 봐보세요!"
reward_constant_signal: reward_constant_signal:
title: 일정 신호기 title: 일정 신호기
desc: desc: 전선 레이어에서 구축할 수 있는 <strong>일정 신호기</strong>가 잠금 해제되었습니다! 간단한 예시로,
전선 레이어에서 구축할 수 있는 <strong>일정 신호기</strong>가 잠금 해제되었습니다! 간단한 예시로,
<strong>아이템 선별</strong>에 연결하여 사용하는 데 유용합니다.<br><br> 일정 신호기는 <strong>아이템 선별</strong>에 연결하여 사용하는 데 유용합니다.<br><br> 일정 신호기는
<strong>도형</strong>, <strong>색상</strong>, 또는 <strong>불 값</strong> (1 <strong>도형</strong>, <strong>색상</strong>, 또는 <strong>불 값</strong> (1
또는 0)을 출력할 수 있습니다. 또는 0)을 출력할 수 있습니다.
reward_logic_gates: reward_logic_gates:
title: 논리 회로 title: 논리 회로
desc: desc: <strong>논리 회로</strong>가 잠금 해제되었습니다! 굳이 흥분할 필요는 없지만, 진짜 멋진 기술입니다!<br><br>
<strong>논리 회로</strong>가 잠금 해제되었습니다! 굳이 흥분할 필요는 없지만, 진짜 멋진 기술입니다!<br><br>
논리 회로를 통해 이제 AND, OR, XOR, NOT 논리 연산을 할 수 있습니다.<br><br> 보너스로, 논리 회로를 통해 이제 AND, OR, XOR, NOT 논리 연산을 할 수 있습니다.<br><br> 보너스로,
<strong>트랜지스터</strong>도 지급되었습니다! <strong>트랜지스터</strong>도 지급되었습니다!
reward_virtual_processing: reward_virtual_processing:
title: 가상 처리 title: 가상 처리
desc: desc: <strong>도형의 처리를 시뮬레이션</strong>할 수 있는 다양한 새로운 건물이 잠금 해제되었습니다!<br><br> 이제 전선
<strong>도형의 처리를 시뮬레이션</strong>할 수 있는 다양한 새로운 건물이 잠금 해제되었습니다!<br><br> 이제 전선
레이어에서 도형에 대한 절단기, 회전기, 결합기 등을 가상으로 시뮬레이션할 수 있습니다! 이제 게임 진행에 있어 다음 세 레이어에서 도형에 대한 절단기, 회전기, 결합기 등을 가상으로 시뮬레이션할 수 있습니다! 이제 게임 진행에 있어 다음 세
가지의 방법이 존재합니다:<br><br> - <strong>완전 자동화된 기계</strong>를 구축하고 허브에서 요구되는 가지의 방법이 존재합니다:<br><br> - <strong>완전 자동화된 기계</strong>를 구축하고 허브에서 요구되는
도형을 제작합니다. (먼저 시도해볼 것을 권합니다!).<br><br> - 전선을 통해 멋진 것들 만듭니다.<br><br> 도형을 제작합니다. (먼저 시도해볼 것을 권합니다!).<br><br> - 전선을 통해 멋진 것들 만듭니다.<br><br>
- 평소처럼 게임을 진행합니다.<br><br> 어떤 방식으로든, 재미있게 게임을 플레이해주시길 바랍니다! - 평소처럼 게임을 진행합니다.<br><br> 어떤 방식으로든, 재미있게 게임을 플레이해주시길 바랍니다!
reward_wires_painter_and_levers: reward_wires_painter_and_levers:
title: 전선과 4단 색칠기 title: 전선과 4단 색칠기
desc: desc: " 방금 <strong>전선 레이어</strong>를 활성화하셨습니다: 이것은 일반 레이어 위에 존재하는 별개의 레이어로 수많은
" 방금 <strong>전선 레이어</strong>를 활성화하셨습니다: 이것은 일반 레이어 위에 존재하는 별개의 레이어로 수많은
새로운 요소를 사용할 수 있습니다!<br><br> <strong>4단 색칠기</strong>를 활성화해 드리겠습니다 - 새로운 요소를 사용할 수 있습니다!<br><br> <strong>4단 색칠기</strong>를 활성화해 드리겠습니다 -
전선 레이어에서 색을 칠할 부분에 연결해 보세요!<br><br> 전선 레이어로 전환하시려면 전선 레이어에서 색을 칠할 부분에 연결해 보세요!<br><br> 전선 레이어로 전환하시려면
<strong>E</strong>키를 눌러주세요.<br><br> 추신: <strong>힌트를 활성화</strong>해서 <strong>E</strong>키를 눌러주세요.<br><br> 추신: <strong>힌트를 활성화</strong>해서
전선 튜토리얼을 활성화해 보세요!" 전선 튜토리얼을 활성화해 보세요!"
reward_filter: reward_filter:
title: 아이템 선별기 title: 아이템 선별기
desc: desc: <strong>아이템 선별기</strong>가 잠금 해제되었습니다! 전선 레이어의 신호와 일치하는지에 대한 여부로 아이템을 위쪽
<strong>아이템 선별기</strong>가 잠금 해제되었습니다! 전선 레이어의 신호와 일치하는지에 대한 여부로 아이템을 위쪽
출력이나 오른쪽 출력으로 보냅니다.<br><br> 불 값 (1 또는 0)을 전달하여 완전히 활성화과 비활성화를 전환할 수 출력이나 오른쪽 출력으로 보냅니다.<br><br> 불 값 (1 또는 0)을 전달하여 완전히 활성화과 비활성화를 전환할 수
있습니다. 있습니다.
reward_demo_end: reward_demo_end:
@ -801,8 +762,7 @@ settings:
labels: labels:
uiScale: uiScale:
title: UI 크기 title: UI 크기
description: description: 사용자 인터페이스의 크기를 변경합니다. 인터페이스는 당신의 해상도에 따라 확장되는데 이 설정은 그 확장의 정도를
사용자 인터페이스의 크기를 변경합니다. 인터페이스는 당신의 해상도에 따라 확장되는데 이 설정은 그 확장의 정도를
제어합니다. 제어합니다.
scales: scales:
super_small: 매우 작게 super_small: 매우 작게
@ -849,18 +809,15 @@ settings:
light: 라이트 light: 라이트
refreshRate: refreshRate:
title: 틱 빈도 title: 틱 빈도
description: description: 이것은 초당 발생하는 게임 틱 수를 결정합니다. 일반적으로 틱 속도가 높을수록 정밀도는 향상되나 성능은 낮아집니다. 낮은
이것은 초당 발생하는 게임 틱 수를 결정합니다. 일반적으로 틱 속도가 높을수록 정밀도는 향상되나 성능은 낮아집니다. 낮은
틱 빈도에서는 처리량이 정확하지 않을 수 있습니다. 틱 빈도에서는 처리량이 정확하지 않을 수 있습니다.
alwaysMultiplace: alwaysMultiplace:
title: 다수 배치 항시 켜기 title: 다수 배치 항시 켜기
description: description: 활성화할 경우 모든 건물은 배치한 후 취소할 때 까지 커서에 선택된 상태를 유지합니다. 이 기능은 SHIFT 키를 계속
활성화할 경우 모든 건물은 배치한 후 취소할 때 까지 커서에 선택된 상태를 유지합니다. 이 기능은 SHIFT 키를 계속
누르는 것과 같습니다. 누르는 것과 같습니다.
offerHints: offerHints:
title: 힌트와 튜토리얼 title: 힌트와 튜토리얼
description: description: 게임 플레이하는 동안 힌트와 튜토리얼을 보여줄 지를 결정합니다. 또한 게임에 더 쉽게 빠져들 수 있도록 특정 레벨까지
게임 플레이하는 동안 힌트와 튜토리얼을 보여줄 지를 결정합니다. 또한 게임에 더 쉽게 빠져들 수 있도록 특정 레벨까지
특정한 UI 요소를 숨깁니다. 특정한 UI 요소를 숨깁니다.
enableTunnelSmartplace: enableTunnelSmartplace:
title: 지능적인 터널 배치 title: 지능적인 터널 배치
@ -889,8 +846,7 @@ settings:
description: 색맹 사용자를 위해 게임을 플레이하는 데 도움을 주는 다양한 도구를 활성화합니다. description: 색맹 사용자를 위해 게임을 플레이하는 데 도움을 주는 다양한 도구를 활성화합니다.
rotationByBuilding: rotationByBuilding:
title: 건물 유형에 따른 방향 title: 건물 유형에 따른 방향
description: description: 각 건물 유형마다 개별적으로 마지막으로 설정했던 방향을 기억하도록 합니다. 다른 건물 변형을 자주 전환하는 경우 이
각 건물 유형마다 개별적으로 마지막으로 설정했던 방향을 기억하도록 합니다. 다른 건물 변형을 자주 전환하는 경우 이
방법이 더욱 편할 수 있습니다. 방법이 더욱 편할 수 있습니다.
soundVolume: soundVolume:
title: 효과음 볼륨 title: 효과음 볼륨
@ -906,8 +862,7 @@ settings:
description: 성능 향상을 위해 타일 그리드를 비활성화할 수 있습니다. 이 역시 게임을 더욱 깨끗하게 보여줍니다! description: 성능 향상을 위해 타일 그리드를 비활성화할 수 있습니다. 이 역시 게임을 더욱 깨끗하게 보여줍니다!
clearCursorOnDeleteWhilePlacing: clearCursorOnDeleteWhilePlacing:
title: 우클릭 시 커서 지우기 title: 우클릭 시 커서 지우기
description: description: 기본적으로 활성화되어 있으며, 배치할 건물을 선택한 상태에서 마우스 우클릭 시 커서를 지웁니다. 비활성화할 경우, 건물을
기본적으로 활성화되어 있으며, 배치할 건물을 선택한 상태에서 마우스 우클릭 시 커서를 지웁니다. 비활성화할 경우, 건물을
커서에 선택한 채로 우클릭하면 바로 건물을 삭제할 수 있습니다. 커서에 선택한 채로 우클릭하면 바로 건물을 삭제할 수 있습니다.
lowQualityTextures: lowQualityTextures:
title: 저품질 텍스처 (못생김) title: 저품질 텍스처 (못생김)
@ -920,8 +875,7 @@ settings:
description: 기본적으로 활성화되어 있으며, 자원 패치에서 피펫 기능을 사용 시 즉시 추출기를 선택합니다. description: 기본적으로 활성화되어 있으며, 자원 패치에서 피펫 기능을 사용 시 즉시 추출기를 선택합니다.
simplifiedBelts: simplifiedBelts:
title: 벨트 단순화 (못생김) title: 벨트 단순화 (못생김)
description: description: 성능 향상을 위해 벨트를 가리킬 때를 제외한 모든 상황에서 벨트 아이템을 렌더링하지 않습니다. 이 기능을 사용할 정도로
성능 향상을 위해 벨트를 가리킬 때를 제외한 모든 상황에서 벨트 아이템을 렌더링하지 않습니다. 이 기능을 사용할 정도로
심각한 성능 문제가 일어나지 않는 한, 이 설정을 사용할 필요는 없습니다. 심각한 성능 문제가 일어나지 않는 한, 이 설정을 사용할 필요는 없습니다.
enableMousePan: enableMousePan:
title: 화면 가장자리 패닝 title: 화면 가장자리 패닝
@ -932,7 +886,12 @@ settings:
mapResourcesScale: mapResourcesScale:
title: 지도 자원 크기 title: 지도 자원 크기
description: 지도를 축소할 때 나타나는 도형의 크기를 제어합니다. description: 지도를 축소할 때 나타나는 도형의 크기를 제어합니다.
shapeTooltipAlwaysOn:
title: Shape Tooltip - Show Always
description: Whether to always show the shape tooltip when hovering buildings,
instead of having to hold 'ALT'.
rangeSliderPercentage: <amount> % rangeSliderPercentage: <amount> %
tickrateHz: <amount> Hz
keybindings: keybindings:
title: 조작법 title: 조작법
hint: "팁: CTRL, SHIFT, ALT를 적절히 사용하세요! 건물을 배치할 때 유용합니다." hint: "팁: CTRL, SHIFT, ALT를 적절히 사용하세요! 건물을 배치할 때 유용합니다."
@ -1013,6 +972,7 @@ keybindings:
goal_acceptor: 목표 수집기 goal_acceptor: 목표 수집기
block: 블록 block: 블록
massSelectClear: 벨트 초기화 massSelectClear: 벨트 초기화
showShapeTooltip: Show shape output tooltip
about: about:
title: 게임 정보 title: 게임 정보
body: >- body: >-
@ -1131,8 +1091,23 @@ puzzleMenu:
easy: 쉬움 easy: 쉬움
medium: 중간 medium: 중간
hard: 어려움 hard: 어려움
dlcHint: DLC를 이미 구입하셨나요? 라이브러리에서 shapez.io를 오른쪽 클릭한 다음 unknown: Unrated
속성… > DLC 메뉴를 선택해서 활성화되었는지 확인해주세요. dlcHint: DLC를 이미 구입하셨나요? 라이브러리에서 shapez.io를 오른쪽 클릭한 다음 속성… > DLC 메뉴를 선택해서
활성화되었는지 확인해주세요.
search:
action: Search
placeholder: Enter a puzzle or author name
includeCompleted: Include Completed
difficulties:
any: Any Difficulty
easy: Easy
medium: Medium
hard: Hard
durations:
any: Any Duration
short: Short (< 2 min)
medium: Normal
long: Long (> 10 min)
backendErrors: backendErrors:
ratelimit: 너무 빠른 시간 내 작업을 반복하고 있습니다. 조금만 기다려 주세요. ratelimit: 너무 빠른 시간 내 작업을 반복하고 있습니다. 조금만 기다려 주세요.
invalid-api-key: 백엔드 서버와 통신할 수 없습니다. 게임을 업데이트하거나 재시작해 주세요 (잘못된 API 키). invalid-api-key: 백엔드 서버와 통신할 수 없습니다. 게임을 업데이트하거나 재시작해 주세요 (잘못된 API 키).

View File

@ -457,6 +457,7 @@ ingame:
titleRatingDesc: Your rating will help me to make you better suggestions in the future titleRatingDesc: Your rating will help me to make you better suggestions in the future
continueBtn: Keep Playing continueBtn: Keep Playing
menuBtn: Menu menuBtn: Menu
nextPuzzle: Next Puzzle
puzzleMetadata: puzzleMetadata:
author: Author author: Author
shortKey: Short Key shortKey: Short Key
@ -1003,7 +1004,12 @@ settings:
title: Map Resources Size title: Map Resources Size
description: Controls the size of the shapes on the map overview (when zooming description: Controls the size of the shapes on the map overview (when zooming
out). out).
shapeTooltipAlwaysOn:
title: Shape Tooltip - Show Always
description: Whether to always show the shape tooltip when hovering buildings,
instead of having to hold 'ALT'.
rangeSliderPercentage: <amount> % rangeSliderPercentage: <amount> %
tickrateHz: <amount> Hz
keybindings: keybindings:
title: Keybindings title: Keybindings
hint: "Tip: Be sure to make use of CTRL, SHIFT and ALT! They enable different hint: "Tip: Be sure to make use of CTRL, SHIFT and ALT! They enable different
@ -1085,6 +1091,7 @@ keybindings:
goal_acceptor: Goal Acceptor goal_acceptor: Goal Acceptor
block: Block block: Block
massSelectClear: Clear belts massSelectClear: Clear belts
showShapeTooltip: Show shape output tooltip
about: about:
title: About this Game title: About this Game
body: >- body: >-
@ -1212,8 +1219,23 @@ puzzleMenu:
easy: Easy easy: Easy
medium: Medium medium: Medium
hard: Hard hard: Hard
unknown: Unrated
dlcHint: Purchased the DLC already? Make sure it is activated by right clicking dlcHint: Purchased the DLC already? Make sure it is activated by right clicking
shapez.io in your library, selecting Properties > DLCs. shapez.io in your library, selecting Properties > DLCs.
search:
action: Search
placeholder: Enter a puzzle or author name
includeCompleted: Include Completed
difficulties:
any: Any Difficulty
easy: Easy
medium: Medium
hard: Hard
durations:
any: Any Duration
short: Short (< 2 min)
medium: Normal
long: Long (> 10 min)
backendErrors: backendErrors:
ratelimit: You are performing your actions too frequent. Please wait a bit. ratelimit: You are performing your actions too frequent. Please wait a bit.
invalid-api-key: Failed to communicate with the backend, please try to invalid-api-key: Failed to communicate with the backend, please try to

View File

@ -14,7 +14,7 @@ steamPage:
Ondanks het feit dat je in het begin alleen vormen maakt, komt er een punt waarop je ze gaat kleuren. Deze kleuren kun je vinden en mengen! Ondanks het feit dat je in het begin alleen vormen maakt, komt er een punt waarop je ze gaat kleuren. Deze kleuren kun je vinden en mengen!
Door het spel op Steam te kopen kun je de volledige versie spelen. Je kunt echter ook een demo versie spelen op shapez.io en later beslissen om over te schakelen zonder voortgang te verliezen. Door het spel op Steam te kopen kun je de volledige versie spelen. Je kunt echter ook een demo versie spelen op shapez.io en later beslissen om over te schakelen zonder voortgang te verliezen.
what_others_say: What people say about shapez.io what_others_say: Wat anderen vinden van shapez.io
nothernlion_comment: This game is great - I'm having a wonderful time playing, nothernlion_comment: This game is great - I'm having a wonderful time playing,
and time has flown by. and time has flown by.
notch_comment: Oh crap. I really should sleep, but I think I just figured out notch_comment: Oh crap. I really should sleep, but I think I just figured out
@ -475,6 +475,7 @@ ingame:
te geven te geven
continueBtn: Blijf Spelen continueBtn: Blijf Spelen
menuBtn: Menu menuBtn: Menu
nextPuzzle: Next Puzzle
puzzleMetadata: puzzleMetadata:
author: Auteur author: Auteur
shortKey: Vorm Sleutel shortKey: Vorm Sleutel
@ -1033,7 +1034,12 @@ settings:
title: Kaartbronnen schaal title: Kaartbronnen schaal
description: Controleert de grootte van de vormen op het map overzicht (wanneer description: Controleert de grootte van de vormen op het map overzicht (wanneer
je uitzoomt). je uitzoomt).
shapeTooltipAlwaysOn:
title: Shape Tooltip - Show Always
description: Whether to always show the shape tooltip when hovering buildings,
instead of having to hold 'ALT'.
rangeSliderPercentage: <amount> % rangeSliderPercentage: <amount> %
tickrateHz: <amount> Hz
keybindings: keybindings:
title: Sneltoetsen title: Sneltoetsen
hint: "Tip: Maak gebruik van CTRL, SHIFT en ALT! Hiermee kun je dingen anders en hint: "Tip: Maak gebruik van CTRL, SHIFT en ALT! Hiermee kun je dingen anders en
@ -1115,6 +1121,7 @@ keybindings:
goal_acceptor: Ontvanger goal_acceptor: Ontvanger
block: Blokkade block: Blokkade
massSelectClear: Lopende banden leeg maken massSelectClear: Lopende banden leeg maken
showShapeTooltip: Show shape output tooltip
about: about:
title: Over dit spel title: Over dit spel
body: >- body: >-
@ -1166,14 +1173,12 @@ tips:
wordt de planner geactiveerd, zodat je gemakkelijk lange rijen kunt wordt de planner geactiveerd, zodat je gemakkelijk lange rijen kunt
plaatsen. plaatsen.
- Knippers knippen altijd verticaal, ongeacht hun oriëntatie. - Knippers knippen altijd verticaal, ongeacht hun oriëntatie.
- Meng alle drie de kleuren om wit te krijgen.
- De opslagbuffer geeft prioriteit aan de eerste uitvoer. - De opslagbuffer geeft prioriteit aan de eerste uitvoer.
- Investeer tijd om herhaalbare ontwerpen te maken - het is het waard! - Investeer tijd om herhaalbare ontwerpen te maken - het is het waard!
- Door <b>SHIFT</b> ingedrukt te houden, kunnen meerdere gebouwen worden - Invest time to build repeatable designs - it's worth it!
geplaatst.
- Je kunt <b>ALT</b> ingedrukt houden om de richting van de geplaatste - Je kunt <b>ALT</b> ingedrukt houden om de richting van de geplaatste
lopende banden om te keren. lopende banden om te keren.
- Efficiëntie is de sleutel! - You can hold <b>ALT</b> to invert the direction of placed belts.
- Vormontginningen die verder van de HUB verwijderd zijn, zijn complexer. - Vormontginningen die verder van de HUB verwijderd zijn, zijn complexer.
- Machines hebben een beperkte snelheid, verdeel ze voor maximale - Machines hebben een beperkte snelheid, verdeel ze voor maximale
efficiëntie. efficiëntie.
@ -1196,8 +1201,8 @@ tips:
mannen. mannen.
- Maak een aparte blueprint fabriek. Ze zijn belangrijk voor modules. - Maak een aparte blueprint fabriek. Ze zijn belangrijk voor modules.
- Bekijk de kleurenmixer eens wat beter, en je vragen worden beantwoord. - Bekijk de kleurenmixer eens wat beter, en je vragen worden beantwoord.
- Gebruik <b>CTRL</b> + klik om een gebied te selecteren. - Have a closer look at the color mixer, and your questions will be answered.
- Te dicht bij de HUB bouwen kan latere projecten in de weg staan. - Use <b>CTRL</b> + Click to select an area.
- Met het speldpictogram naast elke vorm in de upgradelijst zet deze vast op - Met het speldpictogram naast elke vorm in de upgradelijst zet deze vast op
het scherm. het scherm.
- Meng alle primaire kleuren door elkaar om wit te maken! - Meng alle primaire kleuren door elkaar om wit te maken!
@ -1216,6 +1221,7 @@ tips:
- Druk twee keer op F4 om de tegel van je muis en camera weer te geven. - 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 - Je kan aan de linkerkant op een vastgezette vorm klikken om deze los te
maken. maken.
- You can click a pinned shape on the left side to unpin it.
puzzleMenu: puzzleMenu:
play: Spelen play: Spelen
edit: Bewerken edit: Bewerken
@ -1261,6 +1267,21 @@ puzzleMenu:
easy: Makkelijk easy: Makkelijk
medium: Medium medium: Medium
hard: Moeilijk hard: Moeilijk
unknown: Unrated
search:
action: Search
placeholder: Enter a puzzle or author name
includeCompleted: Include Completed
difficulties:
any: Any Difficulty
easy: Easy
medium: Medium
hard: Hard
durations:
any: Any Duration
short: Short (< 2 min)
medium: Normal
long: Long (> 10 min)
backendErrors: backendErrors:
ratelimit: Je voert je handelingen te vaak uit. Wacht alstublieft even. ratelimit: Je voert je handelingen te vaak uit. Wacht alstublieft even.
invalid-api-key: Kan niet communiceren met de servers, probeer alstublieft het invalid-api-key: Kan niet communiceren met de servers, probeer alstublieft het

View File

@ -464,6 +464,7 @@ ingame:
fremtiden fremtiden
continueBtn: Fortsett å spill continueBtn: Fortsett å spill
menuBtn: Meny menuBtn: Meny
nextPuzzle: Next Puzzle
puzzleMetadata: puzzleMetadata:
author: Laget av author: Laget av
shortKey: Kort Kode shortKey: Kort Kode
@ -1022,7 +1023,12 @@ settings:
title: Kart Ressursser Størrelse title: Kart Ressursser Størrelse
description: Kontrollerer størrelsen på former på kartoversikten (når zoomet description: Kontrollerer størrelsen på former på kartoversikten (når zoomet
ut). ut).
shapeTooltipAlwaysOn:
title: Shape Tooltip - Show Always
description: Whether to always show the shape tooltip when hovering buildings,
instead of having to hold 'ALT'.
rangeSliderPercentage: <amount> % rangeSliderPercentage: <amount> %
tickrateHz: <amount> Hz
keybindings: keybindings:
title: Hurtigtaster title: Hurtigtaster
hint: "Tips: Husk å bruke CTRL, SHIFT and ALT! De gir deg flere hint: "Tips: Husk å bruke CTRL, SHIFT and ALT! De gir deg flere
@ -1104,6 +1110,7 @@ keybindings:
goal_acceptor: Mål Mottaker goal_acceptor: Mål Mottaker
block: Blokker block: Blokker
massSelectClear: Tøm Belter massSelectClear: Tøm Belter
showShapeTooltip: Show shape output tooltip
about: about:
title: Om dette spillet title: Om dette spillet
body: >- body: >-
@ -1236,8 +1243,23 @@ puzzleMenu:
easy: Easy easy: Easy
medium: Medium medium: Medium
hard: Hard hard: Hard
unknown: Unrated
dlcHint: Purchased the DLC already? Make sure it is activated by right clicking dlcHint: Purchased the DLC already? Make sure it is activated by right clicking
shapez.io in your library, selecting Properties > DLCs. shapez.io in your library, selecting Properties > DLCs.
search:
action: Search
placeholder: Enter a puzzle or author name
includeCompleted: Include Completed
difficulties:
any: Any Difficulty
easy: Easy
medium: Medium
hard: Hard
durations:
any: Any Duration
short: Short (< 2 min)
medium: Normal
long: Long (> 10 min)
backendErrors: backendErrors:
ratelimit: Du gjør en handling for ofte. Vennligst vent litt. ratelimit: Du gjør en handling for ofte. Vennligst vent litt.
invalid-api-key: Kunne ikke kommunisere med kjernen, vennligst prøv å invalid-api-key: Kunne ikke kommunisere med kjernen, vennligst prøv å

View File

@ -465,6 +465,7 @@ ingame:
titleRatingDesc: Your rating will help me to make you better suggestions in the future titleRatingDesc: Your rating will help me to make you better suggestions in the future
continueBtn: Keep Playing continueBtn: Keep Playing
menuBtn: Menu menuBtn: Menu
nextPuzzle: Next Puzzle
puzzleMetadata: puzzleMetadata:
author: Author author: Author
shortKey: Short Key shortKey: Short Key
@ -1029,7 +1030,12 @@ settings:
title: Rozmiar mapy zasobów title: Rozmiar mapy zasobów
description: Steruje rozmiarem kształtów w przeglądzie mapy (podczas description: Steruje rozmiarem kształtów w przeglądzie mapy (podczas
pomniejszenia). pomniejszenia).
shapeTooltipAlwaysOn:
title: Shape Tooltip - Show Always
description: Whether to always show the shape tooltip when hovering buildings,
instead of having to hold 'ALT'.
rangeSliderPercentage: <amount> % rangeSliderPercentage: <amount> %
tickrateHz: <amount> Hz
keybindings: keybindings:
title: Klawiszologia title: Klawiszologia
hint: "Wskazówka: Upewnij się, że wykorzystujesz CTRL, SHIFT i ALT! Pozwalają na hint: "Wskazówka: Upewnij się, że wykorzystujesz CTRL, SHIFT i ALT! Pozwalają na
@ -1111,6 +1117,7 @@ keybindings:
goal_acceptor: Goal Acceptor goal_acceptor: Goal Acceptor
block: Block block: Block
massSelectClear: Clear belts massSelectClear: Clear belts
showShapeTooltip: Show shape output tooltip
about: about:
title: O Grze title: O Grze
body: 'Ta gra jest open-source. Rozwijana jest przez <a body: 'Ta gra jest open-source. Rozwijana jest przez <a
@ -1251,8 +1258,23 @@ puzzleMenu:
easy: Easy easy: Easy
medium: Medium medium: Medium
hard: Hard hard: Hard
unknown: Unrated
dlcHint: Purchased the DLC already? Make sure it is activated by right clicking dlcHint: Purchased the DLC already? Make sure it is activated by right clicking
shapez.io in your library, selecting Properties > DLCs. shapez.io in your library, selecting Properties > DLCs.
search:
action: Search
placeholder: Enter a puzzle or author name
includeCompleted: Include Completed
difficulties:
any: Any Difficulty
easy: Easy
medium: Medium
hard: Hard
durations:
any: Any Duration
short: Short (< 2 min)
medium: Normal
long: Long (> 10 min)
backendErrors: backendErrors:
ratelimit: You are performing your actions too frequent. Please wait a bit. ratelimit: You are performing your actions too frequent. Please wait a bit.
invalid-api-key: Failed to communicate with the backend, please try to invalid-api-key: Failed to communicate with the backend, please try to

View File

@ -466,6 +466,7 @@ ingame:
titleRatingDesc: Sua avaliação me ajuda a te fazer sugestões melhores no futuro! titleRatingDesc: Sua avaliação me ajuda a te fazer sugestões melhores no futuro!
continueBtn: Continuar jogando continueBtn: Continuar jogando
menuBtn: Menu menuBtn: Menu
nextPuzzle: Next Puzzle
puzzleMetadata: puzzleMetadata:
author: Autor author: Autor
shortKey: Código shortKey: Código
@ -1038,7 +1039,12 @@ settings:
title: Tamanho do Mapa de Recursos title: Tamanho do Mapa de Recursos
description: Controla o tamanho das formas no mapa de panorama (quando afasta o description: Controla o tamanho das formas no mapa de panorama (quando afasta o
zoom). zoom).
shapeTooltipAlwaysOn:
title: Shape Tooltip - Show Always
description: Whether to always show the shape tooltip when hovering buildings,
instead of having to hold 'ALT'.
rangeSliderPercentage: <amount> % rangeSliderPercentage: <amount> %
tickrateHz: <amount> Hz
keybindings: keybindings:
title: Controles title: Controles
hint: "Dica: Certifique-se de usar CTRL, SHIFT e ALT! Eles permitem diferentes hint: "Dica: Certifique-se de usar CTRL, SHIFT e ALT! Eles permitem diferentes
@ -1120,6 +1126,7 @@ keybindings:
goal_acceptor: Receptor de Objetivo goal_acceptor: Receptor de Objetivo
block: Bloco block: Bloco
massSelectClear: Limpar esteiras massSelectClear: Limpar esteiras
showShapeTooltip: Show shape output tooltip
about: about:
title: Sobre o jogo title: Sobre o jogo
body: >- body: >-
@ -1257,8 +1264,23 @@ puzzleMenu:
easy: Easy easy: Easy
medium: Medium medium: Medium
hard: Hard hard: Hard
unknown: Unrated
dlcHint: Purchased the DLC already? Make sure it is activated by right clicking dlcHint: Purchased the DLC already? Make sure it is activated by right clicking
shapez.io in your library, selecting Properties > DLCs. shapez.io in your library, selecting Properties > DLCs.
search:
action: Search
placeholder: Enter a puzzle or author name
includeCompleted: Include Completed
difficulties:
any: Any Difficulty
easy: Easy
medium: Medium
hard: Hard
durations:
any: Any Duration
short: Short (< 2 min)
medium: Normal
long: Long (> 10 min)
backendErrors: backendErrors:
ratelimit: Você está fazendo coisas muito rapidamente. Por favor espere um pouco. ratelimit: Você está fazendo coisas muito rapidamente. Por favor espere um pouco.
invalid-api-key: Falha ao comunicar com o backend, por favor tente invalid-api-key: Falha ao comunicar com o backend, por favor tente

View File

@ -476,6 +476,7 @@ ingame:
titleRatingDesc: A tua avaliação ajudar-me-á a fazer melhores sugestões no futuro titleRatingDesc: A tua avaliação ajudar-me-á a fazer melhores sugestões no futuro
continueBtn: Continua a Jogar continueBtn: Continua a Jogar
menuBtn: Menu menuBtn: Menu
nextPuzzle: Next Puzzle
puzzleMetadata: puzzleMetadata:
author: Autor author: Autor
shortKey: Pequeno Código shortKey: Pequeno Código
@ -1047,7 +1048,12 @@ settings:
title: Tamanho de Recursos no Mapa title: Tamanho de Recursos no Mapa
description: Controla o tamanho das formas na visão geral do mapa (aplicando description: Controla o tamanho das formas na visão geral do mapa (aplicando
zoom out). zoom out).
shapeTooltipAlwaysOn:
title: Shape Tooltip - Show Always
description: Whether to always show the shape tooltip when hovering buildings,
instead of having to hold 'ALT'.
rangeSliderPercentage: <amount> % rangeSliderPercentage: <amount> %
tickrateHz: <amount> Hz
keybindings: keybindings:
title: Atalhos title: Atalhos
hint: "Dica: Utiliza o CTRL, o SHIFT e o ALT! Eles permitem diferentes opções de hint: "Dica: Utiliza o CTRL, o SHIFT e o ALT! Eles permitem diferentes opções de
@ -1129,6 +1135,7 @@ keybindings:
goal_acceptor: Recetor de Objetivo goal_acceptor: Recetor de Objetivo
block: Bloqueador block: Bloqueador
massSelectClear: Limpar tapetes rolante massSelectClear: Limpar tapetes rolante
showShapeTooltip: Show shape output tooltip
about: about:
title: Sobre o Jogo title: Sobre o Jogo
body: >- body: >-
@ -1268,8 +1275,23 @@ puzzleMenu:
easy: Fácil easy: Fácil
medium: Médio medium: Médio
hard: Difícil hard: Difícil
unknown: Unrated
dlcHint: Purchased the DLC already? Make sure it is activated by right clicking dlcHint: Purchased the DLC already? Make sure it is activated by right clicking
shapez.io in your library, selecting Properties > DLCs. shapez.io in your library, selecting Properties > DLCs.
search:
action: Search
placeholder: Enter a puzzle or author name
includeCompleted: Include Completed
difficulties:
any: Any Difficulty
easy: Easy
medium: Medium
hard: Hard
durations:
any: Any Duration
short: Short (< 2 min)
medium: Normal
long: Long (> 10 min)
backendErrors: backendErrors:
ratelimit: Estás a realizar as tuas ações demasiado rápido. Aguarda um pouco. ratelimit: Estás a realizar as tuas ações demasiado rápido. Aguarda um pouco.
invalid-api-key: Falha ao cominucar com o backend, por favor tenta invalid-api-key: Falha ao cominucar com o backend, por favor tenta

View File

@ -466,6 +466,7 @@ ingame:
titleRatingDesc: Your rating will help me to make you better suggestions in the future titleRatingDesc: Your rating will help me to make you better suggestions in the future
continueBtn: Keep Playing continueBtn: Keep Playing
menuBtn: Menu menuBtn: Menu
nextPuzzle: Next Puzzle
puzzleMetadata: puzzleMetadata:
author: Author author: Author
shortKey: Short Key shortKey: Short Key
@ -1024,7 +1025,12 @@ settings:
title: Map Resources Size title: Map Resources Size
description: Controls the size of the shapes on the map overview (when zooming description: Controls the size of the shapes on the map overview (when zooming
out). out).
shapeTooltipAlwaysOn:
title: Shape Tooltip - Show Always
description: Whether to always show the shape tooltip when hovering buildings,
instead of having to hold 'ALT'.
rangeSliderPercentage: <amount> % rangeSliderPercentage: <amount> %
tickrateHz: <amount> Hz
keybindings: keybindings:
title: Tastele setate title: Tastele setate
hint: "Indiciu: Asigură-te că foloseșto CTRL, SHIFT și ALT! Ele activează hint: "Indiciu: Asigură-te că foloseșto CTRL, SHIFT și ALT! Ele activează
@ -1106,6 +1112,7 @@ keybindings:
goal_acceptor: Goal Acceptor goal_acceptor: Goal Acceptor
block: Block block: Block
massSelectClear: Clear belts massSelectClear: Clear belts
showShapeTooltip: Show shape output tooltip
about: about:
title: Despre acest joc title: Despre acest joc
body: >- body: >-
@ -1233,8 +1240,23 @@ puzzleMenu:
easy: Easy easy: Easy
medium: Medium medium: Medium
hard: Hard hard: Hard
unknown: Unrated
dlcHint: Purchased the DLC already? Make sure it is activated by right clicking dlcHint: Purchased the DLC already? Make sure it is activated by right clicking
shapez.io in your library, selecting Properties > DLCs. shapez.io in your library, selecting Properties > DLCs.
search:
action: Search
placeholder: Enter a puzzle or author name
includeCompleted: Include Completed
difficulties:
any: Any Difficulty
easy: Easy
medium: Medium
hard: Hard
durations:
any: Any Duration
short: Short (< 2 min)
medium: Normal
long: Long (> 10 min)
backendErrors: backendErrors:
ratelimit: You are performing your actions too frequent. Please wait a bit. ratelimit: You are performing your actions too frequent. Please wait a bit.
invalid-api-key: Failed to communicate with the backend, please try to invalid-api-key: Failed to communicate with the backend, please try to

View File

@ -468,6 +468,7 @@ ingame:
titleRatingDesc: Ваша оценка поможет мне в будущем делать вам лучшие предложения titleRatingDesc: Ваша оценка поможет мне в будущем делать вам лучшие предложения
continueBtn: Продолжить игру continueBtn: Продолжить игру
menuBtn: Меню menuBtn: Меню
nextPuzzle: Next Puzzle
puzzleMetadata: puzzleMetadata:
author: Автор author: Автор
shortKey: Короткий ключ shortKey: Короткий ключ
@ -1031,6 +1032,11 @@ settings:
mapResourcesScale: mapResourcesScale:
title: Размер ресурсов на карте title: Размер ресурсов на карте
description: Устанавливает размер фигур на карте (когда вид достаточно отдалён). 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
keybindings: keybindings:
title: Настройки управления title: Настройки управления
hint: "Подсказка: Обязательно используйте CTRL, SHIFT и ALT! Они дают разные hint: "Подсказка: Обязательно используйте CTRL, SHIFT и ALT! Они дают разные
@ -1108,10 +1114,11 @@ keybindings:
placementDisableAutoOrientation: Отключить автоопределение направления placementDisableAutoOrientation: Отключить автоопределение направления
placeMultiple: Оставаться в режиме размещения placeMultiple: Оставаться в режиме размещения
placeInverse: Инвертировать автоопределение направления конвейеров placeInverse: Инвертировать автоопределение направления конвейеров
constant_producer: Constant Producer constant_producer: Постоянный генератор
goal_acceptor: Goal Acceptor goal_acceptor: Приёмник предметов
block: Block block: Блок
massSelectClear: Clear belts massSelectClear: Очистить конвейеры
showShapeTooltip: Show shape output tooltip
about: about:
title: Об игре title: Об игре
body: >- body: >-
@ -1245,11 +1252,26 @@ puzzleMenu:
постоянные производители не доставляют фигуры напрямую приемникам постоянные производители не доставляют фигуры напрямую приемникам
цели. цели.
difficulties: difficulties:
easy: Лего easy: Легко
medium: Средне medium: Средне
hard: Сложно hard: Сложно
dlcHint: Purchased the DLC already? Make sure it is activated by right clicking unknown: Unrated
shapez.io in your library, selecting Properties > DLCs. dlcHint: Уже купили DLC? Проверьте, что оно активировано, нажав правый клик на
shapez.io в своей библиотеке, и далее Свойства > Доп. Контент
search:
action: Search
placeholder: Enter a puzzle or author name
includeCompleted: Include Completed
difficulties:
any: Any Difficulty
easy: Easy
medium: Medium
hard: Hard
durations:
any: Any Duration
short: Short (< 2 min)
medium: Normal
long: Long (> 10 min)
backendErrors: backendErrors:
ratelimit: Вы слишком часто выполняете свои действия. Подождите немного. ratelimit: Вы слишком часто выполняете свои действия. Подождите немного.
invalid-api-key: Не удалось связаться с сервером, попробуйте invalid-api-key: Не удалось связаться с сервером, попробуйте

View File

@ -459,6 +459,7 @@ ingame:
titleRatingDesc: Your rating will help me to make you better suggestions in the future titleRatingDesc: Your rating will help me to make you better suggestions in the future
continueBtn: Keep Playing continueBtn: Keep Playing
menuBtn: Menu menuBtn: Menu
nextPuzzle: Next Puzzle
puzzleMetadata: puzzleMetadata:
author: Author author: Author
shortKey: Short Key shortKey: Short Key
@ -1006,7 +1007,12 @@ settings:
title: Map Resources Size title: Map Resources Size
description: Controls the size of the shapes on the map overview (when zooming description: Controls the size of the shapes on the map overview (when zooming
out). out).
shapeTooltipAlwaysOn:
title: Shape Tooltip - Show Always
description: Whether to always show the shape tooltip when hovering buildings,
instead of having to hold 'ALT'.
rangeSliderPercentage: <amount> % rangeSliderPercentage: <amount> %
tickrateHz: <amount> Hz
keybindings: keybindings:
title: Keybindings title: Keybindings
hint: "Tip: Be sure to make use of CTRL, SHIFT and ALT! They enable different hint: "Tip: Be sure to make use of CTRL, SHIFT and ALT! They enable different
@ -1088,6 +1094,7 @@ keybindings:
goal_acceptor: Goal Acceptor goal_acceptor: Goal Acceptor
block: Block block: Block
massSelectClear: Clear belts massSelectClear: Clear belts
showShapeTooltip: Show shape output tooltip
about: about:
title: About this Game title: About this Game
body: >- body: >-
@ -1215,8 +1222,23 @@ puzzleMenu:
easy: Easy easy: Easy
medium: Medium medium: Medium
hard: Hard hard: Hard
unknown: Unrated
dlcHint: Purchased the DLC already? Make sure it is activated by right clicking dlcHint: Purchased the DLC already? Make sure it is activated by right clicking
shapez.io in your library, selecting Properties > DLCs. shapez.io in your library, selecting Properties > DLCs.
search:
action: Search
placeholder: Enter a puzzle or author name
includeCompleted: Include Completed
difficulties:
any: Any Difficulty
easy: Easy
medium: Medium
hard: Hard
durations:
any: Any Duration
short: Short (< 2 min)
medium: Normal
long: Long (> 10 min)
backendErrors: backendErrors:
ratelimit: You are performing your actions too frequent. Please wait a bit. ratelimit: You are performing your actions too frequent. Please wait a bit.
invalid-api-key: Failed to communicate with the backend, please try to invalid-api-key: Failed to communicate with the backend, please try to

File diff suppressed because it is too large Load Diff

View File

@ -463,6 +463,7 @@ ingame:
titleRatingDesc: Your rating will help me to make you better suggestions in the future titleRatingDesc: Your rating will help me to make you better suggestions in the future
continueBtn: Keep Playing continueBtn: Keep Playing
menuBtn: Menu menuBtn: Menu
nextPuzzle: Next Puzzle
puzzleMetadata: puzzleMetadata:
author: Author author: Author
shortKey: Short Key shortKey: Short Key
@ -1014,7 +1015,12 @@ settings:
title: Map Resources Size title: Map Resources Size
description: Controls the size of the shapes on the map overview (when zooming description: Controls the size of the shapes on the map overview (when zooming
out). out).
shapeTooltipAlwaysOn:
title: Shape Tooltip - Show Always
description: Whether to always show the shape tooltip when hovering buildings,
instead of having to hold 'ALT'.
rangeSliderPercentage: <amount> % rangeSliderPercentage: <amount> %
tickrateHz: <amount> Hz
keybindings: keybindings:
title: Snabbtangenter title: Snabbtangenter
hint: "Tips: Se till att använda CTRL, SKIFT, och ALT! De låter dig använda hint: "Tips: Se till att använda CTRL, SKIFT, och ALT! De låter dig använda
@ -1096,6 +1102,7 @@ keybindings:
goal_acceptor: Goal Acceptor goal_acceptor: Goal Acceptor
block: Block block: Block
massSelectClear: Clear belts massSelectClear: Clear belts
showShapeTooltip: Show shape output tooltip
about: about:
title: Om detta spel title: Om detta spel
body: >- body: >-
@ -1223,8 +1230,23 @@ puzzleMenu:
easy: Easy easy: Easy
medium: Medium medium: Medium
hard: Hard hard: Hard
unknown: Unrated
dlcHint: Purchased the DLC already? Make sure it is activated by right clicking dlcHint: Purchased the DLC already? Make sure it is activated by right clicking
shapez.io in your library, selecting Properties > DLCs. shapez.io in your library, selecting Properties > DLCs.
search:
action: Search
placeholder: Enter a puzzle or author name
includeCompleted: Include Completed
difficulties:
any: Any Difficulty
easy: Easy
medium: Medium
hard: Hard
durations:
any: Any Duration
short: Short (< 2 min)
medium: Normal
long: Long (> 10 min)
backendErrors: backendErrors:
ratelimit: You are performing your actions too frequent. Please wait a bit. ratelimit: You are performing your actions too frequent. Please wait a bit.
invalid-api-key: Failed to communicate with the backend, please try to invalid-api-key: Failed to communicate with the backend, please try to

Some files were not shown because too many files have changed in this diff Show More