diff --git a/gulp/gulpfile.js b/gulp/gulpfile.js
index d87ba792..dd532cd7 100644
--- a/gulp/gulpfile.js
+++ b/gulp/gulpfile.js
@@ -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 }));
});
diff --git a/gulp/image-resources.js b/gulp/image-resources.js
index b01ca400..90268517 100644
--- a/gulp/image-resources.js
+++ b/gulp/image-resources.js
@@ -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 }
)
diff --git a/gulp/package.json b/gulp/package.json
index c4ab10c4..f2d542a8 100644
--- a/gulp/package.json
+++ b/gulp/package.json
@@ -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",
diff --git a/gulp/yarn.lock b/gulp/yarn.lock
index 7389e868..8e92a91f 100644
--- a/gulp/yarn.lock
+++ b/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"
diff --git a/res/ui/interactive_tutorial.noinline/1_1_extractor.gif b/res/ui/interactive_tutorial.noinline/1_1_extractor.gif
new file mode 100644
index 00000000..c7208ac2
Binary files /dev/null and b/res/ui/interactive_tutorial.noinline/1_1_extractor.gif differ
diff --git a/res/ui/interactive_tutorial.noinline/1_2_conveyor.gif b/res/ui/interactive_tutorial.noinline/1_2_conveyor.gif
new file mode 100644
index 00000000..db59bfd4
Binary files /dev/null and b/res/ui/interactive_tutorial.noinline/1_2_conveyor.gif differ
diff --git a/res/ui/interactive_tutorial.noinline/1_3_expand.gif b/res/ui/interactive_tutorial.noinline/1_3_expand.gif
new file mode 100644
index 00000000..9c655ab1
Binary files /dev/null and b/res/ui/interactive_tutorial.noinline/1_3_expand.gif differ
diff --git a/src/css/ingame_hud/blueprint_placer.scss b/src/css/ingame_hud/blueprint_placer.scss
index acf66087..e1cf06ef 100644
--- a/src/css/ingame_hud/blueprint_placer.scss
+++ b/src/css/ingame_hud/blueprint_placer.scss
@@ -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;
diff --git a/src/css/ingame_hud/building_placer.scss b/src/css/ingame_hud/building_placer.scss
index 0548390b..99c4d654 100644
--- a/src/css/ingame_hud/building_placer.scss
+++ b/src/css/ingame_hud/building_placer.scss
@@ -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;
diff --git a/src/css/ingame_hud/debug_info.scss b/src/css/ingame_hud/debug_info.scss
index 37e3a07c..f370d04e 100644
--- a/src/css/ingame_hud/debug_info.scss
+++ b/src/css/ingame_hud/debug_info.scss
@@ -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;
diff --git a/src/css/ingame_hud/interactive_tutorial.scss b/src/css/ingame_hud/interactive_tutorial.scss
new file mode 100644
index 00000000..d4fb58e1
--- /dev/null
+++ b/src/css/ingame_hud/interactive_tutorial.scss
@@ -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;
+ }
+}
diff --git a/src/css/ingame_hud/mass_selector.scss b/src/css/ingame_hud/mass_selector.scss
index 5ccbf86a..ddd2d40a 100644
--- a/src/css/ingame_hud/mass_selector.scss
+++ b/src/css/ingame_hud/mass_selector.scss
@@ -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;
diff --git a/src/css/ingame_hud/tutorial_hints.scss b/src/css/ingame_hud/tutorial_hints.scss
index 55603c4e..ad1096af 100644
--- a/src/css/ingame_hud/tutorial_hints.scss
+++ b/src/css/ingame_hud/tutorial_hints.scss
@@ -66,7 +66,7 @@
}
&.enlarged {
- background: rgba(50, 60, 70, 0.9);
+ background: $ingameHudBg;
left: 50%;
bottom: 50%;
transform: translate(-50%, 50%);
@@ -81,7 +81,7 @@
bottom: -1000px;
z-index: 0;
- background: rgba(50, 60, 70, 0.3);
+ background: rgba($ingameHudBg, 0.3);
}
.header {
diff --git a/src/css/main.scss b/src/css/main.scss
index 46fdab9c..10bf384e 100644
--- a/src/css/main.scss
+++ b/src/css/main.scss
@@ -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;
diff --git a/src/css/variables.scss b/src/css/variables.scss
index 03213900..5f056a00 100644
--- a/src/css/variables.scss
+++ b/src/css/variables.scss
@@ -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;
diff --git a/src/js/core/background_resources_loader.js b/src/js/core/background_resources_loader.js
index 28d414f2..ff99d23c 100644
--- a/src/js/core/background_resources_loader.js
+++ b/src/js/core/background_resources_loader.js
@@ -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 = [];
diff --git a/src/js/game/hud/hud.js b/src/js/game/hud/hud.js
index e1f1dbbf..e16431c3 100644
--- a/src/js/game/hud/hud.js
+++ b/src/js/game/hud/hud.js
@@ -31,6 +31,7 @@ import { HUDWaypoints } from "./parts/waypoints";
/* dev:start */
import { TrailerMaker } from "./trailer_maker";
+import { HUDInteractiveTutorial } from "./parts/interactive_tutorial";
/* dev:end */
export class GameHUD {
@@ -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();
diff --git a/src/js/game/hud/parts/interactive_tutorial.js b/src/js/game/hud/parts/interactive_tutorial.js
new file mode 100644
index 00000000..40273638
--- /dev/null
+++ b/src/js/game/hud/parts/interactive_tutorial.js
@@ -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"],
+ `
+ Tutorial
+ `
+ );
+
+ 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);
+ }
+}
diff --git a/src/js/game/hud/parts/tutorial_hints.js b/src/js/game/hud/parts/tutorial_hints.js
index 25d9aa3a..428923d0 100644
--- a/src/js/game/hud/parts/tutorial_hints.js
+++ b/src/js/game/hud/parts/tutorial_hints.js
@@ -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) {
diff --git a/src/js/game/tutorial_goals.js b/src/js/game/tutorial_goals.js
index 14b231f2..c7fa581b 100644
--- a/src/js/game/tutorial_goals.js
+++ b/src/js/game/tutorial_goals.js
@@ -35,7 +35,7 @@ export const tutorialGoals = [
// Circle
{
shape: "CuCuCuCu", // belts t1
- required: 20,
+ required: 40,
reward: enumHubGoalRewards.reward_cutter_and_trash,
},
diff --git a/translations/base-en.yaml b/translations/base-en.yaml
index a1d95c03..b9d5c4eb 100644
--- a/translations/base-en.yaml
+++ b/translations/base-en.yaml
@@ -310,12 +310,21 @@ 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.
Press to create a marker from the current view, or right-click to create a marker at the selected location.
creationSuccessNotification: Marker has been created.
+ # Interactive tutorial
+ interactiveTutorial:
+ title: Tutorial
+ hints:
+ 1_1_extractor: Place an extractor on top of a circle shape to extract it!
+ 1_2_conveyor: Connect the extractor with a conveyor belt to your hub!
+ 1_3_expand: This is NOT an idle game! Build more extractors and belts to finish the goal quicker.
+
# All shop upgrades
shopUpgrades:
belt: