Merge branch 'master' into right-click-doesnt-clear-cursor.
|
Before Width: | Height: | Size: 906 KiB After Width: | Height: | Size: 1.6 MiB |
BIN
artwork/itch.io/bg.png
Normal file
|
After Width: | Height: | Size: 3.1 MiB |
BIN
artwork/steam/announcement.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
3
artwork/steam/announcement.psd
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:de805473208e0901f1185485164a35fde59e4baf3000f30102d0f332842410a5
|
||||
size 184895
|
||||
BIN
artwork/steam/store_page_gif.gif
Normal file
|
After Width: | Height: | Size: 707 KiB |
@ -189,7 +189,7 @@ function serve({ standalone }) {
|
||||
gulp.watch("../res_built/atlas/*.json", ["imgres.atlas"]);
|
||||
|
||||
// Watch the build folder and reload when anything changed
|
||||
const extensions = ["html", "js", "png", "jpg", "svg", "mp3", "ico", "woff2", "json"];
|
||||
const extensions = ["html", "js", "png", "gif", "jpg", "svg", "mp3", "ico", "woff2", "json"];
|
||||
gulp.watch(extensions.map(ext => path.join(buildFolder, "**", "*." + ext))).on("change", function (e) {
|
||||
return gulp.src(e.path).pipe(browserSync.reload({ stream: true }));
|
||||
});
|
||||
@ -275,11 +275,7 @@ gulp.task(
|
||||
$.sequence("sounds.fullbuild", "translations.fullBuild", "js.standalone-beta")
|
||||
);
|
||||
gulp.task("step.standalone-beta.mainbuild", cb =>
|
||||
$.multiProcess(
|
||||
["utils.copyAdditionalBuildFiles", "step.baseResources", "step.standalone-beta.code"],
|
||||
cb,
|
||||
false
|
||||
)
|
||||
$.multiProcess(["step.baseResources", "step.standalone-beta.code"], cb, false)
|
||||
);
|
||||
gulp.task(
|
||||
"step.standalone-beta.all",
|
||||
@ -293,11 +289,7 @@ gulp.task(
|
||||
$.sequence("sounds.fullbuild", "translations.fullBuild", "js.standalone-prod")
|
||||
);
|
||||
gulp.task("step.standalone-prod.mainbuild", cb =>
|
||||
$.multiProcess(
|
||||
["utils.copyAdditionalBuildFiles", "step.baseResources", "step.standalone-prod.code"],
|
||||
cb,
|
||||
false
|
||||
)
|
||||
$.multiProcess(["step.baseResources", "step.standalone-prod.code"], cb, false)
|
||||
);
|
||||
gulp.task(
|
||||
"step.standalone-prod.all",
|
||||
|
||||
16
gulp/html.js
@ -96,12 +96,20 @@ function gulptasksHTML($, gulp, buildFolder, browserSync) {
|
||||
|
||||
const initScript = document.createElement("script");
|
||||
initScript.textContent = `
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
gtag('config', 'UA-165342524-1', { anonymize_ip: true });
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
gtag('config', 'UA-165342524-1', { anonymize_ip: true });
|
||||
`;
|
||||
document.head.appendChild(initScript);
|
||||
|
||||
const abTestingScript = document.createElement("script");
|
||||
abTestingScript.setAttribute(
|
||||
"src",
|
||||
"https://www.googleoptimize.com/optimize.js?id=OPT-M5NHCV7"
|
||||
);
|
||||
abTestingScript.setAttribute("async", "");
|
||||
document.head.appendChild(abTestingScript);
|
||||
}
|
||||
|
||||
// Do not need to preload in app or standalone
|
||||
|
||||
@ -5,7 +5,7 @@ const path = require("path");
|
||||
const nonImageResourcesGlobs = ["../res/**/*.woff2", "../res/*.ico", "../res/**/*.webm"];
|
||||
|
||||
// Globs for ui resources
|
||||
const imageResourcesGlobs = ["../res/**/*.png", "../res/**/*.svg", "../res/**/*.jpg"];
|
||||
const imageResourcesGlobs = ["../res/**/*.png", "../res/**/*.svg", "../res/**/*.jpg", "../res/**/*.gif"];
|
||||
|
||||
function gulptasksImageResources($, gulp, buildFolder) {
|
||||
// Lossless options
|
||||
@ -17,6 +17,10 @@ function gulptasksImageResources($, gulp, buildFolder) {
|
||||
$.imagemin.optipng({
|
||||
optimizationLevel: 3,
|
||||
}),
|
||||
$.imageminGifsicle({
|
||||
optimizationLevel: 3,
|
||||
colors: 128,
|
||||
}),
|
||||
];
|
||||
|
||||
// Lossy options
|
||||
@ -36,6 +40,10 @@ function gulptasksImageResources($, gulp, buildFolder) {
|
||||
$.imagemin.optipng({
|
||||
optimizationLevel: 3,
|
||||
}),
|
||||
$.imageminGifsicle({
|
||||
optimizationLevel: 3,
|
||||
colors: 128,
|
||||
}),
|
||||
];
|
||||
|
||||
// Where the resources folder are
|
||||
@ -124,6 +132,7 @@ function gulptasksImageResources($, gulp, buildFolder) {
|
||||
path.join(buildFolder, "res", "ui", "**", "*.png"),
|
||||
path.join(buildFolder, "res", "ui", "**", "*.jpg"),
|
||||
path.join(buildFolder, "res", "ui", "**", "*.svg"),
|
||||
path.join(buildFolder, "res", "ui", "**", "*.gif"),
|
||||
],
|
||||
{ read: false }
|
||||
)
|
||||
|
||||
@ -70,6 +70,7 @@
|
||||
"css-mqpacker": "^7.0.0",
|
||||
"cssnano": "^4.1.10",
|
||||
"electron-packager": "^14.0.6",
|
||||
"imagemin-gifsicle": "^7.0.0",
|
||||
"faster.js": "^1.1.0",
|
||||
"glob": "^7.1.3",
|
||||
"gulp": "^3.9.1",
|
||||
|
||||
@ -237,7 +237,7 @@ module.exports = ({
|
||||
pattern: /globalConfig\.beltSpeedItemsPerSecond/g,
|
||||
replacement: () => "2.0",
|
||||
},
|
||||
{ pattern: /globalConfig\.itemSpacingOnBelts/g, replacement: () => "0.8" },
|
||||
{ pattern: /globalConfig\.itemSpacingOnBelts/g, replacement: () => "0.63" },
|
||||
{ pattern: /globalConfig\.debug/g, replacement: () => "''" },
|
||||
],
|
||||
}),
|
||||
|
||||
100
gulp/yarn.lock
@ -3412,6 +3412,15 @@ cross-spawn@^5.0.1:
|
||||
shebang-command "^1.2.0"
|
||||
which "^1.2.9"
|
||||
|
||||
cross-spawn@^7.0.0:
|
||||
version "7.0.3"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
|
||||
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
|
||||
dependencies:
|
||||
path-key "^3.1.0"
|
||||
shebang-command "^2.0.0"
|
||||
which "^2.0.1"
|
||||
|
||||
cross-zip@^2.1.5:
|
||||
version "2.1.6"
|
||||
resolved "https://registry.yarnpkg.com/cross-zip/-/cross-zip-2.1.6.tgz#344d3ba9488609942987d815bb84860cff3d9491"
|
||||
@ -4875,6 +4884,21 @@ execa@^1.0.0:
|
||||
signal-exit "^3.0.0"
|
||||
strip-eof "^1.0.0"
|
||||
|
||||
execa@^4.0.0:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/execa/-/execa-4.0.2.tgz#ad87fb7b2d9d564f70d2b62d511bee41d5cbb240"
|
||||
integrity sha512-QI2zLa6CjGWdiQsmSkZoGtDx2N+cQIGb3yNolGTdjSQzydzLgYYf8LRuagp7S7fPimjcrzUDSUFd/MgzELMi4Q==
|
||||
dependencies:
|
||||
cross-spawn "^7.0.0"
|
||||
get-stream "^5.0.0"
|
||||
human-signals "^1.1.1"
|
||||
is-stream "^2.0.0"
|
||||
merge-stream "^2.0.0"
|
||||
npm-run-path "^4.0.0"
|
||||
onetime "^5.1.0"
|
||||
signal-exit "^3.0.2"
|
||||
strip-final-newline "^2.0.0"
|
||||
|
||||
executable@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/executable/-/executable-1.1.0.tgz#877980e9112f3391066da37265de7ad8434ab4d9"
|
||||
@ -5738,7 +5762,7 @@ get-stream@^4.0.0, get-stream@^4.1.0:
|
||||
dependencies:
|
||||
pump "^3.0.0"
|
||||
|
||||
get-stream@^5.1.0:
|
||||
get-stream@^5.0.0, get-stream@^5.1.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.1.0.tgz#01203cdc92597f9b909067c3e656cc1f4d3c4dc9"
|
||||
integrity sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==
|
||||
@ -5767,6 +5791,16 @@ gifsicle@^4.0.0:
|
||||
execa "^1.0.0"
|
||||
logalot "^2.0.0"
|
||||
|
||||
gifsicle@^5.0.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/gifsicle/-/gifsicle-5.1.0.tgz#08f878e9048c70adf046185115a6350516a1fdc0"
|
||||
integrity sha512-hQsOH7yjC7fMokntysN6f2QuxrnX+zmKKKVy0sC3Vhtnk8WrOxLdfH/Z2PNn7lVVx+1+drzIeAe8ufcmdSC/8g==
|
||||
dependencies:
|
||||
bin-build "^3.0.0"
|
||||
bin-wrapper "^4.0.0"
|
||||
execa "^4.0.0"
|
||||
logalot "^2.0.0"
|
||||
|
||||
glob-all@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/glob-all/-/glob-all-3.1.0.tgz#8913ddfb5ee1ac7812656241b03d5217c64b02ab"
|
||||
@ -6859,6 +6893,11 @@ https-browserify@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
|
||||
integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=
|
||||
|
||||
human-signals@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3"
|
||||
integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==
|
||||
|
||||
iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13:
|
||||
version "0.4.24"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
|
||||
@ -6912,6 +6951,15 @@ imagemin-gifsicle@^6.0.1:
|
||||
gifsicle "^4.0.0"
|
||||
is-gif "^3.0.0"
|
||||
|
||||
imagemin-gifsicle@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/imagemin-gifsicle/-/imagemin-gifsicle-7.0.0.tgz#1a7ab136a144c4678657ba3b6c412f80805d26b0"
|
||||
integrity sha512-LaP38xhxAwS3W8PFh4y5iQ6feoTSF+dTAXFRUEYQWYst6Xd+9L/iPk34QGgK/VO/objmIlmq9TStGfVY2IcHIA==
|
||||
dependencies:
|
||||
execa "^1.0.0"
|
||||
gifsicle "^5.0.0"
|
||||
is-gif "^3.0.0"
|
||||
|
||||
imagemin-jpegtran@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/imagemin-jpegtran/-/imagemin-jpegtran-6.0.0.tgz#c8d3bcfb6ec9c561c20a987142854be70d90b04f"
|
||||
@ -8700,6 +8748,11 @@ merge-stream@^1.0.0:
|
||||
dependencies:
|
||||
readable-stream "^2.0.1"
|
||||
|
||||
merge-stream@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
|
||||
integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
|
||||
|
||||
merge2@^1.2.3:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.3.0.tgz#5b366ee83b2f1582c48f87e47cf1a9352103ca81"
|
||||
@ -8810,7 +8863,7 @@ mimic-fn@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
|
||||
integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==
|
||||
|
||||
mimic-fn@^2.0.0:
|
||||
mimic-fn@^2.0.0, mimic-fn@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
|
||||
integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
|
||||
@ -9312,6 +9365,13 @@ npm-run-path@^2.0.0:
|
||||
dependencies:
|
||||
path-key "^2.0.0"
|
||||
|
||||
npm-run-path@^4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea"
|
||||
integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==
|
||||
dependencies:
|
||||
path-key "^3.0.0"
|
||||
|
||||
"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.0, npmlog@^4.0.2:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b"
|
||||
@ -9533,6 +9593,13 @@ onetime@^2.0.0:
|
||||
dependencies:
|
||||
mimic-fn "^1.0.0"
|
||||
|
||||
onetime@^5.1.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.0.tgz#fff0f3c91617fe62bb50189636e99ac8a6df7be5"
|
||||
integrity sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==
|
||||
dependencies:
|
||||
mimic-fn "^2.1.0"
|
||||
|
||||
open@^0.0.5:
|
||||
version "0.0.5"
|
||||
resolved "https://registry.yarnpkg.com/open/-/open-0.0.5.tgz#42c3e18ec95466b6bf0dc42f3a2945c3f0cad8fc"
|
||||
@ -9997,6 +10064,11 @@ path-key@^2.0.0, path-key@^2.0.1:
|
||||
resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
|
||||
integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=
|
||||
|
||||
path-key@^3.0.0, path-key@^3.1.0:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
|
||||
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
|
||||
|
||||
path-parse@^1.0.6:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
|
||||
@ -12038,11 +12110,23 @@ shebang-command@^1.2.0:
|
||||
dependencies:
|
||||
shebang-regex "^1.0.0"
|
||||
|
||||
shebang-command@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
|
||||
integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==
|
||||
dependencies:
|
||||
shebang-regex "^3.0.0"
|
||||
|
||||
shebang-regex@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
|
||||
integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=
|
||||
|
||||
shebang-regex@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
|
||||
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
|
||||
|
||||
shelljs@^0.6.0:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.6.1.tgz#ec6211bed1920442088fe0f70b2837232ed2c8a8"
|
||||
@ -12680,6 +12764,11 @@ strip-eof@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
|
||||
integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=
|
||||
|
||||
strip-final-newline@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad"
|
||||
integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==
|
||||
|
||||
strip-indent@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2"
|
||||
@ -13973,6 +14062,13 @@ which@1, which@^1.1.1, which@^1.2.14, which@^1.2.9, which@^1.3.1:
|
||||
dependencies:
|
||||
isexe "^2.0.0"
|
||||
|
||||
which@^2.0.1:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
|
||||
integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
|
||||
dependencies:
|
||||
isexe "^2.0.0"
|
||||
|
||||
wide-align@^1.1.0:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457"
|
||||
|
||||
@ -12,7 +12,8 @@
|
||||
"lint": "npx 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-experimental --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",
|
||||
@ -41,6 +42,7 @@
|
||||
"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",
|
||||
"obfuscator-loader": "^1.1.2",
|
||||
|
||||
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 695 B |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 1.1 KiB |
BIN
res/ui/interactive_tutorial.noinline/1_1_extractor.gif
Normal file
|
After Width: | Height: | Size: 120 KiB |
BIN
res/ui/interactive_tutorial.noinline/1_2_conveyor.gif
Normal file
|
After Width: | Height: | Size: 297 KiB |
BIN
res/ui/interactive_tutorial.noinline/1_3_expand.gif
Normal file
|
After Width: | Height: | Size: 993 KiB |
@ -5,7 +5,7 @@
|
||||
transform: translateX(-50%);
|
||||
color: #333;
|
||||
z-index: 9999;
|
||||
background: rgba(0, 10, 20, 0.5);
|
||||
background: $ingameHudBg;
|
||||
@include S(padding, 5px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
@include S(width, 240px);
|
||||
@include S(grid-column-gap, 5px);
|
||||
|
||||
background: rgba(#333438, 0.8);
|
||||
background: $ingameHudBg;
|
||||
grid-template-columns: 1fr auto;
|
||||
grid-template-rows: auto 1fr;
|
||||
|
||||
@ -108,7 +108,8 @@
|
||||
.variant {
|
||||
grid-row: 2 / 3;
|
||||
@include S(border-radius, $globalBorderRadius);
|
||||
background: rgba(0, 10, 20, 0.2);
|
||||
background: rgba($ingameHudBg, 0.3);
|
||||
opacity: 0.5;
|
||||
display: inline-flex;
|
||||
vertical-align: top;
|
||||
position: relative;
|
||||
@ -117,7 +118,8 @@
|
||||
@include S(grid-gap, 10px);
|
||||
|
||||
&.active {
|
||||
background-color: rgba(74, 163, 223, 0.6);
|
||||
opacity: 1;
|
||||
background-color: rgba($colorBlueBright, 0.8);
|
||||
}
|
||||
|
||||
$iconSize: 25px;
|
||||
|
||||
@ -41,8 +41,8 @@
|
||||
background: center center / 70% no-repeat;
|
||||
|
||||
&:not(.unlocked) {
|
||||
@include S(width, 30px);
|
||||
opacity: 0.8;
|
||||
@include S(width, 20px);
|
||||
opacity: 0.15;
|
||||
background-image: none !important;
|
||||
|
||||
&::before {
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
#ingame_HUD_DebugInfo {
|
||||
position: absolute;
|
||||
@include S(bottom, 5px);
|
||||
@include S(left, 5px);
|
||||
@include S(right, 5px);
|
||||
|
||||
text-align: right;
|
||||
font-size: 15px;
|
||||
display: flex;
|
||||
line-height: 15px;
|
||||
|
||||
@ -118,7 +118,7 @@
|
||||
pointer-events: all;
|
||||
@include S(width, 350px);
|
||||
|
||||
> strong {
|
||||
strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@ -139,6 +139,14 @@
|
||||
background-color: rgb(250, 206, 206);
|
||||
}
|
||||
}
|
||||
|
||||
ul.bucketList {
|
||||
padding-left: 30px;
|
||||
|
||||
li {
|
||||
display: list-item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
> .buttons {
|
||||
|
||||
@ -76,7 +76,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
> button {
|
||||
.buttonContainer button {
|
||||
@include PlainText;
|
||||
color: #fff;
|
||||
border-color: rgba(0, 0, 0, 0.1);
|
||||
@ -86,7 +86,7 @@
|
||||
@include S(margin-right, 3px);
|
||||
@include IncreasedClickArea(0px);
|
||||
@include ButtonText;
|
||||
@include S(min-height, 30px);
|
||||
@include S(min-height, 40px);
|
||||
transition: all 0.12s ease-in-out;
|
||||
transition-property: opacity, transform;
|
||||
display: inline-flex;
|
||||
|
||||
50
src/css/ingame_hud/interactive_tutorial.scss
Normal file
@ -0,0 +1,50 @@
|
||||
#ingame_HUD_InteractiveTutorial {
|
||||
position: absolute;
|
||||
@include S(left, 10px);
|
||||
@include S(bottom, 10px);
|
||||
|
||||
@include StyleBelowWidth(1430px) {
|
||||
@include S(bottom, 10px + 40px);
|
||||
}
|
||||
|
||||
@include S(width, 150px);
|
||||
|
||||
background: $ingameHudBg;
|
||||
@include S(padding, 4px);
|
||||
color: #eee;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@include MakeAnimationWrappedEvenOdd(0.5s ease-in-out) {
|
||||
0% {
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
|
||||
100% {
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
color: #fff;
|
||||
opacity: 0.5;
|
||||
@include SuperSmallText;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.desc {
|
||||
@include SuperSmallText;
|
||||
strong {
|
||||
color: $colorBlueBright;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.helperGif {
|
||||
@include S(margin-top, 5px);
|
||||
@include S(height, 150px);
|
||||
background: center center / contain no-repeat;
|
||||
}
|
||||
}
|
||||
@ -3,8 +3,7 @@
|
||||
@include S(top, 50px);
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background: rgba(lighten(#f77, 5), 0.95);
|
||||
@include S(border-radius, $globalBorderRadius);
|
||||
background: $ingameHudBg;
|
||||
@include S(padding, 6px, 10px);
|
||||
@include SuperSmallText;
|
||||
color: #fff;
|
||||
|
||||
@ -1,7 +1,12 @@
|
||||
#ingame_HUD_TutorialHints {
|
||||
position: absolute;
|
||||
@include S(left, 10px);
|
||||
@include S(bottom, 50px);
|
||||
@include S(bottom, 10px);
|
||||
|
||||
@include StyleBelowWidth(1430px) {
|
||||
@include S(bottom, 50px);
|
||||
}
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: rgba(50, 60, 70, 0);
|
||||
@ -50,6 +55,7 @@
|
||||
|
||||
button.toggleHint {
|
||||
@include PlainText;
|
||||
@include IncreasedClickArea(0px);
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,7 +66,7 @@
|
||||
}
|
||||
|
||||
&.enlarged {
|
||||
background: rgba(50, 60, 70, 0.9);
|
||||
background: $ingameHudBg;
|
||||
left: 50%;
|
||||
bottom: 50%;
|
||||
transform: translate(-50%, 50%);
|
||||
@ -75,7 +81,7 @@
|
||||
bottom: -1000px;
|
||||
z-index: 0;
|
||||
|
||||
background: rgba(50, 60, 70, 0.3);
|
||||
background: rgba($ingameHudBg, 0.3);
|
||||
}
|
||||
|
||||
.header {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
#ingame_HUD_Watermark {
|
||||
position: absolute;
|
||||
background: uiResource("get_on_itch_io.svg") center center / contain no-repeat;
|
||||
background: uiResource("get_on_steam.png") center center / contain no-repeat;
|
||||
@include S(width, 110px);
|
||||
@include S(height, 40px);
|
||||
@include S(top, 10px);
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#ingame_HUD_Waypoints_Hint {
|
||||
position: absolute;
|
||||
@include S(right, 10px);
|
||||
@include S(bottom, 100px);
|
||||
@include S(bottom, 10px);
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@ -49,6 +49,7 @@
|
||||
@import "ingame_hud/watermark";
|
||||
@import "ingame_hud/blueprint_placer";
|
||||
@import "ingame_hud/waypoints";
|
||||
@import "ingame_hud/interactive_tutorial";
|
||||
|
||||
// prettier-ignore
|
||||
$elements:
|
||||
@ -69,6 +70,7 @@ ingame_HUD_Notifications,
|
||||
ingame_HUD_MassSelector,
|
||||
ingame_HUD_DebugInfo,
|
||||
ingame_HUD_EntityDebugger,
|
||||
ingame_HUD_InteractiveTutorial,
|
||||
ingame_HUD_TutorialHints,
|
||||
ingame_HUD_buildings_toolbar,
|
||||
ingame_HUD_BlueprintPlacer,
|
||||
@ -79,9 +81,9 @@ ingame_HUD_Watermark,
|
||||
ingame_HUD_BetaOverlay,
|
||||
|
||||
// Dialogs
|
||||
ingame_HUD_UnlockNotification,
|
||||
ingame_HUD_Shop,
|
||||
ingame_HUD_Statistics,
|
||||
ingame_HUD_UnlockNotification,
|
||||
ingame_HUD_SettingsMenu,
|
||||
ingame_HUD_ModalDialogs;
|
||||
|
||||
|
||||
@ -60,28 +60,17 @@
|
||||
|
||||
.mainWrapper {
|
||||
@include S(padding, 0, 10px);
|
||||
align-items: center;
|
||||
align-items: start;
|
||||
justify-items: center;
|
||||
|
||||
&.noDemo {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
&.demo {
|
||||
@include S(grid-column-gap, 10px);
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
@include S(grid-column-gap, 10px);
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
|
||||
.standaloneBanner {
|
||||
background: rgb(255, 234, 245);
|
||||
@include S(border-radius, $globalBorderRadius);
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
@include S(width, 300px);
|
||||
@include S(padding, 15px);
|
||||
|
||||
display: flex;
|
||||
@ -114,9 +103,9 @@
|
||||
|
||||
.steamLink {
|
||||
width: 100%;
|
||||
@include S(height, 50px);
|
||||
@include S(height, 40px);
|
||||
|
||||
background: uiResource("get_on_itch_io.svg") center center / contain no-repeat;
|
||||
background: uiResource("get_on_steam.png") center center / contain no-repeat;
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
text-indent: -999em;
|
||||
@ -165,6 +154,44 @@
|
||||
border: #{D(2px)} solid rgba(0, 10, 20, 0.1);
|
||||
}
|
||||
|
||||
.sideContainer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@include S(width, 300px);
|
||||
|
||||
.standaloneBanner {
|
||||
flex-grow: 1;
|
||||
@include S(margin-bottom, 10px);
|
||||
}
|
||||
|
||||
.contest {
|
||||
flex-grow: 1;
|
||||
background: rgb(32, 187, 166);
|
||||
@include S(padding, 15px);
|
||||
|
||||
h3 {
|
||||
@include Heading;
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
@include S(margin-bottom, 5px);
|
||||
}
|
||||
p {
|
||||
color: #fff;
|
||||
@include Text;
|
||||
strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
@include S(margin-bottom, 5px);
|
||||
}
|
||||
|
||||
button {
|
||||
background: #fff;
|
||||
color: #333538;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mainContainer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
width: 200px;
|
||||
height: 80px;
|
||||
min-height: 40px;
|
||||
background: uiResource("get_on_itch_io.svg") center center / contain no-repeat;
|
||||
background: uiResource("get_on_steam.png") center center / contain no-repeat;
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
text-indent: -999em;
|
||||
|
||||
@ -34,8 +34,7 @@ $colorGreenBright: #66bb6a;
|
||||
$colorBlueBright: rgb(74, 163, 223);
|
||||
$colorRedBright: #ef5072;
|
||||
$themeColor: #393747;
|
||||
$ingameHudBg: rgba($accentColorBright, 0.1);
|
||||
$ingameHudBorder: #{D(1.5px)} solid $accentColorDark;
|
||||
$ingameHudBg: rgba(#333438, 0.9);
|
||||
|
||||
$text3dColor: #f4ffff;
|
||||
|
||||
|
||||
@ -40,9 +40,6 @@
|
||||
<meta http-equiv="Expires" content="0" />
|
||||
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico" />
|
||||
<link rel="canonical" href="https://shapez.io" />
|
||||
|
||||
<!-- a/b testing -->
|
||||
<script src="https://www.googleoptimize.com/optimize.js?id=OPT-M5NHCV7"></script>
|
||||
</head>
|
||||
|
||||
<body oncontextmenu="return false" style="background: #393747;"></body>
|
||||
|
||||
@ -121,29 +121,18 @@ export class Application {
|
||||
* Initializes all platform instances
|
||||
*/
|
||||
initPlatformDependentInstances() {
|
||||
logger.log("Creating platform dependent instances");
|
||||
|
||||
// Start with empty ad provider
|
||||
this.adProvider = new NoAdProvider(this);
|
||||
|
||||
if (G_IS_STANDALONE) {
|
||||
this.storage = new StorageImplElectron(this);
|
||||
} else {
|
||||
if (window.indexedDB) {
|
||||
this.storage = new StorageImplBrowserIndexedDB(this);
|
||||
} else {
|
||||
this.storage = new StorageImplBrowser(this);
|
||||
}
|
||||
}
|
||||
this.sound = new SoundImplBrowser(this);
|
||||
logger.log("Creating platform dependent instances (standalone=", G_IS_STANDALONE, ")");
|
||||
|
||||
if (G_IS_STANDALONE) {
|
||||
this.platformWrapper = new PlatformWrapperImplElectron(this);
|
||||
} else {
|
||||
this.platformWrapper = new PlatformWrapperImplBrowser(this);
|
||||
}
|
||||
this.analytics = new GoogleAnalyticsImpl(this);
|
||||
|
||||
// Start with empty ad provider
|
||||
this.adProvider = new NoAdProvider(this);
|
||||
this.sound = new SoundImplBrowser(this);
|
||||
this.analytics = new GoogleAnalyticsImpl(this);
|
||||
this.gameAnalytics = new ShapezGameAnalytics(this);
|
||||
}
|
||||
|
||||
@ -267,11 +256,15 @@ export class Application {
|
||||
onAppRenderableStateChanged(renderable) {
|
||||
logger.log("Application renderable:", renderable);
|
||||
window.focus();
|
||||
const currentState = this.stateMgr.getCurrentState();
|
||||
if (!renderable) {
|
||||
this.stateMgr.getCurrentState().onAppPause();
|
||||
if (currentState) {
|
||||
currentState.onAppPause();
|
||||
}
|
||||
} else {
|
||||
// Got resume
|
||||
this.stateMgr.getCurrentState().onAppResume();
|
||||
if (currentState) {
|
||||
currentState.onAppResume();
|
||||
}
|
||||
this.checkResize();
|
||||
}
|
||||
|
||||
@ -285,7 +278,10 @@ export class Application {
|
||||
if (!this.unloaded) {
|
||||
logSection("UNLOAD HANDLER", "#f77");
|
||||
this.unloaded = true;
|
||||
this.stateMgr.getCurrentState().onBeforeExit();
|
||||
const currentState = this.stateMgr.getCurrentState();
|
||||
if (currentState) {
|
||||
currentState.onBeforeExit();
|
||||
}
|
||||
this.deinitialize();
|
||||
}
|
||||
}
|
||||
@ -295,8 +291,9 @@ export class Application {
|
||||
*/
|
||||
onBeforeUnload(event) {
|
||||
logSection("BEFORE UNLOAD HANDLER", "#f77");
|
||||
const currentState = this.stateMgr.getCurrentState();
|
||||
|
||||
if (!G_IS_DEV && this.stateMgr.getCurrentState().getHasUnloadConfirmation()) {
|
||||
if (!G_IS_DEV && currentState && currentState.getHasUnloadConfirmation()) {
|
||||
if (!G_IS_STANDALONE) {
|
||||
// Need to show a "Are you sure you want to exit"
|
||||
event.preventDefault();
|
||||
@ -346,7 +343,10 @@ export class Application {
|
||||
return;
|
||||
}
|
||||
|
||||
this.stateMgr.getCurrentState().onBackgroundTick(dt);
|
||||
const currentState = this.stateMgr.getCurrentState();
|
||||
if (currentState) {
|
||||
currentState.onBackgroundTick(dt);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -366,7 +366,10 @@ export class Application {
|
||||
this.lastResizeCheck = time;
|
||||
}
|
||||
|
||||
this.stateMgr.getCurrentState().onRender(dt);
|
||||
const currentState = this.stateMgr.getCurrentState();
|
||||
if (currentState) {
|
||||
currentState.onRender(dt);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -379,7 +382,10 @@ export class Application {
|
||||
if (this.screenWidth !== w || this.screenHeight !== h || forceUpdate) {
|
||||
this.screenWidth = w;
|
||||
this.screenHeight = h;
|
||||
this.stateMgr.getCurrentState().onResized(this.screenWidth, this.screenHeight);
|
||||
const currentState = this.stateMgr.getCurrentState();
|
||||
if (currentState) {
|
||||
currentState.onResized(this.screenWidth, this.screenHeight);
|
||||
}
|
||||
|
||||
const scale = this.getEffectiveUiScale();
|
||||
waitNextFrame().then(() => document.documentElement.style.setProperty("--ui-scale", scale));
|
||||
|
||||
@ -1,4 +1,39 @@
|
||||
export const CHANGELOG = [
|
||||
{
|
||||
version: "1.1.8",
|
||||
date: "07.06.2020",
|
||||
entries: [
|
||||
"You can now purchase the standalone on steam! <a href='https://steam.shapez.io' target='blank'>View steam page</a>",
|
||||
"Added ability to create markers in the demo, but only two.",
|
||||
"Contest #01 has ended! I'll now work through the entries, select the 5 I like most and present them to the community to vote for!",
|
||||
],
|
||||
},
|
||||
{
|
||||
version: "1.1.7",
|
||||
date: "04.06.2020",
|
||||
entries: ["HOTFIX: Fix savegames not showing up on the standalone version"],
|
||||
},
|
||||
{
|
||||
version: "1.1.6",
|
||||
date: "04.06.2020",
|
||||
entries: [
|
||||
"The steam release will happen on the <strong>7th of June</strong> - Be sure to add it to your wishlist! <a href='https://steam.shapez.io' target='blank'>View on steam</a>",
|
||||
"Fixed level complete dialog being blurred when the shop was opened before",
|
||||
"Standalone: Increased icon visibility for windows builds",
|
||||
"Web version: Fixed firefox not loading the game when browsing in private mode",
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
version: "1.1.5",
|
||||
date: "03.06.2020",
|
||||
entries: ["Added weekly contests!"],
|
||||
},
|
||||
{
|
||||
version: "1.1.4",
|
||||
date: "01.06.2020",
|
||||
entries: ["Add 'interactive' tutorial for the first level to improve onboarding experience"],
|
||||
},
|
||||
{
|
||||
version: "1.1.3",
|
||||
date: "01.06.2020",
|
||||
|
||||
@ -10,7 +10,10 @@ import { AtlasDefinition, atlasFiles } from "./atlas_definitions";
|
||||
|
||||
const logger = createLogger("background_loader");
|
||||
|
||||
const essentialMainMenuSprites = ["logo.png", ...G_ALL_UI_IMAGES.filter(src => src.startsWith("ui/"))];
|
||||
const essentialMainMenuSprites = [
|
||||
"logo.png",
|
||||
...G_ALL_UI_IMAGES.filter(src => src.startsWith("ui/") && src.indexOf(".gif") < 0),
|
||||
];
|
||||
const essentialMainMenuSounds = [
|
||||
SOUNDS.uiClick,
|
||||
SOUNDS.uiError,
|
||||
@ -21,7 +24,7 @@ const essentialMainMenuSounds = [
|
||||
];
|
||||
|
||||
const essentialBareGameAtlases = atlasFiles;
|
||||
const essentialBareGameSprites = G_ALL_UI_IMAGES;
|
||||
const essentialBareGameSprites = G_ALL_UI_IMAGES.filter(src => src.indexOf(".gif") < 0);
|
||||
const essentialBareGameSounds = [MUSIC.theme];
|
||||
|
||||
const additionalGameSprites = [];
|
||||
|
||||
@ -9,7 +9,7 @@ import { GLOBAL_APP } from "./globals";
|
||||
|
||||
const logger = createLogger("click_detector");
|
||||
|
||||
export const MAX_MOVE_DISTANCE_PX = IS_MOBILE ? 20 : 40;
|
||||
export const MAX_MOVE_DISTANCE_PX = IS_MOBILE ? 20 : 80;
|
||||
|
||||
// For debugging
|
||||
const registerClickDetectors = G_IS_DEV && true;
|
||||
@ -404,11 +404,11 @@ export class ClickDetector {
|
||||
if (this.clickDownPosition) {
|
||||
const pos = /** @type {typeof ClickDetector} */ (this.constructor).extractPointerPosition(event);
|
||||
const distance = pos.distance(this.clickDownPosition);
|
||||
if (distance <= this.maxDistance) {
|
||||
if (!IS_MOBILE || distance <= this.maxDistance) {
|
||||
dispatchClick = true;
|
||||
dispatchClickPos = pos;
|
||||
} else {
|
||||
// console.warn("[ClickDetector] Touch does not count as click: ms=", timeSinceStart, "-> tolerance:", tolerance, "(was", distance, ")");
|
||||
console.warn("[ClickDetector] Touch does not count as click:", "(was", distance, ")");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -15,8 +15,7 @@ export const THIRDPARTY_URLS = {
|
||||
discord: "https://discord.gg/HN7EVzV",
|
||||
github: "https://github.com/tobspr/shapez.io",
|
||||
|
||||
// standaloneStorePage: "https://steam.shapez.io",
|
||||
standaloneStorePage: "https://tobspr.itch.io/shapez.io",
|
||||
standaloneStorePage: "https://store.steampowered.com/app/1318690/shapezio/",
|
||||
};
|
||||
|
||||
export const globalConfig = {
|
||||
@ -46,7 +45,7 @@ export const globalConfig = {
|
||||
// Belt speeds
|
||||
// NOTICE: Update webpack.production.config too!
|
||||
beltSpeedItemsPerSecond: 2,
|
||||
itemSpacingOnBelts: 0.63,
|
||||
itemSpacingOnBelts: 0.8,
|
||||
minerSpeedItemsPerSecond: 0, // COMPUTED
|
||||
|
||||
undergroundBeltMaxTilesByTier: [5, 8],
|
||||
@ -83,7 +82,7 @@ export const globalConfig = {
|
||||
|
||||
debug: {
|
||||
/* dev:start */
|
||||
// fastGameEnter: true,
|
||||
fastGameEnter: true,
|
||||
// noArtificialDelays: true,
|
||||
// disableSavegameWrite: true,
|
||||
// showEntityBounds: true,
|
||||
@ -95,7 +94,7 @@ export const globalConfig = {
|
||||
// rewardsInstant: true,
|
||||
allBuildingsUnlocked: true,
|
||||
blueprintsNoCost: true,
|
||||
// upgradesNoCost: true,
|
||||
upgradesNoCost: true,
|
||||
// disableUnlockDialog: true,
|
||||
// disableLogicTicks: true,
|
||||
// testClipping: true,
|
||||
@ -104,11 +103,12 @@ export const globalConfig = {
|
||||
// enableEntityInspector: true,
|
||||
// testAds: true,
|
||||
// disableMapOverview: true,
|
||||
disableTutorialHints: true,
|
||||
// disableTutorialHints: true,
|
||||
disableUpgradeNotification: true,
|
||||
// instantBelts: true,
|
||||
// instantProcessors: true,
|
||||
// instantMiners: true,
|
||||
// resumeGameOnFastEnter: false,
|
||||
|
||||
// renderForTrailer: true,
|
||||
/* dev:end */
|
||||
|
||||
@ -94,14 +94,15 @@ export class HubGoals extends BasicSerializableObject {
|
||||
|
||||
this.createNextGoal();
|
||||
|
||||
// Allow quickly switching goals in dev mode with key "C"
|
||||
// Allow quickly switching goals in dev mode
|
||||
if (G_IS_DEV) {
|
||||
this.root.gameState.inputReciever.keydown.add(key => {
|
||||
if (key.keyCode === 66) {
|
||||
// Key: b
|
||||
this.onGoalCompleted();
|
||||
}
|
||||
});
|
||||
if (G_IS_DEV) {
|
||||
window.addEventListener("keydown", ev => {
|
||||
if (ev.key === "b") {
|
||||
this.onGoalCompleted();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -28,6 +28,7 @@ import { HUDWatermark } from "./parts/watermark";
|
||||
import { HUDModalDialogs } from "./parts/modal_dialogs";
|
||||
import { HUDPartTutorialHints } from "./parts/tutorial_hints";
|
||||
import { HUDWaypoints } from "./parts/waypoints";
|
||||
import { HUDInteractiveTutorial } from "./parts/interactive_tutorial";
|
||||
|
||||
/* dev:start */
|
||||
import { TrailerMaker } from "./trailer_maker";
|
||||
@ -87,6 +88,7 @@ export class GameHUD {
|
||||
}
|
||||
if (this.root.app.settings.getAllSettings().offerHints) {
|
||||
this.parts.tutorialHints = new HUDPartTutorialHints(this.root);
|
||||
this.parts.interactiveTutorial = new HUDInteractiveTutorial(this.root);
|
||||
}
|
||||
|
||||
const frag = document.createDocumentFragment();
|
||||
|
||||
@ -5,9 +5,9 @@ import { enumNotificationType } from "./notifications";
|
||||
import { T } from "../../../translations";
|
||||
import { KEYMAPPINGS } from "../../key_action_mapper";
|
||||
import { IS_DEMO } from "../../../core/config";
|
||||
import { DynamicDomAttach } from "../dynamic_dom_attach";
|
||||
|
||||
export class HUDGameMenu extends BaseHUDPart {
|
||||
initialize() {}
|
||||
createElements(parent) {
|
||||
this.element = makeDiv(parent, "ingame_HUD_GameMenu");
|
||||
|
||||
@ -22,12 +22,16 @@ export class HUDGameMenu extends BaseHUDPart {
|
||||
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,
|
||||
},
|
||||
];
|
||||
|
||||
@ -36,14 +40,24 @@ export class HUDGameMenu extends BaseHUDPart {
|
||||
* button: HTMLElement,
|
||||
* badgeElement: HTMLElement,
|
||||
* lastRenderAmount: number,
|
||||
* condition?: function,
|
||||
* notification: [string, enumNotificationType]
|
||||
* }>} */
|
||||
this.badgesToUpdate = [];
|
||||
|
||||
buttons.forEach(({ id, label, handler, keybinding, badge, notification }) => {
|
||||
/** @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.element.appendChild(button);
|
||||
this.buttonsElement.appendChild(button);
|
||||
this.trackClicks(button, handler);
|
||||
|
||||
if (keybinding) {
|
||||
@ -52,6 +66,14 @@ export class HUDGameMenu extends BaseHUDPart {
|
||||
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({
|
||||
@ -60,6 +82,7 @@ export class HUDGameMenu extends BaseHUDPart {
|
||||
button,
|
||||
badgeElement,
|
||||
notification,
|
||||
condition: visible,
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -78,27 +101,52 @@ export class HUDGameMenu extends BaseHUDPart {
|
||||
|
||||
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 } = this.badgesToUpdate[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
|
||||
// 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);
|
||||
}
|
||||
@ -107,6 +155,7 @@ export class HUDGameMenu extends BaseHUDPart {
|
||||
if (playSound) {
|
||||
this.root.soundProxy.playUi(SOUNDS.badgeNotification);
|
||||
}
|
||||
|
||||
notifications.forEach(([notification, type]) => {
|
||||
this.root.hud.signals.notification.dispatch(notification, type);
|
||||
});
|
||||
@ -118,13 +167,6 @@ export class HUDGameMenu extends BaseHUDPart {
|
||||
}
|
||||
|
||||
startSave() {
|
||||
// if (IS_DEMO) {
|
||||
// this.root.hud.parts.dialogs.showFeatureRestrictionInfo(
|
||||
// null,
|
||||
// T.dialogs.saveNotPossibleInDemo.desc
|
||||
// );
|
||||
// }
|
||||
|
||||
this.root.gameState.doSave();
|
||||
}
|
||||
|
||||
|
||||
81
src/js/game/hud/parts/interactive_tutorial.js
Normal file
@ -0,0 +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">Tutorial</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);
|
||||
}
|
||||
}
|
||||
@ -23,10 +23,6 @@ export class HUDKeybindingOverlay extends BaseHUDPart {
|
||||
"ingame_HUD_KeybindingOverlay",
|
||||
[],
|
||||
`
|
||||
<div class="binding">
|
||||
<code class="keybinding">${getKeycode(KEYMAPPINGS.navigation.createMarker)}</code>
|
||||
<label>${T.ingame.keybindingsOverlay.createMarker}</label>
|
||||
</div>
|
||||
|
||||
<div class="binding">
|
||||
<code class="keybinding leftMouse noPlacementOnly"></code><i class="noPlacementOnly"></i>
|
||||
@ -35,8 +31,15 @@ export class HUDKeybindingOverlay extends BaseHUDPart {
|
||||
<code class="keybinding">${getKeycode(KEYMAPPINGS.navigation.mapMoveDown)}</code>
|
||||
<code class="keybinding">${getKeycode(KEYMAPPINGS.navigation.mapMoveRight)}</code>
|
||||
<label>${T.ingame.keybindingsOverlay.moveMap}</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="binding noPlacementOnly">
|
||||
<code class="keybinding rightMouse"></code>
|
||||
<label>${T.ingame.keybindingsOverlay.delete}</label>
|
||||
</div>
|
||||
|
||||
<div class="binding noPlacementOnly">
|
||||
<code class="keybinding builtinKey">${getKeycode(
|
||||
KEYMAPPINGS.massSelect.massSelectStart
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import { cachebust } from "../../../core/cachebust";
|
||||
import { InputReceiver } from "../../../core/input_receiver";
|
||||
import { TrackedState } from "../../../core/tracked_state";
|
||||
import { makeDiv } from "../../../core/utils";
|
||||
@ -6,9 +5,8 @@ import { KeyActionMapper, KEYMAPPINGS } from "../../key_action_mapper";
|
||||
import { BaseHUDPart } from "../base_hud_part";
|
||||
import { DynamicDomAttach } from "../dynamic_dom_attach";
|
||||
import { T } from "../../../translations";
|
||||
import { globalConfig } from "../../../core/config";
|
||||
|
||||
const tutorialVideos = [1, 2, 3, 4, 5, 6, 7, 9, 10, 11];
|
||||
const tutorialVideos = [2, 3, 4, 5, 6, 7, 9, 10, 11];
|
||||
|
||||
export class HUDPartTutorialHints extends BaseHUDPart {
|
||||
createElements(parent) {
|
||||
@ -55,15 +53,6 @@ export class HUDPartTutorialHints extends BaseHUDPart {
|
||||
this.domAttach = new DynamicDomAttach(this.root, this.element);
|
||||
|
||||
this.currentShownLevel = new TrackedState(this.updateVideoUrl, this);
|
||||
|
||||
this.root.signals.postLoadHook.add(() => {
|
||||
if (this.root.hubGoals.level === 1 && !(G_IS_DEV && globalConfig.debug.disableTutorialHints)) {
|
||||
this.root.hud.parts.dialogs.showInfo(
|
||||
T.dialogs.hintDescription.title,
|
||||
T.dialogs.hintDescription.desc
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
updateVideoUrl(level) {
|
||||
|
||||
@ -28,7 +28,7 @@ export class HUDUnlockNotification extends BaseHUDPart {
|
||||
createElements(parent) {
|
||||
this.inputReciever = new InputReceiver("unlock-notification");
|
||||
|
||||
this.element = makeDiv(parent, "ingame_HUD_UnlockNotification", []);
|
||||
this.element = makeDiv(parent, "ingame_HUD_UnlockNotification", ["noBlur"]);
|
||||
|
||||
const dialog = makeDiv(this.element, null, ["dialog"]);
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@ export class HUDWatermark extends BaseHUDPart {
|
||||
}
|
||||
|
||||
onWatermarkClick() {
|
||||
this.root.app.analytics.trackUiClick("watermark_click");
|
||||
this.root.app.analytics.trackUiClick("watermark_click_2");
|
||||
this.root.app.platformWrapper.openExternalLink(THIRDPARTY_URLS.standaloneStorePage);
|
||||
}
|
||||
|
||||
|
||||
@ -133,11 +133,6 @@ export class HUDWaypoints extends BaseHUDPart {
|
||||
* @param {Vector=} worldPos Override the world pos, otherwise it is the camera position
|
||||
*/
|
||||
requestCreateMarker(worldPos = null) {
|
||||
if (IS_DEMO) {
|
||||
this.root.hud.parts.dialogs.showFeatureRestrictionInfo(T.demo.features.creatingMarkers);
|
||||
return;
|
||||
}
|
||||
|
||||
const markerNameInput = new FormElementInput({
|
||||
id: "markerName",
|
||||
label: null,
|
||||
@ -157,6 +152,11 @@ export class HUDWaypoints extends BaseHUDPart {
|
||||
const center = worldPos || this.root.camera.center;
|
||||
|
||||
dialog.buttonSignals.ok.add(() => {
|
||||
if (IS_DEMO && this.waypoints.length > 2) {
|
||||
this.root.hud.parts.dialogs.showFeatureRestrictionInfo("", T.dialogs.markerDemoLimit.desc);
|
||||
return;
|
||||
}
|
||||
|
||||
this.waypoints.push({
|
||||
label: markerNameInput.getValue(),
|
||||
center: { x: center.x, y: center.y },
|
||||
|
||||
@ -35,7 +35,7 @@ export const tutorialGoals = [
|
||||
// Circle
|
||||
{
|
||||
shape: "CuCuCuCu", // belts t1
|
||||
required: 20,
|
||||
required: 40,
|
||||
reward: enumHubGoalRewards.reward_cutter_and_trash,
|
||||
},
|
||||
|
||||
|
||||
@ -18,6 +18,36 @@ if (window.coreThreadLoadedCb) {
|
||||
window.coreThreadLoadedCb();
|
||||
}
|
||||
|
||||
if (!G_IS_DEV && !G_IS_STANDALONE) {
|
||||
const monthlyUsers = 300; // thousand
|
||||
const logrocketLimit = 10; // thousand
|
||||
const percentageOfUsers = logrocketLimit / monthlyUsers;
|
||||
|
||||
if (Math.random() <= percentageOfUsers) {
|
||||
logger.log("Analyzing this session with logrocket");
|
||||
const logrocket = require("logrocket");
|
||||
logrocket.init("p1x9zh/shapezio");
|
||||
|
||||
try {
|
||||
logrocket.getSessionURL(function (sessionURL) {
|
||||
logger.log("Connected lockrocket to GA");
|
||||
// @ts-ignore
|
||||
try {
|
||||
window.ga("send", {
|
||||
hitType: "event",
|
||||
eventCategory: "LogRocket",
|
||||
eventAction: sessionURL,
|
||||
});
|
||||
} catch (ex) {
|
||||
logger.warn("Logrocket connection to analytics failed:", ex);
|
||||
}
|
||||
});
|
||||
} catch (ex) {
|
||||
logger.warn("Logrocket connection to analytics failed:", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(
|
||||
`%cshapez.io ️%c\n© 2020 Tobias Springer IT Solutions\nCommit %c${G_BUILD_COMMIT_HASH}%c on %c${new Date(
|
||||
G_BUILD_TIME
|
||||
|
||||
@ -1,11 +1,13 @@
|
||||
import { Math_min } from "../../core/builtins";
|
||||
import { globalConfig, IS_MOBILE, IS_DEBUG, IS_DEMO } from "../../core/config";
|
||||
import { globalConfig, IS_DEMO, IS_MOBILE } from "../../core/config";
|
||||
import { createLogger } from "../../core/logging";
|
||||
import { queryParamOptions } from "../../core/query_parameters";
|
||||
import { clamp } from "../../core/utils";
|
||||
import { GamedistributionAdProvider } from "../ad_providers/gamedistribution";
|
||||
import { NoAdProvider } from "../ad_providers/no_ad_provider";
|
||||
import { PlatformWrapperInterface } from "../wrapper";
|
||||
import { GamedistributionAdProvider } from "../ad_providers/gamedistribution";
|
||||
import { StorageImplBrowser } from "./storage";
|
||||
import { StorageImplBrowserIndexedDB } from "./storage_indexed_db";
|
||||
|
||||
const logger = createLogger("platform/browser");
|
||||
|
||||
@ -72,7 +74,43 @@ export class PlatformWrapperImplBrowser extends PlatformWrapperInterface {
|
||||
|
||||
logger.log("Embed provider:", this.embedProvider.id);
|
||||
|
||||
return super.initialize().then(() => this.initializeAdProvider());
|
||||
return this.detectStorageImplementation()
|
||||
.then(() => this.initializeAdProvider())
|
||||
.then(() => super.initialize());
|
||||
}
|
||||
|
||||
detectStorageImplementation() {
|
||||
return new Promise(resolve => {
|
||||
logger.log("Detecting storage");
|
||||
|
||||
if (!window.indexedDB) {
|
||||
logger.log("Indexed DB not supported");
|
||||
this.app.storage = new StorageImplBrowser(this.app);
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
// Try accessing the indexedb
|
||||
let request;
|
||||
try {
|
||||
request = window.indexedDB.open("indexeddb_feature_detection", 1);
|
||||
} catch (ex) {
|
||||
logger.warn("Error while opening indexed db:", ex);
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
request.onerror = err => {
|
||||
logger.log("Indexed DB can *not* be accessed: ", err);
|
||||
logger.log("Using fallback to local storage");
|
||||
this.app.storage = new StorageImplBrowser(this.app);
|
||||
resolve();
|
||||
};
|
||||
request.onsuccess = () => {
|
||||
logger.log("Indexed DB *can* be accessed");
|
||||
this.app.storage = new StorageImplBrowserIndexedDB(this.app);
|
||||
resolve();
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
getHasUnlimitedSavegames() {
|
||||
@ -83,71 +121,6 @@ export class PlatformWrapperImplBrowser extends PlatformWrapperInterface {
|
||||
return this.embedProvider.showDemoBadge;
|
||||
}
|
||||
|
||||
onSentryLoaded() {
|
||||
logger.log("Initializing sentry");
|
||||
window.Sentry.init({
|
||||
dsn: "TODO SENTRY DSN",
|
||||
release: G_APP_ENVIRONMENT + "-" + G_BUILD_VERSION + "@" + G_BUILD_COMMIT_HASH,
|
||||
// Will cause a deprecation warning, but the demise of `ignoreErrors` is still under discussion.
|
||||
// See: https://github.com/getsentry/raven-js/issues/73
|
||||
ignoreErrors: [
|
||||
// Random plugins/extensions
|
||||
"top.GLOBALS",
|
||||
// See: http://blog.errorception.com/2012/03/tale-of-unfindable-js-error.html
|
||||
"originalCreateNotification",
|
||||
"canvas.contentDocument",
|
||||
"MyApp_RemoveAllHighlights",
|
||||
"http://tt.epicplay.com",
|
||||
"Can't find variable: ZiteReader",
|
||||
"jigsaw is not defined",
|
||||
"ComboSearch is not defined",
|
||||
"http://loading.retry.widdit.com/",
|
||||
"atomicFindClose",
|
||||
// Facebook borked
|
||||
"fb_xd_fragment",
|
||||
// ISP "optimizing" proxy - `Cache-Control: no-transform` seems to reduce this. (thanks @acdha)
|
||||
// See http://stackoverflow.com/questions/4113268/how-to-stop-javascript-injection-from-vodafone-proxy
|
||||
"bmi_SafeAddOnload",
|
||||
"EBCallBackMessageReceived",
|
||||
// See http://toolbar.conduit.com/Developer/HtmlAndGadget/Methods/JSInjection.aspx
|
||||
"conduitPage",
|
||||
// Generic error code from errors outside the security sandbox
|
||||
// You can delete this if using raven.js > 1.0, which ignores these automatically.
|
||||
"Script error.",
|
||||
|
||||
// Errors from ads
|
||||
"Cannot read property 'postMessage' of null",
|
||||
|
||||
// Firefox only
|
||||
"AbortError: The operation was aborted.",
|
||||
|
||||
"<unknown>",
|
||||
],
|
||||
ignoreUrls: [
|
||||
// Facebook flakiness
|
||||
/graph\.facebook\.com/i,
|
||||
// Facebook blocked
|
||||
/connect\.facebook\.net\/en_US\/all\.js/i,
|
||||
// Woopra flakiness
|
||||
/eatdifferent\.com\.woopra-ns\.com/i,
|
||||
/static\.woopra\.com\/js\/woopra\.js/i,
|
||||
// Chrome extensions
|
||||
/extensions\//i,
|
||||
/^chrome:\/\//i,
|
||||
// Other plugins
|
||||
/127\.0\.0\.1:4001\/isrunning/i, // Cacaoweb
|
||||
/webappstoolbarba\.texthelp\.com\//i,
|
||||
/metrics\.itunes\.apple\.com\.edgesuite\.net\//i,
|
||||
],
|
||||
beforeSend(event, hint) {
|
||||
if (window.anyModLoaded) {
|
||||
return null;
|
||||
}
|
||||
return event;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
getId() {
|
||||
return "browser@" + this.embedProvider.id;
|
||||
}
|
||||
|
||||
@ -1,10 +1,17 @@
|
||||
import { PlatformWrapperImplBrowser } from "../browser/wrapper";
|
||||
import { getIPCRenderer } from "../../core/utils";
|
||||
import { createLogger } from "../../core/logging";
|
||||
import { StorageImplElectron } from "./storage";
|
||||
import { PlatformWrapperInterface } from "../wrapper";
|
||||
|
||||
const logger = createLogger("electron-wrapper");
|
||||
|
||||
export class PlatformWrapperImplElectron extends PlatformWrapperImplBrowser {
|
||||
initialize() {
|
||||
this.app.storage = new StorageImplElectron(this);
|
||||
return PlatformWrapperInterface.prototype.initialize.call(this);
|
||||
}
|
||||
|
||||
getId() {
|
||||
return "electron";
|
||||
}
|
||||
@ -22,6 +29,14 @@ export class PlatformWrapperImplElectron extends PlatformWrapperImplBrowser {
|
||||
return false;
|
||||
}
|
||||
|
||||
getHasUnlimitedSavegames() {
|
||||
return true;
|
||||
}
|
||||
|
||||
getShowDemoBadges() {
|
||||
return false;
|
||||
}
|
||||
|
||||
performRestart() {
|
||||
logger.log(this, "Performing restart");
|
||||
window.location.reload(true);
|
||||
|
||||
@ -24,14 +24,11 @@ export class MainMenuState extends GameState {
|
||||
|
||||
<p>${T.demoBanners.intro}</p>
|
||||
|
||||
<ul>
|
||||
${T.demoBanners.advantages.map(advantage => `<li>${advantage}</li>`).join("")}
|
||||
</ul>
|
||||
|
||||
<a href="#" class="steamLink" target="_blank">Get the shapez.io standalone!</a>
|
||||
`;
|
||||
|
||||
return `
|
||||
return (
|
||||
`
|
||||
|
||||
<button class="settingsButton"></button>
|
||||
|
||||
@ -54,18 +51,29 @@ export class MainMenuState extends GameState {
|
||||
|
||||
<div class="logo">
|
||||
<img src="${cachebust("res/logo.png")}" alt="shapez.io Logo">
|
||||
${
|
||||
IS_DEMO && this.app.platformWrapper.getShowDemoBadges()
|
||||
? `<div class="demoBadge"></div>`
|
||||
: ""
|
||||
}
|
||||
</div>
|
||||
|
||||
|
||||
<div class="mainWrapper ${IS_DEMO ? "demo" : "noDemo"}">
|
||||
|
||||
${IS_DEMO ? `<div class="standaloneBanner">${bannerHtml}</div>` : ""}
|
||||
|
||||
<div class="sideContainer">
|
||||
${IS_DEMO ? `<div class="standaloneBanner">${bannerHtml}</div>` : ""}
|
||||
|
||||
<div class="contest">
|
||||
<h3>${T.mainMenu.contests.contest_01_03062020.title}</h3>
|
||||
` +
|
||||
/*<p>${T.mainMenu.contests.contest_01_03062020.desc}</p>
|
||||
<button class="styledButton participateContest">${
|
||||
T.mainMenu.contests.showInfo
|
||||
}</button>*/
|
||||
|
||||
`
|
||||
<p>${T.mainMenu.contests.contestOver}</p>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="mainContainer">
|
||||
${
|
||||
isSupportedBrowser()
|
||||
@ -104,7 +112,8 @@ export class MainMenuState extends GameState {
|
||||
<div class="author">Made by <a class="producerLink" target="_blank">Tobias Springer</a></div>
|
||||
|
||||
</div>
|
||||
`;
|
||||
`
|
||||
);
|
||||
}
|
||||
|
||||
requestImportSavegame() {
|
||||
@ -199,7 +208,7 @@ export class MainMenuState extends GameState {
|
||||
|
||||
if (G_IS_DEV && globalConfig.debug.fastGameEnter) {
|
||||
const games = this.app.savegameMgr.getSavegamesMetaData();
|
||||
if (games.length > 0) {
|
||||
if (games.length > 0 && globalConfig.debug.resumeGameOnFastEnter) {
|
||||
this.resumeGame(games[0]);
|
||||
} else {
|
||||
this.onPlayButtonClicked();
|
||||
@ -220,6 +229,11 @@ export class MainMenuState extends GameState {
|
||||
this.trackClicks(qs(".settingsButton"), this.onSettingsButtonClicked);
|
||||
this.trackClicks(qs(".changelog"), this.onChangelogClicked);
|
||||
|
||||
const contestButton = qs(".participateContest");
|
||||
if (contestButton) {
|
||||
this.trackClicks(contestButton, this.onContestClicked);
|
||||
}
|
||||
|
||||
if (G_IS_STANDALONE) {
|
||||
this.trackClicks(qs(".exitAppButton"), this.onExitAppButtonClicked);
|
||||
}
|
||||
@ -254,7 +268,7 @@ export class MainMenuState extends GameState {
|
||||
}
|
||||
|
||||
onSteamLinkClicked() {
|
||||
this.app.analytics.trackUiClick("main_menu_steam_link");
|
||||
this.app.analytics.trackUiClick("main_menu_steam_link_2");
|
||||
this.app.platformWrapper.openExternalLink(THIRDPARTY_URLS.standaloneStorePage);
|
||||
return false;
|
||||
}
|
||||
@ -267,6 +281,15 @@ export class MainMenuState extends GameState {
|
||||
this.moveToState("ChangelogState");
|
||||
}
|
||||
|
||||
onContestClicked() {
|
||||
this.app.analytics.trackUiClick("contest_click");
|
||||
|
||||
this.dialogs.showInfo(
|
||||
T.mainMenu.contests.contest_01_03062020.title,
|
||||
T.mainMenu.contests.contest_01_03062020.longDesc
|
||||
);
|
||||
}
|
||||
|
||||
renderSavegames() {
|
||||
const oldContainer = this.htmlElement.querySelector(".mainContainer .savegames");
|
||||
if (oldContainer) {
|
||||
@ -375,19 +398,6 @@ export class MainMenuState extends GameState {
|
||||
this.moveToState("SettingsState");
|
||||
}
|
||||
|
||||
doStartNewGame() {
|
||||
this.app.analytics.trackUiClick("startgame");
|
||||
|
||||
this.app.adProvider.showVideoAd().then(() => {
|
||||
const savegame = this.app.savegameMgr.createNewSavegame();
|
||||
|
||||
this.moveToState("InGameState", {
|
||||
savegame,
|
||||
});
|
||||
this.app.analytics.trackUiClick("startgame_adcomplete");
|
||||
});
|
||||
}
|
||||
|
||||
onPlayButtonClicked() {
|
||||
if (
|
||||
IS_DEMO &&
|
||||
@ -399,17 +409,15 @@ export class MainMenuState extends GameState {
|
||||
return;
|
||||
}
|
||||
|
||||
if (IS_DEMO) {
|
||||
this.app.analytics.trackUiClick("startgame_pre_show");
|
||||
const { ok } = this.dialogs.showWarning(
|
||||
T.dialogs.demoExplanation.title,
|
||||
T.dialogs.demoExplanation.desc
|
||||
);
|
||||
ok.add(() => this.doStartNewGame());
|
||||
return;
|
||||
}
|
||||
this.app.analytics.trackUiClick("startgame");
|
||||
this.app.adProvider.showVideoAd().then(() => {
|
||||
const savegame = this.app.savegameMgr.createNewSavegame();
|
||||
|
||||
this.doStartNewGame();
|
||||
this.moveToState("InGameState", {
|
||||
savegame,
|
||||
});
|
||||
this.app.analytics.trackUiClick("startgame_adcomplete");
|
||||
});
|
||||
}
|
||||
|
||||
onLeave() {
|
||||
|
||||
@ -13,11 +13,11 @@ export class MobileWarningState extends GameState {
|
||||
<img class="logo" src="${cachebust("res/logo.png")}" alt="shapez.io Logo">
|
||||
|
||||
<p>
|
||||
I'm sorry, but shapez.io is not yet available on mobile devices!
|
||||
(There is also no estimate when this will change, but feel to make a contribution! It's
|
||||
<a href="https://github.com/tobspr/shapez.io" target="_blank">open source</a>!)</p>
|
||||
I'm sorry, but shapez.io is not available on mobile devices yet!
|
||||
There is also no estimate when this will change, but feel to make a contribution! It's
|
||||
<a href="https://github.com/tobspr/shapez.io" target="_blank">open source</a>!</p>
|
||||
|
||||
<p>If you want to play on your computer, you can also get the standalone on itch.io:</p>
|
||||
<p>If you want to play on your computer, you can also get the standalone on steam:</p>
|
||||
|
||||
|
||||
<a href="${
|
||||
|
||||
@ -82,18 +82,14 @@ export class PreloadState extends GameState {
|
||||
.then(res => res.json())
|
||||
.then(({ latest }) => {
|
||||
if (latest !== G_BUILD_VERSION) {
|
||||
const { ok, viewUpdate } = this.dialogs.showInfo(
|
||||
const { ok } = this.dialogs.showInfo(
|
||||
T.dialogs.newUpdate.title,
|
||||
T.dialogs.newUpdate.desc,
|
||||
["ok:good", "viewUpdate:good"]
|
||||
["ok:good"]
|
||||
);
|
||||
|
||||
return new Promise(resolve => {
|
||||
ok.add(resolve);
|
||||
viewUpdate.add(() => {
|
||||
window.open("https://tobspr.itch.io/shapezio", "_blank");
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
@ -1,81 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
shapez.io shape generator
|
||||
</title>
|
||||
|
||||
<script async src="index.js"></script>
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
}
|
||||
body {
|
||||
font-family: "Source Sans Pro", "Roboto", sans-serif;
|
||||
background: #fafafa;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
#resultWrapper {
|
||||
border: 1px solid #ccc;
|
||||
margin-top: 10px;
|
||||
background: #fff;
|
||||
padding: 40px;
|
||||
}
|
||||
|
||||
#resultWrapper #result {
|
||||
}
|
||||
|
||||
#code {
|
||||
width: 600px;
|
||||
font-family: monospace;
|
||||
padding: 30px;
|
||||
border: 1px solid #ccc;
|
||||
background: #fff;
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
#code:focus {
|
||||
outline: none;
|
||||
border-color: #39f;
|
||||
}
|
||||
|
||||
#error {
|
||||
height: 40px;
|
||||
color: #f77;
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
text-align: left;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#error:not(.hasError) {
|
||||
color: rgb(71, 179, 71);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Shape generator</h2>
|
||||
<input
|
||||
value="CuCuCuCu"
|
||||
id="code"
|
||||
placeholder="shape code"
|
||||
onkeypress="debounce(generate)"
|
||||
onkeydown="debounce(generate)"
|
||||
onkeyup="debounce(generate)"
|
||||
onchange="debounce(generate)"
|
||||
/>
|
||||
<div id="error">Error</div>
|
||||
<br />
|
||||
|
||||
<div id="resultWrapper">
|
||||
<canvas id="result" width="256" height="256"></canvas>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@ -1,301 +0,0 @@
|
||||
/*
|
||||
* Lots of code here is copied 1:1 from actual game files
|
||||
*
|
||||
*/
|
||||
|
||||
/** @enum {string} */
|
||||
const enumSubShape = {
|
||||
rect: "rect",
|
||||
circle: "circle",
|
||||
star: "star",
|
||||
windmill: "windmill",
|
||||
};
|
||||
|
||||
/** @enum {string} */
|
||||
const enumSubShapeToShortcode = {
|
||||
[enumSubShape.rect]: "R",
|
||||
[enumSubShape.circle]: "C",
|
||||
[enumSubShape.star]: "S",
|
||||
[enumSubShape.windmill]: "W",
|
||||
};
|
||||
|
||||
/** @enum {enumSubShape} */
|
||||
const enumShortcodeToSubShape = {};
|
||||
for (const key in enumSubShapeToShortcode) {
|
||||
enumShortcodeToSubShape[enumSubShapeToShortcode[key]] = key;
|
||||
}
|
||||
|
||||
const arrayQuadrantIndexToOffset = [
|
||||
{ x: 1, y: -1 }, // tr
|
||||
{ x: 1, y: 1 }, // br
|
||||
{ x: -1, y: 1 }, // bl
|
||||
{ x: -1, y: -1 }, // tl
|
||||
];
|
||||
|
||||
// From colors.js
|
||||
/** @enum {string} */
|
||||
const enumColors = {
|
||||
red: "red",
|
||||
green: "green",
|
||||
blue: "blue",
|
||||
|
||||
yellow: "yellow",
|
||||
purple: "purple",
|
||||
cyan: "cyan",
|
||||
|
||||
white: "white",
|
||||
uncolored: "uncolored",
|
||||
};
|
||||
|
||||
/** @enum {string} */
|
||||
const enumColorToShortcode = {
|
||||
[enumColors.red]: "r",
|
||||
[enumColors.green]: "g",
|
||||
[enumColors.blue]: "b",
|
||||
|
||||
[enumColors.yellow]: "y",
|
||||
[enumColors.purple]: "p",
|
||||
[enumColors.cyan]: "c",
|
||||
|
||||
[enumColors.white]: "w",
|
||||
[enumColors.uncolored]: "u",
|
||||
};
|
||||
|
||||
/** @enum {string} */
|
||||
const enumColorsToHexCode = {
|
||||
[enumColors.red]: "#ff666a",
|
||||
[enumColors.green]: "#78ff66",
|
||||
[enumColors.blue]: "#66a7ff",
|
||||
|
||||
// red + green
|
||||
[enumColors.yellow]: "#fcf52a",
|
||||
|
||||
// red + blue
|
||||
[enumColors.purple]: "#dd66ff",
|
||||
|
||||
// blue + green
|
||||
[enumColors.cyan]: "#87fff5",
|
||||
|
||||
// blue + green + red
|
||||
[enumColors.white]: "#ffffff",
|
||||
|
||||
[enumColors.uncolored]: "#aaaaaa",
|
||||
};
|
||||
|
||||
/** @enum {enumColors} */
|
||||
const enumShortcodeToColor = {};
|
||||
for (const key in enumColorToShortcode) {
|
||||
enumShortcodeToColor[enumColorToShortcode[key]] = key;
|
||||
}
|
||||
|
||||
CanvasRenderingContext2D.prototype.beginCircle = function (x, y, r) {
|
||||
if (r < 0.05) {
|
||||
this.beginPath();
|
||||
this.rect(x, y, 1, 1);
|
||||
return;
|
||||
}
|
||||
this.beginPath();
|
||||
this.arc(x, y, r, 0, 2.0 * Math.PI);
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
function radians(degrees) {
|
||||
return (degrees * Math.PI) / 180.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the definition from the given short key
|
||||
*/
|
||||
function fromShortKey(key) {
|
||||
const sourceLayers = key.split(":");
|
||||
let layers = [];
|
||||
for (let i = 0; i < sourceLayers.length; ++i) {
|
||||
const text = sourceLayers[i];
|
||||
if (text.length !== 8) {
|
||||
throw new Error("Invalid layer: '" + text + "' -> must be 8 characters");
|
||||
}
|
||||
|
||||
const quads = [null, null, null, null];
|
||||
for (let quad = 0; quad < 4; ++quad) {
|
||||
const shapeText = text[quad * 2 + 0];
|
||||
const subShape = enumShortcodeToSubShape[shapeText];
|
||||
const color = enumShortcodeToColor[text[quad * 2 + 1]];
|
||||
if (subShape) {
|
||||
if (!color) {
|
||||
throw new Error("Invalid shape color key: " + key);
|
||||
}
|
||||
quads[quad] = {
|
||||
subShape,
|
||||
color,
|
||||
};
|
||||
} else if (shapeText !== "-") {
|
||||
throw new Error("Invalid shape key: " + shapeText);
|
||||
}
|
||||
}
|
||||
layers.push(quads);
|
||||
}
|
||||
|
||||
return layers;
|
||||
}
|
||||
|
||||
function renderShape(layers) {
|
||||
const canvas = /** @type {HTMLCanvasElement} */ (document.getElementById("result"));
|
||||
const context = canvas.getContext("2d");
|
||||
|
||||
context.save();
|
||||
context.fillStyle = "#fff";
|
||||
context.fillRect(0, 0, 1000, 1000);
|
||||
|
||||
const w = 256;
|
||||
const h = 256;
|
||||
const dpi = 1;
|
||||
|
||||
context.translate((w * dpi) / 2, (h * dpi) / 2);
|
||||
context.scale((dpi * w) / 23, (dpi * h) / 23);
|
||||
|
||||
context.fillStyle = "#e9ecf7";
|
||||
|
||||
const quadrantSize = 10;
|
||||
const quadrantHalfSize = quadrantSize / 2;
|
||||
|
||||
context.fillStyle = "rgba(40, 50, 65, 0.1)";
|
||||
context.beginCircle(0, 0, quadrantSize * 1.15);
|
||||
context.fill();
|
||||
|
||||
for (let layerIndex = 0; layerIndex < layers.length; ++layerIndex) {
|
||||
const quadrants = layers[layerIndex];
|
||||
|
||||
const layerScale = Math.max(0.1, 0.9 - layerIndex * 0.22);
|
||||
|
||||
for (let quadrantIndex = 0; quadrantIndex < 4; ++quadrantIndex) {
|
||||
if (!quadrants[quadrantIndex]) {
|
||||
continue;
|
||||
}
|
||||
const { subShape, color } = quadrants[quadrantIndex];
|
||||
|
||||
const quadrantPos = arrayQuadrantIndexToOffset[quadrantIndex];
|
||||
const centerQuadrantX = quadrantPos.x * quadrantHalfSize;
|
||||
const centerQuadrantY = quadrantPos.y * quadrantHalfSize;
|
||||
|
||||
const rotation = radians(quadrantIndex * 90);
|
||||
|
||||
context.translate(centerQuadrantX, centerQuadrantY);
|
||||
context.rotate(rotation);
|
||||
|
||||
context.fillStyle = enumColorsToHexCode[color];
|
||||
context.strokeStyle = "#555";
|
||||
context.lineWidth = 1;
|
||||
|
||||
const insetPadding = 0.0;
|
||||
|
||||
switch (subShape) {
|
||||
case enumSubShape.rect: {
|
||||
context.beginPath();
|
||||
const dims = quadrantSize * layerScale;
|
||||
context.rect(
|
||||
insetPadding + -quadrantHalfSize,
|
||||
-insetPadding + quadrantHalfSize - dims,
|
||||
dims,
|
||||
dims
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
case enumSubShape.star: {
|
||||
context.beginPath();
|
||||
const dims = quadrantSize * layerScale;
|
||||
|
||||
let originX = insetPadding - quadrantHalfSize;
|
||||
let originY = -insetPadding + quadrantHalfSize - dims;
|
||||
|
||||
const moveInwards = dims * 0.4;
|
||||
context.moveTo(originX, originY + moveInwards);
|
||||
context.lineTo(originX + dims, originY);
|
||||
context.lineTo(originX + dims - moveInwards, originY + dims);
|
||||
context.lineTo(originX, originY + dims);
|
||||
context.closePath();
|
||||
break;
|
||||
}
|
||||
|
||||
case enumSubShape.windmill: {
|
||||
context.beginPath();
|
||||
const dims = quadrantSize * layerScale;
|
||||
|
||||
let originX = insetPadding - quadrantHalfSize;
|
||||
let originY = -insetPadding + quadrantHalfSize - dims;
|
||||
const moveInwards = dims * 0.4;
|
||||
context.moveTo(originX, originY + moveInwards);
|
||||
context.lineTo(originX + dims, originY);
|
||||
context.lineTo(originX + dims, originY + dims);
|
||||
context.lineTo(originX, originY + dims);
|
||||
context.closePath();
|
||||
break;
|
||||
}
|
||||
|
||||
case enumSubShape.circle: {
|
||||
context.beginPath();
|
||||
context.moveTo(insetPadding + -quadrantHalfSize, -insetPadding + quadrantHalfSize);
|
||||
context.arc(
|
||||
insetPadding + -quadrantHalfSize,
|
||||
-insetPadding + quadrantHalfSize,
|
||||
quadrantSize * layerScale,
|
||||
-Math.PI * 0.5,
|
||||
0
|
||||
);
|
||||
context.closePath();
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
assertAlways(false, "Unkown sub shape: " + subShape);
|
||||
}
|
||||
}
|
||||
|
||||
context.fill();
|
||||
context.stroke();
|
||||
|
||||
context.rotate(-rotation);
|
||||
context.translate(-centerQuadrantX, -centerQuadrantY);
|
||||
}
|
||||
}
|
||||
|
||||
context.restore();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
function showError(msg) {
|
||||
const errorDiv = document.getElementById("error");
|
||||
errorDiv.classList.toggle("hasError", !!msg);
|
||||
if (msg) {
|
||||
errorDiv.innerText = msg;
|
||||
} else {
|
||||
errorDiv.innerText = "Shape generated";
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
window.generate = () => {
|
||||
showError(null);
|
||||
// @ts-ignore
|
||||
const code = document.getElementById("code").value.trim();
|
||||
|
||||
let parsed = null;
|
||||
try {
|
||||
parsed = fromShortKey(code);
|
||||
} catch (ex) {
|
||||
showError(ex);
|
||||
return;
|
||||
}
|
||||
|
||||
renderShape(parsed);
|
||||
};
|
||||
|
||||
// @ts-ignore
|
||||
window.debounce = fn => {
|
||||
setTimeout(fn, 0);
|
||||
};
|
||||
|
||||
// @ts-ignore
|
||||
window.addEventListener("load", window.generate);
|
||||
@ -1,13 +0,0 @@
|
||||
{
|
||||
"name": "shape_generator",
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"http-server": "^0.12.3"
|
||||
},
|
||||
"scripts": {
|
||||
"serve": "http-server . -p 9000 -g --cors -o -c-1"
|
||||
}
|
||||
}
|
||||
@ -1,152 +0,0 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
async@^2.6.2:
|
||||
version "2.6.3"
|
||||
resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff"
|
||||
integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==
|
||||
dependencies:
|
||||
lodash "^4.17.14"
|
||||
|
||||
basic-auth@^1.0.3:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-1.1.0.tgz#45221ee429f7ee1e5035be3f51533f1cdfd29884"
|
||||
integrity sha1-RSIe5Cn37h5QNb4/UVM/HN/SmIQ=
|
||||
|
||||
colors@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78"
|
||||
integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==
|
||||
|
||||
corser@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/corser/-/corser-2.0.1.tgz#8eda252ecaab5840dcd975ceb90d9370c819ff87"
|
||||
integrity sha1-jtolLsqrWEDc2XXOuQ2TcMgZ/4c=
|
||||
|
||||
debug@^3.0.0, debug@^3.1.1:
|
||||
version "3.2.6"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
|
||||
integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
|
||||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
ecstatic@^3.3.2:
|
||||
version "3.3.2"
|
||||
resolved "https://registry.yarnpkg.com/ecstatic/-/ecstatic-3.3.2.tgz#6d1dd49814d00594682c652adb66076a69d46c48"
|
||||
integrity sha512-fLf9l1hnwrHI2xn9mEDT7KIi22UDqA2jaCwyCbSUJh9a1V+LEUSL/JO/6TIz/QyuBURWUHrFL5Kg2TtO1bkkog==
|
||||
dependencies:
|
||||
he "^1.1.1"
|
||||
mime "^1.6.0"
|
||||
minimist "^1.1.0"
|
||||
url-join "^2.0.5"
|
||||
|
||||
eventemitter3@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.0.tgz#d65176163887ee59f386d64c82610b696a4a74eb"
|
||||
integrity sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==
|
||||
|
||||
follow-redirects@^1.0.0:
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.11.0.tgz#afa14f08ba12a52963140fe43212658897bc0ecb"
|
||||
integrity sha512-KZm0V+ll8PfBrKwMzdo5D13b1bur9Iq9Zd/RMmAoQQcl2PxxFml8cxXPaaPYVbV0RjNjq1CU7zIzAOqtUPudmA==
|
||||
dependencies:
|
||||
debug "^3.0.0"
|
||||
|
||||
he@^1.1.1:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
|
||||
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
|
||||
|
||||
http-proxy@^1.18.0:
|
||||
version "1.18.0"
|
||||
resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.0.tgz#dbe55f63e75a347db7f3d99974f2692a314a6a3a"
|
||||
integrity sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ==
|
||||
dependencies:
|
||||
eventemitter3 "^4.0.0"
|
||||
follow-redirects "^1.0.0"
|
||||
requires-port "^1.0.0"
|
||||
|
||||
http-server@^0.12.3:
|
||||
version "0.12.3"
|
||||
resolved "https://registry.yarnpkg.com/http-server/-/http-server-0.12.3.tgz#ba0471d0ecc425886616cb35c4faf279140a0d37"
|
||||
integrity sha512-be0dKG6pni92bRjq0kvExtj/NrrAd28/8fCXkaI/4piTwQMSDSLMhWyW0NI1V+DBI3aa1HMlQu46/HjVLfmugA==
|
||||
dependencies:
|
||||
basic-auth "^1.0.3"
|
||||
colors "^1.4.0"
|
||||
corser "^2.0.1"
|
||||
ecstatic "^3.3.2"
|
||||
http-proxy "^1.18.0"
|
||||
minimist "^1.2.5"
|
||||
opener "^1.5.1"
|
||||
portfinder "^1.0.25"
|
||||
secure-compare "3.0.1"
|
||||
union "~0.5.0"
|
||||
|
||||
lodash@^4.17.14:
|
||||
version "4.17.15"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
|
||||
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
|
||||
|
||||
mime@^1.6.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
|
||||
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
|
||||
|
||||
minimist@^1.1.0, minimist@^1.2.5:
|
||||
version "1.2.5"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
||||
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
|
||||
|
||||
mkdirp@^0.5.1:
|
||||
version "0.5.5"
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
|
||||
integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
|
||||
dependencies:
|
||||
minimist "^1.2.5"
|
||||
|
||||
ms@^2.1.1:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
||||
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
||||
|
||||
opener@^1.5.1:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.1.tgz#6d2f0e77f1a0af0032aca716c2c1fbb8e7e8abed"
|
||||
integrity sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA==
|
||||
|
||||
portfinder@^1.0.25:
|
||||
version "1.0.26"
|
||||
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.26.tgz#475658d56ca30bed72ac7f1378ed350bd1b64e70"
|
||||
integrity sha512-Xi7mKxJHHMI3rIUrnm/jjUgwhbYMkp/XKEcZX3aG4BrumLpq3nmoQMX+ClYnDZnZ/New7IatC1no5RX0zo1vXQ==
|
||||
dependencies:
|
||||
async "^2.6.2"
|
||||
debug "^3.1.1"
|
||||
mkdirp "^0.5.1"
|
||||
|
||||
qs@^6.4.0:
|
||||
version "6.9.4"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.4.tgz#9090b290d1f91728d3c22e54843ca44aea5ab687"
|
||||
integrity sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==
|
||||
|
||||
requires-port@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
|
||||
integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
|
||||
|
||||
secure-compare@3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/secure-compare/-/secure-compare-3.0.1.tgz#f1a0329b308b221fae37b9974f3d578d0ca999e3"
|
||||
integrity sha1-8aAymzCLIh+uN7mXTz1XjQypmeM=
|
||||
|
||||
union@~0.5.0:
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/union/-/union-0.5.0.tgz#b2c11be84f60538537b846edb9ba266ba0090075"
|
||||
integrity sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==
|
||||
dependencies:
|
||||
qs "^6.4.0"
|
||||
|
||||
url-join@^2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/url-join/-/url-join-2.0.5.tgz#5af22f18c052a000a48d7b82c5e9c2e2feeda728"
|
||||
integrity sha1-WvIvGMBSoACkjXuCxenC4v7tpyg=
|
||||
@ -64,15 +64,9 @@ global:
|
||||
|
||||
demoBanners:
|
||||
# This is the "advertisement" shown in the main menu and other various places
|
||||
title: Hey!
|
||||
title: Demo Version
|
||||
intro: >-
|
||||
If you enjoy this game, please consider buying the full version!
|
||||
advantages:
|
||||
- Unlimited savegames
|
||||
- Waypoints
|
||||
- Dark mode & more
|
||||
- >-
|
||||
Allow me to further develop shapez.io ❤️
|
||||
Get the standalone to unlock all features!
|
||||
|
||||
mainMenu:
|
||||
play: Play
|
||||
@ -88,6 +82,29 @@ mainMenu:
|
||||
savegameLevel: Level <x>
|
||||
savegameLevelUnknown: Unknown Level
|
||||
|
||||
contests:
|
||||
contest_01_03062020:
|
||||
title: "Contest #01"
|
||||
desc: Win <strong>$25</strong> for the coolest base!
|
||||
longDesc: >-
|
||||
To give something back to you, I thought it would be cool to make weekly contests!
|
||||
<br><br>
|
||||
<strong>This weeks topic:</strong> Build the coolest base!
|
||||
<br><br>
|
||||
Here's the deal:<br>
|
||||
<ul class="bucketList">
|
||||
<li>Submit a screenshot of your base to <strong>contest@shapez.io</strong></li>
|
||||
<li>Bonus points if you share it on social media!</li>
|
||||
<li>I will choose 5 screenshots and propose it to the <strong>discord</strong> community to vote.</li>
|
||||
<li>The winner gets <strong>$25</strong> (Paypal, Amazon Gift Card, whatever you prefer)</li>
|
||||
<li>Deadline: 07.06.2020 12:00 AM CEST</li>
|
||||
</ul>
|
||||
<br>
|
||||
I'm looking forward to seeing your awesome creations!
|
||||
|
||||
showInfo: View
|
||||
contestOver: This contest has ended - Join the discord to get noticed about new contests!
|
||||
|
||||
dialogs:
|
||||
buttons:
|
||||
ok: OK
|
||||
@ -153,15 +170,11 @@ dialogs:
|
||||
|
||||
leaveNotPossibleInDemo:
|
||||
title: Demo version
|
||||
desc: Your game was saved but you will not be able to restore it in the demo. Restoring your savegames is only possible in the full version. Are you sure?
|
||||
desc: Your game has been saved, but you will not be able to restore it in the demo. Restoring your savegames is only possible in the full version. Are you sure?
|
||||
|
||||
newUpdate:
|
||||
title: Update available
|
||||
desc: There is an update for this game available!
|
||||
|
||||
demoExplanation:
|
||||
title: Notice from the Developer
|
||||
desc: I am developing this game in my free time, and I hope you enjoy it! If you do, please consider to buy the standalone version!
|
||||
desc: There is an update for this game available, be sure to download it!
|
||||
|
||||
oneSavegameLimit:
|
||||
title: Limited savegames
|
||||
@ -206,6 +219,9 @@ dialogs:
|
||||
title: New Marker
|
||||
desc: Give it a meaningful name
|
||||
|
||||
markerDemoLimit:
|
||||
desc: You can only create two custom markers in the demo. Get the standalone for unlimited markers!
|
||||
|
||||
ingame:
|
||||
# This is shown in the top left corner and displays useful keybindings in
|
||||
# every situation
|
||||
@ -220,6 +236,7 @@ ingame:
|
||||
toggleHud: Toggle HUD
|
||||
placeBuilding: Place building
|
||||
createMarker: Create Marker
|
||||
delete: Destroy
|
||||
|
||||
# Everything related to placing buildings (I.e. as soon as you selected a building
|
||||
# from the toolbar)
|
||||
@ -313,12 +330,24 @@ ingame:
|
||||
blueprintPlacer:
|
||||
cost: Cost
|
||||
|
||||
# Map markers
|
||||
waypoints:
|
||||
waypoints: Markers
|
||||
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.
|
||||
|
||||
# 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_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!
|
||||
|
||||
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.
|
||||
|
||||
# All shop upgrades
|
||||
shopUpgrades:
|
||||
belt:
|
||||
@ -574,7 +603,7 @@ settings:
|
||||
offerHints:
|
||||
title: Hints & Tutorials
|
||||
description: >-
|
||||
Whether to offer hints and tutorials while playing.
|
||||
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.
|
||||
|
||||
keybindings:
|
||||
title: Keybindings
|
||||
@ -649,6 +678,5 @@ demo:
|
||||
importingGames: Importing savegames
|
||||
oneGameLimit: Limited to one savegame
|
||||
customizeKeybindings: Customizing Keybindings
|
||||
creatingMarkers: Create custom markers
|
||||
|
||||
settingNotAvailable: Not available in the demo.
|
||||
|
||||
@ -26,6 +26,13 @@ global:
|
||||
# How big numbers are rendered, e.g. "10,000"
|
||||
thousandsDivider: "."
|
||||
|
||||
# The suffix for large numbers, e.g. 1.3k, 400.2M, etc. cf wikipedia système international d'unité
|
||||
suffix:
|
||||
thousands: k
|
||||
millions: M
|
||||
billions: T
|
||||
trillions: E
|
||||
|
||||
# Shown for infinitely big numbers
|
||||
infinite: inf
|
||||
|
||||
@ -152,10 +159,6 @@ dialogs:
|
||||
title: Mise-à-jour disponible
|
||||
desc: Une mise-à-jour est disponible pour ce jeu!
|
||||
|
||||
demoExplanation:
|
||||
title: Note du développeur
|
||||
desc: Je développe ce jeu pendant mon temps libre, et j'espère que vous l'appréciez! Si c'est le cas, merci de considérez l'achat de la version complète!
|
||||
|
||||
oneSavegameLimit:
|
||||
title: Sauvegardes limitées
|
||||
desc: Vous ne pouvez avoir qu'une seule sauvegarde en même temps dans la version démo. Merci de soit effacer l'actuelle ou de vous procurer la version complète!
|
||||
@ -213,6 +216,7 @@ ingame:
|
||||
toggleHud: Basculet l'ATH
|
||||
placeBuilding: Placer un bâtiment
|
||||
createMarker: Créer une balise
|
||||
delete: Supprimer
|
||||
|
||||
# Everything related to placing buildings (I.e. as soon as you selected a building
|
||||
# from the toolbar)
|
||||
@ -278,7 +282,7 @@ ingame:
|
||||
description: Affiche tous les formes que votre usine entière produit, en incluant les formes intermédiaires.
|
||||
delivered:
|
||||
title: Délivré
|
||||
description: Affiche les formes qui ont étés délivrées dans votres bâtiment central.
|
||||
description: Affiche les formes qui ont été livrées dans votre noyau.
|
||||
noShapesProduced: Aucune forme n'a été produite jusqu'à présent.
|
||||
|
||||
# Displays the shapes per minute, e.g. '523 / m'
|
||||
@ -306,12 +310,21 @@ ingame:
|
||||
blueprintPlacer:
|
||||
cost: Coût
|
||||
|
||||
# Map markers
|
||||
waypoints:
|
||||
waypoints: Balise
|
||||
hub: Noyau
|
||||
description: Cliquez une balise pour vous y rendre, clic-droit pour l'effacer.<br><br>Appuyez sur <keybinding> pour créer une balise sur la vue actuelle, ou <strong>clic-droit</strong> pour en créer une sur l'endroit pointé.
|
||||
creationSuccessNotification: La bailse a été créée.
|
||||
|
||||
# Interactive tutorial
|
||||
interactiveTutorial:
|
||||
title: Tutoriel
|
||||
hints:
|
||||
1_1_extractor: Placez un <strong>extracteur</strong> sur une <strong>forme en cercle</strong> pour l'extraire!
|
||||
1_2_conveyor: Connectez l'extracteur avec un <strong>convoyeur</strong> vers votre noyau!
|
||||
1_3_expand: Ceci n'est <strong>PAS</strong> un jeu incrémental et inactif! Construisez plus d'extracteurs et de convoyeurs pour atteindre plus votre votre but.
|
||||
|
||||
# All shop upgrades
|
||||
shopUpgrades:
|
||||
belt:
|
||||
@ -440,7 +453,7 @@ storyRewards:
|
||||
|
||||
reward_tunnel:
|
||||
title: Tunnel
|
||||
desc: Le <strong>tunnel</strong> a été débloqué - Vous pouvez maintenant faire passer des formes vous les convoyeurs et les bâtimentts avec ça!
|
||||
desc: Le <strong>tunnel</strong> a été débloqué - Vous pouvez maintenant faire passer des formes sous les convoyeurs et les bâtiments avec ça!
|
||||
|
||||
reward_rotater_ccw:
|
||||
title: Pivoteur inversé
|
||||
@ -448,7 +461,7 @@ storyRewards:
|
||||
|
||||
reward_miner_chainable:
|
||||
title: Extracteur en série
|
||||
desc: Vous avez débloqué <strong>l'extracteur en série</strong>! Il permet <strong>de transférer ses resources</strong> à d'autres extracteurs pour extraire les ressources plus efficacement!
|
||||
desc: Vous avez débloqué <strong>l'extracteur en série</strong>! Il permet <strong>de transférer ses resources</strong> à d'autres extracteurs pour les extraire plus efficacement!
|
||||
|
||||
reward_underground_belt_tier_2:
|
||||
title: Tunnel échelon II
|
||||
@ -481,7 +494,7 @@ storyRewards:
|
||||
|
||||
reward_blueprints:
|
||||
title: Patrons
|
||||
desc: Vous pouvez maintenant <strong>copier et coller</strong> des perties de votre usines! Sélectionnez une zone (Appuyez sur CTRL, et sélectionnez avec votre souris), et appuyez sur 'C' pour la copier.<br><br>Coller n'est <strong>pas gratuit</strong>, vous devez produire <strong>des formes de patrons</strong> pour vous le payer! (Ceux qu'ont vient de vous donner).
|
||||
desc: Vous pouvez maintenant <strong>copier et coller</strong> des parties de votre usines! Sélectionnez une zone (Appuyez sur CTRL, et sélectionnez avec votre souris), et appuyez sur 'C' pour la copier.<br><br>Coller n'est <strong>pas gratuit</strong>, vous devez produire <strong>des formes de patrons</strong> pour vous le payer! (Ceux que vous venez de livrer).
|
||||
|
||||
# Special reward, which is shown when there is no reward actually
|
||||
no_reward:
|
||||
@ -511,6 +524,23 @@ settings:
|
||||
title: Taille de l'interface
|
||||
description: >-
|
||||
Change la taille de l'interface utilisateur. Cette interface se redimensionnera suivant la résolution de votre appareil, mais cette option contrôle le facteur de résolution.
|
||||
scales:
|
||||
super_small: Très petite
|
||||
small: Petite
|
||||
regular: Normale
|
||||
large: Largr
|
||||
huge: Très large
|
||||
|
||||
scrollWheelSensitivity:
|
||||
title: Sensibilité du zoom
|
||||
description: >-
|
||||
Change la sensibilité du zoom (AUssi bien de la roulette de la souris que du trackpad).
|
||||
sensitivity:
|
||||
super_slow: Super lent
|
||||
slow: Lent
|
||||
regular: Normal
|
||||
fast: Rapide
|
||||
super_fast: Super rapide
|
||||
|
||||
fullscreen:
|
||||
title: Plein écran
|
||||
@ -557,6 +587,7 @@ keybindings:
|
||||
categoryLabels:
|
||||
general: Application
|
||||
ingame: Jeu
|
||||
navigation: Navigation
|
||||
placement: Placement
|
||||
massSelect: Suppression de masse
|
||||
buildings: Raccourcis bâtiment
|
||||
@ -569,9 +600,11 @@ keybindings:
|
||||
mapMoveRight: Aller à droite
|
||||
mapMoveDown: Aller en bas
|
||||
mapMoveLeft: Aller à gauche
|
||||
centerMap: Centrer la carte
|
||||
|
||||
mapZoomIn: Zoom avant
|
||||
mapZoomOut: Zoom arrière
|
||||
createMarker: Créer une balise
|
||||
|
||||
menuOpenShop: Améliorations
|
||||
menuOpenStats: Statistiques
|
||||
@ -621,5 +654,5 @@ demo:
|
||||
|
||||
settingNotAvailable: Indisponible dans la démo.
|
||||
#
|
||||
# French translation version v0.2 based on english v1.1.1 by Didier WEERTS 'The Corsaire'
|
||||
# French translation version v0.3 based on english v1.1.4 by Didier WEERTS 'The Corsaire'
|
||||
#
|
||||
673
translations/base-pt-BR.yaml
Normal file
@ -0,0 +1,673 @@
|
||||
#
|
||||
# GAME TRANSLATIONS
|
||||
#
|
||||
# Contributing:
|
||||
#
|
||||
# If you want to contribute, please make a pull request on this respository
|
||||
# and I will have a look.
|
||||
#
|
||||
# Placeholders:
|
||||
#
|
||||
# Do *not* replace placeholders! Placeholders have a special syntax like
|
||||
# `Hotkey: <key>`. They are encapsulated within angle brackets. The correct
|
||||
# translation for this one in German for example would be: `Taste: <key>` (notice
|
||||
# how the placeholder stayed '<key>' and was not replaced!)
|
||||
#
|
||||
# Adding a new language:
|
||||
#
|
||||
# If you want to add a new language, ask me in the discord and I will setup
|
||||
# the basic structure so the game also detects it.
|
||||
#
|
||||
|
||||
global:
|
||||
loading: Carregando
|
||||
error: Erro
|
||||
|
||||
# How big numbers are rendered, e.g. "10,000"
|
||||
thousandsDivider: "."
|
||||
|
||||
# The suffix for large numbers, e.g. 1.3k, 400.2M, etc.
|
||||
suffix:
|
||||
thousands: K
|
||||
millions: M
|
||||
billions: B
|
||||
trillions: T
|
||||
|
||||
# Shown for infinitely big numbers
|
||||
infinite: inf
|
||||
|
||||
time:
|
||||
# Used for formatting past time dates
|
||||
oneSecondAgo: um segundo atrás
|
||||
xSecondsAgo: <x> segundos atrás
|
||||
oneMinuteAgo: um minuto atrás
|
||||
xMinutesAgo: <x> minutos atrás
|
||||
oneHourAgo: uma hora atrás
|
||||
xHoursAgo: <x> horas atrás
|
||||
oneDayAgo: um dia atrás
|
||||
xDaysAgo: <x> dias atrás
|
||||
|
||||
# Short formats for times, e.g. '5h 23m'
|
||||
secondsShort: <seconds>s
|
||||
minutesAndSecondsShort: <minutes>m <seconds>s
|
||||
hoursAndMinutesShort: <hours>h <minutes>s
|
||||
|
||||
xMinutes: <x> minutos
|
||||
|
||||
keys:
|
||||
tab: TAB
|
||||
control: CTRL
|
||||
alt: ALT
|
||||
escape: ESC
|
||||
shift: SHIFT
|
||||
space: ESPAÇO
|
||||
|
||||
demoBanners:
|
||||
# This is the "advertisement" shown in the main menu and other various places
|
||||
title: Versão Demo
|
||||
intro: >-
|
||||
Pegue a versão completa para desbloquear todas os recursos
|
||||
|
||||
mainMenu:
|
||||
play: Jogar
|
||||
changelog: Changelog
|
||||
importSavegame: Importar
|
||||
openSourceHint: Esse jogo tem código aberto!
|
||||
discordLink: Discord oficial
|
||||
|
||||
# This is shown when using firefox and other browsers which are not supported.
|
||||
browserWarning: >-
|
||||
Desculpe, o jogo fica lento em seu navegador! Compre a versão completa ou baixe o Chrome para obter uma experiência completa.
|
||||
|
||||
savegameLevel: Level <x>
|
||||
savegameLevelUnknown: Level desconhecido
|
||||
|
||||
contests:
|
||||
contest_01_03062020:
|
||||
title: "Concurso #01"
|
||||
desc: Ganhe <strong> $ 25 </strong> pela melhor base!
|
||||
longDesc: >-
|
||||
Para retribuir, pensei que seria legal fazer concursos semanais!
|
||||
<br><br>
|
||||
<strong> Tópico dessa semana:</strong> Cronstua a base mais legal!
|
||||
<br><br>
|
||||
Here's the deal:<br>
|
||||
<ul class="bucketList">
|
||||
<li>Envie uma captura de tela da sua base para <strong>contest@shapez.io</strong></li>
|
||||
<li>Pontos bônus se você o compartilhar nas mídias sociais!</li>
|
||||
<li>Vou escolher 5 capturas de tela e propor à votação a comunidade <strong>discord</strong>.</li>
|
||||
<li>o vencedor recebe <strong> $ 25 </strong> (Paypal, Amazon Gift Card, o que você preferir)</li>
|
||||
<li>Até 07.06.2020 12:00 CEST</li>
|
||||
</ul>
|
||||
<br>
|
||||
Estou ansioso para ver suas criações incríveis!
|
||||
|
||||
showInfo: Participate
|
||||
|
||||
dialogs:
|
||||
buttons:
|
||||
ok: OK
|
||||
delete: Deletar
|
||||
cancel: Cancelar
|
||||
later: Voltar
|
||||
restart: Reiniciar
|
||||
reset: Reset
|
||||
getStandalone: Obter versão completa
|
||||
deleteGame: Eu sei o que eu faço
|
||||
viewUpdate: Atualizações
|
||||
showUpgrades: Mostrar atualizações
|
||||
showKeybindings: Controles
|
||||
|
||||
importSavegameError:
|
||||
title: Erro importante
|
||||
text: >-
|
||||
Falha ao carregar seu savegame:
|
||||
|
||||
importSavegameSuccess:
|
||||
title: Sucesso
|
||||
text: >-
|
||||
Seu savegame foi importado.
|
||||
|
||||
gameLoadFailure:
|
||||
title: Jogo esta quebrado
|
||||
text: >-
|
||||
Falha ao carregar seu savegame
|
||||
|
||||
confirmSavegameDelete:
|
||||
title: Confirmar exclusão
|
||||
text: >-
|
||||
Tem certeza que quer excluir esse jogo?
|
||||
|
||||
savegameDeletionError:
|
||||
title: Falha para deletar
|
||||
text: >-
|
||||
Falha ao deletar seu savegame:
|
||||
|
||||
restartRequired:
|
||||
title: Reiniciar
|
||||
text: >-
|
||||
Voce precisa reiniciar o jogo para aplicar as mudanças.
|
||||
|
||||
editKeybinding:
|
||||
title: Change Keybinding
|
||||
desc: Press the key you want to assign, or escape to cancel.
|
||||
|
||||
resetKeybindingsConfirmation:
|
||||
title: Resetar controles
|
||||
desc: Essa opção deixa os controles no modo padrão.
|
||||
|
||||
keybindingsResetOk:
|
||||
title: Resetar controles
|
||||
desc: Os controles foram resetados para o modo padrão.
|
||||
|
||||
featureRestriction:
|
||||
title: Versão Demo
|
||||
desc: Você tentou acessar um recurso (<feature>) que não está disponível na demo. Considere obter a versão completa para a proceder!
|
||||
|
||||
saveNotPossibleInDemo:
|
||||
desc: Seu jogo foi salvo, mas a restauração só é possível na versão completa. Considere obter a versão completa!
|
||||
|
||||
leaveNotPossibleInDemo:
|
||||
title: Demo version
|
||||
desc: Seu jogo foi salvo, mas você não poderá restaurá-lo na demo. Restaurar seus savegames só é possível na versão completa. Você tem certeza?
|
||||
|
||||
newUpdate:
|
||||
title: Atualização disponível
|
||||
desc: Uma atualização para esse jogo esta disponível!
|
||||
|
||||
oneSavegameLimit:
|
||||
title: Save limitado
|
||||
desc: Você pode ter apenas um savegame por vez na versão demo. Remova o existente ou obtenha a versão completa!
|
||||
|
||||
updateSummary:
|
||||
title: Nova Atualização!
|
||||
desc: >-
|
||||
Aqui estão as alterações desde a última vez que você jogou:
|
||||
|
||||
hintDescription:
|
||||
title: Tutorial
|
||||
desc: >-
|
||||
Sempre que precisar de ajuda ou estiver parado, confira o botão 'Mostrar dica' no canto inferior esquerdo e darei o meu melhor para ajudá-lo!
|
||||
|
||||
upgradesIntroduction:
|
||||
title: Desbloquear updates
|
||||
desc: >-
|
||||
Todas as formas que você produz podem ser usadas para desbloquear atualizações - <strong> Não destrua suas antigas fábricas!!</strong>
|
||||
O guia de atualizações pode ser encontrada no canto superior direito da tela.
|
||||
|
||||
massDeleteConfirm:
|
||||
title: Deletar
|
||||
desc: >-
|
||||
Voce esta deletando vários itens (<count> para ser exato)! Voce quer continuar?
|
||||
|
||||
blueprintsNotUnlocked:
|
||||
title: Não desbloqueado ainda
|
||||
desc: >-
|
||||
Os projetos ainda não foram desbloqueados! Complete mais níveis para desbloqueá-los.
|
||||
|
||||
keybindingsIntroduction:
|
||||
title: Teclas úteis
|
||||
desc: >-
|
||||
Este jogo possui muitas combinações de teclas que facilitam a construção de grandes fábricas
|
||||
Aqui estão alguns mas certifique-se de <strong> verificar as combinações de teclas </strong>!<br><br>
|
||||
<code class='keybinding'>CTRL</code> + Drag: Selecione a área para copiar / delete.<br>
|
||||
<code class='keybinding'>SHIFT</code>: Mantenha pressionado para colocar vários.<br>
|
||||
<code class='keybinding'>ALT</code>: Inverter as posições.<br>
|
||||
|
||||
createMarker:
|
||||
title: Nova Marcação
|
||||
desc: De um nome
|
||||
ingame:
|
||||
# This is shown in the top left corner and displays useful keybindings in
|
||||
# every situation
|
||||
keybindingsOverlay:
|
||||
moveMap: Mover
|
||||
removeBuildings: Deletar
|
||||
stopPlacement: Parar
|
||||
rotateBuilding: Rotação
|
||||
placeMultiple: Colocar vários
|
||||
reverseOrientation: reverso
|
||||
disableAutoOrientation: desligar orientações
|
||||
toggleHud: Base
|
||||
placeBuilding: Colocar construção
|
||||
createMarker: Criar marcador
|
||||
delete: Destruir
|
||||
|
||||
# Everything related to placing buildings (I.e. as soon as you selected a building
|
||||
# from the toolbar)
|
||||
buildingPlacement:
|
||||
# Buildings can have different variants which are unlocked at later levels,
|
||||
# and this is the hint shown when there are multiple variants available.
|
||||
cycleBuildingVariants: Aperte <key> para variações.
|
||||
|
||||
# Shows the hotkey in the ui, e.g. "Hotkey: Q"
|
||||
hotkeyLabel: >-
|
||||
Hotkey: <key>
|
||||
|
||||
infoTexts:
|
||||
speed: velocidade
|
||||
range: distancia
|
||||
storage: Estoque
|
||||
oneItemPerSecond: 1 item / segundo
|
||||
itemsPerSecond: <x> itens / s
|
||||
itemsPerSecondDouble: (x2)
|
||||
|
||||
tiles: <x> tiles
|
||||
|
||||
# The notification when completing a level
|
||||
levelCompleteNotification:
|
||||
# <level> is replaced by the actual level, so this gets 'Level 03' for example.
|
||||
levelTitle: Level <level>
|
||||
completed: Completado
|
||||
unlockText: Desbloqueado <reward>!
|
||||
buttonNextLevel: Próximo Level
|
||||
|
||||
# Notifications on the lower right
|
||||
notifications:
|
||||
newUpgrade: Nova Atualização disponível!
|
||||
gameSaved: Seu jogo foi Salvo.
|
||||
|
||||
# Mass select information, this is when you hold CTRL and then drag with your mouse
|
||||
# to select multiple buildings
|
||||
massSelect:
|
||||
infoText: Aperte <keyCopy> para copiar, <keyDelete> para excluir e <keyCancel> para cancelar.
|
||||
|
||||
# The "Upgrades" window
|
||||
shop:
|
||||
title: Atualizações
|
||||
buttonUnlock: Atualizações
|
||||
|
||||
# Gets replaced to e.g. "Tier IX"
|
||||
tier: Nível <x>
|
||||
|
||||
# The roman number for each tier
|
||||
tierLabels: [I, II, III, IV, V, VI, VII, VIII, IX, X]
|
||||
|
||||
maximumLevel: Level Máximo
|
||||
|
||||
# The "Statistics" window
|
||||
statistics:
|
||||
title: Estatísticas
|
||||
dataSources:
|
||||
stored:
|
||||
title: Estoque
|
||||
description: Exibindo a quantidade de formas armazenadas em seu edifício central.
|
||||
produced:
|
||||
title: Produção
|
||||
description: Exibindo todas as formas que toda a sua fábrica produz, incluindo produtos intermediários..
|
||||
delivered:
|
||||
title: Entregue
|
||||
description: Exibindo formas entregues ao seu edifício central..
|
||||
noShapesProduced: Nenhuma forma foi produzida até o momento.
|
||||
|
||||
# Displays the shapes per minute, e.g. '523 / m'
|
||||
shapesPerMinute: <formas> / m
|
||||
|
||||
# Settings menu, when you press "ESC"
|
||||
settingsMenu:
|
||||
playtime: Tempo de Jogo
|
||||
|
||||
buildingsPlaced: Construções
|
||||
beltsPlaced: Belts
|
||||
|
||||
buttons:
|
||||
continue: Continue
|
||||
settings: Definições
|
||||
menu: Voltar ao menu
|
||||
|
||||
# Bottom left tutorial hints
|
||||
tutorialHints:
|
||||
title: Precisa de ajuda?
|
||||
showHint: Mostrar dica
|
||||
hideHint: Fechar
|
||||
|
||||
# When placing a blueprint
|
||||
blueprintPlacer:
|
||||
cost: Custo
|
||||
|
||||
# Map markers
|
||||
waypoints:
|
||||
waypoints: Marcadores
|
||||
hub: HUB
|
||||
description: Clique com o botão esquerdo do mouse em um marcador para pular, clique com o botão direito do mouse para excluí-lo. <br> <br> Pressione <keybinding> para criar um marcador a partir da exibição atual ou <strong> clique com o botão direito do mouse </strong> para criar um marcador no local selecionado.
|
||||
creationSuccessNotification: Marcador criado.
|
||||
|
||||
# Interactive tutorial
|
||||
interactiveTutorial:
|
||||
title: Tutorial
|
||||
hints:
|
||||
1_1_extractor: Coloque um <strong> extrator </strong> em cima de uma <strong> fonte de círculo </strong> para extraí-lo!
|
||||
1_2_conveyor: >-
|
||||
Conecte o extrator com uma <strong> esteira transportadora </strong> até a sua base! <br><br> Dica, <strong>clique e arraste</strong> a esteira com o mouse!
|
||||
|
||||
1_3_expand: >-
|
||||
Este <strong> NÃO </strong> é um jogo inativo! Construa mais extratores e esteiras para concluir o objetivo mais rapidamente.<br><br>Dica, segure <strong> SHIFT </strong> para colocar vários extratores e use <strong> R </strong> para girá-los.
|
||||
|
||||
# All shop upgrades
|
||||
shopUpgrades:
|
||||
belt:
|
||||
name: Esteiras, Distribuidores e Túneis
|
||||
description: Velocidade +<gain>%
|
||||
miner:
|
||||
name: Extração
|
||||
description: Velocidade +<gain>%
|
||||
processors:
|
||||
name: Cortar, Rotacionar e Empilhamento
|
||||
description: Velocidade +<gain>%
|
||||
painting:
|
||||
name: Misturador e pintura
|
||||
description: Velocidade +<gain>%
|
||||
|
||||
# Buildings and their name / description
|
||||
buildings:
|
||||
belt:
|
||||
default:
|
||||
name: &belt Conveyor Belt
|
||||
description: Transporta itens, mantenha pressionado e arraste para colocar vários.
|
||||
|
||||
miner: # Internal name for the Extractor
|
||||
default:
|
||||
name: &miner Extractor
|
||||
description: Coloque sobre uma forma ou cor para extraí-la.
|
||||
|
||||
chainable:
|
||||
name: Extractor (Chain)
|
||||
description: Coloque sobre uma forma ou cor para extraí-la. Pode ser acorrentado.
|
||||
|
||||
underground_belt: # Internal name for the Tunnel
|
||||
default:
|
||||
name: &underground_belt Tunnel
|
||||
description: Permite transportar recursos sob construções.
|
||||
|
||||
tier2:
|
||||
name: Tunnel Tier II
|
||||
description: Permite transportar recursos sob construções.
|
||||
|
||||
splitter: # Internal name for the Balancer
|
||||
default:
|
||||
name: &splitter Balancer
|
||||
description: Multifunctional - Distribui uniformemente todas as entradas em todas as saídas.
|
||||
|
||||
compact:
|
||||
name: Merger (compact)
|
||||
description: Mescla duas correias transportadoras em uma.
|
||||
|
||||
compact-inverse:
|
||||
name: Merger (compact)
|
||||
description: Mescla duas correias transportadoras em uma.
|
||||
|
||||
cutter:
|
||||
default:
|
||||
name: &cutter Cutter
|
||||
description: Corta as formas de cima para baixo e produz as duas metades. <strong> Se você usar apenas uma parte, não se esqueça de destruir a outra parte, ou ela irá parar a produção! </strong>
|
||||
quad:
|
||||
name: Cutter (Quad)
|
||||
description: Corta as formas em quatro partes. <strong> Se você usar apenas uma parte, não se esqueça de destruir as outras, ou ela irá parar a produção! </strong>
|
||||
|
||||
rotater:
|
||||
default:
|
||||
name: &rotater Rotate
|
||||
description: Gira as formas no sentido horário em 90 graus.
|
||||
ccw:
|
||||
name: Rotate (CCW)
|
||||
description: RGira as formas no sentido anti-horário em 90 graus.
|
||||
|
||||
stacker:
|
||||
default:
|
||||
name: &stacker Stacker
|
||||
description: Empilha os dois itens. Se eles não puderem ser mesclados, o item certo será colocado acima do item esquerdo.
|
||||
|
||||
mixer:
|
||||
default:
|
||||
name: &mixer Color Mixer
|
||||
description: Mistura duas cores usando mistura aditiva.
|
||||
|
||||
painter:
|
||||
default:
|
||||
name: &painter Painter
|
||||
description: Colore a forma inteira na entrada esquerda com a cor da entrada direita.
|
||||
double:
|
||||
name: Painter (Double)
|
||||
description: Colore as duas formas na entrada esquerda com a cor da entrada direita.
|
||||
quad:
|
||||
name: Painter (Quad)
|
||||
description: Permite colorir cada quadrante da forma com uma cor diferente.
|
||||
|
||||
trash:
|
||||
default:
|
||||
name: &trash Lixo
|
||||
description: Aceita qualquer item e os destrói. PARA SEMPRE
|
||||
|
||||
storage:
|
||||
name: Estoque
|
||||
description: Armazena itens em excesso, até uma determinada capacidade. Pode ser usado como uma porta de transbordamento.
|
||||
|
||||
storyRewards:
|
||||
# Those are the rewards gained from completing the store
|
||||
reward_cutter_and_trash:
|
||||
title: Formas de corte
|
||||
desc: Voce desbloqueou <strong>cutter</strong> - corte de formas pela metade de <strong>cima para baixo </strong> independentemente de sua orientação!<br><br> Certifique-se de se livrar do lixo, ou então <strong> ele irá parar a produção </strong> - Para esse propósito, eu lhe dei uma lixo, que destrói tudo o que você coloca nele
|
||||
|
||||
reward_rotater:
|
||||
title: Rodando
|
||||
desc: O <strong> rotator </strong> foi desbloqueado! Gira as formas no sentido horário em 90 graus
|
||||
|
||||
reward_painter:
|
||||
title: Pintando
|
||||
desc: >-
|
||||
O <strong> pintor </strong> foi desbloqueado - Extraia algumas veias coloridas (como você faz com formas) e combine-as com uma forma no pintor para colori-las! <br> <br> PS: Se você é daltônico , Já estou trabalhando em uma solução!
|
||||
|
||||
reward_mixer:
|
||||
title: Mistura de cores
|
||||
desc: O <strong> misturador </strong> foi desbloqueado - combine duas cores usando <strong> mistura aditiva </strong> com esta construção!
|
||||
|
||||
reward_stacker:
|
||||
title: Combinador
|
||||
desc: Agora você pode combinar formas com o <strong> combinador </strong>! Ambas as entradas são combinadas e, se puderem ser colocadas próximas uma da outra, serão <strong> fundidas </strong>. Caso contrário, a entrada direita é <strong> empilhada em cima </strong> da entrada esquerda!
|
||||
|
||||
reward_splitter:
|
||||
title: Divisor/fusão
|
||||
desc: O balanceador multifuncional <strong> </strong> foi desbloqueado - ele pode ser usado para construir fábricas maiores dividindo e mesclando itens </strong>! <br> <br>
|
||||
|
||||
reward_tunnel:
|
||||
title: Túnel
|
||||
desc: O <strong> túnel </strong> foi desbloqueado - Agora você pode canalizar itens através de construções!
|
||||
|
||||
reward_rotater_ccw:
|
||||
title: CCW Rotação
|
||||
desc: Você desbloqueou uma variante do <strong> rotater </strong> - permite girar no sentido anti-horário! Para construí-lo, selecione o rotador e <strong> pressione 'T' para alternar suas variantes </strong>!
|
||||
|
||||
reward_miner_chainable:
|
||||
title: Extrator de encadeamento
|
||||
desc: Você desbloqueou o <strong> extrator de correntes </strong>! Ele pode <strong> encaminhar seus recursos </strong> para outros extratores, para que você possa extrair recursos com mais eficiência!
|
||||
|
||||
reward_underground_belt_tier_2:
|
||||
title: Túnel Tier II
|
||||
desc: Você desbloqueou uma nova variante do <strong> túnel </strong> - ele tem um <strong> maior alcance </strong>, e também pode misturar e combinar esses túneis agora!
|
||||
|
||||
reward_splitter_compact:
|
||||
title: Balanceador compacto
|
||||
desc: >-
|
||||
Você desbloqueou uma variante compacta do <strong> balanceador </strong> - ele aceita duas entradas e as mescla em uma!
|
||||
|
||||
reward_cutter_quad:
|
||||
title: Cortador quádruplo
|
||||
desc: Você desbloqueou uma variante do <strong> cortador </strong> - permite cortar formas em <strong> quatro partes </strong> em vez de apenas duas!
|
||||
|
||||
reward_painter_double:
|
||||
title: Pintura dupla
|
||||
desc: Você desbloqueou uma variante do <strong> pintor </strong> - funciona como o pintor regular, mas processa <strong> duas formas ao mesmo tempo </strong>, consumindo apenas uma cor em vez de duas!
|
||||
|
||||
reward_painter_quad:
|
||||
title: Pintura quádupla
|
||||
desc: Você desbloqueou uma variante do <strong> pintor </strong> - permite pintar cada parte da forma individualmente!
|
||||
|
||||
reward_storage:
|
||||
title: buffer de armazenamento
|
||||
desc: Você desbloqueou uma variante do <strong> lixo </strong> - Permite armazenar itens até uma determinada capacidade!
|
||||
|
||||
reward_freeplay:
|
||||
title: Modo Livre
|
||||
desc: Você fez isso! Você desbloqueou o <strong> modo de jogo livre </strong>! Isso significa que as formas agora são geradas aleatoriamente! (Não se preocupe, mais conteúdo está planejado para o jogo completo!)
|
||||
|
||||
reward_blueprints:
|
||||
title: Projetos
|
||||
desc: Agora você pode <strong> copiar e colar </strong> partes de sua fábrica! Selecione uma área (mantenha pressionada a tecla CTRL e arraste com o mouse) e pressione 'C' para copiá-la. <br> <br> Colar <strong> não é de graça </strong>, é necessário produzir <strong> projetos e formas </strong> para pagar! (Aqueles que você acabou de entregar).
|
||||
|
||||
# Special reward, which is shown when there is no reward actually
|
||||
no_reward:
|
||||
title: Próximo level
|
||||
desc: >-
|
||||
Este nível não lhe deu nenhuma recompensa, mas em breve?! <br> <br> PS: Melhor não destruir sua fábrica existente - Você precisa de <strong> todas </strong> todas essas formas posteriormente mais tarde para <strong> desbloquear atualizações </strong>!
|
||||
|
||||
no_reward_freeplay:
|
||||
title: Next level
|
||||
desc: >-
|
||||
Parabens, não se esqueça existe muita coisa planejada para essa versão.
|
||||
|
||||
settings:
|
||||
title: opções
|
||||
categories:
|
||||
game: Jogo
|
||||
app: Aplicação
|
||||
|
||||
versionBadges:
|
||||
dev: Desenvolvedor
|
||||
staging: Staging
|
||||
prod: Produção
|
||||
buildDate: Built <at-date>
|
||||
|
||||
labels:
|
||||
uiScale:
|
||||
title: Fonte
|
||||
description: >-
|
||||
Altera o tamanho da fonte do usuário. A interface ainda será dimensionada com base na resolução do dispositivo, mas essa configuração controla a quantidade de escala.
|
||||
scales:
|
||||
super_small: Super pequeno
|
||||
small: Pequeno
|
||||
regular: Normal
|
||||
large: Grande
|
||||
huge: Gigante
|
||||
|
||||
scrollWheelSensitivity:
|
||||
title: Sensibilidade do zoom
|
||||
description: >-
|
||||
Altera a sensibilidade do zoom (scrol do mouse ou touchpad).
|
||||
sensitivity:
|
||||
super_slow: Super lento
|
||||
slow: Lento
|
||||
regular: Normal
|
||||
fast: Rápido
|
||||
super_fast: Super Rápido
|
||||
|
||||
fullscreen:
|
||||
title: Tecla Cheia
|
||||
description: >-
|
||||
É recomendável jogar o jogo em tela cheia para obter a melhor experiência. Disponível apenas na versão completa.
|
||||
|
||||
soundsMuted:
|
||||
title: Som
|
||||
description: >-
|
||||
Se ligado o jogo fica Mudo.
|
||||
|
||||
musicMuted:
|
||||
title: Musica
|
||||
description: >-
|
||||
Se ligado a musica é desligada.
|
||||
|
||||
theme:
|
||||
title: Tema
|
||||
description: >-
|
||||
Escolha o tema entre (Branco / Preto).
|
||||
|
||||
refreshRate:
|
||||
title: Frequencia
|
||||
description: >-
|
||||
Se você possui um monitor de 144 hz, altere a taxa de atualização aqui para que o jogo seja simulado corretamente com taxas de atualização mais altas. Isso pode realmente diminuir o FPS se o computador estiver muito lento.
|
||||
|
||||
alwaysMultiplace:
|
||||
title: Multiplicidade
|
||||
description: >-
|
||||
Se ativado, todos os edifícios permanecerão selecionados após o posicionamento até que você o cancele. Isso é equivalente a manter SHIFT permanentemente.
|
||||
|
||||
offerHints:
|
||||
title: Dicas e tutoriais
|
||||
description: >-
|
||||
Se deve oferecer dicas e tutoriais enquanto estiver jogando.v.
|
||||
|
||||
keybindings:
|
||||
title: Comandos
|
||||
hint: >-
|
||||
Tip: Certifique-se de usar CTRL, SHIFT e ALT! Eles permitem diferentes opções de veiculação.
|
||||
|
||||
resetKeybindings: Reset Keyinbindings
|
||||
|
||||
categoryLabels:
|
||||
general: Geral
|
||||
ingame: Jogo
|
||||
navigation: Navegação
|
||||
placement: Posicionamento
|
||||
massSelect: Seleção
|
||||
buildings: Construções
|
||||
placementModifiers: Modificações
|
||||
|
||||
mappings:
|
||||
confirm: Confirmar
|
||||
back: Voltar
|
||||
mapMoveUp: Mover para cima
|
||||
mapMoveRight: Mover para direita
|
||||
mapMoveDown: Mover para baixo
|
||||
mapMoveLeft: Mover para a esquerda
|
||||
centerMap: Centralizar
|
||||
|
||||
mapZoomIn: Aproximar
|
||||
mapZoomOut: Distanciar
|
||||
createMarker: Criar marcação
|
||||
|
||||
menuOpenShop: Atualizações
|
||||
menuOpenStats: Estatísticas
|
||||
|
||||
toggleHud: Ocultar Menu
|
||||
toggleFPSInfo: Mostar FPS
|
||||
belt: *belt
|
||||
splitter: *splitter
|
||||
underground_belt: *underground_belt
|
||||
miner: *miner
|
||||
cutter: *cutter
|
||||
rotater: *rotater
|
||||
stacker: *stacker
|
||||
mixer: *mixer
|
||||
painter: *painter
|
||||
trash: *trash
|
||||
|
||||
abortBuildingPlacement: Cancelar
|
||||
rotateWhilePlacing: Rotacionar
|
||||
rotateInverseModifier: >-
|
||||
Modifier: Rotação instantanea
|
||||
cycleBuildingVariants: Variações
|
||||
confirmMassDelete: Confirmar exclusão em massa
|
||||
cycleBuildings: Trocar de construção
|
||||
|
||||
massSelectStart: Segure e arraste para começar
|
||||
massSelectSelectMultiple: Selecionar área
|
||||
massSelectCopy: Copiar área
|
||||
|
||||
placementDisableAutoOrientation: Desligar orientações automaticas
|
||||
placeMultiple: Permanecer no modo de produção
|
||||
placeInverse: Inverter orientação de esteira
|
||||
|
||||
about:
|
||||
title: Sobre o jogo
|
||||
|
||||
changelog:
|
||||
title: Changelog
|
||||
|
||||
demo:
|
||||
features:
|
||||
restoringGames: Restaurando jogos salvos
|
||||
importingGames: Carregando jogos salvos
|
||||
oneGameLimit: Limitado para um savegamne
|
||||
customizeKeybindings: Modificando Teclas
|
||||
creatingMarkers: Criando marcações
|
||||
|
||||
settingNotAvailable: Não disponível na versão demo.
|
||||
@ -5604,6 +5604,11 @@ logalot@^2.0.0, logalot@^2.1.0:
|
||||
figures "^1.3.5"
|
||||
squeak "^1.0.0"
|
||||
|
||||
logrocket@^1.0.7:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/logrocket/-/logrocket-1.0.7.tgz#fe17dbdfc861481cd274fbda533d552de7800a3a"
|
||||
integrity sha512-v6HWEQIsyG+3FkldB7vIAgHh7/qpsiz2Br4bLK5SHBvjqRrHs/Fp+Jr8oiA2GYq0UurAtCu51U8SWft5+OCKtg==
|
||||
|
||||
longest@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097"
|
||||
|
||||