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

Load css resources async, improve building descriptions

This commit is contained in:
tobspr 2020-09-23 11:14:35 +02:00
parent 9881bd6799
commit 1f12e755a9
49 changed files with 15779 additions and 15552 deletions

View File

@ -81,7 +81,7 @@ This project is based on ES5. Some ES2015 features are used but most of them are
8. In `translations/base-en.yaml` add it to two sections: `buildings.[my_building].XXX` (See other buildings) and also `keybindings.mappings.[my_building]`. Be sure to do it the same way as other buildings do! 8. In `translations/base-en.yaml` add it to two sections: `buildings.[my_building].XXX` (See other buildings) and also `keybindings.mappings.[my_building]`. Be sure to do it the same way as other buildings do!
9. Create a icon (128x128, [prefab](https://github.com/tobspr/shapez.io-artwork/blob/master/ui/toolbar-icons.psd)) for your building and save it in `res/ui/buildings_icons` with the id of your building 9. Create a icon (128x128, [prefab](https://github.com/tobspr/shapez.io-artwork/blob/master/ui/toolbar-icons.psd)) for your building and save it in `res/ui/buildings_icons` with the id of your building
10. Create a tutorial image (600x600) for your building and save it in `res/ui/building_tutorials` 10. Create a tutorial image (600x600) for your building and save it in `res/ui/building_tutorials`
11. In `src/css/icons.scss` add your building to `$buildings` as well as `$buildingAndVariants` 11. In `src/css/resources.scss` add your building to `$buildings` as well as `$buildingAndVariants`
12. Done! Optional: Add a new reward for unlocking your building at some point. 12. Done! Optional: Add a new reward for unlocking your building at some point.
#### Adding a new game system #### Adding a new game system

View File

@ -1,99 +1,135 @@
const path = require("path"); const path = require("path");
const buildUtils = require("./buildutils"); const buildUtils = require("./buildutils");
function gulptasksCSS($, gulp, buildFolder, browserSync) { function gulptasksCSS($, gulp, buildFolder, browserSync) {
// The assets plugin copies the files // The assets plugin copies the files
const commitHash = buildUtils.getRevision(); const commitHash = buildUtils.getRevision();
const postcssAssetsPlugin = cachebust => const postcssAssetsPlugin = cachebust =>
$.postcssAssets({ $.postcssAssets({
loadPaths: [path.join(buildFolder, "res", "ui")], loadPaths: [path.join(buildFolder, "res", "ui")],
basePath: buildFolder, basePath: buildFolder,
baseUrl: ".", baseUrl: ".",
cachebuster: cachebust cachebuster: cachebust
? (filePath, urlPathname) => ({ ? (filePath, urlPathname) => ({
pathname: buildUtils.cachebust(urlPathname, commitHash), pathname: buildUtils.cachebust(urlPathname, commitHash),
}) })
: "", : "",
}); });
// Postcss configuration // Postcss configuration
const postcssPlugins = (prod, { cachebust = false }) => { const postcssPlugins = (prod, { cachebust = false }) => {
const plugins = [postcssAssetsPlugin(cachebust)]; const plugins = [postcssAssetsPlugin(cachebust)];
if (prod) { if (prod) {
plugins.unshift( plugins.unshift(
$.postcssUnprefix(), $.postcssUnprefix(),
$.postcssPresetEnv({ $.postcssPresetEnv({
browsers: ["> 0.1%"], browsers: ["> 0.1%"],
}) })
); );
plugins.push( plugins.push(
$.cssMqpacker({ $.cssMqpacker({
sort: true, sort: true,
}), }),
$.cssnano({ $.cssnano({
preset: [ preset: [
"advanced", "advanced",
{ {
cssDeclarationSorter: false, cssDeclarationSorter: false,
discardUnused: true, discardUnused: true,
mergeIdents: false, mergeIdents: false,
reduceIdents: true, reduceIdents: true,
zindex: true, zindex: true,
}, },
], ],
}), }),
$.postcssRoundSubpixels() $.postcssRoundSubpixels()
); );
} }
return plugins; return plugins;
}; };
// Performs linting on css // Performs linting on css
gulp.task("css.lint", () => { gulp.task("css.lint", () => {
return gulp return gulp
.src(["../src/css/**/*.scss"]) .src(["../src/css/**/*.scss"])
.pipe($.sassLint({ configFile: ".sasslint.yml" })) .pipe($.sassLint({ configFile: ".sasslint.yml" }))
.pipe($.sassLint.format()) .pipe($.sassLint.format())
.pipe($.sassLint.failOnError()); .pipe($.sassLint.failOnError());
}); });
// Builds the css in dev mode function resourcesTask({ cachebust, isProd }) {
gulp.task("css.dev", () => { return gulp
return gulp .src("../src/css/main.scss", { cwd: __dirname })
.src(["../src/css/main.scss"]) .pipe($.plumber())
.pipe($.plumber()) .pipe($.sass.sync().on("error", $.sass.logError))
.pipe($.sass.sync().on("error", $.sass.logError)) .pipe(
.pipe($.postcss(postcssPlugins(false, {}))) $.postcss([
.pipe(gulp.dest(buildFolder)) $.postcssCriticalSplit({
.pipe(browserSync.stream()); blockTag: "@load-async",
}); }),
])
// Builds the css in production mode (=minified) )
gulp.task("css.prod", () => { .pipe($.rename("async-resources.css"))
return ( .pipe($.postcss(postcssPlugins(isProd, { cachebust })))
gulp .pipe(gulp.dest(buildFolder));
.src("../src/css/main.scss", { cwd: __dirname }) }
.pipe($.plumber())
.pipe($.sass.sync({ outputStyle: "compressed" }).on("error", $.sass.logError)) // Builds the css resources
.pipe($.postcss(postcssPlugins(true, { cachebust: true }))) gulp.task("css.resources.dev", () => {
.pipe(gulp.dest(buildFolder)) return resourcesTask({ cachebust: false, isProd: false });
); });
});
// Builds the css resources in prod (=minified)
// Builds the css in production mode (=minified), without cachebusting gulp.task("css.resources.prod", () => {
gulp.task("css.prod-standalone", () => { return resourcesTask({ cachebust: true, isProd: true });
return ( });
gulp
.src("../src/css/main.scss", { cwd: __dirname }) // Builds the css resources in prod (=minified), without cachebusting
.pipe($.plumber()) gulp.task("css.resources.prod-standalone", () => {
.pipe($.sass.sync({ outputStyle: "compressed" }).on("error", $.sass.logError)) return resourcesTask({ cachebust: false, isProd: true });
.pipe($.postcss(postcssPlugins(true, { cachebust: false }))) });
.pipe(gulp.dest(buildFolder))
); function mainTask({ cachebust, isProd }) {
}); return gulp
} .src("../src/css/main.scss", { cwd: __dirname })
.pipe($.plumber())
module.exports = { .pipe($.sass.sync().on("error", $.sass.logError))
gulptasksCSS, .pipe(
}; $.postcss([
$.postcssCriticalSplit({
blockTag: "@load-async",
output: "rest",
}),
])
)
.pipe($.postcss(postcssPlugins(isProd, { cachebust })))
.pipe(gulp.dest(buildFolder));
}
// Builds the css main
gulp.task("css.main.dev", () => {
return mainTask({ cachebust: false, isProd: false });
});
// Builds the css main in prod (=minified)
gulp.task("css.main.prod", () => {
return mainTask({ cachebust: true, isProd: true });
});
// Builds the css main in prod (=minified), without cachebusting
gulp.task("css.main.prod-standalone", () => {
return mainTask({ cachebust: false, isProd: true });
});
gulp.task("css.dev", gulp.parallel("css.main.dev", "css.resources.dev"));
gulp.task("css.prod", gulp.parallel("css.main.prod", "css.resources.prod"));
gulp.task(
"css.prod-standalone",
gulp.parallel("css.main.prod-standalone", "css.resources.prod-standalone")
);
}
module.exports = {
gulptasksCSS,
};

View File

@ -1,283 +1,301 @@
const buildUtils = require("./buildutils"); const buildUtils = require("./buildutils");
const fs = require("fs"); const fs = require("fs");
const path = require("path"); const path = require("path");
const crypto = require("crypto"); const crypto = require("crypto");
function computeIntegrityHash(fullPath, algorithm = "sha256") { function computeIntegrityHash(fullPath, algorithm = "sha256") {
const file = fs.readFileSync(fullPath); const file = fs.readFileSync(fullPath);
const hash = crypto.createHash(algorithm).update(file).digest("base64"); const hash = crypto.createHash(algorithm).update(file).digest("base64");
return algorithm + "-" + hash; return algorithm + "-" + hash;
} }
function gulptasksHTML($, gulp, buildFolder) { function gulptasksHTML($, gulp, buildFolder) {
const commitHash = buildUtils.getRevision(); const commitHash = buildUtils.getRevision();
async function buildHtml( async function buildHtml(
apiUrl, apiUrl,
{ analytics = false, standalone = false, app = false, integrity = true, enableCachebust = true } { analytics = false, standalone = false, app = false, integrity = true, enableCachebust = true }
) { ) {
function cachebust(url) { function cachebust(url) {
if (enableCachebust) { if (enableCachebust) {
return buildUtils.cachebust(url, commitHash); return buildUtils.cachebust(url, commitHash);
} }
return url; return url;
} }
const hasLocalFiles = standalone || app; const hasLocalFiles = standalone || app;
return gulp return gulp
.src("../src/html/" + (standalone ? "index.standalone.html" : "index.html")) .src("../src/html/" + (standalone ? "index.standalone.html" : "index.html"))
.pipe( .pipe(
$.dom(/** @this {Document} **/ function () { $.dom(
const document = this; /** @this {Document} **/ function () {
const document = this;
// Preconnect to api
const prefetchLink = document.createElement("link"); // Preconnect to api
prefetchLink.rel = "preconnect"; const prefetchLink = document.createElement("link");
prefetchLink.href = apiUrl; prefetchLink.rel = "preconnect";
prefetchLink.setAttribute("crossorigin", "anonymous"); prefetchLink.href = apiUrl;
document.head.appendChild(prefetchLink); prefetchLink.setAttribute("crossorigin", "anonymous");
document.head.appendChild(prefetchLink);
// Append css
const css = document.createElement("link"); // Append css
css.rel = "stylesheet"; const css = document.createElement("link");
css.type = "text/css"; css.rel = "stylesheet";
css.media = "none"; css.type = "text/css";
css.setAttribute("onload", "this.media='all'"); css.media = "none";
css.href = cachebust("main.css"); css.setAttribute("onload", "this.media='all'");
if (integrity) { css.href = cachebust("main.css");
css.setAttribute( if (integrity) {
"integrity", css.setAttribute(
computeIntegrityHash(path.join(buildFolder, "main.css")) "integrity",
); computeIntegrityHash(path.join(buildFolder, "main.css"))
} );
document.head.appendChild(css); }
document.head.appendChild(css);
if (app) {
// Append cordova link // Append async css
const cdv = document.createElement("script"); const asyncCss = document.createElement("link");
cdv.src = "cordova.js"; asyncCss.rel = "stylesheet";
cdv.type = "text/javascript"; asyncCss.type = "text/css";
document.head.appendChild(cdv); asyncCss.media = "none";
} asyncCss.setAttribute("onload", "this.media='all'");
asyncCss.href = cachebust("async-resources.css");
// Google analytics if (integrity) {
if (analytics) { asyncCss.setAttribute(
const tagManagerScript = document.createElement("script"); "integrity",
tagManagerScript.src = "https://www.googletagmanager.com/gtag/js?id=UA-165342524-1"; computeIntegrityHash(path.join(buildFolder, "async-resources.css"))
tagManagerScript.setAttribute("async", ""); );
document.head.appendChild(tagManagerScript); }
document.head.appendChild(asyncCss);
const initScript = document.createElement("script");
initScript.textContent = ` if (app) {
window.dataLayer = window.dataLayer || []; // Append cordova link
function gtag(){dataLayer.push(arguments);} const cdv = document.createElement("script");
gtag('js', new Date()); cdv.src = "cordova.js";
gtag('config', 'UA-165342524-1', { anonymize_ip: true }); cdv.type = "text/javascript";
`; document.head.appendChild(cdv);
document.head.appendChild(initScript); }
const abTestingScript = document.createElement("script"); // Google analytics
abTestingScript.setAttribute( if (analytics) {
"src", const tagManagerScript = document.createElement("script");
"https://www.googleoptimize.com/optimize.js?id=OPT-M5NHCV7" tagManagerScript.src =
); "https://www.googletagmanager.com/gtag/js?id=UA-165342524-1";
abTestingScript.setAttribute("async", ""); tagManagerScript.setAttribute("async", "");
document.head.appendChild(abTestingScript); document.head.appendChild(tagManagerScript);
}
const initScript = document.createElement("script");
// Do not need to preload in app or standalone initScript.textContent = `
if (!hasLocalFiles) { window.dataLayer = window.dataLayer || [];
// Preload essentials function gtag(){dataLayer.push(arguments);}
const preloads = ["fonts/GameFont.woff2"]; gtag('js', new Date());
gtag('config', 'UA-165342524-1', { anonymize_ip: true });
preloads.forEach(src => { `;
const preloadLink = document.createElement("link"); document.head.appendChild(initScript);
preloadLink.rel = "preload";
preloadLink.href = cachebust("res/" + src); const abTestingScript = document.createElement("script");
if (src.endsWith(".woff2")) { abTestingScript.setAttribute(
preloadLink.setAttribute("crossorigin", "anonymous"); "src",
preloadLink.setAttribute("as", "font"); "https://www.googleoptimize.com/optimize.js?id=OPT-M5NHCV7"
} else { );
preloadLink.setAttribute("as", "image"); abTestingScript.setAttribute("async", "");
} document.head.appendChild(abTestingScript);
document.head.appendChild(preloadLink); }
});
} // Do not need to preload in app or standalone
if (!hasLocalFiles) {
const loadingSvg = `background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46YXV0bztiYWNrZ3JvdW5kOjAgMCIgd2lkdGg9IjIwMCIgaGVpZ2h0PSIyMDAiIHZpZXdCb3g9IjAgMCAxMDAgMTAwIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCIgZGlzcGxheT0iYmxvY2siPjxjaXJjbGUgY3g9IjUwIiBjeT0iNTAiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzM5Mzc0NyIgc3Ryb2tlLXdpZHRoPSIzIiByPSI0MiIgc3Ryb2tlLWRhc2hhcnJheT0iMTk3LjkyMDMzNzE3NjE1Njk4IDY3Ljk3MzQ0NTcyNTM4NTY2IiB0cmFuc2Zvcm09InJvdGF0ZSg0OC4yNjUgNTAgNTApIj48YW5pbWF0ZVRyYW5zZm9ybSBhdHRyaWJ1dGVOYW1lPSJ0cmFuc2Zvcm0iIHR5cGU9InJvdGF0ZSIgcmVwZWF0Q291bnQ9ImluZGVmaW5pdGUiIGR1cj0iNS41NTU1NTU1NTU1NTU1NTVzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIi8+PC9jaXJjbGU+PC9zdmc+")`; // Preload essentials
const preloads = ["fonts/GameFont.woff2"];
const loadingCss = `
@font-face { preloads.forEach(src => {
font-family: 'GameFont'; const preloadLink = document.createElement("link");
font-style: normal; preloadLink.rel = "preload";
font-weight: normal; preloadLink.href = cachebust("res/" + src);
font-display: swap; if (src.endsWith(".woff2")) {
src: url('${cachebust("res/fonts/GameFont.woff2")}') format('woff2'); preloadLink.setAttribute("crossorigin", "anonymous");
} preloadLink.setAttribute("as", "font");
} else {
#ll_fp { preloadLink.setAttribute("as", "image");
font-family: GameFont; }
font-size: 14px; document.head.appendChild(preloadLink);
position: fixed; });
z-index: -1; }
top: 0;
left: 0; const loadingSvg = `background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46YXV0bztiYWNrZ3JvdW5kOjAgMCIgd2lkdGg9IjIwMCIgaGVpZ2h0PSIyMDAiIHZpZXdCb3g9IjAgMCAxMDAgMTAwIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCIgZGlzcGxheT0iYmxvY2siPjxjaXJjbGUgY3g9IjUwIiBjeT0iNTAiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzM5Mzc0NyIgc3Ryb2tlLXdpZHRoPSIzIiByPSI0MiIgc3Ryb2tlLWRhc2hhcnJheT0iMTk3LjkyMDMzNzE3NjE1Njk4IDY3Ljk3MzQ0NTcyNTM4NTY2IiB0cmFuc2Zvcm09InJvdGF0ZSg0OC4yNjUgNTAgNTApIj48YW5pbWF0ZVRyYW5zZm9ybSBhdHRyaWJ1dGVOYW1lPSJ0cmFuc2Zvcm0iIHR5cGU9InJvdGF0ZSIgcmVwZWF0Q291bnQ9ImluZGVmaW5pdGUiIGR1cj0iNS41NTU1NTU1NTU1NTU1NTVzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIi8+PC9jaXJjbGU+PC9zdmc+")`;
opacity: 0.05;
} const loadingCss = `
@font-face {
#ll_p { font-family: 'GameFont';
display: flex; font-style: normal;
position: fixed; font-weight: normal;
z-index: 99999; font-display: swap;
top: 0; src: url('${cachebust("res/fonts/GameFont.woff2")}') format('woff2');
left: 0; }
right: 0;
bottom: 0; #ll_fp {
justify-content: font-family: GameFont;
center; font-size: 14px;
align-items: center; position: fixed;
} z-index: -1;
top: 0;
#ll_p > div { left: 0;
position: absolute; opacity: 0.05;
text-align: center; }
bottom: 40px;
left: 20px; #ll_p {
right: 20px; display: flex;
color: #393747; position: fixed;
font-family: 'GameFont', sans-serif; z-index: 99999;
font-size: 20px; top: 0;
} left: 0;
right: 0;
#ll_p > span { bottom: 0;
width: 60px; justify-content:
height: 60px; center;
display: inline-flex; align-items: center;
background: center center / contain no-repeat; }
${loadingSvg};
} #ll_p > div {
`; position: absolute;
text-align: center;
const style = document.createElement("style"); bottom: 40px;
style.setAttribute("type", "text/css"); left: 20px;
style.textContent = loadingCss; right: 20px;
document.head.appendChild(style); color: #393747;
font-family: 'GameFont', sans-serif;
// Append loader, but not in standalone (directly include bundle there) font-size: 20px;
if (standalone) { }
const bundleScript = document.createElement("script");
bundleScript.type = "text/javascript"; #ll_p > span {
bundleScript.src = "bundle.js"; width: 60px;
if (integrity) { height: 60px;
bundleScript.setAttribute( display: inline-flex;
"integrity", background: center center / contain no-repeat;
computeIntegrityHash(path.join(buildFolder, "bundle.js")) ${loadingSvg};
); }
} `;
document.head.appendChild(bundleScript);
} else { const style = document.createElement("style");
const loadJs = document.createElement("script"); style.setAttribute("type", "text/css");
loadJs.type = "text/javascript"; style.textContent = loadingCss;
let scriptContent = ""; document.head.appendChild(style);
scriptContent += `var bundleSrc = '${cachebust("bundle.js")}';\n`;
scriptContent += `var bundleSrcTranspiled = '${cachebust( // Append loader, but not in standalone (directly include bundle there)
"bundle-transpiled.js" if (standalone) {
)}';\n`; const bundleScript = document.createElement("script");
bundleScript.type = "text/javascript";
if (integrity) { bundleScript.src = "bundle.js";
scriptContent += if (integrity) {
"var bundleIntegrity = '" + bundleScript.setAttribute(
computeIntegrityHash(path.join(buildFolder, "bundle.js")) + "integrity",
"';\n"; computeIntegrityHash(path.join(buildFolder, "bundle.js"))
scriptContent += );
"var bundleIntegrityTranspiled = '" + }
computeIntegrityHash(path.join(buildFolder, "bundle-transpiled.js")) + document.head.appendChild(bundleScript);
"';\n"; } else {
} else { const loadJs = document.createElement("script");
scriptContent += "var bundleIntegrity = null;\n"; loadJs.type = "text/javascript";
scriptContent += "var bundleIntegrityTranspiled = null;\n"; let scriptContent = "";
} scriptContent += `var bundleSrc = '${cachebust("bundle.js")}';\n`;
scriptContent += `var bundleSrcTranspiled = '${cachebust(
scriptContent += fs.readFileSync("./bundle-loader.js").toString(); "bundle-transpiled.js"
loadJs.textContent = scriptContent; )}';\n`;
document.head.appendChild(loadJs);
} if (integrity) {
scriptContent +=
const bodyContent = ` "var bundleIntegrity = '" +
<div id="ll_fp">_</div> computeIntegrityHash(path.join(buildFolder, "bundle.js")) +
<div id="ll_p"> "';\n";
<span></span> scriptContent +=
<div>${hasLocalFiles ? "Loading" : "Downloading"} Game Files</div > "var bundleIntegrityTranspiled = '" +
</div > computeIntegrityHash(path.join(buildFolder, "bundle-transpiled.js")) +
`; "';\n";
} else {
document.body.innerHTML = bodyContent; scriptContent += "var bundleIntegrity = null;\n";
}) scriptContent += "var bundleIntegrityTranspiled = null;\n";
) }
.pipe(
$.htmlmin({ scriptContent += fs.readFileSync("./bundle-loader.js").toString();
caseSensitive: true, loadJs.textContent = scriptContent;
collapseBooleanAttributes: true, document.head.appendChild(loadJs);
collapseInlineTagWhitespace: true, }
collapseWhitespace: true,
preserveLineBreaks: true, const bodyContent = `
minifyJS: true, <div id="ll_fp">_</div>
minifyCSS: true, <div id="ll_p">
quoteCharacter: '"', <span></span>
useShortDoctype: true, <div>${hasLocalFiles ? "Loading" : "Downloading"} Game Files</div >
}) </div >
) `;
.pipe($.htmlBeautify())
.pipe($.rename("index.html")) document.body.innerHTML = bodyContent;
.pipe(gulp.dest(buildFolder)); }
} )
)
gulp.task("html.dev", () => { .pipe(
return buildHtml("http://localhost:5005", { $.htmlmin({
analytics: false, caseSensitive: true,
integrity: false, collapseBooleanAttributes: true,
enableCachebust: false, collapseInlineTagWhitespace: true,
}); collapseWhitespace: true,
}); preserveLineBreaks: true,
minifyJS: true,
gulp.task("html.staging", () => { minifyCSS: true,
return buildHtml("https://api-staging.shapez.io", { quoteCharacter: '"',
analytics: true, useShortDoctype: true,
}); })
}); )
.pipe($.htmlBeautify())
gulp.task("html.prod", () => { .pipe($.rename("index.html"))
return buildHtml("https://analytics.shapez.io", { .pipe(gulp.dest(buildFolder));
analytics: true, }
});
}); gulp.task("html.dev", () => {
return buildHtml("http://localhost:5005", {
gulp.task("html.standalone-dev", () => { analytics: false,
return buildHtml("https://localhost:5005", { integrity: false,
analytics: false, enableCachebust: false,
standalone: true, });
integrity: false, });
enableCachebust: false,
}); gulp.task("html.staging", () => {
}); return buildHtml("https://api-staging.shapez.io", {
analytics: true,
gulp.task("html.standalone-beta", () => { });
return buildHtml("https://api-staging.shapez.io", { });
analytics: false,
standalone: true, gulp.task("html.prod", () => {
enableCachebust: false, return buildHtml("https://analytics.shapez.io", {
}); analytics: true,
}); });
});
gulp.task("html.standalone-prod", () => {
return buildHtml("https://analytics.shapez.io", { gulp.task("html.standalone-dev", () => {
analytics: false, return buildHtml("https://localhost:5005", {
standalone: true, analytics: false,
enableCachebust: false, standalone: true,
}); integrity: false,
}); enableCachebust: false,
} });
});
module.exports = {
gulptasksHTML, gulp.task("html.standalone-beta", () => {
}; return buildHtml("https://api-staging.shapez.io", {
analytics: false,
standalone: true,
enableCachebust: false,
});
});
gulp.task("html.standalone-prod", () => {
return buildHtml("https://analytics.shapez.io", {
analytics: false,
standalone: true,
enableCachebust: false,
});
});
}
module.exports = {
gulptasksHTML,
};

View File

@ -1,110 +1,111 @@
{ {
"name": "builder", "name": "builder",
"version": "1.0.0", "version": "1.0.0",
"description": "builder", "description": "builder",
"private": true, "private": true,
"scripts": { "scripts": {
"gulp": "gulp" "gulp": "gulp"
}, },
"author": "tobspr", "author": "tobspr",
"license": "private", "license": "private",
"dependencies": { "dependencies": {
"@babel/core": "^7.9.0", "@babel/core": "^7.9.0",
"@babel/plugin-transform-block-scoping": "^7.4.4", "@babel/plugin-transform-block-scoping": "^7.4.4",
"@babel/plugin-transform-classes": "^7.5.5", "@babel/plugin-transform-classes": "^7.5.5",
"@babel/preset-env": "^7.5.4", "@babel/preset-env": "^7.5.4",
"@types/cordova": "^0.0.34", "@types/cordova": "^0.0.34",
"@types/filesystem": "^0.0.29", "@types/filesystem": "^0.0.29",
"@types/node": "^12.7.5", "@types/node": "^12.7.5",
"ajv": "^6.10.2", "ajv": "^6.10.2",
"audiosprite": "^0.7.2", "audiosprite": "^0.7.2",
"babel-loader": "^8.1.0", "babel-loader": "^8.1.0",
"browser-sync": "^2.26.10", "browser-sync": "^2.26.10",
"circular-dependency-plugin": "^5.0.2", "circular-dependency-plugin": "^5.0.2",
"circular-json": "^0.5.9", "circular-json": "^0.5.9",
"clipboard-copy": "^3.1.0", "clipboard-copy": "^3.1.0",
"colors": "^1.3.3", "colors": "^1.3.3",
"core-js": "3", "core-js": "3",
"crypto": "^1.0.1", "crypto": "^1.0.1",
"cssnano-preset-advanced": "^4.0.7", "cssnano-preset-advanced": "^4.0.7",
"delete-empty": "^3.0.0", "delete-empty": "^3.0.0",
"email-validator": "^2.0.4", "email-validator": "^2.0.4",
"eslint": "^5.9.0", "eslint": "^5.9.0",
"fastdom": "^1.0.9", "fastdom": "^1.0.9",
"flatted": "^2.0.1", "flatted": "^2.0.1",
"fs-extra": "^8.1.0", "fs-extra": "^8.1.0",
"gulp-audiosprite": "^1.1.0", "gulp-audiosprite": "^1.1.0",
"howler": "^2.1.2", "howler": "^2.1.2",
"html-loader": "^0.5.5", "html-loader": "^0.5.5",
"ignore-loader": "^0.1.2", "ignore-loader": "^0.1.2",
"lz-string": "^1.4.4", "lz-string": "^1.4.4",
"markdown-loader": "^5.1.0", "markdown-loader": "^5.1.0",
"node-sri": "^1.1.1", "node-sri": "^1.1.1",
"phonegap-plugin-mobile-accessibility": "^1.0.5", "phonegap-plugin-mobile-accessibility": "^1.0.5",
"promise-polyfill": "^8.1.0", "promise-polyfill": "^8.1.0",
"query-string": "^6.8.1", "query-string": "^6.8.1",
"rusha": "^0.8.13", "rusha": "^0.8.13",
"serialize-error": "^3.0.0", "serialize-error": "^3.0.0",
"strictdom": "^1.0.1", "strictdom": "^1.0.1",
"string-replace-webpack-plugin": "^0.1.3", "string-replace-webpack-plugin": "^0.1.3",
"terser-webpack-plugin": "^1.1.0", "terser-webpack-plugin": "^1.1.0",
"through2": "^3.0.1", "through2": "^3.0.1",
"uglify-template-string-loader": "^1.1.0", "uglify-template-string-loader": "^1.1.0",
"unused-files-webpack-plugin": "^3.4.0", "unused-files-webpack-plugin": "^3.4.0",
"webpack": "^4.43.0", "webpack": "^4.43.0",
"webpack-cli": "^3.1.0", "webpack-cli": "^3.1.0",
"webpack-deep-scope-plugin": "^1.6.0", "webpack-deep-scope-plugin": "^1.6.0",
"webpack-plugin-replace": "^1.1.1", "webpack-plugin-replace": "^1.1.1",
"webpack-strip-block": "^0.2.0", "webpack-strip-block": "^0.2.0",
"whatwg-fetch": "^3.0.0", "whatwg-fetch": "^3.0.0",
"worker-loader": "^2.0.0" "worker-loader": "^2.0.0"
}, },
"devDependencies": { "devDependencies": {
"autoprefixer": "^9.4.3", "autoprefixer": "^9.4.3",
"babel-plugin-closure-elimination": "^1.3.0", "babel-plugin-closure-elimination": "^1.3.0",
"babel-plugin-console-source": "^2.0.2", "babel-plugin-console-source": "^2.0.2",
"babel-plugin-danger-remove-unused-import": "^1.1.2", "babel-plugin-danger-remove-unused-import": "^1.1.2",
"css-mqpacker": "^7.0.0", "css-mqpacker": "^7.0.0",
"cssnano": "^4.1.10", "cssnano": "^4.1.10",
"electron-packager": "^14.0.6", "postcss-critical-split": "^2.5.3",
"faster.js": "^1.1.0", "electron-packager": "^14.0.6",
"glob": "^7.1.3", "faster.js": "^1.1.0",
"gulp": "^4.0.2", "glob": "^7.1.3",
"gulp-cache": "^1.1.3", "gulp": "^4.0.2",
"gulp-cached": "^1.1.1", "gulp-cache": "^1.1.3",
"gulp-clean": "^0.4.0", "gulp-cached": "^1.1.1",
"gulp-dom": "^1.0.0", "gulp-clean": "^0.4.0",
"gulp-flatten": "^0.4.0", "gulp-dom": "^1.0.0",
"gulp-fluent-ffmpeg": "^2.0.0", "gulp-flatten": "^0.4.0",
"gulp-html-beautify": "^1.0.1", "gulp-fluent-ffmpeg": "^2.0.0",
"gulp-htmlmin": "^5.0.1", "gulp-html-beautify": "^1.0.1",
"gulp-if": "^3.0.0", "gulp-htmlmin": "^5.0.1",
"gulp-imagemin": "^7.1.0", "gulp-if": "^3.0.0",
"gulp-load-plugins": "^2.0.3", "gulp-imagemin": "^7.1.0",
"gulp-phonegap-build": "^0.1.5", "gulp-load-plugins": "^2.0.3",
"gulp-plumber": "^1.2.1", "gulp-phonegap-build": "^0.1.5",
"gulp-pngquant": "^1.0.13", "gulp-plumber": "^1.2.1",
"gulp-postcss": "^8.0.0", "gulp-pngquant": "^1.0.13",
"gulp-rename": "^2.0.0", "gulp-postcss": "^8.0.0",
"gulp-sass": "^4.1.0", "gulp-rename": "^2.0.0",
"gulp-sass-lint": "^1.4.0", "gulp-sass": "^4.1.0",
"gulp-sftp": "git+https://git@github.com/webksde/gulp-sftp", "gulp-sass-lint": "^1.4.0",
"gulp-terser": "^1.2.0", "gulp-sftp": "git+https://git@github.com/webksde/gulp-sftp",
"gulp-webserver": "^0.9.1", "gulp-terser": "^1.2.0",
"gulp-yaml": "^2.0.4", "gulp-webserver": "^0.9.1",
"imagemin-gifsicle": "^7.0.0", "gulp-yaml": "^2.0.4",
"imagemin-jpegtran": "^7.0.0", "imagemin-gifsicle": "^7.0.0",
"imagemin-pngquant": "^9.0.0", "imagemin-jpegtran": "^7.0.0",
"jimp": "^0.6.1", "imagemin-pngquant": "^9.0.0",
"js-yaml": "^3.13.1", "jimp": "^0.6.1",
"postcss-assets": "^5.0.0", "js-yaml": "^3.13.1",
"postcss-preset-env": "^6.5.0", "postcss-assets": "^5.0.0",
"postcss-round-subpixels": "^1.2.0", "postcss-preset-env": "^6.5.0",
"postcss-unprefix": "^2.1.3", "postcss-round-subpixels": "^1.2.0",
"sass-unused": "^0.3.0", "postcss-unprefix": "^2.1.3",
"strip-json-comments": "^3.0.1", "sass-unused": "^0.3.0",
"trim": "^0.0.1", "strip-json-comments": "^3.0.1",
"webpack-stream": "^5.2.1", "trim": "^0.0.1",
"yaml-loader": "^0.6.0" "webpack-stream": "^5.2.1",
} "yaml-loader": "^0.6.0"
} }
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 46 KiB

View File

@ -114,7 +114,7 @@
}, },
"sprites/belt/built/left_0.png": "sprites/belt/built/left_0.png":
{ {
"frame": {"x":569,"y":1845,"w":130,"h":130}, "frame": {"x":570,"y":1845,"w":130,"h":130},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":0,"y":14,"w":130,"h":130}, "spriteSourceSize": {"x":0,"y":14,"w":130,"h":130},
@ -250,7 +250,7 @@
}, },
"sprites/belt/built/right_3.png": "sprites/belt/built/right_3.png":
{ {
"frame": {"x":997,"y":1785,"w":130,"h":130}, "frame": {"x":998,"y":1785,"w":130,"h":130},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":14,"y":14,"w":130,"h":130}, "spriteSourceSize": {"x":14,"y":14,"w":130,"h":130},
@ -258,7 +258,7 @@
}, },
"sprites/belt/built/right_4.png": "sprites/belt/built/right_4.png":
{ {
"frame": {"x":1375,"y":1617,"w":130,"h":130}, "frame": {"x":1112,"y":1630,"w":130,"h":130},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":14,"y":14,"w":130,"h":130}, "spriteSourceSize": {"x":14,"y":14,"w":130,"h":130},
@ -266,7 +266,7 @@
}, },
"sprites/belt/built/right_5.png": "sprites/belt/built/right_5.png":
{ {
"frame": {"x":1511,"y":1710,"w":130,"h":130}, "frame": {"x":1248,"y":1619,"w":130,"h":130},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":14,"y":14,"w":130,"h":130}, "spriteSourceSize": {"x":14,"y":14,"w":130,"h":130},
@ -274,7 +274,7 @@
}, },
"sprites/belt/built/right_6.png": "sprites/belt/built/right_6.png":
{ {
"frame": {"x":1647,"y":1710,"w":130,"h":130}, "frame": {"x":1134,"y":1766,"w":130,"h":130},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":14,"y":14,"w":130,"h":130}, "spriteSourceSize": {"x":14,"y":14,"w":130,"h":130},
@ -282,7 +282,7 @@
}, },
"sprites/belt/built/right_7.png": "sprites/belt/built/right_7.png":
{ {
"frame": {"x":1783,"y":1747,"w":130,"h":130}, "frame": {"x":1270,"y":1755,"w":130,"h":130},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":14,"y":14,"w":130,"h":130}, "spriteSourceSize": {"x":14,"y":14,"w":130,"h":130},
@ -290,7 +290,7 @@
}, },
"sprites/belt/built/right_8.png": "sprites/belt/built/right_8.png":
{ {
"frame": {"x":1111,"y":1635,"w":130,"h":130}, "frame": {"x":1134,"y":1902,"w":130,"h":130},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":14,"y":14,"w":130,"h":130}, "spriteSourceSize": {"x":14,"y":14,"w":130,"h":130},
@ -298,7 +298,7 @@
}, },
"sprites/belt/built/right_9.png": "sprites/belt/built/right_9.png":
{ {
"frame": {"x":1133,"y":1771,"w":130,"h":130}, "frame": {"x":1270,"y":1891,"w":130,"h":130},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":14,"y":14,"w":130,"h":130}, "spriteSourceSize": {"x":14,"y":14,"w":130,"h":130},
@ -322,7 +322,7 @@
}, },
"sprites/belt/built/right_12.png": "sprites/belt/built/right_12.png":
{ {
"frame": {"x":975,"y":1649,"w":130,"h":130}, "frame": {"x":976,"y":1649,"w":130,"h":130},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":14,"y":14,"w":130,"h":130}, "spriteSourceSize": {"x":14,"y":14,"w":130,"h":130},
@ -378,7 +378,7 @@
}, },
"sprites/blueprints/belt_left.png": "sprites/blueprints/belt_left.png":
{ {
"frame": {"x":1168,"y":1907,"w":130,"h":130}, "frame": {"x":1406,"y":1877,"w":130,"h":130},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":0,"y":14,"w":130,"h":130}, "spriteSourceSize": {"x":0,"y":14,"w":130,"h":130},
@ -386,7 +386,7 @@
}, },
"sprites/blueprints/belt_right.png": "sprites/blueprints/belt_right.png":
{ {
"frame": {"x":1269,"y":1753,"w":130,"h":130}, "frame": {"x":1542,"y":1710,"w":130,"h":130},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":14,"y":14,"w":130,"h":130}, "spriteSourceSize": {"x":14,"y":14,"w":130,"h":130},
@ -426,7 +426,7 @@
}, },
"sprites/blueprints/display.png": "sprites/blueprints/display.png":
{ {
"frame": {"x":841,"y":1698,"w":128,"h":136}, "frame": {"x":842,"y":1698,"w":128,"h":136},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":8,"y":8,"w":128,"h":136}, "spriteSourceSize": {"x":8,"y":8,"w":128,"h":136},
@ -562,10 +562,10 @@
}, },
"sprites/blueprints/rotater-rotate180.png": "sprites/blueprints/rotater-rotate180.png":
{ {
"frame": {"x":271,"y":1735,"w":142,"h":144}, "frame": {"x":271,"y":1735,"w":143,"h":144},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":142,"h":144}, "spriteSourceSize": {"x":1,"y":0,"w":143,"h":144},
"sourceSize": {"w":144,"h":144} "sourceSize": {"w":144,"h":144}
}, },
"sprites/blueprints/rotater.png": "sprites/blueprints/rotater.png":
@ -666,7 +666,7 @@
}, },
"sprites/blueprints/virtual_processor-stacker.png": "sprites/blueprints/virtual_processor-stacker.png":
{ {
"frame": {"x":569,"y":1695,"w":130,"h":144}, "frame": {"x":570,"y":1695,"w":130,"h":144},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":14,"y":0,"w":130,"h":144}, "spriteSourceSize": {"x":14,"y":0,"w":130,"h":144},
@ -778,7 +778,7 @@
}, },
"sprites/buildings/belt_left.png": "sprites/buildings/belt_left.png":
{ {
"frame": {"x":569,"y":1845,"w":130,"h":130}, "frame": {"x":570,"y":1845,"w":130,"h":130},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":0,"y":14,"w":130,"h":130}, "spriteSourceSize": {"x":0,"y":14,"w":130,"h":130},
@ -826,7 +826,7 @@
}, },
"sprites/buildings/display.png": "sprites/buildings/display.png":
{ {
"frame": {"x":841,"y":1840,"w":126,"h":135}, "frame": {"x":842,"y":1840,"w":126,"h":135},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":9,"y":9,"w":126,"h":135}, "spriteSourceSize": {"x":9,"y":9,"w":126,"h":135},
@ -973,7 +973,7 @@
"frame": {"x":1286,"y":902,"w":141,"h":143}, "frame": {"x":1286,"y":902,"w":141,"h":143},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":141,"h":143}, "spriteSourceSize": {"x":2,"y":0,"w":141,"h":143},
"sourceSize": {"w":144,"h":144} "sourceSize": {"w":144,"h":144}
}, },
"sprites/buildings/rotater.png": "sprites/buildings/rotater.png":
@ -1042,7 +1042,7 @@
}, },
"sprites/buildings/virtual_processor-analyzer.png": "sprites/buildings/virtual_processor-analyzer.png":
{ {
"frame": {"x":419,"y":1735,"w":144,"h":144}, "frame": {"x":420,"y":1735,"w":144,"h":144},
"rotated": false, "rotated": false,
"trimmed": false, "trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":144,"h":144}, "spriteSourceSize": {"x":0,"y":0,"w":144,"h":144},
@ -1050,7 +1050,7 @@
}, },
"sprites/buildings/virtual_processor-painter.png": "sprites/buildings/virtual_processor-painter.png":
{ {
"frame": {"x":705,"y":1688,"w":130,"h":144}, "frame": {"x":706,"y":1688,"w":130,"h":144},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":14,"y":0,"w":130,"h":144}, "spriteSourceSize": {"x":14,"y":0,"w":130,"h":144},
@ -1074,7 +1074,7 @@
}, },
"sprites/buildings/virtual_processor-stacker.png": "sprites/buildings/virtual_processor-stacker.png":
{ {
"frame": {"x":705,"y":1838,"w":130,"h":144}, "frame": {"x":706,"y":1838,"w":130,"h":144},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":14,"y":0,"w":130,"h":144}, "spriteSourceSize": {"x":14,"y":0,"w":130,"h":144},
@ -1114,7 +1114,7 @@
}, },
"sprites/buildings/wire-turn.png": "sprites/buildings/wire-turn.png":
{ {
"frame": {"x":997,"y":1921,"w":81,"h":81}, "frame": {"x":998,"y":1921,"w":81,"h":81},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":63,"y":63,"w":81,"h":81}, "spriteSourceSize": {"x":63,"y":63,"w":81,"h":81},
@ -1146,7 +1146,7 @@
}, },
"sprites/colors/blue.png": "sprites/colors/blue.png":
{ {
"frame": {"x":1103,"y":1580,"w":54,"h":49}, "frame": {"x":566,"y":1981,"w":54,"h":49},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":0,"y":4,"w":54,"h":49}, "spriteSourceSize": {"x":0,"y":4,"w":54,"h":49},
@ -1154,7 +1154,7 @@
}, },
"sprites/colors/cyan.png": "sprites/colors/cyan.png":
{ {
"frame": {"x":1163,"y":1580,"w":54,"h":49}, "frame": {"x":626,"y":1981,"w":54,"h":49},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":0,"y":4,"w":54,"h":49}, "spriteSourceSize": {"x":0,"y":4,"w":54,"h":49},
@ -1162,7 +1162,7 @@
}, },
"sprites/colors/green.png": "sprites/colors/green.png":
{ {
"frame": {"x":705,"y":1988,"w":54,"h":49}, "frame": {"x":686,"y":1988,"w":54,"h":49},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":0,"y":4,"w":54,"h":49}, "spriteSourceSize": {"x":0,"y":4,"w":54,"h":49},
@ -1170,7 +1170,7 @@
}, },
"sprites/colors/purple.png": "sprites/colors/purple.png":
{ {
"frame": {"x":765,"y":1988,"w":54,"h":49}, "frame": {"x":746,"y":1988,"w":54,"h":49},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":0,"y":4,"w":54,"h":49}, "spriteSourceSize": {"x":0,"y":4,"w":54,"h":49},
@ -1178,7 +1178,7 @@
}, },
"sprites/colors/red.png": "sprites/colors/red.png":
{ {
"frame": {"x":1492,"y":1846,"w":54,"h":49}, "frame": {"x":806,"y":1988,"w":54,"h":49},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":0,"y":4,"w":54,"h":49}, "spriteSourceSize": {"x":0,"y":4,"w":54,"h":49},
@ -1186,7 +1186,7 @@
}, },
"sprites/colors/uncolored.png": "sprites/colors/uncolored.png":
{ {
"frame": {"x":1552,"y":1846,"w":54,"h":49}, "frame": {"x":866,"y":1981,"w":54,"h":49},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":0,"y":4,"w":54,"h":49}, "spriteSourceSize": {"x":0,"y":4,"w":54,"h":49},
@ -1194,7 +1194,7 @@
}, },
"sprites/colors/white.png": "sprites/colors/white.png":
{ {
"frame": {"x":1612,"y":1846,"w":54,"h":49}, "frame": {"x":1406,"y":1754,"w":54,"h":49},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":0,"y":4,"w":54,"h":49}, "spriteSourceSize": {"x":0,"y":4,"w":54,"h":49},
@ -1202,7 +1202,7 @@
}, },
"sprites/colors/yellow.png": "sprites/colors/yellow.png":
{ {
"frame": {"x":1672,"y":1846,"w":54,"h":49}, "frame": {"x":1406,"y":1809,"w":54,"h":49},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":0,"y":4,"w":54,"h":49}, "spriteSourceSize": {"x":0,"y":4,"w":54,"h":49},
@ -1210,7 +1210,7 @@
}, },
"sprites/debug/acceptor_slot.png": "sprites/debug/acceptor_slot.png":
{ {
"frame": {"x":1269,"y":1889,"w":12,"h":12}, "frame": {"x":1719,"y":555,"w":12,"h":12},
"rotated": false, "rotated": false,
"trimmed": false, "trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12},
@ -1218,7 +1218,7 @@
}, },
"sprites/debug/ejector_slot.png": "sprites/debug/ejector_slot.png":
{ {
"frame": {"x":1719,"y":555,"w":12,"h":12}, "frame": {"x":1921,"y":1028,"w":12,"h":12},
"rotated": false, "rotated": false,
"trimmed": false, "trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12},
@ -1226,7 +1226,7 @@
}, },
"sprites/misc/hub_direction_indicator.png": "sprites/misc/hub_direction_indicator.png":
{ {
"frame": {"x":1247,"y":1619,"w":48,"h":48}, "frame": {"x":1975,"y":266,"w":48,"h":48},
"rotated": false, "rotated": false,
"trimmed": false, "trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48}, "spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
@ -1234,7 +1234,7 @@
}, },
"sprites/misc/processor_disabled.png": "sprites/misc/processor_disabled.png":
{ {
"frame": {"x":1084,"y":1921,"w":78,"h":81}, "frame": {"x":1542,"y":1933,"w":78,"h":81},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":10,"y":10,"w":78,"h":81}, "spriteSourceSize": {"x":10,"y":10,"w":78,"h":81},
@ -1242,7 +1242,7 @@
}, },
"sprites/misc/processor_disconnected.png": "sprites/misc/processor_disconnected.png":
{ {
"frame": {"x":1304,"y":1619,"w":65,"h":84}, "frame": {"x":1629,"y":1846,"w":65,"h":84},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":17,"y":8,"w":65,"h":84}, "spriteSourceSize": {"x":17,"y":8,"w":65,"h":84},
@ -1258,7 +1258,7 @@
}, },
"sprites/misc/slot_bad_arrow.png": "sprites/misc/slot_bad_arrow.png":
{ {
"frame": {"x":1999,"y":161,"w":35,"h":35}, "frame": {"x":1626,"y":2009,"w":35,"h":35},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":2,"y":2,"w":35,"h":35}, "spriteSourceSize": {"x":2,"y":2,"w":35,"h":35},
@ -1266,7 +1266,7 @@
}, },
"sprites/misc/slot_good_arrow.png": "sprites/misc/slot_good_arrow.png":
{ {
"frame": {"x":1999,"y":116,"w":35,"h":39}, "frame": {"x":1198,"y":1580,"w":35,"h":39},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":2,"y":0,"w":35,"h":39}, "spriteSourceSize": {"x":2,"y":0,"w":35,"h":39},
@ -1274,7 +1274,7 @@
}, },
"sprites/misc/storage_overlay.png": "sprites/misc/storage_overlay.png":
{ {
"frame": {"x":566,"y":1981,"w":89,"h":44}, "frame": {"x":1103,"y":1580,"w":89,"h":44},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":89,"h":44}, "spriteSourceSize": {"x":1,"y":1,"w":89,"h":44},
@ -1282,7 +1282,7 @@
}, },
"sprites/misc/waypoint.png": "sprites/misc/waypoint.png":
{ {
"frame": {"x":661,"y":1981,"w":38,"h":48}, "frame": {"x":1999,"y":116,"w":38,"h":48},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":38,"h":48}, "spriteSourceSize": {"x":5,"y":0,"w":38,"h":48},
@ -1298,7 +1298,7 @@
}, },
"sprites/wires/boolean_true.png": "sprites/wires/boolean_true.png":
{ {
"frame": {"x":1999,"y":202,"w":22,"h":41}, "frame": {"x":1471,"y":1617,"w":22,"h":41},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":11,"y":5,"w":22,"h":41}, "spriteSourceSize": {"x":11,"y":5,"w":22,"h":41},
@ -1306,7 +1306,7 @@
}, },
"sprites/wires/display/blue.png": "sprites/wires/display/blue.png":
{ {
"frame": {"x":1391,"y":1927,"w":47,"h":47}, "frame": {"x":1975,"y":374,"w":47,"h":47},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":47,"h":47}, "spriteSourceSize": {"x":1,"y":1,"w":47,"h":47},
@ -1314,7 +1314,7 @@
}, },
"sprites/wires/display/cyan.png": "sprites/wires/display/cyan.png":
{ {
"frame": {"x":1444,"y":1927,"w":47,"h":47}, "frame": {"x":1975,"y":427,"w":47,"h":47},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":47,"h":47}, "spriteSourceSize": {"x":1,"y":1,"w":47,"h":47},
@ -1322,7 +1322,7 @@
}, },
"sprites/wires/display/green.png": "sprites/wires/display/green.png":
{ {
"frame": {"x":1370,"y":1980,"w":47,"h":47}, "frame": {"x":1971,"y":480,"w":47,"h":47},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":47,"h":47}, "spriteSourceSize": {"x":1,"y":1,"w":47,"h":47},
@ -1330,7 +1330,7 @@
}, },
"sprites/wires/display/purple.png": "sprites/wires/display/purple.png":
{ {
"frame": {"x":1423,"y":1980,"w":47,"h":47}, "frame": {"x":1971,"y":533,"w":47,"h":47},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":47,"h":47}, "spriteSourceSize": {"x":1,"y":1,"w":47,"h":47},
@ -1338,7 +1338,7 @@
}, },
"sprites/wires/display/red.png": "sprites/wires/display/red.png":
{ {
"frame": {"x":1497,"y":1901,"w":47,"h":47}, "frame": {"x":1989,"y":586,"w":47,"h":47},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":47,"h":47}, "spriteSourceSize": {"x":1,"y":1,"w":47,"h":47},
@ -1346,7 +1346,7 @@
}, },
"sprites/wires/display/white.png": "sprites/wires/display/white.png":
{ {
"frame": {"x":1550,"y":1901,"w":47,"h":47}, "frame": {"x":1989,"y":639,"w":47,"h":47},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":47,"h":47}, "spriteSourceSize": {"x":1,"y":1,"w":47,"h":47},
@ -1354,7 +1354,7 @@
}, },
"sprites/wires/display/yellow.png": "sprites/wires/display/yellow.png":
{ {
"frame": {"x":1603,"y":1901,"w":47,"h":47}, "frame": {"x":1765,"y":1747,"w":47,"h":47},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":47,"h":47}, "spriteSourceSize": {"x":1,"y":1,"w":47,"h":47},
@ -1378,7 +1378,7 @@
}, },
"sprites/wires/logical_ejector.png": "sprites/wires/logical_ejector.png":
{ {
"frame": {"x":1304,"y":1976,"w":60,"h":67}, "frame": {"x":1626,"y":1936,"w":60,"h":67},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":44,"y":0,"w":60,"h":67}, "spriteSourceSize": {"x":44,"y":0,"w":60,"h":67},
@ -1386,7 +1386,7 @@
}, },
"sprites/wires/network_conflict.png": "sprites/wires/network_conflict.png":
{ {
"frame": {"x":1656,"y":1901,"w":47,"h":44}, "frame": {"x":1384,"y":1704,"w":47,"h":44},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":1,"y":2,"w":47,"h":44}, "spriteSourceSize": {"x":1,"y":2,"w":47,"h":44},
@ -1394,7 +1394,7 @@
}, },
"sprites/wires/network_empty.png": "sprites/wires/network_empty.png":
{ {
"frame": {"x":1732,"y":1846,"w":41,"h":48}, "frame": {"x":1085,"y":1921,"w":41,"h":48},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":41,"h":48}, "spriteSourceSize": {"x":5,"y":0,"w":41,"h":48},
@ -1434,7 +1434,7 @@
}, },
"sprites/wires/sets/color_turn.png": "sprites/wires/sets/color_turn.png":
{ {
"frame": {"x":1405,"y":1753,"w":81,"h":81}, "frame": {"x":1384,"y":1617,"w":81,"h":81},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":63,"y":63,"w":81,"h":81}, "spriteSourceSize": {"x":63,"y":63,"w":81,"h":81},
@ -1450,7 +1450,7 @@
}, },
"sprites/wires/sets/conflict_forward.png": "sprites/wires/sets/conflict_forward.png":
{ {
"frame": {"x":973,"y":1840,"w":18,"h":144}, "frame": {"x":974,"y":1840,"w":18,"h":144},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":63,"y":0,"w":18,"h":144}, "spriteSourceSize": {"x":63,"y":0,"w":18,"h":144},
@ -1466,7 +1466,7 @@
}, },
"sprites/wires/sets/conflict_turn.png": "sprites/wires/sets/conflict_turn.png":
{ {
"frame": {"x":1304,"y":1889,"w":81,"h":81}, "frame": {"x":1678,"y":1710,"w":81,"h":81},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":63,"y":63,"w":81,"h":81}, "spriteSourceSize": {"x":63,"y":63,"w":81,"h":81},
@ -1498,7 +1498,7 @@
}, },
"sprites/wires/sets/regular_turn.png": "sprites/wires/sets/regular_turn.png":
{ {
"frame": {"x":997,"y":1921,"w":81,"h":81}, "frame": {"x":998,"y":1921,"w":81,"h":81},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":63,"y":63,"w":81,"h":81}, "spriteSourceSize": {"x":63,"y":63,"w":81,"h":81},
@ -1530,7 +1530,7 @@
}, },
"sprites/wires/sets/shape_turn.png": "sprites/wires/sets/shape_turn.png":
{ {
"frame": {"x":1405,"y":1840,"w":81,"h":81}, "frame": {"x":1542,"y":1846,"w":81,"h":81},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":63,"y":63,"w":81,"h":81}, "spriteSourceSize": {"x":63,"y":63,"w":81,"h":81},
@ -1538,7 +1538,7 @@
}, },
"sprites/wires/wires_preview.png": "sprites/wires/wires_preview.png":
{ {
"frame": {"x":1247,"y":1673,"w":48,"h":48}, "frame": {"x":1975,"y":320,"w":48,"h":48},
"rotated": false, "rotated": false,
"trimmed": false, "trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48}, "spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
@ -1551,6 +1551,6 @@
"format": "RGBA8888", "format": "RGBA8888",
"size": {"w":2048,"h":2048}, "size": {"w":2048,"h":2048},
"scale": "0.75", "scale": "0.75",
"smartupdate": "$TexturePacker:SmartUpdate:5aa559a5b0e7b321ad8bc0595f1e8ec0:3fcf23da2ddc6370c437cf41f6d44ed0:908b89f5ca8ff73e331a35a3b14d0604$" "smartupdate": "$TexturePacker:SmartUpdate:dac17f2501c07c842209cdd1895313a9:e5152751740891546eb27095657f7239:908b89f5ca8ff73e331a35a3b14d0604$"
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

View File

@ -1551,6 +1551,6 @@
"format": "RGBA8888", "format": "RGBA8888",
"size": {"w":1024,"h":1024}, "size": {"w":1024,"h":1024},
"scale": "0.25", "scale": "0.25",
"smartupdate": "$TexturePacker:SmartUpdate:5aa559a5b0e7b321ad8bc0595f1e8ec0:3fcf23da2ddc6370c437cf41f6d44ed0:908b89f5ca8ff73e331a35a3b14d0604$" "smartupdate": "$TexturePacker:SmartUpdate:dac17f2501c07c842209cdd1895313a9:e5152751740891546eb27095657f7239:908b89f5ca8ff73e331a35a3b14d0604$"
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 281 KiB

After

Width:  |  Height:  |  Size: 278 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 700 KiB

After

Width:  |  Height:  |  Size: 698 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -50,7 +50,6 @@
left: 0; left: 0;
right: 0; right: 0;
bottom: 0; bottom: 0;
background: rgba($mainBgColor, 0.9) uiResource("loading.svg") center center / #{D(60px)} no-repeat;
@include InlineAnimation(0.2s ease-in-out) { @include InlineAnimation(0.2s ease-in-out) {
0% { 0% {
opacity: 0; opacity: 0;
@ -59,6 +58,11 @@
opacity: 1; opacity: 1;
} }
} }
& {
/* @load-async */
background: rgba($mainBgColor, 0.9) uiResource("loading.svg") center center / #{D(60px)} no-repeat;
}
} }
} }
} }

