Initial commit
1
.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
||||
*.wav filter=lfs diff=lfs merge=lfs -text
|
111
.gitignore
vendored
Normal file
@ -0,0 +1,111 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# TypeScript v1 declaration files
|
||||
typings/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Microbundle cache
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
.env.test
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
|
||||
# Next.js build output
|
||||
.next
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
.cache/
|
||||
# Comment in the public line in if your project uses Gatsby and *not* Next.js
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
.tern-port
|
||||
|
||||
|
||||
# Buildfiles
|
||||
build
|
||||
|
||||
|
||||
res_built
|
11
.prettierrc.yaml
Normal file
@ -0,0 +1,11 @@
|
||||
# .prettierrc or .prettierrc.yaml
|
||||
trailingComma: "es5"
|
||||
tabWidth: 4
|
||||
semi: true
|
||||
singleQuote: false
|
||||
printWidth: 110
|
||||
useTabs: false
|
||||
quoteProps: "consistent"
|
||||
bracketSpacing: true
|
||||
arrowParens: avoid
|
||||
endOfLine: "lf"
|
3
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
}
|
44
buildutils.js
Normal file
@ -0,0 +1,44 @@
|
||||
const glob = require("glob");
|
||||
const execSync = require("child_process").execSync;
|
||||
const trim = require("trim");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
module.exports = {
|
||||
getRevision: function (useLast = false) {
|
||||
const commitHash = execSync("git rev-parse --short " + (useLast ? "HEAD^1" : "HEAD")).toString("ascii");
|
||||
return commitHash.replace(/^\s+|\s+$/g, "");
|
||||
},
|
||||
getAllResourceImages() {
|
||||
return glob
|
||||
.sync("res/**/*.@(png|svg|jpg)", { cwd: ".." })
|
||||
.map((f) => f.replace(/^res\//gi, ""))
|
||||
.filter((f) => {
|
||||
if (f.indexOf("ui") >= 0) {
|
||||
// We drop all ui images except for the noinline ones
|
||||
return f.indexOf("noinline") >= 0;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},
|
||||
|
||||
getAllAtlasImages() {
|
||||
return glob.sync("res_built/atlas/*.png", { cwd: ".." }).map((s) => s.replace("res_built/atlas/", "res/"));
|
||||
},
|
||||
|
||||
getAllSounds() {
|
||||
return glob.sync("res_built/sounds/**/*.mp3", { cwd: ".." }).map((s) => s.replace("res_built/sounds/", "res/sounds/"));
|
||||
},
|
||||
|
||||
getVersion() {
|
||||
return trim(fs.readFileSync(path.join(__dirname, "version")).toString());
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {string} url
|
||||
* @param {string} commitHash
|
||||
*/
|
||||
cachebust(url, commitHash) {
|
||||
return "/v/" + commitHash + "/" + url;
|
||||
},
|
||||
};
|
1
gulp/.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
||||
*.wav filter=lfs diff=lfs merge=lfs -text
|
1
gulp/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
additional_build_files
|
48
gulp/babel-es6.config.js
Normal file
@ -0,0 +1,48 @@
|
||||
module.exports = function (api) {
|
||||
api.cache(true);
|
||||
const presets = [
|
||||
[
|
||||
"@babel/preset-env",
|
||||
{
|
||||
targets: "> 5%",
|
||||
useBuiltIns: "usage",
|
||||
corejs: 3,
|
||||
loose: true,
|
||||
spec: false,
|
||||
modules: "auto",
|
||||
// debug: true
|
||||
},
|
||||
],
|
||||
];
|
||||
const plugins = [
|
||||
"closure-elimination",
|
||||
// var is faster than let and const!
|
||||
[
|
||||
"@babel/plugin-transform-block-scoping",
|
||||
{
|
||||
throwIfClosureRequired: false,
|
||||
},
|
||||
],
|
||||
[
|
||||
"@babel/plugin-transform-classes",
|
||||
{
|
||||
loose: true,
|
||||
},
|
||||
],
|
||||
];
|
||||
return {
|
||||
presets,
|
||||
plugins,
|
||||
highlightCode: true,
|
||||
sourceType: "module",
|
||||
sourceMaps: false,
|
||||
parserOpts: {},
|
||||
only: ["../src/js"],
|
||||
generatorOpts: {
|
||||
retainLines: false,
|
||||
compact: true,
|
||||
minified: true,
|
||||
comments: true,
|
||||
},
|
||||
};
|
||||
};
|
41
gulp/babel.config.js
Normal file
@ -0,0 +1,41 @@
|
||||
module.exports = function (api) {
|
||||
api.cache(true);
|
||||
const presets = [
|
||||
[
|
||||
"@babel/preset-env",
|
||||
{
|
||||
targets: "android >= 4.4.4",
|
||||
useBuiltIns: "usage",
|
||||
corejs: 3,
|
||||
loose: true,
|
||||
spec: false,
|
||||
modules: "auto",
|
||||
// debug: true
|
||||
},
|
||||
],
|
||||
];
|
||||
const plugins = [
|
||||
"closure-elimination",
|
||||
[
|
||||
"@babel/plugin-transform-classes",
|
||||
{
|
||||
loose: true,
|
||||
},
|
||||
],
|
||||
];
|
||||
return {
|
||||
presets,
|
||||
plugins,
|
||||
highlightCode: true,
|
||||
sourceType: "module",
|
||||
sourceMaps: false,
|
||||
parserOpts: {},
|
||||
only: ["../src/js"],
|
||||
generatorOpts: {
|
||||
retainLines: false,
|
||||
compact: true,
|
||||
minified: true,
|
||||
comments: true,
|
||||
},
|
||||
};
|
||||
};
|
50
gulp/buildutils.js
Normal file
@ -0,0 +1,50 @@
|
||||
const glob = require("glob");
|
||||
const execSync = require("child_process").execSync;
|
||||
const trim = require("trim");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
module.exports = {
|
||||
getRevision: function (useLast = false) {
|
||||
const commitHash = execSync("git rev-parse --short " + (useLast ? "HEAD^1" : "HEAD")).toString(
|
||||
"ascii"
|
||||
);
|
||||
return commitHash.replace(/^\s+|\s+$/g, "");
|
||||
},
|
||||
getAllResourceImages() {
|
||||
return glob
|
||||
.sync("res/**/*.@(png|svg|jpg)", { cwd: ".." })
|
||||
.map(f => f.replace(/^res\//gi, ""))
|
||||
.filter(f => {
|
||||
if (f.indexOf("ui") >= 0) {
|
||||
// We drop all ui images except for the noinline ones
|
||||
return f.indexOf("noinline") >= 0;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},
|
||||
|
||||
getAllAtlasImages() {
|
||||
return glob
|
||||
.sync("res_built/atlas/*.png", { cwd: ".." })
|
||||
.map(s => s.replace("res_built/atlas/", "res/"));
|
||||
},
|
||||
|
||||
getAllSounds() {
|
||||
return glob
|
||||
.sync("res_built/sounds/**/*.mp3", { cwd: ".." })
|
||||
.map(s => s.replace("res_built/sounds/", "res/sounds/"));
|
||||
},
|
||||
|
||||
getVersion() {
|
||||
return trim(fs.readFileSync(path.join(__dirname, "..", "version")).toString());
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {string} url
|
||||
* @param {string} commitHash
|
||||
*/
|
||||
cachebust(url, commitHash) {
|
||||
return "/v/" + commitHash + "/" + url;
|
||||
},
|
||||
};
|
112
gulp/bundle-loader.js
Normal file
@ -0,0 +1,112 @@
|
||||
/**
|
||||
* ES6 Bundle Loader
|
||||
*
|
||||
* Attempts to load the game code, and if that fails tries with the transpiled
|
||||
* version. Also handles errors during load.
|
||||
*/
|
||||
|
||||
(function () {
|
||||
var loadTimeout = null;
|
||||
var callbackDone = false;
|
||||
|
||||
// Catch load errors
|
||||
|
||||
function errorHandler(event, source, lineno, colno, error) {
|
||||
console.error("👀 Init Error:", event, source, lineno, colno, error);
|
||||
var element = document.createElement("div");
|
||||
element.style.position = "fixed";
|
||||
element.style.top = "0";
|
||||
element.style.right = "0";
|
||||
element.style.bottom = "0";
|
||||
element.style.left = "0";
|
||||
element.style.zIndex = "29999";
|
||||
element.style.backgroundColor = "#222429";
|
||||
element.style.display = "flex";
|
||||
element.style.justifyContent = "center";
|
||||
element.style.alignItems = "center";
|
||||
|
||||
var inner = document.createElement("div");
|
||||
inner.style.color = "#fff";
|
||||
inner.style.fontFamily = "GameFont, sans-serif";
|
||||
inner.style.fontSize = "15px";
|
||||
inner.style.padding = "30px";
|
||||
inner.style.textAlign = "center";
|
||||
element.appendChild(inner);
|
||||
|
||||
var heading = document.createElement("h3");
|
||||
heading.style.color = "#ef5072";
|
||||
heading.innerText = "Error";
|
||||
heading.style.marginBottom = "40px";
|
||||
heading.style.fontSize = "45px";
|
||||
inner.appendChild(heading);
|
||||
|
||||
var content = document.createElement("p");
|
||||
content.style.color = "#eee";
|
||||
content.innerText = error || (event && event.message) || event || "Unknown Error";
|
||||
inner.appendChild(content);
|
||||
|
||||
if (source) {
|
||||
var sourceElement = document.createElement("p");
|
||||
sourceElement.style.color = "#777";
|
||||
sourceElement.innerText = sourceElement + ":" + lineno + ":" + colno;
|
||||
inner.appendChild(sourceElement);
|
||||
}
|
||||
|
||||
document.documentElement.appendChild(element);
|
||||
}
|
||||
window.addEventListener("error", errorHandler);
|
||||
window.addEventListener("unhandledrejection", errorHandler);
|
||||
|
||||
function makeJsTag(src, integrity) {
|
||||
var script = document.createElement("script");
|
||||
script.src = src;
|
||||
script.type = "text/javascript";
|
||||
script.charset = "utf-8";
|
||||
script.defer = true;
|
||||
if (integrity) {
|
||||
script.setAttribute("integrity", integrity);
|
||||
}
|
||||
return script;
|
||||
}
|
||||
|
||||
function loadFallbackJs(error) {
|
||||
console.warn("👀 ES6 Script not supported, loading transpiled code.");
|
||||
console.warn("👀 Error was:", error);
|
||||
var scriptTransp = makeJsTag(bundleSrcTranspiled, bundleIntegrityTranspiled);
|
||||
scriptTransp.addEventListener("error", scriptFail);
|
||||
scriptTransp.addEventListener("load", onJsLoaded);
|
||||
document.head.appendChild(scriptTransp);
|
||||
}
|
||||
|
||||
function scriptFail(error) {
|
||||
console.error("👀 Failed to load bundle!");
|
||||
console.error("👀 Error was:", error);
|
||||
throw new Error("Core load failed.");
|
||||
}
|
||||
|
||||
function expectJsParsed() {
|
||||
if (!callbackDone) {
|
||||
console.error("👀 Got no core callback");
|
||||
throw new Error("Core thread failed to respond within time.");
|
||||
}
|
||||
}
|
||||
|
||||
function onJsLoaded() {
|
||||
console.log("👀 Core loaded at", Math.floor(performance.now()), "ms");
|
||||
loadTimeout = setTimeout(expectJsParsed, 15000);
|
||||
window.removeEventListener("error", errorHandler);
|
||||
window.removeEventListener("unhandledrejection", errorHandler);
|
||||
}
|
||||
|
||||
window.coreThreadLoadedCb = function () {
|
||||
console.log("👀 Core responded at", Math.floor(performance.now()), "ms");
|
||||
clearTimeout(loadTimeout);
|
||||
loadTimeout = null;
|
||||
callbackDone = true;
|
||||
};
|
||||
|
||||
var scriptEs6 = makeJsTag(bundleSrc, bundleIntegrity);
|
||||
scriptEs6.addEventListener("error", loadFallbackJs);
|
||||
scriptEs6.addEventListener("load", onJsLoaded);
|
||||
document.head.appendChild(scriptEs6);
|
||||
})();
|
96
gulp/convert_atlas.js
Normal file
@ -0,0 +1,96 @@
|
||||
// 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));
|
153
gulp/cordova.js
vendored
Normal file
@ -0,0 +1,153 @@
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
const buildUtils = require("./buildutils");
|
||||
|
||||
export function gulptasksCordova($, gulp, buildFolder) {
|
||||
const cdvRes = path.join("..", "..", "res");
|
||||
|
||||
// Cleans up the app assets
|
||||
// Removes all temporary folders used while optimizing the assets
|
||||
gulp.task("cleanupAppAssetsBuiltFolder", () => {
|
||||
return gulp.src(path.join(cdvRes, "built"), { read: false }).pipe($.clean({ force: true }));
|
||||
});
|
||||
|
||||
// Optimizes all built assets
|
||||
gulp.task("optimizeBuiltAppAssets", () => {
|
||||
return gulp
|
||||
.src(path.join(cdvRes, "built", "**", "*.png"))
|
||||
.pipe($.flatten())
|
||||
.pipe($.imagemin([$.imagemin.optipng({ optimizationLevel: 1 })]))
|
||||
.pipe(gulp.dest(path.join(cdvRes, "built")));
|
||||
});
|
||||
|
||||
// Scales the icon resources
|
||||
gulp.task("scaleIconIos", async () => {
|
||||
const sizes = [
|
||||
180,
|
||||
60,
|
||||
120,
|
||||
76,
|
||||
152,
|
||||
40,
|
||||
80,
|
||||
57,
|
||||
114,
|
||||
72,
|
||||
144,
|
||||
167,
|
||||
29,
|
||||
58,
|
||||
87,
|
||||
50,
|
||||
100,
|
||||
167,
|
||||
20,
|
||||
1024,
|
||||
24,
|
||||
48,
|
||||
55,
|
||||
172,
|
||||
196,
|
||||
];
|
||||
for (let i = 0; i < sizes.length; ++i) {
|
||||
const size = sizes[i];
|
||||
console.log("Scaling icon to", size, "x", size);
|
||||
const img = await $.jimp.read(path.join(cdvRes, "ios", "icon-prefab.png"));
|
||||
await img.resize(size, size).write(path.join(cdvRes, "built", "ios", "icon@" + size + ".png"));
|
||||
}
|
||||
});
|
||||
|
||||
gulp.task("copyOtherIosResources", () => {
|
||||
return gulp
|
||||
.src(path.join(cdvRes, "ios", "splash-prefab.png"))
|
||||
.pipe($.rename("Default@2x~universal~anyany.png"))
|
||||
.pipe(gulp.dest(path.join(cdvRes, "built", "ios")));
|
||||
});
|
||||
|
||||
gulp.task("prepareIosRes", ["scaleIconIos", "copyOtherIosResources"]);
|
||||
|
||||
gulp.task("copyAndroidResources", () => {
|
||||
return gulp
|
||||
.src(path.join(cdvRes, "android", "**", "*.*"))
|
||||
.pipe(gulp.dest(path.join(cdvRes, "built", "android")));
|
||||
});
|
||||
|
||||
gulp.task("prepareAndroidRes", ["copyAndroidResources"]);
|
||||
|
||||
gulp.task("prepareCordovaAssets", cb => {
|
||||
return $.sequence(
|
||||
"cleanupAppAssetsBuiltFolder",
|
||||
["prepareIosRes", "prepareAndroidRes"],
|
||||
"optimizeBuiltAppAssets"
|
||||
)(cb);
|
||||
});
|
||||
|
||||
// Patches the config.xml by replacing the app id to app_beta
|
||||
|
||||
gulp.task("patchConfigXML", () => {
|
||||
const configUrl = path.join("..", "..", "config.xml");
|
||||
let configContent = fs.readFileSync(configUrl).toString();
|
||||
const version = buildUtils.getVersion();
|
||||
configContent = configContent.replace("%VERSION%", version);
|
||||
configContent = configContent.replace(' id="io.shapez.app" ', ' id="io.shapez.app_beta" ');
|
||||
configContent = configContent.replace("<name>Shapez.io</name>", "<name>Shapez.io BETA</name>");
|
||||
fs.writeFileSync(configUrl, configContent);
|
||||
});
|
||||
|
||||
gulp.task("patchConfigXMLChangeStagingToProd", () => {
|
||||
const configUrl = path.join("..", "..", "config.xml");
|
||||
let configContent = fs.readFileSync(configUrl).toString();
|
||||
configContent = configContent.replace(' id="io.shapez.app_beta" ', ' id="io.shapez.app" ');
|
||||
configContent = configContent.replace("<name>Shapez.io BETA</name>", "<name>Shapez.io</name>");
|
||||
fs.writeFileSync(configUrl, configContent);
|
||||
});
|
||||
|
||||
// Triggers a new build on phonegap
|
||||
gulp.task("triggerPhonegapBuild", () => {
|
||||
return gulp
|
||||
.src("src/html/", { dot: false })
|
||||
.pipe(
|
||||
$.phonegapBuild({
|
||||
isRepository: true,
|
||||
appId: "3339820",
|
||||
platforms: ["android", "ios"],
|
||||
user: {
|
||||
token: process.env.SHAPEZ_CLI_PHONEGAP_KEY,
|
||||
},
|
||||
})
|
||||
)
|
||||
.pipe(
|
||||
$.phonegapBuild({
|
||||
isRepository: true,
|
||||
appId: "3537816",
|
||||
platforms: ["android", "ios"],
|
||||
user: {
|
||||
token: process.env.SHAPEZ_CLI_PHONEGAP_KEY,
|
||||
},
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
// gulp.task("pushToStagingRepo", (cb) => {
|
||||
// var cmd = spawn('../push-pgb.sh', ['https://TOKEN@github.com/tobspr/shapezapp-cordova-buildslave.git'],
|
||||
// { stdio: 'inherit', stdout: 'inherit', stderr: 'inherit', shell: true });
|
||||
// cmd.on('close', function (code) {
|
||||
// console.log('push staging exited with code ' + code + " / " + cmd.stdout + " / " + cmd.stderr);
|
||||
// cb(code);
|
||||
// });
|
||||
|
||||
// });
|
||||
|
||||
// gulp.task("pushToProdRepo", (cb) => {
|
||||
// var cmd = spawn('../push-pgb.sh', ['https://TOKEN@github.com/tobspr/shapezapp-cordova-buildslave-release.git'],
|
||||
// { stdio: 'inherit', stdout: 'inherit', stderr: 'inherit', shell: true });
|
||||
// cmd.on('close', function (code) {
|
||||
// console.log('push prod exited with code ' + code + " / " + cmd.stdout + " / " + cmd.stderr);
|
||||
// cb(code);
|
||||
// });
|
||||
// });
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
gulptasksCordova,
|
||||
};
|
101
gulp/css.js
Normal file
@ -0,0 +1,101 @@
|
||||
const path = require("path");
|
||||
const buildUtils = require("./buildutils");
|
||||
|
||||
function gulptasksCSS($, gulp, buildFolder, browserSync) {
|
||||
// The assets plugin copies the files
|
||||
const commitHash = buildUtils.getRevision();
|
||||
const postcssAssetsPlugin = cachebust =>
|
||||
$.postcssAssets({
|
||||
loadPaths: [path.join(buildFolder, "res", "ui")],
|
||||
basePath: buildFolder,
|
||||
baseUrl: ".",
|
||||
cachebuster: cachebust
|
||||
? (filePath, urlPathname) => ({
|
||||
pathname: buildUtils.cachebust(urlPathname, commitHash),
|
||||
})
|
||||
: "",
|
||||
});
|
||||
|
||||
// Postcss configuration
|
||||
const postcssPlugins = (prod, { cachebust = false }) => {
|
||||
const plugins = [postcssAssetsPlugin(cachebust)];
|
||||
if (prod) {
|
||||
plugins.unshift(
|
||||
$.postcssUnprefix(),
|
||||
$.postcssPresetEnv({
|
||||
browsers: ["> 0.1%"],
|
||||
})
|
||||
);
|
||||
|
||||
plugins.push(
|
||||
$.cssMqpacker({
|
||||
sort: true,
|
||||
}),
|
||||
$.cssnano({
|
||||
preset: [
|
||||
"advanced",
|
||||
{
|
||||
cssDeclarationSorter: false,
|
||||
discardUnused: true,
|
||||
mergeIdents: false,
|
||||
reduceIdents: true,
|
||||
zindex: true,
|
||||
},
|
||||
],
|
||||
}),
|
||||
$.postcssRoundSubpixels()
|
||||
);
|
||||
}
|
||||
return plugins;
|
||||
};
|
||||
|
||||
// Performs linting on css
|
||||
gulp.task("css.lint", () => {
|
||||
return gulp
|
||||
.src(["../src/css/**/*.scss"])
|
||||
.pipe($.sassLint({ configFile: ".sasslint.yml" }))
|
||||
.pipe($.sassLint.format())
|
||||
.pipe($.sassLint.failOnError());
|
||||
});
|
||||
|
||||
// Builds the css in dev mode
|
||||
gulp.task("css.dev", () => {
|
||||
return gulp
|
||||
.src(["../src/css/main.scss"])
|
||||
.pipe($.plumber())
|
||||
.pipe($.sass.sync().on("error", $.sass.logError))
|
||||
.pipe($.postcss(postcssPlugins(false, {})))
|
||||
.pipe(gulp.dest(buildFolder))
|
||||
.pipe(browserSync.stream());
|
||||
});
|
||||
|
||||
// Builds the css in production mode (=minified)
|
||||
gulp.task("css.prod", () => {
|
||||
return (
|
||||
gulp
|
||||
.src("../src/css/main.scss", { cwd: __dirname })
|
||||
.pipe($.plumber())
|
||||
.pipe($.sass.sync({ outputStyle: "compressed" }).on("error", $.sass.logError))
|
||||
.pipe($.postcss(postcssPlugins(true, { cachebust: true })))
|
||||
// .pipe($.cssbeautify())
|
||||
.pipe(gulp.dest(buildFolder))
|
||||
);
|
||||
});
|
||||
|
||||
// Builds the css in production mode (=minified), without cachebusting
|
||||
gulp.task("css.prod-standalone", () => {
|
||||
return (
|
||||
gulp
|
||||
.src("../src/css/main.scss", { cwd: __dirname })
|
||||
.pipe($.plumber())
|
||||
.pipe($.sass.sync({ outputStyle: "compressed" }).on("error", $.sass.logError))
|
||||
.pipe($.postcss(postcssPlugins(true, { cachebust: false })))
|
||||
// .pipe($.cssbeautify())
|
||||
.pipe(gulp.dest(buildFolder))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
gulptasksCSS,
|
||||
};
|
38
gulp/docs.js
Normal file
@ -0,0 +1,38 @@
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
|
||||
function gulptasksDocs($, gulp, buildFolder) {
|
||||
gulp.task("docs.convertJsToTs", () => {
|
||||
return gulp
|
||||
.src(path.join("..", "src", "js", "**", "*.js"))
|
||||
.pipe(
|
||||
$.rename(path => {
|
||||
path.extname = ".ts";
|
||||
})
|
||||
)
|
||||
.pipe(gulp.dest(path.join("..", "tsc_temp")));
|
||||
});
|
||||
|
||||
gulp.task("docs.copyTsconfigForHints", () => {
|
||||
const src = fs.readFileSync(path.join("..", "src", "js", "tsconfig.json")).toString();
|
||||
const baseConfig = JSON.parse($.stripJsonComments(src));
|
||||
|
||||
baseConfig.allowJs = false;
|
||||
baseConfig.checkJs = false;
|
||||
baseConfig.declaration = true;
|
||||
baseConfig.noEmit = false;
|
||||
baseConfig.strict = false;
|
||||
baseConfig.strictFunctionTypes = false;
|
||||
baseConfig.strictBindCallApply = false;
|
||||
baseConfig.alwaysStrict = false;
|
||||
baseConfig.composite = true;
|
||||
baseConfig.outFile = "bundled-ts.js";
|
||||
fs.writeFileSync(path.join("..", "tsc_temp", "tsconfig.json"), JSON.stringify(baseConfig));
|
||||
});
|
||||
|
||||
gulp.task("main.prepareDocs", $.sequence("docs.convertJsToTs", "docs.copyTsconfigForHints"));
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
gulptasksDocs,
|
||||
};
|
104
gulp/ftp.js
Normal file
@ -0,0 +1,104 @@
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
|
||||
const buildUtils = require("./buildutils");
|
||||
|
||||
function gulptasksFTP($, gulp, buildFolder) {
|
||||
const commitHash = buildUtils.getRevision();
|
||||
|
||||
// Write the "commit.txt" file
|
||||
gulp.task("ftp.writeVersion", () => {
|
||||
fs.writeFileSync(
|
||||
path.join(buildFolder, "version.json"),
|
||||
JSON.stringify(
|
||||
{
|
||||
commit: buildUtils.getRevision(),
|
||||
appVersion: buildUtils.getVersion(),
|
||||
buildTime: new Date().getTime(),
|
||||
},
|
||||
null,
|
||||
4
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
// Copies additional files (like .htaccess) which should be deployed when running
|
||||
// on the ftp server
|
||||
// gulp.task("ftp.copyServerFiles", () => {
|
||||
// return gulp.src(["../ftp_upload/*.*", "../ftp_upload/.*", "../ftp_upload/*"])
|
||||
// .pipe(gulp.dest(buildFolder));
|
||||
// });
|
||||
|
||||
const gameSrcGlobs = [
|
||||
path.join(buildFolder, "**/*.*"),
|
||||
path.join(buildFolder, "**/.*"),
|
||||
path.join(buildFolder, "**/*"),
|
||||
path.join(buildFolder, "!**/index.html"),
|
||||
];
|
||||
|
||||
gulp.task("ftp.upload.staging.game", () => {
|
||||
return gulp
|
||||
.src(gameSrcGlobs, { base: buildFolder })
|
||||
.pipe(
|
||||
$.rename(pth => {
|
||||
pth.dirname = path.join("v", commitHash, pth.dirname);
|
||||
})
|
||||
)
|
||||
.pipe(
|
||||
$.sftp({
|
||||
host: process.env.SHAPEZ_CLI_SERVER_HOST,
|
||||
user: process.env.SHAPEZ_CLI_STAGING_FTP_USER,
|
||||
pass: process.env.SHAPEZ_CLI_STAGING_FTP_PW,
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
gulp.task("ftp.upload.staging.indexHtml", () => {
|
||||
return gulp.src(path.join(buildFolder, "index.html"), { base: buildFolder }).pipe(
|
||||
$.sftp({
|
||||
host: process.env.SHAPEZ_CLI_SERVER_HOST,
|
||||
user: process.env.SHAPEZ_CLI_STAGING_FTP_USER,
|
||||
pass: process.env.SHAPEZ_CLI_STAGING_FTP_PW,
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
gulp.task("ftp.upload.staging", cb => {
|
||||
$.sequence("ftp.writeVersion", "ftp.upload.staging.game", "ftp.upload.staging.indexHtml")(cb);
|
||||
});
|
||||
|
||||
gulp.task("ftp.upload.prod.game", () => {
|
||||
return gulp
|
||||
.src(gameSrcGlobs, { base: buildFolder })
|
||||
.pipe(
|
||||
$.rename(pth => {
|
||||
pth.dirname = path.join("v", commitHash, pth.dirname);
|
||||
})
|
||||
)
|
||||
.pipe(
|
||||
$.sftp({
|
||||
host: process.env.SHAPEZ_CLI_SERVER_HOST,
|
||||
user: process.env.SHAPEZ_CLI_LIVE_FTP_USER,
|
||||
pass: process.env.SHAPEZ_CLI_LIVE_FTP_PW,
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
gulp.task("ftp.upload.prod.indexHtml", () => {
|
||||
return gulp.src(path.join(buildFolder, "index.html"), { base: buildFolder }).pipe(
|
||||
$.sftp({
|
||||
host: process.env.SHAPEZ_CLI_SERVER_HOST,
|
||||
user: process.env.SHAPEZ_CLI_LIVE_FTP_USER,
|
||||
pass: process.env.SHAPEZ_CLI_LIVE_FTP_PW,
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
gulp.task("ftp.upload.prod", cb => {
|
||||
$.sequence("ftp.writeVersion", "ftp.upload.prod.game", "ftp.upload.prod.indexHtml")(cb);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
gulptasksFTP,
|
||||
};
|
274
gulp/gulpfile.js
Normal file
@ -0,0 +1,274 @@
|
||||
/* eslint-disable */
|
||||
|
||||
require("colors");
|
||||
|
||||
const gulp = require("gulp");
|
||||
const browserSync = require("browser-sync").create({});
|
||||
const path = require("path");
|
||||
const deleteEmpty = require("delete-empty");
|
||||
const execSync = require("child_process").execSync;
|
||||
|
||||
// Load other plugins dynamically
|
||||
const $ = require("gulp-load-plugins")({
|
||||
scope: ["devDependencies"],
|
||||
pattern: "*",
|
||||
});
|
||||
|
||||
// Check environment variables
|
||||
|
||||
const envVars = [
|
||||
"SHAPEZ_CLI_SERVER_HOST",
|
||||
// "SHAPEZ_CLI_PHONEGAP_KEY",
|
||||
"SHAPEZ_CLI_STAGING_FTP_USER",
|
||||
"SHAPEZ_CLI_STAGING_FTP_PW",
|
||||
"SHAPEZ_CLI_LIVE_FTP_USER",
|
||||
"SHAPEZ_CLI_LIVE_FTP_PW",
|
||||
// "SHAPEZ_CLI_TRANSREPORT_FTP_USER",
|
||||
// "SHAPEZ_CLI_TRANSREPORT_FTP_PW",
|
||||
];
|
||||
|
||||
for (let i = 0; i < envVars.length; ++i) {
|
||||
if (!process.env[envVars[i]]) {
|
||||
console.warn("Please set", envVars[i]);
|
||||
// process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
const baseDir = path.join(__dirname, "..");
|
||||
const buildFolder = path.join(baseDir, "build");
|
||||
|
||||
const imgres = require("./image-resources");
|
||||
imgres.gulptasksImageResources($, gulp, buildFolder);
|
||||
|
||||
const css = require("./css");
|
||||
css.gulptasksCSS($, gulp, buildFolder, browserSync);
|
||||
|
||||
const sounds = require("./sounds");
|
||||
sounds.gulptasksSounds($, gulp, buildFolder);
|
||||
|
||||
const js = require("./js");
|
||||
js.gulptasksJS($, gulp, buildFolder, browserSync);
|
||||
|
||||
const html = require("./html");
|
||||
html.gulptasksHTML($, gulp, buildFolder, browserSync);
|
||||
|
||||
const ftp = require("./ftp");
|
||||
ftp.gulptasksFTP($, gulp, buildFolder);
|
||||
|
||||
const docs = require("./docs");
|
||||
docs.gulptasksDocs($, gulp, buildFolder);
|
||||
|
||||
const standalone = require("./standalone");
|
||||
standalone.gulptasksStandalone($, gulp, buildFolder);
|
||||
|
||||
// FIXME
|
||||
// const cordova = require("./cordova");
|
||||
// cordova.gulptasksCordova($, gulp, buildFolder);
|
||||
|
||||
///////////////////// BUILD TASKS /////////////////////
|
||||
|
||||
// Cleans up everything
|
||||
gulp.task("utils.cleanup", () => {
|
||||
return gulp.src(buildFolder, { read: false }).pipe($.clean({ force: true }));
|
||||
});
|
||||
|
||||
// Requires no uncomitted files
|
||||
gulp.task("utils.requireCleanWorkingTree", cb => {
|
||||
const output = $.trim(execSync("git status -su").toString("ascii"));
|
||||
if (output.length > 0) {
|
||||
console.error("\n\nYou have unstaged changes, please commit everything first!");
|
||||
process.exit(1);
|
||||
}
|
||||
cb();
|
||||
});
|
||||
|
||||
gulp.task("utils.copyAdditionalBuildFiles", cb => {
|
||||
const additionalFolder = path.join("additional_build_files");
|
||||
const additionalSrcGlobs = [
|
||||
path.join(additionalFolder, "**/*.*"),
|
||||
path.join(additionalFolder, "**/.*"),
|
||||
path.join(additionalFolder, "**/*"),
|
||||
];
|
||||
|
||||
return gulp.src(additionalSrcGlobs).pipe(gulp.dest(buildFolder));
|
||||
});
|
||||
|
||||
// Starts a webserver on the built directory (useful for testing prod build)
|
||||
gulp.task("main.webserver", () => {
|
||||
return gulp.src(buildFolder).pipe(
|
||||
$.webserver({
|
||||
livereload: {
|
||||
enable: true,
|
||||
},
|
||||
directoryListing: false,
|
||||
open: true,
|
||||
port: 3005,
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
function serve({ standalone }) {
|
||||
browserSync.init({
|
||||
server: buildFolder,
|
||||
port: 3005,
|
||||
ghostMode: {
|
||||
clicks: false,
|
||||
scroll: false,
|
||||
location: false,
|
||||
forms: false,
|
||||
},
|
||||
logLevel: "info",
|
||||
logPrefix: "BS",
|
||||
online: false,
|
||||
xip: false,
|
||||
notify: false,
|
||||
reloadDebounce: 100,
|
||||
reloadOnRestart: true,
|
||||
watchEvents: ["add", "change"],
|
||||
});
|
||||
|
||||
// Watch .scss files, those trigger a css rebuild
|
||||
gulp.watch(["../src/**/*.scss"], ["css.dev"]);
|
||||
|
||||
// Watch .html files, those trigger a html rebuild
|
||||
gulp.watch("../src/**/*.html", [standalone ? "html.standalone-dev" : "html.dev"]);
|
||||
|
||||
// Watch sound files
|
||||
// gulp.watch(["../res_raw/sounds/**/*.mp3", "../res_raw/sounds/**/*.wav"], ["sounds.dev"]);
|
||||
|
||||
gulp.watch(
|
||||
["../res_raw/sounds/ui/*.mp3", "../res_raw/sounds/ui/*.wav"],
|
||||
$.sequence("sounds.encodeUi", "sounds.copy")
|
||||
);
|
||||
gulp.watch(
|
||||
["../res_raw/sounds/game/*.mp3", "../res_raw/sounds/game/*.wav"],
|
||||
$.sequence("sounds.encodeGame", "sounds.copy")
|
||||
);
|
||||
gulp.watch(
|
||||
["../res_raw/sounds/music/*.mp3", "../res_raw/sounds/music/*.wav"],
|
||||
$.sequence("sounds.encodeMusic", "sounds.copy")
|
||||
);
|
||||
|
||||
// Watch resource files and copy them on change
|
||||
gulp.watch(imgres.nonImageResourcesGlobs, ["imgres.copyNonImageResources"]);
|
||||
gulp.watch(imgres.imageResourcesGlobs, ["imgres.copyImageResources"]);
|
||||
|
||||
// Watch .atlas files and recompile the atlas on change
|
||||
gulp.watch("../res_built/atlas/*.json", ["imgres.atlas"]);
|
||||
|
||||
// Watch the build folder and reload when anything changed
|
||||
const extensions = ["html", "js", "png", "jpg", "svg", "mp3", "ico", "woff2"];
|
||||
gulp.watch(extensions.map(ext => path.join(buildFolder, "**", "*." + ext))).on("change", function (e) {
|
||||
return gulp.src(e.path).pipe(browserSync.reload({ stream: true }));
|
||||
});
|
||||
|
||||
// Start the webpack watching server (Will never return)
|
||||
if (standalone) {
|
||||
$.sequence("js.standalone-dev.watch")(() => true);
|
||||
} else {
|
||||
$.sequence("js.dev.watch")(() => true);
|
||||
}
|
||||
}
|
||||
|
||||
// Live-development
|
||||
gulp.task("main.serveDev", ["build.dev"], () => serve({ standalone: false }));
|
||||
gulp.task("main.serveStandalone", ["build.standalone.dev"], () => serve({ standalone: true }));
|
||||
|
||||
gulp.task("default", ["main.serveDev"]);
|
||||
|
||||
///////////////////// RUNNABLE TASKS /////////////////////
|
||||
|
||||
// Pre and postbuild
|
||||
gulp.task("step.baseResources", cb => $.multiProcess(["sounds.fullbuild", "imgres.allOptimized"], cb, false));
|
||||
gulp.task("step.deleteEmpty", cb => {
|
||||
deleteEmpty.sync(buildFolder);
|
||||
cb();
|
||||
});
|
||||
|
||||
gulp.task("step.postbuild", $.sequence("imgres.cleanupUnusedCssInlineImages", "step.deleteEmpty"));
|
||||
|
||||
// Builds everything (dev)
|
||||
gulp.task("build.dev", cb => {
|
||||
$.sequence(
|
||||
"utils.cleanup",
|
||||
"utils.copyAdditionalBuildFiles",
|
||||
"imgres.atlas",
|
||||
"sounds.dev",
|
||||
"imgres.copyImageResources",
|
||||
"imgres.copyNonImageResources",
|
||||
"js.dev",
|
||||
"css.dev",
|
||||
"html.dev"
|
||||
)(cb);
|
||||
});
|
||||
|
||||
// Builds everything (standalone -dev)
|
||||
gulp.task("build.standalone.dev", cb => {
|
||||
$.sequence(
|
||||
"utils.cleanup",
|
||||
"imgres.atlas",
|
||||
"sounds.dev",
|
||||
"imgres.copyImageResources",
|
||||
"imgres.copyNonImageResources",
|
||||
"js.standalone-dev",
|
||||
"css.dev",
|
||||
"html.standalone-dev"
|
||||
)(cb);
|
||||
});
|
||||
|
||||
// Builds everything (staging)
|
||||
gulp.task("step.staging.code", $.sequence("js.staging"));
|
||||
gulp.task("step.staging.mainbuild", cb =>
|
||||
$.multiProcess(["utils.copyAdditionalBuildFiles", "step.baseResources", "step.staging.code"], cb, false)
|
||||
);
|
||||
gulp.task("step.staging.all", $.sequence("step.staging.mainbuild", "css.prod", "html.staging"));
|
||||
gulp.task("build.staging", $.sequence("utils.cleanup", "step.staging.all", "step.postbuild"));
|
||||
|
||||
// Builds everything (prod)
|
||||
gulp.task("step.prod.code", $.sequence("js.prod"));
|
||||
gulp.task("step.prod.mainbuild", cb =>
|
||||
$.multiProcess(["utils.copyAdditionalBuildFiles", "step.baseResources", "step.prod.code"], cb, false)
|
||||
);
|
||||
gulp.task("step.prod.all", $.sequence("step.prod.mainbuild", "css.prod", "html.prod"));
|
||||
gulp.task("build.prod", $.sequence("utils.cleanup", "step.prod.all", "step.postbuild"));
|
||||
|
||||
// Builds everything (standalone-beta)
|
||||
gulp.task("step.standalone-beta.code", $.sequence("js.standalone-beta"));
|
||||
gulp.task("step.standalone-beta.mainbuild", cb =>
|
||||
$.multiProcess(
|
||||
["utils.copyAdditionalBuildFiles", "step.baseResources", "step.standalone-beta.code"],
|
||||
cb,
|
||||
false
|
||||
)
|
||||
);
|
||||
gulp.task(
|
||||
"step.standalone-beta.all",
|
||||
$.sequence("step.standalone-beta.mainbuild", "css.prod-standalone", "html.standalone-beta")
|
||||
);
|
||||
gulp.task("build.standalone-beta", $.sequence("utils.cleanup", "step.standalone-beta.all", "step.postbuild"));
|
||||
|
||||
// Builds everything (standalone-prod)
|
||||
gulp.task("step.standalone-prod.code", $.sequence("js.standalone-prod"));
|
||||
gulp.task("step.standalone-prod.mainbuild", cb =>
|
||||
$.multiProcess(
|
||||
["utils.copyAdditionalBuildFiles", "step.baseResources", "step.standalone-prod.code"],
|
||||
cb,
|
||||
false
|
||||
)
|
||||
);
|
||||
gulp.task(
|
||||
"step.standalone-prod.all",
|
||||
$.sequence("step.standalone-prod.mainbuild", "css.prod-standalone", "html.standalone-prod")
|
||||
);
|
||||
gulp.task("build.standalone-prod", $.sequence("utils.cleanup", "step.standalone-prod.all", "step.postbuild"));
|
||||
|
||||
// Deploying!
|
||||
gulp.task(
|
||||
"main.deploy.staging",
|
||||
$.sequence("utils.requireCleanWorkingTree", "build.staging", "ftp.upload.staging")
|
||||
);
|
||||
gulp.task("main.deploy.prod", $.sequence("utils.requireCleanWorkingTree", "build.prod", "ftp.upload.prod"));
|
||||
gulp.task("main.deploy.all", $.sequence("main.deploy.staging", "main.deploy.prod"));
|
||||
|
||||
// gulp.task("main.standalone.beta", $.sequence("build.standalone-beta", "standalone.package.beta"));
|
||||
gulp.task("main.standalone", $.sequence("build.standalone-prod", "standalone.package.prod"));
|
360
gulp/html.js
Normal file
@ -0,0 +1,360 @@
|
||||
const buildUtils = require("./buildutils");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const crypto = require("crypto");
|
||||
|
||||
function computeIntegrityHash(fullPath, algorithm = "sha256") {
|
||||
const file = fs.readFileSync(fullPath);
|
||||
const hash = crypto.createHash(algorithm).update(file).digest("base64");
|
||||
return algorithm + "-" + hash;
|
||||
}
|
||||
|
||||
function gulptasksHTML($, gulp, buildFolder, browserSync) {
|
||||
const commitHash = buildUtils.getRevision();
|
||||
async function buildHtml(
|
||||
apiUrl,
|
||||
{
|
||||
analytics = false,
|
||||
standalone = false,
|
||||
app = false,
|
||||
integrity = true,
|
||||
enableCachebust = true,
|
||||
gameAnalyticsKey = null,
|
||||
gameAnalyticsSecret = null,
|
||||
}
|
||||
) {
|
||||
function cachebust(url) {
|
||||
if (enableCachebust) {
|
||||
return buildUtils.cachebust(url, commitHash);
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
const hasLocalFiles = standalone || app;
|
||||
|
||||
return gulp
|
||||
.src("../src/html/" + (standalone ? "index.standalone.html" : "index.html"))
|
||||
.pipe(
|
||||
$.dom(function () {
|
||||
// @ts-ignore
|
||||
const document = /** @type {Document} */ (this);
|
||||
|
||||
// Preconnect to api
|
||||
const prefetchLink = document.createElement("link");
|
||||
prefetchLink.rel = "preconnect";
|
||||
prefetchLink.href = apiUrl;
|
||||
prefetchLink.setAttribute("crossorigin", "anonymous");
|
||||
document.head.appendChild(prefetchLink);
|
||||
|
||||
// // Append css preload
|
||||
// const cssPreload = document.createElement("link");
|
||||
// cssPreload.rel = "preload";
|
||||
// cssPreload.href = cachebust("main.css");
|
||||
// cssPreload.setAttribute("as", "style");
|
||||
// document.head.appendChild(cssPreload);
|
||||
// document.head.appendChild(prefetchLink);
|
||||
|
||||
// // Append js preload
|
||||
// const jsPreload = document.createElement("link");
|
||||
// jsPreload.rel = "preload";
|
||||
// jsPreload.href = cachebust("bundle.js");
|
||||
// jsPreload.setAttribute("as", "script");
|
||||
// document.head.appendChild(jsPreload);
|
||||
|
||||
// Append css
|
||||
const css = document.createElement("link");
|
||||
css.rel = "stylesheet";
|
||||
css.type = "text/css";
|
||||
css.media = "none";
|
||||
css.setAttribute("onload", "this.media='all'");
|
||||
css.href = cachebust("main.css");
|
||||
if (integrity) {
|
||||
css.setAttribute(
|
||||
"integrity",
|
||||
computeIntegrityHash(path.join(buildFolder, "main.css"))
|
||||
);
|
||||
}
|
||||
document.head.appendChild(css);
|
||||
|
||||
if (analytics) {
|
||||
// Logrocket
|
||||
// const logrocketScript = document.createElement("script");
|
||||
// logrocketScript.src = "https://cdn.lr-ingest.io/LogRocket.min.js";
|
||||
// logrocketScript.setAttribute("crossorigin", "anonymous");
|
||||
// document.head.appendChild(logrocketScript);
|
||||
// const logrocketInit = document.createElement("script");
|
||||
// logrocketInit.textContent = "window.LogRocket && window.LogRocket.init('TODO: GET LOGROCKET ID');";
|
||||
// document.head.appendChild(logrocketInit);
|
||||
}
|
||||
|
||||
if (gameAnalyticsKey && gameAnalyticsSecret) {
|
||||
const gaLoader = document.createElement("script");
|
||||
gaLoader.textContent = `
|
||||
window.GameAnalytics=window.GameAnalytics||function(){(GameAnalytics.q=GameAnalytics.q||[]).push(arguments)};
|
||||
window.ga_comKey = "${gameAnalyticsKey}";
|
||||
window.ga_comToken = "${gameAnalyticsSecret}";
|
||||
`;
|
||||
document.head.appendChild(gaLoader);
|
||||
|
||||
const gaScript = document.createElement("script");
|
||||
gaScript.src = "https://download.gameanalytics.com/js/GameAnalytics-4.0.10.min.js";
|
||||
gaScript.setAttribute("async", "");
|
||||
document.head.appendChild(gaScript);
|
||||
}
|
||||
|
||||
if (app) {
|
||||
// Append cordova link
|
||||
const cdv = document.createElement("script");
|
||||
cdv.src = "cordova.js";
|
||||
cdv.type = "text/javascript";
|
||||
document.head.appendChild(cdv);
|
||||
}
|
||||
|
||||
// Google analytics
|
||||
if (analytics) {
|
||||
const tagManagerScript = document.createElement("script");
|
||||
tagManagerScript.src = "https://www.googletagmanager.com/gtag/js?id=UA-165342524-1";
|
||||
tagManagerScript.setAttribute("async", "");
|
||||
document.head.appendChild(tagManagerScript);
|
||||
|
||||
const initScript = document.createElement("script");
|
||||
initScript.textContent = `
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
gtag('config', 'UA-165342524-1', { anonymize_ip: true });
|
||||
`;
|
||||
document.head.appendChild(initScript);
|
||||
}
|
||||
|
||||
// Do not need to preload in app or standalone
|
||||
if (!hasLocalFiles) {
|
||||
// Preload images
|
||||
const images = buildUtils.getAllResourceImages();
|
||||
|
||||
// Preload essentials
|
||||
const preloads = ["fonts/LouisGeorgeCafe.woff2"];
|
||||
|
||||
// for (let i = 0; i < images.length; ++i) {
|
||||
// if (preloads.indexOf(images[i]) < 0) {
|
||||
// preloads.push(images[i]);
|
||||
// }
|
||||
// }
|
||||
|
||||
preloads.forEach(src => {
|
||||
const preloadLink = document.createElement("link");
|
||||
preloadLink.rel = "preload";
|
||||
preloadLink.href = cachebust("res/" + src);
|
||||
if (src.endsWith(".woff2")) {
|
||||
preloadLink.setAttribute("crossorigin", "anonymous");
|
||||
preloadLink.setAttribute("as", "font");
|
||||
} else {
|
||||
preloadLink.setAttribute("as", "image");
|
||||
}
|
||||
document.head.appendChild(preloadLink);
|
||||
});
|
||||
|
||||
// Sound preloads
|
||||
// const sounds = buildUtils.getAllSounds();
|
||||
// sounds.forEach((src) => {
|
||||
|
||||
// if (src.indexOf("sounds/music/") >= 0) {
|
||||
// // skip music
|
||||
// return;
|
||||
// }
|
||||
|
||||
// const preloadLink = document.createElement("link");
|
||||
// preloadLink.rel = "preload";
|
||||
// preloadLink.href = cachebust(src);
|
||||
// // preloadLink.setAttribute("crossorigin", "anonymous");
|
||||
// preloadLink.setAttribute("as", "fetch");
|
||||
// document.head.appendChild(preloadLink);
|
||||
// });
|
||||
}
|
||||
|
||||
const loadingSvg = `background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46YXV0bztiYWNrZ3JvdW5kOjAgMCIgd2lkdGg9IjIwMCIgaGVpZ2h0PSIyMDAiIHZpZXdCb3g9IjAgMCAxMDAgMTAwIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCIgZGlzcGxheT0iYmxvY2siPjxjaXJjbGUgY3g9IjUwIiBjeT0iNTAiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzM5Mzc0NyIgc3Ryb2tlLXdpZHRoPSIzIiByPSI0MiIgc3Ryb2tlLWRhc2hhcnJheT0iMTk3LjkyMDMzNzE3NjE1Njk4IDY3Ljk3MzQ0NTcyNTM4NTY2IiB0cmFuc2Zvcm09InJvdGF0ZSg0OC4yNjUgNTAgNTApIj48YW5pbWF0ZVRyYW5zZm9ybSBhdHRyaWJ1dGVOYW1lPSJ0cmFuc2Zvcm0iIHR5cGU9InJvdGF0ZSIgcmVwZWF0Q291bnQ9ImluZGVmaW5pdGUiIGR1cj0iNS41NTU1NTU1NTU1NTU1NTVzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIi8+PC9jaXJjbGU+PC9zdmc+")`;
|
||||
|
||||
const loadingCss = `
|
||||
@font-face {
|
||||
font-family: 'GameFont';
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-display: swap;
|
||||
src: url('${cachebust("res/fonts/LouisGeorgeCafe.woff2")}') format('woff2');
|
||||
}
|
||||
|
||||
#ll_fp {
|
||||
font-family: GameFont;
|
||||
font-size: 14px;
|
||||
position: fixed;
|
||||
z-index: -1;
|
||||
top: 0;
|
||||
left: 0;
|
||||
opacity: 0.05;
|
||||
}
|
||||
|
||||
#ll_p {
|
||||
display: flex;
|
||||
position: fixed;
|
||||
z-index: 99999;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
justify-content:
|
||||
center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#ll_p > div {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
bottom: 40px;
|
||||
left: 20px;
|
||||
right: 20px;
|
||||
color: #393747;
|
||||
font-family: 'GameFont', sans-serif;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
#ll_p > span {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
display: inline-flex;
|
||||
background: center center / contain no-repeat;
|
||||
${loadingSvg};
|
||||
}
|
||||
`;
|
||||
|
||||
const style = document.createElement("style");
|
||||
style.setAttribute("type", "text/css");
|
||||
style.textContent = loadingCss;
|
||||
document.head.appendChild(style);
|
||||
|
||||
// Append loader, but not in standalone (directly include bundle there)
|
||||
if (standalone) {
|
||||
const bundleScript = document.createElement("script");
|
||||
bundleScript.type = "text/javascript";
|
||||
bundleScript.src = "bundle.js";
|
||||
if (integrity) {
|
||||
bundleScript.setAttribute(
|
||||
"integrity",
|
||||
computeIntegrityHash(path.join(buildFolder, "bundle.js"))
|
||||
);
|
||||
}
|
||||
document.head.appendChild(bundleScript);
|
||||
} else {
|
||||
const loadJs = document.createElement("script");
|
||||
loadJs.type = "text/javascript";
|
||||
let scriptContent = "";
|
||||
scriptContent += `var bundleSrc = '${cachebust("bundle.js")}';\n`;
|
||||
scriptContent += `var bundleSrcTranspiled = '${cachebust(
|
||||
"bundle-transpiled.js"
|
||||
)}';\n`;
|
||||
|
||||
if (integrity) {
|
||||
scriptContent +=
|
||||
"var bundleIntegrity = '" +
|
||||
computeIntegrityHash(path.join(buildFolder, "bundle.js")) +
|
||||
"';\n";
|
||||
scriptContent +=
|
||||
"var bundleIntegrityTranspiled = '" +
|
||||
computeIntegrityHash(path.join(buildFolder, "bundle-transpiled.js")) +
|
||||
"';\n";
|
||||
} else {
|
||||
scriptContent += "var bundleIntegrity = null;\n";
|
||||
scriptContent += "var bundleIntegrityTranspiled = null;\n";
|
||||
}
|
||||
|
||||
scriptContent += fs.readFileSync("./bundle-loader.js").toString();
|
||||
loadJs.textContent = scriptContent;
|
||||
document.head.appendChild(loadJs);
|
||||
}
|
||||
|
||||
const bodyContent = `
|
||||
<div id="ll_fp">_</div>
|
||||
<div id="ll_p">
|
||||
<span></span>
|
||||
<div>${hasLocalFiles ? "Loading" : "Downloading"} Game Files</div >
|
||||
</div >
|
||||
`;
|
||||
|
||||
document.body.innerHTML = bodyContent;
|
||||
})
|
||||
)
|
||||
.pipe(
|
||||
$.htmlmin({
|
||||
caseSensitive: true,
|
||||
collapseBooleanAttributes: true,
|
||||
collapseInlineTagWhitespace: true,
|
||||
collapseWhitespace: true,
|
||||
preserveLineBreaks: true,
|
||||
minifyJS: true,
|
||||
minifyCSS: true,
|
||||
quoteCharacter: '"',
|
||||
useShortDoctype: true,
|
||||
})
|
||||
)
|
||||
.pipe($.htmlBeautify())
|
||||
.pipe($.rename("index.html"))
|
||||
.pipe(gulp.dest(buildFolder));
|
||||
}
|
||||
|
||||
gulp.task("html.dev", () => {
|
||||
return buildHtml("http://localhost:5005", {
|
||||
analytics: false,
|
||||
integrity: false,
|
||||
enableCachebust: false,
|
||||
gameAnalyticsKey: "c8d77921633d5c32a7134e5d5cfcdf12",
|
||||
// Not an actual "secret" since its built into the JS code
|
||||
gameAnalyticsSecret: "6d23b40a70199bff0e7a7d8a073543772cf07097",
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task("html.staging", () => {
|
||||
return buildHtml("https://api-staging.shapez.io", {
|
||||
analytics: true,
|
||||
gameAnalyticsKey: "903fa0dd2d2e23b07e66ea96ddc4c10c",
|
||||
// Not an actual "secret" since its built into the JS code
|
||||
gameAnalyticsSecret: "9417fc391d7142b9d73a3861ba6046cafa9df6cb",
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task("html.prod", () => {
|
||||
return buildHtml("https://api.shapez.io", {
|
||||
analytics: true,
|
||||
gameAnalyticsKey: "16c7f9d352e40c92f6a750fc1a4f0443",
|
||||
// Not an actual "secret" since its built into the JS code
|
||||
gameAnalyticsSecret: "4202d7adf154c325ff91731e8be6912e6c0d10e5",
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task("html.standalone-dev", () => {
|
||||
return buildHtml("https://localhost:5005", {
|
||||
analytics: false,
|
||||
standalone: true,
|
||||
integrity: false,
|
||||
enableCachebust: false,
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task("html.standalone-beta", () => {
|
||||
return buildHtml("https://api-staging.shapez.io", {
|
||||
analytics: true,
|
||||
standalone: true,
|
||||
enableCachebust: false,
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task("html.standalone-prod", () => {
|
||||
return buildHtml("https://api.shapez.io", {
|
||||
analytics: true,
|
||||
standalone: true,
|
||||
enableCachebust: false,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
gulptasksHTML,
|
||||
};
|
138
gulp/image-resources.js
Normal file
@ -0,0 +1,138 @@
|
||||
// @ts-ignore
|
||||
const path = require("path");
|
||||
|
||||
// Globs for non-ui resources
|
||||
const nonImageResourcesGlobs = ["../res/**/*.woff2", "../res/*.ico"];
|
||||
|
||||
// Globs for ui resources
|
||||
const imageResourcesGlobs = ["../res/**/*.png", "../res/**/*.svg", "../res/**/*.jpg"];
|
||||
|
||||
function gulptasksImageResources($, gulp, buildFolder) {
|
||||
// Lossless options
|
||||
const minifyImagesOptsLossless = () => [
|
||||
$.imagemin.jpegtran({
|
||||
progressive: true,
|
||||
}),
|
||||
$.imagemin.svgo({}),
|
||||
$.imagemin.optipng({
|
||||
optimizationLevel: 3,
|
||||
}),
|
||||
];
|
||||
|
||||
// Lossy options
|
||||
const minifyImagesOpts = () => [
|
||||
$.imageminMozjpeg({
|
||||
quality: 80,
|
||||
maxMemory: 1024 * 1024 * 8,
|
||||
}),
|
||||
$.imagemin.svgo({}),
|
||||
$.imageminPngquant({
|
||||
speed: 1,
|
||||
strip: true,
|
||||
quality: [0.65, 0.9],
|
||||
dithering: false,
|
||||
verbose: false,
|
||||
}),
|
||||
$.imagemin.optipng({
|
||||
optimizationLevel: 3,
|
||||
}),
|
||||
];
|
||||
|
||||
// Where the resources folder are
|
||||
const resourcesDestFolder = path.join(buildFolder, "res");
|
||||
|
||||
/**
|
||||
* Determines if an atlas must use lossless compression
|
||||
* @param {string} fname
|
||||
*/
|
||||
function fileMustBeLossless(fname) {
|
||||
return fname.indexOf("lossless") >= 0;
|
||||
}
|
||||
|
||||
/////////////// ATLAS /////////////////////
|
||||
|
||||
// Copies the atlas to the final destination
|
||||
gulp.task("imgres.atlas", () => {
|
||||
return gulp
|
||||
.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
|
||||
.src(["../res_built/atlas/*.png"])
|
||||
.pipe($.cached("imgres.atlasOptimized"))
|
||||
.pipe(
|
||||
$.if(
|
||||
fname => fileMustBeLossless(fname.history[0]),
|
||||
$.imagemin(minifyImagesOptsLossless()),
|
||||
$.imagemin(minifyImagesOpts())
|
||||
)
|
||||
)
|
||||
.pipe(gulp.dest(resourcesDestFolder));
|
||||
});
|
||||
|
||||
//////////////////// RESOURCES //////////////////////
|
||||
|
||||
// Copies all resources which are no ui resources
|
||||
gulp.task("imgres.copyNonImageResources", () => {
|
||||
return gulp
|
||||
.src(nonImageResourcesGlobs)
|
||||
.pipe($.cached("imgres.copyNonImageResources"))
|
||||
.pipe(gulp.dest(resourcesDestFolder));
|
||||
});
|
||||
|
||||
// Copies all ui resources
|
||||
gulp.task("imgres.copyImageResources", () => {
|
||||
return gulp
|
||||
.src(imageResourcesGlobs)
|
||||
.pipe($.cached("copyImageResources"))
|
||||
.pipe(gulp.dest(path.join(resourcesDestFolder)));
|
||||
});
|
||||
|
||||
// Copies all ui resources and optimizes them
|
||||
gulp.task("imgres.copyImageResourcesOptimized", () => {
|
||||
return gulp
|
||||
.src(imageResourcesGlobs)
|
||||
.pipe($.cached("imgres.copyImageResourcesOptimized"))
|
||||
.pipe(
|
||||
$.if(
|
||||
fname => fileMustBeLossless(fname.history[0]),
|
||||
$.imagemin(minifyImagesOptsLossless()),
|
||||
$.imagemin(minifyImagesOpts())
|
||||
)
|
||||
)
|
||||
.pipe(gulp.dest(path.join(resourcesDestFolder)));
|
||||
});
|
||||
|
||||
// Copies all resources and optimizes them
|
||||
gulp.task("imgres.allOptimized", cb =>
|
||||
$.multiProcess(
|
||||
["imgres.atlasOptimized", "imgres.copyNonImageResources", "imgres.copyImageResourcesOptimized"],
|
||||
cb,
|
||||
false
|
||||
)
|
||||
);
|
||||
|
||||
// Cleans up unused images which are instead inline into the css
|
||||
gulp.task("imgres.cleanupUnusedCssInlineImages", () => {
|
||||
return gulp
|
||||
.src(
|
||||
[
|
||||
path.join(buildFolder, "res", "ui", "**", "*.png"),
|
||||
path.join(buildFolder, "res", "ui", "**", "*.jpg"),
|
||||
path.join(buildFolder, "res", "ui", "**", "*.svg"),
|
||||
],
|
||||
{ read: false }
|
||||
)
|
||||
.pipe($.if(fname => fname.history[0].indexOf("noinline") < 0, $.clean({ force: true })));
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
nonImageResourcesGlobs,
|
||||
imageResourcesGlobs,
|
||||
gulptasksImageResources,
|
||||
};
|
182
gulp/js.js
Normal file
@ -0,0 +1,182 @@
|
||||
const path = require("path");
|
||||
|
||||
function requireUncached(module) {
|
||||
delete require.cache[require.resolve(module)];
|
||||
return require(module);
|
||||
}
|
||||
|
||||
function gulptasksJS($, gulp, buildFolder, browserSync) {
|
||||
gulp.task("js.prettify", () => {
|
||||
return gulp
|
||||
.src(path.join(buildFolder, "bundle.js"))
|
||||
.pipe($.jsbeautifier(require("./jsbeautify.json")))
|
||||
.pipe(gulp.dest(buildFolder));
|
||||
});
|
||||
|
||||
//// DEV
|
||||
|
||||
gulp.task("js.dev.watch", () => {
|
||||
return gulp
|
||||
.src("../src/js/main.js")
|
||||
.pipe(
|
||||
$.webpackStream(
|
||||
requireUncached("./webpack.config.js")({
|
||||
watch: true,
|
||||
})
|
||||
)
|
||||
)
|
||||
.pipe(gulp.dest(buildFolder))
|
||||
.pipe(browserSync.stream());
|
||||
});
|
||||
|
||||
gulp.task("js.dev", () => {
|
||||
return gulp
|
||||
.src("../src/js/main.js")
|
||||
.pipe($.webpackStream(requireUncached("./webpack.config.js")({})))
|
||||
.pipe(gulp.dest(buildFolder));
|
||||
});
|
||||
|
||||
//// STAGING
|
||||
|
||||
gulp.task("js.staging.transpiled", () => {
|
||||
return gulp
|
||||
.src("../src/js/main.js")
|
||||
.pipe(
|
||||
$.webpackStream(
|
||||
requireUncached("./webpack.production.config.js")({
|
||||
enableAssert: true,
|
||||
environment: "staging",
|
||||
apiEndpoint: "https://api-staging.shapez.io/v1",
|
||||
es6: false,
|
||||
})
|
||||
)
|
||||
)
|
||||
.pipe($.rename("bundle-transpiled.js"))
|
||||
.pipe(gulp.dest(buildFolder));
|
||||
});
|
||||
|
||||
gulp.task("js.staging.latest", () => {
|
||||
return gulp
|
||||
.src("../src/js/main.js")
|
||||
.pipe(
|
||||
$.webpackStream(
|
||||
requireUncached("./webpack.production.config.js")({
|
||||
enableAssert: true,
|
||||
environment: "staging",
|
||||
apiEndpoint: "https://api-staging.shapez.io/v1",
|
||||
es6: true,
|
||||
})
|
||||
)
|
||||
)
|
||||
.pipe(gulp.dest(buildFolder));
|
||||
});
|
||||
gulp.task("js.staging", cb => $.multiProcess(["js.staging.transpiled", "js.staging.latest"], cb, false));
|
||||
|
||||
//// PROD
|
||||
gulp.task("js.prod.transpiled", () => {
|
||||
return gulp
|
||||
.src("../src/js/main.js")
|
||||
.pipe(
|
||||
$.webpackStream(
|
||||
requireUncached("./webpack.production.config.js")({
|
||||
enableAssert: false,
|
||||
environment: "prod",
|
||||
apiEndpoint: "https://api.shapez.io/v1",
|
||||
es6: false,
|
||||
})
|
||||
)
|
||||
)
|
||||
.pipe($.rename("bundle-transpiled.js"))
|
||||
.pipe(gulp.dest(buildFolder))
|
||||
.pipe(browserSync.stream());
|
||||
});
|
||||
|
||||
gulp.task("js.prod.latest", () => {
|
||||
return gulp
|
||||
.src("../src/js/main.js")
|
||||
.pipe(
|
||||
$.webpackStream(
|
||||
requireUncached("./webpack.production.config.js")({
|
||||
enableAssert: false,
|
||||
environment: "prod",
|
||||
es6: true,
|
||||
apiEndpoint: "https://api.shapez.io/v1",
|
||||
})
|
||||
)
|
||||
)
|
||||
.pipe(gulp.dest(buildFolder))
|
||||
.pipe(browserSync.stream());
|
||||
});
|
||||
|
||||
gulp.task("js.prod", cb => $.multiProcess(["js.prod.transpiled", "js.prod.latest"], cb, false));
|
||||
|
||||
//// STANDALONE
|
||||
|
||||
gulp.task("js.standalone-dev.watch", () => {
|
||||
return gulp
|
||||
.src("../src/js/main.js")
|
||||
.pipe(
|
||||
$.webpackStream(
|
||||
requireUncached("./webpack.config.js")({
|
||||
watch: true,
|
||||
standalone: true,
|
||||
})
|
||||
)
|
||||
)
|
||||
.pipe(gulp.dest(buildFolder))
|
||||
.pipe(browserSync.stream());
|
||||
});
|
||||
|
||||
gulp.task("js.standalone-dev", () => {
|
||||
return gulp
|
||||
.src("../src/js/main.js")
|
||||
.pipe(
|
||||
$.webpackStream(
|
||||
requireUncached("./webpack.config.js")({
|
||||
standalone: true,
|
||||
})
|
||||
)
|
||||
)
|
||||
.pipe(gulp.dest(buildFolder));
|
||||
});
|
||||
|
||||
gulp.task("js.standalone-beta", () => {
|
||||
return gulp
|
||||
.src("../src/js/main.js")
|
||||
.pipe(
|
||||
$.webpackStream(
|
||||
requireUncached("./webpack.production.config.js")({
|
||||
enableAssert: true,
|
||||
environment: "staging",
|
||||
apiEndpoint: "https://api-staging.shapez.io/v1",
|
||||
es6: true,
|
||||
standalone: true,
|
||||
})
|
||||
)
|
||||
)
|
||||
.pipe(gulp.dest(buildFolder));
|
||||
});
|
||||
|
||||
gulp.task("js.standalone-prod", () => {
|
||||
return gulp
|
||||
.src("../src/js/main.js")
|
||||
.pipe(
|
||||
$.webpackStream(
|
||||
requireUncached("./webpack.production.config.js")({
|
||||
enableAssert: false,
|
||||
environment: "prod",
|
||||
apiEndpoint: "https://api.shapez.io/v1",
|
||||
es6: true,
|
||||
standalone: true,
|
||||
})
|
||||
)
|
||||
)
|
||||
.pipe(gulp.dest(buildFolder));
|
||||
});
|
||||
|
||||
// TODO: Tasks for te app
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
gulptasksJS,
|
||||
};
|
6
gulp/jsconfig.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es6",
|
||||
"checkJs": true
|
||||
}
|
||||
}
|
11
gulp/loader.compressjson.js
Normal file
@ -0,0 +1,11 @@
|
||||
"use strict";
|
||||
|
||||
const lzString = require("lz-string");
|
||||
|
||||
module.exports = function (source) {
|
||||
const compressed = lzString.compressToEncodedURIComponent(source);
|
||||
const sourcecode = `module.exports = (function() {
|
||||
return JSON.parse(require("global-compression").decompressX64("${compressed}"));
|
||||
})()`;
|
||||
return sourcecode;
|
||||
};
|
21
gulp/loader.strip_block.js
Normal file
@ -0,0 +1,21 @@
|
||||
/*jslint node:true */
|
||||
"use strict";
|
||||
|
||||
const startComment = "typehints:start";
|
||||
const endComment = "typehints:end";
|
||||
const regexPattern = new RegExp(
|
||||
"[\\t ]*\\/\\* ?" + startComment + " ?\\*\\/[\\s\\S]*?\\/\\* ?" + endComment + " ?\\*\\/[\\t ]*\\n?",
|
||||
"g"
|
||||
);
|
||||
|
||||
function StripBlockLoader(content) {
|
||||
if (content.indexOf(startComment) >= 0) {
|
||||
content = content.replace(regexPattern, "");
|
||||
}
|
||||
if (this.cacheable) {
|
||||
this.cacheable(true);
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
module.exports = StripBlockLoader;
|
115
gulp/package.json
Normal file
@ -0,0 +1,115 @@
|
||||
{
|
||||
"name": "builder",
|
||||
"version": "1.0.0",
|
||||
"description": "builder",
|
||||
"private": true,
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
"gulp": "gulp"
|
||||
},
|
||||
"author": "tobspr",
|
||||
"license": "private",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.9.0",
|
||||
"@babel/plugin-transform-block-scoping": "^7.4.4",
|
||||
"@babel/plugin-transform-classes": "^7.5.5",
|
||||
"@babel/preset-env": "^7.5.4",
|
||||
"@types/cordova": "^0.0.34",
|
||||
"@types/filesystem": "^0.0.29",
|
||||
"@types/node": "^12.7.5",
|
||||
"ajv": "^6.10.2",
|
||||
"babel-loader": "^8.1.0",
|
||||
"browser-sync": "^2.24.6",
|
||||
"circular-dependency-plugin": "^5.0.2",
|
||||
"circular-json": "^0.5.9",
|
||||
"colors": "^1.3.3",
|
||||
"core-js": "3",
|
||||
"crypto": "^1.0.1",
|
||||
"cssnano-preset-advanced": "^4.0.7",
|
||||
"delete-empty": "^3.0.0",
|
||||
"email-validator": "^2.0.4",
|
||||
"eslint": "^5.9.0",
|
||||
"fastdom": "^1.0.9",
|
||||
"flatted": "^2.0.1",
|
||||
"fs-extra": "^8.1.0",
|
||||
"howler": "^2.1.2",
|
||||
"html-loader": "^0.5.5",
|
||||
"ignore-loader": "^0.1.2",
|
||||
"lz-string": "^1.4.4",
|
||||
"markdown-loader": "^5.1.0",
|
||||
"node-sri": "^1.1.1",
|
||||
"obfuscator-loader": "^1.1.2",
|
||||
"phonegap-plugin-mobile-accessibility": "^1.0.5",
|
||||
"promise-polyfill": "^8.1.0",
|
||||
"query-string": "^6.8.1",
|
||||
"rusha": "^0.8.13",
|
||||
"serialize-error": "^3.0.0",
|
||||
"sloc": "^0.2.1",
|
||||
"strictdom": "^1.0.1",
|
||||
"string-replace-webpack-plugin": "^0.1.3",
|
||||
"terser-webpack-plugin": "^1.1.0",
|
||||
"uglify-template-string-loader": "^1.1.0",
|
||||
"unused-files-webpack-plugin": "^3.4.0",
|
||||
"webpack": "^4.31.0",
|
||||
"webpack-bundle-analyzer": "^3.0.3",
|
||||
"webpack-cli": "^3.1.0",
|
||||
"webpack-deep-scope-plugin": "^1.6.0",
|
||||
"webpack-plugin-replace": "^1.1.1",
|
||||
"webpack-strip-block": "^0.2.0",
|
||||
"whatwg-fetch": "^3.0.0",
|
||||
"worker-loader": "^2.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "^9.4.3",
|
||||
"babel-plugin-closure-elimination": "^1.3.0",
|
||||
"babel-plugin-console-source": "^2.0.2",
|
||||
"babel-plugin-danger-remove-unused-import": "^1.1.2",
|
||||
"css-mqpacker": "^7.0.0",
|
||||
"cssnano": "^4.1.10",
|
||||
"electron-packager": "^14.0.6",
|
||||
"faster.js": "^1.1.0",
|
||||
"glob": "^7.1.3",
|
||||
"gulp": "^3.9.1",
|
||||
"gulp-cache": "^1.1.3",
|
||||
"gulp-cached": "^1.1.1",
|
||||
"gulp-clean": "^0.4.0",
|
||||
"gulp-cssbeautify": "^1.0.1",
|
||||
"gulp-csslint": "^1.0.1",
|
||||
"gulp-dom": "^1.0.0",
|
||||
"gulp-flatten": "^0.4.0",
|
||||
"gulp-fluent-ffmpeg": "^1.0.2",
|
||||
"gulp-html-beautify": "^1.0.1",
|
||||
"gulp-htmlmin": "^5.0.1",
|
||||
"gulp-if": "^2.0.2",
|
||||
"gulp-imagemin": "^5.0.3",
|
||||
"gulp-javascript-obfuscator": "^1.1.5",
|
||||
"gulp-jsbeautifier": "^3.0.0",
|
||||
"gulp-load-plugins": "^1.5.0",
|
||||
"gulp-multi-process": "^1.3.1",
|
||||
"gulp-phonegap-build": "^0.1.5",
|
||||
"gulp-plumber": "^1.2.1",
|
||||
"gulp-pngquant": "^1.0.12",
|
||||
"gulp-postcss": "^8.0.0",
|
||||
"gulp-rename": "^1.4.0",
|
||||
"gulp-sass": "^4.0.1",
|
||||
"gulp-sass-lint": "^1.4.0",
|
||||
"gulp-sequence": "^1.0.0",
|
||||
"gulp-sftp": "^0.1.5",
|
||||
"gulp-terser": "^1.2.0",
|
||||
"gulp-webserver": "^0.9.1",
|
||||
"imagemin-mozjpeg": "^8.0.0",
|
||||
"imagemin-pngquant": "^8.0.0",
|
||||
"jimp": "^0.6.1",
|
||||
"js-yaml": "^3.13.1",
|
||||
"onesky-fetch": "^0.0.7",
|
||||
"postcss-assets": "^5.0.0",
|
||||
"postcss-preset-env": "^6.5.0",
|
||||
"postcss-round-subpixels": "^1.2.0",
|
||||
"postcss-unprefix": "^2.1.3",
|
||||
"sass-unused": "^0.3.0",
|
||||
"speed-measure-webpack-plugin": "^1.3.1",
|
||||
"strip-json-comments": "^3.0.1",
|
||||
"trim": "^0.0.1",
|
||||
"webpack-stream": "^5.1.0"
|
||||
}
|
||||
}
|
107
gulp/sounds.js
Normal file
@ -0,0 +1,107 @@
|
||||
const path = require("path");
|
||||
|
||||
function gulptasksSounds($, gulp, buildFolder) {
|
||||
// Gather some basic infos
|
||||
const soundsDir = path.join("..", "res_raw", "sounds");
|
||||
const builtSoundsDir = path.join("..", "res_built", "sounds");
|
||||
|
||||
gulp.task("sounds.clear", () => {
|
||||
return gulp.src(builtSoundsDir).pipe($.clean({ force: true }));
|
||||
});
|
||||
|
||||
const filters = ["loudnorm", "volume=0.2"];
|
||||
|
||||
const fileCache = new $.cache.Cache({
|
||||
cacheDirName: "shapezio-precompiled-sounds",
|
||||
});
|
||||
|
||||
// Encodes the game music
|
||||
gulp.task("sounds.encodeMusic", () => {
|
||||
return gulp
|
||||
.src([path.join(soundsDir, "music", "**", "*.wav"), path.join(soundsDir, "music", "**", "*.mp3")])
|
||||
.pipe(
|
||||
$.cache(
|
||||
$.fluentFfmpeg("mp3", function (cmd) {
|
||||
return cmd
|
||||
.audioBitrate(48)
|
||||
.audioChannels(1)
|
||||
.audioFrequency(22050)
|
||||
.audioCodec("libmp3lame");
|
||||
// .audioFilters(["volume=0.25"])
|
||||
}),
|
||||
{
|
||||
name: "music",
|
||||
fileCache,
|
||||
}
|
||||
)
|
||||
)
|
||||
.pipe(gulp.dest(path.join(builtSoundsDir, "music")));
|
||||
});
|
||||
|
||||
// Encodes the ui sounds
|
||||
gulp.task("sounds.encodeUi", () => {
|
||||
return gulp
|
||||
.src([path.join(soundsDir, "ui", "**", "*.wav"), path.join(soundsDir, "ui", "**", "*.mp3")])
|
||||
.pipe(
|
||||
$.cache(
|
||||
$.fluentFfmpeg("mp3", function (cmd) {
|
||||
return cmd
|
||||
.audioBitrate(128)
|
||||
.audioChannels(1)
|
||||
.audioFrequency(22050)
|
||||
.audioCodec("libmp3lame")
|
||||
.audioFilters(filters);
|
||||
})
|
||||
),
|
||||
{
|
||||
name: "uisounds",
|
||||
fileCache,
|
||||
}
|
||||
)
|
||||
.pipe(gulp.dest(path.join(builtSoundsDir, "ui")));
|
||||
});
|
||||
|
||||
// Encodes the game sounds
|
||||
gulp.task("sounds.encodeGame", () => {
|
||||
return gulp
|
||||
.src([path.join(soundsDir, "game", "**", "*.wav"), path.join(soundsDir, "game", "**", "*.mp3")])
|
||||
.pipe(
|
||||
$.cache(
|
||||
$.fluentFfmpeg("mp3", function (cmd) {
|
||||
return cmd
|
||||
.audioBitrate(128)
|
||||
.audioChannels(1)
|
||||
.audioFrequency(22050)
|
||||
.audioCodec("libmp3lame")
|
||||
.audioFilters(filters);
|
||||
}),
|
||||
{
|
||||
nane: "gamesounds",
|
||||
fileCache,
|
||||
}
|
||||
)
|
||||
)
|
||||
.pipe(gulp.dest(path.join(builtSoundsDir, "game")));
|
||||
});
|
||||
|
||||
gulp.task("sounds.copy", () => {
|
||||
return gulp
|
||||
.src(path.join(builtSoundsDir, "**", "*.mp3"))
|
||||
.pipe($.cached("sounds.copy"))
|
||||
.pipe(gulp.dest(path.join(buildFolder, "res", "sounds")));
|
||||
});
|
||||
|
||||
gulp.task("sounds.buildall", cb =>
|
||||
$.multiProcess(["sounds.encodeMusic", "sounds.encodeUi", "sounds.encodeGame"], cb, true)
|
||||
);
|
||||
|
||||
gulp.task("sounds.fullbuild", cb => $.sequence("sounds.clear", "sounds.buildall", "sounds.copy")(cb));
|
||||
|
||||
gulp.task("sounds.dev", cb => {
|
||||
return $.sequence("sounds.buildall", "sounds.copy")(cb);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
gulptasksSounds,
|
||||
};
|
215
gulp/standalone.js
Normal file
@ -0,0 +1,215 @@
|
||||
const packager = require("electron-packager");
|
||||
const path = require("path");
|
||||
const buildutils = require("./buildutils");
|
||||
const fs = require("fs");
|
||||
const fse = require("fs-extra");
|
||||
const execSync = require("child_process").execSync;
|
||||
|
||||
function gulptasksStandalone($, gulp, buildFolder) {
|
||||
const electronBaseDir = path.join("../electron");
|
||||
|
||||
const tempDestDir = path.join("..", "tmp_standalone_files");
|
||||
const tempDestBuildDir = path.join(tempDestDir, "built");
|
||||
|
||||
gulp.task("standalone.prepare.cleanup", () => {
|
||||
return gulp.src(tempDestDir, { read: false }).pipe($.clean({ force: true }));
|
||||
});
|
||||
|
||||
gulp.task("standalone.prepare.copyPrefab", () => {
|
||||
// const requiredFiles = $.glob.sync("../electron/");
|
||||
const requiredFiles = [
|
||||
path.join(electronBaseDir, "lib", "**", "*.node"),
|
||||
path.join(electronBaseDir, "node_modules", "**", "*.*"),
|
||||
path.join(electronBaseDir, "node_modules", "**", ".*"),
|
||||
path.join(electronBaseDir, "node_modules", "**", "*"),
|
||||
path.join(electronBaseDir, "favicon*"),
|
||||
];
|
||||
return gulp.src(requiredFiles, { base: electronBaseDir }).pipe(gulp.dest(tempDestBuildDir));
|
||||
});
|
||||
|
||||
gulp.task("standalone.prepare.writePackageJson", () => {
|
||||
fs.writeFileSync(
|
||||
path.join(tempDestBuildDir, "package.json"),
|
||||
JSON.stringify(
|
||||
{
|
||||
devDependencies: {
|
||||
electron: "6.0.10",
|
||||
},
|
||||
},
|
||||
null,
|
||||
4
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
gulp.task("standalone.prepare.minifyCode", () => {
|
||||
return gulp
|
||||
.src(path.join(electronBaseDir, "*.js"))
|
||||
.pipe(
|
||||
$.terser({
|
||||
ecma: 6,
|
||||
parse: {},
|
||||
module: false,
|
||||
toplevel: true,
|
||||
keep_classnames: false,
|
||||
keep_fnames: false,
|
||||
safari10: false,
|
||||
compress: {
|
||||
arguments: false, // breaks
|
||||
drop_console: false,
|
||||
// keep_fargs: false,
|
||||
keep_infinity: true,
|
||||
passes: 2,
|
||||
module: false,
|
||||
toplevel: true,
|
||||
unsafe_math: true,
|
||||
unsafe_arrows: false,
|
||||
warnings: true,
|
||||
},
|
||||
mangle: {
|
||||
eval: true,
|
||||
keep_classnames: false,
|
||||
keep_fnames: false,
|
||||
module: false,
|
||||
toplevel: true,
|
||||
safari10: false,
|
||||
},
|
||||
output: {
|
||||
comments: false,
|
||||
ascii_only: true,
|
||||
beautify: false,
|
||||
braces: false,
|
||||
ecma: 6,
|
||||
},
|
||||
})
|
||||
)
|
||||
.pipe(gulp.dest(tempDestBuildDir));
|
||||
});
|
||||
|
||||
gulp.task("standalone.prepare.copyGamefiles", () => {
|
||||
return gulp.src("../../www/**/*.*", { base: "../../www" }).pipe(gulp.dest(tempDestBuildDir));
|
||||
});
|
||||
|
||||
gulp.task("standalone.killRunningInstances", () => {
|
||||
try {
|
||||
execSync("taskkill /F /IM shapezio.exe");
|
||||
} catch (ex) {
|
||||
console.warn("Failed to kill running instances, maybe none are up.");
|
||||
}
|
||||
});
|
||||
|
||||
gulp.task(
|
||||
"standalone.prepare",
|
||||
$.sequence(
|
||||
"standalone.killRunningInstances",
|
||||
"standalone.prepare.cleanup",
|
||||
"standalone.prepare.copyPrefab",
|
||||
"standalone.prepare.writePackageJson",
|
||||
"standalone.prepare.minifyCode",
|
||||
"standalone.prepare.copyGamefiles"
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {'win32'|'linux'|'darwin'} platform
|
||||
* @param {'x64'|'ia32'} arch
|
||||
* @param {function():void} cb
|
||||
* @param {boolean=} isRelease
|
||||
*/
|
||||
function packageStandalone(platform, arch, cb, isRelease = false) {
|
||||
const libDirName = (platform === "win32" ? "win" : platform) + (arch === "x64" ? "64" : "32");
|
||||
|
||||
const libDir = path.join(electronBaseDir, "lib", libDirName);
|
||||
if (!fs.existsSync(libDir)) {
|
||||
console.error("FATAL ERROR: LIB DIR does not exist:", libDir);
|
||||
cb();
|
||||
return;
|
||||
}
|
||||
|
||||
packager({
|
||||
dir: tempDestBuildDir,
|
||||
appCopyright: "Tobias Springer IT Solutions",
|
||||
appVersion: buildutils.getVersion(),
|
||||
buildVersion: "1.0.0",
|
||||
arch,
|
||||
platform,
|
||||
asar: true,
|
||||
executableName: "shapezio",
|
||||
icon: path.join(electronBaseDir, "favicon"),
|
||||
name: "Shapez.io Standalone",
|
||||
out: tempDestDir,
|
||||
overwrite: true,
|
||||
appBundleId: "io.shapez.standalone",
|
||||
appCategoryType: "public.app-category.games",
|
||||
}).then(
|
||||
appPaths => {
|
||||
console.log("Packages created:", appPaths);
|
||||
appPaths.forEach(appPath => {
|
||||
if (!fs.existsSync(appPath)) {
|
||||
console.error("Bad app path gotten:", appPath);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("Copying lib files to", appPath);
|
||||
const libFiles = $.glob.sync(path.join("**", "*.+(dylib|so|dll|lib)"), { cwd: libDir });
|
||||
libFiles.forEach(f => {
|
||||
console.log(" -> Copying", f);
|
||||
fs.copyFileSync(path.join(libDir, f), path.join(appPath, f));
|
||||
});
|
||||
|
||||
const playablePath = appPath + "_PLAYABLE";
|
||||
fse.copySync(appPath, playablePath);
|
||||
fs.writeFileSync(path.join(playablePath, "steam_appid.txt"), "1134480");
|
||||
fs.writeFileSync(
|
||||
path.join(playablePath, "play.bat"),
|
||||
"start shapezio --dev --disable-direct-composition --in-process-gpu\r\n"
|
||||
);
|
||||
fs.writeFileSync(
|
||||
path.join(playablePath, "play_local.bat"),
|
||||
"start shapezio --local --dev --disable-direct-composition --in-process-gpu\r\n"
|
||||
);
|
||||
});
|
||||
|
||||
cb();
|
||||
},
|
||||
err => {
|
||||
console.error("Packaging error:", err);
|
||||
cb();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// gulp.task("standalone.package.beta.win64", (cb) => packageStandalone("win32", "x64", cb));
|
||||
// gulp.task("standalone.package.beta.win32", (cb) => packageStandalone("win32", "ia32", cb));
|
||||
// gulp.task("standalone.package.beta.linux64", (cb) => packageStandalone("linux", "x64", cb));
|
||||
// gulp.task("standalone.package.beta.linux32", (cb) => packageStandalone("linux", "ia32", cb));
|
||||
// gulp.task("standalone.package.beta.darwin64", (cb) => packageStandalone("darwin", "x64", cb));
|
||||
|
||||
// gulp.task("standalone.package.beta", $.sequence("standalone.prepare", [
|
||||
// "standalone.package.beta.win64",
|
||||
// "standalone.package.beta.win32",
|
||||
// "standalone.package.beta.linux64",
|
||||
// "standalone.package.beta.linux32",
|
||||
// "standalone.package.beta.darwin64"
|
||||
// ]));
|
||||
|
||||
gulp.task("standalone.package.prod.win64", cb => packageStandalone("win32", "x64", cb, true));
|
||||
gulp.task("standalone.package.prod.win32", cb => packageStandalone("win32", "ia32", cb, true));
|
||||
gulp.task("standalone.package.prod.linux64", cb => packageStandalone("linux", "x64", cb, true));
|
||||
gulp.task("standalone.package.prod.linux32", cb => packageStandalone("linux", "ia32", cb, true));
|
||||
gulp.task("standalone.package.prod.darwin64", cb => packageStandalone("darwin", "x64", cb, true));
|
||||
|
||||
gulp.task(
|
||||
"standalone.package.prod",
|
||||
$.sequence("standalone.prepare", [
|
||||
"standalone.package.prod.win64",
|
||||
// "standalone.package.prod.win32",
|
||||
// "standalone.package.prod.linux64",
|
||||
// "standalone.package.prod.linux32",
|
||||
// "standalone.package.prod.darwin64"
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = { gulptasksStandalone };
|
59
gulp/tsconfig.json
Normal file
@ -0,0 +1,59 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
/* Basic Options */
|
||||
"target": "es6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */,
|
||||
"module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */,
|
||||
// "lib": [], /* Specify library files to be included in the compilation. */
|
||||
"allowJs": true /* Allow javascript files to be compiled. */,
|
||||
"checkJs": true /* Report errors in .js files. */,
|
||||
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
|
||||
// "declaration": true, /* Generates corresponding '.d.ts' file. */
|
||||
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
|
||||
// "sourceMap": true, /* Generates corresponding '.map' file. */
|
||||
// "outFile": "./typedefs_gen", /* Concatenate and emit output to single file. */
|
||||
// "outDir": "./typedefs_gen", /* Redirect output structure to the directory. */
|
||||
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
|
||||
// "composite": true, /* Enable project compilation */
|
||||
// "incremental": true, /* Enable incremental compilation */
|
||||
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
|
||||
// "removeComments": true, /* Do not emit comments to output. */
|
||||
"noEmit": true /* Do not emit outputs. */,
|
||||
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
|
||||
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
|
||||
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
|
||||
/* Strict Type-Checking Options */
|
||||
// "strict": true, /* Enable all strict type-checking options. */
|
||||
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
|
||||
// "strictNullChecks": true, /* Enable strict null checks. */
|
||||
"strictFunctionTypes": true /* Enable strict checking of function types. */,
|
||||
"strictBindCallApply": true /* Enable strict 'bind', 'call', and 'apply' methods on functions. */,
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
"noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */,
|
||||
"alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */,
|
||||
/* Additional Checks */
|
||||
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
|
||||
"noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */,
|
||||
/* Module Resolution Options */
|
||||
"moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
|
||||
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
|
||||
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
|
||||
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
|
||||
// "typeRoots": [], /* List of folders to include type definitions from. */
|
||||
// "types": [], /* Type declaration files to be included in compilation. */
|
||||
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
|
||||
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
|
||||
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
|
||||
/* Source Map Options */
|
||||
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
|
||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
|
||||
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
|
||||
/* Experimental Options */
|
||||
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
|
||||
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"exclude": ["backend/shared/gameserver_base_impl"]
|
||||
}
|
116
gulp/webpack.config.js
Normal file
@ -0,0 +1,116 @@
|
||||
const path = require("path");
|
||||
const webpack = require("webpack");
|
||||
const utils = require("./buildutils");
|
||||
const lzString = require("lz-string");
|
||||
// const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
|
||||
const CircularDependencyPlugin = require("circular-dependency-plugin");
|
||||
|
||||
module.exports = ({ watch = false, standalone = false }) => {
|
||||
return {
|
||||
mode: "development",
|
||||
devtool: "cheap-source-map",
|
||||
entry: {
|
||||
"bundle.js": [path.resolve(__dirname, "../src/js/main.js")],
|
||||
},
|
||||
watch,
|
||||
node: {
|
||||
fs: "empty",
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
"global-compression": path.resolve(__dirname, "..", "src", "js", "core", "lzstring.js"),
|
||||
},
|
||||
},
|
||||
context: path.resolve(__dirname, ".."),
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
assert: "window.assert",
|
||||
assertAlways: "window.assert",
|
||||
abstract:
|
||||
"window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));",
|
||||
G_HAVE_ASSERT: "true",
|
||||
G_APP_ENVIRONMENT: JSON.stringify("dev"),
|
||||
G_API_ENDPOINT: JSON.stringify(
|
||||
lzString.compressToEncodedURIComponent("http://localhost:5005/v1")
|
||||
),
|
||||
G_TRACKING_ENDPOINT: JSON.stringify(
|
||||
lzString.compressToEncodedURIComponent("http://localhost:10005/v1")
|
||||
),
|
||||
G_IS_DEV: "true",
|
||||
G_IS_PROD: "false",
|
||||
G_IS_RELEASE: "false",
|
||||
G_IS_MOBILE_APP: "false",
|
||||
G_IS_BROWSER: "true",
|
||||
G_IS_STANDALONE: standalone ? "true" : "false",
|
||||
G_BUILD_TIME: "" + new Date().getTime(),
|
||||
G_BUILD_COMMIT_HASH: JSON.stringify(utils.getRevision()),
|
||||
G_BUILD_VERSION: JSON.stringify(utils.getVersion()),
|
||||
G_ALL_UI_IMAGES: JSON.stringify(utils.getAllResourceImages()),
|
||||
}),
|
||||
|
||||
new CircularDependencyPlugin({
|
||||
// exclude detection of files based on a RegExp
|
||||
exclude: /node_modules/,
|
||||
|
||||
// add errors to webpack instead of warnings
|
||||
failOnError: true,
|
||||
|
||||
// allow import cycles that include an asyncronous import,
|
||||
// e.g. via import(/* webpackMode: "weak" */ './file.js')
|
||||
allowAsyncCycles: false,
|
||||
|
||||
// set the current working directory for displaying module paths
|
||||
cwd: path.join(__dirname, "..", "src", "js"),
|
||||
}),
|
||||
// new BundleAnalyzerPlugin()
|
||||
],
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.json$/,
|
||||
enforce: "pre",
|
||||
use: ["./gulp/loader.compressjson"],
|
||||
type: "javascript/auto",
|
||||
},
|
||||
{ test: /\.(png|jpe?g|svg)$/, loader: "ignore-loader" },
|
||||
{
|
||||
test: /\.md$/,
|
||||
use: [
|
||||
{
|
||||
loader: "html-loader",
|
||||
},
|
||||
"markdown-loader",
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
enforce: "pre",
|
||||
exclude: /node_modules/,
|
||||
use: [
|
||||
{
|
||||
loader: "webpack-strip-block",
|
||||
options: {
|
||||
start: "typehints:start",
|
||||
end: "typehints:end",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.worker\.js$/,
|
||||
use: {
|
||||
loader: "worker-loader",
|
||||
options: {
|
||||
fallback: false,
|
||||
inline: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
output: {
|
||||
filename: "bundle.js",
|
||||
path: path.resolve(__dirname, "..", "build"),
|
||||
},
|
||||
};
|
||||
};
|
258
gulp/webpack.production.config.js
Normal file
@ -0,0 +1,258 @@
|
||||
const path = require("path");
|
||||
const webpack = require("webpack");
|
||||
const utils = require("./buildutils");
|
||||
const lzString = require("lz-string");
|
||||
|
||||
const TerserPlugin = require("terser-webpack-plugin");
|
||||
const StringReplacePlugin = require("string-replace-webpack-plugin");
|
||||
// const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
|
||||
const UnusedFilesPlugin = require("unused-files-webpack-plugin").UnusedFilesWebpackPlugin;
|
||||
// const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
|
||||
|
||||
module.exports = ({
|
||||
enableAssert = false,
|
||||
apiEndpoint,
|
||||
environment,
|
||||
es6 = false,
|
||||
standalone = false,
|
||||
isBrowser = true,
|
||||
mobileApp = false,
|
||||
}) => {
|
||||
const globalDefs = {
|
||||
assert: enableAssert ? "window.assert" : "false && window.assert",
|
||||
assertAlways: "window.assert",
|
||||
abstract: "window.assert(false, 'abstract method called');",
|
||||
G_IS_DEV: "false",
|
||||
G_IS_PROD: "true",
|
||||
G_IS_RELEASE: environment === "prod" ? "true" : "false",
|
||||
G_IS_STANDALONE: standalone ? "true" : "false",
|
||||
G_IS_BROWSER: isBrowser ? "true" : "false",
|
||||
G_IS_MOBILE_APP: mobileApp ? "true" : "false",
|
||||
G_API_ENDPOINT: JSON.stringify(lzString.compressToEncodedURIComponent(apiEndpoint)),
|
||||
G_TRACKING_ENDPOINT: JSON.stringify(
|
||||
lzString.compressToEncodedURIComponent("https://tracking.shapez.io/v1")
|
||||
),
|
||||
G_APP_ENVIRONMENT: JSON.stringify(environment),
|
||||
G_HAVE_ASSERT: enableAssert ? "true" : "false",
|
||||
G_BUILD_TIME: "" + new Date().getTime(),
|
||||
G_BUILD_COMMIT_HASH: JSON.stringify(utils.getRevision()),
|
||||
G_BUILD_VERSION: JSON.stringify(utils.getVersion()),
|
||||
G_ALL_UI_IMAGES: JSON.stringify(utils.getAllResourceImages()),
|
||||
};
|
||||
|
||||
return {
|
||||
mode: "production",
|
||||
devtool: false,
|
||||
entry: {
|
||||
"bundle.js": [path.resolve(__dirname, "..", "src", "js", "main.js")],
|
||||
},
|
||||
node: {
|
||||
fs: "empty",
|
||||
},
|
||||
output: {
|
||||
filename: "bundle.js",
|
||||
path: path.resolve(__dirname, "..", "build"),
|
||||
},
|
||||
context: path.resolve(__dirname, ".."),
|
||||
stats: {
|
||||
// Examine all modules
|
||||
maxModules: Infinity,
|
||||
// Display bailout reasons
|
||||
optimizationBailout: true,
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
"global-compression": path.resolve(__dirname, "..", "src", "js", "core", "lzstring.js"),
|
||||
},
|
||||
},
|
||||
optimization: {
|
||||
minimize: true,
|
||||
// namedModules: true,
|
||||
|
||||
noEmitOnErrors: true,
|
||||
removeAvailableModules: true,
|
||||
removeEmptyChunks: true,
|
||||
mergeDuplicateChunks: true,
|
||||
flagIncludedChunks: true,
|
||||
occurrenceOrder: true,
|
||||
providedExports: true,
|
||||
usedExports: true,
|
||||
concatenateModules: true,
|
||||
sideEffects: true,
|
||||
|
||||
minimizer: [
|
||||
new TerserPlugin({
|
||||
parallel: true,
|
||||
sourceMap: false,
|
||||
cache: false,
|
||||
terserOptions: {
|
||||
ecma: es6 ? 6 : 5,
|
||||
parse: {},
|
||||
module: true,
|
||||
toplevel: true,
|
||||
keep_classnames: false,
|
||||
keep_fnames: false,
|
||||
keep_fargs: false,
|
||||
safari10: true,
|
||||
compress: {
|
||||
arguments: false, // breaks
|
||||
drop_console: false,
|
||||
global_defs: globalDefs,
|
||||
keep_fargs: false,
|
||||
keep_infinity: true,
|
||||
passes: 2,
|
||||
module: true,
|
||||
pure_funcs: [
|
||||
"Math.round",
|
||||
"Math.ceil",
|
||||
"Math.floor",
|
||||
"Math.sqrt",
|
||||
"Math.hypot",
|
||||
"Math.abs",
|
||||
"Math.max",
|
||||
"Math.min",
|
||||
"Math.sin",
|
||||
"Math.cos",
|
||||
"Math.tan",
|
||||
"Math.sign",
|
||||
"Math.pow",
|
||||
"Math.atan2",
|
||||
|
||||
"Math_round",
|
||||
"Math_ceil",
|
||||
"Math_floor",
|
||||
"Math_sqrt",
|
||||
"Math_hypot",
|
||||
"Math_abs",
|
||||
"Math_max",
|
||||
"Math_min",
|
||||
"Math_sin",
|
||||
"Math_cos",
|
||||
"Math_tan",
|
||||
"Math_sign",
|
||||
"Math_pow",
|
||||
"Math_atan2",
|
||||
],
|
||||
toplevel: true,
|
||||
unsafe_math: true,
|
||||
unsafe_arrows: false,
|
||||
warnings: true,
|
||||
},
|
||||
mangle: {
|
||||
eval: true,
|
||||
keep_classnames: false,
|
||||
keep_fnames: false,
|
||||
module: true,
|
||||
toplevel: true,
|
||||
safari10: true,
|
||||
},
|
||||
output: {
|
||||
comments: false,
|
||||
ascii_only: true,
|
||||
beautify: false,
|
||||
braces: false,
|
||||
ecma: es6 ? 6 : 5,
|
||||
preamble:
|
||||
"/* Shapez.io Codebase - Copyright 2020 Tobias Springer - " +
|
||||
utils.getVersion() +
|
||||
" @ " +
|
||||
utils.getRevision() +
|
||||
" */",
|
||||
},
|
||||
},
|
||||
}),
|
||||
],
|
||||
},
|
||||
performance: {
|
||||
maxEntrypointSize: 5120000,
|
||||
maxAssetSize: 5120000,
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin(globalDefs),
|
||||
|
||||
new UnusedFilesPlugin({
|
||||
failOnUnused: false,
|
||||
cwd: path.join(__dirname, "..", "src", "js"),
|
||||
patterns: ["../src/js/**/*.js"],
|
||||
}),
|
||||
|
||||
// new ReplaceCompressBlocks()
|
||||
// new webpack.optimize.ModuleConcatenationPlugin()
|
||||
// new WebpackDeepScopeAnalysisPlugin()
|
||||
// new BundleAnalyzerPlugin()
|
||||
],
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.json$/,
|
||||
enforce: "pre",
|
||||
use: ["./gulp/loader.compressjson"],
|
||||
type: "javascript/auto",
|
||||
},
|
||||
{ test: /\.(png|jpe?g|svg)$/, loader: "ignore-loader" },
|
||||
{
|
||||
test: /\.js$/,
|
||||
enforce: "pre",
|
||||
exclude: /node_modules/,
|
||||
use: [
|
||||
{
|
||||
loader: "webpack-strip-block",
|
||||
options: {
|
||||
start: "typehints:start",
|
||||
end: "typehints:end",
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: "webpack-strip-block",
|
||||
options: {
|
||||
start: "dev:start",
|
||||
end: "dev:end",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
use: [
|
||||
// "thread-loader",
|
||||
{
|
||||
loader: "babel-loader?cacheDirectory",
|
||||
options: {
|
||||
configFile: require.resolve(
|
||||
es6 ? "./babel-es6.config.js" : "./babel.config.js"
|
||||
),
|
||||
},
|
||||
},
|
||||
"uglify-template-string-loader", // Finally found this plugin
|
||||
StringReplacePlugin.replace({
|
||||
replacements: [
|
||||
{ pattern: /globalConfig\.tileSize/g, replacement: () => "32" },
|
||||
{ pattern: /globalConfig\.halfTileSize/g, replacement: () => "16" },
|
||||
{
|
||||
pattern: /globalConfig\.beltSpeedItemsPerSecond/g,
|
||||
replacement: () => "1.0",
|
||||
},
|
||||
{ pattern: /globalConfig\.itemSpacingOnBelts/g, replacement: () => "0.8" },
|
||||
{ pattern: /globalConfig\.debug/g, replacement: () => "''" },
|
||||
],
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.worker\.js$/,
|
||||
use: {
|
||||
loader: "worker-loader",
|
||||
options: {
|
||||
fallback: false,
|
||||
inline: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.md$/,
|
||||
use: ["html-loader", "markdown-loader"],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
};
|
14195
gulp/yarn.lock
Normal file
7
jsconfig.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es6",
|
||||
"checkJs": true,
|
||||
|
||||
}
|
||||
}
|
84
package.json
Normal file
@ -0,0 +1,84 @@
|
||||
{
|
||||
"name": "shapez.io",
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"repository": "https://github.com/tobspr/shapez.io",
|
||||
"author": "Tobias Springer <tobias.springer1@gmail.com>",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "./gulp/gulp main.serveDev",
|
||||
"prettier-all": "prettier --write src/**/*.* && prettier --write gulp/**/*.*"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.5.4",
|
||||
"@babel/plugin-transform-block-scoping": "^7.4.4",
|
||||
"@babel/plugin-transform-classes": "^7.5.5",
|
||||
"@babel/preset-env": "^7.5.4",
|
||||
"@types/cordova": "^0.0.34",
|
||||
"@types/filesystem": "^0.0.29",
|
||||
"ajv": "^6.10.2",
|
||||
"babel-loader": "^8.0.4",
|
||||
"browser-sync": "^2.24.6",
|
||||
"circular-dependency-plugin": "^5.0.2",
|
||||
"circular-json": "^0.5.9",
|
||||
"clipboard-copy": "^3.1.0",
|
||||
"colors": "^1.3.3",
|
||||
"core-js": "3",
|
||||
"cssnano-preset-advanced": "^4.0.7",
|
||||
"email-validator": "^2.0.4",
|
||||
"eslint": "^5.9.0",
|
||||
"fastdom": "^1.0.8",
|
||||
"flatted": "^2.0.1",
|
||||
"howler": "^2.1.2",
|
||||
"html-loader": "^0.5.5",
|
||||
"ignore-loader": "^0.1.2",
|
||||
"lz-string": "^1.4.4",
|
||||
"markdown-loader": "^4.0.0",
|
||||
"obfuscator-loader": "^1.1.2",
|
||||
"phonegap-plugin-mobile-accessibility": "^1.0.5",
|
||||
"promise-polyfill": "^8.1.0",
|
||||
"query-string": "^6.8.1",
|
||||
"rusha": "^0.8.13",
|
||||
"serialize-error": "^3.0.0",
|
||||
"sloc": "^0.2.1",
|
||||
"strictdom": "^1.0.1",
|
||||
"string-replace-webpack-plugin": "^0.1.3",
|
||||
"terser-webpack-plugin": "^1.1.0",
|
||||
"uglify-template-string-loader": "^1.1.0",
|
||||
"unused-files-webpack-plugin": "^3.4.0",
|
||||
"webpack": "^4.31.0",
|
||||
"webpack-bundle-analyzer": "^3.0.3",
|
||||
"webpack-cli": "^3.1.0",
|
||||
"webpack-deep-scope-plugin": "^1.6.0",
|
||||
"webpack-plugin-replace": "^1.1.1",
|
||||
"webpack-strip-block": "^0.2.0",
|
||||
"whatwg-fetch": "^3.0.0",
|
||||
"worker-loader": "^2.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "^9.4.3",
|
||||
"babel-plugin-closure-elimination": "^1.3.0",
|
||||
"babel-plugin-console-source": "^2.0.2",
|
||||
"babel-plugin-danger-remove-unused-import": "^1.1.2",
|
||||
"css-mqpacker": "^7.0.0",
|
||||
"cssnano": "^4.1.10",
|
||||
"faster.js": "^1.1.0",
|
||||
"glob": "^7.1.3",
|
||||
"imagemin-mozjpeg": "^8.0.0",
|
||||
"imagemin-pngquant": "^8.0.0",
|
||||
"jimp": "^0.6.1",
|
||||
"js-yaml": "^3.13.1",
|
||||
"onesky-fetch": "^0.0.7",
|
||||
"postcss-assets": "^5.0.0",
|
||||
"postcss-preset-env": "^6.5.0",
|
||||
"postcss-round-subpixels": "^1.2.0",
|
||||
"postcss-unprefix": "^2.1.3",
|
||||
"prettier": "^2.0.4",
|
||||
"sass-unused": "^0.3.0",
|
||||
"speed-measure-webpack-plugin": "^1.3.1",
|
||||
"strip-json-comments": "^3.0.1",
|
||||
"trim": "^0.0.1",
|
||||
"webpack-stream": "^5.1.0"
|
||||
}
|
||||
}
|
BIN
res/fonts/LouisGeorgeCafe.woff2
Normal file
BIN
res/logo.png
Normal file
After Width: | Height: | Size: 62 KiB |
BIN
res/ui/building_tutorials/belt.png
Normal file
After Width: | Height: | Size: 43 KiB |
BIN
res/ui/building_tutorials/cutter.png
Normal file
After Width: | Height: | Size: 62 KiB |
BIN
res/ui/building_tutorials/miner.png
Normal file
After Width: | Height: | Size: 71 KiB |
BIN
res/ui/building_tutorials/mixer.png
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
res/ui/building_tutorials/painter.png
Normal file
After Width: | Height: | Size: 37 KiB |
BIN
res/ui/building_tutorials/rotater.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
res/ui/building_tutorials/splitter.png
Normal file
After Width: | Height: | Size: 81 KiB |
BIN
res/ui/building_tutorials/stacker.png
Normal file
After Width: | Height: | Size: 55 KiB |
BIN
res/ui/building_tutorials/trash.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
res/ui/building_tutorials/underground_belt.png
Normal file
After Width: | Height: | Size: 87 KiB |
BIN
res/ui/dialog_bg_pattern.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
res/ui/icons/close.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
res/ui/icons/mouse_left.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
res/ui/icons/mouse_right.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
res/ui/icons/shop.png
Normal file
After Width: | Height: | Size: 877 B |
BIN
res/ui/icons/statistics.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
6
res/ui/loading.svg
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="margin: auto; background: none; display: block; shape-rendering: auto;" width="200px" height="200px" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
|
||||
<circle cx="50" cy="50" fill="none" stroke="#393747" stroke-width="3" r="42" stroke-dasharray="197.92033717615698 67.97344572538566" transform="rotate(48.2654 50 50)">
|
||||
<animateTransform attributeName="transform" type="rotate" repeatCount="indefinite" dur="5.555555555555555s" values="0 50 50;360 50 50" keyTimes="0;1"></animateTransform>
|
||||
</circle>
|
||||
<!-- [ldio] generated by https://loading.io/ --></svg>
|
After Width: | Height: | Size: 688 B |
BIN
res/ui/locked_building.png
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
res/ui/menu_bg.noinline.jpg
Normal file
After Width: | Height: | Size: 510 KiB |
BIN
res/ui/sad_ghost.png
Normal file
After Width: | Height: | Size: 6.6 KiB |
BIN
res/ui/upgrades/belt.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
res/ui/upgrades/miner.png
Normal file
After Width: | Height: | Size: 940 B |
BIN
res/ui/upgrades/painting.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
res/ui/upgrades/processors.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
417
res_raw/atlas.tps
Normal file
@ -0,0 +1,417 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<data version="1.0">
|
||||
<struct type="Settings">
|
||||
<key>fileFormatVersion</key>
|
||||
<int>4</int>
|
||||
<key>texturePackerVersion</key>
|
||||
<string>5.3.0</string>
|
||||
<key>autoSDSettings</key>
|
||||
<array>
|
||||
<struct type="AutoSDSettings">
|
||||
<key>scale</key>
|
||||
<double>1</double>
|
||||
<key>extension</key>
|
||||
<string>_100</string>
|
||||
<key>spriteFilter</key>
|
||||
<string></string>
|
||||
<key>acceptFractionalValues</key>
|
||||
<false/>
|
||||
<key>maxTextureSize</key>
|
||||
<QSize>
|
||||
<key>width</key>
|
||||
<int>-1</int>
|
||||
<key>height</key>
|
||||
<int>-1</int>
|
||||
</QSize>
|
||||
</struct>
|
||||
<struct type="AutoSDSettings">
|
||||
<key>scale</key>
|
||||
<double>0.75</double>
|
||||
<key>extension</key>
|
||||
<string>_75</string>
|
||||
<key>spriteFilter</key>
|
||||
<string></string>
|
||||
<key>acceptFractionalValues</key>
|
||||
<false/>
|
||||
<key>maxTextureSize</key>
|
||||
<QSize>
|
||||
<key>width</key>
|
||||
<int>-1</int>
|
||||
<key>height</key>
|
||||
<int>-1</int>
|
||||
</QSize>
|
||||
</struct>
|
||||
<struct type="AutoSDSettings">
|
||||
<key>scale</key>
|
||||
<double>0.5</double>
|
||||
<key>extension</key>
|
||||
<string>_50</string>
|
||||
<key>spriteFilter</key>
|
||||
<string></string>
|
||||
<key>acceptFractionalValues</key>
|
||||
<false/>
|
||||
<key>maxTextureSize</key>
|
||||
<QSize>
|
||||
<key>width</key>
|
||||
<int>-1</int>
|
||||
<key>height</key>
|
||||
<int>-1</int>
|
||||
</QSize>
|
||||
</struct>
|
||||
<struct type="AutoSDSettings">
|
||||
<key>scale</key>
|
||||
<double>0.25</double>
|
||||
<key>extension</key>
|
||||
<string>_25</string>
|
||||
<key>spriteFilter</key>
|
||||
<string></string>
|
||||
<key>acceptFractionalValues</key>
|
||||
<false/>
|
||||
<key>maxTextureSize</key>
|
||||
<QSize>
|
||||
<key>width</key>
|
||||
<int>-1</int>
|
||||
<key>height</key>
|
||||
<int>-1</int>
|
||||
</QSize>
|
||||
</struct>
|
||||
<struct type="AutoSDSettings">
|
||||
<key>scale</key>
|
||||
<double>0.1</double>
|
||||
<key>extension</key>
|
||||
<string>_10</string>
|
||||
<key>spriteFilter</key>
|
||||
<string></string>
|
||||
<key>acceptFractionalValues</key>
|
||||
<false/>
|
||||
<key>maxTextureSize</key>
|
||||
<QSize>
|
||||
<key>width</key>
|
||||
<int>-1</int>
|
||||
<key>height</key>
|
||||
<int>-1</int>
|
||||
</QSize>
|
||||
</struct>
|
||||
</array>
|
||||
<key>allowRotation</key>
|
||||
<false/>
|
||||
<key>shapeDebug</key>
|
||||
<false/>
|
||||
<key>dpi</key>
|
||||
<uint>72</uint>
|
||||
<key>dataFormat</key>
|
||||
<string>json</string>
|
||||
<key>textureFileName</key>
|
||||
<filename></filename>
|
||||
<key>flipPVR</key>
|
||||
<false/>
|
||||
<key>pvrCompressionQuality</key>
|
||||
<enum type="SettingsBase::PvrCompressionQuality">PVR_QUALITY_NORMAL</enum>
|
||||
<key>atfCompressData</key>
|
||||
<false/>
|
||||
<key>mipMapMinSize</key>
|
||||
<uint>32768</uint>
|
||||
<key>etc1CompressionQuality</key>
|
||||
<enum type="SettingsBase::Etc1CompressionQuality">ETC1_QUALITY_LOW_PERCEPTUAL</enum>
|
||||
<key>etc2CompressionQuality</key>
|
||||
<enum type="SettingsBase::Etc2CompressionQuality">ETC2_QUALITY_LOW_PERCEPTUAL</enum>
|
||||
<key>dxtCompressionMode</key>
|
||||
<enum type="SettingsBase::DxtCompressionMode">DXT_PERCEPTUAL</enum>
|
||||
<key>jxrColorFormat</key>
|
||||
<enum type="SettingsBase::JpegXrColorMode">JXR_YUV444</enum>
|
||||
<key>jxrTrimFlexBits</key>
|
||||
<uint>0</uint>
|
||||
<key>jxrCompressionLevel</key>
|
||||
<uint>0</uint>
|
||||
<key>ditherType</key>
|
||||
<enum type="SettingsBase::DitherType">NearestNeighbour</enum>
|
||||
<key>backgroundColor</key>
|
||||
<uint>0</uint>
|
||||
<key>libGdx</key>
|
||||
<struct type="LibGDX">
|
||||
<key>filtering</key>
|
||||
<struct type="LibGDXFiltering">
|
||||
<key>x</key>
|
||||
<enum type="LibGDXFiltering::Filtering">Linear</enum>
|
||||
<key>y</key>
|
||||
<enum type="LibGDXFiltering::Filtering">Linear</enum>
|
||||
</struct>
|
||||
</struct>
|
||||
<key>shapePadding</key>
|
||||
<uint>0</uint>
|
||||
<key>jpgQuality</key>
|
||||
<uint>80</uint>
|
||||
<key>pngOptimizationLevel</key>
|
||||
<uint>0</uint>
|
||||
<key>webpQualityLevel</key>
|
||||
<uint>101</uint>
|
||||
<key>textureSubPath</key>
|
||||
<string></string>
|
||||
<key>atfFormats</key>
|
||||
<string></string>
|
||||
<key>textureFormat</key>
|
||||
<enum type="SettingsBase::TextureFormat">png</enum>
|
||||
<key>borderPadding</key>
|
||||
<uint>1</uint>
|
||||
<key>maxTextureSize</key>
|
||||
<QSize>
|
||||
<key>width</key>
|
||||
<int>4096</int>
|
||||
<key>height</key>
|
||||
<int>4096</int>
|
||||
</QSize>
|
||||
<key>fixedTextureSize</key>
|
||||
<QSize>
|
||||
<key>width</key>
|
||||
<int>-1</int>
|
||||
<key>height</key>
|
||||
<int>-1</int>
|
||||
</QSize>
|
||||
<key>algorithmSettings</key>
|
||||
<struct type="AlgorithmSettings">
|
||||
<key>algorithm</key>
|
||||
<enum type="AlgorithmSettings::AlgorithmId">MaxRects</enum>
|
||||
<key>freeSizeMode</key>
|
||||
<enum type="AlgorithmSettings::AlgorithmFreeSizeMode">Best</enum>
|
||||
<key>sizeConstraints</key>
|
||||
<enum type="AlgorithmSettings::SizeConstraints">AnySize</enum>
|
||||
<key>forceSquared</key>
|
||||
<false/>
|
||||
<key>maxRects</key>
|
||||
<struct type="AlgorithmMaxRectsSettings">
|
||||
<key>heuristic</key>
|
||||
<enum type="AlgorithmMaxRectsSettings::Heuristic">Best</enum>
|
||||
</struct>
|
||||
<key>basic</key>
|
||||
<struct type="AlgorithmBasicSettings">
|
||||
<key>sortBy</key>
|
||||
<enum type="AlgorithmBasicSettings::SortBy">Best</enum>
|
||||
<key>order</key>
|
||||
<enum type="AlgorithmBasicSettings::Order">Ascending</enum>
|
||||
</struct>
|
||||
<key>polygon</key>
|
||||
<struct type="AlgorithmPolygonSettings">
|
||||
<key>alignToGrid</key>
|
||||
<uint>1</uint>
|
||||
</struct>
|
||||
</struct>
|
||||
<key>dataFileNames</key>
|
||||
<map type="GFileNameMap">
|
||||
<key>data</key>
|
||||
<struct type="DataFile">
|
||||
<key>name</key>
|
||||
<filename>../res_built/atlas/atlas{n}{v}.json</filename>
|
||||
</struct>
|
||||
</map>
|
||||
<key>multiPack</key>
|
||||
<true/>
|
||||
<key>forceIdenticalLayout</key>
|
||||
<false/>
|
||||
<key>outputFormat</key>
|
||||
<enum type="SettingsBase::OutputFormat">RGBA8888</enum>
|
||||
<key>alphaHandling</key>
|
||||
<enum type="SettingsBase::AlphaHandling">ClearTransparentPixels</enum>
|
||||
<key>contentProtection</key>
|
||||
<struct type="ContentProtection">
|
||||
<key>key</key>
|
||||
<string></string>
|
||||
</struct>
|
||||
<key>autoAliasEnabled</key>
|
||||
<true/>
|
||||
<key>trimSpriteNames</key>
|
||||
<false/>
|
||||
<key>prependSmartFolderName</key>
|
||||
<true/>
|
||||
<key>autodetectAnimations</key>
|
||||
<true/>
|
||||
<key>globalSpriteSettings</key>
|
||||
<struct type="SpriteSettings">
|
||||
<key>scale</key>
|
||||
<double>1</double>
|
||||
<key>scaleMode</key>
|
||||
<enum type="ScaleMode">Smooth</enum>
|
||||
<key>extrude</key>
|
||||
<uint>2</uint>
|
||||
<key>trimThreshold</key>
|
||||
<uint>2</uint>
|
||||
<key>trimMargin</key>
|
||||
<uint>1</uint>
|
||||
<key>trimMode</key>
|
||||
<enum type="SpriteSettings::TrimMode">Trim</enum>
|
||||
<key>tracerTolerance</key>
|
||||
<int>200</int>
|
||||
<key>heuristicMask</key>
|
||||
<false/>
|
||||
<key>defaultPivotPoint</key>
|
||||
<point_f>0.5,0.5</point_f>
|
||||
<key>writePivotPoints</key>
|
||||
<false/>
|
||||
</struct>
|
||||
<key>individualSpriteSettings</key>
|
||||
<map type="IndividualSpriteSettingsMap">
|
||||
<key type="filename">sprites/belt/forward_0.png</key>
|
||||
<key type="filename">sprites/belt/forward_1.png</key>
|
||||
<key type="filename">sprites/belt/forward_2.png</key>
|
||||
<key type="filename">sprites/buildings/miner.png</key>
|
||||
<key type="filename">sprites/buildings/rotater.png</key>
|
||||
<key type="filename">sprites/buildings/trash.png</key>
|
||||
<struct type="IndividualSpriteSettings">
|
||||
<key>pivotPoint</key>
|
||||
<point_f>0.5,0.5</point_f>
|
||||
<key>spriteScale</key>
|
||||
<double>1</double>
|
||||
<key>scale9Enabled</key>
|
||||
<false/>
|
||||
<key>scale9Borders</key>
|
||||
<rect>32,32,64,64</rect>
|
||||
<key>scale9Paddings</key>
|
||||
<rect>32,32,64,64</rect>
|
||||
<key>scale9FromFile</key>
|
||||
<false/>
|
||||
</struct>
|
||||
<key type="filename">sprites/belt/forward_3.png</key>
|
||||
<key type="filename">sprites/belt/forward_4.png</key>
|
||||
<key type="filename">sprites/belt/forward_5.png</key>
|
||||
<key type="filename">sprites/belt/left_0.png</key>
|
||||
<key type="filename">sprites/belt/left_1.png</key>
|
||||
<key type="filename">sprites/belt/left_2.png</key>
|
||||
<key type="filename">sprites/belt/left_3.png</key>
|
||||
<key type="filename">sprites/belt/left_4.png</key>
|
||||
<key type="filename">sprites/belt/left_5.png</key>
|
||||
<key type="filename">sprites/belt/right_0.png</key>
|
||||
<key type="filename">sprites/belt/right_1.png</key>
|
||||
<key type="filename">sprites/belt/right_2.png</key>
|
||||
<key type="filename">sprites/belt/right_3.png</key>
|
||||
<key type="filename">sprites/belt/right_4.png</key>
|
||||
<key type="filename">sprites/belt/right_5.png</key>
|
||||
<key type="filename">sprites/buildings/belt_left.png</key>
|
||||
<key type="filename">sprites/buildings/belt_right.png</key>
|
||||
<key type="filename">sprites/buildings/belt_top.png</key>
|
||||
<struct type="IndividualSpriteSettings">
|
||||
<key>pivotPoint</key>
|
||||
<point_f>0.5,0.5</point_f>
|
||||
<key>spriteScale</key>
|
||||
<double>1</double>
|
||||
<key>scale9Enabled</key>
|
||||
<false/>
|
||||
<key>scale9Borders</key>
|
||||
<rect>32,32,63,63</rect>
|
||||
<key>scale9Paddings</key>
|
||||
<rect>32,32,63,63</rect>
|
||||
<key>scale9FromFile</key>
|
||||
<false/>
|
||||
</struct>
|
||||
<key type="filename">sprites/buildings/cutter.png</key>
|
||||
<key type="filename">sprites/buildings/mixer.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>
|
||||
<struct type="IndividualSpriteSettings">
|
||||
<key>pivotPoint</key>
|
||||
<point_f>0.5,0.5</point_f>
|
||||
<key>spriteScale</key>
|
||||
<double>1</double>
|
||||
<key>scale9Enabled</key>
|
||||
<false/>
|
||||
<key>scale9Borders</key>
|
||||
<rect>64,32,128,64</rect>
|
||||
<key>scale9Paddings</key>
|
||||
<rect>64,32,128,64</rect>
|
||||
<key>scale9FromFile</key>
|
||||
<false/>
|
||||
</struct>
|
||||
<key type="filename">sprites/buildings/hub.png</key>
|
||||
<struct type="IndividualSpriteSettings">
|
||||
<key>pivotPoint</key>
|
||||
<point_f>0.5,0.5</point_f>
|
||||
<key>spriteScale</key>
|
||||
<double>1</double>
|
||||
<key>scale9Enabled</key>
|
||||
<false/>
|
||||
<key>scale9Borders</key>
|
||||
<rect>192,192,384,384</rect>
|
||||
<key>scale9Paddings</key>
|
||||
<rect>192,192,384,384</rect>
|
||||
<key>scale9FromFile</key>
|
||||
<false/>
|
||||
</struct>
|
||||
<key type="filename">sprites/buildings/underground_belt_entry.png</key>
|
||||
<key type="filename">sprites/buildings/underground_belt_exit.png</key>
|
||||
<struct type="IndividualSpriteSettings">
|
||||
<key>pivotPoint</key>
|
||||
<point_f>0.5,0.5</point_f>
|
||||
<key>spriteScale</key>
|
||||
<double>1</double>
|
||||
<key>scale9Enabled</key>
|
||||
<false/>
|
||||
<key>scale9Borders</key>
|
||||
<rect>48,48,96,96</rect>
|
||||
<key>scale9Paddings</key>
|
||||
<rect>48,48,96,96</rect>
|
||||
<key>scale9FromFile</key>
|
||||
<false/>
|
||||
</struct>
|
||||
<key type="filename">sprites/debug/acceptor_slot.png</key>
|
||||
<key type="filename">sprites/debug/ejector_slot.png</key>
|
||||
<key type="filename">sprites/map_overview/belt_forward.png</key>
|
||||
<key type="filename">sprites/map_overview/belt_left.png</key>
|
||||
<key type="filename">sprites/map_overview/belt_right.png</key>
|
||||
<struct type="IndividualSpriteSettings">
|
||||
<key>pivotPoint</key>
|
||||
<point_f>0.5,0.5</point_f>
|
||||
<key>spriteScale</key>
|
||||
<double>1</double>
|
||||
<key>scale9Enabled</key>
|
||||
<false/>
|
||||
<key>scale9Borders</key>
|
||||
<rect>8,8,16,16</rect>
|
||||
<key>scale9Paddings</key>
|
||||
<rect>8,8,16,16</rect>
|
||||
<key>scale9FromFile</key>
|
||||
<false/>
|
||||
</struct>
|
||||
<key type="filename">sprites/misc/slot_bad_arrow.png</key>
|
||||
<key type="filename">sprites/misc/slot_good_arrow.png</key>
|
||||
<struct type="IndividualSpriteSettings">
|
||||
<key>pivotPoint</key>
|
||||
<point_f>0.5,0.5</point_f>
|
||||
<key>spriteScale</key>
|
||||
<double>1</double>
|
||||
<key>scale9Enabled</key>
|
||||
<false/>
|
||||
<key>scale9Borders</key>
|
||||
<rect>24,24,48,48</rect>
|
||||
<key>scale9Paddings</key>
|
||||
<rect>24,24,48,48</rect>
|
||||
<key>scale9FromFile</key>
|
||||
<false/>
|
||||
</struct>
|
||||
</map>
|
||||
<key>fileList</key>
|
||||
<array>
|
||||
<filename>sprites</filename>
|
||||
</array>
|
||||
<key>ignoreFileList</key>
|
||||
<array/>
|
||||
<key>replaceList</key>
|
||||
<array/>
|
||||
<key>ignoredWarnings</key>
|
||||
<array/>
|
||||
<key>commonDivisorX</key>
|
||||
<uint>1</uint>
|
||||
<key>commonDivisorY</key>
|
||||
<uint>1</uint>
|
||||
<key>packNormalMaps</key>
|
||||
<false/>
|
||||
<key>autodetectNormalMaps</key>
|
||||
<true/>
|
||||
<key>normalMapFilter</key>
|
||||
<string></string>
|
||||
<key>normalMapSuffix</key>
|
||||
<string></string>
|
||||
<key>normalMapSheetFileName</key>
|
||||
<filename></filename>
|
||||
<key>exporterProperties</key>
|
||||
<map type="ExporterProperties"/>
|
||||
</struct>
|
||||
</data>
|
3
res_raw/sounds/music/main_menu.wav
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:811a57acb5a16af8079744e048c3809799211f1d7c6e79eaa5247ed852b5d4eb
|
||||
size 23990546
|
3
res_raw/sounds/music/theme_full.wav
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:6b4cbf863591aba38d1729fb1cbaa792323f045722279f0deca2492acaaf19b5
|
||||
size 123844300
|
3
res_raw/sounds/ui/dialog_error.wav
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:2b164ef5d1942b30480c202583266707cd52443cdd6fccc5304d941a4aa93c97
|
||||
size 17420
|
3
res_raw/sounds/ui/dialog_ok.wav
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:59eea912cf8d9c6668ec89b3fbfc3cb8c49221aad43449c62d9e30486550cb2f
|
||||
size 169258
|
3
res_raw/sounds/ui/ui_click.wav
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:7f4c56728534d030fca2d75f297027a2774d6f765f5be84a27a3705569f878f2
|
||||
size 20158
|
3
res_raw/sounds/ui/ui_error.wav
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:88c66825955990b1b93197c2b943d010b3190b242991db7e4c10f6db8a688bb7
|
||||
size 59222
|
3
res_raw/sounds/ui/ui_swish_hide.wav
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:250247888bb15badf626dbcb6c76daddac5bb592075d4b6fcccc4930dc3a1465
|
||||
size 16924
|
3
res_raw/sounds/ui/ui_swish_show.wav
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:1c119251f4a7511f5d95c4b9eb208062ebb59eaafe535a8b352fcf7fbb5b409c
|
||||
size 22178
|
BIN
res_raw/sprites/belt/forward_0.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
res_raw/sprites/belt/forward_1.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
res_raw/sprites/belt/forward_2.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
res_raw/sprites/belt/forward_3.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
res_raw/sprites/belt/forward_4.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
res_raw/sprites/belt/forward_5.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
res_raw/sprites/belt/left_0.png
Normal file
After Width: | Height: | Size: 5.6 KiB |
BIN
res_raw/sprites/belt/left_1.png
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
res_raw/sprites/belt/left_2.png
Normal file
After Width: | Height: | Size: 5.9 KiB |
BIN
res_raw/sprites/belt/left_3.png
Normal file
After Width: | Height: | Size: 5.9 KiB |
BIN
res_raw/sprites/belt/left_4.png
Normal file
After Width: | Height: | Size: 6.0 KiB |
BIN
res_raw/sprites/belt/left_5.png
Normal file
After Width: | Height: | Size: 5.9 KiB |
BIN
res_raw/sprites/belt/right_0.png
Normal file
After Width: | Height: | Size: 5.3 KiB |
BIN
res_raw/sprites/belt/right_1.png
Normal file
After Width: | Height: | Size: 5.6 KiB |
BIN
res_raw/sprites/belt/right_2.png
Normal file
After Width: | Height: | Size: 5.7 KiB |
BIN
res_raw/sprites/belt/right_3.png
Normal file
After Width: | Height: | Size: 5.7 KiB |
BIN
res_raw/sprites/belt/right_4.png
Normal file
After Width: | Height: | Size: 5.7 KiB |
BIN
res_raw/sprites/belt/right_5.png
Normal file
After Width: | Height: | Size: 5.7 KiB |
BIN
res_raw/sprites/buildings/belt_left.png
Normal file
After Width: | Height: | Size: 5.6 KiB |
BIN
res_raw/sprites/buildings/belt_right.png
Normal file
After Width: | Height: | Size: 5.3 KiB |
BIN
res_raw/sprites/buildings/belt_top.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
res_raw/sprites/buildings/cutter.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
res_raw/sprites/buildings/hub.png
Normal file
After Width: | Height: | Size: 61 KiB |
BIN
res_raw/sprites/buildings/miner.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
res_raw/sprites/buildings/mixer.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
res_raw/sprites/buildings/painter.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
res_raw/sprites/buildings/rotater.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
res_raw/sprites/buildings/splitter.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
res_raw/sprites/buildings/stacker.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
res_raw/sprites/buildings/trash.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
res_raw/sprites/buildings/underground_belt_entry.png
Normal file
After Width: | Height: | Size: 9.8 KiB |
BIN
res_raw/sprites/buildings/underground_belt_exit.png
Normal file
After Width: | Height: | Size: 9.7 KiB |