Merge branch 'master' of https://github.com/tobspr/shapez.io into arrays-now-sets
28
README.md
@ -64,7 +64,7 @@ This project is based on ES5. Some ES2015 features are used but most of them are
|
|||||||
5. Add a constructor. **The constructor must be called with optional parameters only!** `new MyFancyComponent({})` should always work.
|
5. Add a constructor. **The constructor must be called with optional parameters only!** `new MyFancyComponent({})` should always work.
|
||||||
6. Add any props you need in the constructor.
|
6. Add any props you need in the constructor.
|
||||||
7. Add the component in `src/js/game/component_registry.js`
|
7. Add the component in `src/js/game/component_registry.js`
|
||||||
8. Add the componetn in `src/js/game/entity_components.js`
|
8. Add the component in `src/js/game/entity_components.js`
|
||||||
9. Done! You can use your component now
|
9. Done! You can use your component now
|
||||||
|
|
||||||
#### Adding a new building
|
#### Adding a new building
|
||||||
@ -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
|
||||||
@ -92,10 +92,32 @@ This project is based on ES5. Some ES2015 features are used but most of them are
|
|||||||
4. Add the system in `src/js/game/game_system_manager.js` (To `this.systems` and also call `add` in the `internalInitSystems()` method)
|
4. Add the system in `src/js/game/game_system_manager.js` (To `this.systems` and also call `add` in the `internalInitSystems()` method)
|
||||||
5. If your system should draw stuff, this is a bit more complicated. Have a look at existing systems on how they do it.
|
5. If your system should draw stuff, this is a bit more complicated. Have a look at existing systems on how they do it.
|
||||||
|
|
||||||
|
#### Checklist for a new building / testing it
|
||||||
|
|
||||||
|
This is a quick checklist, if a new building is added this points should be fulfilled:
|
||||||
|
|
||||||
|
2. The translation for all variants is done and finalized
|
||||||
|
3. The artwork (regular sprite) is finalized
|
||||||
|
4. The blueprint sprite has been generated and is up to date
|
||||||
|
5. The building has been added to the appropriate toolbar
|
||||||
|
6. The building has a keybinding which makes sense
|
||||||
|
7. The building has a reward assigned and is unlocked at a meaningful point
|
||||||
|
8. The reward for the building has a proper translation
|
||||||
|
9. The reward for the building has a proper image
|
||||||
|
10. The building has a proper tutorial image assigned
|
||||||
|
11. The buliding has a proper toolbar icon
|
||||||
|
12. The reward requires a proper shape
|
||||||
|
13. The building has a proper silhouette color
|
||||||
|
14. The building has a proper matrix for being rendered on the minimap
|
||||||
|
15. The building has proper statistics in the dialog
|
||||||
|
16. The building properly contributes to the shapes produced analytics
|
||||||
|
17. The building is properly persisted in the savegame
|
||||||
|
18. The building is explained properly, ideally via an interactive tutorial
|
||||||
|
|
||||||
### Assets
|
### Assets
|
||||||
|
|
||||||
For most assets I use Adobe Photoshop, you can find them in `assets/`.
|
For most assets I use Adobe Photoshop, you can find them in `assets/`.
|
||||||
|
|
||||||
You will need a <a href="https://www.codeandweb.com/texturepacker" target="_blank">Texture Packer</a> license in order to regenerate the atlas. If you don't have one but want to contribute assets, let me know and I might compile it for you. I'm currently switching to an open source solution but I can't give an estimate when thats done.
|
You will need a <a href="https://www.codeandweb.com/texturepacker" target="_blank">Texture Packer</a> license in order to regenerate the atlas. If you don't have one but want to contribute assets, let me know and I might compile it for you. I'm currently switching to an open source solution but I can't give an estimate when that's done.
|
||||||
|
|
||||||
<img src="https://i.imgur.com/W25Fkl0.png" alt="shapez.io Screenshot">
|
<img src="https://i.imgur.com/W25Fkl0.png" alt="shapez.io Screenshot">
|
||||||
|
|||||||
@ -1,96 +0,0 @@
|
|||||||
// Converts the atlas description to a JSON file
|
|
||||||
|
|
||||||
String.prototype.replaceAll = function (search, replacement) {
|
|
||||||
var target = this;
|
|
||||||
return target.split(search).join(replacement);
|
|
||||||
};
|
|
||||||
|
|
||||||
const fs = require("fs");
|
|
||||||
const path = require("path");
|
|
||||||
|
|
||||||
const folder = path.join(__dirname, "res_built", "atlas");
|
|
||||||
const files = fs.readdirSync(folder);
|
|
||||||
|
|
||||||
const metadata = [];
|
|
||||||
|
|
||||||
files.forEach(filename => {
|
|
||||||
if (filename.endsWith(".atlas")) {
|
|
||||||
// Read content
|
|
||||||
|
|
||||||
const content = fs.readFileSync(path.join(folder, filename), "ascii");
|
|
||||||
|
|
||||||
const lines = content.replaceAll("\r", "").replaceAll("\t", "").split("\n");
|
|
||||||
|
|
||||||
const readLine = () => lines.splice(0, 1)[0];
|
|
||||||
const readValue = () => readLine().replaceAll(" ", "").split(":")[1];
|
|
||||||
const readVector = () =>
|
|
||||||
readValue()
|
|
||||||
.split(",")
|
|
||||||
.map(d => parseInt(d, 10));
|
|
||||||
|
|
||||||
let maxAtlas = 100;
|
|
||||||
|
|
||||||
atlasLoop: while (maxAtlas-- > 0 && lines.length >= 7) {
|
|
||||||
const result = {
|
|
||||||
entries: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
// Extract header
|
|
||||||
const header_fileStart = readLine();
|
|
||||||
const header_fileName = readLine();
|
|
||||||
const header_size = readVector();
|
|
||||||
const header_format = readLine();
|
|
||||||
const header_filter = readLine();
|
|
||||||
const header_repeat = readLine();
|
|
||||||
const baseAtlasName = header_fileName.replace(".png", "");
|
|
||||||
|
|
||||||
// Store size
|
|
||||||
result.size = header_size;
|
|
||||||
|
|
||||||
lineLoop: while (lines.length >= 7) {
|
|
||||||
const entryResult = {};
|
|
||||||
|
|
||||||
const nextLine = lines[0];
|
|
||||||
if (nextLine.length === 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const entry_fileName = readLine() + ".png";
|
|
||||||
|
|
||||||
const entry_rotate = readValue();
|
|
||||||
const entry_xy = readVector();
|
|
||||||
const entry_size = readVector();
|
|
||||||
const entry_orig = readVector();
|
|
||||||
const entry_offset = readVector();
|
|
||||||
const entry_index = readValue();
|
|
||||||
|
|
||||||
entryResult.filename = entry_fileName;
|
|
||||||
entryResult.xy = entry_xy;
|
|
||||||
entryResult.size = entry_size;
|
|
||||||
// entryResult.offset = entry_offset;
|
|
||||||
|
|
||||||
entryResult.origSize = entry_orig;
|
|
||||||
|
|
||||||
let offset = [0, 0];
|
|
||||||
|
|
||||||
// GDX Atlas packer uses 1 - y coordinates. This sucks, and we have to convert it
|
|
||||||
offset[0] = entry_offset[0];
|
|
||||||
offset[1] = entry_orig[1] - entry_offset[1] - entry_size[1];
|
|
||||||
|
|
||||||
entryResult.offset = offset;
|
|
||||||
|
|
||||||
result.entries.push(entryResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("[Atlas]", "'" + baseAtlasName + "'", "has", result.entries.length, "entries");
|
|
||||||
// fs.writeFileSync(path.join(folder, baseAtlasName + ".gen.json"), JSON.stringify(result));
|
|
||||||
|
|
||||||
metadata.push({
|
|
||||||
filename: baseAtlasName + ".png",
|
|
||||||
entries: result,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
fs.writeFileSync(path.join(folder, "meta.gen.json"), JSON.stringify(metadata, null, 4));
|
|
||||||
236
gulp/css.js
@ -1,99 +1,137 @@
|
|||||||
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(browserSync.stream());
|
||||||
.pipe($.plumber())
|
}
|
||||||
.pipe($.sass.sync({ outputStyle: "compressed" }).on("error", $.sass.logError))
|
|
||||||
.pipe($.postcss(postcssPlugins(true, { cachebust: true })))
|
// Builds the css resources
|
||||||
.pipe(gulp.dest(buildFolder))
|
gulp.task("css.resources.dev", () => {
|
||||||
);
|
return resourcesTask({ cachebust: false, isProd: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
// Builds the css in production mode (=minified), without cachebusting
|
// Builds the css resources in prod (=minified)
|
||||||
gulp.task("css.prod-standalone", () => {
|
gulp.task("css.resources.prod", () => {
|
||||||
return (
|
return resourcesTask({ cachebust: true, isProd: true });
|
||||||
gulp
|
});
|
||||||
.src("../src/css/main.scss", { cwd: __dirname })
|
|
||||||
.pipe($.plumber())
|
// Builds the css resources in prod (=minified), without cachebusting
|
||||||
.pipe($.sass.sync({ outputStyle: "compressed" }).on("error", $.sass.logError))
|
gulp.task("css.resources.prod-standalone", () => {
|
||||||
.pipe($.postcss(postcssPlugins(true, { cachebust: false })))
|
return resourcesTask({ cachebust: false, isProd: true });
|
||||||
.pipe(gulp.dest(buildFolder))
|
});
|
||||||
);
|
|
||||||
});
|
function mainTask({ cachebust, isProd }) {
|
||||||
}
|
return gulp
|
||||||
|
.src("../src/css/main.scss", { cwd: __dirname })
|
||||||
module.exports = {
|
.pipe($.plumber())
|
||||||
gulptasksCSS,
|
.pipe($.sass.sync().on("error", $.sass.logError))
|
||||||
};
|
.pipe(
|
||||||
|
$.postcss([
|
||||||
|
$.postcssCriticalSplit({
|
||||||
|
blockTag: "@load-async",
|
||||||
|
output: "rest",
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
)
|
||||||
|
.pipe($.postcss(postcssPlugins(isProd, { cachebust })))
|
||||||
|
.pipe(gulp.dest(buildFolder))
|
||||||
|
.pipe(browserSync.stream());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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,
|
||||||
|
};
|
||||||
|
|||||||
650
gulp/gulpfile.js
@ -1,325 +1,325 @@
|
|||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
|
|
||||||
require("colors");
|
require("colors");
|
||||||
|
|
||||||
const gulp = require("gulp");
|
const gulp = require("gulp");
|
||||||
const browserSync = require("browser-sync").create({});
|
const browserSync = require("browser-sync").create({});
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const deleteEmpty = require("delete-empty");
|
const deleteEmpty = require("delete-empty");
|
||||||
const execSync = require("child_process").execSync;
|
const execSync = require("child_process").execSync;
|
||||||
|
|
||||||
const lfsOutput = execSync("git lfs install", { encoding: "utf-8" });
|
const lfsOutput = execSync("git lfs install", { encoding: "utf-8" });
|
||||||
if (!lfsOutput.toLowerCase().includes("git lfs initialized")) {
|
if (!lfsOutput.toLowerCase().includes("git lfs initialized")) {
|
||||||
console.error(`
|
console.error(`
|
||||||
Git LFS is not installed, unable to build.
|
Git LFS is not installed, unable to build.
|
||||||
|
|
||||||
To install Git LFS on Linux:
|
To install Git LFS on Linux:
|
||||||
- Arch:
|
- Arch:
|
||||||
sudo pacman -S git-lfs
|
sudo pacman -S git-lfs
|
||||||
- Debian/Ubuntu:
|
- Debian/Ubuntu:
|
||||||
sudo apt install git-lfs
|
sudo apt install git-lfs
|
||||||
|
|
||||||
For other systems, see:
|
For other systems, see:
|
||||||
https://github.com/git-lfs/git-lfs/wiki/Installation
|
https://github.com/git-lfs/git-lfs/wiki/Installation
|
||||||
`);
|
`);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load other plugins dynamically
|
// Load other plugins dynamically
|
||||||
const $ = require("gulp-load-plugins")({
|
const $ = require("gulp-load-plugins")({
|
||||||
scope: ["devDependencies"],
|
scope: ["devDependencies"],
|
||||||
pattern: "*",
|
pattern: "*",
|
||||||
});
|
});
|
||||||
|
|
||||||
// Check environment variables
|
// Check environment variables
|
||||||
|
|
||||||
const envVars = [
|
const envVars = [
|
||||||
"SHAPEZ_CLI_SERVER_HOST",
|
"SHAPEZ_CLI_SERVER_HOST",
|
||||||
// "SHAPEZ_CLI_PHONEGAP_KEY",
|
// "SHAPEZ_CLI_PHONEGAP_KEY",
|
||||||
"SHAPEZ_CLI_ALPHA_FTP_USER",
|
"SHAPEZ_CLI_ALPHA_FTP_USER",
|
||||||
"SHAPEZ_CLI_ALPHA_FTP_PW",
|
"SHAPEZ_CLI_ALPHA_FTP_PW",
|
||||||
"SHAPEZ_CLI_STAGING_FTP_USER",
|
"SHAPEZ_CLI_STAGING_FTP_USER",
|
||||||
"SHAPEZ_CLI_STAGING_FTP_PW",
|
"SHAPEZ_CLI_STAGING_FTP_PW",
|
||||||
"SHAPEZ_CLI_LIVE_FTP_USER",
|
"SHAPEZ_CLI_LIVE_FTP_USER",
|
||||||
"SHAPEZ_CLI_LIVE_FTP_PW",
|
"SHAPEZ_CLI_LIVE_FTP_PW",
|
||||||
];
|
];
|
||||||
|
|
||||||
for (let i = 0; i < envVars.length; ++i) {
|
for (let i = 0; i < envVars.length; ++i) {
|
||||||
if (!process.env[envVars[i]]) {
|
if (!process.env[envVars[i]]) {
|
||||||
console.warn("Please set", envVars[i]);
|
console.warn("Please set", envVars[i]);
|
||||||
// process.exit(1);
|
// process.exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const baseDir = path.join(__dirname, "..");
|
const baseDir = path.join(__dirname, "..");
|
||||||
const buildFolder = path.join(baseDir, "build");
|
const buildFolder = path.join(baseDir, "build");
|
||||||
|
|
||||||
const imgres = require("./image-resources");
|
const imgres = require("./image-resources");
|
||||||
imgres.gulptasksImageResources($, gulp, buildFolder);
|
imgres.gulptasksImageResources($, gulp, buildFolder);
|
||||||
|
|
||||||
const css = require("./css");
|
const css = require("./css");
|
||||||
css.gulptasksCSS($, gulp, buildFolder, browserSync);
|
css.gulptasksCSS($, gulp, buildFolder, browserSync);
|
||||||
|
|
||||||
const sounds = require("./sounds");
|
const sounds = require("./sounds");
|
||||||
sounds.gulptasksSounds($, gulp, buildFolder);
|
sounds.gulptasksSounds($, gulp, buildFolder);
|
||||||
|
|
||||||
const js = require("./js");
|
const js = require("./js");
|
||||||
js.gulptasksJS($, gulp, buildFolder, browserSync);
|
js.gulptasksJS($, gulp, buildFolder, browserSync);
|
||||||
|
|
||||||
const html = require("./html");
|
const html = require("./html");
|
||||||
html.gulptasksHTML($, gulp, buildFolder, browserSync);
|
html.gulptasksHTML($, gulp, buildFolder, browserSync);
|
||||||
|
|
||||||
const ftp = require("./ftp");
|
const ftp = require("./ftp");
|
||||||
ftp.gulptasksFTP($, gulp, buildFolder);
|
ftp.gulptasksFTP($, gulp, buildFolder);
|
||||||
|
|
||||||
const docs = require("./docs");
|
const docs = require("./docs");
|
||||||
docs.gulptasksDocs($, gulp, buildFolder);
|
docs.gulptasksDocs($, gulp, buildFolder);
|
||||||
|
|
||||||
const standalone = require("./standalone");
|
const standalone = require("./standalone");
|
||||||
standalone.gulptasksStandalone($, gulp, buildFolder);
|
standalone.gulptasksStandalone($, gulp, buildFolder);
|
||||||
|
|
||||||
const translations = require("./translations");
|
const translations = require("./translations");
|
||||||
translations.gulptasksTranslations($, gulp, buildFolder);
|
translations.gulptasksTranslations($, gulp, buildFolder);
|
||||||
|
|
||||||
// FIXME
|
// FIXME
|
||||||
// const cordova = require("./cordova");
|
// const cordova = require("./cordova");
|
||||||
// cordova.gulptasksCordova($, gulp, buildFolder);
|
// cordova.gulptasksCordova($, gulp, buildFolder);
|
||||||
|
|
||||||
///////////////////// BUILD TASKS /////////////////////
|
///////////////////// BUILD TASKS /////////////////////
|
||||||
|
|
||||||
// Cleans up everything
|
// Cleans up everything
|
||||||
gulp.task("utils.cleanBuildFolder", () => {
|
gulp.task("utils.cleanBuildFolder", () => {
|
||||||
return gulp.src(buildFolder, { read: false, allowEmpty: true }).pipe($.clean({ force: true }));
|
return gulp.src(buildFolder, { read: false, allowEmpty: true }).pipe($.clean({ force: true }));
|
||||||
});
|
});
|
||||||
gulp.task("utils.cleanBuildTempFolder", () => {
|
gulp.task("utils.cleanBuildTempFolder", () => {
|
||||||
return gulp
|
return gulp
|
||||||
.src(path.join(__dirname, "..", "src", "js", "built-temp"), { read: false, allowEmpty: true })
|
.src(path.join(__dirname, "..", "src", "js", "built-temp"), { read: false, allowEmpty: true })
|
||||||
.pipe($.clean({ force: true }));
|
.pipe($.clean({ force: true }));
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task("utils.cleanup", gulp.series("utils.cleanBuildFolder", "utils.cleanBuildTempFolder"));
|
gulp.task("utils.cleanup", gulp.series("utils.cleanBuildFolder", "utils.cleanBuildTempFolder"));
|
||||||
|
|
||||||
// Requires no uncomitted files
|
// Requires no uncomitted files
|
||||||
gulp.task("utils.requireCleanWorkingTree", cb => {
|
gulp.task("utils.requireCleanWorkingTree", cb => {
|
||||||
let output = $.trim(execSync("git status -su").toString("ascii")).replace(/\r/gi, "").split("\n");
|
let output = $.trim(execSync("git status -su").toString("ascii")).replace(/\r/gi, "").split("\n");
|
||||||
|
|
||||||
// Filter files which are OK to be untracked
|
// Filter files which are OK to be untracked
|
||||||
output = output
|
output = output
|
||||||
.map(x => x.replace(/[\r\n]+/gi, ""))
|
.map(x => x.replace(/[\r\n]+/gi, ""))
|
||||||
.filter(x => x.indexOf(".local.js") < 0)
|
.filter(x => x.indexOf(".local.js") < 0)
|
||||||
.filter(x => x.length > 0);
|
.filter(x => x.length > 0);
|
||||||
if (output.length > 0) {
|
if (output.length > 0) {
|
||||||
console.error("\n\nYou have unstaged changes, please commit everything first!");
|
console.error("\n\nYou have unstaged changes, please commit everything first!");
|
||||||
console.error("Unstaged files:");
|
console.error("Unstaged files:");
|
||||||
console.error(output.map(x => "'" + x + "'").join("\n"));
|
console.error(output.map(x => "'" + x + "'").join("\n"));
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
cb();
|
cb();
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task("utils.copyAdditionalBuildFiles", cb => {
|
gulp.task("utils.copyAdditionalBuildFiles", cb => {
|
||||||
const additionalFolder = path.join("additional_build_files");
|
const additionalFolder = path.join("additional_build_files");
|
||||||
const additionalSrcGlobs = [
|
const additionalSrcGlobs = [
|
||||||
path.join(additionalFolder, "**/*.*"),
|
path.join(additionalFolder, "**/*.*"),
|
||||||
path.join(additionalFolder, "**/.*"),
|
path.join(additionalFolder, "**/.*"),
|
||||||
path.join(additionalFolder, "**/*"),
|
path.join(additionalFolder, "**/*"),
|
||||||
];
|
];
|
||||||
|
|
||||||
return gulp.src(additionalSrcGlobs).pipe(gulp.dest(buildFolder));
|
return gulp.src(additionalSrcGlobs).pipe(gulp.dest(buildFolder));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Starts a webserver on the built directory (useful for testing prod build)
|
// Starts a webserver on the built directory (useful for testing prod build)
|
||||||
gulp.task("main.webserver", () => {
|
gulp.task("main.webserver", () => {
|
||||||
return gulp.src(buildFolder).pipe(
|
return gulp.src(buildFolder).pipe(
|
||||||
$.webserver({
|
$.webserver({
|
||||||
livereload: {
|
livereload: {
|
||||||
enable: true,
|
enable: true,
|
||||||
},
|
},
|
||||||
directoryListing: false,
|
directoryListing: false,
|
||||||
open: true,
|
open: true,
|
||||||
port: 3005,
|
port: 3005,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
function serve({ standalone }) {
|
function serve({ standalone }) {
|
||||||
browserSync.init({
|
browserSync.init({
|
||||||
server: buildFolder,
|
server: buildFolder,
|
||||||
port: 3005,
|
port: 3005,
|
||||||
ghostMode: {
|
ghostMode: {
|
||||||
clicks: false,
|
clicks: false,
|
||||||
scroll: false,
|
scroll: false,
|
||||||
location: false,
|
location: false,
|
||||||
forms: false,
|
forms: false,
|
||||||
},
|
},
|
||||||
logLevel: "info",
|
logLevel: "info",
|
||||||
logPrefix: "BS",
|
logPrefix: "BS",
|
||||||
online: false,
|
online: false,
|
||||||
xip: false,
|
xip: false,
|
||||||
notify: false,
|
notify: false,
|
||||||
reloadDebounce: 100,
|
reloadDebounce: 100,
|
||||||
reloadOnRestart: true,
|
reloadOnRestart: true,
|
||||||
watchEvents: ["add", "change"],
|
watchEvents: ["add", "change"],
|
||||||
});
|
});
|
||||||
|
|
||||||
// Watch .scss files, those trigger a css rebuild
|
// Watch .scss files, those trigger a css rebuild
|
||||||
gulp.watch(["../src/**/*.scss"], gulp.series("css.dev"));
|
gulp.watch(["../src/**/*.scss"], gulp.series("css.dev"));
|
||||||
|
|
||||||
// Watch .html files, those trigger a html rebuild
|
// Watch .html files, those trigger a html rebuild
|
||||||
gulp.watch("../src/**/*.html", gulp.series(standalone ? "html.standalone-dev" : "html.dev"));
|
gulp.watch("../src/**/*.html", gulp.series(standalone ? "html.standalone-dev" : "html.dev"));
|
||||||
|
|
||||||
// Watch sound files
|
// Watch sound files
|
||||||
// gulp.watch(["../res_raw/sounds/**/*.mp3", "../res_raw/sounds/**/*.wav"], gulp.series("sounds.dev"));
|
// gulp.watch(["../res_raw/sounds/**/*.mp3", "../res_raw/sounds/**/*.wav"], gulp.series("sounds.dev"));
|
||||||
|
|
||||||
// Watch translations
|
// Watch translations
|
||||||
gulp.watch("../translations/**/*.yaml", gulp.series("translations.convertToJson"));
|
gulp.watch("../translations/**/*.yaml", gulp.series("translations.convertToJson"));
|
||||||
|
|
||||||
gulp.watch(
|
gulp.watch(
|
||||||
["../res_raw/sounds/sfx/*.mp3", "../res_raw/sounds/sfx/*.wav"],
|
["../res_raw/sounds/sfx/*.mp3", "../res_raw/sounds/sfx/*.wav"],
|
||||||
gulp.series("sounds.sfx", "sounds.copy")
|
gulp.series("sounds.sfx", "sounds.copy")
|
||||||
);
|
);
|
||||||
gulp.watch(
|
gulp.watch(
|
||||||
["../res_raw/sounds/music/*.mp3", "../res_raw/sounds/music/*.wav"],
|
["../res_raw/sounds/music/*.mp3", "../res_raw/sounds/music/*.wav"],
|
||||||
gulp.series("sounds.music", "sounds.copy")
|
gulp.series("sounds.music", "sounds.copy")
|
||||||
);
|
);
|
||||||
|
|
||||||
// Watch resource files and copy them on change
|
// Watch resource files and copy them on change
|
||||||
gulp.watch(imgres.nonImageResourcesGlobs, gulp.series("imgres.copyNonImageResources"));
|
gulp.watch(imgres.nonImageResourcesGlobs, gulp.series("imgres.copyNonImageResources"));
|
||||||
gulp.watch(imgres.imageResourcesGlobs, gulp.series("imgres.copyImageResources"));
|
gulp.watch(imgres.imageResourcesGlobs, gulp.series("imgres.copyImageResources"));
|
||||||
|
|
||||||
// Watch .atlas files and recompile the atlas on change
|
// Watch .atlas files and recompile the atlas on change
|
||||||
gulp.watch("../res_built/atlas/*.json", gulp.series("imgres.atlas"));
|
gulp.watch("../res_built/atlas/*.json", gulp.series("imgres.atlas"));
|
||||||
|
|
||||||
// Watch the build folder and reload when anything changed
|
// Watch the build folder and reload when anything changed
|
||||||
const extensions = ["html", "js", "png", "gif", "jpg", "svg", "mp3", "ico", "woff2", "json"];
|
const extensions = ["html", "js", "png", "gif", "jpg", "svg", "mp3", "ico", "woff2", "json"];
|
||||||
gulp.watch(extensions.map(ext => path.join(buildFolder, "**", "*." + ext))).on("change", function (path) {
|
gulp.watch(extensions.map(ext => path.join(buildFolder, "**", "*." + ext))).on("change", function (path) {
|
||||||
return gulp.src(path).pipe(browserSync.reload({ stream: true }));
|
return gulp.src(path).pipe(browserSync.reload({ stream: true }));
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.watch("../src/js/built-temp/*.json").on("change", function (path) {
|
gulp.watch("../src/js/built-temp/*.json").on("change", function (path) {
|
||||||
return gulp.src(path).pipe(browserSync.reload({ stream: true }));
|
return gulp.src(path).pipe(browserSync.reload({ stream: true }));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Start the webpack watching server (Will never return)
|
// Start the webpack watching server (Will never return)
|
||||||
if (standalone) {
|
if (standalone) {
|
||||||
gulp.series("js.standalone-dev.watch")(() => true);
|
gulp.series("js.standalone-dev.watch")(() => true);
|
||||||
} else {
|
} else {
|
||||||
gulp.series("js.dev.watch")(() => true);
|
gulp.series("js.dev.watch")(() => true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////// RUNNABLE TASKS /////////////////////
|
///////////////////// RUNNABLE TASKS /////////////////////
|
||||||
|
|
||||||
// Pre and postbuild
|
// Pre and postbuild
|
||||||
gulp.task("step.baseResources", gulp.series("imgres.allOptimized"));
|
gulp.task("step.baseResources", gulp.series("imgres.allOptimized"));
|
||||||
gulp.task("step.deleteEmpty", cb => {
|
gulp.task("step.deleteEmpty", cb => {
|
||||||
deleteEmpty.sync(buildFolder);
|
deleteEmpty.sync(buildFolder);
|
||||||
cb();
|
cb();
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task("step.postbuild", gulp.series("imgres.cleanupUnusedCssInlineImages", "step.deleteEmpty"));
|
gulp.task("step.postbuild", gulp.series("imgres.cleanupUnusedCssInlineImages", "step.deleteEmpty"));
|
||||||
|
|
||||||
// Builds everything (dev)
|
// Builds everything (dev)
|
||||||
gulp.task(
|
gulp.task(
|
||||||
"build.dev",
|
"build.dev",
|
||||||
gulp.series(
|
gulp.series(
|
||||||
"utils.cleanup",
|
"utils.cleanup",
|
||||||
"utils.copyAdditionalBuildFiles",
|
"utils.copyAdditionalBuildFiles",
|
||||||
"imgres.atlas",
|
"imgres.atlas",
|
||||||
"sounds.dev",
|
"sounds.dev",
|
||||||
"imgres.copyImageResources",
|
"imgres.copyImageResources",
|
||||||
"imgres.copyNonImageResources",
|
"imgres.copyNonImageResources",
|
||||||
"translations.fullBuild",
|
"translations.fullBuild",
|
||||||
"css.dev",
|
"css.dev",
|
||||||
"html.dev"
|
"html.dev"
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Builds everything (standalone -dev)
|
// Builds everything (standalone -dev)
|
||||||
gulp.task(
|
gulp.task(
|
||||||
"build.standalone.dev",
|
"build.standalone.dev",
|
||||||
gulp.series(
|
gulp.series(
|
||||||
"utils.cleanup",
|
"utils.cleanup",
|
||||||
"imgres.atlas",
|
"imgres.atlas",
|
||||||
"sounds.dev",
|
"sounds.dev",
|
||||||
"imgres.copyImageResources",
|
"imgres.copyImageResources",
|
||||||
"imgres.copyNonImageResources",
|
"imgres.copyNonImageResources",
|
||||||
"translations.fullBuild",
|
"translations.fullBuild",
|
||||||
"js.standalone-dev",
|
"js.standalone-dev",
|
||||||
"css.dev",
|
"css.dev",
|
||||||
"html.standalone-dev"
|
"html.standalone-dev"
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Builds everything (staging)
|
// Builds everything (staging)
|
||||||
gulp.task("step.staging.code", gulp.series("sounds.fullbuild", "translations.fullBuild", "js.staging"));
|
gulp.task("step.staging.code", gulp.series("sounds.fullbuild", "translations.fullBuild", "js.staging"));
|
||||||
gulp.task(
|
gulp.task(
|
||||||
"step.staging.mainbuild",
|
"step.staging.mainbuild",
|
||||||
gulp.parallel("utils.copyAdditionalBuildFiles", "step.baseResources", "step.staging.code")
|
gulp.parallel("utils.copyAdditionalBuildFiles", "step.baseResources", "step.staging.code")
|
||||||
);
|
);
|
||||||
gulp.task("step.staging.all", gulp.series("step.staging.mainbuild", "css.prod", "html.staging"));
|
gulp.task("step.staging.all", gulp.series("step.staging.mainbuild", "css.prod", "html.staging"));
|
||||||
gulp.task("build.staging", gulp.series("utils.cleanup", "step.staging.all", "step.postbuild"));
|
gulp.task("build.staging", gulp.series("utils.cleanup", "step.staging.all", "step.postbuild"));
|
||||||
|
|
||||||
// Builds everything (prod)
|
// Builds everything (prod)
|
||||||
gulp.task("step.prod.code", gulp.series("sounds.fullbuild", "translations.fullBuild", "js.prod"));
|
gulp.task("step.prod.code", gulp.series("sounds.fullbuild", "translations.fullBuild", "js.prod"));
|
||||||
gulp.task(
|
gulp.task(
|
||||||
"step.prod.mainbuild",
|
"step.prod.mainbuild",
|
||||||
gulp.parallel("utils.copyAdditionalBuildFiles", "step.baseResources", "step.prod.code")
|
gulp.parallel("utils.copyAdditionalBuildFiles", "step.baseResources", "step.prod.code")
|
||||||
);
|
);
|
||||||
gulp.task("step.prod.all", gulp.series("step.prod.mainbuild", "css.prod", "html.prod"));
|
gulp.task("step.prod.all", gulp.series("step.prod.mainbuild", "css.prod", "html.prod"));
|
||||||
gulp.task("build.prod", gulp.series("utils.cleanup", "step.prod.all", "step.postbuild"));
|
gulp.task("build.prod", gulp.series("utils.cleanup", "step.prod.all", "step.postbuild"));
|
||||||
|
|
||||||
// Builds everything (standalone-beta)
|
// Builds everything (standalone-beta)
|
||||||
gulp.task(
|
gulp.task(
|
||||||
"step.standalone-beta.code",
|
"step.standalone-beta.code",
|
||||||
gulp.series("sounds.fullbuildHQ", "translations.fullBuild", "js.standalone-beta")
|
gulp.series("sounds.fullbuildHQ", "translations.fullBuild", "js.standalone-beta")
|
||||||
);
|
);
|
||||||
gulp.task("step.standalone-beta.mainbuild", gulp.parallel("step.baseResources", "step.standalone-beta.code"));
|
gulp.task("step.standalone-beta.mainbuild", gulp.parallel("step.baseResources", "step.standalone-beta.code"));
|
||||||
gulp.task(
|
gulp.task(
|
||||||
"step.standalone-beta.all",
|
"step.standalone-beta.all",
|
||||||
gulp.series("step.standalone-beta.mainbuild", "css.prod-standalone", "html.standalone-beta")
|
gulp.series("step.standalone-beta.mainbuild", "css.prod-standalone", "html.standalone-beta")
|
||||||
);
|
);
|
||||||
gulp.task(
|
gulp.task(
|
||||||
"build.standalone-beta",
|
"build.standalone-beta",
|
||||||
gulp.series("utils.cleanup", "step.standalone-beta.all", "step.postbuild")
|
gulp.series("utils.cleanup", "step.standalone-beta.all", "step.postbuild")
|
||||||
);
|
);
|
||||||
|
|
||||||
// Builds everything (standalone-prod)
|
// Builds everything (standalone-prod)
|
||||||
gulp.task(
|
gulp.task(
|
||||||
"step.standalone-prod.code",
|
"step.standalone-prod.code",
|
||||||
gulp.series("sounds.fullbuildHQ", "translations.fullBuild", "js.standalone-prod")
|
gulp.series("sounds.fullbuildHQ", "translations.fullBuild", "js.standalone-prod")
|
||||||
);
|
);
|
||||||
gulp.task("step.standalone-prod.mainbuild", gulp.parallel("step.baseResources", "step.standalone-prod.code"));
|
gulp.task("step.standalone-prod.mainbuild", gulp.parallel("step.baseResources", "step.standalone-prod.code"));
|
||||||
gulp.task(
|
gulp.task(
|
||||||
"step.standalone-prod.all",
|
"step.standalone-prod.all",
|
||||||
gulp.series("step.standalone-prod.mainbuild", "css.prod-standalone", "html.standalone-prod")
|
gulp.series("step.standalone-prod.mainbuild", "css.prod-standalone", "html.standalone-prod")
|
||||||
);
|
);
|
||||||
gulp.task(
|
gulp.task(
|
||||||
"build.standalone-prod",
|
"build.standalone-prod",
|
||||||
gulp.series("utils.cleanup", "step.standalone-prod.all", "step.postbuild")
|
gulp.series("utils.cleanup", "step.standalone-prod.all", "step.postbuild")
|
||||||
);
|
);
|
||||||
|
|
||||||
// Deploying!
|
// Deploying!
|
||||||
gulp.task(
|
gulp.task(
|
||||||
"main.deploy.alpha",
|
"main.deploy.alpha",
|
||||||
gulp.series("utils.requireCleanWorkingTree", "build.staging", "ftp.upload.alpha")
|
gulp.series("utils.requireCleanWorkingTree", "build.staging", "ftp.upload.alpha")
|
||||||
);
|
);
|
||||||
gulp.task(
|
gulp.task(
|
||||||
"main.deploy.staging",
|
"main.deploy.staging",
|
||||||
gulp.series("utils.requireCleanWorkingTree", "build.staging", "ftp.upload.staging")
|
gulp.series("utils.requireCleanWorkingTree", "build.staging", "ftp.upload.staging")
|
||||||
);
|
);
|
||||||
gulp.task("main.deploy.prod", gulp.series("utils.requireCleanWorkingTree", "build.prod", "ftp.upload.prod"));
|
gulp.task("main.deploy.prod", gulp.series("utils.requireCleanWorkingTree", "build.prod", "ftp.upload.prod"));
|
||||||
gulp.task("main.deploy.all", gulp.series("main.deploy.staging", "main.deploy.prod"));
|
gulp.task("main.deploy.all", gulp.series("main.deploy.staging", "main.deploy.prod"));
|
||||||
gulp.task("main.standalone", gulp.series("build.standalone-prod", "standalone.package.prod"));
|
gulp.task("main.standalone", gulp.series("build.standalone-prod", "standalone.package.prod"));
|
||||||
|
|
||||||
// Live-development
|
// Live-development
|
||||||
gulp.task(
|
gulp.task(
|
||||||
"main.serveDev",
|
"main.serveDev",
|
||||||
gulp.series("build.dev", () => serve({ standalone: false }))
|
gulp.series("build.dev", () => serve({ standalone: false }))
|
||||||
);
|
);
|
||||||
gulp.task(
|
gulp.task(
|
||||||
"main.serveStandalone",
|
"main.serveStandalone",
|
||||||
gulp.series("build.standalone.dev", () => serve({ standalone: true }))
|
gulp.series("build.standalone.dev", () => serve({ standalone: true }))
|
||||||
);
|
);
|
||||||
|
|
||||||
gulp.task("default", gulp.series("main.serveDev"));
|
gulp.task("default", gulp.series("main.serveDev"));
|
||||||
|
|||||||
584
gulp/html.js
@ -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,
|
||||||
|
};
|
||||||
|
|||||||
@ -1,148 +1,141 @@
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
|
|
||||||
// Globs for non-ui resources
|
// Globs for non-ui resources
|
||||||
const nonImageResourcesGlobs = ["../res/**/*.woff2", "../res/*.ico", "../res/**/*.webm"];
|
const nonImageResourcesGlobs = ["../res/**/*.woff2", "../res/*.ico", "../res/**/*.webm"];
|
||||||
|
|
||||||
// Globs for ui resources
|
// Globs for ui resources
|
||||||
const imageResourcesGlobs = ["../res/**/*.png", "../res/**/*.svg", "../res/**/*.jpg", "../res/**/*.gif"];
|
const imageResourcesGlobs = ["../res/**/*.png", "../res/**/*.svg", "../res/**/*.jpg", "../res/**/*.gif"];
|
||||||
|
|
||||||
function gulptasksImageResources($, gulp, buildFolder) {
|
function gulptasksImageResources($, gulp, buildFolder) {
|
||||||
// Lossless options
|
// Lossless options
|
||||||
const minifyImagesOptsLossless = () => [
|
const minifyImagesOptsLossless = () => [
|
||||||
$.imageminJpegtran({
|
$.imageminJpegtran({
|
||||||
progressive: true,
|
progressive: true,
|
||||||
}),
|
}),
|
||||||
$.imagemin.svgo({}),
|
$.imagemin.svgo({}),
|
||||||
$.imagemin.optipng({
|
$.imagemin.optipng({
|
||||||
optimizationLevel: 3,
|
optimizationLevel: 3,
|
||||||
}),
|
}),
|
||||||
$.imageminGifsicle({
|
$.imageminGifsicle({
|
||||||
optimizationLevel: 3,
|
optimizationLevel: 3,
|
||||||
colors: 128,
|
colors: 128,
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
// Lossy options
|
// Lossy options
|
||||||
const minifyImagesOpts = () => [
|
const minifyImagesOpts = () => [
|
||||||
$.imagemin.mozjpeg({
|
$.imagemin.mozjpeg({
|
||||||
quality: 80,
|
quality: 80,
|
||||||
maxMemory: 1024 * 1024 * 8,
|
maxMemory: 1024 * 1024 * 8,
|
||||||
}),
|
}),
|
||||||
$.imagemin.svgo({}),
|
$.imagemin.svgo({}),
|
||||||
$.imageminPngquant({
|
$.imageminPngquant({
|
||||||
speed: 1,
|
speed: 1,
|
||||||
strip: true,
|
strip: true,
|
||||||
quality: [0.65, 0.9],
|
quality: [0.65, 0.9],
|
||||||
dithering: false,
|
dithering: false,
|
||||||
verbose: false,
|
verbose: false,
|
||||||
}),
|
}),
|
||||||
$.imagemin.optipng({
|
$.imagemin.optipng({
|
||||||
optimizationLevel: 3,
|
optimizationLevel: 3,
|
||||||
}),
|
}),
|
||||||
$.imageminGifsicle({
|
$.imageminGifsicle({
|
||||||
optimizationLevel: 3,
|
optimizationLevel: 3,
|
||||||
colors: 128,
|
colors: 128,
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
// Where the resources folder are
|
// Where the resources folder are
|
||||||
const resourcesDestFolder = path.join(buildFolder, "res");
|
const resourcesDestFolder = path.join(buildFolder, "res");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if an atlas must use lossless compression
|
* Determines if an atlas must use lossless compression
|
||||||
* @param {string} fname
|
* @param {string} fname
|
||||||
*/
|
*/
|
||||||
function fileMustBeLossless(fname) {
|
function fileMustBeLossless(fname) {
|
||||||
return fname.indexOf("lossless") >= 0;
|
return fname.indexOf("lossless") >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////// ATLAS /////////////////////
|
/////////////// ATLAS /////////////////////
|
||||||
|
|
||||||
// Copies the atlas to the final destination
|
// Copies the atlas to the final destination
|
||||||
gulp.task("imgres.atlas", () => {
|
gulp.task("imgres.atlas", () => {
|
||||||
return gulp
|
return gulp.src(["../res_built/atlas/*.png"]).pipe(gulp.dest(resourcesDestFolder));
|
||||||
.src(["../res_built/atlas/*.png"])
|
});
|
||||||
.pipe($.cached("imgres.atlas"))
|
|
||||||
.pipe(gulp.dest(resourcesDestFolder));
|
// Copies the atlas to the final destination after optimizing it (lossy compression)
|
||||||
});
|
gulp.task("imgres.atlasOptimized", () => {
|
||||||
|
return gulp
|
||||||
// Copies the atlas to the final destination after optimizing it (lossy compression)
|
.src(["../res_built/atlas/*.png"])
|
||||||
gulp.task("imgres.atlasOptimized", () => {
|
.pipe(
|
||||||
return gulp
|
$.if(
|
||||||
.src(["../res_built/atlas/*.png"])
|
fname => fileMustBeLossless(fname.history[0]),
|
||||||
.pipe($.cached("imgres.atlasOptimized"))
|
$.imagemin(minifyImagesOptsLossless()),
|
||||||
.pipe(
|
$.imagemin(minifyImagesOpts())
|
||||||
$.if(
|
)
|
||||||
fname => fileMustBeLossless(fname.history[0]),
|
)
|
||||||
$.imagemin(minifyImagesOptsLossless()),
|
.pipe(gulp.dest(resourcesDestFolder));
|
||||||
$.imagemin(minifyImagesOpts())
|
});
|
||||||
)
|
|
||||||
)
|
//////////////////// RESOURCES //////////////////////
|
||||||
.pipe(gulp.dest(resourcesDestFolder));
|
|
||||||
});
|
// Copies all resources which are no ui resources
|
||||||
|
gulp.task("imgres.copyNonImageResources", () => {
|
||||||
//////////////////// RESOURCES //////////////////////
|
return gulp.src(nonImageResourcesGlobs).pipe(gulp.dest(resourcesDestFolder));
|
||||||
|
});
|
||||||
// Copies all resources which are no ui resources
|
|
||||||
gulp.task("imgres.copyNonImageResources", () => {
|
// Copies all ui resources
|
||||||
return gulp
|
gulp.task("imgres.copyImageResources", () => {
|
||||||
.src(nonImageResourcesGlobs)
|
return gulp
|
||||||
.pipe($.cached("imgres.copyNonImageResources"))
|
.src(imageResourcesGlobs)
|
||||||
.pipe(gulp.dest(resourcesDestFolder));
|
|
||||||
});
|
.pipe($.cached("imgres.copyImageResources"))
|
||||||
|
.pipe(gulp.dest(path.join(resourcesDestFolder)));
|
||||||
// Copies all ui resources
|
});
|
||||||
gulp.task("imgres.copyImageResources", () => {
|
|
||||||
return gulp
|
// Copies all ui resources and optimizes them
|
||||||
.src(imageResourcesGlobs)
|
gulp.task("imgres.copyImageResourcesOptimized", () => {
|
||||||
.pipe($.cached("copyImageResources"))
|
return gulp
|
||||||
.pipe(gulp.dest(path.join(resourcesDestFolder)));
|
.src(imageResourcesGlobs)
|
||||||
});
|
.pipe(
|
||||||
|
$.if(
|
||||||
// Copies all ui resources and optimizes them
|
fname => fileMustBeLossless(fname.history[0]),
|
||||||
gulp.task("imgres.copyImageResourcesOptimized", () => {
|
$.imagemin(minifyImagesOptsLossless()),
|
||||||
return gulp
|
$.imagemin(minifyImagesOpts())
|
||||||
.src(imageResourcesGlobs)
|
)
|
||||||
.pipe($.cached("imgres.copyImageResourcesOptimized"))
|
)
|
||||||
.pipe(
|
.pipe(gulp.dest(path.join(resourcesDestFolder)));
|
||||||
$.if(
|
});
|
||||||
fname => fileMustBeLossless(fname.history[0]),
|
|
||||||
$.imagemin(minifyImagesOptsLossless()),
|
// Copies all resources and optimizes them
|
||||||
$.imagemin(minifyImagesOpts())
|
gulp.task(
|
||||||
)
|
"imgres.allOptimized",
|
||||||
)
|
gulp.parallel(
|
||||||
.pipe(gulp.dest(path.join(resourcesDestFolder)));
|
"imgres.atlasOptimized",
|
||||||
});
|
"imgres.copyNonImageResources",
|
||||||
|
"imgres.copyImageResourcesOptimized"
|
||||||
// Copies all resources and optimizes them
|
)
|
||||||
gulp.task(
|
);
|
||||||
"imgres.allOptimized",
|
|
||||||
gulp.parallel(
|
// Cleans up unused images which are instead inline into the css
|
||||||
"imgres.atlasOptimized",
|
gulp.task("imgres.cleanupUnusedCssInlineImages", () => {
|
||||||
"imgres.copyNonImageResources",
|
return gulp
|
||||||
"imgres.copyImageResourcesOptimized"
|
.src(
|
||||||
)
|
[
|
||||||
);
|
path.join(buildFolder, "res", "ui", "**", "*.png"),
|
||||||
|
path.join(buildFolder, "res", "ui", "**", "*.jpg"),
|
||||||
// Cleans up unused images which are instead inline into the css
|
path.join(buildFolder, "res", "ui", "**", "*.svg"),
|
||||||
gulp.task("imgres.cleanupUnusedCssInlineImages", () => {
|
path.join(buildFolder, "res", "ui", "**", "*.gif"),
|
||||||
return gulp
|
],
|
||||||
.src(
|
{ read: false }
|
||||||
[
|
)
|
||||||
path.join(buildFolder, "res", "ui", "**", "*.png"),
|
.pipe($.if(fname => fname.history[0].indexOf("noinline") < 0, $.clean({ force: true })));
|
||||||
path.join(buildFolder, "res", "ui", "**", "*.jpg"),
|
});
|
||||||
path.join(buildFolder, "res", "ui", "**", "*.svg"),
|
}
|
||||||
path.join(buildFolder, "res", "ui", "**", "*.gif"),
|
|
||||||
],
|
module.exports = {
|
||||||
{ read: false }
|
nonImageResourcesGlobs,
|
||||||
)
|
imageResourcesGlobs,
|
||||||
.pipe($.if(fname => fname.history[0].indexOf("noinline") < 0, $.clean({ force: true })));
|
gulptasksImageResources,
|
||||||
});
|
};
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
nonImageResourcesGlobs,
|
|
||||||
imageResourcesGlobs,
|
|
||||||
gulptasksImageResources,
|
|
||||||
};
|
|
||||||
|
|||||||
@ -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"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -16,6 +16,12 @@ function gulptasksSounds($, gulp, buildFolder) {
|
|||||||
cacheDirName: "shapezio-precompiled-sounds",
|
cacheDirName: "shapezio-precompiled-sounds",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function getFileCacheValue(file) {
|
||||||
|
const { _isVinyl, base, cwd, contents, history, stat, path } = file;
|
||||||
|
const encodedContents = Buffer.from(contents).toString("base64");
|
||||||
|
return { _isVinyl, base, cwd, contents: encodedContents, history, stat, path };
|
||||||
|
}
|
||||||
|
|
||||||
// Encodes the game music
|
// Encodes the game music
|
||||||
gulp.task("sounds.music", () => {
|
gulp.task("sounds.music", () => {
|
||||||
return gulp
|
return gulp
|
||||||
@ -34,6 +40,7 @@ function gulptasksSounds($, gulp, buildFolder) {
|
|||||||
{
|
{
|
||||||
name: "music",
|
name: "music",
|
||||||
fileCache,
|
fileCache,
|
||||||
|
value: getFileCacheValue,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -58,6 +65,7 @@ function gulptasksSounds($, gulp, buildFolder) {
|
|||||||
{
|
{
|
||||||
name: "music-high-quality",
|
name: "music-high-quality",
|
||||||
fileCache,
|
fileCache,
|
||||||
|
value: getFileCacheValue,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -110,7 +118,6 @@ function gulptasksSounds($, gulp, buildFolder) {
|
|||||||
return gulp
|
return gulp
|
||||||
.src(path.join(builtSoundsDir, "**", "*.mp3"))
|
.src(path.join(builtSoundsDir, "**", "*.mp3"))
|
||||||
.pipe($.plumber())
|
.pipe($.plumber())
|
||||||
.pipe($.cached("sounds.copy"))
|
|
||||||
.pipe(gulp.dest(path.join(buildFolder, "res", "sounds")));
|
.pipe(gulp.dest(path.join(buildFolder, "res", "sounds")));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
27116
gulp/yarn.lock
BIN
res/ui/building_icons/analyzer.png
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
BIN
res/ui/building_icons/balancer.png
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.5 KiB |
BIN
res/ui/building_icons/comparator.png
Normal file
|
After Width: | Height: | Size: 8.0 KiB |
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 6.8 KiB |
|
Before Width: | Height: | Size: 9.7 KiB After Width: | Height: | Size: 8.9 KiB |
|
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 7.2 KiB |
|
Before Width: | Height: | Size: 9.0 KiB After Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 6.4 KiB |
BIN
res/ui/building_icons/storage.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
res/ui/building_icons/transistor.png
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 3.8 KiB |
BIN
res/ui/building_tutorials/analyzer.png
Normal file
|
After Width: | Height: | Size: 233 KiB |
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 57 KiB |
BIN
res/ui/building_tutorials/balancer-splitter.png
Normal file
|
After Width: | Height: | Size: 79 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
BIN
res/ui/building_tutorials/constant_signal.png
Normal file
|
After Width: | Height: | Size: 157 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 36 KiB |
BIN
res/ui/building_tutorials/display.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
res/ui/building_tutorials/lever.png
Normal file
|
After Width: | Height: | Size: 68 KiB |
BIN
res/ui/building_tutorials/logic_gate-and.png
Normal file
|
After Width: | Height: | Size: 281 KiB |
BIN
res/ui/building_tutorials/logic_gate-not.png
Normal file
|
After Width: | Height: | Size: 287 KiB |
BIN
res/ui/building_tutorials/logic_gate-or.png
Normal file
|
After Width: | Height: | Size: 283 KiB |
BIN
res/ui/building_tutorials/logic_gate-xor.png
Normal file
|
After Width: | Height: | Size: 286 KiB |
BIN
res/ui/building_tutorials/painter-mirrored.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 165 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 45 KiB |
BIN
res/ui/building_tutorials/reader.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 34 KiB |
BIN
res/ui/building_tutorials/rotater-rotate180.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 106 KiB |
BIN
res/ui/building_tutorials/storage.png
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
res/ui/building_tutorials/transistor.png
Normal file
|
After Width: | Height: | Size: 260 KiB |
|
Before Width: | Height: | Size: 40 KiB |
BIN
res/ui/building_tutorials/virtual_processor-cutter.png
Normal file
|
After Width: | Height: | Size: 116 KiB |
BIN
res/ui/building_tutorials/virtual_processor-painter.png
Normal file
|
After Width: | Height: | Size: 116 KiB |
BIN
res/ui/building_tutorials/virtual_processor-rotater.png
Normal file
|
After Width: | Height: | Size: 106 KiB |
BIN
res/ui/building_tutorials/virtual_processor-stacker.png
Normal file
|
After Width: | Height: | Size: 121 KiB |
BIN
res/ui/building_tutorials/virtual_processor-unstacker.png
Normal file
|
After Width: | Height: | Size: 121 KiB |
BIN
res/ui/building_tutorials/wire-second.png
Normal file
|
After Width: | Height: | Size: 114 KiB |
BIN
res/ui/building_tutorials/wire.png
Normal file
|
After Width: | Height: | Size: 138 KiB |
BIN
res/ui/building_tutorials/wire_tunnel.png
Normal file
|
After Width: | Height: | Size: 91 KiB |
|
Before Width: | Height: | Size: 825 B After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 756 B After Width: | Height: | Size: 2.2 KiB |
BIN
res/ui/icons/enum_selector_white.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 731 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 728 B After Width: | Height: | Size: 385 B |
BIN
res/ui/icons/settings_menu_exit.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
res/ui/icons/settings_menu_play.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
res/ui/icons/settings_menu_settings.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
BIN
res/ui/icons/shop_active.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 927 B After Width: | Height: | Size: 546 B |
BIN
res/ui/icons/toggle_unit.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 280 KiB After Width: | Height: | Size: 279 KiB |
|
Before Width: | Height: | Size: 677 KiB After Width: | Height: | Size: 700 KiB |
@ -104,7 +104,7 @@
|
|||||||
</struct>
|
</struct>
|
||||||
</struct>
|
</struct>
|
||||||
<key>shapePadding</key>
|
<key>shapePadding</key>
|
||||||
<uint>0</uint>
|
<uint>2</uint>
|
||||||
<key>jpgQuality</key>
|
<key>jpgQuality</key>
|
||||||
<uint>80</uint>
|
<uint>80</uint>
|
||||||
<key>pngOptimizationLevel</key>
|
<key>pngOptimizationLevel</key>
|
||||||
@ -118,7 +118,7 @@
|
|||||||
<key>textureFormat</key>
|
<key>textureFormat</key>
|
||||||
<enum type="SettingsBase::TextureFormat">png</enum>
|
<enum type="SettingsBase::TextureFormat">png</enum>
|
||||||
<key>borderPadding</key>
|
<key>borderPadding</key>
|
||||||
<uint>1</uint>
|
<uint>3</uint>
|
||||||
<key>maxTextureSize</key>
|
<key>maxTextureSize</key>
|
||||||
<QSize>
|
<QSize>
|
||||||
<key>width</key>
|
<key>width</key>
|
||||||
@ -257,81 +257,84 @@
|
|||||||
<key type="filename">sprites/belt/built/right_7.png</key>
|
<key type="filename">sprites/belt/built/right_7.png</key>
|
||||||
<key type="filename">sprites/belt/built/right_8.png</key>
|
<key type="filename">sprites/belt/built/right_8.png</key>
|
||||||
<key type="filename">sprites/belt/built/right_9.png</key>
|
<key type="filename">sprites/belt/built/right_9.png</key>
|
||||||
|
<key type="filename">sprites/blueprints/analyzer.png</key>
|
||||||
|
<key type="filename">sprites/blueprints/balancer-merger-inverse.png</key>
|
||||||
|
<key type="filename">sprites/blueprints/balancer-merger.png</key>
|
||||||
|
<key type="filename">sprites/blueprints/balancer-splitter-inverse.png</key>
|
||||||
|
<key type="filename">sprites/blueprints/balancer-splitter.png</key>
|
||||||
|
<key type="filename">sprites/blueprints/belt_left.png</key>
|
||||||
|
<key type="filename">sprites/blueprints/belt_right.png</key>
|
||||||
|
<key type="filename">sprites/blueprints/belt_top.png</key>
|
||||||
|
<key type="filename">sprites/blueprints/comparator.png</key>
|
||||||
<key type="filename">sprites/blueprints/constant_signal.png</key>
|
<key type="filename">sprites/blueprints/constant_signal.png</key>
|
||||||
<key type="filename">sprites/blueprints/display.png</key>
|
<key type="filename">sprites/blueprints/display.png</key>
|
||||||
<key type="filename">sprites/blueprints/lever.png</key>
|
<key type="filename">sprites/blueprints/lever.png</key>
|
||||||
<key type="filename">sprites/blueprints/logic_gate-not.png</key>
|
<key type="filename">sprites/blueprints/logic_gate-not.png</key>
|
||||||
<key type="filename">sprites/blueprints/logic_gate-or.png</key>
|
<key type="filename">sprites/blueprints/logic_gate-or.png</key>
|
||||||
<key type="filename">sprites/blueprints/logic_gate-transistor.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/logic_gate-xor.png</key>
|
<key type="filename">sprites/blueprints/logic_gate-xor.png</key>
|
||||||
<key type="filename">sprites/blueprints/logic_gate.png</key>
|
<key type="filename">sprites/blueprints/logic_gate.png</key>
|
||||||
<key type="filename">sprites/blueprints/miner-chainable.png</key>
|
<key type="filename">sprites/blueprints/miner-chainable.png</key>
|
||||||
<key type="filename">sprites/blueprints/miner.png</key>
|
<key type="filename">sprites/blueprints/miner.png</key>
|
||||||
<key type="filename">sprites/blueprints/reader.png</key>
|
<key type="filename">sprites/blueprints/reader.png</key>
|
||||||
<key type="filename">sprites/blueprints/rotater-ccw.png</key>
|
<key type="filename">sprites/blueprints/rotater-ccw.png</key>
|
||||||
<key type="filename">sprites/blueprints/rotater-fl.png</key>
|
<key type="filename">sprites/blueprints/rotater-rotate180.png</key>
|
||||||
<key type="filename">sprites/blueprints/rotater.png</key>
|
<key type="filename">sprites/blueprints/rotater.png</key>
|
||||||
<key type="filename">sprites/blueprints/splitter-compact-inverse.png</key>
|
<key type="filename">sprites/blueprints/transistor-mirrored.png</key>
|
||||||
<key type="filename">sprites/blueprints/splitter-compact-merge-inverse.png</key>
|
<key type="filename">sprites/blueprints/transistor.png</key>
|
||||||
<key type="filename">sprites/blueprints/splitter-compact-merge.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/splitter-compact.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/trash.png</key>
|
<key type="filename">sprites/blueprints/trash.png</key>
|
||||||
<key type="filename">sprites/blueprints/underground_belt_entry-tier2.png</key>
|
<key type="filename">sprites/blueprints/underground_belt_entry-tier2.png</key>
|
||||||
<key type="filename">sprites/blueprints/underground_belt_entry.png</key>
|
<key type="filename">sprites/blueprints/underground_belt_entry.png</key>
|
||||||
<key type="filename">sprites/blueprints/underground_belt_exit-tier2.png</key>
|
<key type="filename">sprites/blueprints/underground_belt_exit-tier2.png</key>
|
||||||
<key type="filename">sprites/blueprints/underground_belt_exit.png</key>
|
<key type="filename">sprites/blueprints/underground_belt_exit.png</key>
|
||||||
<key type="filename">sprites/blueprints/virtual_processor-analyzer.png</key>
|
<key type="filename">sprites/blueprints/virtual_processor-painter.png</key>
|
||||||
<key type="filename">sprites/blueprints/virtual_processor-rotater.png</key>
|
<key type="filename">sprites/blueprints/virtual_processor-rotater.png</key>
|
||||||
<key type="filename">sprites/blueprints/virtual_processor-shapecompare.png</key>
|
<key type="filename">sprites/blueprints/virtual_processor-stacker.png</key>
|
||||||
<key type="filename">sprites/blueprints/virtual_processor-unstacker.png</key>
|
<key type="filename">sprites/blueprints/virtual_processor-unstacker.png</key>
|
||||||
<key type="filename">sprites/blueprints/virtual_processor.png</key>
|
<key type="filename">sprites/blueprints/virtual_processor.png</key>
|
||||||
<key type="filename">sprites/blueprints/wire_tunnel-coating.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/wire_tunnel.png</key>
|
<key type="filename">sprites/blueprints/wire_tunnel.png</key>
|
||||||
|
<key type="filename">sprites/buildings/analyzer.png</key>
|
||||||
|
<key type="filename">sprites/buildings/balancer-merger-inverse.png</key>
|
||||||
|
<key type="filename">sprites/buildings/balancer-merger.png</key>
|
||||||
|
<key type="filename">sprites/buildings/balancer-splitter-inverse.png</key>
|
||||||
|
<key type="filename">sprites/buildings/balancer-splitter.png</key>
|
||||||
|
<key type="filename">sprites/buildings/comparator.png</key>
|
||||||
<key type="filename">sprites/buildings/constant_signal.png</key>
|
<key type="filename">sprites/buildings/constant_signal.png</key>
|
||||||
<key type="filename">sprites/buildings/display.png</key>
|
<key type="filename">sprites/buildings/display.png</key>
|
||||||
<key type="filename">sprites/buildings/lever.png</key>
|
<key type="filename">sprites/buildings/lever.png</key>
|
||||||
<key type="filename">sprites/buildings/logic_gate-not.png</key>
|
<key type="filename">sprites/buildings/logic_gate-not.png</key>
|
||||||
<key type="filename">sprites/buildings/logic_gate-or.png</key>
|
<key type="filename">sprites/buildings/logic_gate-or.png</key>
|
||||||
<key type="filename">sprites/buildings/logic_gate-transistor.png</key>
|
|
||||||
<key type="filename">sprites/buildings/logic_gate-xor.png</key>
|
<key type="filename">sprites/buildings/logic_gate-xor.png</key>
|
||||||
<key type="filename">sprites/buildings/logic_gate.png</key>
|
<key type="filename">sprites/buildings/logic_gate.png</key>
|
||||||
<key type="filename">sprites/buildings/miner-chainable.png</key>
|
<key type="filename">sprites/buildings/miner-chainable.png</key>
|
||||||
<key type="filename">sprites/buildings/reader.png</key>
|
<key type="filename">sprites/buildings/reader.png</key>
|
||||||
<key type="filename">sprites/buildings/rotater-ccw.png</key>
|
<key type="filename">sprites/buildings/rotater-ccw.png</key>
|
||||||
<key type="filename">sprites/buildings/rotater-fl.png</key>
|
<key type="filename">sprites/buildings/rotater-rotate180.png</key>
|
||||||
<key type="filename">sprites/buildings/splitter-compact-inverse.png</key>
|
<key type="filename">sprites/buildings/transistor-mirrored.png</key>
|
||||||
<key type="filename">sprites/buildings/splitter-compact-merge-inverse.png</key>
|
<key type="filename">sprites/buildings/transistor.png</key>
|
||||||
<key type="filename">sprites/buildings/splitter-compact-merge.png</key>
|
|
||||||
<key type="filename">sprites/buildings/splitter-compact.png</key>
|
|
||||||
<key type="filename">sprites/buildings/underground_belt_entry-tier2.png</key>
|
<key type="filename">sprites/buildings/underground_belt_entry-tier2.png</key>
|
||||||
<key type="filename">sprites/buildings/underground_belt_entry.png</key>
|
<key type="filename">sprites/buildings/underground_belt_entry.png</key>
|
||||||
<key type="filename">sprites/buildings/underground_belt_exit-tier2.png</key>
|
<key type="filename">sprites/buildings/underground_belt_exit-tier2.png</key>
|
||||||
<key type="filename">sprites/buildings/underground_belt_exit.png</key>
|
<key type="filename">sprites/buildings/underground_belt_exit.png</key>
|
||||||
<key type="filename">sprites/buildings/virtual_processor-analyzer.png</key>
|
<key type="filename">sprites/buildings/virtual_processor-painter.png</key>
|
||||||
<key type="filename">sprites/buildings/virtual_processor-rotater.png</key>
|
<key type="filename">sprites/buildings/virtual_processor-rotater.png</key>
|
||||||
<key type="filename">sprites/buildings/virtual_processor-shapecompare.png</key>
|
<key type="filename">sprites/buildings/virtual_processor-stacker.png</key>
|
||||||
<key type="filename">sprites/buildings/virtual_processor-unstacker.png</key>
|
<key type="filename">sprites/buildings/virtual_processor-unstacker.png</key>
|
||||||
<key type="filename">sprites/buildings/virtual_processor.png</key>
|
<key type="filename">sprites/buildings/virtual_processor.png</key>
|
||||||
<key type="filename">sprites/buildings/wire_tunnel-coating.png</key>
|
|
||||||
<key type="filename">sprites/buildings/wire_tunnel.png</key>
|
<key type="filename">sprites/buildings/wire_tunnel.png</key>
|
||||||
<key type="filename">sprites/misc/reader_overlay.png</key>
|
<key type="filename">sprites/misc/reader_overlay.png</key>
|
||||||
<key type="filename">sprites/wires/lever_on.png</key>
|
<key type="filename">sprites/wires/lever_on.png</key>
|
||||||
<key type="filename">sprites/wires/sets/color_cross.png</key>
|
|
||||||
<key type="filename">sprites/wires/sets/color_forward.png</key>
|
|
||||||
<key type="filename">sprites/wires/sets/color_split.png</key>
|
|
||||||
<key type="filename">sprites/wires/sets/color_turn.png</key>
|
|
||||||
<key type="filename">sprites/wires/sets/conflict_cross.png</key>
|
<key type="filename">sprites/wires/sets/conflict_cross.png</key>
|
||||||
<key type="filename">sprites/wires/sets/conflict_forward.png</key>
|
<key type="filename">sprites/wires/sets/conflict_forward.png</key>
|
||||||
<key type="filename">sprites/wires/sets/conflict_split.png</key>
|
<key type="filename">sprites/wires/sets/conflict_split.png</key>
|
||||||
<key type="filename">sprites/wires/sets/conflict_turn.png</key>
|
<key type="filename">sprites/wires/sets/conflict_turn.png</key>
|
||||||
<key type="filename">sprites/wires/sets/regular_cross.png</key>
|
<key type="filename">sprites/wires/sets/first_cross.png</key>
|
||||||
<key type="filename">sprites/wires/sets/regular_forward.png</key>
|
<key type="filename">sprites/wires/sets/first_forward.png</key>
|
||||||
<key type="filename">sprites/wires/sets/regular_split.png</key>
|
<key type="filename">sprites/wires/sets/first_split.png</key>
|
||||||
<key type="filename">sprites/wires/sets/regular_turn.png</key>
|
<key type="filename">sprites/wires/sets/first_turn.png</key>
|
||||||
<key type="filename">sprites/wires/sets/shape_cross.png</key>
|
<key type="filename">sprites/wires/sets/second_cross.png</key>
|
||||||
<key type="filename">sprites/wires/sets/shape_forward.png</key>
|
<key type="filename">sprites/wires/sets/second_forward.png</key>
|
||||||
<key type="filename">sprites/wires/sets/shape_split.png</key>
|
<key type="filename">sprites/wires/sets/second_split.png</key>
|
||||||
<key type="filename">sprites/wires/sets/shape_turn.png</key>
|
<key type="filename">sprites/wires/sets/second_turn.png</key>
|
||||||
<struct type="IndividualSpriteSettings">
|
<struct type="IndividualSpriteSettings">
|
||||||
<key>pivotPoint</key>
|
<key>pivotPoint</key>
|
||||||
<point_f>0.5,0.5</point_f>
|
<point_f>0.5,0.5</point_f>
|
||||||
@ -346,20 +349,16 @@
|
|||||||
<key>scale9FromFile</key>
|
<key>scale9FromFile</key>
|
||||||
<false/>
|
<false/>
|
||||||
</struct>
|
</struct>
|
||||||
<key type="filename">sprites/blueprints/belt_left.png</key>
|
<key type="filename">sprites/blueprints/balancer.png</key>
|
||||||
<key type="filename">sprites/blueprints/belt_right.png</key>
|
<key type="filename">sprites/blueprints/cutter.png</key>
|
||||||
<key type="filename">sprites/blueprints/belt_top.png</key>
|
<key type="filename">sprites/blueprints/filter.png</key>
|
||||||
<key type="filename">sprites/blueprints/wire-cross.png</key>
|
<key type="filename">sprites/blueprints/mixer.png</key>
|
||||||
<key type="filename">sprites/blueprints/wire-split.png</key>
|
<key type="filename">sprites/blueprints/painter-mirrored.png</key>
|
||||||
<key type="filename">sprites/blueprints/wire-turn.png</key>
|
<key type="filename">sprites/blueprints/painter.png</key>
|
||||||
<key type="filename">sprites/blueprints/wire.png</key>
|
<key type="filename">sprites/blueprints/stacker.png</key>
|
||||||
<key type="filename">sprites/buildings/belt_left.png</key>
|
<key type="filename">sprites/buildings/balancer.png</key>
|
||||||
<key type="filename">sprites/buildings/belt_right.png</key>
|
<key type="filename">sprites/buildings/filter.png</key>
|
||||||
<key type="filename">sprites/buildings/belt_top.png</key>
|
<key type="filename">sprites/buildings/painter-mirrored.png</key>
|
||||||
<key type="filename">sprites/buildings/wire-cross.png</key>
|
|
||||||
<key type="filename">sprites/buildings/wire-split.png</key>
|
|
||||||
<key type="filename">sprites/buildings/wire-turn.png</key>
|
|
||||||
<key type="filename">sprites/buildings/wire.png</key>
|
|
||||||
<struct type="IndividualSpriteSettings">
|
<struct type="IndividualSpriteSettings">
|
||||||
<key>pivotPoint</key>
|
<key>pivotPoint</key>
|
||||||
<point_f>0.5,0.5</point_f>
|
<point_f>0.5,0.5</point_f>
|
||||||
@ -368,9 +367,9 @@
|
|||||||
<key>scale9Enabled</key>
|
<key>scale9Enabled</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>scale9Borders</key>
|
<key>scale9Borders</key>
|
||||||
<rect>32,32,63,63</rect>
|
<rect>96,48,192,96</rect>
|
||||||
<key>scale9Paddings</key>
|
<key>scale9Paddings</key>
|
||||||
<rect>32,32,63,63</rect>
|
<rect>96,48,192,96</rect>
|
||||||
<key>scale9FromFile</key>
|
<key>scale9FromFile</key>
|
||||||
<false/>
|
<false/>
|
||||||
</struct>
|
</struct>
|
||||||
@ -392,15 +391,10 @@
|
|||||||
<key>scale9FromFile</key>
|
<key>scale9FromFile</key>
|
||||||
<false/>
|
<false/>
|
||||||
</struct>
|
</struct>
|
||||||
<key type="filename">sprites/blueprints/cutter.png</key>
|
<key type="filename">sprites/blueprints/painter-double.png</key>
|
||||||
<key type="filename">sprites/blueprints/filter.png</key>
|
<key type="filename">sprites/blueprints/storage.png</key>
|
||||||
<key type="filename">sprites/blueprints/mixer.png</key>
|
<key type="filename">sprites/buildings/painter-double.png</key>
|
||||||
<key type="filename">sprites/blueprints/painter-mirrored.png</key>
|
<key type="filename">sprites/buildings/storage.png</key>
|
||||||
<key type="filename">sprites/blueprints/painter.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/splitter.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/stacker.png</key>
|
|
||||||
<key type="filename">sprites/buildings/filter.png</key>
|
|
||||||
<key type="filename">sprites/buildings/painter-mirrored.png</key>
|
|
||||||
<struct type="IndividualSpriteSettings">
|
<struct type="IndividualSpriteSettings">
|
||||||
<key>pivotPoint</key>
|
<key>pivotPoint</key>
|
||||||
<point_f>0.5,0.5</point_f>
|
<point_f>0.5,0.5</point_f>
|
||||||
@ -409,15 +403,15 @@
|
|||||||
<key>scale9Enabled</key>
|
<key>scale9Enabled</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>scale9Borders</key>
|
<key>scale9Borders</key>
|
||||||
<rect>96,48,192,96</rect>
|
<rect>96,96,192,192</rect>
|
||||||
<key>scale9Paddings</key>
|
<key>scale9Paddings</key>
|
||||||
<rect>96,48,192,96</rect>
|
<rect>96,96,192,192</rect>
|
||||||
<key>scale9FromFile</key>
|
<key>scale9FromFile</key>
|
||||||
<false/>
|
<false/>
|
||||||
</struct>
|
</struct>
|
||||||
<key type="filename">sprites/blueprints/painter-double.png</key>
|
<key type="filename">sprites/buildings/belt_left.png</key>
|
||||||
<key type="filename">sprites/blueprints/trash-storage.png</key>
|
<key type="filename">sprites/buildings/belt_right.png</key>
|
||||||
<key type="filename">sprites/buildings/painter-double.png</key>
|
<key type="filename">sprites/buildings/belt_top.png</key>
|
||||||
<struct type="IndividualSpriteSettings">
|
<struct type="IndividualSpriteSettings">
|
||||||
<key>pivotPoint</key>
|
<key>pivotPoint</key>
|
||||||
<point_f>0.5,0.5</point_f>
|
<point_f>0.5,0.5</point_f>
|
||||||
@ -426,16 +420,15 @@
|
|||||||
<key>scale9Enabled</key>
|
<key>scale9Enabled</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>scale9Borders</key>
|
<key>scale9Borders</key>
|
||||||
<rect>96,96,192,192</rect>
|
<rect>32,32,63,63</rect>
|
||||||
<key>scale9Paddings</key>
|
<key>scale9Paddings</key>
|
||||||
<rect>96,96,192,192</rect>
|
<rect>32,32,63,63</rect>
|
||||||
<key>scale9FromFile</key>
|
<key>scale9FromFile</key>
|
||||||
<false/>
|
<false/>
|
||||||
</struct>
|
</struct>
|
||||||
<key type="filename">sprites/buildings/cutter.png</key>
|
<key type="filename">sprites/buildings/cutter.png</key>
|
||||||
<key type="filename">sprites/buildings/mixer.png</key>
|
<key type="filename">sprites/buildings/mixer.png</key>
|
||||||
<key type="filename">sprites/buildings/painter.png</key>
|
<key type="filename">sprites/buildings/painter.png</key>
|
||||||
<key type="filename">sprites/buildings/splitter.png</key>
|
|
||||||
<key type="filename">sprites/buildings/stacker.png</key>
|
<key type="filename">sprites/buildings/stacker.png</key>
|
||||||
<struct type="IndividualSpriteSettings">
|
<struct type="IndividualSpriteSettings">
|
||||||
<key>pivotPoint</key>
|
<key>pivotPoint</key>
|
||||||
@ -488,7 +481,14 @@
|
|||||||
<key>scale9FromFile</key>
|
<key>scale9FromFile</key>
|
||||||
<false/>
|
<false/>
|
||||||
</struct>
|
</struct>
|
||||||
<key type="filename">sprites/buildings/trash-storage.png</key>
|
<key type="filename">sprites/colors/blue.png</key>
|
||||||
|
<key type="filename">sprites/colors/cyan.png</key>
|
||||||
|
<key type="filename">sprites/colors/green.png</key>
|
||||||
|
<key type="filename">sprites/colors/purple.png</key>
|
||||||
|
<key type="filename">sprites/colors/red.png</key>
|
||||||
|
<key type="filename">sprites/colors/uncolored.png</key>
|
||||||
|
<key type="filename">sprites/colors/white.png</key>
|
||||||
|
<key type="filename">sprites/colors/yellow.png</key>
|
||||||
<struct type="IndividualSpriteSettings">
|
<struct type="IndividualSpriteSettings">
|
||||||
<key>pivotPoint</key>
|
<key>pivotPoint</key>
|
||||||
<point_f>0.5,0.5</point_f>
|
<point_f>0.5,0.5</point_f>
|
||||||
@ -497,9 +497,9 @@
|
|||||||
<key>scale9Enabled</key>
|
<key>scale9Enabled</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>scale9Borders</key>
|
<key>scale9Borders</key>
|
||||||
<rect>144,144,288,288</rect>
|
<rect>18,18,36,36</rect>
|
||||||
<key>scale9Paddings</key>
|
<key>scale9Paddings</key>
|
||||||
<rect>144,144,288,288</rect>
|
<rect>18,18,36,36</rect>
|
||||||
<key>scale9FromFile</key>
|
<key>scale9FromFile</key>
|
||||||
<false/>
|
<false/>
|
||||||
</struct>
|
</struct>
|
||||||
|
|||||||
@ -1,226 +1,212 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Run `yarn global add canvas` first
|
* Run `yarn global add canvas` first
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { createCanvas } = require("canvas");
|
const { createCanvas } = require("canvas");
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
|
|
||||||
const outputFolder = path.join(__dirname, "..", "wires", "sets");
|
const outputFolder = path.join(__dirname, "..", "wires", "sets");
|
||||||
|
|
||||||
const dimensions = 192;
|
const dimensions = 192;
|
||||||
const lineSize = 12;
|
const lineSize = 14;
|
||||||
const lowerLineSize = 20;
|
const lowerLineSize = 32;
|
||||||
|
|
||||||
function hexToRGB(h) {
|
const variants = {
|
||||||
let r = 0,
|
first: "#61ef6f",
|
||||||
g = 0,
|
second: "#5fb2f1",
|
||||||
b = 0;
|
conflict: "#f74c4c",
|
||||||
|
};
|
||||||
// 3 digits
|
|
||||||
if (h.length == 4) {
|
function hexToRGB(h) {
|
||||||
r = "0x" + h[1] + h[1];
|
let r = 0,
|
||||||
g = "0x" + h[2] + h[2];
|
g = 0,
|
||||||
b = "0x" + h[3] + h[3];
|
b = 0;
|
||||||
|
|
||||||
// 6 digits
|
// 3 digits
|
||||||
} else if (h.length == 7) {
|
if (h.length == 4) {
|
||||||
r = "0x" + h[1] + h[2];
|
r = "0x" + h[1] + h[1];
|
||||||
g = "0x" + h[3] + h[4];
|
g = "0x" + h[2] + h[2];
|
||||||
b = "0x" + h[5] + h[6];
|
b = "0x" + h[3] + h[3];
|
||||||
}
|
|
||||||
|
// 6 digits
|
||||||
return [+r, +g, +b];
|
} else if (h.length == 7) {
|
||||||
}
|
r = "0x" + h[1] + h[2];
|
||||||
|
g = "0x" + h[3] + h[4];
|
||||||
function RGBToHSL(r, g, b) {
|
b = "0x" + h[5] + h[6];
|
||||||
// Make r, g, and b fractions of 1
|
}
|
||||||
r /= 255;
|
|
||||||
g /= 255;
|
return [+r, +g, +b];
|
||||||
b /= 255;
|
}
|
||||||
|
|
||||||
// Find greatest and smallest channel values
|
function RGBToHSL(r, g, b) {
|
||||||
let cmin = Math.min(r, g, b),
|
// Make r, g, and b fractions of 1
|
||||||
cmax = Math.max(r, g, b),
|
r /= 255;
|
||||||
delta = cmax - cmin,
|
g /= 255;
|
||||||
h = 0,
|
b /= 255;
|
||||||
s = 0,
|
|
||||||
l = 0;
|
// Find greatest and smallest channel values
|
||||||
// Calculate hue
|
let cmin = Math.min(r, g, b),
|
||||||
// No difference
|
cmax = Math.max(r, g, b),
|
||||||
if (delta == 0) h = 0;
|
delta = cmax - cmin,
|
||||||
// Red is max
|
h = 0,
|
||||||
else if (cmax == r) h = ((g - b) / delta) % 6;
|
s = 0,
|
||||||
// Green is max
|
l = 0;
|
||||||
else if (cmax == g) h = (b - r) / delta + 2;
|
// Calculate hue
|
||||||
// Blue is max
|
// No difference
|
||||||
else h = (r - g) / delta + 4;
|
if (delta == 0) h = 0;
|
||||||
|
// Red is max
|
||||||
h = Math.round(h * 60);
|
else if (cmax == r) h = ((g - b) / delta) % 6;
|
||||||
|
// Green is max
|
||||||
// Make negative hues positive behind 360°
|
else if (cmax == g) h = (b - r) / delta + 2;
|
||||||
if (h < 0) h += 360;
|
// Blue is max
|
||||||
|
else h = (r - g) / delta + 4;
|
||||||
// Calculate lightness
|
|
||||||
l = (cmax + cmin) / 2;
|
h = Math.round(h * 60);
|
||||||
|
|
||||||
// Calculate saturation
|
// Make negative hues positive behind 360°
|
||||||
s = delta == 0 ? 0 : delta / (1 - Math.abs(2 * l - 1));
|
if (h < 0) h += 360;
|
||||||
|
|
||||||
// Multiply l and s by 100
|
// Calculate lightness
|
||||||
s = +(s * 100).toFixed(1);
|
l = (cmax + cmin) / 2;
|
||||||
l = +(l * 100).toFixed(1);
|
|
||||||
|
// Calculate saturation
|
||||||
return [h, s, l];
|
s = delta == 0 ? 0 : delta / (1 - Math.abs(2 * l - 1));
|
||||||
}
|
|
||||||
|
// Multiply l and s by 100
|
||||||
function HSLToRGB(h, s, l) {
|
s = +(s * 100).toFixed(1);
|
||||||
// Must be fractions of 1
|
l = +(l * 100).toFixed(1);
|
||||||
s /= 100;
|
|
||||||
l /= 100;
|
return [h, s, l];
|
||||||
|
}
|
||||||
let c = (1 - Math.abs(2 * l - 1)) * s,
|
|
||||||
x = c * (1 - Math.abs(((h / 60) % 2) - 1)),
|
function HSLToRGB(h, s, l) {
|
||||||
m = l - c / 2,
|
// Must be fractions of 1
|
||||||
r = 0,
|
s /= 100;
|
||||||
g = 0,
|
l /= 100;
|
||||||
b = 0;
|
|
||||||
|
let c = (1 - Math.abs(2 * l - 1)) * s,
|
||||||
if (0 <= h && h < 60) {
|
x = c * (1 - Math.abs(((h / 60) % 2) - 1)),
|
||||||
r = c;
|
m = l - c / 2,
|
||||||
g = x;
|
r = 0,
|
||||||
b = 0;
|
g = 0,
|
||||||
} else if (60 <= h && h < 120) {
|
b = 0;
|
||||||
r = x;
|
|
||||||
g = c;
|
if (0 <= h && h < 60) {
|
||||||
b = 0;
|
r = c;
|
||||||
} else if (120 <= h && h < 180) {
|
g = x;
|
||||||
r = 0;
|
b = 0;
|
||||||
g = c;
|
} else if (60 <= h && h < 120) {
|
||||||
b = x;
|
r = x;
|
||||||
} else if (180 <= h && h < 240) {
|
g = c;
|
||||||
r = 0;
|
b = 0;
|
||||||
g = x;
|
} else if (120 <= h && h < 180) {
|
||||||
b = c;
|
r = 0;
|
||||||
} else if (240 <= h && h < 300) {
|
g = c;
|
||||||
r = x;
|
b = x;
|
||||||
g = 0;
|
} else if (180 <= h && h < 240) {
|
||||||
b = c;
|
r = 0;
|
||||||
} else if (300 <= h && h < 360) {
|
g = x;
|
||||||
r = c;
|
b = c;
|
||||||
g = 0;
|
} else if (240 <= h && h < 300) {
|
||||||
b = x;
|
r = x;
|
||||||
}
|
g = 0;
|
||||||
r = Math.round((r + m) * 255);
|
b = c;
|
||||||
g = Math.round((g + m) * 255);
|
} else if (300 <= h && h < 360) {
|
||||||
b = Math.round((b + m) * 255);
|
r = c;
|
||||||
|
g = 0;
|
||||||
return [r, g, b];
|
b = x;
|
||||||
}
|
}
|
||||||
|
r = Math.round((r + m) * 255);
|
||||||
async function run() {
|
g = Math.round((g + m) * 255);
|
||||||
console.log("Running");
|
b = Math.round((b + m) * 255);
|
||||||
|
|
||||||
const variants = {
|
return [r, g, b];
|
||||||
regular: "#25fff2",
|
}
|
||||||
color: "#eba458",
|
|
||||||
shape: "#8858eb",
|
async function run() {
|
||||||
conflict: "#ff3e3e",
|
console.log("Running");
|
||||||
};
|
|
||||||
|
const promises = [];
|
||||||
const promises = [];
|
|
||||||
|
for (const variantId in variants) {
|
||||||
for (const variantId in variants) {
|
const variantColor = variants[variantId];
|
||||||
const variantColor = variants[variantId];
|
const variantHSL = RGBToHSL(...hexToRGB(variantColor));
|
||||||
const variantHSL = RGBToHSL(...hexToRGB(variantColor));
|
const darkenedColor = HSLToRGB(variantHSL[0], variantHSL[1] - 15, variantHSL[2] - 20);
|
||||||
const darkenedColor = HSLToRGB(variantHSL[0], variantHSL[1] - 15, variantHSL[2] - 20);
|
const hexDarkenedColor = "rgb(" + darkenedColor.join(",") + ")";
|
||||||
const hexDarkenedColor = "rgb(" + darkenedColor.join(",") + ")";
|
|
||||||
|
console.log(variantColor, "->", hexToRGB(variantColor), variantHSL, "->", darkenedColor);
|
||||||
console.log(variantColor, "->", hexToRGB(variantColor), variantHSL, "->", darkenedColor);
|
|
||||||
|
const parts = {
|
||||||
const parts = {
|
forward: [[0.5, 0, 0.5, 1]],
|
||||||
forward: [[0.5, 0, 0.5, 1]],
|
turn: [
|
||||||
turn: [
|
[0.5, 0.5, 0.5, 1],
|
||||||
[0.5, 0.5, 0.5, 1],
|
[0.5, 0.5, 1, 0.5],
|
||||||
[0.5, 0.5, 1, 0.5],
|
],
|
||||||
],
|
split: [
|
||||||
split: [
|
[0.5, 0.5, 0.5, 1],
|
||||||
[0.5, 0.5, 0.5, 1],
|
[0, 0.5, 1, 0.5],
|
||||||
[0, 0.5, 1, 0.5],
|
],
|
||||||
],
|
cross: [
|
||||||
cross: [
|
[0, 0.5, 1, 0.5],
|
||||||
[0, 0.5, 1, 0.5],
|
[0.5, 0, 0.5, 1],
|
||||||
[0.5, 0, 0.5, 1],
|
],
|
||||||
],
|
};
|
||||||
};
|
|
||||||
|
for (const partId in parts) {
|
||||||
for (const partId in parts) {
|
const partLines = parts[partId];
|
||||||
const partLines = parts[partId];
|
|
||||||
|
const canvas = createCanvas(dimensions, dimensions);
|
||||||
const canvas = createCanvas(dimensions, dimensions);
|
const context = canvas.getContext("2d");
|
||||||
const context = canvas.getContext("2d");
|
context.quality = "best";
|
||||||
context.quality = "best";
|
context.clearRect(0, 0, dimensions, dimensions);
|
||||||
context.clearRect(0, 0, dimensions, dimensions);
|
|
||||||
|
const lineCanvas = createCanvas(dimensions, dimensions);
|
||||||
context.strokeStyle = hexDarkenedColor;
|
const lineContext = lineCanvas.getContext("2d");
|
||||||
context.lineWidth = lowerLineSize;
|
lineContext.quality = "best";
|
||||||
context.lineCap = "square";
|
lineContext.clearRect(0, 0, dimensions, dimensions);
|
||||||
context.imageSmoothingEnabled = false;
|
lineContext.strokeStyle = hexDarkenedColor;
|
||||||
|
lineContext.lineWidth = lowerLineSize;
|
||||||
// Draw lower lines
|
lineContext.lineCap = "square";
|
||||||
partLines.forEach(([x1, y1, x2, y2]) => {
|
lineContext.imageSmoothingEnabled = false;
|
||||||
context.beginPath();
|
|
||||||
context.moveTo(x1 * dimensions, y1 * dimensions);
|
// Draw lower lines
|
||||||
context.lineTo(x2 * dimensions, y2 * dimensions);
|
partLines.forEach(([x1, y1, x2, y2]) => {
|
||||||
context.stroke();
|
lineContext.beginPath();
|
||||||
});
|
lineContext.moveTo(x1 * dimensions, y1 * dimensions);
|
||||||
|
lineContext.lineTo(x2 * dimensions, y2 * dimensions);
|
||||||
context.strokeStyle = variantColor;
|
lineContext.stroke();
|
||||||
context.lineWidth = lineSize;
|
});
|
||||||
|
|
||||||
// Draw upper lines
|
context.globalAlpha = 0.4;
|
||||||
partLines.forEach(([x1, y1, x2, y2]) => {
|
context.drawImage(lineCanvas, 0, 0, dimensions, dimensions);
|
||||||
context.beginPath();
|
|
||||||
context.moveTo(x1 * dimensions, y1 * dimensions);
|
context.globalAlpha = 1;
|
||||||
context.lineTo(x2 * dimensions, y2 * dimensions);
|
context.imageSmoothingEnabled = false;
|
||||||
context.stroke();
|
context.lineCap = "square";
|
||||||
});
|
context.strokeStyle = variantColor;
|
||||||
|
context.lineWidth = lineSize;
|
||||||
const out = fs.createWriteStream(path.join(outputFolder, variantId + "_" + partId + ".png"));
|
|
||||||
const stream = canvas.createPNGStream();
|
// Draw upper lines
|
||||||
stream.pipe(out);
|
partLines.forEach(([x1, y1, x2, y2]) => {
|
||||||
promises.push(new Promise(resolve => stream.on("end", resolve)));
|
context.beginPath();
|
||||||
}
|
context.moveTo(x1 * dimensions, y1 * dimensions);
|
||||||
}
|
context.lineTo(x2 * dimensions, y2 * dimensions);
|
||||||
|
context.stroke();
|
||||||
console.log("Waiting for completion");
|
});
|
||||||
await Promise.all(promises);
|
|
||||||
|
const out = fs.createWriteStream(path.join(outputFolder, variantId + "_" + partId + ".png"));
|
||||||
// Also wait a bit more
|
const stream = canvas.createPNGStream();
|
||||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
stream.pipe(out);
|
||||||
|
promises.push(new Promise(resolve => stream.on("end", resolve)));
|
||||||
console.log("Copying files to all locations");
|
}
|
||||||
|
}
|
||||||
// // Copy other files
|
|
||||||
fs.copyFileSync(
|
console.log("Waiting for completion");
|
||||||
path.join(outputFolder, "regular_forward.png"),
|
await Promise.all(promises);
|
||||||
path.join(__dirname, "..", "buildings", "wire.png")
|
|
||||||
);
|
console.log("Done!");
|
||||||
fs.copyFileSync(
|
}
|
||||||
path.join(outputFolder, "regular_turn.png"),
|
|
||||||
path.join(__dirname, "..", "buildings", "wire-turn.png")
|
run();
|
||||||
);
|
|
||||||
fs.copyFileSync(
|
|
||||||
path.join(outputFolder, "regular_split.png"),
|
|
||||||
path.join(__dirname, "..", "buildings", "wire-split.png")
|
|
||||||
);
|
|
||||||
fs.copyFileSync(
|
|
||||||
path.join(outputFolder, "regular_cross.png"),
|
|
||||||
path.join(__dirname, "..", "buildings", "wire-cross.png")
|
|
||||||
);
|
|
||||||
|
|
||||||
console.log("Done!");
|
|
||||||
}
|
|
||||||
|
|
||||||
run();
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
BIN
res_raw/sprites/blueprints/balancer.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.3 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 7.8 KiB |
|
Before Width: | Height: | Size: 18 KiB |
BIN
res_raw/sprites/blueprints/rotater-rotate180.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 23 KiB |