1
0
mirror of https://github.com/tobspr/shapez.io.git synced 2025-06-13 13:04:03 +00:00

Merge branch 'master' into french-pedantry

This commit is contained in:
Leopold Tal G 2020-09-13 11:20:22 +02:00
commit 6413ed6e88
33 changed files with 11093 additions and 10959 deletions

View File

@ -1,99 +1,100 @@
{
"name": "shapez.io",
"version": "1.0.0",
"main": "index.js",
"repository": "https://github.com/tobspr/shapez.io",
"author": "Tobias Springer <tobias.springer1@gmail.com>",
"license": "MIT",
"private": true,
"scripts": {
"dev": "cd gulp && yarn gulp main.serveDev",
"tslint": "cd src/js && tsc",
"lint": "eslint src/js",
"prettier-all": "prettier --write src/**/*.* && prettier --write gulp/**/*.*",
"publishOnItchWindows": "butler push tmp_standalone_files/shapez.io-standalone-win32-x64 tobspr/shapezio:windows --userversion-file version",
"publishOnItchLinux": "butler push tmp_standalone_files/shapez.io-standalone-linux-x64 tobspr/shapezio:linux --userversion-file version",
"publishOnItch": "yarn publishOnItchWindows && yarn publishOnItchLinux",
"publishOnSteam": "cd gulp/steampipe && ./upload.bat",
"publishStandalone": "yarn publishOnItch && yarn publishOnSteam",
"publishWeb": "cd gulp && yarn main.deploy.prod",
"publish": "yarn publishStandalone && yarn publishWeb",
"syncTranslations": "node sync-translations.js"
},
"dependencies": {
"@babel/core": "^7.5.4",
"@babel/plugin-transform-block-scoping": "^7.4.4",
"@babel/plugin-transform-classes": "^7.5.5",
"@babel/preset-env": "^7.5.4",
"@types/cordova": "^0.0.34",
"@types/filesystem": "^0.0.29",
"ajv": "^6.10.2",
"babel-loader": "^8.0.4",
"circular-dependency-plugin": "^5.0.2",
"circular-json": "^0.5.9",
"clipboard-copy": "^3.1.0",
"colors": "^1.3.3",
"core-js": "3",
"crc": "^3.8.0",
"cssnano-preset-advanced": "^4.0.7",
"email-validator": "^2.0.4",
"eslint": "7.1.0",
"fastdom": "^1.0.8",
"flatted": "^2.0.1",
"howler": "^2.1.2",
"html-loader": "^0.5.5",
"ignore-loader": "^0.1.2",
"logrocket": "^1.0.7",
"lz-string": "^1.4.4",
"markdown-loader": "^4.0.0",
"match-all": "^1.2.5",
"phonegap-plugin-mobile-accessibility": "^1.0.5",
"promise-polyfill": "^8.1.0",
"query-string": "^6.8.1",
"rusha": "^0.8.13",
"serialize-error": "^3.0.0",
"strictdom": "^1.0.1",
"string-replace-webpack-plugin": "^0.1.3",
"terser-webpack-plugin": "^1.1.0",
"typescript": "3.9.3",
"uglify-template-string-loader": "^1.1.0",
"unused-files-webpack-plugin": "^3.4.0",
"webpack": "^4.43.0",
"webpack-bundle-analyzer": "^3.0.3",
"webpack-cli": "^3.1.0",
"webpack-deep-scope-plugin": "^1.6.0",
"webpack-plugin-replace": "^1.1.1",
"webpack-strip-block": "^0.2.0",
"whatwg-fetch": "^3.0.0",
"worker-loader": "^2.0.0",
"yaml": "^1.10.0",
"yawn-yaml": "^1.5.0"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "3.0.1",
"@typescript-eslint/parser": "3.0.1",
"autoprefixer": "^9.4.3",
"babel-plugin-closure-elimination": "^1.3.0",
"babel-plugin-console-source": "^2.0.2",
"babel-plugin-danger-remove-unused-import": "^1.1.2",
"css-mqpacker": "^7.0.0",
"cssnano": "^4.1.10",
"eslint-config-prettier": "6.11.0",
"eslint-plugin-prettier": "3.1.3",
"faster.js": "^1.1.0",
"glob": "^7.1.3",
"imagemin-mozjpeg": "^8.0.0",
"imagemin-pngquant": "^8.0.0",
"jimp": "^0.6.1",
"js-yaml": "^3.13.1",
"postcss-assets": "^5.0.0",
"postcss-preset-env": "^6.5.0",
"postcss-round-subpixels": "^1.2.0",
"postcss-unprefix": "^2.1.3",
"prettier": "^2.0.4",
"sass-unused": "^0.3.0",
"strip-json-comments": "^3.0.1",
"trim": "^0.0.1",
"yarn": "^1.22.4"
}
}
{
"name": "shapez.io",
"version": "1.0.0",
"main": "index.js",
"repository": "https://github.com/tobspr/shapez.io",
"author": "Tobias Springer <tobias.springer1@gmail.com>",
"license": "MIT",
"private": true,
"scripts": {
"dev": "cd gulp && yarn gulp main.serveDev",
"tslint": "cd src/js && tsc",
"lint": "eslint src/js",
"prettier-all": "prettier --write src/**/*.* && prettier --write gulp/**/*.*",
"publishOnItchWindows": "butler push tmp_standalone_files/shapez.io-standalone-win32-x64 tobspr/shapezio:windows --userversion-file version",
"publishOnItchLinux": "butler push tmp_standalone_files/shapez.io-standalone-linux-x64 tobspr/shapezio:linux --userversion-file version",
"publishOnItch": "yarn publishOnItchWindows && yarn publishOnItchLinux",
"publishOnSteam": "cd gulp/steampipe && ./upload.bat",
"publishStandalone": "yarn publishOnItch && yarn publishOnSteam",
"publishWeb": "cd gulp && yarn main.deploy.prod",
"publish": "yarn publishStandalone && yarn publishWeb",
"syncTranslations": "node sync-translations.js"
},
"dependencies": {
"@babel/core": "^7.5.4",
"@babel/plugin-transform-block-scoping": "^7.4.4",
"@babel/plugin-transform-classes": "^7.5.5",
"@babel/preset-env": "^7.5.4",
"@types/cordova": "^0.0.34",
"@types/filesystem": "^0.0.29",
"ajv": "^6.10.2",
"babel-loader": "^8.0.4",
"circular-dependency-plugin": "^5.0.2",
"circular-json": "^0.5.9",
"clipboard-copy": "^3.1.0",
"colors": "^1.3.3",
"core-js": "3",
"crc": "^3.8.0",
"cssnano-preset-advanced": "^4.0.7",
"debounce-promise": "^3.1.2",
"email-validator": "^2.0.4",
"eslint": "7.1.0",
"fastdom": "^1.0.8",
"flatted": "^2.0.1",
"howler": "^2.1.2",
"html-loader": "^0.5.5",
"ignore-loader": "^0.1.2",
"logrocket": "^1.0.7",
"lz-string": "^1.4.4",
"markdown-loader": "^4.0.0",
"match-all": "^1.2.5",
"phonegap-plugin-mobile-accessibility": "^1.0.5",
"promise-polyfill": "^8.1.0",
"query-string": "^6.8.1",
"rusha": "^0.8.13",
"serialize-error": "^3.0.0",
"strictdom": "^1.0.1",
"string-replace-webpack-plugin": "^0.1.3",
"terser-webpack-plugin": "^1.1.0",
"typescript": "3.9.3",
"uglify-template-string-loader": "^1.1.0",
"unused-files-webpack-plugin": "^3.4.0",
"webpack": "^4.43.0",
"webpack-bundle-analyzer": "^3.0.3",
"webpack-cli": "^3.1.0",
"webpack-deep-scope-plugin": "^1.6.0",
"webpack-plugin-replace": "^1.1.1",
"webpack-strip-block": "^0.2.0",
"whatwg-fetch": "^3.0.0",
"worker-loader": "^2.0.0",
"yaml": "^1.10.0",
"yawn-yaml": "^1.5.0"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "3.0.1",
"@typescript-eslint/parser": "3.0.1",
"autoprefixer": "^9.4.3",
"babel-plugin-closure-elimination": "^1.3.0",
"babel-plugin-console-source": "^2.0.2",
"babel-plugin-danger-remove-unused-import": "^1.1.2",
"css-mqpacker": "^7.0.0",
"cssnano": "^4.1.10",
"eslint-config-prettier": "6.11.0",
"eslint-plugin-prettier": "3.1.3",
"faster.js": "^1.1.0",
"glob": "^7.1.3",
"imagemin-mozjpeg": "^8.0.0",
"imagemin-pngquant": "^8.0.0",
"jimp": "^0.6.1",
"js-yaml": "^3.13.1",
"postcss-assets": "^5.0.0",
"postcss-preset-env": "^6.5.0",
"postcss-round-subpixels": "^1.2.0",
"postcss-unprefix": "^2.1.3",
"prettier": "^2.0.4",
"sass-unused": "^0.3.0",
"strip-json-comments": "^3.0.1",
"trim": "^0.0.1",
"yarn": "^1.22.4"
}
}

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a4f810fcfbfcea08cfb48a8d58f9b65d1fd14cd20ff3cabf94a03c39b5250547
size 1765124
oid sha256:3207e92c0fa5e71030d04c739647032be2697bf910eb7b7d9548bf04e95803b1
size 1223220

View File

@ -351,12 +351,12 @@ canvas {
box-sizing: border-box;
}
.pressed {
.pressed:not(.noPressEffect) {
transform: scale(0.98) !important;
animation: none !important;
}
.pressedSmallElement {
.pressedSmallElement:not(.noPressEffect) {
transform: scale(0.88) !important;
animation: none !important;
}
@ -570,36 +570,46 @@ canvas {
}
}
.range {
.rangeInputContainer {
display: flex;
align-items: center;
justify-content: center;
label {
@include S(margin-right, 5px);
&,
& * {
@include PlainText;
}
}
}
.range-input {
input.rangeInput {
cursor: pointer;
background-color: transparent;
width: 100px;
height: 10px;
transform: translate(7px, 2px);
@include S(width, 100px);
@include S(height, 16px);
&::-webkit-slider-runnable-track {
background-color: darken($mainBgColor, 3);
color: darken($mainBgColor, 3);
height: 16px;
border-radius: 8px;
// @include S(height, 16px);
@include S(border-radius, 8px);
}
&::-webkit-slider-thumb {
appearance: none;
-webkit-appearance: none;
box-shadow: inset 0 0 0 10px $themeColor;
background-color: transparent;
width: 20px;
height: 20px;
box-shadow: inset 0 0 0 D(10px) $themeColor;
border-radius: 50%;
transition: 0.3s;
transition: box-shadow 0.3s;
}
&:hover::-webkit-slider-thumb {
box-shadow: inset 0 0 0 10px lighten($themeColor, 15);
&:hover {
&::-webkit-slider-thumb {
box-shadow: inset 0 0 0 D(10px) lighten($themeColor, 15);
}
}
}

View File

@ -18,6 +18,14 @@
background-color: #55585a;
}
transition: opacity 0.1s ease-out;
&.hovered {
opacity: 0.1;
.buildingImage {
opacity: 0;
}
}
.buildingLabel {
@include PlainText;
@include S(margin-bottom, 2px);
@ -70,6 +78,7 @@
@include S(height, 100px);
background: top left / 100% 100% no-repeat;
@include S(border-radius, $globalBorderRadius);
transition: opacity 0.1s ease-in-out;
}
@include StyleBelowWidth(700px) {

View File

@ -1,160 +1,147 @@
#ingame_HUD_GameMenu {
position: absolute;
top: 0;
right: 0;
display: flex;
grid-auto-flow: column;
> .menuButtons {
position: relative;
display: flex;
flex-grow: 1;
@include S(padding, 5px, 4px);
justify-content: flex-end;
@include S(margin-left, 20px);
> .button {
@include S(width, 30px);
@include S(height, 30px);
display: inline-block;
background: center center / 60% no-repeat;
pointer-events: all;
cursor: pointer;
transition: all 0.12s ease-in-out;
transition-property: opacity, transform;
will-change: opacity;
opacity: 0.9;
@include S(margin-left, 5px);
position: relative;
@include IncreasedClickArea(0px);
@include DarkThemeInvert;
&:hover {
opacity: 0.8;
}
&.music {
background-image: uiResource("icons/music_on.png");
&.muted {
background-image: uiResource("icons/music_off.png");
}
}
&.sfx {
background-image: uiResource("icons/sound_on.png");
&.muted {
background-image: uiResource("icons/sound_off.png");
}
}
&.save {
background-image: uiResource("icons/save.png");
@include MakeAnimationWrappedEvenOdd(0.5s ease-in-out) {
0% {
transform: scale(1, 1);
}
70% {
transform: scale(1.5, 1.5) rotate(20deg);
opacity: 0.2;
}
85% {
transform: scale(0.9, 0.9);
opacity: 1;
}
90% {
transform: scale(1.1, 1.1);
}
}
}
&.settings {
background-image: uiResource("icons/settings.png");
}
}
}
.buttonContainer button {
@include PlainText;
color: #fff;
border-color: rgba(0, 0, 0, 0.1);
@include S(padding, 5px, 5px, 5px);
@include S(padding-left, 30px);
@include S(margin-right, 3px);
@include IncreasedClickArea(0px);
@include ButtonText;
@include S(min-height, 40px);
transition: all 0.12s ease-in-out;
transition-property: opacity, transform;
display: inline-flex;
background: center #{D(13px)} / #{D(20px)} no-repeat;
background-color: $colorGreenBright;
&[data-button-id="shop"] {
background-color: rgb(93, 103, 250);
background-image: uiResource("icons/shop.png");
background-size: #{D(18px)};
}
&[data-button-id="stats"] {
background-color: rgb(85, 199, 138);
background-image: uiResource("icons/statistics.png");
}
&:hover {
opacity: 0.9;
}
.keybinding {
border: 0;
color: #fff;
border-top-left-radius: 0;
border-top-right-radius: 0;
bottom: unset;
background: transparent;
@include S(top, 0px);
right: unset;
left: 50%;
transform: translateX(-50%);
}
&:not(.hasBadge) .badge {
display: none;
}
&.hasBadge {
transform-origin: 50% 0%;
@include InlineAnimation(1s ease-in-out infinite) {
50% {
transform: scale(1.02);
}
}
.badge {
position: absolute;
@include S(bottom, -8px);
left: 50%;
transform: translateX(-50%);
background: #333;
@include PlainText;
display: flex;
justify-content: center;
align-items: center;
@include S(min-width, 5px);
@include S(height, 10px);
@include S(padding, 1px, 3px, 2px);
@include S(border-radius, $globalBorderRadius);
border: #{D(1px)} solid #fff;
@include InlineAnimation(1s ease-in-out infinite) {
50% {
transform: translateX(-50%) scale(1.05);
}
}
}
}
}
}
#ingame_HUD_GameMenu {
position: absolute;
top: 0;
right: 0;
display: flex;
grid-auto-flow: column;
> .menuButtons {
position: relative;
display: flex;
flex-grow: 1;
@include S(padding, 5px, 4px);
justify-content: flex-end;
@include S(margin-left, 20px);
> .button {
@include S(width, 30px);
@include S(height, 30px);
display: inline-block;
background: center center / 60% no-repeat;
pointer-events: all;
cursor: pointer;
transition: all 0.12s ease-in-out;
transition-property: opacity, transform;
will-change: opacity;
opacity: 0.9;
@include S(margin-left, 5px);
position: relative;
@include IncreasedClickArea(0px);
@include DarkThemeInvert;
&:hover {
opacity: 0.8;
}
&.save {
background-image: uiResource("icons/save.png");
@include MakeAnimationWrappedEvenOdd(0.5s ease-in-out) {
0% {
transform: scale(1, 1);
}
70% {
transform: scale(1.5, 1.5) rotate(20deg);
opacity: 0.2;
}
85% {
transform: scale(0.9, 0.9);
opacity: 1;
}
90% {
transform: scale(1.1, 1.1);
}
}
}
&.settings {
background-image: uiResource("icons/settings.png");
}
}
}
.buttonContainer button {
@include PlainText;
color: #fff;
border-color: rgba(0, 0, 0, 0.1);
@include S(padding, 5px, 5px, 5px);
@include S(padding-left, 30px);
@include S(margin-right, 3px);
@include IncreasedClickArea(0px);
@include ButtonText;
@include S(min-height, 40px);
transition: all 0.12s ease-in-out;
transition-property: opacity, transform;
display: inline-flex;
background: center #{D(13px)} / #{D(20px)} no-repeat;
background-color: $colorGreenBright;
&[data-button-id="shop"] {
background-color: rgb(93, 103, 250);
background-image: uiResource("icons/shop.png");
background-size: #{D(18px)};
}
&[data-button-id="stats"] {
background-color: rgb(85, 199, 138);
background-image: uiResource("icons/statistics.png");
}
&:hover {
opacity: 0.9;
}
.keybinding {
border: 0;
color: #fff;
border-top-left-radius: 0;
border-top-right-radius: 0;
bottom: unset;
background: transparent;
@include S(top, 0px);
right: unset;
left: 50%;
transform: translateX(-50%);
}
&:not(.hasBadge) .badge {
display: none;
}
&.hasBadge {
transform-origin: 50% 0%;
@include InlineAnimation(1s ease-in-out infinite) {
50% {
transform: scale(1.02);
}
}
.badge {
position: absolute;
@include S(bottom, -8px);
left: 50%;
transform: translateX(-50%);
background: #333;
@include PlainText;
display: flex;
justify-content: center;
align-items: center;
@include S(min-width, 5px);
@include S(height, 10px);
@include S(padding, 1px, 3px, 2px);
@include S(border-radius, $globalBorderRadius);
border: #{D(1px)} solid #fff;
@include InlineAnimation(1s ease-in-out infinite) {
50% {
transform: translateX(-50%) scale(1.05);
}
}
}
}
}
}

View File

@ -29,6 +29,16 @@
}
}
pointer-events: all;
transition: opacity 0.1s ease-out;
&.hovered {
opacity: 10%;
.helperGif {
opacity: 0%;
}
}
.title {
color: #fff;
opacity: 0.5;
@ -48,5 +58,6 @@
@include S(margin-top, 5px);
@include S(height, 150px);
background: center center / contain no-repeat;
transition: opacity 0.1s ease-out;
}
}

View File

@ -1,69 +1,74 @@
#ingame_HUD_KeybindingOverlay {
position: absolute;
@include S(top, 10px);
@include S(left, 10px);
display: flex;
flex-direction: column;
align-items: flex-start;
color: #333438;
backdrop-filter: blur(D(2px));
padding: D(3px);
@include DarkThemeOverride {
color: #fff;
}
> .binding {
&:not(.visible) {
display: none !important;
}
display: inline-grid;
@include PlainText;
align-items: center;
@include S(margin-bottom, 3px);
grid-auto-flow: column;
@include S(grid-gap, 2px);
i {
display: inline-block;
@include S(height, 10px);
width: 1px;
@include S(margin, 0, 3px);
background-color: #fff;
transform: rotate(10deg);
// @include S(margin, 0, 3px);
}
code {
position: relative;
top: unset;
left: unset;
margin: 0;
&.rightMouse {
background: #fff uiResource("icons/mouse_right.png") center center / 85% no-repeat;
}
&.leftMouse {
background: #fff uiResource("icons/mouse_left.png") center center / 85% no-repeat;
}
}
label {
color: #333438;
@include SuperSmallText;
text-transform: uppercase;
// color: #fff;
@include DarkThemeOverride {
color: #fff;
}
@include S(margin-left, 5px);
}
}
}
body.uiHidden #ingame_HUD_KeybindingOverlay .binding:not(.hudToggle) {
display: none;
}
#ingame_HUD_KeybindingOverlay {
position: absolute;
@include S(top, 10px);
@include S(left, 10px);
display: flex;
flex-direction: column;
align-items: flex-start;
color: #333438;
backdrop-filter: blur(D(2px));
padding: D(3px);
@include DarkThemeOverride {
color: #fff;
}
transition: opacity 0.1s ease-out;
&.hovered {
opacity: 0.1;
}
> .binding {
&:not(.visible) {
display: none !important;
}
display: inline-grid;
@include PlainText;
align-items: center;
@include S(margin-bottom, 3px);
grid-auto-flow: column;
@include S(grid-gap, 2px);
i {
display: inline-block;
@include S(height, 10px);
width: 1px;
@include S(margin, 0, 3px);
background-color: #fff;
transform: rotate(10deg);
// @include S(margin, 0, 3px);
}
code {
position: relative;
top: unset;
left: unset;
margin: 0;
&.rightMouse {
background: #fff uiResource("icons/mouse_right.png") center center / 85% no-repeat;
}
&.leftMouse {
background: #fff uiResource("icons/mouse_left.png") center center / 85% no-repeat;
}
}
label {
color: #333438;
@include SuperSmallText;
text-transform: uppercase;
// color: #fff;
@include DarkThemeOverride {
color: #fff;
}
@include S(margin-left, 5px);
}
}
}
body.uiHidden #ingame_HUD_KeybindingOverlay .binding:not(.hudToggle) {
display: none;
}

View File

@ -1,95 +1,107 @@
#ingame_HUD_Waypoints_Hint {
position: absolute;
@include S(right, 10px);
@include S(bottom, 10px);
display: flex;
flex-direction: column;
@include PlainText;
@include S(width, 150px);
background: rgba(0, 10, 20, 0.5);
@include S(padding, 5px);
color: #eee;
.desc {
@include SuperSmallText;
color: #babcbf;
.keybinding {
position: relative;
}
strong {
color: #fff;
}
}
}
#ingame_HUD_Waypoints {
position: absolute;
@include S(right, 10px);
@include S(top, 45px);
display: flex;
flex-direction: column;
@include DarkThemeInvert();
.waypoint {
@include SuperSmallText;
pointer-events: all;
cursor: pointer;
color: #333438;
@include S(padding-left, 11px);
display: grid;
grid-template-columns: 1fr auto;
align-items: center;
background: uiResource("icons/waypoint.png") left 50% / #{D(8px)} no-repeat;
opacity: 0.7;
@include S(margin-bottom, 1px);
font-weight: bold;
&:hover {
opacity: 0.8;
}
.editButton {
@include S(width, 10px);
@include S(height, 10px);
@include S(margin-left, 4px);
background: uiResource("icons/edit_key.png") center center / 70% no-repeat;
pointer-events: all;
cursor: pointer;
position: relative;
@include IncreasedClickArea(2px);
transition: transform 0.04s ease-in-out;
&:hover {
transform: scale(1.5);
}
}
&.hub {
// Transform because there is a canvas before
@include S(margin-left, -2px);
grid-template-columns: auto 1fr;
background: none !important;
@include S(padding-left, 0);
canvas {
@include S(width, 12px);
@include S(height, 12px);
@include S(margin-right, 1px);
}
}
&.shapeIcon {
canvas {
@include S(width, 15px);
@include S(height, 15px);
pointer-events: none;
// Double invert, to make sure it has the right color
@include DarkThemeInvert();
}
}
}
}
#ingame_HUD_Waypoints_Hint {
position: absolute;
@include S(right, 10px);
@include S(bottom, 10px);
display: flex;
flex-direction: column;
@include PlainText;
@include S(width, 150px);
background: rgba(0, 10, 20, 0.5);
@include S(padding, 5px);
color: #eee;
.desc {
@include SuperSmallText;
color: #babcbf;
.keybinding {
position: relative;
}
strong {
color: #fff;
}
}
}
#ingame_HUD_Waypoints {
position: absolute;
@include S(right, 10px);
@include S(top, 45px);
display: flex;
flex-direction: column;
@include DarkThemeInvert();
max-height: 50vh;
overflow-x: hidden;
overflow-y: auto;
pointer-events: all;
@include S(padding-right, 5px);
// Scrollbar
&::-webkit-scrollbar {
@include S(width, 2px);
@include S(height, 6px);
}
.waypoint {
@include SuperSmallText;
pointer-events: all;
cursor: pointer;
color: #333438;
@include S(padding-left, 11px);
display: grid;
grid-template-columns: 1fr auto;
align-items: center;
background: uiResource("icons/waypoint.png") left 50% / #{D(8px)} no-repeat;
opacity: 0.7;
@include S(margin-bottom, 1px);
font-weight: bold;
&:hover {
opacity: 0.8;
}
.editButton {
@include S(width, 10px);
@include S(height, 10px);
@include S(margin-left, 4px);
background: uiResource("icons/edit_key.png") center center / 70% no-repeat;
pointer-events: all;
cursor: pointer;
position: relative;
@include IncreasedClickArea(2px);
transition: transform 0.04s ease-in-out;
&:hover {
transform: scale(1.5);
}
}
&.hub {
// Transform because there is a canvas before
@include S(margin-left, -2px);
grid-template-columns: auto 1fr;
background: none !important;
@include S(padding-left, 0);
canvas {
@include S(width, 12px);
@include S(height, 12px);
@include S(margin-right, 1px);
}
}
&.shapeIcon {
canvas {
@include S(width, 15px);
@include S(height, 15px);
pointer-events: none;
// Double invert, to make sure it has the right color
@include DarkThemeInvert();
}
}
}
}

View File

@ -1,188 +1,188 @@
#state_SettingsState {
$colorCategoryButton: #eee;
$colorCategoryButtonSelected: #5f748b;
.container .content {
display: flex;
overflow-y: scroll;
.categoryContainer {
width: 100%;
.category {
display: none;
&.active {
display: block;
}
.setting {
@include S(padding, 10px);
background: #eeeff5;
@include S(border-radius, $globalBorderRadius);
@include S(margin-bottom, 5px);
label {
text-transform: uppercase;
@include Text;
}
.desc {
@include S(margin-top, 5px);
@include SuperSmallText;
color: #aaadb2;
}
> .row {
display: grid;
align-items: center;
grid-template-columns: 1fr auto;
}
&.disabled {
// opacity: 0.3;
pointer-events: none;
* {
pointer-events: none !important;
cursor: default !important;
}
position: relative;
.standaloneOnlyHint {
@include PlainText;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
pointer-events: all;
display: flex;
align-items: center;
justify-content: center;
background: rgba(#fff, 0.5);
text-transform: uppercase;
color: $colorRedBright;
}
}
.value.enum {
background: #fff;
@include PlainText;
display: flex;
align-items: flex-start;
pointer-events: all;
cursor: pointer;
justify-content: center;
@include S(min-width, 100px);
@include S(border-radius, $globalBorderRadius);
@include S(padding, 4px);
@include S(padding-right, 15px);
background: #fff uiResource("icons/enum_selector.png") calc(100% - #{D(5px)})
calc(50% + #{D(1px)}) / #{D(15px)} no-repeat;
transition: background-color 0.12s ease-in-out;
&:hover {
background-color: #fafafa;
}
}
}
}
}
.sidebar {
display: flex;
flex-direction: column;
@include S(min-width, 210px);
@include S(max-width, 320px);
width: 30%;
height: 100%;
position: sticky;
top: 0;
@include S(margin-left, 20px);
@include S(margin-right, 32px);
.other {
margin-top: auto;
}
button {
@include S(margin-top, 4px);
width: calc(100% - #{D(20px)});
text-align: start;
&::after {
content: unset;
}
}
button.categoryButton,
button.about {
background-color: $colorCategoryButton;
color: #777a7f;
&.active {
background-color: $colorCategoryButtonSelected;
color: #fff;
&:hover {
opacity: 1;
}
}
&.pressed {
transform: none !important;
}
}
.versionbar {
@include S(margin-top, 20px);
@include SuperSmallText;
display: grid;
align-items: center;
grid-template-columns: 1fr auto;
.buildVersion {
display: flex;
flex-direction: column;
color: #aaadaf;
}
}
}
}
@include DarkThemeOverride {
.container .content {
.sidebar {
button.categoryButton,
button.about {
background-color: #3f3f47;
&.active {
background-color: $colorBlueBright;
}
}
}
.categoryContainer {
.category {
.setting {
background: darken($darkModeGameBackground, 10);
.value.enum {
// dirty but works
filter: invert(0.78) sepia(40%) hue-rotate(190deg);
color: #222;
}
.value.checkbox {
background-color: #74767b;
&.checked {
background-color: $colorBlueBright;
}
}
}
}
}
}
}
}
#state_SettingsState {
$colorCategoryButton: #eee;
$colorCategoryButtonSelected: #5f748b;
.container .content {
display: flex;
overflow-y: scroll;
.categoryContainer {
width: 100%;
.category {
display: none;
&.active {
display: block;
}
.setting {
@include S(padding, 10px);
background: #eeeff5;
@include S(border-radius, $globalBorderRadius);
@include S(margin-bottom, 5px);
.desc {
@include S(margin-top, 5px);
@include SuperSmallText;
color: #aaadb2;
}
> .row {
display: grid;
align-items: center;
grid-template-columns: 1fr auto;
> label {
text-transform: uppercase;
@include Text;
}
}
&.disabled {
// opacity: 0.3;
pointer-events: none;
* {
pointer-events: none !important;
cursor: default !important;
}
position: relative;
.standaloneOnlyHint {
@include PlainText;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
pointer-events: all;
display: flex;
align-items: center;
justify-content: center;
background: rgba(#fff, 0.5);
text-transform: uppercase;
color: $colorRedBright;
}
}
.value.enum {
background: #fff;
@include PlainText;
display: flex;
align-items: flex-start;
pointer-events: all;
cursor: pointer;
justify-content: center;
@include S(min-width, 100px);
@include S(border-radius, $globalBorderRadius);
@include S(padding, 4px);
@include S(padding-right, 15px);
background: #fff uiResource("icons/enum_selector.png") calc(100% - #{D(5px)})
calc(50% + #{D(1px)}) / #{D(15px)} no-repeat;
transition: background-color 0.12s ease-in-out;
&:hover {
background-color: #fafafa;
}
}
}
}
}
.sidebar {
display: flex;
flex-direction: column;
@include S(min-width, 210px);
@include S(max-width, 320px);
width: 30%;
height: 100%;
position: sticky;
top: 0;
@include S(margin-left, 20px);
@include S(margin-right, 32px);
.other {
margin-top: auto;
}
button {
@include S(margin-top, 4px);
width: calc(100% - #{D(20px)});
text-align: start;
&::after {
content: unset;
}
}
button.categoryButton,
button.about {
background-color: $colorCategoryButton;
color: #777a7f;
&.active {
background-color: $colorCategoryButtonSelected;
color: #fff;
&:hover {
opacity: 1;
}
}
&.pressed {
transform: none !important;
}
}
.versionbar {
@include S(margin-top, 20px);
@include SuperSmallText;
display: grid;
align-items: center;
grid-template-columns: 1fr auto;
.buildVersion {
display: flex;
flex-direction: column;
color: #aaadaf;
}
}
}
}
@include DarkThemeOverride {
.container .content {
.sidebar {
button.categoryButton,
button.about {
background-color: #3f3f47;
&.active {
background-color: $colorBlueBright;
}
}
}
.categoryContainer {
.category {
.setting {
background: darken($darkModeGameBackground, 10);
.value.enum {
// dirty but works
filter: invert(0.78) sepia(40%) hue-rotate(190deg);
color: #222;
}
.value.checkbox {
background-color: #74767b;
&.checked {
background-color: $colorBlueBright;
}
}
}
}
}
}
}
}

View File

@ -18,14 +18,18 @@ export const CHANGELOG = [
"Tier 2 tunnels are now 9 tiles wide, so the gap between is 8 tiles (double the tier 1 range)",
"Updated and added new translations (Thanks to all contributors!)",
"Added setting to be able to delete buildings while placing (inspired by hexy)",
"You can now adjust the sound and music volumes! (inspired by Yoshie2000)",
"Some hud elements now have reduced opacity when hovering, so you can see through (inspired by mvb005)",
"Mark pinned shapes in statistics dialog and show them first (inspired by davidburhans)",
"Added setting to show chunk borders",
"Quad painters have been reworked! They now are integrated with the wires, and only paint the shape when the value is 1 (inspired by dengr1605)",
"There are now compact 1x1 splitters available to be unlocked!",
"Replaced level completion sound to be less distracting",
"Allow editing waypoints (by isaisstillalive)",
"Show confirmation when cutting area which is too expensive to get pasted again (by isaisstillalive)",
"Show mouse and camera tile on debug overlay (F4) (by dengr)",
"Fix tunnels entrances connecting to exits sometimes when they shouldn't",
"Fixed tunnels entrances connecting to exits sometimes when they shouldn't",
"Added setting to auto select the extractor when pipetting a resource patch (by Exund)",
"The initial belt planner direction is now based on the cursor movement (by MizardX)",
"Fix preferred variant not getting saved when clicking on the hud (by Danacus)",
],

View File

@ -1,331 +1,347 @@
/* typehints:start */
import { Application } from "../application";
/* typehints:end */
import { sha1, CRC_PREFIX, computeCrc } from "./sensitive_utils.encrypt";
import { createLogger } from "./logging";
import { FILE_NOT_FOUND } from "../platform/storage";
import { accessNestedPropertyReverse } from "./utils";
import { IS_DEBUG, globalConfig } from "./config";
import { ExplainedResult } from "./explained_result";
import { decompressX64, compressX64 } from "./lzstring";
import { asyncCompressor, compressionPrefix } from "./async_compression";
import { compressObject, decompressObject } from "../savegame/savegame_compressor";
const logger = createLogger("read_write_proxy");
const salt = accessNestedPropertyReverse(globalConfig, ["file", "info"]);
// Helper which only writes / reads if verify() works. Also performs migration
export class ReadWriteProxy {
constructor(app, filename) {
/** @type {Application} */
this.app = app;
this.filename = filename;
/** @type {object} */
this.currentData = null;
// TODO: EXTREMELY HACKY! To verify we need to do this a step later
if (G_IS_DEV && IS_DEBUG) {
setTimeout(() => {
assert(
this.verify(this.getDefaultData()).result,
"Verify() failed for default data: " + this.verify(this.getDefaultData()).reason
);
});
}
}
// -- Methods to override
/** @returns {ExplainedResult} */
verify(data) {
abstract;
return ExplainedResult.bad();
}
// Should return the default data
getDefaultData() {
abstract;
return {};
}
// Should return the current version as an integer
getCurrentVersion() {
abstract;
return 0;
}
// Should migrate the data (Modify in place)
/** @returns {ExplainedResult} */
migrate(data) {
abstract;
return ExplainedResult.bad();
}
// -- / Methods
// Resets whole data, returns promise
resetEverythingAsync() {
logger.warn("Reset data to default");
this.currentData = this.getDefaultData();
return this.writeAsync();
}
getCurrentData() {
return this.currentData;
}
/**
*
* @param {object} obj
*/
static serializeObject(obj) {
const jsonString = JSON.stringify(compressObject(obj));
const checksum = computeCrc(jsonString + salt);
return compressionPrefix + compressX64(checksum + jsonString);
}
/**
*
* @param {object} text
*/
static deserializeObject(text) {
const decompressed = decompressX64(text.substr(compressionPrefix.length));
if (!decompressed) {
// LZ string decompression failure
throw new Error("bad-content / decompression-failed");
}
if (decompressed.length < 40) {
// String too short
throw new Error("bad-content / payload-too-small");
}
// Compare stored checksum with actual checksum
const checksum = decompressed.substring(0, 40);
const jsonString = decompressed.substr(40);
const desiredChecksum = checksum.startsWith(CRC_PREFIX)
? computeCrc(jsonString + salt)
: sha1(jsonString + salt);
if (desiredChecksum !== checksum) {
// Checksum mismatch
throw new Error("bad-content / checksum-mismatch");
}
const parsed = JSON.parse(jsonString);
const decoded = decompressObject(parsed);
return decoded;
}
/**
* Writes the data asychronously, fails if verify() fails
* @returns {Promise<void>}
*/
writeAsync() {
const verifyResult = this.internalVerifyEntry(this.currentData);
if (!verifyResult.result) {
logger.error("Tried to write invalid data to", this.filename, "reason:", verifyResult.reason);
return Promise.reject(verifyResult.reason);
}
return asyncCompressor
.compressObjectAsync(this.currentData)
.then(compressed => {
return this.app.storage.writeFileAsync(this.filename, compressed);
})
.then(() => {
logger.log("📄 Wrote", this.filename);
})
.catch(err => {
logger.error("Failed to write", this.filename, ":", err);
throw err;
});
}
// Reads the data asynchronously, fails if verify() fails
readAsync() {
// Start read request
return (
this.app.storage
.readFileAsync(this.filename)
// Check for errors during read
.catch(err => {
if (err === FILE_NOT_FOUND) {
logger.log("File not found, using default data");
// File not found or unreadable, assume default file
return Promise.resolve(null);
}
return Promise.reject("file-error: " + err);
})
// Decrypt data (if its encrypted)
// @ts-ignore
.then(rawData => {
if (rawData == null) {
// So, the file has not been found, use default data
return JSON.stringify(compressObject(this.getDefaultData()));
}
if (rawData.startsWith(compressionPrefix)) {
const decompressed = decompressX64(rawData.substr(compressionPrefix.length));
if (!decompressed) {
// LZ string decompression failure
return Promise.reject("bad-content / decompression-failed");
}
if (decompressed.length < 40) {
// String too short
return Promise.reject("bad-content / payload-too-small");
}
// Compare stored checksum with actual checksum
const checksum = decompressed.substring(0, 40);
const jsonString = decompressed.substr(40);
const desiredChecksum = checksum.startsWith(CRC_PREFIX)
? computeCrc(jsonString + salt)
: sha1(jsonString + salt);
if (desiredChecksum !== checksum) {
// Checksum mismatch
return Promise.reject(
"bad-content / checksum-mismatch: " + desiredChecksum + " vs " + checksum
);
}
return jsonString;
} else {
if (!G_IS_DEV) {
return Promise.reject("bad-content / missing-compression");
}
}
return rawData;
})
// Parse JSON, this could throw but thats fine
.then(res => {
try {
return JSON.parse(res);
} catch (ex) {
logger.error(
"Failed to parse file content of",
this.filename,
":",
ex,
"(content was:",
res,
")"
);
throw new Error("invalid-serialized-data");
}
})
// Decompress
.then(compressed => decompressObject(compressed))
// Verify basic structure
.then(contents => {
const result = this.internalVerifyBasicStructure(contents);
if (!result.isGood()) {
return Promise.reject("verify-failed: " + result.reason);
}
return contents;
})
// Check version and migrate if required
.then(contents => {
if (contents.version > this.getCurrentVersion()) {
return Promise.reject("stored-data-is-newer");
}
if (contents.version < this.getCurrentVersion()) {
logger.log(
"Trying to migrate data object from version",
contents.version,
"to",
this.getCurrentVersion()
);
const migrationResult = this.migrate(contents); // modify in place
if (migrationResult.isBad()) {
return Promise.reject("migration-failed: " + migrationResult.reason);
}
}
return contents;
})
// Verify
.then(contents => {
const verifyResult = this.internalVerifyEntry(contents);
if (!verifyResult.result) {
logger.error(
"Read invalid data from",
this.filename,
"reason:",
verifyResult.reason,
"contents:",
contents
);
return Promise.reject("invalid-data: " + verifyResult.reason);
}
return contents;
})
// Store
.then(contents => {
this.currentData = contents;
logger.log("📄 Read data with version", this.currentData.version, "from", this.filename);
return contents;
})
// Catchall
.catch(err => {
return Promise.reject("Failed to read " + this.filename + ": " + err);
})
);
}
/**
* Deletes the file
* @returns {Promise<void>}
*/
deleteAsync() {
return this.app.storage.deleteFileAsync(this.filename);
}
// Internal
/** @returns {ExplainedResult} */
internalVerifyBasicStructure(data) {
if (!data) {
return ExplainedResult.bad("Data is empty");
}
if (!Number.isInteger(data.version) || data.version < 0) {
return ExplainedResult.bad(
`Data has invalid version: ${data.version} (expected ${this.getCurrentVersion()})`
);
}
return ExplainedResult.good();
}
/** @returns {ExplainedResult} */
internalVerifyEntry(data) {
if (data.version !== this.getCurrentVersion()) {
return ExplainedResult.bad(
"Version mismatch, got " + data.version + " and expected " + this.getCurrentVersion()
);
}
const verifyStructureError = this.internalVerifyBasicStructure(data);
if (!verifyStructureError.isGood()) {
return verifyStructureError;
}
return this.verify(data);
}
}
/* typehints:start */
import { Application } from "../application";
/* typehints:end */
import { sha1, CRC_PREFIX, computeCrc } from "./sensitive_utils.encrypt";
import { createLogger } from "./logging";
import { FILE_NOT_FOUND } from "../platform/storage";
import { accessNestedPropertyReverse } from "./utils";
import { IS_DEBUG, globalConfig } from "./config";
import { ExplainedResult } from "./explained_result";
import { decompressX64, compressX64 } from "./lzstring";
import { asyncCompressor, compressionPrefix } from "./async_compression";
import { compressObject, decompressObject } from "../savegame/savegame_compressor";
const debounce = require("debounce-promise");
const logger = createLogger("read_write_proxy");
const salt = accessNestedPropertyReverse(globalConfig, ["file", "info"]);
// Helper which only writes / reads if verify() works. Also performs migration
export class ReadWriteProxy {
constructor(app, filename) {
/** @type {Application} */
this.app = app;
this.filename = filename;
/** @type {object} */
this.currentData = null;
// TODO: EXTREMELY HACKY! To verify we need to do this a step later
if (G_IS_DEV && IS_DEBUG) {
setTimeout(() => {
assert(
this.verify(this.getDefaultData()).result,
"Verify() failed for default data: " + this.verify(this.getDefaultData()).reason
);
});
}
/**
* Store a debounced handler to prevent double writes
*/
this.debouncedWrite = debounce(this.doWriteAsync.bind(this), 50);
}
// -- Methods to override
/** @returns {ExplainedResult} */
verify(data) {
abstract;
return ExplainedResult.bad();
}
// Should return the default data
getDefaultData() {
abstract;
return {};
}
// Should return the current version as an integer
getCurrentVersion() {
abstract;
return 0;
}
// Should migrate the data (Modify in place)
/** @returns {ExplainedResult} */
migrate(data) {
abstract;
return ExplainedResult.bad();
}
// -- / Methods
// Resets whole data, returns promise
resetEverythingAsync() {
logger.warn("Reset data to default");
this.currentData = this.getDefaultData();
return this.writeAsync();
}
getCurrentData() {
return this.currentData;
}
/**
*
* @param {object} obj
*/
static serializeObject(obj) {
const jsonString = JSON.stringify(compressObject(obj));
const checksum = computeCrc(jsonString + salt);
return compressionPrefix + compressX64(checksum + jsonString);
}
/**
*
* @param {object} text
*/
static deserializeObject(text) {
const decompressed = decompressX64(text.substr(compressionPrefix.length));
if (!decompressed) {
// LZ string decompression failure
throw new Error("bad-content / decompression-failed");
}
if (decompressed.length < 40) {
// String too short
throw new Error("bad-content / payload-too-small");
}
// Compare stored checksum with actual checksum
const checksum = decompressed.substring(0, 40);
const jsonString = decompressed.substr(40);
const desiredChecksum = checksum.startsWith(CRC_PREFIX)
? computeCrc(jsonString + salt)
: sha1(jsonString + salt);
if (desiredChecksum !== checksum) {
// Checksum mismatch
throw new Error("bad-content / checksum-mismatch");
}
const parsed = JSON.parse(jsonString);
const decoded = decompressObject(parsed);
return decoded;
}
/**
* Writes the data asychronously, fails if verify() fails.
* Debounces the operation by up to 50ms
* @returns {Promise<void>}
*/
writeAsync() {
const verifyResult = this.internalVerifyEntry(this.currentData);
if (!verifyResult.result) {
logger.error("Tried to write invalid data to", this.filename, "reason:", verifyResult.reason);
return Promise.reject(verifyResult.reason);
}
return this.debouncedWrite();
}
/**
* Actually writes the data asychronously
* @returns {Promise<void>}
*/
doWriteAsync() {
return asyncCompressor
.compressObjectAsync(this.currentData)
.then(compressed => {
return this.app.storage.writeFileAsync(this.filename, compressed);
})
.then(() => {
logger.log("📄 Wrote", this.filename);
})
.catch(err => {
logger.error("Failed to write", this.filename, ":", err);
throw err;
});
}
// Reads the data asynchronously, fails if verify() fails
readAsync() {
// Start read request
return (
this.app.storage
.readFileAsync(this.filename)
// Check for errors during read
.catch(err => {
if (err === FILE_NOT_FOUND) {
logger.log("File not found, using default data");
// File not found or unreadable, assume default file
return Promise.resolve(null);
}
return Promise.reject("file-error: " + err);
})
// Decrypt data (if its encrypted)
// @ts-ignore
.then(rawData => {
if (rawData == null) {
// So, the file has not been found, use default data
return JSON.stringify(compressObject(this.getDefaultData()));
}
if (rawData.startsWith(compressionPrefix)) {
const decompressed = decompressX64(rawData.substr(compressionPrefix.length));
if (!decompressed) {
// LZ string decompression failure
return Promise.reject("bad-content / decompression-failed");
}
if (decompressed.length < 40) {
// String too short
return Promise.reject("bad-content / payload-too-small");
}
// Compare stored checksum with actual checksum
const checksum = decompressed.substring(0, 40);
const jsonString = decompressed.substr(40);
const desiredChecksum = checksum.startsWith(CRC_PREFIX)
? computeCrc(jsonString + salt)
: sha1(jsonString + salt);
if (desiredChecksum !== checksum) {
// Checksum mismatch
return Promise.reject(
"bad-content / checksum-mismatch: " + desiredChecksum + " vs " + checksum
);
}
return jsonString;
} else {
if (!G_IS_DEV) {
return Promise.reject("bad-content / missing-compression");
}
}
return rawData;
})
// Parse JSON, this could throw but thats fine
.then(res => {
try {
return JSON.parse(res);
} catch (ex) {
logger.error(
"Failed to parse file content of",
this.filename,
":",
ex,
"(content was:",
res,
")"
);
throw new Error("invalid-serialized-data");
}
})
// Decompress
.then(compressed => decompressObject(compressed))
// Verify basic structure
.then(contents => {
const result = this.internalVerifyBasicStructure(contents);
if (!result.isGood()) {
return Promise.reject("verify-failed: " + result.reason);
}
return contents;
})
// Check version and migrate if required
.then(contents => {
if (contents.version > this.getCurrentVersion()) {
return Promise.reject("stored-data-is-newer");
}
if (contents.version < this.getCurrentVersion()) {
logger.log(
"Trying to migrate data object from version",
contents.version,
"to",
this.getCurrentVersion()
);
const migrationResult = this.migrate(contents); // modify in place
if (migrationResult.isBad()) {
return Promise.reject("migration-failed: " + migrationResult.reason);
}
}
return contents;
})
// Verify
.then(contents => {
const verifyResult = this.internalVerifyEntry(contents);
if (!verifyResult.result) {
logger.error(
"Read invalid data from",
this.filename,
"reason:",
verifyResult.reason,
"contents:",
contents
);
return Promise.reject("invalid-data: " + verifyResult.reason);
}
return contents;
})
// Store
.then(contents => {
this.currentData = contents;
logger.log("📄 Read data with version", this.currentData.version, "from", this.filename);
return contents;
})
// Catchall
.catch(err => {
return Promise.reject("Failed to read " + this.filename + ": " + err);
})
);
}
/**
* Deletes the file
* @returns {Promise<void>}
*/
deleteAsync() {
return this.app.storage.deleteFileAsync(this.filename);
}
// Internal
/** @returns {ExplainedResult} */
internalVerifyBasicStructure(data) {
if (!data) {
return ExplainedResult.bad("Data is empty");
}
if (!Number.isInteger(data.version) || data.version < 0) {
return ExplainedResult.bad(
`Data has invalid version: ${data.version} (expected ${this.getCurrentVersion()})`
);
}
return ExplainedResult.good();
}
/** @returns {ExplainedResult} */
internalVerifyEntry(data) {
if (data.version !== this.getCurrentVersion()) {
return ExplainedResult.bad(
"Version mismatch, got " + data.version + " and expected " + this.getCurrentVersion()
);
}
const verifyStructureError = this.internalVerifyBasicStructure(data);
if (!verifyStructureError.isGood()) {
return verifyStructureError;
}
return this.verify(data);
}
}

View File

@ -1,3 +1,4 @@
import { TrackedState } from "../../core/tracked_state";
import { GameRoot } from "../root";
// Automatically attaches and detaches elements from the dom
@ -7,15 +8,28 @@ import { GameRoot } from "../root";
// Also attaches a class name if desired
export class DynamicDomAttach {
constructor(root, element, { timeToKeepSeconds = 0, attachClass = null } = {}) {
/**
*
* @param {GameRoot} root
* @param {HTMLElement} element
* @param {object} param2
* @param {number=} param2.timeToKeepSeconds How long to keep the element visible (in ms) after it should be hidden.
* Useful for fade-out effects
* @param {string=} param2.attachClass If set, attaches a class while the element is visible
* @param {boolean=} param2.trackHover If set, attaches the 'hovered' class if the cursor is above the element. Useful
* for fading out the element if its below the cursor for example.
*/
constructor(root, element, { timeToKeepSeconds = 0, attachClass = null, trackHover = false } = {}) {
/** @type {GameRoot} */
this.root = root;
/** @type {HTMLElement} */
this.element = element;
this.parent = this.element.parentElement;
assert(this.parent, "Dom attach created without parent");
this.attachClass = attachClass;
this.trackHover = trackHover;
this.timeToKeepSeconds = timeToKeepSeconds;
this.lastVisibleTime = 0;
@ -26,8 +40,19 @@ export class DynamicDomAttach {
this.internalIsClassAttached = false;
this.classAttachTimeout = null;
// Store the last bounds we computed
/** @type {DOMRect} */
this.lastComputedBounds = null;
this.lastComputedBoundsTime = -1;
// Track the 'hovered' class
this.trackedIsHovered = new TrackedState(this.setIsHoveredClass, this);
}
/**
* Internal method to attach the element
*/
internalAttach() {
if (!this.attached) {
this.parent.appendChild(this.element);
@ -36,6 +61,9 @@ export class DynamicDomAttach {
}
}
/**
* Internal method to detach the element
*/
internalDetach() {
if (this.attached) {
assert(this.element.parentElement === this.parent, "Invalid parent #2");
@ -44,14 +72,50 @@ export class DynamicDomAttach {
}
}
/**
* Returns whether the element is currently attached
*/
isAttached() {
return this.attached;
}
/**
* Actually sets the 'hovered' class
* @param {boolean} isHovered
*/
setIsHoveredClass(isHovered) {
this.element.classList.toggle("hovered", isHovered);
}
/**
* Call this every frame, and the dom attach class will take care of
* everything else
* @param {boolean} isVisible Whether the element should currently be visible or not
*/
update(isVisible) {
if (isVisible) {
this.lastVisibleTime = this.root ? this.root.time.realtimeNow() : 0;
this.internalAttach();
if (this.trackHover && this.root) {
let bounds = this.lastComputedBounds;
// Recompute bounds only once in a while
if (!bounds || this.root.time.realtimeNow() - this.lastComputedBoundsTime > 1.0) {
bounds = this.lastComputedBounds = this.element.getBoundingClientRect();
this.lastComputedBoundsTime = this.root.time.realtimeNow();
}
const mousePos = this.root.app.mousePosition;
if (mousePos) {
this.trackedIsHovered.set(
mousePos.x > bounds.left &&
mousePos.x < bounds.right &&
mousePos.y > bounds.top &&
mousePos.y < bounds.bottom
);
}
}
} else {
if (!this.root || this.root.time.realtimeNow() - this.lastVisibleTime >= this.timeToKeepSeconds) {
this.internalDetach();

View File

@ -55,7 +55,7 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic {
this.signals.variantChanged.add(this.rerenderVariants, this);
this.root.hud.signals.buildingSelectedForPlacement.add(this.startSelection, this);
this.domAttach = new DynamicDomAttach(this.root, this.element, {});
this.domAttach = new DynamicDomAttach(this.root, this.element, { trackHover: true });
this.variantsAttach = new DynamicDomAttach(this.root, this.variantsElement, {});
this.currentInterpolatedCornerTile = new Vector();

View File

@ -327,7 +327,7 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart {
const tileBelow = this.root.map.getLowerLayerContentXY(tile.x, tile.y);
// Check if there's a shape or color item below, if so select the miner
if (tileBelow) {
if (tileBelow && this.root.app.settings.getAllSettings().pickMinerOnPatch) {
this.currentMetaBuilding.set(gMetaBuildingRegistry.findByClass(MetaMinerBuilding));
// Select chained miner if available, since thats always desired once unlocked

View File

@ -1,188 +1,169 @@
import { BaseHUDPart } from "../base_hud_part";
import { makeDiv } from "../../../core/utils";
import { SOUNDS } from "../../../platform/sound";
import { enumNotificationType } from "./notifications";
import { T } from "../../../translations";
import { KEYMAPPINGS } from "../../key_action_mapper";
import { DynamicDomAttach } from "../dynamic_dom_attach";
export class HUDGameMenu extends BaseHUDPart {
createElements(parent) {
this.element = makeDiv(parent, "ingame_HUD_GameMenu");
const buttons = [
{
id: "shop",
label: "Upgrades",
handler: () => this.root.hud.parts.shop.show(),
keybinding: KEYMAPPINGS.ingame.menuOpenShop,
badge: () => this.root.hubGoals.getAvailableUpgradeCount(),
notification: /** @type {[string, enumNotificationType]} */ ([
T.ingame.notifications.newUpgrade,
enumNotificationType.upgrade,
]),
visible: () =>
!this.root.app.settings.getAllSettings().offerHints || this.root.hubGoals.level >= 3,
},
{
id: "stats",
label: "Stats",
handler: () => this.root.hud.parts.statistics.show(),
keybinding: KEYMAPPINGS.ingame.menuOpenStats,
visible: () =>
!this.root.app.settings.getAllSettings().offerHints || this.root.hubGoals.level >= 3,
},
];
/** @type {Array<{
* badge: function,
* button: HTMLElement,
* badgeElement: HTMLElement,
* lastRenderAmount: number,
* condition?: function,
* notification: [string, enumNotificationType]
* }>} */
this.badgesToUpdate = [];
/** @type {Array<{
* button: HTMLElement,
* condition: function,
* domAttach: DynamicDomAttach
* }>} */
this.visibilityToUpdate = [];
this.buttonsElement = makeDiv(this.element, null, ["buttonContainer"]);
buttons.forEach(({ id, label, handler, keybinding, badge, notification, visible }) => {
const button = document.createElement("button");
button.setAttribute("data-button-id", id);
this.buttonsElement.appendChild(button);
this.trackClicks(button, handler);
if (keybinding) {
const binding = this.root.keyMapper.getBinding(keybinding);
binding.add(handler);
binding.appendLabelToElement(button);
}
if (visible) {
this.visibilityToUpdate.push({
button,
condition: visible,
domAttach: new DynamicDomAttach(this.root, button),
});
}
if (badge) {
const badgeElement = makeDiv(button, null, ["badge"]);
this.badgesToUpdate.push({
badge,
lastRenderAmount: 0,
button,
badgeElement,
notification,
condition: visible,
});
}
});
const menuButtons = makeDiv(this.element, null, ["menuButtons"]);
this.musicButton = makeDiv(menuButtons, null, ["button", "music"]);
this.sfxButton = makeDiv(menuButtons, null, ["button", "sfx"]);
this.saveButton = makeDiv(menuButtons, null, ["button", "save", "animEven"]);
this.settingsButton = makeDiv(menuButtons, null, ["button", "settings"]);
this.trackClicks(this.musicButton, this.toggleMusic);
this.trackClicks(this.sfxButton, this.toggleSfx);
this.trackClicks(this.saveButton, this.startSave);
this.trackClicks(this.settingsButton, this.openSettings);
this.musicButton.classList.toggle("muted", this.root.app.settings.getAllSettings().musicMuted);
this.sfxButton.classList.toggle("muted", this.root.app.settings.getAllSettings().soundsMuted);
}
initialize() {
this.root.signals.gameSaved.add(this.onGameSaved, this);
}
update() {
let playSound = false;
let notifications = new Set();
// Update visibility of buttons
for (let i = 0; i < this.visibilityToUpdate.length; ++i) {
const { button, condition, domAttach } = this.visibilityToUpdate[i];
domAttach.update(condition());
}
// Check for notifications and badges
for (let i = 0; i < this.badgesToUpdate.length; ++i) {
const {
badge,
button,
badgeElement,
lastRenderAmount,
notification,
condition,
} = this.badgesToUpdate[i];
if (condition && !condition()) {
// Do not show notifications for invisible buttons
continue;
}
// Check if the amount shown differs from the one shown last frame
const amount = badge();
if (lastRenderAmount !== amount) {
if (amount > 0) {
badgeElement.innerText = amount;
}
// Check if the badge increased, if so play a notification
if (amount > lastRenderAmount) {
playSound = true;
if (notification) {
notifications.add(notification);
}
}
// Rerender notifications
this.badgesToUpdate[i].lastRenderAmount = amount;
button.classList.toggle("hasBadge", amount > 0);
}
}
if (playSound) {
this.root.soundProxy.playUi(SOUNDS.badgeNotification);
}
notifications.forEach(([notification, type]) => {
this.root.hud.signals.notification.dispatch(notification, type);
});
}
onGameSaved() {
this.saveButton.classList.toggle("animEven");
this.saveButton.classList.toggle("animOdd");
}
startSave() {
this.root.gameState.doSave();
}
openSettings() {
this.root.hud.parts.settingsMenu.show();
}
toggleMusic() {
const newValue = !this.root.app.settings.getAllSettings().musicMuted;
this.root.app.settings.updateSetting("musicMuted", newValue);
this.musicButton.classList.toggle("muted", newValue);
}
toggleSfx() {
const newValue = !this.root.app.settings.getAllSettings().soundsMuted;
this.root.app.settings.updateSetting("soundsMuted", newValue);
this.sfxButton.classList.toggle("muted", newValue);
}
}
import { BaseHUDPart } from "../base_hud_part";
import { makeDiv } from "../../../core/utils";
import { SOUNDS } from "../../../platform/sound";
import { enumNotificationType } from "./notifications";
import { T } from "../../../translations";
import { KEYMAPPINGS } from "../../key_action_mapper";
import { DynamicDomAttach } from "../dynamic_dom_attach";
export class HUDGameMenu extends BaseHUDPart {
createElements(parent) {
this.element = makeDiv(parent, "ingame_HUD_GameMenu");
const buttons = [
{
id: "shop",
label: "Upgrades",
handler: () => this.root.hud.parts.shop.show(),
keybinding: KEYMAPPINGS.ingame.menuOpenShop,
badge: () => this.root.hubGoals.getAvailableUpgradeCount(),
notification: /** @type {[string, enumNotificationType]} */ ([
T.ingame.notifications.newUpgrade,
enumNotificationType.upgrade,
]),
visible: () =>
!this.root.app.settings.getAllSettings().offerHints || this.root.hubGoals.level >= 3,
},
{
id: "stats",
label: "Stats",
handler: () => this.root.hud.parts.statistics.show(),
keybinding: KEYMAPPINGS.ingame.menuOpenStats,
visible: () =>
!this.root.app.settings.getAllSettings().offerHints || this.root.hubGoals.level >= 3,
},
];
/** @type {Array<{
* badge: function,
* button: HTMLElement,
* badgeElement: HTMLElement,
* lastRenderAmount: number,
* condition?: function,
* notification: [string, enumNotificationType]
* }>} */
this.badgesToUpdate = [];
/** @type {Array<{
* button: HTMLElement,
* condition: function,
* domAttach: DynamicDomAttach
* }>} */
this.visibilityToUpdate = [];
this.buttonsElement = makeDiv(this.element, null, ["buttonContainer"]);
buttons.forEach(({ id, label, handler, keybinding, badge, notification, visible }) => {
const button = document.createElement("button");
button.setAttribute("data-button-id", id);
this.buttonsElement.appendChild(button);
this.trackClicks(button, handler);
if (keybinding) {
const binding = this.root.keyMapper.getBinding(keybinding);
binding.add(handler);
binding.appendLabelToElement(button);
}
if (visible) {
this.visibilityToUpdate.push({
button,
condition: visible,
domAttach: new DynamicDomAttach(this.root, button),
});
}
if (badge) {
const badgeElement = makeDiv(button, null, ["badge"]);
this.badgesToUpdate.push({
badge,
lastRenderAmount: 0,
button,
badgeElement,
notification,
condition: visible,
});
}
});
const menuButtons = makeDiv(this.element, null, ["menuButtons"]);
this.saveButton = makeDiv(menuButtons, null, ["button", "save", "animEven"]);
this.settingsButton = makeDiv(menuButtons, null, ["button", "settings"]);
this.trackClicks(this.saveButton, this.startSave);
this.trackClicks(this.settingsButton, this.openSettings);
}
initialize() {
this.root.signals.gameSaved.add(this.onGameSaved, this);
}
update() {
let playSound = false;
let notifications = new Set();
// Update visibility of buttons
for (let i = 0; i < this.visibilityToUpdate.length; ++i) {
const { condition, domAttach } = this.visibilityToUpdate[i];
domAttach.update(condition());
}
// Check for notifications and badges
for (let i = 0; i < this.badgesToUpdate.length; ++i) {
const {
badge,
button,
badgeElement,
lastRenderAmount,
notification,
condition,
} = this.badgesToUpdate[i];
if (condition && !condition()) {
// Do not show notifications for invisible buttons
continue;
}
// Check if the amount shown differs from the one shown last frame
const amount = badge();
if (lastRenderAmount !== amount) {
if (amount > 0) {
badgeElement.innerText = amount;
}
// Check if the badge increased, if so play a notification
if (amount > lastRenderAmount) {
playSound = true;
if (notification) {
notifications.add(notification);
}
}
// Rerender notifications
this.badgesToUpdate[i].lastRenderAmount = amount;
button.classList.toggle("hasBadge", amount > 0);
}
}
if (playSound) {
this.root.soundProxy.playUi(SOUNDS.badgeNotification);
}
notifications.forEach(([notification, type]) => {
this.root.hud.signals.notification.dispatch(notification, type);
});
}
onGameSaved() {
this.saveButton.classList.toggle("animEven");
this.saveButton.classList.toggle("animOdd");
}
startSave() {
this.root.gameState.doSave();
}
openSettings() {
this.root.hud.parts.settingsMenu.show();
}
}

View File

@ -1,81 +1,81 @@
import { BaseHUDPart } from "../base_hud_part";
import { makeDiv } from "../../../core/utils";
import { GameRoot } from "../../root";
import { MinerComponent } from "../../components/miner";
import { DynamicDomAttach } from "../dynamic_dom_attach";
import { TrackedState } from "../../../core/tracked_state";
import { cachebust } from "../../../core/cachebust";
import { T } from "../../../translations";
const tutorialsByLevel = [
// Level 1
[
// 1.1. place an extractor
{
id: "1_1_extractor",
condition: /** @param {GameRoot} root */ root => {
return root.entityMgr.getAllWithComponent(MinerComponent).length === 0;
},
},
// 1.2. connect to hub
{
id: "1_2_conveyor",
condition: /** @param {GameRoot} root */ root => {
return root.hubGoals.getCurrentGoalDelivered() === 0;
},
},
// 1.3 wait for completion
{
id: "1_3_expand",
condition: () => true,
},
],
];
export class HUDInteractiveTutorial extends BaseHUDPart {
createElements(parent) {
this.element = makeDiv(
parent,
"ingame_HUD_InteractiveTutorial",
["animEven"],
`
<strong class="title">${T.ingame.interactiveTutorial.title}</strong>
`
);
this.elementDescription = makeDiv(this.element, null, ["desc"]);
this.elementGif = makeDiv(this.element, null, ["helperGif"]);
}
initialize() {
this.domAttach = new DynamicDomAttach(this.root, this.element);
this.currentHintId = new TrackedState(this.onHintChanged, this);
}
onHintChanged(hintId) {
this.elementDescription.innerHTML = T.ingame.interactiveTutorial.hints[hintId];
this.elementGif.style.backgroundImage =
"url('" + cachebust("res/ui/interactive_tutorial.noinline/" + hintId + ".gif") + "')";
this.element.classList.toggle("animEven");
this.element.classList.toggle("animOdd");
}
update() {
// Compute current hint
const thisLevelHints = tutorialsByLevel[this.root.hubGoals.level - 1];
let targetHintId = null;
if (thisLevelHints) {
for (let i = 0; i < thisLevelHints.length; ++i) {
const hint = thisLevelHints[i];
if (hint.condition(this.root)) {
targetHintId = hint.id;
break;
}
}
}
this.currentHintId.set(targetHintId);
this.domAttach.update(!!targetHintId);
}
}
import { BaseHUDPart } from "../base_hud_part";
import { makeDiv } from "../../../core/utils";
import { GameRoot } from "../../root";
import { MinerComponent } from "../../components/miner";
import { DynamicDomAttach } from "../dynamic_dom_attach";
import { TrackedState } from "../../../core/tracked_state";
import { cachebust } from "../../../core/cachebust";
import { T } from "../../../translations";
const tutorialsByLevel = [
// Level 1
[
// 1.1. place an extractor
{
id: "1_1_extractor",
condition: /** @param {GameRoot} root */ root => {
return root.entityMgr.getAllWithComponent(MinerComponent).length === 0;
},
},
// 1.2. connect to hub
{
id: "1_2_conveyor",
condition: /** @param {GameRoot} root */ root => {
return root.hubGoals.getCurrentGoalDelivered() === 0;
},
},
// 1.3 wait for completion
{
id: "1_3_expand",
condition: () => true,
},
],
];
export class HUDInteractiveTutorial extends BaseHUDPart {
createElements(parent) {
this.element = makeDiv(
parent,
"ingame_HUD_InteractiveTutorial",
["animEven"],
`
<strong class="title">${T.ingame.interactiveTutorial.title}</strong>
`
);
this.elementDescription = makeDiv(this.element, null, ["desc"]);
this.elementGif = makeDiv(this.element, null, ["helperGif"]);
}
initialize() {
this.domAttach = new DynamicDomAttach(this.root, this.element, { trackHover: true });
this.currentHintId = new TrackedState(this.onHintChanged, this);
}
onHintChanged(hintId) {
this.elementDescription.innerHTML = T.ingame.interactiveTutorial.hints[hintId];
this.elementGif.style.backgroundImage =
"url('" + cachebust("res/ui/interactive_tutorial.noinline/" + hintId + ".gif") + "')";
this.element.classList.toggle("animEven");
this.element.classList.toggle("animOdd");
}
update() {
// Compute current hint
const thisLevelHints = tutorialsByLevel[this.root.hubGoals.level - 1];
let targetHintId = null;
if (thisLevelHints) {
for (let i = 0; i < thisLevelHints.length; ++i) {
const hint = thisLevelHints[i];
if (hint.condition(this.root)) {
targetHintId = hint.id;
break;
}
}
}
this.currentHintId.set(targetHintId);
this.domAttach.update(!!targetHintId);
}
}

View File

@ -1,323 +1,330 @@
import { makeDiv } from "../../../core/utils";
import { T } from "../../../translations";
import {
getStringForKeyCode,
KEYCODE_LMB,
KEYCODE_MMB,
KEYCODE_RMB,
KEYMAPPINGS,
} from "../../key_action_mapper";
import { BaseHUDPart } from "../base_hud_part";
import { DynamicDomAttach } from "../dynamic_dom_attach";
const DIVIDER_TOKEN = "/";
const ADDER_TOKEN = "+";
/**
* @typedef {{ keyCode: number }} KeyCode
*/
/**
* @typedef {{
* condition: () => boolean,
* keys: Array<KeyCode|number|string>,
* label: string,
* cachedElement?: HTMLElement,
* cachedVisibility?: boolean
* }} KeyBinding
*/
export class HUDKeybindingOverlay extends BaseHUDPart {
initialize() {}
/**
* HELPER / Returns if there is a building selected for placement
* @returns {boolean}
*/
get buildingPlacementActive() {
const placer = this.root.hud.parts.buildingPlacer;
return !this.mapOverviewActive && placer && !!placer.currentMetaBuilding.get();
}
/**
* HELPER / Returns if there is a building selected for placement and
* it supports the belt planner
* @returns {boolean}
*/
get buildingPlacementSupportsBeltPlanner() {
const placer = this.root.hud.parts.buildingPlacer;
return (
!this.mapOverviewActive &&
placer &&
placer.currentMetaBuilding.get() &&
placer.currentMetaBuilding.get().getHasDirectionLockAvailable()
);
}
/**
* HELPER / Returns if there is a building selected for placement and
* it has multiplace enabled by default
* @returns {boolean}
*/
get buildingPlacementStaysInPlacement() {
const placer = this.root.hud.parts.buildingPlacer;
return (
!this.mapOverviewActive &&
placer &&
placer.currentMetaBuilding.get() &&
placer.currentMetaBuilding.get().getStayInPlacementMode()
);
}
/**
* HELPER / Returns if there is a blueprint selected for placement
* @returns {boolean}
*/
get blueprintPlacementActive() {
const placer = this.root.hud.parts.blueprintPlacer;
return placer && !!placer.currentBlueprint.get();
}
/**
* HELPER / Returns if the belt planner is currently active
* @returns {boolean}
*/
get beltPlannerActive() {
const placer = this.root.hud.parts.buildingPlacer;
return !this.mapOverviewActive && placer && placer.isDirectionLockActive;
}
/**
* HELPER / Returns if there is a last blueprint available
* @returns {boolean}
*/
get lastBlueprintAvailable() {
const placer = this.root.hud.parts.blueprintPlacer;
return placer && !!placer.lastBlueprintUsed;
}
/**
* HELPER / Returns if there is anything selected on the map
* @returns {boolean}
*/
get anythingSelectedOnMap() {
const selector = this.root.hud.parts.massSelector;
return selector && selector.selectedUids.size > 0;
}
/**
* HELPER / Returns if there is a building or blueprint selected for placement
* @returns {boolean}
*/
get anyPlacementActive() {
return this.buildingPlacementActive || this.blueprintPlacementActive;
}
/**
* HELPER / Returns if the map overview is active
* @returns {boolean}
*/
get mapOverviewActive() {
return this.root.camera.getIsMapOverlayActive();
}
/**
* Initializes the element
* @param {HTMLElement} parent
*/
createElements(parent) {
const mapper = this.root.keyMapper;
const k = KEYMAPPINGS;
/** @type {Array<KeyBinding>} */
this.keybindings = [
{
// Move map - Including mouse
label: T.ingame.keybindingsOverlay.moveMap,
keys: [
KEYCODE_LMB,
DIVIDER_TOKEN,
k.navigation.mapMoveUp,
k.navigation.mapMoveLeft,
k.navigation.mapMoveDown,
k.navigation.mapMoveRight,
],
condition: () => !this.anyPlacementActive,
},
{
// Move map - No mouse
label: T.ingame.keybindingsOverlay.moveMap,
keys: [
k.navigation.mapMoveUp,
k.navigation.mapMoveLeft,
k.navigation.mapMoveDown,
k.navigation.mapMoveRight,
],
condition: () => this.anyPlacementActive,
},
{
// [OVERVIEW] Create marker with right click
label: T.ingame.keybindingsOverlay.createMarker,
keys: [KEYCODE_RMB],
condition: () => this.mapOverviewActive && !this.blueprintPlacementActive,
},
{
// Pipette
label: T.ingame.keybindingsOverlay.pipette,
keys: [k.placement.pipette],
condition: () => !this.mapOverviewActive && !this.blueprintPlacementActive,
},
{
// Cancel placement
label: T.ingame.keybindingsOverlay.stopPlacement,
keys: [KEYCODE_RMB],
condition: () => this.anyPlacementActive,
},
{
// Delete with right click
label: T.ingame.keybindingsOverlay.delete,
keys: [KEYCODE_RMB],
condition: () =>
!this.anyPlacementActive && !this.mapOverviewActive && !this.anythingSelectedOnMap,
},
{
// Area select
label: T.ingame.keybindingsOverlay.selectBuildings,
keys: [k.massSelect.massSelectStart, ADDER_TOKEN, KEYCODE_LMB],
condition: () => !this.anyPlacementActive && !this.anythingSelectedOnMap,
},
{
// Place building
label: T.ingame.keybindingsOverlay.placeBuilding,
keys: [KEYCODE_LMB],
condition: () => this.anyPlacementActive,
},
{
// Rotate
label: T.ingame.keybindingsOverlay.rotateBuilding,
keys: [k.placement.rotateWhilePlacing],
condition: () => this.anyPlacementActive && !this.beltPlannerActive,
},
{
// [BELT PLANNER] Flip Side
label: T.ingame.keybindingsOverlay.plannerSwitchSide,
keys: [k.placement.switchDirectionLockSide],
condition: () => this.beltPlannerActive,
},
{
// Place last blueprint
label: T.ingame.keybindingsOverlay.pasteLastBlueprint,
keys: [k.massSelect.pasteLastBlueprint],
condition: () => !this.blueprintPlacementActive && this.lastBlueprintAvailable,
},
{
// Belt planner
label: T.ingame.keybindingsOverlay.lockBeltDirection,
keys: [k.placementModifiers.lockBeltDirection],
condition: () => this.buildingPlacementSupportsBeltPlanner && !this.beltPlannerActive,
},
{
// [SELECTION] Destroy
label: T.ingame.keybindingsOverlay.delete,
keys: [k.massSelect.confirmMassDelete],
condition: () => this.anythingSelectedOnMap,
},
{
// [SELECTION] Cancel
label: T.ingame.keybindingsOverlay.clearSelection,
keys: [k.general.back],
condition: () => this.anythingSelectedOnMap,
},
{
// [SELECTION] Cut
label: T.ingame.keybindingsOverlay.cutSelection,
keys: [k.massSelect.massSelectCut],
condition: () => this.anythingSelectedOnMap,
},
{
// [SELECTION] Copy
label: T.ingame.keybindingsOverlay.copySelection,
keys: [k.massSelect.massSelectCopy],
condition: () => this.anythingSelectedOnMap,
},
{
// Switch layers
label: T.ingame.keybindingsOverlay.switchLayers,
keys: [k.ingame.switchLayers],
condition: () => true,
},
];
if (!this.root.app.settings.getAllSettings().alwaysMultiplace) {
this.keybindings.push({
// Multiplace
label: T.ingame.keybindingsOverlay.placeMultiple,
keys: [k.placementModifiers.placeMultiple],
condition: () => this.anyPlacementActive && !this.buildingPlacementStaysInPlacement,
});
}
this.element = makeDiv(parent, "ingame_HUD_KeybindingOverlay", []);
for (let i = 0; i < this.keybindings.length; ++i) {
let html = "";
const handle = this.keybindings[i];
for (let k = 0; k < handle.keys.length; ++k) {
const key = handle.keys[k];
switch (key) {
case KEYCODE_LMB:
html += `<code class="keybinding leftMouse"></code>`;
break;
case KEYCODE_RMB:
html += `<code class="keybinding rightMouse"></code>`;
break;
case KEYCODE_MMB:
html += `<code class="keybinding middleMouse"></code>`;
break;
case DIVIDER_TOKEN:
html += `<i></i>`;
break;
case ADDER_TOKEN:
html += `+`;
break;
default:
html += `<code class="keybinding">${getStringForKeyCode(
mapper.getBinding(/** @type {KeyCode} */ (key)).keyCode
)}</code>`;
}
}
html += `<label>${handle.label}</label>`;
handle.cachedElement = makeDiv(this.element, null, ["binding"], html);
handle.cachedVisibility = false;
}
}
update() {
for (let i = 0; i < this.keybindings.length; ++i) {
const handle = this.keybindings[i];
const visibility = handle.condition();
if (visibility !== handle.cachedVisibility) {
handle.cachedVisibility = visibility;
handle.cachedElement.classList.toggle("visible", visibility);
}
}
}
}
import { makeDiv } from "../../../core/utils";
import { T } from "../../../translations";
import {
getStringForKeyCode,
KEYCODE_LMB,
KEYCODE_MMB,
KEYCODE_RMB,
KEYMAPPINGS,
} from "../../key_action_mapper";
import { BaseHUDPart } from "../base_hud_part";
import { DynamicDomAttach } from "../dynamic_dom_attach";
const DIVIDER_TOKEN = "/";
const ADDER_TOKEN = "+";
/**
* @typedef {{ keyCode: number }} KeyCode
*/
/**
* @typedef {{
* condition: () => boolean,
* keys: Array<KeyCode|number|string>,
* label: string,
* cachedElement?: HTMLElement,
* cachedVisibility?: boolean
* }} KeyBinding
*/
export class HUDKeybindingOverlay extends BaseHUDPart {
/**
* HELPER / Returns if there is a building selected for placement
* @returns {boolean}
*/
get buildingPlacementActive() {
const placer = this.root.hud.parts.buildingPlacer;
return !this.mapOverviewActive && placer && !!placer.currentMetaBuilding.get();
}
/**
* HELPER / Returns if there is a building selected for placement and
* it supports the belt planner
* @returns {boolean}
*/
get buildingPlacementSupportsBeltPlanner() {
const placer = this.root.hud.parts.buildingPlacer;
return (
!this.mapOverviewActive &&
placer &&
placer.currentMetaBuilding.get() &&
placer.currentMetaBuilding.get().getHasDirectionLockAvailable()
);
}
/**
* HELPER / Returns if there is a building selected for placement and
* it has multiplace enabled by default
* @returns {boolean}
*/
get buildingPlacementStaysInPlacement() {
const placer = this.root.hud.parts.buildingPlacer;
return (
!this.mapOverviewActive &&
placer &&
placer.currentMetaBuilding.get() &&
placer.currentMetaBuilding.get().getStayInPlacementMode()
);
}
/**
* HELPER / Returns if there is a blueprint selected for placement
* @returns {boolean}
*/
get blueprintPlacementActive() {
const placer = this.root.hud.parts.blueprintPlacer;
return placer && !!placer.currentBlueprint.get();
}
/**
* HELPER / Returns if the belt planner is currently active
* @returns {boolean}
*/
get beltPlannerActive() {
const placer = this.root.hud.parts.buildingPlacer;
return !this.mapOverviewActive && placer && placer.isDirectionLockActive;
}
/**
* HELPER / Returns if there is a last blueprint available
* @returns {boolean}
*/
get lastBlueprintAvailable() {
const placer = this.root.hud.parts.blueprintPlacer;
return placer && !!placer.lastBlueprintUsed;
}
/**
* HELPER / Returns if there is anything selected on the map
* @returns {boolean}
*/
get anythingSelectedOnMap() {
const selector = this.root.hud.parts.massSelector;
return selector && selector.selectedUids.size > 0;
}
/**
* HELPER / Returns if there is a building or blueprint selected for placement
* @returns {boolean}
*/
get anyPlacementActive() {
return this.buildingPlacementActive || this.blueprintPlacementActive;
}
/**
* HELPER / Returns if the map overview is active
* @returns {boolean}
*/
get mapOverviewActive() {
return this.root.camera.getIsMapOverlayActive();
}
/**
* Initializes the element
* @param {HTMLElement} parent
*/
createElements(parent) {
const mapper = this.root.keyMapper;
const k = KEYMAPPINGS;
/** @type {Array<KeyBinding>} */
this.keybindings = [
{
// Move map - Including mouse
label: T.ingame.keybindingsOverlay.moveMap,
keys: [
KEYCODE_LMB,
DIVIDER_TOKEN,
k.navigation.mapMoveUp,
k.navigation.mapMoveLeft,
k.navigation.mapMoveDown,
k.navigation.mapMoveRight,
],
condition: () => !this.anyPlacementActive,
},
{
// Move map - No mouse
label: T.ingame.keybindingsOverlay.moveMap,
keys: [
k.navigation.mapMoveUp,
k.navigation.mapMoveLeft,
k.navigation.mapMoveDown,
k.navigation.mapMoveRight,
],
condition: () => this.anyPlacementActive,
},
{
// [OVERVIEW] Create marker with right click
label: T.ingame.keybindingsOverlay.createMarker,
keys: [KEYCODE_RMB],
condition: () => this.mapOverviewActive && !this.blueprintPlacementActive,
},
{
// Pipette
label: T.ingame.keybindingsOverlay.pipette,
keys: [k.placement.pipette],
condition: () => !this.mapOverviewActive && !this.blueprintPlacementActive,
},
{
// Cancel placement
label: T.ingame.keybindingsOverlay.stopPlacement,
keys: [KEYCODE_RMB],
condition: () => this.anyPlacementActive,
},
{
// Delete with right click
label: T.ingame.keybindingsOverlay.delete,
keys: [KEYCODE_RMB],
condition: () =>
!this.anyPlacementActive && !this.mapOverviewActive && !this.anythingSelectedOnMap,
},
{
// Area select
label: T.ingame.keybindingsOverlay.selectBuildings,
keys: [k.massSelect.massSelectStart, ADDER_TOKEN, KEYCODE_LMB],
condition: () => !this.anyPlacementActive && !this.anythingSelectedOnMap,
},
{
// Place building
label: T.ingame.keybindingsOverlay.placeBuilding,
keys: [KEYCODE_LMB],
condition: () => this.anyPlacementActive,
},
{
// Rotate
label: T.ingame.keybindingsOverlay.rotateBuilding,
keys: [k.placement.rotateWhilePlacing],
condition: () => this.anyPlacementActive && !this.beltPlannerActive,
},
{
// [BELT PLANNER] Flip Side
label: T.ingame.keybindingsOverlay.plannerSwitchSide,
keys: [k.placement.switchDirectionLockSide],
condition: () => this.beltPlannerActive,
},
{
// Place last blueprint
label: T.ingame.keybindingsOverlay.pasteLastBlueprint,
keys: [k.massSelect.pasteLastBlueprint],
condition: () => !this.blueprintPlacementActive && this.lastBlueprintAvailable,
},
{
// Belt planner
label: T.ingame.keybindingsOverlay.lockBeltDirection,
keys: [k.placementModifiers.lockBeltDirection],
condition: () => this.buildingPlacementSupportsBeltPlanner && !this.beltPlannerActive,
},
{
// [SELECTION] Destroy
label: T.ingame.keybindingsOverlay.delete,
keys: [k.massSelect.confirmMassDelete],
condition: () => this.anythingSelectedOnMap,
},
{
// [SELECTION] Cancel
label: T.ingame.keybindingsOverlay.clearSelection,
keys: [k.general.back],
condition: () => this.anythingSelectedOnMap,
},
{
// [SELECTION] Cut
label: T.ingame.keybindingsOverlay.cutSelection,
keys: [k.massSelect.massSelectCut],
condition: () => this.anythingSelectedOnMap,
},
{
// [SELECTION] Copy
label: T.ingame.keybindingsOverlay.copySelection,
keys: [k.massSelect.massSelectCopy],
condition: () => this.anythingSelectedOnMap,
},
{
// Switch layers
label: T.ingame.keybindingsOverlay.switchLayers,
keys: [k.ingame.switchLayers],
condition: () => true,
},
];
if (!this.root.app.settings.getAllSettings().alwaysMultiplace) {
this.keybindings.push({
// Multiplace
label: T.ingame.keybindingsOverlay.placeMultiple,
keys: [k.placementModifiers.placeMultiple],
condition: () => this.anyPlacementActive && !this.buildingPlacementStaysInPlacement,
});
}
this.element = makeDiv(parent, "ingame_HUD_KeybindingOverlay", []);
for (let i = 0; i < this.keybindings.length; ++i) {
let html = "";
const handle = this.keybindings[i];
for (let k = 0; k < handle.keys.length; ++k) {
const key = handle.keys[k];
switch (key) {
case KEYCODE_LMB:
html += `<code class="keybinding leftMouse"></code>`;
break;
case KEYCODE_RMB:
html += `<code class="keybinding rightMouse"></code>`;
break;
case KEYCODE_MMB:
html += `<code class="keybinding middleMouse"></code>`;
break;
case DIVIDER_TOKEN:
html += `<i></i>`;
break;
case ADDER_TOKEN:
html += `+`;
break;
default:
html += `<code class="keybinding">${getStringForKeyCode(
mapper.getBinding(/** @type {KeyCode} */ (key)).keyCode
)}</code>`;
}
}
html += `<label>${handle.label}</label>`;
handle.cachedElement = makeDiv(this.element, null, ["binding"], html);
handle.cachedVisibility = false;
}
}
initialize() {
this.domAttach = new DynamicDomAttach(this.root, this.element, {
trackHover: true,
});
}
update() {
for (let i = 0; i < this.keybindings.length; ++i) {
const handle = this.keybindings[i];
const visibility = handle.condition();
if (visibility !== handle.cachedVisibility) {
handle.cachedVisibility = visibility;
handle.cachedElement.classList.toggle("visible", visibility);
}
}
// Required for hover
this.domAttach.update(true);
}
}

View File

@ -185,6 +185,9 @@ export class SoundImplBrowser extends SoundInterface {
}
initialize() {
// NOTICE: We override the initialize() method here with custom logic because
// we have a sound sprites instance
this.sfxHandle = new SoundSpritesContainer();
// @ts-ignore
@ -198,11 +201,11 @@ export class SoundImplBrowser extends SoundInterface {
this.music[musicPath] = music;
}
this.musicMuted = this.app.settings.getAllSettings().musicMuted;
this.soundsMuted = this.app.settings.getAllSettings().soundsMuted;
this.musicVolume = this.app.settings.getAllSettings().musicVolume;
this.soundVolume = this.app.settings.getAllSettings().soundVolume;
if (G_IS_DEV && globalConfig.debug.disableMusic) {
this.musicMuted = true;
this.musicVolume = 0.0;
}
return Promise.resolve();

View File

@ -103,9 +103,6 @@ export class SoundInterface {
this.pageIsVisible = true;
this.musicMuted = false;
this.soundsMuted = false;
this.musicVolume = 1.0;
this.soundVolume = 1.0;
}
@ -127,13 +124,11 @@ export class SoundInterface {
this.music[musicPath] = music;
}
this.musicMuted = this.app.settings.getAllSettings().musicMuted;
this.soundsMuted = this.app.settings.getAllSettings().soundsMuted;
this.musicVolume = this.app.settings.getAllSettings().musicVolume;
this.soundVolume = this.app.settings.getAllSettings().soundVolume;
if (G_IS_DEV && globalConfig.debug.disableMusic) {
this.musicMuted = true;
this.musicVolume = 0.0;
}
return Promise.resolve();
@ -170,47 +165,6 @@ export class SoundInterface {
return Promise.all(...promises);
}
/**
* Returns if the music is muted
* @returns {boolean}
*/
getMusicMuted() {
return this.musicMuted;
}
/**
* Returns if sounds are muted
* @returns {boolean}
*/
getSoundsMuted() {
return this.soundsMuted;
}
/**
* Sets if the music is muted
* @param {boolean} muted
*/
setMusicMuted(muted) {
this.musicMuted = muted;
if (this.musicMuted) {
if (this.currentMusic) {
this.currentMusic.stop();
}
} else {
if (this.currentMusic) {
this.currentMusic.play(this.musicVolume);
}
}
}
/**
* Sets if the sounds are muted
* @param {boolean} muted
*/
setSoundsMuted(muted) {
this.soundsMuted = muted;
}
/**
* Returns the music volume
* @returns {number}
@ -254,7 +208,7 @@ export class SoundInterface {
this.pageIsVisible = pageIsVisible;
if (this.currentMusic) {
if (pageIsVisible) {
if (!this.currentMusic.isPlaying() && !this.musicMuted) {
if (!this.currentMusic.isPlaying()) {
this.currentMusic.play(this.musicVolume);
}
} else {
@ -267,9 +221,6 @@ export class SoundInterface {
* @param {string} key
*/
playUiSound(key) {
if (this.soundsMuted) {
return;
}
if (!this.sounds[key]) {
logger.warn("Sound", key, "not found, probably not loaded yet");
return;
@ -288,7 +239,7 @@ export class SoundInterface {
logger.warn("Music", key, "not found, probably not loaded yet");
return;
}
if (!this.pageIsVisible || this.soundsMuted) {
if (!this.pageIsVisible) {
return;
}
@ -319,7 +270,7 @@ export class SoundInterface {
this.currentMusic.stop();
}
this.currentMusic = music;
if (music && this.pageIsVisible && !this.musicMuted) {
if (music && this.pageIsVisible) {
logger.log("Starting", this.currentMusic.key);
music.play(this.musicVolume);
}

View File

@ -159,29 +159,13 @@ export const allApplicationSettings = [
(app, id) => app.updateAfterUiScaleChanged(),
}),
new BoolSetting(
"soundsMuted",
enumCategories.general,
/**
* @param {Application} app
*/
(app, value) => app.sound.setSoundsMuted(value)
),
new RangeSetting(
"soundVolume",
enumCategories.general,
/**
* @param {Application} app
*/
(app, value) => app.sound.setSoundVolume(value / 100.0)
),
new BoolSetting(
"musicMuted",
enumCategories.general,
/**
* @param {Application} app
*/
(app, value) => app.sound.setMusicMuted(value)
(app, value) => app.sound.setSoundVolume(value)
),
new RangeSetting(
"musicVolume",
@ -189,7 +173,7 @@ export const allApplicationSettings = [
/**
* @param {Application} app
*/
(app, value) => app.sound.setMusicVolume(value / 100.0)
(app, value) => app.sound.setMusicVolume(value)
),
new BoolSetting(
@ -277,6 +261,7 @@ export const allApplicationSettings = [
new BoolSetting("disableCutDeleteWarnings", enumCategories.advanced, (app, value) => {}),
new BoolSetting("rotationByBuilding", enumCategories.advanced, (app, value) => {}),
new BoolSetting("displayChunkBorders", enumCategories.advanced, (app, value) => {}),
new BoolSetting("pickMinerOnPatch", enumCategories.advanced, (app, value) => {}),
new EnumSetting("refreshRate", {
options: refreshRateOptions,
@ -302,8 +287,6 @@ class SettingsStorage {
this.uiScale = "regular";
this.fullscreen = G_IS_STANDALONE;
this.soundsMuted = false;
this.musicMuted = false;
this.soundVolume = 1.0;
this.musicVolume = 1.0;
@ -323,6 +306,7 @@ class SettingsStorage {
this.rotationByBuilding = true;
this.clearCursorOnDeleteWhilePlacing = true;
this.displayChunkBorders = false;
this.pickMinerOnPatch = true;
this.enableColorBlindHelper = false;
@ -515,7 +499,17 @@ export class ApplicationSettings extends ReadWriteProxy {
const setting = allApplicationSettings[i];
const storedValue = settings[setting.id];
if (!setting.validate(storedValue)) {
return ExplainedResult.bad("Bad setting value for " + setting.id + ": " + storedValue);
return ExplainedResult.bad(
"Bad setting value for " +
setting.id +
": " +
storedValue +
" @ settings version " +
data.version +
" (latest is " +
this.getCurrentVersion() +
")"
);
}
}
return ExplainedResult.good();
@ -529,7 +523,7 @@ export class ApplicationSettings extends ReadWriteProxy {
}
getCurrentVersion() {
return 24;
return 26;
}
/** @param {{settings: SettingsStorage, version: number}} data */
@ -633,10 +627,23 @@ export class ApplicationSettings extends ReadWriteProxy {
}
if (data.version < 24) {
data.settings.musicVolume = 1.0;
data.settings.soundVolume = 1.0;
data.settings.refreshRate = "60";
data.version = 24;
}
if (data.version < 25) {
data.settings.musicVolume = 0.5;
data.settings.soundVolume = 0.5;
// @ts-ignore
delete data.settings.musicMuted;
// @ts-ignore
delete data.settings.soundsMuted;
data.version = 25;
}
if (data.version < 26) {
data.settings.pickMinerOnPatch = true;
data.version = 26;
}
return ExplainedResult.good();

View File

@ -227,10 +227,10 @@ export class RangeSetting extends BaseSetting {
category,
changeCb = null,
enabled = true,
defaultValue = 100,
defaultValue = 1.0,
minValue = 0,
maxValue = 100,
stepSize = 1
maxValue = 1.0,
stepSize = 0.0001
) {
super(id, category, changeCb, enabled);
@ -247,9 +247,9 @@ export class RangeSetting extends BaseSetting {
<div class="row">
<label>${T.settings.labels[this.id].title}</label>
<div class="value range" data-setting="${this.id}">
<label class="range-label">${this.defaultValue}</label>
<input class="range-input" type="range" value="${this.defaultValue}" min="${
<div class="value rangeInputContainer noPressEffect" data-setting="${this.id}">
<label>${this.defaultValue}</label>
<input class="rangeInput" type="range" value="${this.defaultValue}" min="${
this.minValue
}" max="${this.maxValue}" step="${this.stepSize}">
</div>
@ -265,33 +265,58 @@ export class RangeSetting extends BaseSetting {
this.element = element;
this.dialogs = dialogs;
this.element.querySelector(".range-input").addEventListener("input", () => {
this.getRangeInputElement().addEventListener("input", () => {
this.updateLabels();
});
this.getRangeInputElement().addEventListener("change", () => {
this.modify();
});
}
syncValueToElement() {
const value = this.app.settings.getSetting(this.id);
/** @type {HTMLInputElement} */
const rangeInput = this.element.querySelector(".range-input"),
rangeLabel = this.element.querySelector(".range-label");
rangeInput.value = value;
rangeLabel.innerHTML = value;
this.setElementValue(value);
}
/**
* Sets the elements value to the given value
* @param {number} value
*/
setElementValue(value) {
const rangeInput = this.getRangeInputElement();
const rangeLabel = this.element.querySelector("label");
rangeInput.value = String(value);
rangeLabel.innerHTML = T.settings.rangeSliderPercentage.replace(
"<amount>",
String(Math.round(value * 100.0))
);
}
updateLabels() {
const value = Number(this.getRangeInputElement().value);
this.setElementValue(value);
}
/**
* @returns {HTMLInputElement}
*/
getRangeInputElement() {
return this.element.querySelector("input.rangeInput");
}
modify() {
/** @type {HTMLInputElement} */
const rangeInput = this.element.querySelector(".range-input");
const newValue = Number(rangeInput.value);
const rangeInput = this.getRangeInputElement();
const newValue = Math.round(Number(rangeInput.value) * 100.0) / 100.0;
this.app.settings.updateSetting(this.id, newValue);
this.syncValueToElement();
console.log("SET", newValue);
if (this.changeCb) {
this.changeCb(this.app, newValue);
}
}
validate(value) {
return typeof value === "number";
return typeof value === "number" && value >= this.minValue && value <= this.maxValue;
}
}

View File

@ -42,7 +42,7 @@ steamPage:
Der går ikke lang tid før du må mikse farver og male dine figurer med dem - Kombiner rød, grøn og blå farveresurser for at producere forskellige farver og mal derefter figurer med dem for at møde efterspørgslen.
Dette spil indeholder 18 fremadskridende levels (Som allerede burde holde dig beskæftiget i timevis!) men jeg tilføjer hele tiden nyt - Der er en hel masse planlagt!
Dette spil indeholder 18 fremadskridende Niveauers (Som allerede burde holde dig beskæftiget i timevis!) men jeg tilføjer hele tiden nyt - Der er en hel masse planlagt!
Hvis du køber spillet, får du adgang til den selvstændige version, der har endnu flere ting, og du får også adgang til nyudviklet indhold.
@ -54,7 +54,7 @@ steamPage:
[*] Uendelige Gem
[*] Yderligere Indstillinger
[*] Kommer snart: Ledninger & Energi! Går efter at udgive (omkring) enden af juli 2020.
[*] Kommer snart: Flere levels
[*] Kommer snart: Niveauer
[*] Støtter mig i yderligere at udvikle shapez.io ❤️
[/list]
@ -130,7 +130,7 @@ global:
control: CTRL
alt: ALT
escape: ESC
shift: SHIFT
shift: SKIFT
space: MELLEMRUM
demoBanners:
@ -145,7 +145,7 @@ mainMenu:
newGame: Nyt Spil
changelog: Changelog
subreddit: Reddit
importSavegame: Importer
importSavegame: Importér
openSourceHint: Dette spil er open source!
discordLink: Officiel Discord Server
helpTranslate: Hjælp med at oversætte!
@ -155,8 +155,8 @@ mainMenu:
browserWarning: >-
Undskyld, men spillet er kendt for at køre langsomt på denne browser! Køb spillet eller download chrome for den fulde oplevelse.
savegameLevel: Level <x>
savegameLevelUnknown: Ukendt Level
savegameLevel: Niveau <x>
savegameLevelUnknown: Ukendt Niveau
dialogs:
buttons:
@ -175,32 +175,32 @@ dialogs:
importSavegameError:
title: Import Fejl
text: >-
Importering af gem fejlede:
Importering af gemt spil fejlede:
importSavegameSuccess:
title: Gem Importeret
title: Gemt spil Importeret
text: >-
Dit gem blev importet.
Dit gemte spil blev importet.
gameLoadFailure:
title: Spillet er i stykker
text: >-
Det lykkedes ikke at åbne dit gem:
Det lykkedes ikke at åbne dit gemte spil:
confirmSavegameDelete:
title: Bekræft sletning
text: >-
Er du sikker på du vil slette dit gem?
Er du sikker på du vil slette dit gemte spil?
savegameDeletionError:
title: Sletning fejlede
text: >-
Det lykkedes ikke at slette dit gem:
Det lykkedes ikke at slette dit gemte spil:
restartRequired:
title: Genstart er nødvendig
text: >-
You need to restart the game to apply the settings.
Du er nødt til at genstarte spillet for at anvende indstillingerne.
editKeybinding:
title: Ændr Keybinding
@ -208,7 +208,7 @@ dialogs:
resetKeybindingsConfirmation:
title: Nulstil keybindings
desc: Dette vil nulstille alle keybindings til deres standarder. Vær sød at bekræfte.
desc: Dette vil nulstille alle keybindings til deres standarder. Bekræft venligst.
keybindingsResetOk:
title: Keybindings nulstillet
@ -219,8 +219,8 @@ dialogs:
desc: Du prøvede at bruge en funktion (<feature>) der ikke er tilgængelig i demoen. Overvej at købe spillet for den fulde oplevelse!
oneSavegameLimit:
title: Begrænset mængde gem
desc: Du kan kun have et gem af gangen in demoversionen. Vær sød at slette det nuværende gem eller at købe spillet!
title: Begrænset mængde gemte spil
desc: Du kan kun have et gemt spil ad gangen in demoversionen. Vær sød at slette det nuværende gemte spil eller at købe spillet!
updateSummary:
title: Ny opdatering!
@ -230,23 +230,23 @@ dialogs:
upgradesIntroduction:
title: Få Opgraderinger
desc: >-
Alle figurer du producere kan blive brugt til at få opgraderinger - <strong>Ødelæg ikke dine gamle fabrikker!</strong>
Alle figurer du producerer kan blive brugt til at få opgraderinger - <strong>Ødelæg ikke dine gamle fabrikker!</strong>
Opgraderingeringsvinduet kan findes i det øverste højre hjørne af skærmen.
massDeleteConfirm:
title: Bekræft sletning
desc: >-
Du er ved at slette mange bygninger (<count> helt præcis)! Er du sikker på at det er det du vil gøre?
Du er ved at slette mange bygninger (<count> helt præcist)! Er du sikker på at det er det du vil gøre?
massCutConfirm:
title: Bekræft klip
desc: >-
Du er ved at klippe mange bygninger (<count> helt præcis)! Er du sikker på at det er det du vil gøre?
Du er ved at klippe mange bygninger (<count> helt præcist)! Er du sikker på at det er det du vil gøre?
blueprintsNotUnlocked:
title: Ikke tilgængeligt endnu
desc: >-
Klar level 12 for at bruge arbejdstegninger!
Gennemfør Niveau 12 for at bruge arbejdstegninger!
keybindingsIntroduction:
title: Brugbare keybindings
@ -254,8 +254,8 @@ dialogs:
Dette spil har mange keybindings, som gør det lettere at bygge store fabrikker.
Her er et par, men husk at <strong>tjekke keybindings</strong>!<br><br>
<code class='keybinding'>CTRL</code> + Træk: Vælg et område.<br>
<code class='keybinding'>SHIFT</code>: Hold for at sætte flere af en bygning.<br>
<code class='keybinding'>ALT</code>: Vend retningen af nedsatte transportbånd.<br>
<code class='keybinding'>SHIFT</code>: Hold for at placere flere af en bygning.<br>
<code class='keybinding'>ALT</code>: Vend retningen af placerede transportbånd.<br>
createMarker:
title: Ny Markør
@ -270,7 +270,7 @@ dialogs:
desc: Du bad om at eksportere din fabrik som et skærmbillede. Bemærk at dette kan være rimelig langsomt for en stor base og kan endda lukke dit spil!
massCutInsufficientConfirm:
title: Bekræft klip
desc: Du har ikke råd til at sætte dette område ind igen! Er du sikker på du vil klippe det?
desc: Du har ikke råd til at sætte dette område ind igen! Er du sikker på at du vil klippe det?
ingame:
# This is shown in the top left corner and displays useful keybindings in
@ -280,7 +280,7 @@ ingame:
selectBuildings: Marker område
stopPlacement: Stop placering
rotateBuilding: Roter bygning
placeMultiple: Sæt flere
placeMultiple: Placer flere
reverseOrientation: Omvend retning
disableAutoOrientation: Slå automatisk retning fra
toggleHud: Slå HUD til/fra
@ -289,7 +289,7 @@ ingame:
delete: Slet
pasteLastBlueprint: Sæt sidste arbejdstegning ind
lockBeltDirection: Aktiver bælteplanlægger
plannerSwitchSide: Flip planlægsningsside
plannerSwitchSide: Vend planlægsningsside
cutSelection: Klip
copySelection: Kopier
clearSelection: Ryd Selektion
@ -353,7 +353,7 @@ ingame:
# The roman number for each tier
tierLabels: [I, II, III, IV, V, VI, VII, VIII, IX, X]
maximumLevel: STØRSTE NIVEAU (Speed x<currentMult>)
maximumLevel: HØJESTE NIVEAU (Speed x<currentMult>)
# The "Statistics" window
statistics:
@ -364,7 +364,7 @@ ingame:
description: Viser mængden af opbevarede figurer i din centrale bygning.
produced:
title: Produceret
description: Viser alle de figurer hele din fabrik producere, inklusiv produkter brugt til videre produktion.
description: Viser alle de figurer hele din fabrik producerer, inklusiv produkter brugt til videre produktion.
delivered:
title: Afleveret
description: Viser figurer som er afleveret til din centrale bygning.
@ -383,7 +383,7 @@ ingame:
buttons:
continue: Fortsæt
settings: Indstillinger
menu: Til menu
menu: Hovedmenu
# Bottom left tutorial hints
tutorialHints:
@ -399,7 +399,7 @@ ingame:
waypoints:
waypoints: Markører
hub: HUB
description: Venstreklik en markør for at hoppe til den, højreklik for at slette den.<br><br>Tryk <keybinding> for at lave en markør på det nuværende sted, eller <strong>højreklik</strong> for at lave en markør på den valgte lokation.
description: Venstreklik en markør for at hoppe til den, højreklik for at slette den.<br><br>Tryk <keybinding> for at lave en markør på det nuværende sted, eller <strong>højreklik</strong> for at lave en markør på det valgte sted.
creationSuccessNotification: Markør er sat.
# Shape viewer
@ -414,10 +414,10 @@ ingame:
hints:
1_1_extractor: Sæt en <strong>udvinder</strong> på toppen af en<strong>cirkelfigur</strong> for at begynde produktion af den!
1_2_conveyor: >-
Forbind udvinderen med et <strong>transportbælte</strong> til din hub!<br><br>Tip: <strong>Tryk og træk</strong> bæltet med din mus!
Forbind udvinderen til din hub med et <strong>transportbælte</strong>!<br><br>Tip: <strong>Tryk og træk</strong> bæltet med din mus!
1_3_expand: >-
Dette er <strong>IKKE</strong> et idle game! Byg flere udvindere og bælter for at færdiggøre målet hurtigere.<br><br>Tip: Hold <strong>SHIFT</strong> for at sætte flere udvindere, og tryk <strong>R</strong> for at rotere dem.
Dette er <strong>IKKE</strong> et idle game! Byg flere udvindere og bælter for at færdiggøre målet hurtigere.<br><br>Tip: Hold <strong>SKIFT</strong> for at sætte flere udvindere, og tryk <strong>R</strong> for at rotere dem.
# All shop upgrades
shopUpgrades:
@ -439,12 +439,12 @@ buildings:
hub:
deliver: Aflever
toUnlock: for at få adgang til
levelShortcut: LVL
levelShortcut: NIV
belt:
default:
name: &belt Transportbælte
description: Transportere varer, hold og træk for at sætte flere.
description: Transporterer figurer, hold og træk for at sætte flere.
# Internal name for the Extractor
miner:
@ -454,55 +454,55 @@ buildings:
chainable:
name: Udvinder (Kæde)
description: Placer over en figur eller farve for at udvinde den. Kan sættes i kæder.
description: Placer over en figur eller farve for at udvinde den. Kan kædes.
# Internal name for the Tunnel
underground_belt:
default:
name: &underground_belt Tunnel
description: Laver tunneller under bygninger and bælter.
description: Laver tunneller under bygninger og bælter.
tier2:
name: Tunnel Trin II
description: Laver tunneller under bygninger and bælter.
description: Laver tunneller under bygninger og bælter.
# Internal name for the Balancer
splitter:
default:
name: &splitter Spalter
name: &splitter Fordeler
description: Flere funktioner - Fordeler alle modtagne varer jævnt.
compact:
name: Sammenlægger (kompakt)
description: Sammenlægger to bælter til en.
description: Lægger to bælter sammen til et.
compact-inverse:
name: Sammenlægger (kompakt)
description: Sammenlægger to bælter til en.
description: Lægger to bælter sammen til et.
cutter:
default:
name: &cutter Klipper
description: Klipper figurer fra top til bund og udsender begge halvdele. <strong>Hvis du kun bruger den ene halvdel så husk at ødelæg den anden del eller maskinen går i stå!</strong>
description: Klipper figurer fra top til bund og udsender begge halvdele. <strong>Hvis du kun bruger den ene halvdel så husk at ødelægge den anden del, ellers går maskinen i stå!</strong>
quad:
name: Klipper (firdeler)
description: Klipper figurer om til fire dele. <strong>Hvis du kun bruger nogle af dem så husk at ødelæg de andre dele eller maskinen går i stå!</strong>
description: Klipper figurer om til fire dele. <strong>Hvis du kun bruger nogle af dem så husk at ødelægge de andre dele, ellers går maskinen i stå!</strong>
rotater:
default:
name: &rotater Drejer
description: Drejer figurer med uret med 90 grader.
description: Drejer figurer 90 grader med uret.
ccw:
name: Drejer (mod uret)
description: Drejer figurer mod uret med 90 grader.
description: Drejer figurer 90 grader mod uret.
fl:
name: Drejer (180)
description: Drejer figurer med 180 grader.
description: Drejer figurer 180 grader.
stacker:
default:
name: &stacker Stabler
description: Stabler begge figurer. Hvis de ikke kan sammensmeltes, så er den højre figur sat oven på den venstre.
description: Stabler begge figurer. Hvis de ikke kan sammensmeltes, så sættes den højre figur oven på den venstre.
mixer:
default:
@ -527,12 +527,12 @@ buildings:
trash:
default:
name: &trash Skrald
description: Tillader input fra alle sider og ødelææger dem. For evigt.
name: &trash Skraldespand
description: Tillader input fra alle sider og ødelægger dem. For evigt.
storage:
name: Opbevaring
description: Opbevarer ekstra varer, til en given kapicitet. Kan bruges til at håndtere overproduktion.
description: Opbevarer ekstra figurer, til en given kapicitet. Kan bruges til at håndtere overproduktion.
energy_generator:
deliver: Aflever
@ -548,14 +548,14 @@ buildings:
advanced_processor:
default:
name: Farveomvender
description: Tager imod en farve giver den modsatte.
description: Tager imod en farve, og giver den modsatte.
wire_crossings:
default:
name: Ledningsspalter
description: Spalter en energiledning i to.
merger:
name: Ledningssammenlægger
description: Sammenlægger to energiledninger til en.
description: Lægger to energiledninger sammen til en.
storyRewards:
# Those are the rewards gained from completing the store
@ -565,7 +565,7 @@ storyRewards:
reward_rotater:
title: Rotation
desc: <strong>Drejeren</strong> er nu tilgængelig! Den drejer figurer med uret med 90 grader.
desc: <strong>Drejeren</strong> er nu tilgængelig! Den drejer figurer 90 grader med uret.
reward_painter:
title: Maling
@ -578,11 +578,11 @@ storyRewards:
reward_stacker:
title: Stabler
desc: Du kan du stable figurer med <strong>stableren</strong>! Begge input er stablet, hvis de kan sættes ved siden af hinanden, <strong>sammensmeltes de</strong>. Hvis ikke er det højre input <strong>stablet ovenpå</strong> det venstre!
desc: Du kan du stable figurer med <strong>stableren</strong>! Begge inputs stables. Hvis de kan sættes ved siden af hinanden, <strong>sammensmeltes de</strong>. Hvis ikke, bliver det højre input <strong>stablet ovenpå</strong> det venstre!
reward_splitter:
title: Spalter/Sammenlægger
desc: Den flerfunktionelle <strong>spalter</strong> er nu tilgængelig - Den kan blive brugt til at bygge større fabrikker ved at <strong>spalte og sammenlægge varer</strong> på flere bælter!<br><br>
title: Fordeler/Sammenlægger
desc: Den flerfunktionelle <strong>Fordeler</strong> er nu tilgængelig - Den kan bruges til at bygge større fabrikker ved at <strong>fordele og sammenlægge varer</strong> på flere bælter!<br><br>
reward_tunnel:
title: Tunnel
@ -601,13 +601,13 @@ storyRewards:
desc: Du har fået adgang til en variant af <strong>tunnellen</strong> - Den har en <strong>større rækkevidde</strong>, og du kan også bruge begge typer tunneller på den samme strækning!
reward_splitter_compact:
title: Kompakt Spalter
title: Kompakt Fordeler
desc: >-
Du har fået adgang til en kompakt variant af <strong>spalteren</strong> - Den tager to inputs og sammenlægger dem til en!
Du har fået adgang til en kompakt variant af <strong>fordeleren</strong> - Den tager to inputs og lægger dem sammen til en!
reward_cutter_quad:
title: Quad Klipining
desc: Du har fået adgang til en variant af <strong>klipperen</strong> - Den lader dig klippe figurer i <strong>fire dele</strong> i stedet for bare to!
desc: Du har fået adgang til en variant af <strong>klipperen</strong> - Den lader dig klippe figurer i <strong>fire dele</strong> i stedet for kun to!
reward_painter_double:
title: Dobbelt Maling
@ -615,37 +615,37 @@ storyRewards:
reward_painter_quad:
title: Quad Maling
desc: Du har fået adgang til en variant af <strong>maleren</strong> - Den lader dig male hver del af en figur for sig!
desc: Du har fået adgang til en variant af <strong>maleren</strong> - Den lader dig male alle dele af en figur hver for sig!
reward_storage:
title: Opbevaringsbuffer
desc: Du har fået adgang til en variant af <strong>skraldespanden</strong> - Den lader dig opbevarer varer til en hvis kapacitet!
desc: Du har fået adgang til en variant af <strong>skraldespanden</strong> - Den lader dig opbevare varer til en hvis kapacitet!
reward_freeplay:
title: Frit spil
desc: Du klarede det! Du har fået adgang til <strong>frit spil</strong>! Dette betyder at figurer nu er tilfældigt genereret! (Vær ikke bekymret, mere indhold er planlagt for den bte version!)
desc: Du klarede det! Du har fået adgang til <strong>frit spil</strong>! Dette betyder at figurer nu er tilfældigt genereret! (Vær ikke bekymret, mere indhold er planlagt for den betalte version!)
reward_blueprints:
title: Arbejdstegninger
desc: Du kan nu <strong>kopiere og indsætte</strong> dele af din fabrik! Vælg et område (Hold CTRL, og træk med musen), og tryk 'C' for at kopiere det.<br><br>At sætte det ind er <strong>ikke gratis</strong>, du skal producere <strong>arbejdstegning figurer</strong> for at have råd til det! (Dem du lige har leveret).
desc: Du kan nu <strong>kopiere og indsætte</strong> dele af din fabrik! Vælg et område (Hold CTRL, og træk med musen), og tryk 'C' for at kopiere det.<br><br>At sætte det ind er <strong>ikke gratis</strong>. Du skal producere <strong>arbejdstegning figurer</strong> for at have råd til det! (Dem du lige har leveret).
# Special reward, which is shown when there is no reward actually
no_reward:
title: Næste level
title: Næste niveau
desc: >-
Dette level gav dig ingen belønninger, men det vil det næste! <br><br> PS: Du må hellere lade være med at ødelægge din fabrik - Du får brug for <strong>alle</strong> de figurer senere igen for at <strong>få opgraderinger</strong>!
Dette niveau gav dig ingen belønninger, men det vil det næste! <br><br> PS: Du må hellere lade være med at ødelægge din fabrik - Du får brug for <strong>alle</strong> de figurer senere igen for at <strong>få opgraderinger</strong>!
no_reward_freeplay:
title: Næste level
title: Næste niveau
desc: >-
Tillykke! Forresten er mere indhold planlagt for den bte version!
Tillykke! Forresten er mere indhold planlagt for den betalte version!
settings:
title: Indstillinger
categories:
general: Generelt
userInterface: Brugerflade
advanced: Advanceret
advanced: Avanceret
versionBadges:
dev: Udvikling
@ -657,7 +657,7 @@ settings:
uiScale:
title: Grænseflade størrelse
description: >-
Ændrer størrelsen på brugerfladen. Den vil stadig skalere baseret på opløsningen af din skærm, men denne indstilling bestemmer hvor meget den skalere.
Ændrer størrelsen på brugerfladen. Den vil stadig skalere baseret på opløsningen af din skærm, men denne indstilling bestemmer hvor meget den skalerer.
scales:
super_small: Meget lille
small: Lille
@ -668,20 +668,20 @@ settings:
autosaveInterval:
title: Autogem Interval
description: >-
Kontrollere hvor ofte spillet gemmer automatisk. Du kan også slå det helt fra her.
Ændrer hvor ofte spillet gemmer automatisk. Du kan også slå det helt fra her.
intervals:
one_minute: 1 Minut
two_minutes: 2 Minuter
five_minutes: 5 Minuter
ten_minutes: 10 Minuter
twenty_minutes: 20 Minuter
two_minutes: 2 Minutter
five_minutes: 5 Minutter
ten_minutes: 10 Minutter
twenty_minutes: 20 Minutter
disabled: Slået fra
scrollWheelSensitivity:
title: Zoom følsomhed
description: >-
Ændrer hvor følsomt zoomet er (Enten mussehjulet eller trackpad).
Ændrer hvor følsomt zoomet er (Enten musehjulet eller trackpad).
sensitivity:
super_slow: Meget langsom
slow: Langsom
@ -709,12 +709,12 @@ settings:
enableColorBlindHelper:
title: Farveblindstilstand
description: >-
Aktivere forskellige redskaber der lader dig spille, selv hvis du er farveblind.
Aktiverer forskellige redskaber der lader dig spille, selv hvis du er farveblind.
fullscreen:
title: Fuld skærm
description: >-
Det er forslået at spille i fuld skærm for den bedste oplevelse. Kun tilgængelig i den bte version.
Det er foreslået at spille i fuld skærm for den bedste oplevelse. Kun tilgængelig i den betalte version.
soundsMuted:
title: Slå lydeffekterne fra
@ -727,9 +727,9 @@ settings:
Aktiver for at slå al musik fra.
theme:
title: Spiltilstand
title: Tema
description: >-
Vælg spiltilstand (lys / mørk).
Vælg tema (lys / mørk).
themes:
dark: Mørk
light: Lys
@ -737,17 +737,17 @@ settings:
refreshRate:
title: Simulationsmål
description: >-
Hvis du har en 144hz skærm ændr opdateringshastigheden her så spillet vil simulere den højere opdateringshastighed korrekt. Dette kan faktisk sænke din FPS hvis din computer er for langsom.
Hvis du har en 144hz skærm, så ændr opdateringshastigheden her så spillet vil simulere den højere opdateringshastighed korrekt. Dette kan faktisk sænke din FPS hvis din computer er for langsom.
alwaysMultiplace:
title: Multiplacer
title: Multiplacér
description: >-
Aktiver for at alle bygninger fortsætter med at være valgt efter placering, indtil du vælger den fra. Dette svarer til altid at holde SHIFT nede.
Aktiver for at alle bygninger fortsætter med at være valgt efter placering, indtil du vælger dem fra. Dette svarer til altid at holde SKIFT nede.
offerHints:
title: Hints & Vejledning
description: >-
Om spillet skal tilbyde hints og vejledning imens du spiller. Skjuler også visse dele af brugerfladen indtil et givent level for at gøre det nemmere at lære spillet at kende.
Om spillet skal tilbyde hints og vejledning imens du spiller. Skjuler også visse dele af brugerfladen indtil et givent niveau for at gøre det nemmere at lære spillet at kende.
enableTunnelSmartplace:
title: Smarte Tunneller
@ -757,7 +757,7 @@ settings:
vignette:
title: Vignette
description: >-
Aktivere vignette hvilket mørkner kanterne af skærmen og gør teksten nemmere at læse.
Aktiverer vignette hvilket mørkner kanterne af skærmen og gør teksten nemmere at læse.
rotationByBuilding:
title: Rotation baseret på bygningstype
@ -767,7 +767,7 @@ settings:
compactBuildingInfo:
title: Kompakt Bygningsinfo
description: >-
Forkorter infobokse til bygninger ved kun at vise deres ratioer. Ellers er en beskrivelse og et billede også vist.
Forkorter infobokse til bygninger ved kun at vise deres forhold. Ellers er en beskrivelse og et billede også vist.
disableCutDeleteWarnings:
title: Slå klip/slet advarsler fra
@ -777,7 +777,7 @@ settings:
keybindings:
title: Keybindings
hint: >-
Tip: Husk at bruge CTRL, SHIFT og ALT! De byder på forskellige placeringsmuligheder.
Tip: Husk at bruge CTRL, SKIFT og ALT! De byder på forskellige placeringsmuligheder.
resetKeybindings: Nulstil Keybindings
@ -840,7 +840,7 @@ keybindings:
massSelectCopy: Kopier område
massSelectCut: Klip område
placementDisableAutoOrientation: Slå automatisk orientering fra
placementDisableAutoOrientation: Slå automatisk rotation fra
placeMultiple: Bliv i placeringstilstand
placeInverse: Spejlvend automatisk bælteorientering
menuClose: Luk Menu
@ -850,7 +850,7 @@ keybindings:
about:
title: Om dette spil
body: >-
Dette spil er open source og er udviklet af <a href="https://github.com/tobspr" target="_blank">Tobias Springer</a> (dette er mig).<br><br>
Dette spil er open source og er udviklet af <a href="https://github.com/tobspr" target="_blank">Tobias Springer</a> (det er mig).<br><br>
Hvis du vil kontribuere, tjek <a href="<githublink>" target="_blank">shapez.io på github</a>.<br><br>

View File

@ -303,7 +303,7 @@ ingame:
green: Grün
blue: Blau
yellow: Gelb
purple: Violett
purple: Magenta
cyan: Cyan
white: Weiß
black: Schwarz
@ -400,7 +400,7 @@ ingame:
waypoints:
waypoints: Markierungen
hub: Hub
description: Linksklick auf einen Marker, um dort hinzugelangen, Rechtsklick, um ihn zu löschen.<br><br>Drücke <keybinding> um einen Marker aus deinem Blickwinkel, oder <strong>rechtsklicke</strong>, um einen Marker auf der ausgewählten Position zu erschaffen.
description: Linksklick auf einen Marker, um dort hinzugelangen. Rechtsklick, um ihn zu löschen.<br><br>Drücke <keybinding>, um einen Marker aus deinem Blickwinkel, oder <strong>rechtsklicke</strong>, um einen Marker auf der ausgewählten Position zu erschaffen.
creationSuccessNotification: Marker wurde erstellt.
# Shape viewer
@ -413,12 +413,12 @@ ingame:
interactiveTutorial:
title: Tutorial
hints:
1_1_extractor: Platziere einen <strong>Extrahierer</strong> auf der <strong>Kreisform</strong> um sie zu extrahieren!
1_1_extractor: Platziere einen <strong>Extrahierer</strong> auf der <strong>Kreisform</strong>, um sie zu extrahieren!
1_2_conveyor: >-
Verbinde den Extrahierer mit einem <strong>Förderband</strong> und schließe ihn am Hub an!<br><br>Tipp: <strong>Drück und ziehe</strong> das Förderband mit der Maus!
Verbinde den Extrahierer mit einem <strong>Förderband</strong> und schließe ihn am Hub an!<br><br>Tipp: <strong>Drücke und ziehe</strong> das Förderband mit der Maus!
1_3_expand: >-
Dies ist <strong>KEIN</strong> Idle-Game! Baue mehr Extrahierer und Förderbänder, um das Ziel schneller zu erreichen.<br><br>Tipp: Halte <strong>UMSCH</strong>, um mehrere Gebäude zu platzieren und nutze <strong>R</strong> um sie zu rotieren.
Dies ist <strong>KEIN</strong> Idle-Game! Baue mehr Extrahierer und Förderbänder, um das Ziel schneller zu erreichen.<br><br>Tipp: Halte <strong>UMSCH</strong>, um mehrere Gebäude zu platzieren und nutze <strong>R</strong>, um sie zu rotieren.
# All shop upgrades
shopUpgrades:
@ -446,17 +446,17 @@ buildings:
belt:
default:
name: &belt Förderband
description: Transportiert Items. Halte und ziehe um mehrere zu platzieren.
description: Transportiert Items. Halte und ziehe, um mehrere zu platzieren.
# Internal name for the Extractor
miner:
default:
name: &miner Extrahierer
description: Platziere ihn auf einer Form oder Farbe um sie zu extrahieren.
description: Platziere ihn auf einer Form oder Farbe, um sie zu extrahieren.
chainable:
name: Extrahierer (Kette)
description: Platziere ihn auf einer Form oder Farbe um sie zu extrahieren. Kann verkettet werden.
description: Platziere ihn auf einer Form oder Farbe, um sie zu extrahieren. Kann verkettet werden.
# Internal name for the Tunnel
underground_belt:
@ -472,15 +472,15 @@ buildings:
splitter:
default:
name: &splitter Verteiler
description: Multifunktional - Verteilt gleichmäßig vom Eingang auf den Ausgang.
description: Multifunktional - Verteilt gleichmäßig von den Eingängen auf die Ausgänge.
compact:
name: Kombinierer (Kompakt)
description: Vereint zwei Förderbänder zu einem.
description: Vereint zwei Eingänge zu einem Ausgang.
compact-inverse:
name: Kombinierer (Kompakt)
description: Vereint zwei Förderbänder zu einem.
description: Vereint zwei Eingänge zu einem Ausgang.
cutter:
default:
@ -521,12 +521,12 @@ buildings:
description: *painter_desc
double:
name: Färber (2-Fach)
name: Färber (2-fach)
description: Färbt beide Formen aus dem linken Eingang mit der Farbe aus dem oberen Eingang.
quad:
name: Färber (4-Fach)
description: Erlaubt jedes einzelne Viertel einer Form beliebig einzufärben.
name: Färber (4-fach)
description: Erlaubt es, jedes einzelne Viertel einer Form beliebig einzufärben.
trash:
default:
@ -535,7 +535,7 @@ buildings:
storage:
name: Lager
description: Lagert den Überschuss bis zu einer gegebenen Kapazität. Kann als Überlauftor agieren.
description: Lagert Items bis zu einer gegebenen Kapazität und verwaltet den Überlauf.
wire:
default:
@ -563,24 +563,24 @@ storyRewards:
# Those are the rewards gained from completing the store
reward_cutter_and_trash:
title: Formen zerschneiden
desc: Du hast den <strong>Schneider</strong> freigeschaltet! - Er zerschneidet Formen von <strong>oben nach unten</strong>, unabhängig von ihrer Orientierung!<br><br>Stelle sicher, dass du den Abfall loswirst, sonst <strong>verstopft die Maschine</strong>! - Dafür habe ich dir extra einen Mülleimer freigeschaltet.
desc: Du hast den <strong>Schneider</strong> freigeschaltet! Er zerschneidet Formen von <strong>oben nach unten</strong>, unabhängig von ihrer Orientierung.<br><br>Stelle sicher, dass du den Abfall loswirst, sonst <strong>verstopft die Maschine</strong>! Dafür habe ich dir extra einen Mülleimer freigeschaltet.
reward_rotater:
title: Rotieren
desc: Der <strong>Rotierer</strong> wurde freigeschaltet! Er rotiert Formen im Uhrzeigersinn um 90 Grad!
desc: Der <strong>Rotierer</strong> wurde freigeschaltet! Er rotiert Formen im Uhrzeigersinn um 90 Grad.
reward_painter:
title: Färben
desc: >-
Der <strong>Färber</strong> wurde freigeschaltet. Extrahiere ein paar Farben (genauso wie bei Formen) und färbe damit eine Form im Färber!<br><br>PS: Falls du Farbenblind bist, es gibt einen <strong>Modus für Farbenblinde</strong> in den Einstellungen!
Der <strong>Färber</strong> wurde freigeschaltet. Extrahiere ein paar Farben (genauso wie bei Formen) und färbe damit eine Form im Färber.<br><br>PS: Falls du Farbenblind bist, gibt es einen <strong>Modus für Farbenblinde</strong> in den Einstellungen!
reward_mixer:
title: Farben mischen
desc: Der <strong>Farbmischer</strong> wurde freigeschaltet! Kombiniere mit diesem Gebäude zwei Farben getreu der <strong>additiven Farbmischung</strong>!
desc: Der <strong>Farbmischer</strong> wurde freigeschaltet! Kombiniere mit diesem Gebäude zwei Farben getreu der <strong>additiven Farbmischung</strong>.
reward_stacker:
title: Stapler
desc: Mit dem <strong>Stapler</strong> kannst du nun Formen kombinieren! Passen sie nebeneinander, werden sie <strong>verschmolzen</strong>. Anderenfalls wird die rechte auf die linke Form <strong>gestapelt</strong>!
desc: Mit dem <strong>Stapler</strong> kannst du nun Formen kombinieren! Passen sie nebeneinander, werden sie <strong>verschmolzen</strong>. Anderenfalls wird die rechte auf die linke Form <strong>gestapelt</strong>.
reward_splitter:
title: Verteiler/Kombinierer
@ -588,11 +588,11 @@ storyRewards:
reward_tunnel:
title: Tunnel
desc: Der <strong>Tunnel</strong> wurde freigeschaltet! Du kannst Items nun unter Gebäuden oder Förderbändern hindurchleiten!
desc: Der <strong>Tunnel</strong> wurde freigeschaltet! Du kannst Items nun unter Gebäuden oder Förderbändern hindurchleiten.
reward_rotater_ccw:
title: Gegen UZS Rotieren
desc: Du hast eine zweite Variante des <strong>Rotierers</strong> freigeschaltet! Damit können Items gegen den Uhrzeigensinn gedreht werden. Wähle den Rotierer aus und <strong>drücke 'T', um auf verschiedene Varianten zuzugreifen</strong>!
desc: Du hast eine zweite Variante des <strong>Rotierers</strong> freigeschaltet! Damit können Items gegen den Uhrzeigensinn gedreht werden. Wähle den Rotierer aus und <strong>drücke 'T', um auf verschiedene Varianten zuzugreifen</strong>.
reward_miner_chainable:
title: Extrahierer (Kette)
@ -600,28 +600,28 @@ storyRewards:
reward_underground_belt_tier_2:
title: Tunnel Stufe II
desc: Du hast eine neue Variante des <strong>Tunnels</strong> freigeschaltet! Dieser hat eine <strong>höhere Reichweite</strong> und du kannst beide Tunnel miteinander mischen!
desc: Du hast eine neue Variante des <strong>Tunnels</strong> freigeschaltet! Dieser hat eine <strong>höhere Reichweite</strong> und du kannst beide Tunnel miteinander mischen.
reward_splitter_compact:
title: Kompakter Kombinierer
desc: >-
Du hast eine kompakte Variante des <strong>Kombinierers</strong> freigeschaltet! Er hat zwei Eingänge und gibt zwei Förderbänder als eines aus!
Du hast eine kompakte Variante des <strong>Kombinierers</strong> freigeschaltet! Er hat zwei Eingänge und vereint diese zu einem Ausgang.
reward_cutter_quad:
title: Schneider (4-fach)
desc: Du hast eine neue Variante des <strong>Schneiders</strong> freigeschaltet! Damit kannst du Formen in alle <strong>vier Teile</strong> zerschneiden!
desc: Du hast eine neue Variante des <strong>Schneiders</strong> freigeschaltet! Damit kannst du Formen in alle <strong>vier Teile</strong> zerschneiden.
reward_painter_double:
title: Färber (2-fach)
desc: Du hast eine neue Variante des <strong>Färbers</strong> freigeschaltet! Hiermit kannst du <strong>zwei Formen auf einmal</strong> färben und verbrauchst nur eine Farbe!
desc: Du hast eine neue Variante des <strong>Färbers</strong> freigeschaltet! Hiermit kannst du <strong>zwei Formen auf einmal</strong> färben und verbrauchst nur eine Farbe.
reward_painter_quad:
title: Färber (4-fach)
desc: Du hast eine neue Variante des <strong>Färbers</strong> freigeschaltet! Er kann jedes Viertel einer Form einzeln färben, verbraucht aber auch jeweils eine Farbe!
desc: Du hast eine neue Variante des <strong>Färbers</strong> freigeschaltet! Er kann jedes Viertel einer Form einzeln färben, verbraucht aber auch jeweils eine Farbe.
reward_storage:
title: Zwischenlager
desc: Du hast eine neue Variante des <strong>Mülleimers</strong> freigeschaltet! Bis zu einer gewissen Kapazität können hier Items zwischengelagert werden!
desc: Du hast eine neue Variante des <strong>Mülleimers</strong> freigeschaltet! Bis zu einer gewissen Kapazität können hier Items zwischengelagert werden.
reward_freeplay:
title: Freies Spiel
@ -635,7 +635,7 @@ storyRewards:
no_reward:
title: Nächstes Level
desc: >-
Dieses Level hat dir keine Belohnung gegeben, aber dafür das Nächste schon! <br><br> PS: Denk daran, deine alten Fabriken nicht zu zerstören - Du wirst sie später <strong>alle</strong> noch brauchen, um <strong>Upgrades freizuschalten</strong>!
Dieses Level hat dir keine Belohnung gegeben, aber dafür das Nächste schon! <br><br> PS: Denke daran, deine alten Fabriken nicht zu zerstören - Du wirst sie später <strong>alle</strong> noch brauchen, um <strong>Upgrades freizuschalten</strong>!
no_reward_freeplay:
title: Nächstes Level
@ -721,22 +721,22 @@ settings:
soundsMuted:
title: Geräusche stummschalten
description: >-
Bei der Aktivierung werden alle Geräusche stummgeschaltet.
Bei Aktivierung werden alle Geräusche stummgeschaltet.
musicMuted:
title: Musik stummschalten
description: >-
Bei der Aktivierung wird die Musik stummgeschaltet.
Bei Aktivierung wird die Musik stummgeschaltet.
soundVolume:
title: Geräuschlautstärke
description: >-
Ändert die Lautstärke von Geräuschen.
Regler für die Lautstärke von Geräuschen.
musicVolume:
title: Musiklautstärke
description: >-
Ändert die Lautstärke der Musik.
Regler für die Lautstärke der Musik.
theme:
title: Farbmodus
@ -749,12 +749,12 @@ settings:
refreshRate:
title: Tickrate
description: >-
Das Spiel passt die Tickrate automatisch so an, dass sie immer zwischen diesem Wert und der hälfte bleibt. Zum Beispiel bei einer Tickrate von 60 Hz versucht das Spiel, diese zu halten. Falls dies zu viel ist, regelt der Computer diese runter bis zu einer Untergrenze von 30Hz.
Das Spiel passt die Tickrate automatisch so an, dass sie immer zwischen diesem Wert und der Hälfte bleibt. Zum Beispiel bei einer Tickrate von 60 Hz versucht das Spiel, diese zu halten. Bei Bedarf regelt der Computer diese bis zu einer Untergrenze von 30 Hz herunter.
alwaysMultiplace:
title: Mehrfachplatzierung
description: >-
Bei Aktivierung wird das platzierte Gebäude nicht abgewählt. Das hat den gleichen Effekt wie beim Platzieren UMSCH gedrückt zu halten.
Bei Aktivierung wird das platzierte Gebäude nicht abgewählt. Das hat den gleichen Effekt, wie beim Platzieren UMSCH gedrückt zu halten.
offerHints:
title: Hinweise & Tutorials
@ -793,7 +793,7 @@ keybindings:
hint: >-
Tipp: Benutze STRG, UMSCH and ALT! Sie aktivieren verschiedene Platzierungsoptionen.
resetKeybindings: Tastenbelegung zurücksetzen.
resetKeybindings: Tastenbelegung zurücksetzen
categoryLabels:
general: Anwendung
@ -844,13 +844,13 @@ keybindings:
rotateWhilePlacing: Rotieren
rotateInverseModifier: >-
Modifikator: stattdessen gegen den UZS rotieren
cycleBuildingVariants: Variante wählen
cycleBuildingVariants: Nächste Variante auswählen
confirmMassDelete: Massenlöschung bestätigen
pasteLastBlueprint: Letzte Blaupause einfügen
cycleBuildings: Gebäude rotieren
cycleBuildings: Nächstes Gebäude auswählen
lockBeltDirection: Bandplaner aktivieren
switchDirectionLockSide: >-
Planer: Seite wechseln
Bandplaner: Seite wechseln
massSelectStart: Halten und ziehen zum Beginnen
massSelectSelectMultiple: Mehrere Areale markieren

View File

@ -596,7 +596,7 @@ buildings:
default:
name: &filter Filter
# TEMP
description: Only leaves through items who match exactly the provided shape / color. If you put in a boolean 1, it leaves everything through, if you put in a 0 it will leave nothing through.
description: Only allows through items which match exactly the provided shape / color. If you put in a boolean 1, it allows everything through, if you put in a 0 it will allow nothing through.
display:
default:
@ -728,6 +728,8 @@ settings:
prod: Production
buildDate: Built <at-date>
rangeSliderPercentage: <amount> %
labels:
uiScale:
title: Interface scale
@ -885,6 +887,11 @@ settings:
description: >-
The game is divided into chunks of 16x16 tiles, if this setting is enabled the borders of each chunk are displayed.
pickMinerOnPatch:
title: Pick miner on resource patch
description: >-
Enabled by default, selects the miner if you use the pipette when hovering a resource patch.
keybindings:
title: Keybindings
hint: >-

View File

@ -639,6 +639,7 @@ settings:
general: Général
userInterface: Interface utilisateur
advanced: Avancé
performance: Performance
versionBadges:
dev: Développement
@ -723,11 +724,13 @@ settings:
fast: Rapide
super_fast: Très rapide
extremely_fast: Extrêmement rapide
enableTunnelSmartplace:
title: Tunnels intelligents
description: >-
Si cette option est sélectionnée, placer des tunnels effacera automatiquement les convoyeurs inutiles.
Cela permet aussi détirer les tunnels et les tunnels en surnombre seront effacés.
Cela permet aussi détirer les tunnels, et les tunnels en surnombre seront effacés.
vignette:
title: Effet de vignette
description: >-
@ -744,10 +747,12 @@ settings:
ten_minutes: 10 minutes
twenty_minutes: 20 minutes
disabled: Désactivé
compactBuildingInfo:
title: Informations réduites sur les bâtiments
description: >-
Raccourcit les panneaux dinformation sur les bâtiments en naffichant que les ratios. Si désactivé, montre une description et une image.
disableCutDeleteWarnings:
title: Désactive les avertissements pour Couper/Effacer
description: >-
@ -756,12 +761,39 @@ settings:
enableColorBlindHelper:
title: Mode daltonien
description: Active divers outils qui permettent de jouer à ce jeu si vous êtes daltonien.
rotationByBuilding:
title: Rotation par catégorie de bâtiment
description: >-
Chaque catégorie de bâtiment enregistre le sens de rotation que vous lui avez assigné la dernière fois, de manière individuelle.
Cela sera sans doute plus agréable si vous alternez fréquemment entre le placement de différents types de bâtiments.
lowQualityMapResources:
title: Ressources de la carte de plus basse qualité
description: >-
Simplifie le rendu des ressources sur la carte lorsquelle est zoomée pour améliorer les performances.
Ça donne un rendu encore plus propre, alors essayez-le!
disableTileGrid:
title: Désactiver la grille de placement
description: >-
Désactiver la grille de placement peut améliorer les performances. Ça rend aussi lapparence plus unie!
clearCursorOnDeleteWhilePlacing:
title: Vider le curseur avec le clic droit
description: >-
Activé par défaut, remet à zéro le curseur lorsque vous faites un clic droit en ayant un bâtiment selectionné pour la construction. Si désactivé, vous pouvez détruire les bâtiments avec un clic droit puis continuer de placer un bâtiment.
lowQualityTextures:
title: Textures de basse résolution (moche)
description: >-
Utilise des textures de basse qualité pour améliorer les performances. Rend le jeu très moche!
displayChunkBorders:
title: Monter les blocs
description: >-
Le jeu est divisé en blocs de 16×16 cases. Si ce réglage est activé, les limites de chaque bloc sont affichées.
keybindings:
title: Contrôles
hint: >-
@ -869,6 +901,4 @@ demo:
# French translation version v0.5 based on english v1.1.8 by Didier WEERTS 'The Corsaire'
#
# French translation completed (and corrected) by Pascal Grossé and Withers001
# French translation entirely completed and corrected by martypiton
# French translation completed (and corrected) by Pascal Grossé, martypiton and Withers001.

View File

@ -31,75 +31,76 @@ steamPage:
longText: >-
[img]{STEAM_APP_IMAGE}/extras/store_page_gif.gif[/img]
shapez.io is a game about building factories to automate the creation and processing of increasingly complex shapes across an infinitely expanding map.
Upon delivering the requested shapes you will progress within the game and unlock upgrades to speed up your factory.
In shapez.io potrai costruire delle fabbriche per automatizzare la creazione e la combinazione di forme sempre più complesse, in una mappa infinita.
As the demand for shapes increases, you will have to scale up your factory to meet the demand - Don't forget about resources though, you will have to expand across the [b]infinite map[/b]!
Una volta che avrai consegnato le forme richieste, progredirai nel gioco e sbloccherai dei miglioramenti per rendere la tua fabbrica più veloce.
Soon you will have to mix colors and paint your shapes with them - Combine red, green and blue color resources to produce different colors and paint shapes with it to satisfy the demand.
Per rispondere alla crescente richiesta di forme, dovrai ingrandire la tua fabbrica - Non dimenticarti delle risorse, però; dovrai espanderti attraverso la [b]mappa infinita[/b]!
This game features 18 progressive levels (Which should keep you busy for hours already!) but I'm constantly adding new content - There is a lot planned!
Presto dovrai mescolare colori e usarli per verniciare le tue forme - Combina le risorse dei colori rosso, verde e blu per produrre colori differenti, verniciare le forme con essi e soddisfare la richiesta.
Purchasing the game gives you access to the standalone version which has additional features and you'll also receive access to newly developed features.
Nel gioco sono presenti 18 livelli progressivi (Che già dovrebbero tenerti occupato per ore) Ma sto costantemente aggiungendo nuovi contenuti - C'è molto in programma!
[b]Standalone Advantages[/b]
Acquistare il gioco ti darà accesso alla versione standalone, con caratteristiche aggiuntive e l'accesso ai nuovi contenuti sviluppati.
[b]Vantaggi della versione completa[/b]
[list]
[*] Dark Mode
[*] Unlimited Waypoints
[*] Unlimited Savegames
[*] Additional settings
[*] Coming soon: Wires & Energy! Aiming for (roughly) end of July 2020.
[*] Coming soon: More Levels
[*] Allows me to further develop shapez.io ❤️
[*] Modalità scura
[*] Segnapunti illimitati
[*] Salvataggi illimitati
[*] Opzioni aggiuntive
[*] In arrivo: Cavi ed energia! Previsti (approssimativamente) per la fine di Luglio 2020.
[*] Coming soon: Più livelli
[*] Mi consente di svillupare ulteriormente shapez.io ❤️
[/list]
[b]Future Updates[/b]
[b]Aggiornamenti futuri[/b]
I am updating the game very often and trying to push an update at least every week!
Sto aggiornando il gioco molto di frequente e cerco di pubblicare un nuovo aggiornamento almeno una volta a settimana.
[list]
[*] Different maps and challenges (e.g. maps with obstacles)
[*] Puzzles (Deliver the requested shape with a restricted area / set of buildings)
[*] A story mode where buildings have a cost
[*] Configurable map generator (Configure resource/shape size/density, seed and more)
[*] Additional types of shapes
[*] Performance improvements (The game already runs pretty well!)
[*] And much more!
[*] Mappe diverse e sfide (ad esempio mappe con ostacoli)
[*] Rompicapi (Consegna la forma richiesta utilizzando un'area limitata o un insieme ristretto di edifici)
[*] Una modalità storia in cui gli edifici hanno un costo.
[*] Generatore della mappa configurabile (Configura dimensione e densità delle forme/risorse, seed e altro)
[*] Tipi di forma aggiuntivi.
[*] Miglioramenti delle prestazioni (Il gioco funziona già piuttosto bene!)
[*] E molto altro!
[/list]
[b]This game is open source![/b]
[b]Questo gioco è open source![/b]
Anybody can contribute, I'm actively involved in the community and attempt to review all suggestions and take feedback into consideration where possible.
Be sure to check out my trello board for the full roadmap!
Chiunque può contribuire, interagisco attivamente con la community, cerco leggere tutti i suggerimenti e tengo in considerazione i feedback quando possibile.
Visita la mia pagina su trello per la tabella di marcia completa!
[b]Links[/b]
[list]
[*] [url=https://discord.com/invite/HN7EVzV]Official Discord[/url]
[*] [url=https://trello.com/b/ISQncpJP/shapezio]Roadmap[/url]
[*] [url=https://discord.com/invite/HN7EVzV]Server ufficiale Discord[/url]
[*] [url=https://trello.com/b/ISQncpJP/shapezio]Tabella di marcia[/url]
[*] [url=https://www.reddit.com/r/shapezio]Subreddit[/url]
[*] [url=https://github.com/tobspr/shapez.io]Source code (GitHub)[/url]
[*] [url=https://github.com/tobspr/shapez.io/blob/master/translations/README.md]Help translate[/url]
[*] [url=https://github.com/tobspr/shapez.io]Codice sorgente(GitHub)[/url]
[*] [url=https://github.com/tobspr/shapez.io/blob/master/translations/README.md]Aiuto per le traduzioni[/url]
[/list]
discordLink: Official Discord - Chat with me!
discordLink: Server ufficiale Discord - Chatta con me!
global:
loading: Caricamento
error: Errore
# How big numbers are rendered, e.g. "10,000"
thousandsDivider: ","
thousandsDivider: "'"
# What symbol to use to seperate the integer part from the fractional part of a number, e.g. "0.4"
decimalSeparator: "."
decimalSeparator: ","
# The suffix for large numbers, e.g. 1.3k, 400.2M, etc.
suffix:
thousands: k
millions: M
billions: B
billions: G
trillions: T
# Shown for infinitely big numbers
@ -135,7 +136,7 @@ demoBanners:
# This is the "advertisement" shown in the main menu and other various places
title: Versione Demo
intro: >-
Ottieni la versione standalone per sbloccare tutte le funzioni!
Ottieni la versione completa per sbloccare tutte le funzioni!
mainMenu:
play: Play
@ -147,7 +148,7 @@ mainMenu:
# This is shown when using firefox and other browsers which are not supported.
browserWarning: >-
Ci spiace, ma il gioco è molto lento su questo browser! Ottieni la versione standalone oppure scarica Chrome per provare l'esperienza completa.
Ci spiace, ma il gioco è molto lento su questo browser! Ottieni la versione completa oppure scarica Chrome per l'intera esperienza.
savegameLevel: Livello <x>
savegameLevelUnknown: Livello sconosciuto
@ -163,12 +164,12 @@ dialogs:
delete: Elimina
cancel: Annulla
later: Più tardi
restart: Ricomincia
restart: Riavvia
reset: Reset
getStandalone: Ottieni la versione completa
deleteGame: So cosa sto facendo
viewUpdate: Mostra aggiornamento
showUpgrades: Mostra upgrade
showUpgrades: Mostra miglioramenti
showKeybindings: Mostra scorciatoie
importSavegameError:
@ -199,42 +200,43 @@ dialogs:
restartRequired:
title: Restart richiesto
text: >-
Per applicare le nuove impostazioni è necessario il Restart del gioco.
Per applicare le nuove impostazioni è necessario riavviare del gioco.
editKeybinding:
title: Cambia comandi
desc: Premi un nuovo tasto o un tasto del mouse a cui vuoi assegnare questo comando, Esc per cancellarlo.
desc: Premi un nuovo tasto o un tasto del mouse a cui vuoi assegnare questo comando, Esc per annullare.
resetKeybindingsConfirmation:
title: Reset comandi assegnati
desc: Così riporterai tutti comandi al loro stato di default. Perfavore conferma.
desc: Così riporterai tutti comandi al loro stato predefinto. Per favore conferma.
keybindingsResetOk:
title: Successo nel reset dei comandi
desc: I comandi sono stati riassegnati ai loro rispettivi comandi di default!
desc: I comandi predefiniti sono stati ripristinati!
featureRestriction:
title: Versione Demo
desc: Hai provato ad accedere ad una feature (<feature>) che non è disponibile nella Demo. Considera di prendere la versione standalne per un'esperienza completa!
desc: Hai provato ad accedere ad una caratteristica (<feature>) che non è disponibile nella Demo. Considera di prendere la versione completa per l'intera esperienza!
oneSavegameLimit:
title: Salvataggi limitati
desc: Puoi avere solo un salvataggio nella versione Demo. Perfavore rimuovi il salvataggio già esistente o prendi la versione standalone!
desc: Puoi avere solo un salvataggio nella versione Demo. Perfavore rimuovi il salvataggio già esistente o prendi la versione completa!
updateSummary:
title: Nuovo update!
title: Nuovo aggiornamento!
desc: >-
Qui puoi trovare i cambiamenti dall'ultima volta che hai giocato:
upgradesIntroduction:
title: Aggiornamenti sbloccati
title: Miglioramenti sbloccati
desc: >-
Tutte le forme che produci possono essere utilizzate per i miglioramenti - <strong>Non distruggere le tue vecchie fabbriche!</strong>
Puoi trovare gli aggiornamenti nell'angolo in alto a destra dello schermo.
Puoi trovare i miglioramenti nell'angolo in alto a destra dello schermo.
massDeleteConfirm:
title: Conferma la rimozione
desc: >-
Stai rimuovendo molte strutture (<count> to be exact)!
Stai rimuovendo molte strutture (<count> per essere precisi)!
Sei sicuro di volerlo fare?
blueprintsNotUnlocked:
@ -246,33 +248,33 @@ dialogs:
title: Comandi utili
desc: >-
Questo gioco ha molti comandi utili che possono rendere più semplice la costruzione delle fabbriche.
Qui ce ne sono un paio, ma sii sicuro <strong>controlla i comandi</strong>!<br><br>
Qui ce ne sono un paio, ma dovresti <strong>controllare i comandi</strong>!<br><br>
<code class='keybinding'>CTRL</code> + Drag: Seleziona l'area da copiare / cancella.<br>
<code class='keybinding'>SHIFT</code>: Tieni premuto per costruire copie dalla struttura.<br>
<code class='keybinding'>ALT</code>: Invert l'orientamento dei nastri trasportatori.<br>
<code class='keybinding'>SHIFT</code>: Tieni premuto per costruire copie dell'edificio.<br>
<code class='keybinding'>ALT</code>: Inverti l'orientamento dei nastri trasportatori.<br>
createMarker:
title: Nuovo Marker
desc: Dagli un magnifico nome, puoi anche includere <strong>short key</strong> di una figura (Che puoi generare <a href="https://viewer.shapez.io" target="_blank">here</a>)
titleEdit: Edit Marker
title: Nuovo segnapunto
desc: Dagli un nome con un significato, puoi anche includere il <strong>codice</strong> di una figura (Che puoi generare <a href="https://viewer.shapez.io" target="_blank">qui</a>)
titleEdit: Modifica segnapunto
markerDemoLimit:
desc: Puoi creare solo due Marker personalizzati nella Demo. Prendi la versione standalone per Marker personalizzati illimitati!
desc: Puoi creare solo due segnapunti personalizzati nella Demo. Ottieni la versione completa per avere segnapunti personalizzati illimitati!
massCutConfirm:
title: Conferma taglio
desc: >-
Stai tagliando molte strutture (<count> to be exact)!
Stai tagliando molte strutture (<count> per essere precisi)!
Sei sicuro di volerlo fare?
exportScreenshotWarning:
title: Esportare screenshot
desc: >-
Hai richiesto di esportare la tua base come screenshot. Perfavore tieni conto che potrebbe
essere lento per una grossa base e che potrebbe crushare il gioco!
essere lento per una grossa base e che potrebbe causare il crash del gioco!
massCutInsufficientConfirm:
title: Confirm cut
desc: You can not afford to paste this area! Are you sure you want to cut it?
title: Conferma taglia
desc: Non puoi permetterti di incollare quest'area! Sei sicuro di volerla tagliare?
ingame:
# This is shown in the top left corner and displays useful keybindings in
@ -281,23 +283,22 @@ ingame:
moveMap: Sposta
selectBuildings: Seleziona area
stopPlacement: Concludi posizionamento
rotateBuilding: Ruota costruzione
rotateBuilding: Ruota edificio
placeMultiple: Posiziona multiplo
reverseOrientation: Inverti orientamento
disableAutoOrientation: Disabilita orientamento automatico
toggleHud: Mostra/Nascondi HUD
placeBuilding: Posiziona costruzione
createMarker: Crea etichetta
delete: Distruggi
pasteLastBlueprint: Paste last blueprint
lockBeltDirection: Enable belt planner
plannerSwitchSide: Flip planner side
delete: Cancella
pasteLastBlueprint: Incolla l'ultimo progetto
lockBeltDirection: Attiva pianificatore nastri
plannerSwitchSide: Cambia direzione pianificatore
cutSelection: Taglia
copySelection: Copia
clearSelection: Annulla selezione
pipette: Contagocce
switchLayers: Switch layers
switchLayers: Cambia livello
# Everything related to placing buildings (I.e. as soon as you selected a building
# from the toolbar)
buildingPlacement:
@ -317,47 +318,48 @@ ingame:
itemsPerSecond: <x> oggetti / s
itemsPerSecondDouble: (x2)
tiles: <x> titles
tiles: <x> caselle
# The notification when completing a level
levelCompleteNotification:
# <level> is replaced by the actual level, so this gets 'Level 03' for example.
levelTitle: Livello <level>
completed: Completato
unlockText: Sbloccato <reward>!
unlockText: >-
Sbloccato: <reward>!
buttonNextLevel: Prossimo livello
# Notifications on the lower right
notifications:
newUpgrade: U nuovo aggiornamento è disponibile!
gameSaved: La tua partita è stata salvata.
newUpgrade: È disponibile un nuovo aggiornamento!
gameSaved: Partita salvata.
# The "Upgrades" window
shop:
title: Aggiornamenti
title: Miglioramenti
buttonUnlock: Sblocca
# Gets replaced to e.g. "Tier IX"
tier: Tier <x>
tier: Grado <x>
# The roman number for each tier
tierLabels: [I, II, III, IV, V, VI, VII, VIII, IX, X]
maximumLevel: LIVELLO MASSIMO (Speed x<currentMult>)
maximumLevel: GRADO MASSIMO (Velocità x<currentMult>)
# The "Statistics" window
statistics:
title: Statistiche
dataSources:
stored:
title: Immagazzinati
description: Displaying amount of stored shapes in your central building.
title: Immagazzinate
description: Mostra il numero di forme immagizzinate nell'edificio centrale.
produced:
title: Prodotti
description: Displaying all shapes your whole factory produces, including intermediate products.
title: Prodotte
description: Mostra tutte le forme prodotte dalla tua fabbrica, inclusi i prodotti intermedi.
delivered:
title: Delivered
description: Displaying shapes which are delivered to your central building.
title: Consegnate
description: Mostra le forme che vengono consegnate all'edificio centrale.
noShapesProduced: No shapes have been produced so far.
# Displays the shapes per minute, e.g. '523 / m'
@ -367,7 +369,7 @@ ingame:
settingsMenu:
playtime: Tempo di gioco
buildingsPlaced: Buildings
buildingsPlaced: Edifici
beltsPlaced: Nastri
buttons:
@ -387,50 +389,50 @@ ingame:
# Map markers
waypoints:
waypoints: Markers
waypoints: Segnapunti
hub: HUB
description: Left-click a marker to jump to it, right-click to delete it.<br><br>Press <keybinding> to create a marker from the current view, or <strong>right-click</strong> to create a marker at the selected location.
creationSuccessNotification: Marker has been created.
description: Click sinistro su un segnapunto per raggiungerlo, click destro per cancellarlo. <br><br>Premi <keybinding> per creare un segnapunto dalla visuale corrente, oppure <strong>click destro</strong> per creare un segnapunto nella posizione selezionata.
creationSuccessNotification: Il segnapunto è stato creato.
# Interactive tutorial
interactiveTutorial:
title: Tutorial
hints:
1_1_extractor: Place an <strong>extractor</strong> on top of a <strong>circle shape</strong> to extract it!
1_1_extractor: Posiziona un <strong>estrattore</strong> sopra una <strong>forma circolare</strong> per estrarla!
1_2_conveyor: >-
Connect the extractor with a <strong>conveyor belt</strong> to your hub!<br><br>Tip: <strong>Click and drag</strong> the belt with your mouse!
Connetti l'estrattore all'Hub centrale utilizzando un <strong>nastro trasportatore</strong>!<br><br>Suggerimento: <strong>Clicca e trascina</strong> il nastro con il mouse!
1_3_expand: >-
This is <strong>NOT</strong> an idle game! Build more extractors and belts to finish the goal quicker.<br><br>Tip: Hold <strong>SHIFT</strong> to place multiple extractors, and use <strong>R</strong> to rotate them.
Questo <strong>NON</strong> è un idle game! Costruisci più estrattori e nastri per raggiungere l'obiettivo più velocemente.<br><br>Suggerimento: Tieni premuto <strong>MAIUSC</strong> per piazzare estrattori multipli, e usa <strong>R</strong> per ruotarli.
colors:
red: Rosso
green: Verde
blue: Blu
yellow: Giallo
purple: Viola
purple: Magenta
cyan: Azzurro
white: Bianco
uncolored: No colore
black: Black
black: Nero
shapeViewer:
title: Livelli
title: Strati
empty: Vuoto
copyKey: Copy Key
copyKey: Copia codice
# All shop upgrades
shopUpgrades:
belt:
name: Belts, Distributor & Tunnels
name: Nastri, distribuzione e tunnel
description: Velocità x<currentMult> → x<newMult>
miner:
name: Estrazione
description: Velocità x<currentMult> → x<newMult>
processors:
name: Cutting, Rotating & Stacking
name: Taglio, rotazione e impilamento
description: Velocità x<currentMult> → x<newMult>
painting:
name: Mixing & Painting
name: Mix e verniciatura
description: Velocità x<currentMult> → x<newMult>
# Buildings and their name / description
@ -473,27 +475,27 @@ buildings:
cutter:
default:
name: &cutter Cutter
description: Cuts shapes from top to bottom and outputs both halfs. <strong>If you use only one part, be sure to destroy the other part or it will stall!</strong>
name: &cutter Tagliatrice
description: Taglia le forme verticalmente e restituisce le metà destra e sinistra. <strong>Se usi solo una parte, distruggi l'altra o la macchina si fermerà!</strong>
quad:
name: Cutter (Quad)
description: Cuts shapes into four parts. <strong>If you use only one part, be sure to destroy the other part or it will stall!</strong>
name: Tagliatrice (4x)
description: Taglia le forme in quattro parti. <strong>Se usi solo una parte, distruggi le altre o la macchina si fermerà!</strong>
rotater:
default:
name: &rotater Rotate
description: Rotates shapes clockwise by 90 degrees.
name: &rotater Ruotatrice
description: Ruota le forme di 90 gradi in senso orario.
ccw:
name: Rotate (CCW)
description: Rotates shapes counter clockwise by 90 degrees.
name: Ruotatrice (Ant.)
description: Ruota le forme di 90 gradi in senso antiorario.
fl:
name: Rotate (180)
description: Rotates shapes by 180 degrees.
name: Ruotatrice (180)
description: Ruota le forme di 180 gradi.
stacker:
default:
name: &stacker Stacker
description: Stacks both items. If they can not be merged, the right item is placed above the left item.
name: &stacker Impilatrice
description: Unisce o impila i due oggetti, se gli oggetti non possono essere uniti, l'oggetto destro è posizionato sopra il sinstro.
mixer:
default:
@ -502,14 +504,14 @@ buildings:
painter:
default:
name: &painter Verniciatore
description: &painter_desc Colora l'intera forma dell'ingresso sinistro con il colore dell'ingresso destro.
name: &painter Verniciatrice
description: &painter_desc Colora l'intera forma dall'ingresso sinistro con il colore dall'ingresso destro.
double:
name: Verniciatore (Doppio)
description: Colors the shapes on the left inputs with the color from the top input.
name: Verniciatrice (2x)
description: Colora le forme dagli ingressi sinistri con il colore dall'ingresso destro.
quad:
name: Verniciatore (Quadruplo)
description: Allows to color each quadrant of the shape with a different color.
name: Verniciatrice (4x)
description: Consente di colorare ogni quadrante della forma con un colore diverso.
mirrored:
name: *painter
description: *painter_desc
@ -517,156 +519,158 @@ buildings:
trash:
default:
name: &trash Cestino
description: Accetta ingressi da tutti i lati e li distrugge. per sempre.
description: Accetta oggetti da tutti i lati e li distrugge. Per sempre.
storage:
name: Storage
description: Stores excess items, up to a given capacity. Can be used as an overflow gate.
name: Stoccaggio
#Literal translation, quite ugly, might need rephrasing
description: Immagazzina gli oggetti in eccesso, fino ad una certa capacità. Può essere usato come varco per le eccedenze
hub:
deliver: Consegna
toUnlock: per sbloccare
levelShortcut: LVL
wire:
default:
name: Energy Wire
description: Allows you to transport energy.
name: Cavo energetico
description: Ti consente di trasportare energia.
advanced_processor:
default:
name: Color Inverter
description: Accepts a color or shape and inverts it.
name: Invertitore di colori
description: Accetta un colore o una forma e li inverte.
energy_generator:
deliver: Deliver
toGenerateEnergy: For
deliver: Consegna
toGenerateEnergy: per generare
default:
name: Energy Generator
description: Generates energy by consuming shapes.
name: Generatore di energia
description: Genera energia consumando forme.
wire_crossings:
default:
name: Wire Splitter
description: Splits a energy wire into two.
name: Separatore cavi
description: Divide un cavo energetico in due.
merger:
name: Wire Merger
description: Merges two energy wires into one.
name: Giunzione cavi
description: Unisce due cavi energetici in uno.
storyRewards:
# Those are the rewards gained from completing the store
reward_cutter_and_trash:
title: Cutting Shapes
desc: You just unlocked the <strong>cutter</strong> - it cuts shapes half from <strong>top to bottom</strong> regardless of its orientation!<br><br>Be sure to get rid of the waste, or otherwise <strong>it will stall</strong> - For this purpose I gave you a trash, which destroys everything you put into it!
title: Taglio forme
desc: Hai appena sbloccato la <strong>tagliatrice</strong> - taglia le forme <strong>verticalmente</strong> indipendentemente da come è orientata!<br><br>Elimina gli scarti, o altrimenti <strong>si bloccherà</strong> - A questo scopo ti ho dato un cestino, che distrugge qualsiasi cosa tu metta dentro!
reward_rotater:
title: Rotating
desc: The <strong>rotater</strong> has been unlocked! It rotates shapes clockwise by 90 degrees.
title: Rotazione
desc: La <strong>ruotatrice</strong> è stata sbloccata! Ruota le forme di 90 gradi in senso orario.
reward_painter:
title: Painting
title: Verniciatura
desc: >-
The <strong>painter</strong> has been unlocked - Extract some color veins (just as you do with shapes) and combine it with a shape in the painter to color them!<br><br>PS: If you are colorblind, there is a <strong>color blind mode</strong> in the settings!
La <strong>verniciatrice</strong> è stata sbloccata - Estrai dalle vene colorate (esattamente come fai con le forme) e combina il colore con una forma nella veniciatrice per colorarla!<br><br>PS: Se sei daltonico, c'è la <strong>modalità daltonici </strong> nelle opzioni!
reward_mixer:
title: Color Mixing
desc: The <strong>mixer</strong> has been unlocked - Combine two colors using <strong>additive blending</strong> with this building!
title: Mix colori
desc: Il <strong>mixer</strong> è stato sbloccato - Con questo edificio, puoi combinare due colori mediante <strong>sintesi additiva</strong>!
reward_stacker:
title: Combiner
desc: You can now combine shapes with the <strong>combiner</strong>! Both inputs are combined, and if they can be put next to each other, they will be <strong>fused</strong>. If not, the right input is <strong>stacked on top</strong> of the left input!
rreward_stacker:
title: Impilatrice
desc: >-
Ora puoi unire forme con l'<strong>impilatrice</strong>! Le forme in ingresso vengono combinate: se possono essere poste l'una accanto all'altra verranno <strong>fuse</strong>, altrimenti le forme dall'ingresso destro vengono <strong>impilate sopra</strong> quelle dal sinistro!
reward_splitter:
title: Splitter/Merger
desc: The multifunctional <strong>balancer</strong> has been unlocked - It can be used to build bigger factories by <strong>splitting and merging items</strong> onto multiple belts!<br><br>
title: Separatore/Agrregatore
desc: Il <strong>bilanciatore</strong> multifunzione è stato sbloccato - Può essere usato per costruire fabbriche più grandi <strong>unendo o dividendo gli oggetti</strong> tra diversi nastri!<br><br>
reward_tunnel:
title: Tunnel
desc: The <strong>tunnel</strong> has been unlocked - You can now pipe items through belts and buildings with it!
desc: Il <strong>tunnel</strong> è stato sbloccato - In questo modo puoi trasportare oggetti al di sotto di nastri ed edifici!
reward_rotater_ccw:
title: CCW Rotating
desc: You have unlocked a variant of the <strong>rotater</strong> - It allows to rotate counter clockwise! To build it, select the rotater and <strong>press 'T' to cycle its variants</strong>!
title: Rotazione antioraria
desc: Hai sbloccato una variante della <strong>ruotatrice</strong> - Consente di ruotare in senso antiorario! Per costruirla, seleziona la ruotatrice e <strong>premi 'T' per cambiare variante</strong>!
reward_miner_chainable:
title: Chaining Extractor
desc: You have unlocked the <strong>chaining extractor</strong>! It can <strong>forward its resources</strong> to other extractors so you can more efficiently extract resources!
title: Estrattore a catena
desc: Hai sbloccato l'<strong>estrattore a catena</strong>! Può <strong>trasferire le sue risorse</strong> ad altri estrattori, così puoi estrarre risorse in modo più efficiente!
reward_underground_belt_tier_2:
title: Tunnel Tier II
desc: You have unlocked a new variant of the <strong>tunnel</strong> - It has a <strong>bigger range</strong>, and you can also mix-n-match those tunnels now!
title: Tunnel grado II
desc: Hai sbloccato una nuova variante del <strong>tunnel</strong> - Ha un <strong>raggio più ampio</strong> e puoi anche mischiare le due varianti ora!
reward_splitter_compact:
title: Compact Balancer
title: Bilanciatore compatto
desc: >-
You have unlocked a compact variant of the <strong>balancer</strong> - It accepts two inputs and merges them into one!
Hai sbloccato una variante compatta del <strong>bilanciatore</strong> - Accetta due ingressi e li unisce!
reward_cutter_quad:
title: Quad Cutting
desc: You have unlocked a variant of the <strong>cutter</strong> - It allows you to cut shapes in <strong>four parts</strong> instead of just two!
title: Taglio quadruplo
desc: Hai sbloccato una variante della <strong>tagliatrice</strong> - Cconsente di tagliare le forme in <strong>quattro parti</strong> invece che in due!
reward_painter_double:
title: Double Painting
desc: You have unlocked a variant of the <strong>painter</strong> - It works as the regular painter but processes <strong>two shapes at once</strong> consuming just one color instead of two!
title: Verniciatura doppia
desc: Hai sbloccato una variante della <strong>verniciatrice</strong> - Funziona come una normale verniciatrice, ma processa <strong>due forme alla volta</strong> consumando solo un'unità di colore invece che due!
reward_painter_quad:
title: Quad Painting
desc: You have unlocked a variant of the <strong>painter</strong> - It allows to paint each part of the shape individually!
title: Verniciatrice
desc: Hai sbloccato una variante della <strong>verniciatrice</strong> - Consente di verniciare ogni parte della forma indipendentemente!
reward_storage:
title: Storage Buffer
desc: You have unlocked a variant of the <strong>trash</strong> - It allows to store items up to a given capacity!
title: Unità di stoccaggio
desc: Hai sbloccato una variante del <strong>cestino</strong> - Consente di immagazzinare oggetti fino ad una certa capacità!
reward_freeplay:
title: Freeplay
desc: You did it! You unlocked the <strong>free-play mode</strong>! This means that shapes are now randomly generated! (No worries, more content is planned for the standalone!)
title: Modalità libera
desc: Ce l'hai fatta! Hai sbloccato la <strong>modalità libera</strong>! Questo significa che adesso le forme sono generate casualmente! (Non preoccuparti, altri contenuti sono in programma per la versione completa!)
reward_blueprints:
title: Blueprints
desc: You can now <strong>copy and paste</strong> parts of your factory! Select an area (Hold CTRL, then drag with your mouse), and press 'C' to copy it.<br><br>Pasting it is <strong>not free</strong>, you need to produce <strong>blueprint shapes</strong> to afford it! (Those you just delivered).
title: Progetti
desc: Ora puoi <strong>copiare ed incollare</strong> parti della tua fabbrica! Seleziona un'area (Tieni premuto CTRL e trascina con il mouse) e premi 'C' per copiarla.<br><br>Incollarla <strong>non è gratis</strong>, devi produrre <strong>forme progetto</strong> per potertelo permettere! (Quelle che hai appena consegnato).
# Special reward, which is shown when there is no reward actually
no_reward:
title: Next level
title: Prossimo livello
desc: >-
This level gave you no reward, but the next one will! <br><br> PS: Better don't destroy your existing factory - You need <strong>all</strong> those shapes later again to <strong>unlock upgrades</strong>!
Questo livello non ti ha dato alcuna ricompensa, ma il prossimo lo farà! <br><br> PS: Meglio non distruggere la fabbrica che hai costruito - Successivamente avrai bisogno di <strong>tutte</strong> quelle forme per <strong>sbloccare i miglioramenti</strong>!
no_reward_freeplay:
title: Next level
title: Prossimo livello
desc: >-
Congratulations! By the way, more content is planned for the standalone!
Congratulazioni! Ci sono altri contenuti in prgramma per la versione completa!
settings:
title: Impostazioni
categories:
general: General
userInterface: User Interface
advanced: Advanced
general: Generali
userInterface: Interfaccia utente
advanced: Avanzate
versionBadges:
dev: Sviluppo
staging: Staging
prod: Produzione
buildDate: Built <at-date>
buildDate: Build del <at-date>
labels:
uiScale:
title: Interface scale
title: Dimensione interfaccia
description: >-
Changes the size of the user interface. The interface will still scale based on your device resolution, but this setting controls the amount of scale.
Cambia la dimensione dell'interfaccia utente. L'interfaccia continuerà a cambiare in base alla risoluzione del tuo dispositivo, ma questa impostazione controlla la proporzione.
scales:
super_small: Super small
small: Small
regular: Regular
large: Large
huge: Huge
super_small: Minuscola
small: Piccola
regular: Normale
large: Grande
huge: Enorme
scrollWheelSensitivity:
title: Zoom sensitivity
title: Sensibilità zoom
description: >-
Changes how sensitive the zoom is (Either mouse wheel or trackpad).
Determina quanto è sensibile lo zoom (Sia rotella del mouse che trackpad).
sensitivity:
super_slow: Super slow
slow: Slow
regular: Regular
fast: Fast
super_fast: Super fast
super_slow: Molto lento
slow: Lento
regular: Regolare
fast: Veloce
super_fast: Molto veloce
language:
title: Lingua
@ -674,9 +678,9 @@ settings:
Cambia la lingua. Tutte le traduzioni sono realizzate dagli utenti e potrebbero essere incomplete!
fullscreen:
title: Fullscreen
title: Schermo intero
description: >-
It is recommended to play the game in fullscreen to get the best experience. Only available in the standalone.
È consigliabile giocare a schermo intero per la migliore esperienza. Disponibile solo nella versione completa.
soundsMuted:
title: Silenzia Suoni
@ -698,23 +702,23 @@ settings:
light: Chiaro
refreshRate:
title: Simulation Target
title: Obiettivo della simulazione
description: >-
If you have a 144hz monitor, change the refresh rate here so the game will properly simulate at higher refresh rates. This might actually decrease the FPS if your computer is too slow.
Se hai un monitor a 144Hz, cambia la frequenza di aggiornamento, in modo tale che il gioco possa correttamente simulare alla frequenza di aggiornamento più alta. Questo potrebbe abbasare i frame al secondo se il tuo computer è troppo lento.
alwaysMultiplace:
title: Multiplace
title: Posizionamento multiplo
description: >-
If enabled, all buildings will stay selected after placement until you cancel it. This is equivalent to holding SHIFT permanently.
Se abilitato, tutti gli edifici rimarranno selezionati dopo il posizionamento finchè non lo annullerai. È equivalente a tenere costantemente premuto MAIUSC.
offerHints:
title: Hints & Tutorials
title: Indizi e tutorial
description: >-
Whether to offer hints and tutorials while playing. Also hides certain UI elements onto a given level to make it easier to get into the game.
Determina se saranno presenti indizi e tutorial durante il gioco. Inoltre, nasconde alcuni elementi dell'interfaccia in certi livelli per semplificare le prime fasi di gioco.
movementSpeed:
title: Movement speed
description: Changes how fast the view moves when using the keyboard.
title: Velocità di movimento
description: Determina la velocità di spostamento sulla mappa quando si usa la tastiera.
speeds:
super_slow: Molto lento
slow: Lento
@ -723,79 +727,75 @@ settings:
super_fast: Molto veloce
extremely_fast: Velocissimo
enableTunnelSmartplace:
title: Smart Tunnels
title: Tunnel intelligenti
description: >-
When enabled, placing tunnels will automatically remove unnecessary belts.
This also enables to drag tunnels and excess tunnels will get removed.
Se abilitato, piazzare un tunnel rimuoverà anche qualsiasi nastro superfluo.
Consente anche di trascinare i tunnel: i tunnel in eccesso verrano rimossi.
vignette:
title: Vignetta
title: Vignettatura
description: >-
Enables the vignette which darkens the screen corners and makes text easier
to read.
Abilita la vignettatura che scurisce gli angoli dello schermo e rende i testi più leggibili.
autosaveInterval:
title: Autosave Interval
title: Intervallo salvataggio automatico
description: >-
Controls how often the game saves automatically. You can also disable it
entirely here.
Determina ogni quanto il gioco salva automaticamente.
Qui puoi anche disabilitarlo completamente.
intervals:
one_minute: 1 Minute
two_minutes: 2 Minutes
five_minutes: 5 Minutes
ten_minutes: 10 Minutes
twenty_minutes: 20 Minutes
disabled: Disabled
one_minute: 1 Minuto
two_minutes: 2 Minuti
five_minutes: 5 Minuti
ten_minutes: 10 Minuti
twenty_minutes: 20 Minuti
disabled: Disabilitato
compactBuildingInfo:
title: Compact Building Infos
title: Info edifici compatte
description: >-
Shortens info boxes for buildings by only showing their ratios. Otherwise a
description and image is shown.
Accorcia le informazioni sugli edifici mostrandone solo la velocità. In caso contrario saranno mostrate immagine e descrizione.
disableCutDeleteWarnings:
title: Disable Cut/Delete Warnings
title: Disabilita avvertimenti taglia/cancella
description: >-
Disable the warning dialogs brought up when cutting/deleting more than 100
entities.
Disabilita i messaggi d'avvertimento quando tagli o cancelli più di 100 entità.
enableColorBlindHelper:
title: Color Blind Mode
description: Enables various tools which allow to play the game if you are color blind.
title: Modalità daltonici
description: Abilita vari strumenti che ti consentono di giocare se sei daltonico.
rotationByBuilding:
title: Rotation by building type
title: Rotazione per tipo di edificio
description: >-
Each building type remembers the rotation you last set it to individually.
This may be more comfortable if you frequently switch between placing
different building types.
Ogni tipo di edificio ricorderà l'ultimo orientamento che hai selezionato indipendentemente dagli altri tipi.
È utile se cambi spesso tipo di edificio.
keybindings:
title: Keybindings
title: Comandi
hint: >-
Tip: Be sure to make use of CTRL, SHIFT and ALT! They enable different placement options.
Suggerimento: Usa spesso CTRL, MAIUSC e ALT! Abilitano opzioni di posizionamento alternative.
resetKeybindings: Reset Keyinbindings
resetKeybindings: Reimposta comandi
categoryLabels:
general: Applicazione
general: Generale
ingame: Gioco
navigation: Navigazione
placement: Posizionamento
massSelect: Mass Select
buildings: Building Shortcuts
placementModifiers: Placement Modifiers
massSelect: Selezione di massa
buildings: Scorciatoie edifici
placementModifiers: Modificatori piazzamento
mappings:
confirm: Conferma
back: Indietro
mapMoveUp: Move Up
mapMoveRight: Move Right
mapMoveDown: Move Down
mapMoveLeft: Move Left
mapMoveUp: Spostati sù
mapMoveRight: Spostati a destra
mapMoveDown: Spostati giù
mapMoveLeft: Spostati a sinistra
centerMap: Centra mappa
mapZoomIn: Zoom in
mapZoomOut: Zoom out
createMarker: Create Marker
mapZoomIn: Aumenta zoom
mapZoomOut: Riduci zoom
createMarker: Crea segnapunto
menuOpenShop: Upgrade
menuOpenShop: Miglioramenti
menuOpenStats: Statistiche
toggleHud: Mostra/Nascondi HUD
@ -813,50 +813,48 @@ keybindings:
rotateWhilePlacing: Ruota
rotateInverseModifier: >-
Modifier: Rotate CCW instead
Modificatore: Ruota in senso antiorario
cycleBuildingVariants: Cicla varianti
confirmMassDelete: Conferma eliminazione di massa
cycleBuildings: Cycle Buildings
cycleBuildings: Cicla edifici
massSelectStart: Hold and drag to start
massSelectStart: Clicca e trascina per cominciare
massSelectSelectMultiple: Seleziona aree multiple
massSelectCopy: Copia area
placementDisableAutoOrientation: Disable automatic orientation
placeMultiple: Stay in placement mode
placeInverse: Invert automatic belt orientation
pasteLastBlueprint: Paste last blueprint
massSelectCut: Cut area
exportScreenshot: Export whole Base as Image
mapMoveFaster: Move Faster
lockBeltDirection: Enable belt planner
switchDirectionLockSide: "Planner: Switch side"
pipette: Pipette
menuClose: Close Menu
switchLayers: Switch layers
advanced_processor: Color Inverter
energy_generator: Energy Generator
wire: Energy Wire
placementDisableAutoOrientation: Disabilita orientamento automatico
placeMultiple: Rimani in modalità posizionamento
placeInverse: Inverti direzione automatica nastri
pasteLastBlueprint: Incolla l'ultimo progetto
massSelectCut: Taglia area
exportScreenshot: Esporta l'intera base come immagine
mapMoveFaster: Muoviti più rapidamente
lockBeltDirection: Abilita pianificatore nastri
switchDirectionLockSide: "Pianificatore: cambia direzione"
pipette: Contagocce
menuClose: Chiudi menù
switchLayers: Cambia livello
advanced_processor: Inversore di colore
energy_generator: Generatore di energia
wire: Cavo energetico
about:
title: Riguardo questo gioco
body: >-
This game is open source and developed by <a href="https://github.com/tobspr"
target="_blank">Tobias Springer</a> (this is me).<br><br>
Questo gioco è open source e sviluppato da <a href="https://github.com/tobspr"
target="_blank">Tobias Springer</a> (me).<br><br>
If you want to contribute, check out <a href="<githublink>"
target="_blank">shapez.io on github</a>.<br><br>
Se vuoi contribuire visita la pagina github di <a href="<githublink>"
target="_blank">shapez.io</a>.<br><br>
This game wouldn't have been possible without the great Discord community
around my games - You should really join the <a href="<discordlink>"
target="_blank">Discord server</a>!<br><br>
Realizzare questo gioco non sarebbe stato possibile senza la grande community di Discord per i miei giochi - Unisciti al <a href="<discordlink>"
target="_blank">server di Discord</a>!<br><br>
The soundtrack was made by <a href="https://soundcloud.com/pettersumelius"
target="_blank">Peppsen</a> - He's awesome.<br><br>
La colonna sonora è stata composta da<a href="https://soundcloud.com/pettersumelius"
target="_blank">Peppsen</a> - È un grande.<br><br>
Finally, huge thanks to my best friend <a
href="https://github.com/niklas-dahl" target="_blank">Niklas</a> - Without our
factorio sessions this game would never have existed.
Per finire, grazie di cuore al mio migliore amico <a
href="https://github.com/niklas-dahl" target="_blank">Niklas</a> - Senza le nostre sessioni su factorio questo gioco non sarebbe mai esistito.
changelog:
title: Changelog

View File

@ -70,7 +70,7 @@ steamPage:
[b]このゲームはオープンソースです![/b]
誰でもこのげむの開発を手伝うことができ、私もプレーヤーの意見をできるだけゲームに取り入れようとしています。
誰でもこのゲームの開発を手伝うことができ、私もプレーヤーの意見をできるだけゲームに取り入れようとしています。
Trelloで今後の予定が全て確認できます。
[b]外部リンク[/b]

View File

@ -213,12 +213,12 @@ dialogs:
desc: 모든 키바인딩이 기본값으로 재설정 되었습니다!
featureRestriction:
title: 데모 버전
desc: 데모 버전에는 없는 콘텐츠(<feature>)로 시도했습니다. 유료 버전을 구입해서 모든 콘텐츠를 사용해보세요!
title: 체험판 버전
desc: 체험판 버전에는 없는 콘텐츠(<feature>)로 시도했습니다. 유료 버전을 구입해서 모든 콘텐츠를 사용해보세요!
oneSavegameLimit:
title: 저장파일 개수 제한
desc: 데모 버전에서는 저장 파일을 한 번에 한 개만 사용할 수 있습니다. 이미 있는 저장 파일을 지우거나 유료 버전을 구입 해주새요.
desc: 체험판 버전에서는 저장 파일을 한 번에 한 개만 사용할 수 있습니다. 이미 있는 저장 파일을 지우거나 유료 버전을 구입 해주새요.
updateSummary:
title: 신규 버전!
@ -261,7 +261,7 @@ dialogs:
titleEdit: 마커 변경
markerDemoLimit:
desc: 데모 버전에서는 마커를 2개 까지만 놓을 수 있습니다. 유료 버전을 구입하면 마커를 무제한으로 놓을 수 있습니다!
desc: 체험판 버전에서는 마커를 2개 까지만 놓을 수 있습니다. 유료 버전을 구입하면 마커를 무제한으로 놓을 수 있습니다!
exportScreenshotWarning:
title: 스크린샷 내보내기
@ -460,7 +460,7 @@ buildings:
tier2:
name: 터널 티어 II
description: 도형을 건물과 벨트 밑으로 통과시킴.
description: 도형을 건물과 벨트 밑으로 터널 보다 빨리 통과시킴.
splitter: # Internal name for the Balancer
default:
@ -543,10 +543,10 @@ buildings:
wire_crossings:
default:
name: 전선 분배기
description: Splits a energy wire into two.
description: 에너지 와이어를 두 개로 분할합니다.
merger:
name: 전선 병합기
description: Merges two energy wires into one.
description: 두 개의 에너지 와이어를 하나로 병합합니다.
storyRewards:
# Those are the rewards gained from completing the store
@ -634,9 +634,9 @@ storyRewards:
settings:
title: 설정
categories:
general: General
userInterface: User Interface
advanced: Advanced
general: 일반
userInterface: 유저 인터페이스
advanced: 고급
versionBadges:
dev: 개발
@ -654,7 +654,7 @@ settings:
small: 작게
regular: 보통
large: 크게
huge: 거대하
huge: 매우 크
scrollWheelSensitivity:
title: 확대 민감도
@ -682,7 +682,7 @@ settings:
language:
title: 언어
description: >-
언어 바꾸기 - 모든 언어팩은 사용자들이 만든 것이므로 완성되지 않았을 수 있습니다!
언어 바꾸기 - 모든 언어팩은 사용자들이 만든 것이므로 정확하지 않을 수 있습니다!
fullscreen:
title: 전체화면
@ -745,7 +745,7 @@ settings:
twenty_minutes: 20분
disabled: 기능 끄기
compactBuildingInfo:
title: 한 건물 정보
title: 한 건물 정보
description: >-
건물의 정보창을 해당 건물의 능률만 보이도록 줄입니다.
아니면, 설명과 이미지가 보입니다.
@ -862,7 +862,7 @@ demo:
restoringGames: 게임 자장 파일 리스토어 하기
importingGames: 게임 저장 파일 불러오기
oneGameLimit: 게임 저장 파일 최대 1개
customizeKeybindings: 바인딩 설정하기
customizeKeybindings: 설정하기
exportingBase: 공장 전체를 이미지로 내보내기
settingNotAvailable: 데모 버전에서 사용 불가
settingNotAvailable: 체험판 버전에서 사용 불가

View File

@ -56,10 +56,10 @@ steamPage:
[b]Fremtidige Oppdateringer[/b]
Jeg oppdaterer spillet veldig ofte og prøver å presse inn en oppdatering i det minste hver uke!
Jeg oppdaterer spillet veldig ofte og prøver å presse inn minst en oppdatering hver uke!
[list]
[*] Forskjellige baner og utfordringer (f.eks. baner med hindringer)
[*] Forskjellige nivåer og utfordringer (f.eks. nivåer med hindringer)
[*] Gåter (lever den forspurte formen med et begrenset område / sett med bygninger)
[*] En historiemodus der bygninger har en pris
[*] Konfigurerbar kartgenerator (Konfigurer ressurser/former, størrelse/tetthet, seed og mer)
@ -142,12 +142,12 @@ mainMenu:
changelog: Endringshistorikk
importSavegame: Importer
openSourceHint: Dette spillet er åpen kildekode!
discordLink: Offisiel Discord Server
discordLink: Offisiel Discord-Server
helpTranslate: Hjelp oversetting!
# This is shown when using firefox and other browsers which are not supported.
browserWarning: >-
Beklager, men spillet er kjent for å kjøre sakte på din nettleser! Skaff deg frittstående versjon, eller last ned Chrome for den fulle opplevelsen.
Beklager, men spillet er kjent for å kjøre sakte i din nettleser! Skaff deg den frittstående versjonen, eller last ned Chrome for den fulle opplevelsen.
savegameLevel: Nivå <x>
savegameLevelUnknown: Ukjent Nivå
@ -172,14 +172,14 @@ dialogs:
showKeybindings: Se Hurtigtaster
importSavegameError:
title: Importerings feil
title: Importeringsfeil
text: >-
Kunne ikke importere lagringsfilen:
importSavegameSuccess:
title: Lagringsfil importert
text: >-
Din Lagringsfil ble vellykket importert.
Din Lagringsfil ble importert.
gameLoadFailure:
title: Lagringsfilen er ødelagt
@ -206,20 +206,20 @@ dialogs:
desc: Trykk på knappen eller museknappen du vil tildele, eller escape for å avbryte.
resetKeybindingsConfirmation:
title: Nullstill Hurtigtaster
desc: Dette vil nullstille alle hurtigtaster tilbake til standard. Vennligst bekreft.
title: Tilbakestill Hurtigtaster
desc: Dette vil tilbakestille alle hurtigtaster. Er du sikker?.
keybindingsResetOk:
title: Hurtigtaster nullstilt
desc: Hurtigtastene har blitt nullstilt tilbake til standard!
title: Hurtigtaster tilbakestillt
desc: Hurtigtastene har blitt tilbakestillt til standard!
featureRestriction:
title: Demo Versjon
desc: Du prøvde å benytte deg av en funksjon (<feature>) som ikke er tilgjengelig i demoen. Vurder å skaffe frittstående versjon for den fulle opplevelsen!
title: Demoversjon
desc: Du prøvde å benytte deg av en funksjon (<feature>) som ikke er tilgjengelig i demoen. Vurder å skaffe den frittstående versjonen for den fulle opplevelsen!
oneSavegameLimit:
title: Begrenset Lagringsfiler
desc: Du kan du ha en lagringsfil om gangen i demo versjonen. Vennligst slett den eksisterende, eller skaff frittstående versjon!
title: Begrenset antall Lagringsfiler
desc: Du kan du ha en lagringsfil om gangen i demoversjonen. Vennligst slett den eksisterende, eller skaff den frittstående versjonen!
updateSummary:
title: Ny oppdatering!!
@ -238,7 +238,7 @@ dialogs:
Du skal til å slette mange bygninger (<count> for å være nøyaktig)! Er du sikker på at du ønsker å gjøre dette?
massCutConfirm:
title: Bekreft Klipping
title: Bekreft Utlipping
desc: >-
Du klipper ut mange bygninger (<count> for å være nøyaktig)! Er du sikker på at du ønsker å gjøre dette?
@ -253,23 +253,23 @@ dialogs:
Spillet har mange hurtigtaster som gjør det enklere å bygge store fabrikker.
Her er noen få, men sørg for å <strong>sjekke ut hurtigtaster</strong>!<br><br>
<code class='keybinding'>CTRL</code> + Dra: Velg et område.<br>
<code class='keybinding'>SHIFT</code>: Hold trykket for å plassere flere av en bygning.<br>
<code class='keybinding'>ALT</code>: Inverter orientasjon av plasserte belter.<br>
<code class='keybinding'>SHIFT</code>: Hold inne for å plassere flere av en bygning.<br>
<code class='keybinding'>ALT</code>: Inverter rettning på plasserte samlebånd.<br>
createMarker:
title: Ny Markør
desc: Gi markøren et meningsfullt navn, du kan også inkludere <strong>"short key"</strong> av et objekt (Som du kan generere <a href="https://viewer.shapez.io" target="_blank">her</a>)
titleEdit: Edit Marker
desc: Gi markøren et meningsfullt navn, du kan også inkludere en <strong>"short key"</strong> av et objekt (Som du kan generere <a href="https://viewer.shapez.io" target="_blank">her</a>)
titleEdit: Rediger markør
markerDemoLimit:
desc: Du kan kun ha to markører i demo verjsonen. Skaff deg frittstående versjon for ubegrensede markører!
desc: Du kan kun ha to markører i demoverjsonen. Skaff deg den frittstående versjonen for ubegrensede markører!
exportScreenshotWarning:
title: Eksporter skjermbilde
desc: Du forespurte å eksportere bilde av basen din som et skjermbilde. Vær obs på at dette kan ta lang tid for en stor base, og i verste fall kræsje spillet ditt (Husk å lagre først)!
massCutInsufficientConfirm:
title: Confirm cut
desc: You can not afford to paste this area! Are you sure you want to cut it?
title: Bekreft Utklipping
desc: Du har ikke råd til å lime inn dette området! er du sikker på at du vil klippe det ut?
ingame:
# This is shown in the top left corner and displays useful keybindings in
@ -293,7 +293,7 @@ ingame:
copySelection: Kopier
clearSelection: Fjern Valgte
pipette: Pipette
switchLayers: Switch layers
switchLayers: Bytt lag
# Everything related to placing buildings (I.e. as soon as you selected a building
# from the toolbar)
@ -365,7 +365,7 @@ ingame:
playtime: Spilletid
buildingsPlaced: Bygninger
beltsPlaced: Belter
beltsPlaced: Samlebånd
buttons:
continue: Fortsett
@ -393,7 +393,7 @@ ingame:
interactiveTutorial:
title: Opplæring
hints:
1_1_extractor: Plasser en <strong>utdrager</strong> på toppen av en <strong>sirkel form</strong> for å samle den!
1_1_extractor: Plasser en <strong>utdrager</strong> på toppen av en <strong>sirkelform</strong> for å samle den!
1_2_conveyor: >-
Koble utdrageren med et <strong>transportbånd</strong> til hovedbygningen!<br><br>Tips: <strong>Trykk og dra</strong> beltet med musa!
@ -409,7 +409,7 @@ ingame:
cyan: Cyan
white: Hvit
uncolored: Ingen farge
black: Black
black: Svart
shapeViewer:
title: Lag
empty: Tom
@ -418,7 +418,7 @@ ingame:
# All shop upgrades
shopUpgrades:
belt:
name: Belter, Distributører & Tuneller
name: Belter, Distributører & Tunneler
description: Hastighet x<currentMult> → x<newMult>
miner:
name: Utdrager
@ -439,7 +439,7 @@ buildings:
belt:
default:
name: &belt Transportbånd
name: &belt Samlebånd
description: Transporterer objekter, hold og dra for å plassere flere.
miner: # Internal name for the Extractor
@ -453,7 +453,7 @@ buildings:
underground_belt: # Internal name for the Tunnel
default:
name: &underground_belt Tunell
name: &underground_belt Tunnel
description: Lar deg bruke tuneller for å transportere objekter under bygninger og belter.
tier2:
@ -476,26 +476,26 @@ buildings:
cutter:
default:
name: &cutter Kutter
description: Kutter objekter fra top til bunn og spytter ut begge halvdeler. <strong>Hvis du bare skal bruke den ene biten, sørg for å ødelegge den andre biten ellers vil det låse seg!</strong>
description: Kutter objekter fra top til bunn og spytter ut begge halvdeler. <strong>Hvis du bare skal bruke den ene biten, sørg for å ødelegge den andre biten ellers vil det stoppe opp!</strong>
quad:
name: Kutter (4-Veis)
description: Kutter objekter til 4 biter. <strong>Hvis du bare skal bruke den ene biten, sørg for å ødelegge den andre biten ellers vil det låse seg!</strong>
description: Kutter objekter til 4 biter. <strong>Hvis du bare skal bruke den ene biten, sørg for å ødelegge den andre biten ellers vil det stoppe opp!</strong>
rotater:
default:
name: &rotater Roter
description: Roter objekter med klokken, 90 grader.
description: Roter former med klokken, 90 grader.
ccw:
name: Roter (Mot klokken)
description: Roter objekter mot klokken, 90 grader.
description: Roter former mot klokken, 90 grader.
fl:
name: Rotate (180)
description: Rotates shapes by 180 degrees.
description: Roterer former 180 grader.
stacker:
default:
name: &stacker Stabler
description: Stabler begge objekter. Hvis de ikke kan bli stablet sidelengs, vil høyre stables over den andre.
description: Stabler begge formene. Hvis de ikke kan bli stablet sidelengs, vil høyre stables over den andre.
mixer:
default:
@ -505,13 +505,13 @@ buildings:
painter:
default:
name: &painter Maler
description: &painter_desc Maler hele objektet på venstre inngang med fargen fra øverste inngang.
description: &painter_desc Maler hele formen på venstre inngang med fargen fra øverste inngang.
double:
name: Maler (Dobbel)
description: Maler hele objektet på venstre inngang med fargen fra øverste inngang.
description: Maler hele formen på venstre inngang med fargen fra øverste inngang.
quad:
name: Maler (Fireganger)
description: Farger enhver kvadrant av objektet med forskjellige farger.
name: Maler (Firedobbel)
description: Farger hvert hjørne av formen med forskjellige farger.
mirrored:
name: *painter
description: *painter_desc
@ -519,38 +519,38 @@ buildings:
trash:
default:
name: &trash Søppelkasse
description: Tar imot objekter fra alle sider og ødelegger de. For alltid.
description: Tar imot former og farger fra alle sider og ødelegger de. For alltid.
storage:
name: Lagringsboks
description: Lagrer overflødige objekter, opp til en viss kapasitet. Kan bli brukt som mellomlagring for overflyt.
description: Lagrer overflødige former og farger, opp til en viss kapasitet. Kan bli brukt som mellomlagring for overflyt.
wire:
default:
name: Energy Wire
description: Allows you to transport energy.
name: Energikabel
description: Lar deg transportere energi.
advanced_processor:
default:
name: Color Inverter
description: Accepts a color or shape and inverts it.
name: Fargeinverterer
description: Tar imot en farge eller form og inverterer den.
energy_generator:
deliver: Deliver
deliver: Lever
toGenerateEnergy: For
default:
name: Energy Generator
description: Generates energy by consuming shapes.
name: Energigenerator
description: Genererer energi ved å ta imot former.
wire_crossings:
default:
name: Wire Splitter
description: Splits a energy wire into two.
name: Kabeldeler
description: Deler en energikabel i to.
merger:
name: Wire Merger
description: Merges two energy wires into one.
name: Kabelsammenslåer
description: Slår sammen to energikabler til en.
storyRewards:
# Those are the rewards gained from completing the store
reward_cutter_and_trash:
title: Kutt Objekter
desc: Du åpnet nettop <strong>kutter</strong> - den kutter objekter i to fra <strong>topp til bunn</strong> uavhengig av rotasjon!<br><br>Husk å kvitt deg med alt søppel, ellers <strong>kiler det seg fast</strong> - For dette formålet har du søplekassen, som ødelegger alt du putter i den!
desc: Du åpnet nettop <strong>kutter</strong> - den kutter former i to fra <strong>topp til bunn</strong> uavhengig av rotasjon!<br><br>Husk å kvitt deg med alt søppel, ellers <strong>kiler det seg fast</strong> - Derfor har jeg gitt deg søplekassen, som ødelegger alt du putter i den!
reward_rotater:
title: Rotering
@ -559,7 +559,7 @@ storyRewards:
reward_painter:
title: Maling
desc: >-
<strong>Maleren</strong> har blitt tilgjengelig - Hent ut fargeressurser (på samme måte som du gjør med objekter) og kombiner det med et objekt i maleren for å male de!<br><br>PS: Hvis du er fargeblind, så er det en <strong>modus for fargeblinde</strong> i instillinger!
<strong>Maleren</strong> har blitt tilgjengelig - Hent ut fargeressurser (på samme måte som du gjør med objekter) og kombiner det med et objekt i maleren for å male de!<br><br>PS: Hvis du er fargeblind, så er det en <strong>modus for fargeblinde</strong> i instillingene!
reward_mixer:
title: Fargemikser
@ -571,23 +571,23 @@ storyRewards:
reward_splitter:
title: Fordeler/Sammenslåer
desc: Den multifunksjonelle <strong>fordeleren</strong> har blitt tilgjengelig - Den kan brukes til å bygge større fabrikker ved å <strong>fordele og slå sammen objekter</strong> til flere transportbånd!<br><br>
desc: Den multifunksjonelle <strong>fordeleren</strong> har blitt tilgjengelig - Den kan brukes til å bygge større fabrikker ved å <strong>fordele og slå sammen objekter</strong> til flere samlebånd!<br><br>
reward_tunnel:
title: Tunell
desc: <strong>Tunellen</strong> har blitt tilgjengelig - Du kan nå transportere objekter under transportbelter og bygninger med den!
title: Tunnel
desc: <strong>Tunnelen</strong> har blitt tilgjengelig - Du kan nå transportere objekter under samlebånd og bygninger med den!
reward_rotater_ccw:
title: Mot klokken rotering
title: Rotering mot klokken
desc: Du har åpnte en variant av <strong>rotereren</strong> - Den tillater rotasjoner mot klokken! For å bygge den, velg rotereren og <strong>trykk 'T' for å veksle mellom variantene</strong>!
reward_miner_chainable:
title: Kjede Utdrager
desc: Du har åpnet <strong>kjede utdrageren</strong>! Den sender <strong>videre sine resurser</strong> til andre utdragere så de kan mer effektivt hente ut resurser!
title: Kjedeutdrager
desc: Du har åpnet <strong>kjedeutdrageren</strong>! Den sender <strong>sine resurser videre</strong> til andre utdragere så de kan hente ut ressurser mer effektivt!
reward_underground_belt_tier_2:
title: Tunell Nivå II
desc: Du har åpnet en ny variant av <strong>tunellen</strong> - Den har <strong>lengre rekkevidde</strong>, og du kan også blande de forskjellige tunellene nå!
title: Tunnel Nivå II
desc: Du har åpnet en ny variant av <strong>tunnelen</strong> - Den har <strong>lengre rekkevidde</strong>, og du kan også blande de forskjellige tunnelene nå!
reward_splitter_compact:
title: Kompakt Utjevning
@ -600,51 +600,51 @@ storyRewards:
reward_painter_double:
title: Dobbel Maling
desc: Du har åpnet en variant av <strong>maleren</strong> - Den fungerer som vanlig maler, men prosesserer <strong>to objekter om gangen</strong>, konsumerer bare en farge istedenfor to!
desc: Du har åpnet en variant av <strong>maleren</strong> - Den fungerer som vanlig maler, men maler <strong>to objekter om gangen</strong>, konsumerer bare en farge istedenfor to!
reward_painter_quad:
title: Firegangers Maling
title: 4-Veis Maling
desc: Du har åpnet en variant av <strong>maleren</strong> - Den lar deg male hver del av objektet individuelt!
reward_storage:
title: Lagrings Buffer
desc: Du har åpnet en variant av <strong>søplekassen</strong> - Den lar deg lagre objekter opp til en viss mengde!
title: Lagringsbuffer
desc: Du har åpnet en variant av <strong>søpplekassen</strong> - Den lar deg lagre objekter opp til en viss mengde!
reward_freeplay:
title: Frispill
desc: Du klarte det! Du åpnet <strong>frispill modus</strong>! Dette betyr at formene er nå tilfeldig generert! (Frykt ikke, mer innhold er planlagt for frittstående versjon!)
desc: Du klarte det! Du åpnet <strong>frispillmodus</strong>! Dette betyr at formene er nå tilfeldig generert! (Ikke vær redd, mer innhold er planlagt for den frittstående versjonen!)
reward_blueprints:
title: Blåkopier
desc: Du kan nå <strong>kopiere og lime inn</strong> deler av fabrikken din! Velg et område (Hold inne CTRL, så dra med musa), trykk så 'C' for å kopiere det.<br><br>Lime det inn er <strong>ikke gratis</strong>, du må produsere <strong>blåkopi objekter</strong> for å få råd til det! (Det du nettop leverte).
desc: Du kan nå <strong>kopiere og lime inn</strong> deler av fabrikken din! Velg et område (Hold inne CTRL, så dra med musa), trykk så 'C' for å kopiere det.<br><br>Lime det inn er <strong>ikke gratis</strong>, du må produsere <strong>blåkopiobjekter</strong> for å få råd til det! (Det du nettop leverte).
# Special reward, which is shown when there is no reward actually
no_reward:
title: Neste nivå
desc: >-
Dette nivået ga deg ingen belønning, men neste gjør det! <br><br> PS: Burde ikke ødelegge din nåværende fabrikk - Du trenger <strong>alle</strong> de objektene senere for å <strong>åpne nye ting</strong>!
Dette nivået ga deg ingen belønning, men neste gjør det! <br><br> PS: Du burde ikke ødelegge din nåværende fabrikk - Du trenger <strong>alle</strong> de objektene senere for å <strong>åpne nye ting</strong>!
no_reward_freeplay:
title: Neste nivå
desc: >-
Gratulerer!! Forresten, mer innhold er planlagt for frittstående versjon!
Gratulerer!! Forresten, mer innhold er planlagt for den frittstående versjonen!
settings:
title: Instillinger
categories:
general: General
userInterface: User Interface
advanced: Advanced
general: Generelt
userInterface: Brukergrensesnitt
advanced: Avansert
versionBadges:
dev: Utvikling
staging: Icenesettelse
staging: Iscenesettelse
prod: Produksjon
buildDate: Bygget <at-date>
labels:
uiScale:
title: Grensesnitt skala
title: Grensesnittskala
description: >-
Endrer størrelsen på brukergrensesnitt. Grensesnittet vil fortsatt skaleres basert på din enhets oppløsning, men denne instillingen styrer mengden den skalerer.
scales:
@ -655,9 +655,9 @@ settings:
huge: Gigantisk
scrollWheelSensitivity:
title: Forstørrelses sensitivitet
title: Forstørrelsessensitivitet
description: >-
Endrer hvor sensitiv forstørringen er (Enten musehjulet eller trackpad).
Endrer hvor sensitiv forstørringen er (Enten musehjulet eller museplate).
sensitivity:
super_slow: Veldig Sakte
slow: Sakte
@ -670,7 +670,7 @@ settings:
description: >-
Endrer hvor raskt bildet beveger seg når man bruker tastaturet.
speeds:
super_slow: Veldig Sakte slow
super_slow: Veldig Sakte
slow: Sakte
regular: Vanlig
fast: Raskt
@ -690,30 +690,30 @@ settings:
soundsMuted:
title: Skru av lyder
description: >-
Hvis aktivert, skrur av alle lydeffekter.
Skrur av alle lydeffekter.
musicMuted:
title: Skru av Musikk
description: >-
Hvis aktivert, skrur av all musikk.
Skrur av all musikk.
theme:
title: Spilltema
description: >-
Velg spilltema (lys / mørk).
Velg spilltema (lyst / mørk).
themes:
dark: Mørk
light: Lys
light: Lyst
refreshRate:
title: Simulerings Mål
title: Simuleringsmål
description: >-
Hvis du har en 144hz skjerm, endre oppdateringsfrekvensen her så vil spillet simuleres mer korrekt på høyere oppdateringsfrekvenser. Dette kan redusere FPS om din PC er for treg.
alwaysMultiplace:
title: Plasser flere
description: >-
Hvis aktivert, alle bygg vil forbli valgt etter plassering inntil du avbryter det. Dette tilsvarer å holde SHIFT nede permanent.
Hvis aktivert vil alle bygg forbli valgt etter plassering inntil du avbryter det. Dette tilsvarer å holde SHIFT nede permanent.
offerHints:
title: Hint & Opplæring
@ -723,8 +723,8 @@ settings:
enableTunnelSmartplace:
title: Smarte Tuneller
description: >-
Når aktivert, plassering av tuneller vil automatisk fjerne unødvendige bånd.
Dette lar deg også dra og slippe tuneller, og overflødige tuneller blir fjernet.
Når aktivert vil plassering av tunneler automatisk fjerne unødvendige bånd.
Dette lar deg også dra og slippe tunneler, og overflødige tunneler blir fjernet.
vignette:
title: Vignett
description: >-
@ -746,21 +746,21 @@ settings:
compactBuildingInfo:
title: Kompakt Bygningsinformasjon
description: >-
Forkorter informasjonsboksen for bygninger ved å bare vise dems forhold. Ellers
vises en beskrivelse og bilde er vist.
Forkorter informasjonsboksen for bygninger ved å bare vise deres forhold. Ellers
vises en beskrivelse og et bilde.
disableCutDeleteWarnings:
title: Deaktiverer Kutt/Slette Advarsler
title: Deaktiverer Utklipps- og Sletteadvarsler
description: >-
Deaktiverer advarselsdialogen som kommer frem når du kutter/sletter mer enn 100
Deaktiverer advarselsmeldingen som kommer frem når du klipper ut eller sletter mer enn 100
bygninger.
enableColorBlindHelper:
title: Fargeblind Modus
title: Fargeblindmodus
description: Aktiverer forskjellige verktøy som lar deg spille spillet om du er fargeblind.
rotationByBuilding:
title: Roter basert på bygningstype
description: >-
Hver bygning type husker rotasjonen du sist brukte individuelt.
Hver bygningstype husker rotasjonen du sist brukte på dee.
Dette kan være mer komfortabelt hvis du ofte veksler mellom plassering
av forskjellige bygninger.
@ -777,8 +777,8 @@ keybindings:
navigation: Navigering
placement: Plassering
massSelect: Velg Masse
buildings: Bygnings Snarvei
placementModifiers: Plasserings Alternativer
buildings: Bygningssnarvei
placementModifiers: Plasseringsalternativer
mappings:
confirm: Bekreft
@ -798,7 +798,7 @@ keybindings:
menuOpenStats: Statistikk
toggleHud: Veksle Grensesnitt
toggleFPSInfo: Veksle FPS og debug informasjon
toggleFPSInfo: Veksle FPS-og debuginformasjon
exportScreenshot: Eksporter hele basen som et bilde
belt: *belt
splitter: *splitter
@ -822,19 +822,19 @@ keybindings:
massSelectStart: Hold og dra for å starte
massSelectSelectMultiple: Velg flere områder
massSelectCopy: Kopier Område
massSelectCut: Kutt ut Område
massSelectCut: Klipp ut Område
placementDisableAutoOrientation: Deaktiver automatisk orientering
placeMultiple: Forbli i plasseringsmodus
placeInverse: Inverter automatisk transportbånd orientering
lockBeltDirection: Enable belt planner
placeInverse: Inverter automatisk samlebåndsorientering
lockBeltDirection: Aktiver samlebåndplanlegger
switchDirectionLockSide: "Planlegger: Bytt side"
pipette: Pipette
menuClose: Close Menu
switchLayers: Switch layers
advanced_processor: Color Inverter
energy_generator: Energy Generator
wire: Energy Wire
menuClose: Lukk meny
switchLayers: Bytt lag
advanced_processor: Fargeinverterer
energy_generator: Energigenerator
wire: Energikabel
about:
title: Om dette spillet
@ -843,11 +843,11 @@ about:
Hvis du ønsker å bidra, sjekk ut <a href="<githublink>" target="_blank">shapez.io på github</a>.<br><br>
Spillet ville ikke vært mulig uten det fantastidke Discord samfunnet rundt spillet mitt - Du burde virkelig bli med på <a href="<discordlink>" target="_blank">Discord serveren</a>!<br><br>
Spillet ville ikke vært mulig uten det fantastiske Discord-samfunnet rundt spillet mitt - Du burde virkelig bli med på <a href="<discordlink>" target="_blank">Discord-serveren</a>!<br><br>
Lydsporet er laget av <a href="https://soundcloud.com/pettersumelius" target="_blank">Peppsen</a> - Han er rå.<br><br>
Til slutt, stor takk til min beste venn <a href="https://github.com/niklas-dahl" target="_blank">Niklas</a> - Uten våre factorio økter ville ikke dette spillet ha eksistert.
Til slutt, en stor takk til min beste venn <a href="https://github.com/niklas-dahl" target="_blank">Niklas</a> - Uten våre factorio-økter ville ikke dette spillet ha eksistert.
changelog:
title: Endringshistorikk
@ -858,6 +858,6 @@ demo:
importingGames: Importer lagringsfiler
oneGameLimit: Begrenset til en lagringsfil
customizeKeybindings: Forandre Hurtigtaster
exportingBase: Eksporter hele basen som bile
exportingBase: Eksporter hele basen som bilde
settingNotAvailable: Ikke tilgjengelig i demoversjonen.

View File

@ -83,7 +83,7 @@ steamPage:
[*] [url=https://github.com/tobspr/shapez.io/blob/master/translations/README.md]Pomóż w tłumaczeniu[/url]
[/list]
discordLink: Oficjalna Discord - Porozmawiaj ze mną!
discordLink: Oficjalny serwer Discord - Porozmawiaj ze mną!
global:
loading: Ładowanie
@ -274,8 +274,8 @@ dialogs:
Czy na pewno chcesz kontynuować?
massCutInsufficientConfirm:
title: Potwierdź cięcie
desc: Nie możesz sobie pozwolić na wklejenie tego obszaru! Czy na pewno chcesz to wyciąć?
title: Potwierdź wycinanie
desc: Nie posiadasz wystarczająco kształtów schematów na wklejenie tego obszaru! Czy na pewno chcesz go wyciąć?
ingame:
# This is shown in the top left corner and displays useful keybindings in
@ -299,7 +299,7 @@ ingame:
copySelection: Skopiuj
clearSelection: Wyczyść zaznaczenie
pipette: Wybierz obiekt z mapy
switchLayers: Switch layers
switchLayers: Przełącz warstwy
# Names of the colors, used for the color blind mode
colors:
@ -311,7 +311,7 @@ ingame:
cyan: Cyjanowy
white: Biały
uncolored: Brak koloru
black: Black
black: Czarny
# Everything related to placing buildings (I.e. as soon as you selected a building
# from the toolbar)
@ -414,7 +414,7 @@ ingame:
shapeViewer:
title: Poziomy
empty: Puste
copyKey: Copy Key
copyKey: Skopiuj kod
# Interactive tutorial
interactiveTutorial:
@ -539,25 +539,25 @@ buildings:
description: Magazynuje obiekty, do określonego limitu. Może zostać użyty jako bramka przepełnienia.
wire:
default:
name: Energy Wire
description: Allows you to transport energy.
name: Przewód energetyczny
description: Pozwala na transportowanie energii.
advanced_processor:
default:
name: Color Inverter
description: Accepts a color or shape and inverts it.
name: Odwracacz kolorów
description: Przyjmuje barwnik lub kształt i odwraca jego kolory.
energy_generator:
deliver: Deliver
toGenerateEnergy: For
deliver: Dostarcz
toGenerateEnergy: Za
default:
name: Energy Generator
description: Generates energy by consuming shapes.
name: Generator energii
description: Generuje energię poprzez zużywanie kształtów.
wire_crossings:
default:
name: Wire Splitter
description: Splits a energy wire into two.
name: Rozdzielacz przewodów
description: Rozdziela przewód energetyczny na dwa.
merger:
name: Wire Merger
description: Merges two energy wires into one.
name: Łącznik przewodów
description: Łączy dwa przewody energetyczne w jeden.
storyRewards:
# Those are the rewards gained from completing the store
@ -656,9 +656,9 @@ storyRewards:
settings:
title: Ustawienia
categories:
general: General
userInterface: User Interface
advanced: Advanced
general: Ogólne
userInterface: Interfejs
advanced: Zaawansowane
versionBadges:
dev: Wersja Rozwojowa
@ -780,7 +780,7 @@ settings:
100 budynków.
enableColorBlindHelper:
title: Tryb ślepy na kolory
title: Tryb dla daltonistów
description: Włącza różne narzędzia, które pozwalają ci grać, jeśli jesteś daltonistą.
rotationByBuilding:
title: Obrót według typu budynku
@ -823,6 +823,7 @@ keybindings:
toggleHud: Przełącz widoczność interfejsu
toggleFPSInfo: Pokaż Licznik FPS i informacje do debugowania
belt: *belt
splitter: *splitter
underground_belt: *underground_belt
@ -847,7 +848,7 @@ keybindings:
placementDisableAutoOrientation: Wyłącz automatyczną orientację
placeMultiple: Pozostań w trybie stawiania
placeInverse: Odwróć automatyczną orientację pasów
placeInverse: Odwróć automatyczną orientację taśmociągów
pasteLastBlueprint: Wklej ostatnio skopiowany obszar
massSelectCut: Wytnij obszar
exportScreenshot: Wyeksportuj całą fabrykę jako zrzut ekranu
@ -856,10 +857,10 @@ keybindings:
Planowanie taśmociągu: Zmień stronę
pipette: Wybieranie obiektów z mapy
menuClose: Zamknij Menu
switchLayers: zamknij menu
switchLayers: Przełącz warstwy
advanced_processor: Kolor Falownika
energy_generator: Generator Energii
wire: Drut Energetyczny
wire: Przewód Energetyczny
about:
title: O Grze

View File

@ -61,7 +61,7 @@ steamPage:
[list]
[*] Различные карты и испытания (например, карты с препятствиями)
[*] Пазлы (Доставить запрошенную фигуру с ограничением пространства / набора зданий)
[*] Режим истории, где здания стоят фигур
[*] Режим истории, где здания стоят фигуры
[*] Настраиваемый генератор карт (настройка ресурса / размера фигуры / плотности, семя и т.д.)
[*] Дополнительные типы фигур
[*] Улучшения производительности (игра уже работает довольно хорошо!)
@ -71,7 +71,7 @@ steamPage:
[b]Это игра с открытым исходным кодом![/b]
Любой может внести свой вклад, я активно участвую в жизни сообщества и пытаюсь рассмотреть все предложения и по возможности принять во внимание отзывы.
Не забудьте проверить мою доску trello со всеми планами!
Не забудьте проверить мою доску Trello со всеми планами!
[b]Ссылки[/b]
@ -208,7 +208,7 @@ dialogs:
resetKeybindingsConfirmation:
title: Сброс управления
desc: Это сбросит все настройки управления к их значениям по умолчанию. Пожалуйста подтвердите.
desc: Это сбросит все настройки управления к их значениям по умолчанию. Подтвердите это действие.
keybindingsResetOk:
title: Сброс управления
@ -236,12 +236,12 @@ dialogs:
massDeleteConfirm:
title: Подтвердить удаление
desc: >-
Вы удаляете много построек (точнее: <count>)! Вы действительно хотите сделать это?
Вы собираетесь удалить много построек (точнее: <count>)! Вы действительно хотите сделать это?
blueprintsNotUnlocked:
title: Еще не открыто
desc: >-
Чертежи еще не открыты! Завершите больше уровней, что-бы открыть их.
Чертежи еще не открыты! Завершите больше уровней, чтобы открыть их.
keybindingsIntroduction:
title: Полезные горячие клавиши
@ -262,13 +262,13 @@ dialogs:
massCutConfirm:
title: Подтвердите вырезку
desc: >-
Вы вырезаете много зданий (точнее: <count>)! Вы уверены,
Вы собираетесь вырезать много зданий (точнее: <count>)! Вы уверены,
что хотите это сделать?
exportScreenshotWarning:
title: Экспорт скриншота
desc: >-
Вы запросили экспортировать вашу базу в виде скриншота. Обратите внимание,
Вы собираетесь экспортировать вашу базу в виде скриншота. Обратите внимание,
что это может быть довольно медленным процессом для большой базы
и даже привести к аварийному завершению игры!
@ -358,7 +358,7 @@ ingame:
title: Производится
description: Показывает производящиеся фигуры, включая промежуточное производство.
delivered:
title: Доставлено
title: Доставляется
description: Показывает фигуры, которые доставляются в хаб.
noShapesProduced: Фигуры еще не произведены.
@ -391,8 +391,8 @@ ingame:
waypoints:
waypoints: Маркеры
hub: ХАБ
description: ЛКМ по маркеру, чтобы переместиться к нему, ПКМ что-бы удалить. <br><br>Нажмите <keybinding> чтобы создать маркер в текущей позиции или <strong>ПКМ</strong> чтобы выбрать другое место для создания маркера.
creationSuccessNotification: Маркер был создан.
description: ЛКМ по маркеру, чтобы переместиться к нему, ПКМ, чтобы удалить. <br><br>Нажмите <keybinding> чтобы создать маркер в текущей позиции или <strong>ПКМ</strong>, чтобы выбрать другое место для создания маркера.
creationSuccessNotification: Маркер создан.
# Interactive tutorial
interactiveTutorial:
@ -440,7 +440,7 @@ buildings:
belt:
default:
name: &belt Конвейер
description: Транспортирует предметы, держите и тащите, чтобы разместить несколько.
description: Транспортирует предметы. Держите и тащите, чтобы разместить несколько.
miner: # Internal name for the Extractor
default:
@ -448,7 +448,7 @@ buildings:
description: Поместите над жилой с фигурами или красителями, чтобы добыть ресурс.
chainable:
name: Экстрактор(Цеп.)
name: Цеп. экстрактор
description: Поместите над жилой с фигурами или красителями, чтобы добыть ресурс. Может последовательно соединяться в цепь.
underground_belt: # Internal name for the Tunnel
@ -475,11 +475,11 @@ buildings:
cutter:
default:
name: &cutter Резчик
description: Разрезает фигуры сверху вниз и выводит обе половины. <strong>Используя только одну часть - уничтожьте другую, иначе производство остановится!</strong>
name: &cutter Резак
description: Разрезает фигуры сверху вниз и выводит обе половины. <strong>Если Вы собираетесь использовать только одну часть, уничтожьте другую, иначе производство остановится!</strong>
quad:
name: Резчик (4Вых.)
description: Разрезает фигуры на четыре части. <strong>Используя не все части - уничтожьте оставшиеся, иначе производство остановится!</strong>
name: Резак (4Вых.)
description: Разрезает фигуры на четыре части. <strong>Если Вы собираетесь использовать не все части - уничтожьте оставшиеся, иначе производство остановится!</strong>
rotater:
default:
@ -519,18 +519,18 @@ buildings:
trash:
default:
name: &trash Мусорка
description: Имеет входы со всех сторон. Уничтожает все что принимает, навсегда.
description: Имеет входы со всех сторон. Уничтожает все принимаемые ресурсы.
storage:
name: Хранилище
description: Хранит лишние предметы, до заданной вместимости. Может использоваться в качестве ворот для пропускания излишков.
description: Хранит лишние предметы до заданной вместимости. Может использоваться в качестве ворот для пропускания излишков.
hub:
deliver: Доставить
toUnlock: чтобы открыть
levelShortcut: Ур.
wire:
default:
name: Энергетический провод
name: Энерг. провод
description: Позволяет транспортировать энергию.
advanced_processor:
default:
@ -541,7 +541,7 @@ buildings:
toGenerateEnergy: Для
default:
name: Генератор энергии
description: Производит энергию потребляя фигуры.
description: Производит энергию из фигур.
wire_crossings:
default:
name: Разделитель провода
@ -554,7 +554,7 @@ storyRewards:
# Those are the rewards gained from completing the store
reward_cutter_and_trash:
title: Разрезание Фигур
desc: Вы только что открыли <strong>резчик</strong> - он разрезает фигуры пополам <strong>сверху вниз</strong> независимо от их ориентации!<br><br> Обязательно избавьтесь от отходов, иначе <strong>он остановится</strong> - для этого я дал вам мусорку, которая уничтожит все, что в нее поместить!
desc: Вы только что открыли <strong>резак</strong> - он разрезает фигуры пополам <strong>сверху вниз</strong> независимо от их ориентации!<br><br> Обязательно избавьтесь от отходов, иначе <strong>он остановится</strong> - для этого я дал вам мусорку, которая уничтожит все, что в нее поместить!
reward_rotater:
title: Вращение
@ -563,7 +563,7 @@ storyRewards:
reward_painter:
title: Покраска
desc: >-
Разблокирован <strong>покрасчик</strong>! Добудьте краситель из жилы (так же как и фигуры) и объедините его с фигурой в покрасчике, чтобы раскрасить ее!<br><br>PS: Если вы дальтоник, то в настройках есть <strong>Режим Дальтоника</strong>!
Разблокирован <strong>покрасчик</strong>! Добудьте краситель из жилы (так же, как и фигуры) и объедините его с фигурой в покрасчике, чтобы раскрасить ее!<br><br>PS: Если вы дальтоник, то в настройках есть <strong>Режим Дальтоника</strong>!
reward_mixer:
title: Смешивание Цветов
@ -579,11 +579,11 @@ storyRewards:
reward_tunnel:
title: Туннель
desc: Разблокирован <strong>туннель</strong>! Теперь вы можете транспортировать предметы сквозь конвейеры и здания!
desc: Разблокирован <strong>туннель</strong>! Теперь вы можете транспортировать предметы под другими конвейерами и зданиями!
reward_rotater_ccw:
title: Вращатель (обратный)
desc: Разблокирован вариант <strong>вращателя</strong>, он позволяет вращать фигуры против часовой стрелки! Чтобы построить его, выберите вращатель и <strong>нажмите 'T' чтобы переключаться между вариантами</strong>!
desc: Разблокирован вариант <strong>вращателя</strong>, вращающий фигуры против часовой стрелки! Чтобы построить его, выберите вращатель и <strong>нажмите 'T', чтобы переключить вариант</strong>!
reward_miner_chainable:
title: Цепной Экстрактор
@ -595,12 +595,11 @@ storyRewards:
reward_splitter_compact:
title: Компактный Соединитель
desc: >-
Разблокирован компактный вариант <strong>разделителя</strong>, он объединяет воедино потоки предметов из двух входов!
desc: Разблокирован компактный вариант <strong>разделителя</strong>, объединяющий потоки предметов из двух входов!
reward_cutter_quad:
title: Резчик (4 Выхода)
desc: Разблокирован вариант <strong>резчика</strong> - он позволяет разрезать фигуры на <strong>четыре части</strong> вместо, всего лишь двух!
title: Резак (4 Выхода)
desc: Разблокирован вариант <strong>резака</strong>, разрезающий фигуры на <strong>четыре части</strong> вместо двух!
reward_painter_double:
title: Двойной Покрасчик
@ -620,13 +619,13 @@ storyRewards:
reward_blueprints:
title: Чертежи
desc: Теперь вы можете <strong>копировать и вставлять</strong> части вашей фабрики! Выберите область (Удерживая CTRL, перетащите мышь) и нажмите 'C' чтобы скопировать ее.<br><br>Вставка <strong>не бесплатна</strong>, чтобы позволить себе это вам необходимо произвести <strong>фигуры для чертежей</strong>! (Которые вы только что доставили).
desc: Теперь вы можете <strong>копировать и вставлять</strong> части вашей фабрики! Выберите область (Удерживая CTRL, перетащите мышь) и нажмите 'C', чтобы скопировать ее.<br><br>Вставка <strong>не бесплатна</strong>, для этого необходимо произвести <strong>фигуры для чертежей</strong>! (Которые вы только что доставили).
# Special reward, which is shown when there is no reward actually
no_reward:
title: Следующий уровень
desc: >-
Этот уровень не дал вам награды, но следующий даст! <br><br> PS: Лучше не разрушайте вашу существующую фабрику - Вам понадобятся <strong>все</strong> эти фигуры позже, чтобы <strong>разблокировать улучшения</strong>!
Этот уровень не дал вам награды, но следующий даст! <br><br> PS: Лучше не разрушайте вашу существующую фабрику - Вам понадобятся <strong>все</strong> эти фигуры позже, чтобы <strong>разблокировать улучшения</strong>!
no_reward_freeplay:
title: Следующий уровень
@ -737,7 +736,7 @@ settings:
title: Интервал авто-сохранения
description: >-
Управляет тем, как часто игра автоматически сохраняется.
А также здесь можно полностью отключить авто-сохранение.
Также здесь можно полностью отключить авто-сохранение.
intervals:
one_minute: 1 Минута
two_minutes: 2 Минуты
@ -751,7 +750,7 @@ settings:
Сокращает отображаемую информацию о зданиях, показывая только их множители.
Иначе информация отображается с описанием и изображением.
disableCutDeleteWarnings:
title: Отключить Предупреждение о Вырезании\Удалении
title: Отключить Предупреждение о Вырезании/Удалении
description: >-
Отключает диалоговые окна с предупреждениями, появляющиеся при
вырезании/удалении более 100 объектов.
@ -844,19 +843,19 @@ about:
Эта игра с открытым исходным кодом, разработана <a href="https://github.com/tobspr"
target="_blank">Тобиасом Спрингером</a> (это я).<br><br>
Если вы хотите внести свой вклад то вам сюда - <a href="<githublink>"
Если вы хотите внести свой вклад игре - <a href="<githublink>"
target="_blank">shapez.io в github</a>.<br><br>
Эта игра не была бы возможна без большого сообщества в дискорде, которое собралось
вокруг моих игр - Вы действительно должны присоединиться к <a href="<discordlink>"
target="_blank">серверу в дискорде</a>!<br><br>
вокруг моих игр - Вам действительно стоит присоединиться к <a href="<discordlink>"
target="_blank">серверу Discord!</a>!<br><br>
Саундтрек сделал <a href="https://soundcloud.com/pettersumelius"
target="_blank">Peppsen</a> - Он потрясающий.<br><br>
Наконец, огромное спасибо моему лучшему другу <a
href="https://github.com/niklas-dahl" target="_blank">Niklas</a> - Без наших
игровых сессий в factorio эта игра никогда не существовала бы.
игровых сессий в Factorio эта игра никогда не существовала бы.
changelog:
title: Список изменений

View File

@ -3,7 +3,7 @@
#
# Translators:
#
# Prosta4ok_ua 07.07.2020 — 04.08.2020
# Prosta4ok_ua 07.07.2020 — 05.09.2020
#
# Contributing:
#
@ -31,6 +31,7 @@
# range дальність
# storage сховище
# shape форма
# layer шар
---
steamPage:
@ -272,7 +273,7 @@ dialogs:
Ось декілька, але обов’язково <strong>ознайомтеся з прив’язками клавіш</strong>!<br><br>
<code class='keybinding'>CTRL</code> + тягніть: виділити зону.<br>
<code class='keybinding'>SHIFT</code>: тримайте, щоб розмістити декілька одного будинку.<br>
<code class='keybinding'>ALT</code>: змінити орієнтацію розміщеної конвеєрної стрічки.<br>
<code class='keybinding'>ALT</code>: змінити сторону розміщеної конвеєрної стрічки.<br>
createMarker:
title: Нова позначка
@ -367,7 +368,7 @@ ingame:
# The roman number for each tier
tierLabels: [I, II, III, IV, V, VI, VII, VIII, IX, X]
maximumLevel: МАКСИМАЛЬНИЙ РІВЕНЬ (Швидкість <currentMult>х)
maximumLevel: МАКСИМАЛЬНИЙ РІВЕНЬ (Швидкість x<currentMult>)
# The "Statistics" window
statistics:
@ -489,7 +490,7 @@ buildings:
splitter:
default:
name: &splitter Розподілювач
description: Multifunctional - Evenly distributes all inputs onto all outputs.
description: Багатофункціональний. Рівномірно розподіляє все, що входить.
compact:
name: З’єднувач
@ -526,128 +527,128 @@ buildings:
stacker:
default:
name: &stacker Укладальник
description: Stacks both items. If they can not be merged, the right item is placed above the left item.
description: Складає обидва елементи. Якщо їх неможливо об’єднати, правий елемент розміщується над лівим елементом.
mixer:
default:
name: &mixer Змішувач кольо8рів
name: &mixer Змішувач кольорів
description: Змішує два кольори за допомогою добавки.
painter:
default:
name: &painter Painter
description: &painter_desc Colors the whole shape on the left input with the color from the top input.
name: &painter Фарбувач
description: &painter_desc Забирає форму з лівого входу, а колір з верхнього.
mirrored:
name: *painter
description: *painter_desc
double:
name: Painter (Double)
description: Colors the shapes on the left inputs with the color from the top input.
name: Фарбувач (подв.)
description: Фарбує фігури, що надійшла з лівого входу, кольором, що надійшов з верхнього.
quad:
name: Painter (Quad)
description: Allows you to color each quadrant of the shape with a different color.
name: Фарбувач (чотири)
description: Дозволяє вам фарбувати кожну четвертину форми у різний колір.
trash:
default:
name: &trash Trash
description: Accepts inputs from all sides and destroys them. Forever.
name: &trash Смітник
description: Приймає форми зі всіх сторін і руйнує їх. Назавжди.
storage:
name: Storage
description: Stores excess items, up to a given capacity. Can be used as an overflow gate.
name: Сховище
description: Зберігає зайві предмети до заданої місткості. Може використовуватися для зберігання надлишкових речей.
energy_generator:
deliver: Deliver
deliver: Доставте
# This will be shown before the amount, so for example 'For 123 Energy'
toGenerateEnergy: For
toGenerateEnergy: За
default:
name: &energy_generator Energy Generator
description: Generates energy by consuming shapes. Each energy generator requires a different shape.
name: &energy_generator Енергетичний генератор
description: Створює енергію споживаючи форми. Кожний енергетичний генератор потрібує свою форму.
wire_crossings:
default:
name: &wire_crossings Wire Splitter
description: Splits a wire into two
name: &wire_crossings Дротовий розподілювач
description: Ділить дріт надвоє.
merger:
name: Wire Merger
description: Merges two wires into one
name: Дротовий з’єднувач
description: Об’єднує два дроти в один.
storyRewards:
# Those are the rewards gained from completing the store
reward_cutter_and_trash:
title: Різання фігур
desc: Ви тільки-но розблокували <strong>різця</strong>. Він розрізає фігури наполовину з <strong>вершини до низу</strong> незалежно від його орієнтації!<br><br>Обов’язково позбудьтесь відходів або <strong>він зупиниться</strong>. Для цього є сміттєбак, який знищує все, що входить в нього.
desc: Ви тільки-но розблокували <strong>різця</strong>. Він розрізає фігури наполовину з <strong>вершини до низу</strong> незалежно від його орієнтації!<br><br>Обов’язково позбудьтесь відходів або <strong>він зупиниться</strong>. Для цього є смітник, який знищує все, що входить в нього.
reward_rotater:
title: Rotating
desc: The <strong>rotater</strong> has been unlocked! It rotates shapes clockwise by 90 degrees.
title: Обертання
desc: <strong>Обертач</strong> розблоковано! Він повертає форми за годинниковою стрілкою на 90 градусів.
reward_painter:
title: Painting
title: Фарбування
desc: >-
The <strong>painter</strong> has been unlocked - Extract some color veins (just as you do with shapes) and combine it with a shape in the painter to color them!<br><br>PS: If you are colorblind, there is a <strong>colorblind mode</strong> in the settings!
<strong>Фарбувач</strong> розблоковано. Видобудьте трохи кольорів з відповідних жилок (як ви зробили це з формами) і об’єднуйте їх з формами у фарбувачі, щоб розфарбувати форми!<br><br>До речі, якщо ви дальтонік, то в увімкніть <strong>режим високої контрастності</strong> в налаштуваннях!
reward_mixer:
title: Color Mixing
desc: The <strong>mixer</strong> has been unlocked - Combine two colors using <strong>additive blending</strong> with this building!
title: Змішування кольорів
desc: <strong>Змішування кольорів</strong> розблоковано. Об’єднуйте два кольори у цій будівлі.
reward_stacker:
title: Combiner
desc: You can now combine shapes with the <strong>combiner</strong>! Both inputs are combined, and if they can be put next to each other, they will be <strong>fused</strong>. If not, the right input is <strong>stacked on top</strong> of the left input!
title: Поєднувач форм
desc: Тепер ви можете поєднувати фігури з <strong>поєднувачем форм</strong>! Форми об’єднуються з двох сторін, і якщо їх можна поставити поруч, вони будуть <strong>з’єднані</strong>. Якщо ні, то форма, що подана з правого входу, <strong>застрягне на горі</strong> лівого входу.
reward_splitter:
title: Splitter/Merger
desc: Багатофункціональний <strong> балансир </strong> було розблоковано. Його можна використовувати для створення великих фабрик, <strong>розділяючи та об’єднуючи предмети </strong> на кілька стрічок!<br><br>
title: Розподілювач (з’єднувач)
desc: Багатофункціональний <strong>розподілювач</strong> було розблоковано. Його можна використовувати для створення великих фабрик, <strong>розділяючи та об’єднуючи предмети </strong> на кілька стрічок!<br><br>
reward_tunnel:
title: Tunnel
desc: The <strong>tunnel</strong> has been unlocked - You can now tunnel items through belts and buildings with it!
title: Тунель
desc: <strong>Тунель</strong> розблоковано. Ви можете створювати тунелі для преметів через стрічки і будівлі.
reward_rotater_ccw:
title: CCW Rotating
desc: You have unlocked a variant of the <strong>rotater</strong> - It allows you to rotate shapes counter-clockwise! To build it, select the rotater and <strong>press 'T' to cycle through its variants</strong>!
title: Обертання проти годинникової стрілки
desc: Ви розблокували новий варіант <strong>обертача</strong>. Він дозволяє обертати проти годинникової стрілки! Щоб побудувати його виберіть обертач, <strong>натисніть «T», щоб переглянути всі варіанти, та оберіть потрібний</strong>!
reward_miner_chainable:
title: Chaining Extractor
desc: You have unlocked the <strong>chaining extractor</strong>! It can <strong>forward its resources</strong> to other extractors so you can more efficiently extract resources!
title: Екстрактор (ланцюг.)
desc: Ви розблокували <strong>ланцюговий екстрактор</strong>! Він може <strong>пересилати свої ресурси</strong> іншим екстракторам, щоб ви могли ефективніше видобувати ресурси!
reward_underground_belt_tier_2:
title: Tunnel Tier II
desc: You have unlocked a new variant of the <strong>tunnel</strong> - It has a <strong>bigger range</strong>, and you can also mix-n-match those tunnels now!
title: Тунель II
desc: Ви розблокували новий варіант <strong>тунеля</strong>. Він має <strong>більшу дальність</strong>, і ви можете також змішувати і зіставляти ці тунелі!
reward_splitter_compact:
title: Compact Balancer
title: Компактний розподілювач
desc: >-
You have unlocked a compact variant of the <strong>balancer</strong> - It accepts two inputs and merges them into one belt!
Ви розблокували компактний варіант <strong>розподілювача</strong>. Він приймає з двох сторін і об’єднує на одну стрічку!
reward_cutter_quad:
title: Quad Cutting
desc: You have unlocked a variant of the <strong>cutter</strong> - It allows you to cut shapes in <strong>four parts</strong> instead of just two!
title: Різчик (чотири)
desc: Ви розблокували інший варіант <strong>різчика</strong>. Він може розрізати форми на <strong>чотири частини</strong> замість двох.
reward_painter_double:
title: Double Painting
desc: You have unlocked a variant of the <strong>painter</strong> - It works as the regular painter but processes <strong>two shapes at once</strong> consuming just one color instead of two!
desc: Ви розблокували інший варіант <strong>фарбувача</strong>. Він працює як звичайний фарбувач, але обробляє <strong>дві фігури одночасно</strong>, споживаючи лише один колір замість двох!
reward_painter_quad:
title: Quad Painting
desc: You have unlocked a variant of the <strong>painter</strong> - It allows you to paint each part of the shape individually!
desc: Ви розблокували інший варіант <strong>фарбувача</strong>. Він дозволяє фарбувати кожну частину форми індивідуально!
reward_storage:
title: Storage Buffer
desc: You have unlocked a variant of the <strong>trash</strong> - It allows you to store items up to a given capacity!
desc: Ви розблокували інший варіант <strong>trash</strong> - It allows you to store items up to a given capacity!
reward_freeplay:
title: Freeplay
desc: You did it! You unlocked the <strong>free-play mode</strong>! This means that shapes are now randomly generated! (No worries, more content is planned for the standalone!)
title: Пісочниця
desc: Ви зробили це! Ви розблокували <strong>вільний режим</strong>! Це означає, що форми тут створюватимуться випадкові! Не хвилюйтеся, більше контенту планується для окремого режиму!
reward_blueprints:
title: Blueprints
desc: You can now <strong>copy and paste</strong> parts of your factory! Select an area (Hold CTRL, then drag with your mouse), and press 'C' to copy it.<br><br>Pasting it is <strong>not free</strong>, you need to produce <strong>blueprint shapes</strong> to afford it! (Those you just delivered).
title: Креслення
desc: Ви вже можете <strong>копіювати і вставляти</strong> частини вашої фабрики. Виберіть зону (утримуйте CTRL, а тоді тягніть мишою), і натисніть «C», щоб скопіювати.<br><br>Вставляти креслення — <strong>річ не безкоштовна</strong>, спочатку вам потрібно створити <strong>форми креслень</strong>, щоб собі це дозволити! (ті, що ви щойно доставили).
# Special reward, which is shown when there is no reward actually
no_reward:
@ -668,10 +669,10 @@ settings:
advanced: Передове
versionBadges:
dev: Development
staging: Staging
prod: Production
buildDate: Built <at-date>
dev: Розробка
staging: Тестування
prod: Виробництво
buildDate: Створено <at-date>
labels:
uiScale:
@ -724,7 +725,7 @@ settings:
language:
title: Мова
description: >-
Змініть мову. Усі переклади зроблені користувачами і можуть бути незавершеними!
Зміна мови. Усі переклади зроблені користувачами і можуть бути незавершеними!
enableColorBlindHelper:
title: Режим високої контрастності
@ -770,55 +771,55 @@ settings:
Якщо увімкнено, то пропонує підказки та посібники під час гри. Також приховує певні елементи інтерфейсу до заданого рівня, щоб полегшити потрапляння в гру.
enableTunnelSmartplace:
title: Розумні Tunnels
title: Розумні тунелі
description: >-
When enabled, placing tunnels will automatically remove unnecessary belts. This also enables you to drag tunnels and excess tunnels will get removed.
Якщо увімкнено, то розміщення тунелів видалить непотрібні стрічки. Це також дозволяє вам перетягувати тунелі і видаляти автоматично зайві тунелі.
vignette:
title: Vignette
title: Віньєтка
description: >-
Enables the vignette, which darkens the screen corners and makes text easier to read.
Вмикає віньєтку, яка затемнює кути екрану і робить текст легшим для читання.
rotationByBuilding:
title: Rotation by building type
title: Обертання за типом будівлі
description: >-
Each building type remembers the rotation you last set it to individually. This may be more comfortable if you frequently switch between placing different building types.
Кожний тип будівлі запам’ятовує обертання, яке ви встановили. Це може бути зручнішим, якщо ви часто перемикаєтесь між розміщенням різних типів будівель.
compactBuildingInfo:
title: Compact Building Infos
title: Компактна інформація про будівлі
description: >-
Shortens info boxes for buildings by only showing their ratios. Otherwise a description and image is shown.
Скорочує інформаційні поля для будівель, лише показуючи їх співвідношення. В іншому випадку відображається опис та зображення.
disableCutDeleteWarnings:
title: Disable Cut/Delete Warnings
title: Вимкнути попердження про вирізання та видалення
description: >-
Disables the warning dialogs brought up when cutting/deleting more than 100 entities.
Вимикає діалогові вікна попередження, що з’являються під час вирізання/видалення більше 100 об’єктів.
keybindings:
title: Гарячі клавіши
hint: >-
Tip: Be sure to make use of CTRL, SHIFT and ALT! They enable different placement options.
Tip: Упевніться, що ви можете використовувати CTRL, SHIFT і ALT! Вони дозволяють різні варіанти розміщення.
resetKeybindings: Скинути гарячі клавіші
categoryLabels:
general: Застосунок
ingame: Гра
navigation: Navigating
placement: Placement
massSelect: Mass Select
buildings: Building Shortcuts
placementModifiers: Placement Modifiers
navigation: Навігація
placement: Розміщення
massSelect: Масовий вибір
buildings: Гарячі клавіши будівництва
placementModifiers: Модифікатори розміщення
mappings:
confirm: Підтвердити
back: Назад
mapMoveUp: Move Up
mapMoveRight: Move Right
mapMoveDown: Move Down
mapMoveLeft: Move Left
mapMoveFaster: Move Faster
centerMap: Center Map
mapMoveUp: Угору
mapMoveRight: Праворуч
mapMoveDown: Униз
mapMoveLeft: Ліворуч
mapMoveFaster: Пришвидшитися
centerMap: Центрувати мапу
mapZoomIn: Приблизити
mapZoomOut: Віддалити
@ -828,10 +829,10 @@ keybindings:
menuOpenStats: Статистика
menuClose: Закрити меню
toggleHud: Toggle HUD
toggleFPSInfo: Toggle FPS and Debug Info
switchLayers: Switch layers
exportScreenshot: Export whole Base as Image
toggleHud: Перемкнути користувацький інтерфейс
toggleFPSInfo: Перемкнути інформацію про FPS та зневадження
switchLayers: Перемкнути шари
exportScreenshot: Експортувати цілу базу у вигляді зображення
belt: *belt
splitter: *splitter
underground_belt: *underground_belt
@ -846,26 +847,26 @@ keybindings:
trash: *trash
wire: *wire
pipette: Pipetteї
pipette: Піпетка
rotateWhilePlacing: Повернути
rotateInverseModifier: >-
Modifier: Rotate CCW instead
cycleBuildingVariants: Cycle Variants
Modifier: Повернути проти годинникової стрілки натомість
cycleBuildingVariants: Повторювати варіанти циклічно
confirmMassDelete: Видалити ділянку
pasteLastBlueprint: Paste last blueprint
cycleBuildings: Cycle Buildings
lockBeltDirection: Enable belt planner
pasteLastBlueprint: Вставити останнє креслення
cycleBuildings: Перемикання будівль
lockBeltDirection: Увімкнути планувальник конвеєрних стрічок
switchDirectionLockSide: >-
Planner: Switch side
Planner: Змінити сторону
massSelectStart: Hold and drag to start
massSelectStart: Утримуйте і перетягуйте, щоб розпочати
massSelectSelectMultiple:
massSelectCopy: Копіювати ділянку
massSelectCut: Вирізати ділянку
placementDisableAutoOrientation: Вимкнути автоматичну орієнтацію
placeMultiple: Stay in placement mode
placeInverse: Invert automatic belt orientation
placeMultiple: Залишатися у режимі розміщення
placeInverse: Перевернути автоматичну орієнтацію стрічки
about:
title: Про гру

17271
yarn.lock

File diff suppressed because it is too large Load Diff