View File

@ -391,11 +391,15 @@ canvas {
color: #393747; color: #393747;
&::after { &::after {
content: " "; content: " ";
background: uiResource("loading.svg") center center / contain no-repeat;
@include S(width, 35px); @include S(width, 35px);
@include S(height, 35px); @include S(height, 35px);
display: inline-block; display: inline-block;
vertical-align: middle; vertical-align: middle;
& {
/* @load-async */
background: uiResource("loading.svg") center center / contain no-repeat;
}
} }
@include InlineAnimation(1.5s ease-in-out infinite) { @include InlineAnimation(1.5s ease-in-out infinite) {
@ -451,7 +455,6 @@ canvas {
.prefab_InfoIcon { .prefab_InfoIcon {
@include S(width, 25px); @include S(width, 25px);
@include S(height, 25px); @include S(height, 25px);
// background: uiResource("icons_small/info.png") center center / contain no-repeat;
z-index: 100; z-index: 100;
opacity: 0.8; opacity: 0.8;
cursor: pointer; cursor: pointer;
@ -468,7 +471,6 @@ canvas {
justify-content: center; justify-content: center;
flex-direction: column; flex-direction: column;
.loadingImage { .loadingImage {
background: uiResource("loading.svg") center center / #{D(40px)} no-repeat;
width: 100%; width: 100%;
display: flex; display: flex;
flex-grow: 1; flex-grow: 1;
@ -478,6 +480,11 @@ canvas {
transform: scale(1.2) rotate(160deg); transform: scale(1.2) rotate(160deg);
} }
} }
& {
/* @load-async */
background: uiResource("loading.svg") center center / #{D(40px)} no-repeat;
}
} }
.prefab_GameHint { .prefab_GameHint {

View File

@ -69,14 +69,18 @@
&::before { &::before {
content: " "; content: " ";
background: uiResource("locked_building.png") center center / #{D(20px)} #{D(20px)}
no-repeat;
position: absolute; position: absolute;
top: 0; top: 0;
right: 0; right: 0;
bottom: 0; bottom: 0;
left: 0; left: 0;
z-index: 4; z-index: 4;
& {
/* @load-async */
background: uiResource("locked_building.png") center center / #{D(20px)} #{D(20px)}
no-repeat;
}
} }
} }

View File

@ -122,13 +122,16 @@
opacity: 0.7; opacity: 0.7;
@include S(width, 20px); @include S(width, 20px);
@include S(height, 20px); @include S(height, 20px);
background: uiResource("icons/close.png") center center / 80% no-repeat;
cursor: pointer; cursor: pointer;
pointer-events: all; pointer-events: all;
transition: opacity 0.2s ease-in-out; transition: opacity 0.2s ease-in-out;
&:hover { &:hover {
opacity: 0.4; opacity: 0.4;
} }
& {
/* @load-async */
background: uiResource("icons/close.png") center center / 80% no-repeat;
}
} }
} }

View File

@ -38,17 +38,26 @@
@include DarkThemeInvert; @include DarkThemeInvert;
&.shop { &.shop {
background-image: uiResource("icons/shop.png");
grid-column: 1; grid-column: 1;
& {
/* @load-async */
background-image: uiResource("icons/shop.png");
}
} }
&.stats { &.stats {
background-image: uiResource("icons/statistics.png");
grid-column: 2; grid-column: 2;
& {
/* @load-async */
background-image: uiResource("icons/statistics.png");
}
} }
&.save { &.save {
background-image: uiResource("icons/save.png"); & {
/* @load-async */
background-image: uiResource("icons/save.png");
}
grid-column: 3; grid-column: 3;
@include MakeAnimationWrappedEvenOdd(0.5s ease-in-out) { @include MakeAnimationWrappedEvenOdd(0.5s ease-in-out) {
0% { 0% {
@ -83,8 +92,11 @@
} }
&.settings { &.settings {
background-image: uiResource("icons/settings_menu_settings.png");
grid-column: 4; grid-column: 4;
& {
/* @load-async */
background-image: uiResource("icons/settings_menu_settings.png");
}
} }
&:hover { &:hover {
@ -99,9 +111,14 @@
&.hasBadge { &.hasBadge {
&.shop { &.shop {
filter: none; filter: none;
background-image: uiResource("icons/shop_active.png");
opacity: 0.9; opacity: 0.9;
& {
/* @load-async */
background-image: uiResource("icons/shop_active.png");
}
} }
transform-origin: 50% 50%; transform-origin: 50% 50%;
@include InlineAnimation(0.8s ease-in-out infinite) { @include InlineAnimation(0.8s ease-in-out infinite) {
50% { 50% {

View File

@ -47,10 +47,12 @@
left: unset; left: unset;
margin: 0; margin: 0;
&.rightMouse { &.rightMouse {
/* @load-async */
background: #fff uiResource("icons/mouse_right.png") center center / 85% no-repeat; background: #fff uiResource("icons/mouse_right.png") center center / 85% no-repeat;
} }
&.leftMouse { &.leftMouse {
/* @load-async */
background: #fff uiResource("icons/mouse_left.png") center center / 85% no-repeat; background: #fff uiResource("icons/mouse_left.png") center center / 85% no-repeat;
} }
} }

View File

@ -77,7 +77,6 @@
> .infoButton { > .infoButton {
@include S(width, 8px); @include S(width, 8px);
@include S(height, 8px); @include S(height, 8px);
background: uiResource("icons/info_button.png") center center / 95% no-repeat;
position: absolute; position: absolute;
opacity: 0.7; opacity: 0.7;
@include S(top, 13px); @include S(top, 13px);
@ -90,6 +89,11 @@
&:hover { &:hover {
opacity: 0.8; opacity: 0.8;
} }
& {
/* @load-async */
background: uiResource("icons/info_button.png") center center / 95% no-repeat;
}
} }
&.goal, &.goal,
@ -107,11 +111,13 @@
&.goal .amountLabel { &.goal .amountLabel {
&::after { &::after {
/* @load-async */
background-image: uiResource("icons/current_goal_marker.png"); background-image: uiResource("icons/current_goal_marker.png");
background-size: 90%; background-size: 90%;
} }
@include DarkThemeOverride { @include DarkThemeOverride {
&::after { &::after {
/* @load-async */
background-image: uiResource("icons/current_goal_marker_inverted.png") !important; background-image: uiResource("icons/current_goal_marker_inverted.png") !important;
} }
} }
@ -119,11 +125,13 @@
&.blueprint .amountLabel { &.blueprint .amountLabel {
&::after { &::after {
/* @load-async */
background-image: uiResource("icons/blueprint_marker.png"); background-image: uiResource("icons/blueprint_marker.png");
background-size: 90%; background-size: 90%;
} }
@include DarkThemeOverride { @include DarkThemeOverride {
&::after { &::after {
/* @load-async */
background-image: uiResource("icons/blueprint_marker_inverted.png") !important; background-image: uiResource("icons/blueprint_marker_inverted.png") !important;
} }
} }

View File

@ -39,23 +39,29 @@
background: transparent; background: transparent;
filter: invert(1); filter: invert(1);
background: uiResource("icons/settings_menu_play.png") center top / contain no-repeat;
content: ""; content: "";
opacity: 0.8; opacity: 0.8;
@include S(width, 35px); @include S(width, 35px);
@include S(height, 35px); @include S(height, 35px);
&.settings { &.settings {
/* @load-async */
background-image: uiResource("icons/settings_menu_settings.png"); background-image: uiResource("icons/settings_menu_settings.png");
} }
&.menu { &.menu {
/* @load-async */
background-image: uiResource("icons/settings_menu_exit.png"); background-image: uiResource("icons/settings_menu_exit.png");
} }
&:hover { &:hover {
opacity: 0.6; opacity: 0.6;
} }
& {
/* @load-async */
background: uiResource("icons/settings_menu_play.png") center top / contain no-repeat;
}
} }
} }
} }

View File

@ -113,9 +113,13 @@
overflow: hidden; overflow: hidden;
button.pin { button.pin {
& {
/* @load-async */
background: uiResource("icons/pin.png") center center / 95% no-repeat;
}
@include S(width, 12px); @include S(width, 12px);
@include S(height, 12px); @include S(height, 12px);
background: uiResource("icons/pin.png") center center / 95% no-repeat;
position: absolute; position: absolute;
@include S(top, 2px); @include S(top, 2px);
@include S(right, 2px); @include S(right, 2px);
@ -143,6 +147,7 @@
} }
&.isGoal { &.isGoal {
/* @load-async */
background: uiResource("icons/current_goal_marker.png") center center / 95% background: uiResource("icons/current_goal_marker.png") center center / 95%
no-repeat; no-repeat;
opacity: $disabledOpacity !important; opacity: $disabledOpacity !important;
@ -198,7 +203,6 @@
button.showInfo { button.showInfo {
@include S(width, 11px); @include S(width, 11px);
@include S(height, 11px); @include S(height, 11px);
background: uiResource("icons/info_button.png") center center / 95% no-repeat;
position: absolute; position: absolute;
@include S(top, 17px); @include S(top, 17px);
@include S(right, 2.5px); @include S(right, 2.5px);
@ -213,6 +217,10 @@
opacity: 0.6; opacity: 0.6;
} }
} }
button.showInfo {
/* @load-async */
background: uiResource("icons/info_button.png") center center / 95% no-repeat;
}
canvas { canvas {
@include S(width, 40px); @include S(width, 40px);

View File

@ -39,10 +39,12 @@
} }
&.displayDetailed { &.displayDetailed {
/* @load-async */
background-image: uiResource("icons/display_list.png"); background-image: uiResource("icons/display_list.png");
} }
&.displayIcons { &.displayIcons {
/* @load-async */
background-image: uiResource("icons/display_icons.png"); background-image: uiResource("icons/display_icons.png");
background-size: #{D(11.5px)}; background-size: #{D(11.5px)};
} }
@ -53,7 +55,10 @@
} }
&.displaySorted { &.displaySorted {
background-image: uiResource("icons/display_sorted.png"); & {
/* @load-async */
background-image: uiResource("icons/display_sorted.png");
}
background-size: #{D(11.5px)}; background-size: #{D(11.5px)};
margin-right: 5px; margin-right: 5px;
@include S(border-top-right-radius, $globalBorderRadius); @include S(border-top-right-radius, $globalBorderRadius);
@ -63,7 +68,10 @@
} }
&.displayIterateUnit { &.displayIterateUnit {
background-image: uiResource("icons/toggle_unit.png"); & {
/* @load-async */
background-image: uiResource("icons/toggle_unit.png");
}
opacity: 0.8; opacity: 0.8;
@include S(padding, 1px, 0); @include S(padding, 1px, 0);
} }

View File

@ -1,117 +1,120 @@
#ingame_HUD_TutorialHints { #ingame_HUD_TutorialHints {
position: absolute; position: absolute;
@include S(left, 10px); @include S(left, 10px);
@include S(bottom, 10px); @include S(bottom, 10px);
@include StyleBelowWidth(1430px) { @include StyleBelowWidth(1430px) {
@include S(bottom, 50px); @include S(bottom, 50px);
} }
display: flex; display: flex;
flex-direction: column; flex-direction: column;
background: rgba(50, 60, 70, 0); background: rgba(50, 60, 70, 0);
transition: all 0.2s ease-in-out; transition: all 0.2s ease-in-out;
pointer-events: all; pointer-events: all;
transition-property: background-color, transform, bottom, left; transition-property: background-color, transform, bottom, left;
@include S(padding, 5px); @include S(padding, 5px);
video { video {
transition: all 0.2s ease-in-out; transition: all 0.2s ease-in-out;
transition-property: opacity, width; transition-property: opacity, width;
@include S(width, 0px); @include S(width, 0px);
opacity: 0; opacity: 0;
z-index: 10; z-index: 10;
position: relative; position: relative;
} }
.header { .header {
color: #333438; color: #333438;
display: grid; display: grid;
align-items: center; align-items: center;
@include S(grid-gap, 2px); @include S(grid-gap, 2px);
grid-template-columns: 1fr; grid-template-columns: 1fr;
@include S(margin-bottom, 3px); @include S(margin-bottom, 3px);
z-index: 11; z-index: 11;
position: relative; position: relative;
> span { > span {
@include DarkThemeInvert; @include DarkThemeInvert;
display: flex; display: flex;
@include SuperSmallText; @include SuperSmallText;
justify-content: flex-start; justify-content: flex-start;
align-items: center; align-items: center;
&::before { &::before {
@include S(margin-right, 4px); @include S(margin-right, 4px);
content: " "; content: " ";
@include S(width, 12px); @include S(width, 12px);
@include S(height, 12px); @include S(height, 12px);
display: inline-block; display: inline-block;
background: uiResource("icons/help.png") center center / 95% no-repeat; & {
} /* @load-async */
} background: uiResource("icons/help.png") center center / 95% no-repeat;
}
button.toggleHint { }
@include PlainText; }
@include IncreasedClickArea(0px);
} button.toggleHint {
} @include PlainText;
@include IncreasedClickArea(0px);
button.toggleHint { }
.hide { }
display: none;
} button.toggleHint {
} .hide {
display: none;
&.enlarged { }
background: $ingameHudBg; }
left: 50%;
bottom: 50%; &.enlarged {
transform: translate(-50%, 50%); background: $ingameHudBg;
left: 50%;
&::before { bottom: 50%;
pointer-events: all; transform: translate(-50%, 50%);
content: " ";
position: fixed; &::before {
top: -1000px; pointer-events: all;
left: -1000px; content: " ";
right: -1000px; position: fixed;
bottom: -1000px; top: -1000px;
z-index: 0; left: -1000px;
right: -1000px;
background: rgba($ingameHudBg, 0.3); bottom: -1000px;
} z-index: 0;
.header { background: rgba($ingameHudBg, 0.3);
grid-template-columns: 1fr auto; }
> span {
display: none; .header {
} grid-template-columns: 1fr auto;
button.toggleHint { > span {
grid-column: 2 / 3; display: none;
} }
} button.toggleHint {
grid-column: 2 / 3;
video { }
@include InlineAnimation(0.2s ease-in-out) { }
0% {
opacity: 0; video {
@include S(width, 0px); @include InlineAnimation(0.2s ease-in-out) {
} 0% {
} opacity: 0;
@include S(width, 0px);
opacity: 1; }
@include S(width, 500px); }
}
button.toggleHint { opacity: 1;
.hide { @include S(width, 500px);
display: block; }
} button.toggleHint {
.show { .hide {
display: none; display: block;
} }
} .show {
} display: none;
} }
}
}
}

View File

@ -1,177 +1,181 @@
#ingame_HUD_UnlockNotification { #ingame_HUD_UnlockNotification {
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
right: 0; right: 0;
bottom: 0; bottom: 0;
background: rgba(#333538, 0.98) uiResource("dialog_bg_pattern.png") top left / #{D(10px)} repeat; display: flex;
display: flex; justify-content: center;
justify-content: center; align-items: center;
align-items: center; pointer-events: all;
pointer-events: all;
& {
@include InlineAnimation(0.1s ease-in-out) { /* @load-async */
0% { background: rgba(#333538, 0.98) uiResource("dialog_bg_pattern.png") top left / #{D(10px)} repeat;
opacity: 0; }
}
} @include InlineAnimation(0.1s ease-in-out) {
0% {
.dialog { opacity: 0;
// background: rgba(#222428, 0.5); }
@include S(border-radius, $globalBorderRadius); }
@include S(padding, 30px);
.dialog {
@include InlineAnimation(0.5s ease-in-out) { // background: rgba(#222428, 0.5);
0% { @include S(border-radius, $globalBorderRadius);
opacity: 0; @include S(padding, 30px);
}
} @include InlineAnimation(0.5s ease-in-out) {
display: flex; 0% {
align-items: center; opacity: 0;
flex-direction: column; }
max-height: 100vh; }
display: flex;
color: #fff; align-items: center;
text-align: center; flex-direction: column;
.title, max-height: 100vh;
.subTitle {
@include SuperHeading; color: #fff;
text-transform: uppercase; text-align: center;
@include S(font-size, 40px); .title,
.subTitle {
@include InlineAnimation(0.5s ease-in-out) { @include SuperHeading;
0% { text-transform: uppercase;
transform: translateY(-50vh); @include S(font-size, 40px);
}
50% { @include InlineAnimation(0.5s ease-in-out) {
transform: translateY(5vh); 0% {
} transform: translateY(-50vh);
75% { }
transform: translateY(-2vh); 50% {
} transform: translateY(5vh);
} }
} 75% {
transform: translateY(-2vh);
.subTitle { }
@include PlainText; }
display: inline-block; }
@include S(margin, 5px, 0, 20px);
color: $colorGreenBright; .subTitle {
@include PlainText;
@include S(border-radius, $globalBorderRadius); display: inline-block;
@include InlineAnimation(0.5s ease-in-out) { @include S(margin, 5px, 0, 20px);
0% { color: $colorGreenBright;
transform: translateY(-60vh);
} @include S(border-radius, $globalBorderRadius);
50% { @include InlineAnimation(0.5s ease-in-out) {
transform: translateY(6vh); 0% {
} transform: translateY(-60vh);
75% { }
transform: translateY(-3vh); 50% {
} transform: translateY(6vh);
} }
} 75% {
transform: translateY(-3vh);
.contents { }
@include S(width, 400px); }
@include InlineAnimation(0.5s ease-in-out) { }
0% {
transform: translateX(-100vw); .contents {
} @include S(width, 400px);
50% { @include InlineAnimation(0.5s ease-in-out) {
transform: translateX(5vw); 0% {
} transform: translateX(-100vw);
}
75% { 50% {
transform: translateX(-2vw); transform: translateX(5vw);
} }
}
display: flex; 75% {
flex-direction: column; transform: translateX(-2vw);
align-items: center; }
justify-content: center; }
@include S(grid-gap, 10px); display: flex;
flex-direction: column;
.rewardName { align-items: center;
grid-column: 1 / 3; justify-content: center;
display: none; @include S(grid-gap, 10px);
@include InlineAnimation(0.5s ease-in-out) {
0% { .rewardName {
transform: translateX(200vw); grid-column: 1 / 3;
} display: none;
50% { @include InlineAnimation(0.5s ease-in-out) {
transform: translateX(-10vw); 0% {
} transform: translateX(200vw);
}
75% { 50% {
transform: translateX(4vw); transform: translateX(-10vw);
} }
}
} 75% {
transform: translateX(4vw);
.rewardDesc { }
grid-column: 1 / 3; }
@include PlainText; }
@include S(margin-bottom, 15px);
color: #aaacaf; .rewardDesc {
@include S(width, 400px); grid-column: 1 / 3;
text-align: left; @include PlainText;
strong { @include S(margin-bottom, 15px);
color: #fff; color: #aaacaf;
} @include S(width, 400px);
} text-align: left;
strong {
.images { color: #fff;
display: flex; }
.buildingExplanation { }
@include S(width, 200px);
@include S(height, 200px); .images {
display: inline-block; display: flex;
background-position: center center; .buildingExplanation {
background-size: cover; @include S(width, 200px);
background-repeat: no-repeat; @include S(height, 200px);
@include S(border-radius, $globalBorderRadius); display: inline-block;
box-shadow: #{D(2px)} #{D(3px)} 0 0 rgba(0, 0, 0, 0.15); background-position: center center;
} background-size: cover;
} background-repeat: no-repeat;
} @include S(border-radius, $globalBorderRadius);
box-shadow: #{D(2px)} #{D(3px)} 0 0 rgba(0, 0, 0, 0.15);
button.close { }
border: 0; }
position: relative; }
@include S(margin-top, 30px);
button.close {
&:not(.unlocked) { border: 0;
pointer-events: none; position: relative;
opacity: 0.8; @include S(margin-top, 30px);
cursor: default;
} &:not(.unlocked) {
pointer-events: none;
&.unlocked { opacity: 0.8;
&::after { cursor: default;
animation: none !important; }
}
} &.unlocked {
&::after {
&::after { animation: none !important;
content: " "; }
display: inline-block; }
position: absolute;
top: 0; &::after {
left: 100%; content: " ";
right: 0; display: inline-block;
bottom: 0; position: absolute;
background: rgba(0, 10, 20, 0.8); top: 0;
left: 100%;
@include InlineAnimation(5s linear) { right: 0;
0% { bottom: 0;
left: 0; background: rgba(0, 10, 20, 0.8);
}
100% { @include InlineAnimation(5s linear) {
left: 100%; 0% {
} left: 0;
} }
} 100% {
} left: 100%;
} }
} }
}
}
}
}

View File

@ -4,7 +4,10 @@
left: 0; left: 0;
right: 0; right: 0;
bottom: 0; bottom: 0;
background: uiResource("vignette.lossless.png") center center / cover no-repeat; & {
/* @load-async */
background: uiResource("vignette.lossless.png") center center / cover no-repeat;
}
pointer-events: none; pointer-events: none;
@include DarkThemeOverride { @include DarkThemeOverride {

View File

@ -1,18 +1,22 @@
#ingame_HUD_Watermark { #ingame_HUD_Watermark {
position: absolute; position: absolute;
background: uiResource("get_on_steam.png") center center / contain no-repeat; & {
@include S(width, 110px); /* @load-async */
@include S(height, 40px); background: uiResource("get_on_steam.png") center center / contain no-repeat;
@include S(top, 10px); }
pointer-events: all;
cursor: pointer; @include S(width, 110px);
@include S(left, 160px); @include S(height, 40px);
@include S(top, 10px);
transition: all 0.12s ease-in; pointer-events: all;
transition-property: opacity, transform; cursor: pointer;
transform: skewX(-0.5deg); @include S(left, 160px);
&:hover {
transform: skewX(-1deg) scale(1.02); transition: all 0.12s ease-in;
opacity: 0.9; transition-property: opacity, transform;
} transform: skewX(-0.5deg);
} &:hover {
transform: skewX(-1deg) scale(1.02);
opacity: 0.9;
}
}

View File

@ -55,7 +55,10 @@
display: grid; display: grid;
grid-template-columns: 1fr auto; grid-template-columns: 1fr auto;
align-items: center; align-items: center;
background: uiResource("icons/waypoint.png") left 50% / #{D(8px)} no-repeat; & {
/* @load-async */
background: uiResource("icons/waypoint.png") left 50% / #{D(8px)} no-repeat;
}
opacity: 0.7; opacity: 0.7;
@include S(margin-bottom, 1px); @include S(margin-bottom, 1px);
font-weight: bold; font-weight: bold;
@ -68,7 +71,10 @@
@include S(width, 10px); @include S(width, 10px);
@include S(height, 10px); @include S(height, 10px);
@include S(margin-left, 4px); @include S(margin-left, 4px);
background: uiResource("icons/edit_key.png") center center / 70% no-repeat; & {
/* @load-async */
background: uiResource("icons/edit_key.png") center center / 70% no-repeat;
}
pointer-events: all; pointer-events: all;
cursor: pointer; cursor: pointer;
position: relative; position: relative;

View File

@ -6,7 +6,7 @@
@return inline($pth); @return inline($pth);
} }
@import "icons"; @import "resources";
@import "trigonometry"; @import "trigonometry";
@import "material_colors"; @import "material_colors";
@import "dynamic_ui"; @import "dynamic_ui";

View File

@ -1,363 +1,316 @@
// ---------------------------------------- // ----------------------------------------
/* Forces an element to get rendered on its own layer, increasing /* Forces an element to get rendered on its own layer, increasing
the performance when animated. Use only transform and opacity in animations! */ the performance when animated. Use only transform and opacity in animations! */
@mixin FastAnimation { @mixin FastAnimation {
will-change: transform, opacity, filter; will-change: transform, opacity, filter;
// transform: translateZ(0); // transform: translateZ(0);
backface-visibility: hidden; backface-visibility: hidden;
-webkit-backface-visibility: hidden; -webkit-backface-visibility: hidden;
} }
// Helper which includes the translateZ webkit fix, use together with Fast animation // Helper which includes the translateZ webkit fix, use together with Fast animation
// $hardwareAcc: translateZ(0); // $hardwareAcc: translateZ(0);
$hardwareAcc: null; $hardwareAcc: null;
// ---------------------------------------- // ----------------------------------------
/** Increased click area for this element, helpful on mobile */ /** Increased click area for this element, helpful on mobile */
@mixin IncreasedClickArea($size) { @mixin IncreasedClickArea($size) {
&::after { &::after {
content: ""; content: "";
position: absolute; position: absolute;
top: #{D(-$size)}; top: #{D(-$size)};
bottom: #{D(-$size)}; bottom: #{D(-$size)};
left: #{D(-$size)}; left: #{D(-$size)};
right: #{D(-$size)}; right: #{D(-$size)};
// background: rgba(255, 0, 0, 0.3); // background: rgba(255, 0, 0, 0.3);
} }
} }
button, button,
.increasedClickArea { .increasedClickArea {
position: relative; position: relative;
@include IncreasedClickArea(15px); @include IncreasedClickArea(15px);
} }
// ---------------------------------------- // ----------------------------------------
/* Duplicates an animation and adds two classes .<classPrefix>Even and .<classPrefix>Odd which uses the /* Duplicates an animation and adds two classes .<classPrefix>Even and .<classPrefix>Odd which uses the
animation. This can be used to replay the animation by toggling between the classes, because animation. This can be used to replay the animation by toggling between the classes, because
it is not possible to restart a css animation */ it is not possible to restart a css animation */
@mixin MakeAnimationWrappedEvenOdd($duration, $classPrefix: "anim", $childSelector: "") { @mixin MakeAnimationWrappedEvenOdd($duration, $classPrefix: "anim", $childSelector: "") {
$animName: autogen_anim_#{unique-id()}; $animName: autogen_anim_#{unique-id()};
@at-root { @at-root {
@keyframes #{$animName}_even { @keyframes #{$animName}_even {
@content; @content;
} }
@keyframes #{$animName}_odd { @keyframes #{$animName}_odd {
@content; @content;
} }
} }
&.#{$classPrefix}Even #{$childSelector} { &.#{$classPrefix}Even #{$childSelector} {
animation: #{$animName}_even $duration; animation: #{$animName}_even $duration;
} }
&.#{$classPrefix}Odd #{$childSelector} { &.#{$classPrefix}Odd #{$childSelector} {
animation: #{$animName}_odd $duration; animation: #{$animName}_odd $duration;
} }
} }
// ---------------------------------------- // ----------------------------------------
/* Allows to use and define an animation without specifying its name */ /* Allows to use and define an animation without specifying its name */
@mixin InlineAnimation($duration) { @mixin InlineAnimation($duration) {
$animName: autogen_anim_#{unique-id()}; $animName: autogen_anim_#{unique-id()};
@at-root { @at-root {
@keyframes #{$animName} { @keyframes #{$animName} {
@content; @content;
} }
} }
animation: $animName $duration !important; animation: $animName $duration !important;
} }
// ---------------------------------------- // ----------------------------------------
/* Animation prefab for a double bounce pop-in animation, useful for dialogs */ /* Animation prefab for a double bounce pop-in animation, useful for dialogs */
@mixin DoubleBounceAnim($duration: 0.5s ease-in-out, $amount: 0.2, $initialOpacity: 0) { @mixin DoubleBounceAnim($duration: 0.5s ease-in-out, $amount: 0.2, $initialOpacity: 0) {
@include InlineAnimation($duration) { @include InlineAnimation($duration) {
0% { 0% {
opacity: $initialOpacity; opacity: $initialOpacity;
transform: scale(0) $hardwareAcc; transform: scale(0) $hardwareAcc;
} }
25% { 25% {
opacity: 0.5; opacity: 0.5;
transform: scale(1 + $amount) $hardwareAcc; transform: scale(1 + $amount) $hardwareAcc;
} }
50% { 50% {
opacity: 1; opacity: 1;
transform: scale(1 - $amount * 0.5) $hardwareAcc; transform: scale(1 - $amount * 0.5) $hardwareAcc;
} }
75% { 75% {
transform: scale(1 + $amount * 0.25) $hardwareAcc; transform: scale(1 + $amount * 0.25) $hardwareAcc;
} }
100% { 100% {
transform: scale(1) $hardwareAcc; transform: scale(1) $hardwareAcc;
} }
} }
opacity: 1; opacity: 1;
} }
// ---------------------------------------- // ----------------------------------------
/* Define a style which is only applied in horizontal mode */ /* Define a style which is only applied in horizontal mode */
@mixin HorizontalStyle { @mixin HorizontalStyle {
@include AppendGlobal(".h") { @include AppendGlobal(".h") {
@content; @content;
} }
} }
// ---------------------------------------- // ----------------------------------------
/* Define a style which is only applied in vertical mode */ /* Define a style which is only applied in vertical mode */
@mixin VerticalStyle { @mixin VerticalStyle {
@include AppendGlobal(".v") { @include AppendGlobal(".v") {
@content; @content;
} }
} }
// ---------------------------------------- // ----------------------------------------
/* Define a style which is only while the hardware keyboard is open */ /* Define a style which is only while the hardware keyboard is open */
@mixin AndroidHwKeyboardOpen { @mixin AndroidHwKeyboardOpen {
@include AppendGlobal(".kb") { @include AppendGlobal(".kb") {
@content; @content;
} }
} }
// ---------------------------------------- // ----------------------------------------
/* Automatically transforms the game state if a hardware keyboard is open */ /* Automatically transforms the game state if a hardware keyboard is open */
@mixin TransformToMatchKeyboard { @mixin TransformToMatchKeyboard {
transition: transform 0.2s ease-in-out; transition: transform 0.2s ease-in-out;
@include AndroidHwKeyboardOpen { @include AndroidHwKeyboardOpen {
@include VerticalStyle { @include VerticalStyle {
transform: translateY(#{D(-125px)}) $hardwareAcc; transform: translateY(#{D(-125px)}) $hardwareAcc;
} }
@include HorizontalStyle { @include HorizontalStyle {
transform: translateY(#{D(-100px)}) $hardwareAcc; transform: translateY(#{D(-100px)}) $hardwareAcc;
} }
} }
} }
// ---------------------------------------- // ----------------------------------------
/* Define a style which is only applied when the viewport is at least X pixels wide */ /* Define a style which is only applied when the viewport is at least X pixels wide */
@mixin StyleAtWidth($minW) { @mixin StyleAtWidth($minW) {
@media (min-width: #{$minW}) { @media (min-width: #{$minW}) {
@content; @content;
} }
} }
// ---------------------------------------- // ----------------------------------------
/* Define a style which is only applied when the viewport is at least X pixels height */ /* Define a style which is only applied when the viewport is at least X pixels height */
@mixin StyleAtHeight($minH) { @mixin StyleAtHeight($minH) {
@media (min-height: #{$minH}) { @media (min-height: #{$minH}) {
@content; @content;
} }
} }
// ---------------------------------------- // ----------------------------------------
/* Define a style which is only applied when the viewport has at least the given dimensions */ /* Define a style which is only applied when the viewport has at least the given dimensions */
@mixin StyleAtDims($minW, $minH) { @mixin StyleAtDims($minW, $minH) {
@media (min-height: #{$minH}) and (min-width: #{$minW}) { @media (min-height: #{$minH}) and (min-width: #{$minW}) {
@content; @content;
} }
} }
// ---------------------------------------- // ----------------------------------------
/* Define a style which is only applied when the viewport has at maximum the given dimensions */ /* Define a style which is only applied when the viewport has at maximum the given dimensions */
@mixin StyleBelowDims($maxW, $maxH) { @mixin StyleBelowDims($maxW, $maxH) {
@media (max-height: #{$maxH}) and (max-width: #{$maxW}) { @media (max-height: #{$maxH}) and (max-width: #{$maxW}) {
@content; @content;
} }
} }
// ---------------------------------------- // ----------------------------------------
/* Define a style which is only applied when the viewport has at maximum the given height */ /* Define a style which is only applied when the viewport has at maximum the given height */
@mixin StyleBelowHeight($maxH) { @mixin StyleBelowHeight($maxH) {
@media (max-height: #{$maxH}) { @media (max-height: #{$maxH}) {
@content; @content;
} }
} }
// ---------------------------------------- // ----------------------------------------
/* Define a style which is only applied when the viewport has at maximum the given width */ /* Define a style which is only applied when the viewport has at maximum the given width */
@mixin StyleBelowWidth($maxW) { @mixin StyleBelowWidth($maxW) {
@media (max-width: #{$maxW}) { @media (max-width: #{$maxW}) {
@content; @content;
} }
} }
// ---------------------------------------- // ----------------------------------------
// Dynamic graphics quality styles // Dynamic graphics quality styles
@mixin BoxShadow3D($bgColor, $size: 3px, $pressEffect: true) { @mixin BoxShadow3D($bgColor, $size: 3px, $pressEffect: true) {
background-color: $bgColor; background-color: $bgColor;
$borderSize: 1.5px; $borderSize: 1.5px;
$borderColor: rgb(18, 20, 24); $borderColor: rgb(18, 20, 24);
// box-shadow: 0 0 0 D($borderSize) $borderColor, 0 D($size) 0 0px rgba(mix(darken($bgColor, 9), #b0e2ff, 95%), 1), // box-shadow: 0 0 0 D($borderSize) $borderColor, 0 D($size) 0 0px rgba(mix(darken($bgColor, 9), #b0e2ff, 95%), 1),
// 0 D($size) 0 D($borderSize) $borderColor; // 0 D($size) 0 D($borderSize) $borderColor;
// box-shadow: 0 0 0 D($borderSize) $borderColor, 0 D($size) 0 D($borderSize) $borderColor, // box-shadow: 0 0 0 D($borderSize) $borderColor, 0 D($size) 0 D($borderSize) $borderColor,
// D(-$size * 1.5) D($size * 2) 0 D($borderSize) rgba(0, 0, 0, 0.1); // D(-$size * 1.5) D($size * 2) 0 D($borderSize) rgba(0, 0, 0, 0.1);
// transition: box-shadow 0.1s ease-in-out; // transition: box-shadow 0.1s ease-in-out;
// @if $pressEffect { // @if $pressEffect {
// &.pressed { // &.pressed {
// transform: none !important; // transform: none !important;
// $pSize: max(0, $size - 1.5px); // $pSize: max(0, $size - 1.5px);
// transition: none !important; // transition: none !important;
// box-shadow: 0 0 0 D($borderSize) $borderColor, 0 D($pSize) 0 0px rgba(mix(darken($bgColor, 9), #b0e2ff, 95%), 1), // box-shadow: 0 0 0 D($borderSize) $borderColor, 0 D($pSize) 0 0px rgba(mix(darken($bgColor, 9), #b0e2ff, 95%), 1),
// 0 D($pSize) 0 D($borderSize) $borderColor; // 0 D($pSize) 0 D($borderSize) $borderColor;
// top: D($size - $pSize); // top: D($size - $pSize);
// } // }
// } // }
} }
@mixin BorderRadius($v1: 2px, $v2: "", $v3: "", $v4: "") { @mixin BorderRadius($v1: 2px, $v2: "", $v3: "", $v4: "") {
@include S(border-radius, $v1, $v2, $v3, $v4); @include S(border-radius, $v1, $v2, $v3, $v4);
} }
@mixin BoxShadow($x, $y, $blur, $offset, $color) { @mixin BoxShadow($x, $y, $blur, $offset, $color) {
box-shadow: D($x) D($y) D($blur) D($offset) $color; box-shadow: D($x) D($y) D($blur) D($offset) $color;
} }
@mixin DropShadow($yOffset: 2px, $blur: 2px, $amount: 0.2) { @mixin DropShadow($yOffset: 2px, $blur: 2px, $amount: 0.2) {
@include BoxShadow(0, $yOffset, $blur, 0, rgba(#000, $amount)); @include BoxShadow(0, $yOffset, $blur, 0, rgba(#000, $amount));
} }
@mixin TextShadow($yOffset: 2px, $blur: 1px, $amount: 0.6) { @mixin TextShadow($yOffset: 2px, $blur: 1px, $amount: 0.6) {
text-shadow: 0 D($yOffset) D($blur) rgba(#000, $amount); text-shadow: 0 D($yOffset) D($blur) rgba(#000, $amount);
} }
@mixin Button3D($bgColor, $pressEffect: true) { @mixin Button3D($bgColor, $pressEffect: true) {
@include BoxShadow3D($bgColor, 2px, $pressEffect); @include BoxShadow3D($bgColor, 2px, $pressEffect);
} }
@mixin ButtonDisabled3D($bgColor) { @mixin ButtonDisabled3D($bgColor) {
@include BoxShadow3D($bgColor, 0.5px, false); @include BoxShadow3D($bgColor, 0.5px, false);
} }
@mixin BoxShadowInset($bgColor, $size: 3px) { @mixin BoxShadowInset($bgColor, $size: 3px) {
background-color: $bgColor; background-color: $bgColor;
$borderSize: 1px; $borderSize: 1px;
$borderColor: rgb(15, 19, 24); $borderColor: rgb(15, 19, 24);
box-shadow: 0 0 0 D($borderSize) $borderColor, 0 D($size) 0 rgba(#fff, 0.07); box-shadow: 0 0 0 D($borderSize) $borderColor, 0 D($size) 0 rgba(#fff, 0.07);
border-top: D($size) solid rgba(#000, 0.1); border-top: D($size) solid rgba(#000, 0.1);
//, 0 D($size) 0 0px rgba(mix(darken($bgColor, 9), #b0e2ff, 95%), 1), //, 0 D($size) 0 0px rgba(mix(darken($bgColor, 9), #b0e2ff, 95%), 1),
// 0 D($size + $borderSize) 0 0 $borderColor; // 0 D($size + $borderSize) 0 0 $borderColor;
} }
@mixin TextShadow3D($color: rgb(222, 234, 238), $borderColor: #000) { @mixin TextShadow3D($color: rgb(222, 234, 238), $borderColor: #000) {
color: $color; color: $color;
} }
// ---------------------------------------- // ----------------------------------------
/* Shine animation prefab, useful for buttons etc. Adds a bright shine which moves over /* String replacement */
the button like a reflection. Performance heavy. */ @function str-replace($string, $search, $replace: "") {
@mixin ShineAnimation($duration, $bgColor, $w: 200px, $shineAlpha: 0.25, $lightenAmount: 7, $bgAnim: true) { $index: str-index($string, $search);
$bgBase: darken($bgColor, 5);
background-color: $bgBase; @if $index {
@return str-slice($string, 1, $index - 1) + $replace +
@include HighQualityOrMore { str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
position: relative; }
// overflow: hidden;
// overflow: visible; @return $string;
}
&:before {
content: " "; @mixin BounceInFromSide($mul, $duration: 0.18s ease-in-out) {
position: absolute; @include InlineAnimation($duration) {
top: 0; 0% {
left: 0; transform: translateY(#{D(-100px * $mul)}) scale(0.9);
right: 0; opacity: 0;
bottom: 0; }
background: uiResource("misc/shine_bg.png") 0px center / 100% 100% no-repeat;
100% {
@include InlineAnimation($duration ease-in-out infinite) { opacity: 1;
0% { transform: none;
background-position-x: #{D(-$w)}; }
} }
100% { opacity: 1;
background-position-x: #{D($w)}; transform: none;
} }
}
} @mixin BreakText {
word-wrap: break-word;
@if ($bgAnim) { word-break: break-all;
@include InlineAnimation($duration ease-in-out infinite) { overflow-wrap: break-all;
0% { }
background-color: $bgBase;
} @mixin SupportsAndroidNotchQuery {
50% { @supports (color: constant(--notch-inset-left)) {
background-color: lighten($bgBase, $lightenAmount); @content;
} }
100% { }
background-color: $bgBase; @mixin SupportsiOsNotchQuery {
} @supports (color: env(safe-area-inset-left, 0px)) {
} @content;
} }
} }
}
@mixin DarkThemeOverride {
// ---------------------------------------- @at-root html[data-theme="dark"] &,
/* String replacement */ &[data-theme="dark"] {
@function str-replace($string, $search, $replace: "") { @content;
$index: str-index($string, $search); }
}
@if $index {
@return str-slice($string, 1, $index - 1) + $replace + @mixin DarkThemeInvert {
str-replace(str-slice($string, $index + str-length($search)), $search, $replace); @include DarkThemeOverride {
} filter: invert(1);
}
@return $string; }
}
@mixin BounceInFromSide($mul, $duration: 0.18s ease-in-out) {
@include InlineAnimation($duration) {
0% {
transform: translateY(#{D(-100px * $mul)}) scale(0.9);
opacity: 0;
}
100% {
opacity: 1;
transform: none;
}
}
opacity: 1;
transform: none;
}
@mixin BreakText {
word-wrap: break-word;
word-break: break-all;
overflow-wrap: break-all;
}
@mixin SupportsAndroidNotchQuery {
@supports (color: constant(--notch-inset-left)) {
@content;
}
}
@mixin SupportsiOsNotchQuery {
@supports (color: env(safe-area-inset-left, 0px)) {
@content;
}
}
@mixin DarkThemeOverride {
@at-root html[data-theme="dark"] &,
&[data-theme="dark"] {
@content;
}
}
@mixin DarkThemeInvert {
@include DarkThemeOverride {
filter: invert(1);
}
}

View File

@ -3,15 +3,17 @@ $buildings: belt, cutter, miner, mixer, painter, rotater, balancer, stacker, tra
@each $building in $buildings { @each $building in $buildings {
[data-icon="building_icons/#{$building}.png"] { [data-icon="building_icons/#{$building}.png"] {
/* @load-async */
background-image: uiResource("res/ui/building_icons/#{$building}.png") !important; background-image: uiResource("res/ui/building_icons/#{$building}.png") !important;
} }
} }
$buildingsAndVariants: belt, balancer, balancer-merger, balancer-splitter, underground_belt, $buildingsAndVariants: belt, balancer, balancer-merger, balancer-splitter, underground_belt,
underground_belt-tier2, miner, miner-chainable, cutter, cutter-quad, rotater, rotater-ccw, rotater-fl, underground_belt-tier2, miner, miner-chainable, cutter, cutter-quad, rotater, rotater-ccw, rotater-fl,
stacker, mixer, painter, painter-double, painter-quad, trash, storage; stacker, mixer, painter, painter-double, painter-quad, trash, storage, reader;
@each $building in $buildingsAndVariants { @each $building in $buildingsAndVariants {
[data-icon="building_tutorials/#{$building}.png"] { [data-icon="building_tutorials/#{$building}.png"] {
/* @load-async */
background-image: uiResource("res/ui/building_tutorials/#{$building}.png") !important; background-image: uiResource("res/ui/building_tutorials/#{$building}.png") !important;
} }
} }
@ -20,18 +22,22 @@ $buildingsAndVariants: belt, balancer, balancer-merger, balancer-splitter, under
// Special cases for mirrored vairants // Special cases for mirrored vairants
[data-icon="building_tutorials/painter-mirrored.png"] { [data-icon="building_tutorials/painter-mirrored.png"] {
/* @load-async */
background-image: uiResource("res/ui/building_tutorials/painter.png") !important; background-image: uiResource("res/ui/building_tutorials/painter.png") !important;
} }
[data-icon="building_tutorials/balancer-merger-inverse.png"] { [data-icon="building_tutorials/balancer-merger-inverse.png"] {
/* @load-async */
background-image: uiResource("res/ui/building_tutorials/balancer-merger.png") !important; background-image: uiResource("res/ui/building_tutorials/balancer-merger.png") !important;
} }
[data-icon="building_tutorials/balancer-splitter-inverse.png"] { [data-icon="building_tutorials/balancer-splitter-inverse.png"] {
/* @load-async */
background-image: uiResource("res/ui/building_tutorials/balancer-splitter.png") !important; background-image: uiResource("res/ui/building_tutorials/balancer-splitter.png") !important;
} }
$icons: notification_saved, notification_success, notification_upgrade; $icons: notification_saved, notification_success, notification_upgrade;
@each $icon in $icons { @each $icon in $icons {
[data-icon="icons/#{$icon}.png"] { [data-icon="icons/#{$icon}.png"] {
/* @load-async */
background-image: uiResource("res/ui/icons/#{$icon}.png") !important; background-image: uiResource("res/ui/icons/#{$icon}.png") !important;
} }
} }
@ -41,6 +47,7 @@ $languages: en, de, cs, da, et, es-419, fr, it, pt-BR, sv, tr, el, ru, uk, zh-TW
@each $language in $languages { @each $language in $languages {
[data-languageicon="#{$language}"] { [data-languageicon="#{$language}"] {
/* @load-async */
background-image: uiResource("languages/#{$language}.svg") !important; background-image: uiResource("languages/#{$language}.svg") !important;
} }
} }

View File

@ -35,10 +35,12 @@
background: transparent center center / 40% no-repeat; background: transparent center center / 40% no-repeat;
opacity: 0.9; opacity: 0.9;
&.editKeybinding { &.editKeybinding {
/* @load-async */
background-image: uiResource("icons/edit_key.png"); background-image: uiResource("icons/edit_key.png");
} }
&.resetKeybinding { &.resetKeybinding {
/* @load-async */
background-image: uiResource("icons/reset_key.png"); background-image: uiResource("icons/reset_key.png");
} }

View File

@ -22,7 +22,10 @@
@include S(height, 25px); @include S(height, 25px);
pointer-events: all; pointer-events: all;
cursor: pointer; cursor: pointer;
background: uiResource("icons/main_menu_settings.png") center center / contain no-repeat; & {
/* @load-async */
background: uiResource("icons/main_menu_settings.png") center center / contain no-repeat;
}
transition: opacity 0.12s ease-in-out; transition: opacity 0.12s ease-in-out;
@include IncreasedClickArea(2px); @include IncreasedClickArea(2px);
opacity: 0.7; opacity: 0.7;
@ -32,6 +35,7 @@
} }
.exitAppButton { .exitAppButton {
/* @load-async */
background-image: uiResource("icons/main_menu_exit.png"); background-image: uiResource("icons/main_menu_exit.png");
background-size: 90%; background-size: 90%;
} }
@ -129,8 +133,10 @@
width: 100%; width: 100%;
@include S(height, 40px); @include S(height, 40px);
@include S(width, 180px); @include S(width, 180px);
& {
background: #171a23 uiResource("get_on_steam.png") center center / contain no-repeat; /* @load-async */
background: #171a23 uiResource("get_on_steam.png") center center / contain no-repeat;
}
overflow: hidden; overflow: hidden;
display: block; display: block;
text-indent: -999em; text-indent: -999em;
@ -167,7 +173,10 @@
@include S(margin, 10px, 0); @include S(margin, 10px, 0);
@include S(width, 100px); @include S(width, 100px);
@include S(height, 30px); @include S(height, 30px);
background: uiResource("demo_badge.png") center center / contain no-repeat; & {
/* @load-async */
background: uiResource("demo_badge.png") center center / contain no-repeat;
}
display: inline-block; display: inline-block;
} }
@ -335,14 +344,22 @@
align-self: center; align-self: center;
justify-self: center; justify-self: center;
@include IncreasedClickArea(0px); @include IncreasedClickArea(0px);
background: #44484a uiResource("icons/play.png") center center / 40% no-repeat;
& {
/* @load-async */
background: #44484a uiResource("icons/play.png") center center / 40% no-repeat;
}
} }
button.downloadGame { button.downloadGame {
grid-column: 3 / 4; grid-column: 3 / 4;
grid-row: 1 / 2; grid-row: 1 / 2;
background-color: transparent; background-color: transparent;
background-image: uiResource("icons/download.png");
& {
/* @load-async */
background-image: uiResource("icons/download.png");
}
@include S(width, 15px); @include S(width, 15px);
@include IncreasedClickArea(0px); @include IncreasedClickArea(0px);
@include S(height, 15px); @include S(height, 15px);
@ -362,7 +379,11 @@
grid-row: 2 / 3; grid-row: 2 / 3;
background-color: transparent; background-color: transparent;
@include IncreasedClickArea(0px); @include IncreasedClickArea(0px);
background-image: uiResource("icons/delete.png");
& {
/* @load-async */
background-image: uiResource("icons/delete.png");
}
@include S(width, 15px); @include S(width, 15px);
@include S(height, 15px); @include S(height, 15px);
align-self: end; align-self: end;
@ -379,7 +400,11 @@
button.renameGame { button.renameGame {
background-color: transparent; background-color: transparent;
@include IncreasedClickArea(2px); @include IncreasedClickArea(2px);
background-image: uiResource("icons/edit_key.png");
& {
/* @load-async */
background-image: uiResource("icons/edit_key.png");
}
@include S(width, 10px); @include S(width, 10px);
@include S(height, 10px); @include S(height, 10px);
align-self: center; align-self: center;
@ -445,7 +470,11 @@
grid-template-columns: 1fr auto; grid-template-columns: 1fr auto;
justify-content: center; justify-content: center;
background: $linkBg uiResource("icons/link.png") top D(3px) right D(3px) / D(9px) no-repeat;
& {
/* @load-async */
background: $linkBg uiResource("icons/link.png") top D(3px) right D(3px) / D(9px) no-repeat;
}
@include S(padding, 5px); @include S(padding, 5px);
@include S(padding-left, 10px); @include S(padding-left, 10px);
@include S(border-radius, $globalBorderRadius); @include S(border-radius, $globalBorderRadius);
@ -472,9 +501,11 @@
@include S(height, 50px); @include S(height, 50px);
background: center center / 80% no-repeat; background: center center / 80% no-repeat;
&.githubLogo { &.githubLogo {
/* @load-async */
background-image: uiResource("main_menu/github.png"); background-image: uiResource("main_menu/github.png");
} }
&.discordLogo { &.discordLogo {
/* @load-async */
background-image: uiResource("main_menu/discord.png"); background-image: uiResource("main_menu/discord.png");
background-size: 95%; background-size: 95%;
} }
@ -516,12 +547,15 @@
transition: background-color 0.12s ease-in-out; transition: background-color 0.12s ease-in-out;
&.redditLink { &.redditLink {
/* @load-async */
background-image: uiResource("main_menu/reddit.svg"); background-image: uiResource("main_menu/reddit.svg");
} }
&.changelog { &.changelog {
/* @load-async */
background-image: uiResource("main_menu/changelog.svg"); background-image: uiResource("main_menu/changelog.svg");
} }
&.helpTranslate { &.helpTranslate {
/* @load-async */
background-image: uiResource("main_menu/translate.svg"); background-image: uiResource("main_menu/translate.svg");
} }
} }

View File

@ -1,48 +1,51 @@
#state_MobileWarningState { #state_MobileWarningState {
display: flex; display: flex;
align-items: center; align-items: center;
background: #333438 !important; background: #333438 !important;
@include S(padding, 20px); @include S(padding, 20px);
box-sizing: border-box; box-sizing: border-box;
justify-content: center; justify-content: center;
flex-direction: column; flex-direction: column;
.logo { .logo {
width: 80%; width: 80%;
max-width: 200px; max-width: 200px;
margin-bottom: 10px; margin-bottom: 10px;
} }
p { p {
color: #aaacaf; color: #aaacaf;
display: block; display: block;
margin-bottom: 13px; margin-bottom: 13px;
font-size: 16px; font-size: 16px;
line-height: 20px; line-height: 20px;
max-width: 300px; max-width: 300px;
text-align: left; text-align: left;
a { a {
color: $colorBlueBright; color: $colorBlueBright;
} }
} }
.standaloneLink { .standaloneLink {
width: 200px; width: 200px;
height: 80px; height: 80px;
min-height: 40px; min-height: 40px;
background: uiResource("get_on_steam.png") center center / contain no-repeat; & {
overflow: hidden; /* @load-async */
display: block; background: uiResource("get_on_steam.png") center center / contain no-repeat;
text-indent: -999em; }
cursor: pointer; overflow: hidden;
margin-top: 10px; display: block;
pointer-events: all; text-indent: -999em;
transition: all 0.12s ease-in; cursor: pointer;
transition-property: opacity, transform; margin-top: 10px;
transform: skewX(-0.5deg); pointer-events: all;
&:hover { transition: all 0.12s ease-in;
transform: skewX(-1deg) scale(1.02); transition-property: opacity, transform;
opacity: 0.9; transform: skewX(-0.5deg);
} &:hover {
} transform: skewX(-1deg) scale(1.02);
} opacity: 0.9;
}
}
}

View File

@ -159,8 +159,11 @@
@include S(padding, 4px); @include S(padding, 4px);
@include S(padding-right, 15px); @include S(padding-right, 15px);
background: #fff uiResource("icons/enum_selector.png") calc(100% - #{D(5px)}) & {
calc(50% + #{D(1px)}) / #{D(15px)} no-repeat; /* @load-async */
background: #fff uiResource("icons/enum_selector.png") calc(100% - #{D(5px)})
calc(50% + #{D(1px)}) / #{D(15px)} no-repeat;
}
transition: background-color 0.12s ease-in-out; transition: background-color 0.12s ease-in-out;
&:hover { &:hover {
@ -196,7 +199,11 @@
// dirty but works // dirty but works
// color: #222; // color: #222;
background-color: $darkModeControlsBackground; background-color: $darkModeControlsBackground;
background-image: uiResource("icons/enum_selector_white.png");
& {
/* @load-async */
background-image: uiResource("icons/enum_selector_white.png");
}
color: #ddd; color: #ddd;
&:hover { &:hover {
background-color: darken($darkModeControlsBackground, 2); background-color: darken($darkModeControlsBackground, 2);

View File

@ -26,9 +26,11 @@
@include S(height, 30px); @include S(height, 30px);
@include S(margin-right, 10px); @include S(margin-right, 10px);
@include S(margin-left, -5px); @include S(margin-left, -5px);
background: uiResource("icons/state_back_button.png") center center / 70% no-repeat; & {
/* @load-async */
background: uiResource("icons/state_back_button.png") center center / 70% no-repeat;
}
} }
@include S(margin-bottom, 20px); @include S(margin-bottom, 20px);
} }

View File

@ -7,7 +7,7 @@ import { MetaBuilding, defaultBuildingVariant } from "../meta_building";
import { GameRoot } from "../root"; import { GameRoot } from "../root";
import { enumHubGoalRewards } from "../tutorial_goals"; import { enumHubGoalRewards } from "../tutorial_goals";
import { T } from "../../translations"; import { T } from "../../translations";
import { formatItemsPerSecond } from "../../core/utils"; import { formatItemsPerSecond, generateMatrixRotations } from "../../core/utils";
import { BeltUnderlaysComponent } from "../components/belt_underlays"; import { BeltUnderlaysComponent } from "../components/belt_underlays";
/** @enum {string} */ /** @enum {string} */
@ -18,6 +18,14 @@ export const enumBalancerVariants = {
splitterInverse: "splitter-inverse", splitterInverse: "splitter-inverse",
}; };
const overlayMatrices = {
[defaultBuildingVariant]: null,
[enumBalancerVariants.merger]: generateMatrixRotations([0, 1, 0, 0, 1, 1, 0, 1, 0]),
[enumBalancerVariants.mergerInverse]: generateMatrixRotations([0, 1, 0, 1, 1, 0, 0, 1, 0]),
[enumBalancerVariants.splitter]: generateMatrixRotations([0, 1, 0, 0, 1, 1, 0, 1, 0]),
[enumBalancerVariants.splitterInverse]: generateMatrixRotations([0, 1, 0, 1, 1, 0, 0, 1, 0]),
};
export class MetaBalancerBuilding extends MetaBuilding { export class MetaBalancerBuilding extends MetaBuilding {
constructor() { constructor() {
super("balancer"); super("balancer");
@ -37,18 +45,43 @@ export class MetaBalancerBuilding extends MetaBuilding {
} }
} }
/**
* @param {number} rotation
* @param {number} rotationVariant
* @param {string} variant
* @param {Entity} entity
* @returns {Array<number>|null}
*/
getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) {
const matrix = overlayMatrices[variant];
if (matrix) {
return matrix[rotation];
}
return null;
}
/** /**
* @param {GameRoot} root * @param {GameRoot} root
* @param {string} variant * @param {string} variant
* @returns {Array<[string, string]>} * @returns {Array<[string, string]>}
*/ */
getAdditionalStatistics(root, variant) { getAdditionalStatistics(root, variant) {
const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.balancer); let speedMultiplier = 2;
switch (variant) {
case enumBalancerVariants.merger:
case enumBalancerVariants.mergerInverse:
case enumBalancerVariants.splitter:
case enumBalancerVariants.splitterInverse:
speedMultiplier = 1;
}
const speed =
(root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.balancer) / 2) * speedMultiplier;
return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]]; return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
} }
getSilhouetteColor() { getSilhouetteColor() {
return "#444"; return "#555759";
} }
/** /**

View File

@ -6,12 +6,15 @@ import { MetaBuilding, defaultBuildingVariant } from "../meta_building";
import { GameRoot } from "../root"; import { GameRoot } from "../root";
import { enumHubGoalRewards } from "../tutorial_goals"; import { enumHubGoalRewards } from "../tutorial_goals";
import { T } from "../../translations"; import { T } from "../../translations";
import { formatItemsPerSecond } from "../../core/utils"; import { formatItemsPerSecond, generateMatrixRotations } from "../../core/utils";
/** @enum {string} */ /** @enum {string} */
export const enumMinerVariants = { chainable: "chainable" }; export const enumMinerVariants = { chainable: "chainable" };
const overlayMatrix = [1, 1, 1, 1, 0, 1, 1, 1, 1]; const overlayMatrix = {
[defaultBuildingVariant]: generateMatrixRotations([1, 1, 1, 1, 0, 1, 1, 1, 1]),
[enumMinerVariants.chainable]: generateMatrixRotations([0, 1, 0, 1, 1, 1, 1, 1, 1]),
};
export class MetaMinerBuilding extends MetaBuilding { export class MetaMinerBuilding extends MetaBuilding {
constructor() { constructor() {
@ -50,7 +53,7 @@ export class MetaMinerBuilding extends MetaBuilding {
* @param {Entity} entity * @param {Entity} entity
*/ */
getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) { getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) {
return overlayMatrix; return overlayMatrix[variant][rotation];
} }
/** /**

View File

@ -1,4 +1,4 @@
import { formatItemsPerSecond } from "../../core/utils"; import { formatItemsPerSecond, generateMatrixRotations } from "../../core/utils";
import { enumDirection, Vector } from "../../core/vector"; import { enumDirection, Vector } from "../../core/vector";
import { T } from "../../translations"; import { T } from "../../translations";
import { ItemAcceptorComponent } from "../components/item_acceptor"; import { ItemAcceptorComponent } from "../components/item_acceptor";
@ -12,6 +12,11 @@ import { enumHubGoalRewards } from "../tutorial_goals";
/** @enum {string} */ /** @enum {string} */
export const enumRotaterVariants = { ccw: "ccw", rotate180: "rotate180" }; export const enumRotaterVariants = { ccw: "ccw", rotate180: "rotate180" };
const overlayMatrices = {
[defaultBuildingVariant]: generateMatrixRotations([0, 1, 1, 1, 1, 0, 0, 1, 1]),
[enumRotaterVariants.ccw]: generateMatrixRotations([1, 1, 0, 0, 1, 1, 1, 1, 0]),
};
export class MetaRotaterBuilding extends MetaBuilding { export class MetaRotaterBuilding extends MetaBuilding {
constructor() { constructor() {
super("rotater"); super("rotater");
@ -21,6 +26,21 @@ export class MetaRotaterBuilding extends MetaBuilding {
return "#7dc6cd"; return "#7dc6cd";
} }
/**
* @param {number} rotation
* @param {number} rotationVariant
* @param {string} variant
* @param {Entity} entity
* @returns {Array<number>|null}
*/
getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) {
const matrix = overlayMatrices[variant];
if (matrix) {
return matrix[rotation];
}
return null;
}
/** /**
* @param {GameRoot} root * @param {GameRoot} root
* @param {string} variant * @param {string} variant

View File

@ -1,266 +1,268 @@
import { Loader } from "../../core/loader"; import { Loader } from "../../core/loader";
import { enumDirection, Vector, enumAngleToDirection, enumDirectionToVector } from "../../core/vector"; import { enumDirection, Vector, enumAngleToDirection, enumDirectionToVector } from "../../core/vector";
import { ItemAcceptorComponent } from "../components/item_acceptor"; import { ItemAcceptorComponent } from "../components/item_acceptor";
import { ItemEjectorComponent } from "../components/item_ejector"; import { ItemEjectorComponent } from "../components/item_ejector";
import { enumUndergroundBeltMode, UndergroundBeltComponent } from "../components/underground_belt"; import { enumUndergroundBeltMode, UndergroundBeltComponent } from "../components/underground_belt";
import { Entity } from "../entity"; import { Entity } from "../entity";
import { MetaBuilding, defaultBuildingVariant } from "../meta_building"; import { MetaBuilding, defaultBuildingVariant } from "../meta_building";
import { GameRoot } from "../root"; import { GameRoot } from "../root";
import { globalConfig } from "../../core/config"; import { globalConfig } from "../../core/config";
import { enumHubGoalRewards } from "../tutorial_goals"; import { enumHubGoalRewards } from "../tutorial_goals";
import { formatItemsPerSecond, generateMatrixRotations } from "../../core/utils"; import { formatItemsPerSecond, generateMatrixRotations } from "../../core/utils";
import { T } from "../../translations"; import { T } from "../../translations";
/** @enum {string} */ /** @enum {string} */
export const arrayUndergroundRotationVariantToMode = [ export const arrayUndergroundRotationVariantToMode = [
enumUndergroundBeltMode.sender, enumUndergroundBeltMode.sender,
enumUndergroundBeltMode.receiver, enumUndergroundBeltMode.receiver,
]; ];
/** @enum {string} */ /** @enum {string} */
export const enumUndergroundBeltVariants = { tier2: "tier2" }; export const enumUndergroundBeltVariants = { tier2: "tier2" };
export const enumUndergroundBeltVariantToTier = { export const enumUndergroundBeltVariantToTier = {
[defaultBuildingVariant]: 0, [defaultBuildingVariant]: 0,
[enumUndergroundBeltVariants.tier2]: 1, [enumUndergroundBeltVariants.tier2]: 1,
}; };
const overlayMatrices = [ const colorsByRotationVariant = ["#6d9dff", "#51d723"];
// Sender
generateMatrixRotations([1, 1, 1, 0, 1, 0, 0, 1, 0]), const overlayMatrices = [
// Sender
// Receiver generateMatrixRotations([1, 1, 1, 0, 1, 0, 0, 1, 0]),
generateMatrixRotations([0, 1, 0, 0, 1, 0, 1, 1, 1]),
]; // Receiver
generateMatrixRotations([0, 1, 0, 0, 1, 0, 1, 1, 1]),
export class MetaUndergroundBeltBuilding extends MetaBuilding { ];
constructor() {
super("underground_belt"); export class MetaUndergroundBeltBuilding extends MetaBuilding {
} constructor() {
super("underground_belt");
getSilhouetteColor() { }
return "#222";
} getSilhouetteColor(variant, rotationVariant) {
return colorsByRotationVariant[rotationVariant];
getFlipOrientationAfterPlacement() { }
return true;
} getFlipOrientationAfterPlacement() {
return true;
getStayInPlacementMode() { }
return true;
} getStayInPlacementMode() {
return true;
/** }
* @param {number} rotation
* @param {number} rotationVariant /**
* @param {string} variant * @param {number} rotation
* @param {Entity} entity * @param {number} rotationVariant
*/ * @param {string} variant
getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) { * @param {Entity} entity
return overlayMatrices[rotationVariant][rotation]; */
} getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) {
return overlayMatrices[rotationVariant][rotation];
/** }
* @param {GameRoot} root
* @param {string} variant /**
* @returns {Array<[string, string]>} * @param {GameRoot} root
*/ * @param {string} variant
getAdditionalStatistics(root, variant) { * @returns {Array<[string, string]>}
const rangeTiles = */
globalConfig.undergroundBeltMaxTilesByTier[enumUndergroundBeltVariantToTier[variant]]; getAdditionalStatistics(root, variant) {
const rangeTiles =
const beltSpeed = root.hubGoals.getUndergroundBeltBaseSpeed(); globalConfig.undergroundBeltMaxTilesByTier[enumUndergroundBeltVariantToTier[variant]];
return [
[ const beltSpeed = root.hubGoals.getUndergroundBeltBaseSpeed();
T.ingame.buildingPlacement.infoTexts.range, return [
T.ingame.buildingPlacement.infoTexts.tiles.replace("<x>", "" + rangeTiles), [
], T.ingame.buildingPlacement.infoTexts.range,
[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(beltSpeed)], T.ingame.buildingPlacement.infoTexts.tiles.replace("<x>", "" + rangeTiles),
]; ],
} [T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(beltSpeed)],
];
/** }
* @param {GameRoot} root
*/ /**
getAvailableVariants(root) { * @param {GameRoot} root
if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_underground_belt_tier_2)) { */
return [defaultBuildingVariant, enumUndergroundBeltVariants.tier2]; getAvailableVariants(root) {
} if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_underground_belt_tier_2)) {
return super.getAvailableVariants(root); return [defaultBuildingVariant, enumUndergroundBeltVariants.tier2];
} }
return super.getAvailableVariants(root);
/** }
* @param {number} rotationVariant
* @param {string} variant /**
*/ * @param {number} rotationVariant
getPreviewSprite(rotationVariant, variant) { * @param {string} variant
let suffix = ""; */
if (variant !== defaultBuildingVariant) { getPreviewSprite(rotationVariant, variant) {
suffix = "-" + variant; let suffix = "";
} if (variant !== defaultBuildingVariant) {
suffix = "-" + variant;
switch (arrayUndergroundRotationVariantToMode[rotationVariant]) { }
case enumUndergroundBeltMode.sender:
return Loader.getSprite("sprites/buildings/underground_belt_entry" + suffix + ".png"); switch (arrayUndergroundRotationVariantToMode[rotationVariant]) {
case enumUndergroundBeltMode.receiver: case enumUndergroundBeltMode.sender:
return Loader.getSprite("sprites/buildings/underground_belt_exit" + suffix + ".png"); return Loader.getSprite("sprites/buildings/underground_belt_entry" + suffix + ".png");
default: case enumUndergroundBeltMode.receiver:
assertAlways(false, "Invalid rotation variant"); return Loader.getSprite("sprites/buildings/underground_belt_exit" + suffix + ".png");
} default:
} assertAlways(false, "Invalid rotation variant");
}
/** }
* @param {number} rotationVariant
* @param {string} variant /**
*/ * @param {number} rotationVariant
getBlueprintSprite(rotationVariant, variant) { * @param {string} variant
let suffix = ""; */
if (variant !== defaultBuildingVariant) { getBlueprintSprite(rotationVariant, variant) {
suffix = "-" + variant; let suffix = "";
} if (variant !== defaultBuildingVariant) {
suffix = "-" + variant;
switch (arrayUndergroundRotationVariantToMode[rotationVariant]) { }
case enumUndergroundBeltMode.sender:
return Loader.getSprite("sprites/blueprints/underground_belt_entry" + suffix + ".png"); switch (arrayUndergroundRotationVariantToMode[rotationVariant]) {
case enumUndergroundBeltMode.receiver: case enumUndergroundBeltMode.sender:
return Loader.getSprite("sprites/blueprints/underground_belt_exit" + suffix + ".png"); return Loader.getSprite("sprites/blueprints/underground_belt_entry" + suffix + ".png");
default: case enumUndergroundBeltMode.receiver:
assertAlways(false, "Invalid rotation variant"); return Loader.getSprite("sprites/blueprints/underground_belt_exit" + suffix + ".png");
} default:
} assertAlways(false, "Invalid rotation variant");
}
/** }
* @param {number} rotationVariant
* @param {string} variant /**
*/ * @param {number} rotationVariant
getSprite(rotationVariant, variant) { * @param {string} variant
return this.getPreviewSprite(rotationVariant, variant); */
} getSprite(rotationVariant, variant) {
return this.getPreviewSprite(rotationVariant, variant);
/** }
* @param {GameRoot} root
*/ /**
getIsUnlocked(root) { * @param {GameRoot} root
return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_tunnel); */
} getIsUnlocked(root) {
return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_tunnel);
/** }
* Creates the entity at the given location
* @param {Entity} entity /**
*/ * Creates the entity at the given location
setupEntityComponents(entity) { * @param {Entity} entity
// Required, since the item processor needs this. */
entity.addComponent( setupEntityComponents(entity) {
new ItemEjectorComponent({ // Required, since the item processor needs this.
slots: [], entity.addComponent(
}) new ItemEjectorComponent({
); slots: [],
})
entity.addComponent(new UndergroundBeltComponent({})); );
entity.addComponent(
new ItemAcceptorComponent({ entity.addComponent(new UndergroundBeltComponent({}));
slots: [], entity.addComponent(
}) new ItemAcceptorComponent({
); slots: [],
} })
);
/** }
* Should compute the optimal rotation variant on the given tile
* @param {object} param0 /**
* @param {GameRoot} param0.root * Should compute the optimal rotation variant on the given tile
* @param {Vector} param0.tile * @param {object} param0
* @param {number} param0.rotation * @param {GameRoot} param0.root
* @param {string} param0.variant * @param {Vector} param0.tile
* @param {Layer} param0.layer * @param {number} param0.rotation
* @return {{ rotation: number, rotationVariant: number, connectedEntities?: Array<Entity> }} * @param {string} param0.variant
*/ * @param {Layer} param0.layer
computeOptimalDirectionAndRotationVariantAtTile({ root, tile, rotation, variant, layer }) { * @return {{ rotation: number, rotationVariant: number, connectedEntities?: Array<Entity> }}
const searchDirection = enumAngleToDirection[rotation]; */
const searchVector = enumDirectionToVector[searchDirection]; computeOptimalDirectionAndRotationVariantAtTile({ root, tile, rotation, variant, layer }) {
const tier = enumUndergroundBeltVariantToTier[variant]; const searchDirection = enumAngleToDirection[rotation];
const searchVector = enumDirectionToVector[searchDirection];
const targetRotation = (rotation + 180) % 360; const tier = enumUndergroundBeltVariantToTier[variant];
const targetSenderRotation = rotation;
const targetRotation = (rotation + 180) % 360;
for ( const targetSenderRotation = rotation;
let searchOffset = 1;
searchOffset <= globalConfig.undergroundBeltMaxTilesByTier[tier]; for (
++searchOffset let searchOffset = 1;
) { searchOffset <= globalConfig.undergroundBeltMaxTilesByTier[tier];
tile = tile.addScalars(searchVector.x, searchVector.y); ++searchOffset
) {
/* WIRES: FIXME */ tile = tile.addScalars(searchVector.x, searchVector.y);
const contents = root.map.getTileContent(tile, "regular");
if (contents) { /* WIRES: FIXME */
const undergroundComp = contents.components.UndergroundBelt; const contents = root.map.getTileContent(tile, "regular");
if (undergroundComp && undergroundComp.tier === tier) { if (contents) {
const staticComp = contents.components.StaticMapEntity; const undergroundComp = contents.components.UndergroundBelt;
if (staticComp.rotation === targetRotation) { if (undergroundComp && undergroundComp.tier === tier) {
if (undergroundComp.mode !== enumUndergroundBeltMode.sender) { const staticComp = contents.components.StaticMapEntity;
// If we encounter an underground receiver on our way which is also faced in our direction, we don't accept that if (staticComp.rotation === targetRotation) {
break; if (undergroundComp.mode !== enumUndergroundBeltMode.sender) {
} // If we encounter an underground receiver on our way which is also faced in our direction, we don't accept that
return { break;
rotation: targetRotation, }
rotationVariant: 1, return {
connectedEntities: [contents], rotation: targetRotation,
}; rotationVariant: 1,
} else if (staticComp.rotation === targetSenderRotation) { connectedEntities: [contents],
// Draw connections to receivers };
if (undergroundComp.mode === enumUndergroundBeltMode.receiver) { } else if (staticComp.rotation === targetSenderRotation) {
return { // Draw connections to receivers
rotation: rotation, if (undergroundComp.mode === enumUndergroundBeltMode.receiver) {
rotationVariant: 0, return {
connectedEntities: [contents], rotation: rotation,
}; rotationVariant: 0,
} else { connectedEntities: [contents],
break; };
} } else {
} break;
} }
} }
} }
}
return { }
rotation,
rotationVariant: 0, return {
}; rotation,
} rotationVariant: 0,
};
/** }
*
* @param {Entity} entity /**
* @param {number} rotationVariant *
* @param {string} variant * @param {Entity} entity
*/ * @param {number} rotationVariant
updateVariants(entity, rotationVariant, variant) { * @param {string} variant
entity.components.UndergroundBelt.tier = enumUndergroundBeltVariantToTier[variant]; */
updateVariants(entity, rotationVariant, variant) {
switch (arrayUndergroundRotationVariantToMode[rotationVariant]) { entity.components.UndergroundBelt.tier = enumUndergroundBeltVariantToTier[variant];
case enumUndergroundBeltMode.sender: {
entity.components.UndergroundBelt.mode = enumUndergroundBeltMode.sender; switch (arrayUndergroundRotationVariantToMode[rotationVariant]) {
entity.components.ItemEjector.setSlots([]); case enumUndergroundBeltMode.sender: {
entity.components.ItemAcceptor.setSlots([ entity.components.UndergroundBelt.mode = enumUndergroundBeltMode.sender;
{ entity.components.ItemEjector.setSlots([]);
pos: new Vector(0, 0), entity.components.ItemAcceptor.setSlots([
directions: [enumDirection.bottom], {
}, pos: new Vector(0, 0),
]); directions: [enumDirection.bottom],
return; },
} ]);
case enumUndergroundBeltMode.receiver: { return;
entity.components.UndergroundBelt.mode = enumUndergroundBeltMode.receiver; }
entity.components.ItemAcceptor.setSlots([]); case enumUndergroundBeltMode.receiver: {
entity.components.ItemEjector.setSlots([ entity.components.UndergroundBelt.mode = enumUndergroundBeltMode.receiver;
{ entity.components.ItemAcceptor.setSlots([]);
pos: new Vector(0, 0), entity.components.ItemEjector.setSlots([
direction: enumDirection.top, {
}, pos: new Vector(0, 0),
]); direction: enumDirection.top,
return; },
} ]);
default: return;
assertAlways(false, "Invalid rotation variant"); }
} default:
} assertAlways(false, "Invalid rotation variant");
} }
}
}

View File

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

View File

@ -170,7 +170,10 @@ export class MapChunkView extends MapChunk {
); );
} }
context.fillStyle = metaBuilding.getSilhouetteColor(); context.fillStyle = metaBuilding.getSilhouetteColor(
data.variant,
data.rotationVariant
);
for (let dx = 0; dx < 3; ++dx) { for (let dx = 0; dx < 3; ++dx) {
for (let dy = 0; dy < 3; ++dy) { for (let dy = 0; dy < 3; ++dy) {
const isFilled = overlayMatrix[dx + dy * 3]; const isFilled = overlayMatrix[dx + dy * 3];
@ -187,7 +190,10 @@ export class MapChunkView extends MapChunk {
continue; continue;
} else { } else {
context.fillStyle = metaBuilding.getSilhouetteColor(); context.fillStyle = metaBuilding.getSilhouetteColor(
data.variant,
data.rotationVariant
);
context.fillRect( context.fillRect(
x * CHUNK_OVERLAY_RES, x * CHUNK_OVERLAY_RES,
y * CHUNK_OVERLAY_RES, y * CHUNK_OVERLAY_RES,
@ -256,7 +262,8 @@ export class MapChunkView extends MapChunk {
data.variant, data.variant,
entity entity
); );
context.fillStyle = overrideColor || metaBuilding.getSilhouetteColor(); context.fillStyle =
overrideColor || metaBuilding.getSilhouetteColor(data.variant, data.rotationVariant);
if (overlayMatrix) { if (overlayMatrix) {
for (let dx = 0; dx < 3; ++dx) { for (let dx = 0; dx < 3; ++dx) {
for (let dy = 0; dy < 3; ++dy) { for (let dy = 0; dy < 3; ++dy) {

View File

@ -1,273 +1,275 @@
import { Loader } from "../core/loader"; import { Loader } from "../core/loader";
import { AtlasSprite } from "../core/sprites"; import { AtlasSprite } from "../core/sprites";
import { Vector } from "../core/vector"; import { Vector } from "../core/vector";
import { SOUNDS } from "../platform/sound"; import { SOUNDS } from "../platform/sound";
import { StaticMapEntityComponent } from "./components/static_map_entity"; import { StaticMapEntityComponent } from "./components/static_map_entity";
import { Entity } from "./entity"; import { Entity } from "./entity";
import { GameRoot } from "./root"; import { GameRoot } from "./root";
import { getCodeFromBuildingData } from "./building_codes"; import { getCodeFromBuildingData } from "./building_codes";
export const defaultBuildingVariant = "default"; export const defaultBuildingVariant = "default";
export class MetaBuilding { export class MetaBuilding {
/** /**
* *
* @param {string} id Building id * @param {string} id Building id
*/ */
constructor(id) { constructor(id) {
this.id = id; this.id = id;
} }
/** /**
* Returns the id of this building * Returns the id of this building
*/ */
getId() { getId() {
return this.id; return this.id;
} }
/** /**
* Returns the edit layer of the building * Returns the edit layer of the building
* @returns {Layer} * @returns {Layer}
*/ */
getLayer() { getLayer() {
return "regular"; return "regular";
} }
/** /**
* Should return the dimensions of the building * Should return the dimensions of the building
*/ */
getDimensions(variant = defaultBuildingVariant) { getDimensions(variant = defaultBuildingVariant) {
return new Vector(1, 1); return new Vector(1, 1);
} }
/** /**
* Returns whether the building has the direction lock switch available * Returns whether the building has the direction lock switch available
*/ */
getHasDirectionLockAvailable() { getHasDirectionLockAvailable() {
return false; return false;
} }
/** /**
* Whether to stay in placement mode after having placed a building * Whether to stay in placement mode after having placed a building
*/ */
getStayInPlacementMode() { getStayInPlacementMode() {
return false; return false;
} }
/** /**
* Can return a special interlaved 9 elements overlay matrix for rendering * Can return a special interlaved 9 elements overlay matrix for rendering
* @param {number} rotation * @param {number} rotation
* @param {number} rotationVariant * @param {number} rotationVariant
* @param {string} variant * @param {string} variant
* @param {Entity} entity * @param {Entity} entity
* @returns {Array<number>|null} * @returns {Array<number>|null}
*/ */
getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) { getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) {
return null; return null;
} }
/** /**
* Should return additional statistics about this building * Should return additional statistics about this building
* @param {GameRoot} root * @param {GameRoot} root
* @param {string} variant * @param {string} variant
* @returns {Array<[string, string]>} * @returns {Array<[string, string]>}
*/ */
getAdditionalStatistics(root, variant) { getAdditionalStatistics(root, variant) {
return []; return [];
} }
/** /**
* Returns whether this building can get replaced * Returns whether this building can get replaced
*/ */
getIsReplaceable() { getIsReplaceable() {
return false; return false;
} }
/** /**
* Whether to flip the orientation after a building has been placed - useful * Whether to flip the orientation after a building has been placed - useful
* for tunnels. * for tunnels.
*/ */
getFlipOrientationAfterPlacement() { getFlipOrientationAfterPlacement() {
return false; return false;
} }
/** /**
* Whether to show a preview of the wires layer when placing the building * Whether to show a preview of the wires layer when placing the building
*/ */
getShowWiresLayerPreview() { getShowWiresLayerPreview() {
return false; return false;
} }
/** /**
* Whether to rotate automatically in the dragging direction while placing * Whether to rotate automatically in the dragging direction while placing
* @param {string} variant * @param {string} variant
*/ */
getRotateAutomaticallyWhilePlacing(variant) { getRotateAutomaticallyWhilePlacing(variant) {
return false; return false;
} }
/** /**
* Returns whether this building is removable * Returns whether this building is removable
* @returns {boolean} * @returns {boolean}
*/ */
getIsRemovable() { getIsRemovable() {
return true; return true;
} }
/** /**
* Returns the placement sound * Returns the placement sound
* @returns {string} * @returns {string}
*/ */
getPlacementSound() { getPlacementSound() {
return SOUNDS.placeBuilding; return SOUNDS.placeBuilding;
} }
/** /**
* @param {GameRoot} root * @param {GameRoot} root
*/ */
getAvailableVariants(root) { getAvailableVariants(root) {
return [defaultBuildingVariant]; return [defaultBuildingVariant];
} }
/** /**
* Returns a preview sprite * Returns a preview sprite
* @returns {AtlasSprite} * @returns {AtlasSprite}
*/ */
getPreviewSprite(rotationVariant = 0, variant = defaultBuildingVariant) { getPreviewSprite(rotationVariant = 0, variant = defaultBuildingVariant) {
return Loader.getSprite( return Loader.getSprite(
"sprites/buildings/" + "sprites/buildings/" +
this.id + this.id +
(variant === defaultBuildingVariant ? "" : "-" + variant) + (variant === defaultBuildingVariant ? "" : "-" + variant) +
".png" ".png"
); );
} }
/** /**
* Returns a sprite for blueprints * Returns a sprite for blueprints
* @returns {AtlasSprite} * @returns {AtlasSprite}
*/ */
getBlueprintSprite(rotationVariant = 0, variant = defaultBuildingVariant) { getBlueprintSprite(rotationVariant = 0, variant = defaultBuildingVariant) {
return Loader.getSprite( return Loader.getSprite(
"sprites/blueprints/" + "sprites/blueprints/" +
this.id + this.id +
(variant === defaultBuildingVariant ? "" : "-" + variant) + (variant === defaultBuildingVariant ? "" : "-" + variant) +
".png" ".png"
); );
} }
/** /**
* Returns whether this building is rotateable * Returns whether this building is rotateable
* @param {string} variant * @param {string} variant
* @returns {boolean} * @returns {boolean}
*/ */
getIsRotateable(variant) { getIsRotateable(variant) {
return true; return true;
} }
/** /**
* Returns whether this building is unlocked for the given game * Returns whether this building is unlocked for the given game
* @param {GameRoot} root * @param {GameRoot} root
*/ */
getIsUnlocked(root) { getIsUnlocked(root) {
return true; return true;
} }
/** /**
* Should return a silhouette color for the map overview or null if not set * Should return a silhouette color for the map overview or null if not set
*/ * @param {string} variant
getSilhouetteColor() { * @param {number} rotationVariant
return null; */
} getSilhouetteColor(variant, rotationVariant) {
return null;
/** }
* Should return false if the pins are already included in the sprite of the building
* @returns {boolean} /**
*/ * Should return false if the pins are already included in the sprite of the building
getRenderPins() { * @returns {boolean}
return true; */
} getRenderPins() {
return true;
/** }
* Creates the entity without placing it
* @param {object} param0 /**
* @param {GameRoot} param0.root * Creates the entity without placing it
* @param {Vector} param0.origin Origin tile * @param {object} param0
* @param {number=} param0.rotation Rotation * @param {GameRoot} param0.root
* @param {number} param0.originalRotation Original Rotation * @param {Vector} param0.origin Origin tile
* @param {number} param0.rotationVariant Rotation variant * @param {number=} param0.rotation Rotation
* @param {string} param0.variant * @param {number} param0.originalRotation Original Rotation
*/ * @param {number} param0.rotationVariant Rotation variant
createEntity({ root, origin, rotation, originalRotation, rotationVariant, variant }) { * @param {string} param0.variant
const entity = new Entity(root); */
entity.layer = this.getLayer(); createEntity({ root, origin, rotation, originalRotation, rotationVariant, variant }) {
entity.addComponent( const entity = new Entity(root);
new StaticMapEntityComponent({ entity.layer = this.getLayer();
origin: new Vector(origin.x, origin.y), entity.addComponent(
rotation, new StaticMapEntityComponent({
originalRotation, origin: new Vector(origin.x, origin.y),
tileSize: this.getDimensions(variant).copy(), rotation,
code: getCodeFromBuildingData(this, variant, rotationVariant), originalRotation,
}) tileSize: this.getDimensions(variant).copy(),
); code: getCodeFromBuildingData(this, variant, rotationVariant),
this.setupEntityComponents(entity, root); })
this.updateVariants(entity, rotationVariant, variant); );
return entity; this.setupEntityComponents(entity, root);
} this.updateVariants(entity, rotationVariant, variant);
return entity;
/** }
* Returns the sprite for a given variant
* @param {number} rotationVariant /**
* @param {string} variant * Returns the sprite for a given variant
* @returns {AtlasSprite} * @param {number} rotationVariant
*/ * @param {string} variant
getSprite(rotationVariant, variant) { * @returns {AtlasSprite}
return Loader.getSprite( */
"sprites/buildings/" + getSprite(rotationVariant, variant) {
this.id + return Loader.getSprite(
(variant === defaultBuildingVariant ? "" : "-" + variant) + "sprites/buildings/" +
".png" this.id +
); (variant === defaultBuildingVariant ? "" : "-" + variant) +
} ".png"
);
/** }
* Should compute the optimal rotation variant on the given tile
* @param {object} param0 /**
* @param {GameRoot} param0.root * Should compute the optimal rotation variant on the given tile
* @param {Vector} param0.tile * @param {object} param0
* @param {number} param0.rotation * @param {GameRoot} param0.root
* @param {string} param0.variant * @param {Vector} param0.tile
* @param {Layer} param0.layer * @param {number} param0.rotation
* @return {{ rotation: number, rotationVariant: number, connectedEntities?: Array<Entity> }} * @param {string} param0.variant
*/ * @param {Layer} param0.layer
computeOptimalDirectionAndRotationVariantAtTile({ root, tile, rotation, variant, layer }) { * @return {{ rotation: number, rotationVariant: number, connectedEntities?: Array<Entity> }}
if (!this.getIsRotateable(variant)) { */
return { computeOptimalDirectionAndRotationVariantAtTile({ root, tile, rotation, variant, layer }) {
rotation: 0, if (!this.getIsRotateable(variant)) {
rotationVariant: 0, return {
}; rotation: 0,
} rotationVariant: 0,
return { };
rotation, }
rotationVariant: 0, return {
}; rotation,
} rotationVariant: 0,
};
/** }
* Should update the entity to match the given variants
* @param {Entity} entity /**
* @param {number} rotationVariant * Should update the entity to match the given variants
* @param {string} variant * @param {Entity} entity
*/ * @param {number} rotationVariant
updateVariants(entity, rotationVariant, variant) {} * @param {string} variant
*/
// PRIVATE INTERFACE updateVariants(entity, rotationVariant, variant) {}
/** // PRIVATE INTERFACE
* Should setup the entity components
* @param {Entity} entity /**
* @param {GameRoot} root * Should setup the entity components
*/ * @param {Entity} entity
setupEntityComponents(entity, root) { * @param {GameRoot} root
abstract; */
} setupEntityComponents(entity, root) {
} abstract;
}
}

View File

@ -203,7 +203,10 @@ export function initBuildingCodesAfterResourcesLoaded() {
variant.rotationVariant, variant.rotationVariant,
variant.variant variant.variant
); );
variant.silhouetteColor = variant.metaInstance.getSilhouetteColor(); variant.silhouetteColor = variant.metaInstance.getSilhouetteColor(
variant.variant,
variant.rotationVariant
);
} }
// Update caches // Update caches

View File

@ -5,7 +5,6 @@ import { BaseItem } from "../base_item";
import { MinerComponent } from "../components/miner"; import { MinerComponent } from "../components/miner";
import { Entity } from "../entity"; import { Entity } from "../entity";
import { GameSystemWithFilter } from "../game_system_with_filter"; import { GameSystemWithFilter } from "../game_system_with_filter";
import { statisticsUnitsSeconds } from "../hud/parts/statistics_handle";
import { MapChunkView } from "../map_chunk_view"; import { MapChunkView } from "../map_chunk_view";
export class MinerSystem extends GameSystemWithFilter { export class MinerSystem extends GameSystemWithFilter {

View File

@ -45,7 +45,7 @@ export const enumHubGoalRewardsToContentUnlocked = {
[enumHubGoalRewards.reward_cutter_quad]: typed([[MetaCutterBuilding, enumCutterVariants.quad]]), [enumHubGoalRewards.reward_cutter_quad]: typed([[MetaCutterBuilding, enumCutterVariants.quad]]),
[enumHubGoalRewards.reward_painter_double]: typed([[MetaPainterBuilding, enumPainterVariants.double]]), [enumHubGoalRewards.reward_painter_double]: typed([[MetaPainterBuilding, enumPainterVariants.double]]),
[enumHubGoalRewards.reward_painter_quad]: typed([[MetaPainterBuilding, enumPainterVariants.quad]]), [enumHubGoalRewards.reward_painter_quad]: typed([[MetaPainterBuilding, enumPainterVariants.quad]]),
[enumHubGoalRewards.reward_storage]: typed([[MetaStorageBuilding]]), [enumHubGoalRewards.reward_storage]: typed([[MetaStorageBuilding, defaultBuildingVariant]]),
[enumHubGoalRewards.reward_belt_reader]: typed([[MetaReaderBuilding, defaultBuildingVariant]]), [enumHubGoalRewards.reward_belt_reader]: typed([[MetaReaderBuilding, defaultBuildingVariant]]),
[enumHubGoalRewards.reward_display]: typed([[MetaDisplayBuilding, defaultBuildingVariant]]), [enumHubGoalRewards.reward_display]: typed([[MetaDisplayBuilding, defaultBuildingVariant]]),

View File

@ -560,7 +560,7 @@ buildings:
storage: storage:
default: default:
name: &storage Storage name: &storage Storage
description: Stores excess items, up to a given capacity. Can be used as an overflow gate. description: Stores excess items, up to a given capacity. Prioritizes the left output and can be used as an overflow gate.
wire: wire:
default: default:
@ -619,8 +619,7 @@ buildings:
reader: reader:
default: default:
name: &reader Belt Reader name: &reader Belt Reader
# TEMP description: Allows to measure belt throughput. Outputs the last read item on the wires layer (once unlocked).
description: Allows to read the current item from a belt, as well as measuring the throughput.
virtual_processor: virtual_processor:
default: default:
@ -671,8 +670,8 @@ storyRewards:
desc: The <strong>mixer</strong> has been unlocked - Combine two colors using <strong>additive blending</strong> with this building! desc: The <strong>mixer</strong> has been unlocked - Combine two colors using <strong>additive blending</strong> with this building!
reward_stacker: reward_stacker:
title: Combiner title: Stacker
desc: You can now combine shapes with the <strong>combiner</strong>! Both inputs are combined, and if they can be put next to each other, they will be <strong>fused</strong>. If not, the right input is <strong>stacked on top</strong> of the left input! desc: You can now combine shapes with the <strong>stacker</strong>! Both inputs are combined, and if they can be put next to each other, they will be <strong>fused</strong>. If not, the right input is <strong>stacked on top</strong> of the left input!
reward_balancer: reward_balancer:
title: Balancer title: Balancer
@ -712,7 +711,7 @@ storyRewards:
You have now unlocked the <strong>belt reader</strong>! It allows you to measure the throughput of a belt.<br><br>And wait until you unlock wires - then it gets really useful! You have now unlocked the <strong>belt reader</strong>! It allows you to measure the throughput of a belt.<br><br>And wait until you unlock wires - then it gets really useful!
reward_cutter_quad: reward_cutter_quad:
title: Quad Cutting title: Quad Cutter
desc: You have unlocked a variant of the <strong>cutter</strong> - It allows you to cut shapes in <strong>four parts</strong> instead of just two! desc: You have unlocked a variant of the <strong>cutter</strong> - It allows you to cut shapes in <strong>four parts</strong> instead of just two!
reward_painter_double: reward_painter_double: