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

Resolve merge conflict. Setting doesn't work.

This commit is contained in:
hexagonhexagon 2020-06-21 19:53:07 -04:00
commit aa75e0e2f7
157 changed files with 11850 additions and 5190 deletions

3
.gitignore vendored
View File

@ -112,3 +112,6 @@ tmp_standalone_files
# Github Actions files
.github/workflows
# Local config
config.local.js

9
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,9 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
// List of extensions which should be recommended for users of this workspace.
"recommendations": ["esbenp.prettier-vscode"],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": []
}

View File

@ -16,7 +16,7 @@ Your goal is to produce shapes by cutting, rotating, merging and painting parts
- Make sure git `git lfs` extension is on your path
- Run `git lfs pull` to download sound assets
- Make sure `ffmpeg` is on your path
- Install Yarn and Node.js 10
- Install Node.js and Yarn
- Run `yarn` in the root folder, then run `yarn` in the `gulp/` folder
- Cd into `gulp` and run `yarn gulp` - it should now open in your browser

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6463b33b2cae50d1ecb11f0a845f06633aff331a5c2c0998d9eb93e40ad576b1
size 636254
oid sha256:7d05e340acb18f7b6b6f05fa7536f14179cda54a9ead0923fbb8e39c68da148c
size 703229

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

BIN
artwork/reddit/banner.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 597 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2c0021548cdc52b0a70b19f7e432f6ab5dddc2a8a032694ed6fa047dc90fa904
size 202335
oid sha256:ebde52e75e54d2f4add0cf498c85f059082a0745212a23c4de7328a7d78b00a5
size 238170

BIN
artwork/steam/devlog.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

3
artwork/steam/devlog.psd Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:746c6cf3f0284798a78c08f77d7e9d0c28b02323081fda42b5fa876a7ade29a0
size 205925

Binary file not shown.

After

Width:  |  Height:  |  Size: 380 KiB

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e0cd2d82917e470202d38d32277f7519ccfd1821cb21791266539ddf07486d1b
size 7314327

BIN
artwork/wires/prefab.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

3
artwork/wires/prefab.psd Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:498dea7314b8720c40dcd8bdd64b1b4a7a35259b2ffe7e896fc3db22878d6414
size 1954036

BIN
electron/favicon.icns Normal file

Binary file not shown.

27
gulp/cordova.js vendored
View File

@ -2,13 +2,15 @@ const path = require("path");
const fs = require("fs");
const buildUtils = require("./buildutils");
export function gulptasksCordova($, gulp, buildFolder) {
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 }));
return gulp
.src(path.join(cdvRes, "built"), { read: false, allowEmpty: true })
.pipe($.clean({ force: true }));
});
// Optimizes all built assets
@ -64,7 +66,7 @@ export function gulptasksCordova($, gulp, buildFolder) {
.pipe(gulp.dest(path.join(cdvRes, "built", "ios")));
});
gulp.task("prepareIosRes", ["scaleIconIos", "copyOtherIosResources"]);
gulp.task("prepareIosRes", gulp.series("scaleIconIos", "copyOtherIosResources"));
gulp.task("copyAndroidResources", () => {
return gulp
@ -72,19 +74,20 @@ export function gulptasksCordova($, gulp, buildFolder) {
.pipe(gulp.dest(path.join(cdvRes, "built", "android")));
});
gulp.task("prepareAndroidRes", ["copyAndroidResources"]);
gulp.task("prepareAndroidRes", gulp.series("copyAndroidResources"));
gulp.task("prepareCordovaAssets", cb => {
return $.sequence(
gulp.task(
"prepareCordovaAssets",
gulp.series(
"cleanupAppAssetsBuiltFolder",
["prepareIosRes", "prepareAndroidRes"],
gulp.parallel("prepareIosRes", "prepareAndroidRes"),
"optimizeBuiltAppAssets"
)(cb);
});
)
);
// Patches the config.xml by replacing the app id to app_beta
gulp.task("patchConfigXML", () => {
gulp.task("patchConfigXML", cb => {
const configUrl = path.join("..", "..", "config.xml");
let configContent = fs.readFileSync(configUrl).toString();
const version = buildUtils.getVersion();
@ -92,14 +95,16 @@ export function gulptasksCordova($, gulp, buildFolder) {
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);
cb();
});
gulp.task("patchConfigXMLChangeStagingToProd", () => {
gulp.task("patchConfigXMLChangeStagingToProd", cb => {
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);
cb();
});
// Triggers a new build on phonegap

View File

@ -13,7 +13,7 @@ function gulptasksDocs($, gulp, buildFolder) {
.pipe(gulp.dest(path.join("..", "tsc_temp")));
});
gulp.task("docs.copyTsconfigForHints", () => {
gulp.task("docs.copyTsconfigForHints", cb => {
const src = fs.readFileSync(path.join("..", "src", "js", "tsconfig.json")).toString();
const baseConfig = JSON.parse($.stripJsonComments(src));
@ -28,9 +28,10 @@ function gulptasksDocs($, gulp, buildFolder) {
baseConfig.composite = true;
baseConfig.outFile = "bundled-ts.js";
fs.writeFileSync(path.join("..", "tsc_temp", "tsconfig.json"), JSON.stringify(baseConfig));
cb();
});
gulp.task("main.prepareDocs", $.sequence("docs.convertJsToTs", "docs.copyTsconfigForHints"));
gulp.task("main.prepareDocs", gulp.series("docs.convertJsToTs", "docs.copyTsconfigForHints"));
}
module.exports = {

View File

@ -28,7 +28,7 @@ function gulptasksFTP($, gulp, buildFolder) {
};
// Write the "commit.txt" file
gulp.task("ftp.writeVersion", () => {
gulp.task("ftp.writeVersion", cb => {
fs.writeFileSync(
path.join(buildFolder, "version.json"),
JSON.stringify(
@ -41,6 +41,7 @@ function gulptasksFTP($, gulp, buildFolder) {
4
)
);
cb();
});
const gameSrcGlobs = [
@ -78,14 +79,15 @@ function gulptasksFTP($, gulp, buildFolder) {
.pipe($.sftp(deployCredentials));
});
gulp.task(`ftp.upload.${deployEnv}`, cb => {
$.sequence(
gulp.task(
`ftp.upload.${deployEnv}`,
gulp.series(
"ftp.writeVersion",
`ftp.upload.${deployEnv}.game`,
`ftp.upload.${deployEnv}.indexHtml`,
`ftp.upload.${deployEnv}.additionalFiles`
)(cb);
});
)
);
}
}

View File

@ -1,11 +1,5 @@
/* eslint-disable */
const nodeVersion = process.versions.node.split(".")[0];
if (nodeVersion !== "10") {
console.error("This cli requires exactly Node.js 10. You are using Node.js " + nodeVersion);
process.exit(1);
}
require("colors");
const gulp = require("gulp");
@ -95,21 +89,26 @@ translations.gulptasksTranslations($, gulp, buildFolder);
// Cleans up everything
gulp.task("utils.cleanBuildFolder", () => {
return gulp.src(buildFolder, { read: false }).pipe($.clean({ force: true }));
return gulp.src(buildFolder, { read: false, allowEmpty: true }).pipe($.clean({ force: true }));
});
gulp.task("utils.cleanBuildTempFolder", () => {
return gulp
.src(path.join(__dirname, "..", "src", "js", "built-temp"), { read: false })
.src(path.join(__dirname, "..", "src", "js", "built-temp"), { read: false, allowEmpty: true })
.pipe($.clean({ force: true }));
});
gulp.task("utils.cleanup", $.sequence("utils.cleanBuildFolder", "utils.cleanBuildTempFolder"));
gulp.task("utils.cleanup", gulp.series("utils.cleanBuildFolder", "utils.cleanBuildTempFolder"));
// Requires no uncomitted files
gulp.task("utils.requireCleanWorkingTree", cb => {
const output = $.trim(execSync("git status -su").toString("ascii"));
let output = $.trim(execSync("git status -su").toString("ascii")).replace(/\r/gi, "").split("\n");
// Filter files which are OK to be untracked
output = output.filter(x => x.indexOf(".local.js") < 0);
if (output.length > 0) {
console.error("\n\nYou have unstaged changes, please commit everything first!");
console.error("Unstaged files:");
console.error(output.join("\n"));
process.exit(1);
}
cb();
@ -161,71 +160,66 @@ function serve({ standalone }) {
});
// Watch .scss files, those trigger a css rebuild
gulp.watch(["../src/**/*.scss"], ["css.dev"]);
gulp.watch(["../src/**/*.scss"], gulp.series("css.dev"));
// Watch .html files, those trigger a html rebuild
gulp.watch("../src/**/*.html", [standalone ? "html.standalone-dev" : "html.dev"]);
gulp.watch("../src/**/*.html", gulp.series(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/**/*.mp3", "../res_raw/sounds/**/*.wav"], gulp.series("sounds.dev"));
// Watch translations
gulp.watch("../translations/**/*.yaml", ["translations.convertToJson"]);
gulp.watch("../translations/**/*.yaml", gulp.series("translations.convertToJson"));
gulp.watch(
["../res_raw/sounds/sfx/*.mp3", "../res_raw/sounds/sfx/*.wav"],
$.sequence("sounds.sfx", "sounds.copy")
gulp.series("sounds.sfx", "sounds.copy")
);
gulp.watch(
["../res_raw/sounds/music/*.mp3", "../res_raw/sounds/music/*.wav"],
$.sequence("sounds.music", "sounds.copy")
gulp.series("sounds.music", "sounds.copy")
);
// Watch resource files and copy them on change
gulp.watch(imgres.nonImageResourcesGlobs, ["imgres.copyNonImageResources"]);
gulp.watch(imgres.imageResourcesGlobs, ["imgres.copyImageResources"]);
gulp.watch(imgres.nonImageResourcesGlobs, gulp.series("imgres.copyNonImageResources"));
gulp.watch(imgres.imageResourcesGlobs, gulp.series("imgres.copyImageResources"));
// Watch .atlas files and recompile the atlas on change
gulp.watch("../res_built/atlas/*.json", ["imgres.atlas"]);
gulp.watch("../res_built/atlas/*.json", gulp.series("imgres.atlas"));
// Watch the build folder and reload when anything changed
const extensions = ["html", "js", "png", "gif", "jpg", "svg", "mp3", "ico", "woff2", "json"];
gulp.watch(extensions.map(ext => path.join(buildFolder, "**", "*." + ext))).on("change", function (e) {
return gulp.src(e.path).pipe(browserSync.reload({ stream: true }));
gulp.watch(extensions.map(ext => path.join(buildFolder, "**", "*." + ext))).on("change", function (path) {
return gulp.src(path).pipe(browserSync.reload({ stream: true }));
});
gulp.watch("../src/js/built-temp/*.json").on("change", function (e) {
return gulp.src(e.path).pipe(browserSync.reload({ stream: true }));
gulp.watch("../src/js/built-temp/*.json").on("change", function (path) {
return gulp.src(path).pipe(browserSync.reload({ stream: true }));
});
// Start the webpack watching server (Will never return)
if (standalone) {
$.sequence("js.standalone-dev.watch")(() => true);
gulp.series("js.standalone-dev.watch")(() => true);
} else {
$.sequence("js.dev.watch")(() => true);
gulp.series("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 => $.sequence("imgres.allOptimized")(cb));
gulp.task("step.baseResources", gulp.series("imgres.allOptimized"));
gulp.task("step.deleteEmpty", cb => {
deleteEmpty.sync(buildFolder);
cb();
});
gulp.task("step.postbuild", $.sequence("imgres.cleanupUnusedCssInlineImages", "step.deleteEmpty"));
gulp.task("step.postbuild", gulp.series("imgres.cleanupUnusedCssInlineImages", "step.deleteEmpty"));
// Builds everything (dev)
gulp.task("build.dev", cb => {
$.sequence(
gulp.task(
"build.dev",
gulp.series(
"utils.cleanup",
"utils.copyAdditionalBuildFiles",
"imgres.atlas",
@ -235,12 +229,13 @@ gulp.task("build.dev", cb => {
"translations.fullBuild",
"css.dev",
"html.dev"
)(cb);
});
)
);
// Builds everything (standalone -dev)
gulp.task("build.standalone.dev", cb => {
$.sequence(
gulp.task(
"build.standalone.dev",
gulp.series(
"utils.cleanup",
"imgres.atlas",
"sounds.dev",
@ -250,58 +245,74 @@ gulp.task("build.standalone.dev", cb => {
"js.standalone-dev",
"css.dev",
"html.standalone-dev"
)(cb);
});
)
);
// Builds everything (staging)
gulp.task("step.staging.code", $.sequence("sounds.fullbuild", "translations.fullBuild", "js.staging"));
gulp.task("step.staging.mainbuild", cb =>
$.multiProcess(["utils.copyAdditionalBuildFiles", "step.baseResources", "step.staging.code"], cb, false)
gulp.task("step.staging.code", gulp.series("sounds.fullbuild", "translations.fullBuild", "js.staging"));
gulp.task(
"step.staging.mainbuild",
gulp.parallel("utils.copyAdditionalBuildFiles", "step.baseResources", "step.staging.code")
);
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"));
gulp.task("step.staging.all", gulp.series("step.staging.mainbuild", "css.prod", "html.staging"));
gulp.task("build.staging", gulp.series("utils.cleanup", "step.staging.all", "step.postbuild"));
// Builds everything (prod)
gulp.task("step.prod.code", $.sequence("sounds.fullbuild", "translations.fullBuild", "js.prod"));
gulp.task("step.prod.mainbuild", cb =>
$.multiProcess(["utils.copyAdditionalBuildFiles", "step.baseResources", "step.prod.code"], cb, false)
gulp.task("step.prod.code", gulp.series("sounds.fullbuild", "translations.fullBuild", "js.prod"));
gulp.task(
"step.prod.mainbuild",
gulp.parallel("utils.copyAdditionalBuildFiles", "step.baseResources", "step.prod.code")
);
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"));
gulp.task("step.prod.all", gulp.series("step.prod.mainbuild", "css.prod", "html.prod"));
gulp.task("build.prod", gulp.series("utils.cleanup", "step.prod.all", "step.postbuild"));
// Builds everything (standalone-beta)
gulp.task(
"step.standalone-beta.code",
$.sequence("sounds.fullbuild", "translations.fullBuild", "js.standalone-beta")
);
gulp.task("step.standalone-beta.mainbuild", cb =>
$.multiProcess(["step.baseResources", "step.standalone-beta.code"], cb, false)
gulp.series("sounds.fullbuild", "translations.fullBuild", "js.standalone-beta")
);
gulp.task("step.standalone-beta.mainbuild", gulp.parallel("step.baseResources", "step.standalone-beta.code"));
gulp.task(
"step.standalone-beta.all",
$.sequence("step.standalone-beta.mainbuild", "css.prod-standalone", "html.standalone-beta")
gulp.series("step.standalone-beta.mainbuild", "css.prod-standalone", "html.standalone-beta")
);
gulp.task(
"build.standalone-beta",
gulp.series("utils.cleanup", "step.standalone-beta.all", "step.postbuild")
);
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("sounds.fullbuild", "translations.fullBuild", "js.standalone-prod")
);
gulp.task("step.standalone-prod.mainbuild", cb =>
$.multiProcess(["step.baseResources", "step.standalone-prod.code"], cb, false)
gulp.series("sounds.fullbuild", "translations.fullBuild", "js.standalone-prod")
);
gulp.task("step.standalone-prod.mainbuild", gulp.parallel("step.baseResources", "step.standalone-prod.code"));
gulp.task(
"step.standalone-prod.all",
$.sequence("step.standalone-prod.mainbuild", "css.prod-standalone", "html.standalone-prod")
gulp.series("step.standalone-prod.mainbuild", "css.prod-standalone", "html.standalone-prod")
);
gulp.task(
"build.standalone-prod",
gulp.series("utils.cleanup", "step.standalone-prod.all", "step.postbuild")
);
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.series("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", $.sequence("build.standalone-prod", "standalone.package.prod"));
gulp.task("main.deploy.prod", gulp.series("utils.requireCleanWorkingTree", "build.prod", "ftp.upload.prod"));
gulp.task("main.deploy.all", gulp.series("main.deploy.staging", "main.deploy.prod"));
gulp.task("main.standalone", gulp.series("build.standalone-prod", "standalone.package.prod"));
// Live-development
gulp.task(
"main.serveDev",
gulp.series("build.dev", () => serve({ standalone: false }))
);
gulp.task(
"main.serveStandalone",
gulp.series("build.standalone.dev", () => serve({ standalone: true }))
);
gulp.task("default", gulp.series("main.serveDev"));

View File

@ -10,7 +10,7 @@ const imageResourcesGlobs = ["../res/**/*.png", "../res/**/*.svg", "../res/**/*.
function gulptasksImageResources($, gulp, buildFolder) {
// Lossless options
const minifyImagesOptsLossless = () => [
$.imagemin.jpegtran({
$.imageminJpegtran({
progressive: true,
}),
$.imagemin.svgo({}),
@ -25,7 +25,7 @@ function gulptasksImageResources($, gulp, buildFolder) {
// Lossy options
const minifyImagesOpts = () => [
$.imageminMozjpeg({
$.imagemin.mozjpeg({
quality: 80,
maxMemory: 1024 * 1024 * 8,
}),
@ -116,11 +116,12 @@ function gulptasksImageResources($, gulp, buildFolder) {
});
// Copies all resources and optimizes them
gulp.task("imgres.allOptimized", cb =>
$.multiProcess(
["imgres.atlasOptimized", "imgres.copyNonImageResources", "imgres.copyImageResourcesOptimized"],
cb,
false
gulp.task(
"imgres.allOptimized",
gulp.parallel(
"imgres.atlasOptimized",
"imgres.copyNonImageResources",
"imgres.copyImageResourcesOptimized"
)
);

View File

@ -68,7 +68,7 @@ function gulptasksJS($, gulp, buildFolder, browserSync) {
)
.pipe(gulp.dest(buildFolder));
});
gulp.task("js.staging", cb => $.multiProcess(["js.staging.transpiled", "js.staging.latest"], cb, false));
gulp.task("js.staging", gulp.parallel("js.staging.transpiled", "js.staging.latest"));
//// PROD
gulp.task("js.prod.transpiled", () => {
@ -104,7 +104,7 @@ function gulptasksJS($, gulp, buildFolder, browserSync) {
.pipe(browserSync.stream());
});
gulp.task("js.prod", cb => $.multiProcess(["js.prod.transpiled", "js.prod.latest"], cb, false));
gulp.task("js.prod", gulp.parallel("js.prod.transpiled", "js.prod.latest"));
//// STANDALONE

View File

@ -70,40 +70,38 @@
"css-mqpacker": "^7.0.0",
"cssnano": "^4.1.10",
"electron-packager": "^14.0.6",
"imagemin-gifsicle": "^7.0.0",
"faster.js": "^1.1.0",
"glob": "^7.1.3",
"gulp": "^3.9.1",
"gulp": "^4.0.2",
"gulp-cache": "^1.1.3",
"gulp-cached": "^1.1.1",
"gulp-clean": "^0.4.0",
"gulp-cssbeautify": "^1.0.1",
"gulp-cssbeautify": "^2.0.1",
"gulp-csslint": "^1.0.1",
"gulp-dom": "^1.0.0",
"gulp-flatten": "^0.4.0",
"gulp-fluent-ffmpeg": "^1.0.2",
"gulp-fluent-ffmpeg": "^2.0.0",
"gulp-html-beautify": "^1.0.1",
"gulp-htmlmin": "^5.0.1",
"gulp-if": "^2.0.2",
"gulp-imagemin": "^5.0.3",
"gulp-if": "^3.0.0",
"gulp-imagemin": "^7.1.0",
"gulp-javascript-obfuscator": "^1.1.5",
"gulp-jsbeautifier": "^3.0.0",
"gulp-load-plugins": "^1.5.0",
"gulp-multi-process": "^1.3.1",
"gulp-load-plugins": "^2.0.3",
"gulp-phonegap-build": "^0.1.5",
"gulp-plumber": "^1.2.1",
"gulp-pngquant": "^1.0.12",
"gulp-pngquant": "^1.0.13",
"gulp-postcss": "^8.0.0",
"gulp-rename": "^1.4.0",
"gulp-sass": "^4.0.1",
"gulp-rename": "^2.0.0",
"gulp-sass": "^4.1.0",
"gulp-sass-lint": "^1.4.0",
"gulp-sequence": "^1.0.0",
"gulp-sftp": "^0.1.5",
"gulp-sftp": "git+https://git@github.com/webksde/gulp-sftp",
"gulp-terser": "^1.2.0",
"gulp-webserver": "^0.9.1",
"gulp-yaml": "^2.0.4",
"imagemin-mozjpeg": "^8.0.0",
"imagemin-pngquant": "^8.0.0",
"imagemin-gifsicle": "^7.0.0",
"imagemin-jpegtran": "^7.0.0",
"imagemin-pngquant": "^9.0.0",
"jimp": "^0.6.1",
"js-yaml": "^3.13.1",
"onesky-fetch": "^0.0.7",

View File

@ -3,11 +3,11 @@ const audiosprite = require("gulp-audiosprite");
function gulptasksSounds($, gulp, buildFolder) {
// Gather some basic infos
const soundsDir = path.join("..", "res_raw", "sounds");
const builtSoundsDir = path.join("..", "res_built", "sounds");
const soundsDir = path.join(__dirname, "..", "res_raw", "sounds");
const builtSoundsDir = path.join(__dirname, "..", "res_built", "sounds");
gulp.task("sounds.clear", () => {
return gulp.src(builtSoundsDir).pipe($.clean({ force: true }));
return gulp.src(builtSoundsDir, { read: false, allowEmpty: true }).pipe($.clean({ force: true }));
});
const filters = ["volume=0.2"];
@ -29,7 +29,7 @@ function gulptasksSounds($, gulp, buildFolder) {
.audioChannels(1)
.audioFrequency(22050)
.audioCodec("libmp3lame")
.audioFilters(["volume=0.3"]);
.audioFilters(["volume=0.15"]);
}),
{
name: "music",
@ -79,7 +79,7 @@ function gulptasksSounds($, gulp, buildFolder) {
gulp.task(
"sounds.sfx",
$.sequence("sounds.sfxGenerateSprites", "sounds.sfxOptimize", "sounds.sfxCopyAtlas")
gulp.series("sounds.sfxGenerateSprites", "sounds.sfxOptimize", "sounds.sfxCopyAtlas")
);
gulp.task("sounds.copy", () => {
@ -90,10 +90,10 @@ function gulptasksSounds($, gulp, buildFolder) {
.pipe(gulp.dest(path.join(buildFolder, "res", "sounds")));
});
gulp.task("sounds.buildall", cb => $.multiProcess(["sounds.music", "sounds.sfx"], cb, true));
gulp.task("sounds.buildall", gulp.parallel("sounds.music", "sounds.sfx"));
gulp.task("sounds.fullbuild", cb => $.sequence("sounds.clear", "sounds.buildall", "sounds.copy")(cb));
gulp.task("sounds.dev", cb => $.sequence("sounds.buildall", "sounds.copy")(cb));
gulp.task("sounds.fullbuild", gulp.series("sounds.clear", "sounds.buildall", "sounds.copy"));
gulp.task("sounds.dev", gulp.series("sounds.buildall", "sounds.copy"));
}
module.exports = {

View File

@ -6,13 +6,13 @@ const fse = require("fs-extra");
const execSync = require("child_process").execSync;
function gulptasksStandalone($, gulp, buildFolder) {
const electronBaseDir = path.join("../electron");
const electronBaseDir = path.join(__dirname, "..", "electron");
const tempDestDir = path.join("..", "tmp_standalone_files");
const tempDestDir = path.join(__dirname, "..", "tmp_standalone_files");
const tempDestBuildDir = path.join(tempDestDir, "built");
gulp.task("standalone.prepare.cleanup", () => {
return gulp.src(tempDestDir, { read: false }).pipe($.clean({ force: true }));
return gulp.src(tempDestDir, { read: false, allowEmpty: true }).pipe($.clean({ force: true }));
});
gulp.task("standalone.prepare.copyPrefab", () => {
@ -30,7 +30,7 @@ function gulptasksStandalone($, gulp, buildFolder) {
return gulp.src(requiredFiles, { base: electronBaseDir }).pipe(gulp.dest(tempDestBuildDir));
});
gulp.task("standalone.prepare.writePackageJson", () => {
gulp.task("standalone.prepare.writePackageJson", cb => {
fs.writeFileSync(
path.join(tempDestBuildDir, "package.json"),
JSON.stringify(
@ -43,67 +43,71 @@ function gulptasksStandalone($, gulp, buildFolder) {
4
)
);
cb();
});
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));
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("../build/**/*.*", { base: "../build" }).pipe(gulp.dest(tempDestBuildDir));
});
gulp.task("standalone.killRunningInstances", () => {
gulp.task("standalone.killRunningInstances", cb => {
try {
execSync("taskkill /F /IM shapezio.exe");
} catch (ex) {
console.warn("Failed to kill running instances, maybe none are up.");
}
cb();
});
gulp.task(
"standalone.prepare",
$.sequence(
gulp.series(
"standalone.killRunningInstances",
"standalone.prepare.cleanup",
"standalone.prepare.copyPrefab",
@ -190,13 +194,16 @@ function gulptasksStandalone($, gulp, buildFolder) {
gulp.task(
"standalone.package.prod",
$.sequence("standalone.prepare", [
"standalone.package.prod.win64",
"standalone.package.prod.linux64",
"standalone.package.prod.darwin64",
// "standalone.package.prod.win32",
// "standalone.package.prod.linux32",
])
gulp.series(
"standalone.prepare",
gulp.parallel(
"standalone.package.prod.win64",
"standalone.package.prod.linux64",
"standalone.package.prod.darwin64"
// "standalone.package.prod.win32",
// "standalone.package.prod.linux32",
)
)
);
}

View File

@ -14,7 +14,7 @@ function gulptasksTranslations($, gulp, buildFolder) {
.pipe(gulp.dest(translationsJsonDir));
});
gulp.task("translations.fullBuild", $.sequence("translations.convertToJson"));
gulp.task("translations.fullBuild", gulp.series("translations.convertToJson"));
}
module.exports = {

View File

@ -40,6 +40,8 @@ module.exports = ({
G_ALL_UI_IMAGES: JSON.stringify(utils.getAllResourceImages()),
};
const minifyNames = environment === "prod";
return {
mode: "production",
entry: {
@ -91,15 +93,15 @@ module.exports = ({
parse: {},
module: true,
toplevel: true,
keep_classnames: false,
keep_fnames: false,
keep_fargs: false,
keep_classnames: !minifyNames,
keep_fnames: !minifyNames,
keep_fargs: !minifyNames,
safari10: true,
compress: {
arguments: false, // breaks
drop_console: false,
global_defs: globalDefs,
keep_fargs: false,
keep_fargs: !minifyNames,
keep_infinity: true,
passes: 2,
module: true,
@ -141,8 +143,8 @@ module.exports = ({
},
mangle: {
eval: true,
keep_classnames: false,
keep_fnames: false,
keep_classnames: !minifyNames,
keep_fnames: !minifyNames,
module: true,
toplevel: true,
safari10: true,
@ -154,7 +156,7 @@ module.exports = ({
braces: false,
ecma: es6 ? 6 : 5,
preamble:
"/* Shapez.io Codebase - Copyright 2020 Tobias Springer - " +
"/* shapez.io Codebase - Copyright 2020 Tobias Springer - " +
utils.getVersion() +
" @ " +
utils.getRevision() +

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@
"license": "MIT",
"private": true,
"scripts": {
"dev": "./gulp/gulp main.serveDev",
"dev": "cd gulp && yarn gulp main.serveDev",
"tslint": "cd src/js && tsc",
"lint": "npx eslint src/js",
"prettier-all": "prettier --write src/**/*.* && prettier --write gulp/**/*.*",
@ -17,7 +17,8 @@
"publishOnSteam": "cd gulp/steampipe && ./upload.bat",
"publishStandalone": "yarn publishOnItch && yarn publishOnSteam",
"publishWeb": "cd gulp && yarn main.deploy.prod",
"publish": "yarn publishStandalone && yarn publishWeb"
"publish": "yarn publishStandalone && yarn publishWeb",
"syncTranslations": "node sync-translations.js"
},
"dependencies": {
"@babel/core": "^7.5.4",
@ -45,6 +46,7 @@
"logrocket": "^1.0.7",
"lz-string": "^1.4.4",
"markdown-loader": "^4.0.0",
"match-all": "^1.2.5",
"obfuscator-loader": "^1.1.2",
"phonegap-plugin-mobile-accessibility": "^1.0.5",
"promise-polyfill": "^8.1.0",
@ -65,7 +67,9 @@
"webpack-plugin-replace": "^1.1.1",
"webpack-strip-block": "^0.2.0",
"whatwg-fetch": "^3.0.0",
"worker-loader": "^2.0.0"
"worker-loader": "^2.0.0",
"yaml": "^1.10.0",
"yawn-yaml": "^1.5.0"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "3.0.1",

View File

@ -1,60 +1,25 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<path style="fill:#C8414B;" d="M400,0H112C50.144,0,0,50.144,0,112v288c0,61.856,50.144,112,112,112h288 c61.856,0,112-50.144,112-112V112C512,50.144,461.856,0,400,0z"/>
<rect y="106.63" style="fill:#FFD250;" width="512" height="298.74"/>
<path style="fill:#C8414B;" d="M223.091,256.412l8.255-33.665c0.76-3.1-1.843-6.041-5.347-6.041h-5.815 c-3.504,0-6.108,2.941-5.347,6.041L223.091,256.412z"/>
<rect x="213.35" y="238.76" style="fill:#F5F5F5;" width="19.473" height="75"/>
<rect x="208.49" y="229.94" style="fill:#FAB446;" width="29.21" height="8.823"/>
<g>
<rect x="189.01" y="256.41" style="fill:#C8414B;" width="48.681" height="8.823"/>
<polygon style="fill:#C8414B;" points="237.696,291.706 208.487,282.882 208.487,274.059 237.696,282.882 "/>
<path style="fill:#C8414B;" d="M77.047,256.412l8.255-33.665c0.76-3.1-1.843-6.041-5.347-6.041H74.14 c-3.504,0-6.108,2.941-5.347,6.041L77.047,256.412z"/>
</g>
<path style="fill:#F5F5F5;" d="M111.124,229.941c-5.377,0-9.736,3.95-9.736,8.824v57.353c0,10.721,11.041,30.882,48.682,30.882 s48.682-20.162,48.682-30.882v-57.353c0-4.873-4.359-8.824-9.736-8.824L111.124,229.941L111.124,229.941z"/>
<g>
<path style="fill:#C8414B;" d="M150.069,274.059h-48.682V239.21c0-5.119,4.15-9.269,9.269-9.269h39.413V274.059z"/>
<path style="fill:#C8414B;" d="M150.069,274.059h48.682v20.946c0,12.797-10.374,23.172-23.172,23.172h-2.338 c-12.797,0-23.172-10.374-23.172-23.172L150.069,274.059L150.069,274.059z"/>
</g>
<path style="fill:#FAB446;" d="M101.387,274.059h48.682v20.946c0,12.797-10.374,23.172-23.172,23.172h-2.338 c-12.797,0-23.172-10.374-23.172-23.172C101.387,295.005,101.387,274.059,101.387,274.059z"/>
<g>
<path style="fill:#C8414B;" d="M140.333,313.665v-39.606h-9.736v43.673C134.217,317.065,137.49,315.612,140.333,313.665z"/>
<path style="fill:#C8414B;" d="M120.86,317.732v-43.673h-9.736v39.606C113.967,315.612,117.239,317.065,120.86,317.732z"/>
</g>
<rect x="111.12" y="256.41" style="fill:#FFB441;" width="29.21" height="8.823"/>
<g>
<rect x="111.12" y="238.76" style="fill:#FAB446;" width="29.21" height="8.824"/>
<rect x="115.99" y="244.01" style="fill:#FAB446;" width="19.473" height="15.985"/>
</g>
<rect x="67.31" y="238.76" style="fill:#F5F5F5;" width="19.473" height="75"/>
<g>
<rect x="62.44" y="309.35" style="fill:#FAB446;" width="29.21" height="8.823"/>
<rect x="62.44" y="229.94" style="fill:#FAB446;" width="29.21" height="8.823"/>
</g>
<rect x="57.57" y="318.18" style="fill:#5064AA;" width="38.945" height="8.823"/>
<rect x="213.35" y="309.35" style="fill:#FAB446;" width="29.21" height="8.823"/>
<rect x="203.62" y="318.18" style="fill:#5064AA;" width="38.945" height="8.823"/>
<rect x="120.86" y="221.12" style="fill:#FAB446;" width="58.42" height="8.823"/>
<rect x="145.2" y="194.65" style="fill:#FFB441;" width="9.736" height="26.471"/>
<g>
<path style="fill:#F5F5F5;" d="M140.333,207.882c-8.053,0-14.604-5.937-14.604-13.235s6.551-13.235,14.604-13.235 c8.053,0,14.604,5.937,14.604,13.235S148.386,207.882,140.333,207.882z M140.333,190.235c-2.686,0-4.868,1.978-4.868,4.412 s2.182,4.412,4.868,4.412c2.686,0,4.868-1.978,4.868-4.412C145.201,192.213,143.019,190.235,140.333,190.235z"/>
<path style="fill:#F5F5F5;" d="M159.805,207.882c-8.053,0-14.604-5.937-14.604-13.235s6.551-13.235,14.604-13.235 c8.053,0,14.604,5.937,14.604,13.235S167.859,207.882,159.805,207.882z M159.805,190.235c-2.686,0-4.868,1.978-4.868,4.412 s2.182,4.412,4.868,4.412c2.686,0,4.868-1.978,4.868-4.412C164.673,192.213,162.491,190.235,159.805,190.235z"/>
<path style="fill:#F5F5F5;" d="M179.278,216.706c-8.053,0-14.604-5.937-14.604-13.235s6.551-13.235,14.604-13.235 c8.053,0,14.605,5.937,14.605,13.235S187.331,216.706,179.278,216.706z M179.278,199.059c-2.686,0-4.868,1.978-4.868,4.412 s2.182,4.412,4.868,4.412c2.686,0,4.868-1.978,4.868-4.412C184.146,201.036,181.964,199.059,179.278,199.059z"/>
<path style="fill:#F5F5F5;" d="M120.86,216.706c-8.053,0-14.604-5.937-14.604-13.235s6.551-13.235,14.604-13.235 s14.604,5.937,14.604,13.235S128.913,216.706,120.86,216.706z M120.86,199.059c-2.686,0-4.868,1.978-4.868,4.412 s2.182,4.412,4.868,4.412s4.868-1.978,4.868-4.412C125.728,201.036,123.546,199.059,120.86,199.059z"/>
</g>
<path style="fill:#FAB446;" d="M179.278,291.706v4.412c0,2.433-2.184,4.412-4.868,4.412c-2.684,0-4.868-1.979-4.868-4.412v-4.412 H179.278 M189.014,282.882h-29.209v13.235c0,7.298,6.552,13.235,14.604,13.235c8.053,0,14.605-5.938,14.605-13.235V282.882 L189.014,282.882z"/>
<path style="fill:#FFA0D2;" d="M174.877,265.235h-0.935c-5.119,0-9.269-4.15-9.269-9.269v-7.933c0-5.119,4.15-9.269,9.269-9.269 h0.935c5.119,0,9.269,4.15,9.269,9.269v7.933C184.146,261.086,179.996,265.235,174.877,265.235z"/>
<ellipse style="fill:#5064AA;" cx="150.07" cy="274.06" rx="14.604" ry="13.235"/>
<rect x="145.2" y="177" style="fill:#FAB446;" width="9.736" height="26.471"/>
<path style="fill:#C8414B;" d="M120.86,221.118l-9.736-8.824l5.703-5.169c8.816-7.99,20.774-12.478,33.242-12.478l0,0 c12.468,0,24.426,4.489,33.242,12.478l5.703,5.169l-9.736,8.824H120.86z"/>
<g>
<ellipse style="fill:#FFD250;" cx="150.07" cy="212.29" rx="4.868" ry="4.412"/>
<ellipse style="fill:#FFD250;" cx="130.6" cy="212.29" rx="4.868" ry="4.412"/>
<ellipse style="fill:#FFD250;" cx="169.54" cy="212.29" rx="4.868" ry="4.412"/>
</g>
<g>
<rect x="62.44" y="256.41" style="fill:#C8414B;" width="48.681" height="8.823"/>
<polygon style="fill:#C8414B;" points="62.442,291.706 91.651,282.882 91.651,274.059 62.442,282.882 "/>
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<g transform="translate(-1)">
<path style="fill:#46B29D;" d="M328.61,98.163h0.088c1.971-0.012,3.923,0.379,5.738,1.148l71.683,29.484
c4.07,1.723,7.249,5.049,8.787,9.193c1.537,4.144,1.297,8.739-0.665,12.699l-11.652,24.099
c-5.942,12.252-10.388,25.174-13.242,38.488l-12.624,58.086c-1.107,5.424-5.003,9.857-10.24,11.652l-11.653,3.972
c-5.094,1.809-8.94,6.053-10.241,11.299l-6.885,28.513c-0.25,1.103-0.635,2.17-1.148,3.178l-5.473,11.211
c-2.003,4.139-5.709,7.201-10.152,8.386l-18.715,4.855c-7.018,1.83-11.893,8.196-11.829,15.448v11.211
c-0.023,3.42-1.102,6.75-3.09,9.534l-19.51,26.748c-3.683,5.056-5.967,10.993-6.621,17.214l-6.091,56.585
c-0.638,5.71-3.3,11.002-7.503,14.919c-4.172,3.812-9.621,5.922-15.272,5.914c-10.207-0.042-19.147-6.854-21.896-16.684
L187.45,416.75c-0.269-0.922-0.447-1.868-0.53-2.825l-17.656-163.84c-0.585-5.323-3.801-9.997-8.563-12.447l-21.629-11.211
c-5.391-2.781-9.662-7.331-12.094-12.888l-26.661-61.793c-4.326-9.941-2.235-21.509,5.297-29.308l10.064-10.417
c3.583-3.658,5.192-8.813,4.326-13.859l-4.414-27.63c-2.316-13.91,2.107-28.094,11.918-38.223l18.715-19.244
C154.266,4.72,165.356,0.003,176.945,0h29.662c11.59,0.003,22.679,4.72,30.721,13.065l16.244,16.684L328.61,98.163z"/>
<path style="fill:#BDC3C7;" d="M283.478,97.103h35.31V220.69c0,9.751-7.904,17.655-17.655,17.655l0,0
c-9.751,0-17.655-7.904-17.655-17.655V97.103z"/>
<circle style="fill:#CC4B4C;" cx="301.133" cy="52.966" r="52.966"/>
<path style="fill:#FB7B76;" d="M283.478,61.793c-4.875,0-8.828-3.952-8.828-8.828c0.016-14.619,11.863-26.467,26.483-26.483
c4.875,0,8.828,3.952,8.828,8.828s-3.952,8.828-8.828,8.828c-4.873,0.006-8.821,3.955-8.828,8.828
C292.305,57.841,288.353,61.793,283.478,61.793z"/>
</g>
<g>
</g>

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

99
res/ui/languages/kor.svg Normal file
View File

@ -0,0 +1,99 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<path style="fill:#F5F5F5;" d="M400,0H112C50.144,0,0,50.144,0,112v288c0,61.856,50.144,112,112,112h288
c61.856,0,112-50.144,112-112V112C512,50.144,461.856,0,400,0z"/>
<path style="fill:#FF4B55;" d="M305.008,182.532c-40.562-27.042-95.35-15.985-122.374,24.507
c-13.555,20.211-8.046,47.674,12.235,61.195c20.265,13.521,47.64,8.03,61.161-12.252c13.521-20.281,40.914-25.704,61.179-12.253
c20.297,13.521,25.756,40.984,12.217,61.195C356.468,264.362,345.537,209.574,305.008,182.532"/>
<path style="fill:#41479B;" d="M182.634,207.039c-13.555,20.211-8.046,47.674,12.235,61.195c20.265,13.521,47.64,8.03,61.161-12.252
c13.521-20.281,40.914-25.704,61.179-12.253c20.297,13.521,25.756,40.984,12.217,61.195
c-27.005,40.633-81.776,51.548-122.338,24.507C166.561,302.39,155.593,247.602,182.634,207.039"/>
<g>
<path style="fill:#464655;" d="M349.921,149.189l16.035,24.101c1.347,2.025,0.802,4.759-1.219,6.112l-4.066,2.723
c-2.029,1.359-4.775,0.812-6.129-1.22l-16.055-24.096c-1.351-2.027-0.804-4.766,1.222-6.118l4.086-2.728
C345.825,146.608,348.569,147.158,349.921,149.189z"/>
<path style="fill:#464655;" d="M374.66,186.351l16.087,24.087c1.358,2.034,0.804,4.785-1.237,6.134l-4.083,2.699
c-2.026,1.339-4.754,0.789-6.103-1.23l-16.078-24.061c-1.354-2.027-0.81-4.767,1.217-6.122l4.074-2.724
C370.564,183.778,373.306,184.323,374.66,186.351z"/>
<path style="fill:#464655;" d="M367.088,137.733l40.829,61.274c1.352,2.028,0.803,4.768-1.225,6.12l-4.102,2.735
c-2.028,1.352-4.769,0.804-6.121-1.224l-40.843-61.269c-1.353-2.029-0.803-4.771,1.227-6.122l4.115-2.739
C362.998,135.156,365.737,135.705,367.088,137.733z"/>
<path style="fill:#464655;" d="M384.211,126.291l16.07,24.149c1.353,2.034,0.797,4.78-1.241,6.128l-4.087,2.701
c-2.028,1.34-4.757,0.789-6.106-1.234l-16.082-24.117c-1.353-2.028-0.805-4.769,1.224-6.121l4.099-2.732
C380.117,123.711,382.859,124.261,384.211,126.291z"/>
<path style="fill:#464655;" d="M408.967,163.531l16.046,24.099c1.349,2.026,0.803,4.762-1.221,6.115l-4.075,2.725
c-2.029,1.357-4.774,0.809-6.127-1.223l-16.046-24.099c-1.349-2.026-0.803-4.762,1.221-6.115l4.075-2.725
C404.869,160.951,407.614,161.499,408.967,163.531z"/>
<path style="fill:#464655;" d="M132.72,293.982l40.824,61.208c1.352,2.027,0.806,4.767-1.221,6.12l-4.089,2.73
c-2.028,1.354-4.77,0.807-6.123-1.222l-40.824-61.208c-1.352-2.027-0.805-4.767,1.221-6.12l4.089-2.73
C128.626,291.406,131.367,291.954,132.72,293.982z"/>
<path style="fill:#464655;" d="M115.582,305.431l16.027,24.041c1.35,2.026,0.806,4.762-1.217,6.116l-4.066,2.722
c-2.027,1.357-4.771,0.812-6.126-1.217l-16.048-24.035c-1.354-2.027-0.807-4.768,1.22-6.122l4.086-2.728
C111.487,302.854,114.229,303.402,115.582,305.431z"/>
<path style="fill:#464655;" d="M140.351,342.605l16.047,24.101c1.349,2.026,0.803,4.763-1.221,6.115l-4.078,2.726
c-2.029,1.356-4.773,0.809-6.126-1.222l-16.057-24.097c-1.351-2.027-0.804-4.765,1.222-6.118l4.088-2.73
C136.255,340.026,138.999,340.574,140.351,342.605z"/>
<path style="fill:#464655;" d="M98.442,316.876l40.798,61.211c1.351,2.026,0.805,4.764-1.22,6.117l-4.077,2.725
c-2.028,1.356-4.771,0.809-6.125-1.22l-40.822-61.203c-1.353-2.028-0.805-4.769,1.224-6.122l4.101-2.734
C94.349,314.3,97.09,314.848,98.442,316.876z"/>
<path style="fill:#464655;" d="M121.295,210.441l40.818-61.257c1.353-2.03,4.095-2.578,6.124-1.223l4.087,2.729
c2.027,1.353,2.573,4.093,1.221,6.12l-40.834,61.222c-1.349,2.023-4.08,2.574-6.108,1.232l-4.071-2.694
C120.494,215.221,119.94,212.475,121.295,210.441z"/>
<path style="fill:#464655;" d="M104.147,199.009l40.826-61.269c1.353-2.031,4.097-2.578,6.126-1.222l4.077,2.725
c2.024,1.353,2.57,4.09,1.22,6.116l-40.815,61.273c-1.352,2.03-4.095,2.579-6.124,1.224l-4.088-2.729
C103.343,203.775,102.796,201.036,104.147,199.009z"/>
<path style="fill:#464655;" d="M86.991,187.625l40.829-61.33c1.353-2.032,4.098-2.58,6.127-1.223l4.077,2.726
c2.023,1.353,2.57,4.088,1.222,6.114L98.441,195.25c-1.351,2.031-4.093,2.581-6.123,1.228l-4.101-2.734
C86.189,192.392,85.64,189.653,86.991,187.625z"/>
<path style="fill:#464655;" d="M338.492,355.189l16.048-24.035c1.355-2.029,4.099-2.574,6.127-1.217l4.066,2.723
c2.023,1.354,2.567,4.091,1.217,6.116l-16.028,24.04c-1.353,2.029-4.095,2.577-6.123,1.223l-4.086-2.728
C337.685,359.957,337.138,357.217,338.492,355.189z"/>
<path style="fill:#464655;" d="M363.243,318.14l16.073-24.154c1.351-2.031,4.093-2.58,6.123-1.227l4.096,2.73
c2.03,1.353,2.577,4.096,1.222,6.124l-16.107,24.116c-1.35,2.022-4.082,2.571-6.109,1.228l-4.062-2.692
C362.445,322.916,361.891,320.172,363.243,318.14z"/>
<path style="fill:#464655;" d="M355.626,366.698l16.058-24.098c1.352-2.029,4.093-2.578,6.122-1.225l4.104,2.737
c2.027,1.352,2.576,4.09,1.225,6.118l-16.047,24.101c-1.351,2.029-4.091,2.579-6.12,1.228l-4.115-2.739
C354.824,371.469,354.274,368.728,355.626,366.698z"/>
<path style="fill:#464655;" d="M380.402,329.464l16.066-24.042c1.353-2.025,4.092-2.571,6.118-1.22l4.101,2.734
c2.03,1.353,2.577,4.096,1.221,6.125l-16.065,24.042c-1.353,2.025-4.091,2.571-6.118,1.22l-4.102-2.735
C379.594,334.235,379.047,331.492,380.402,329.464z"/>
<path style="fill:#464655;" d="M372.771,378.081l16.075-24.056c1.349-2.02,4.077-2.569,6.103-1.23l4.087,2.701
c2.04,1.348,2.595,4.097,1.239,6.131l-16.063,24.088c-1.352,2.028-4.092,2.576-6.121,1.224l-4.099-2.732
C371.963,382.853,371.416,380.109,372.771,378.081z"/>
<path style="fill:#464655;" d="M397.553,340.969l16.036-24.085c1.353-2.032,4.098-2.58,6.127-1.223l4.072,2.722
c2.025,1.354,2.57,4.093,1.218,6.119l-16.048,24.053c-1.35,2.023-4.083,2.573-6.11,1.229l-4.059-2.691
C396.754,345.746,396.201,343.001,397.553,340.969z"/>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.0 KiB

41
res/ui/languages/no.svg Normal file
View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<path style="fill:#FF4B55;" d="M400,0H112C50.144,0,0,50.144,0,112v288c0,61.856,50.144,112,112,112h288
c61.856,0,112-50.144,112-112V112C512,50.144,461.856,0,400,0z"/>
<polygon style="fill:#F5F5F5;" points="512,211.862 229.517,211.862 229.517,0 141.241,0 141.241,211.862 0,211.862 0,300.138
141.241,300.138 141.241,512 229.517,512 229.517,300.138 512,300.138 "/>
<polygon style="fill:#41479B;" points="512,229.517 211.862,229.517 211.862,0 158.897,0 158.897,229.517 0,229.517 0,282.483
158.897,282.483 158.897,512 211.862,512 211.862,282.483 512,282.483 "/>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<path style="fill:#FF4B55;" d="M400,0H185.379v512H400c61.856,0,112-50.144,112-112V112C512,50.144,461.856,0,400,0z"/>
<path style="fill:#73AF00;" d="M112,0C50.144,0,0,50.144,0,112v288c0,61.856,50.144,112,112,112h73.379V0H112z"/>
<circle style="fill:#FFE15A;" cx="185.45" cy="256" r="112.38"/>
<path style="fill:#FF4B55;" d="M222.941,218.508v49.99c0,20.673-16.819,37.492-37.492,37.492s-37.492-16.819-37.492-37.492v-49.99
L222.941,218.508 M235.438,193.513h-99.98c-6.902,0-12.497,5.595-12.497,12.497v62.487c0,34.511,27.977,62.487,62.487,62.487
s62.487-27.977,62.487-62.487V206.01C247.936,199.108,242.34,193.513,235.438,193.513L235.438,193.513z"/>
<path style="fill:#F5F5F5;" d="M211.931,229.517v35.31c0,14.603-11.88,26.483-26.483,26.483s-26.483-11.88-26.483-26.483v-35.31
H211.931"/>
<g>
<circle style="fill:#FFE15A;" cx="135.36" cy="206.01" r="6.249"/>
<circle style="fill:#FFE15A;" cx="235.34" cy="206.01" r="6.249"/>
<circle style="fill:#FFE15A;" cx="135.36" cy="256" r="6.249"/>
<circle style="fill:#FFE15A;" cx="235.34" cy="256" r="6.249"/>
<circle style="fill:#FFE15A;" cx="185.35" cy="206.01" r="6.249"/>
<circle style="fill:#FFE15A;" cx="222.87" cy="302.08" r="6.249"/>
<circle style="fill:#FFE15A;" cx="148.57" cy="302.08" r="6.249"/>
</g>
<g>
<path style="fill:#41479B;" d="M193.52,252.832v10.762c0,4.451-3.621,8.071-8.071,8.071s-8.071-3.621-8.071-8.071v-10.762H193.52"
/>
<path style="fill:#41479B;" d="M193.52,227.317v10.762c0,4.451-3.621,8.071-8.071,8.071s-8.071-3.621-8.071-8.071v-10.762H193.52"
/>
<path style="fill:#41479B;" d="M193.52,278.608v10.762c0,4.451-3.621,8.071-8.071,8.071s-8.071-3.621-8.071-8.071v-10.762H193.52"
/>
<path style="fill:#41479B;" d="M215.26,252.832v10.762c0,4.451-3.621,8.071-8.071,8.071s-8.071-3.621-8.071-8.071v-10.762H215.26"
/>
<path style="fill:#41479B;" d="M171.779,252.832v10.762c0,4.451-3.621,8.071-8.071,8.071s-8.071-3.621-8.071-8.071v-10.762H171.779
"/>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<path style="fill:#FF4B55;" d="M400,0H112C50.144,0,0,50.144,0,112v288c0,61.856,50.144,112,112,112h288 c61.856,0,112-50.144,112-112V112C512,50.144,461.856,0,400,0z"/>
<g>
<path style="fill:#FFE15A;" d="M114.021,87.182l12.722,38.146l40.21,0.312c5.206,0.04,7.365,6.684,3.177,9.777l-32.348,23.887 l12.129,38.339c1.57,4.964-4.081,9.07-8.317,6.042l-32.714-23.383l-32.714,23.383c-4.235,3.027-9.887-1.079-8.317-6.042 l12.129-38.339L47.63,135.417c-4.188-3.093-2.029-9.736,3.177-9.777l40.21-0.312l12.722-38.146 C105.388,82.243,112.374,82.243,114.021,87.182z"/>
<path style="fill:#FFE15A;" d="M260.037,96.582l9.122,12.44l14.723-4.604c1.906-0.596,3.474,1.577,2.307,3.198l-9.012,12.52 l8.928,12.58c1.156,1.629-0.427,3.791-2.329,3.183l-14.692-4.702l-9.205,12.378c-1.192,1.603-3.738,0.766-3.746-1.231 l-0.068-15.426l-14.617-4.929c-1.893-0.638-1.883-3.318,0.013-3.944l14.65-4.831l0.171-15.425 C256.305,95.791,258.856,94.971,260.037,96.582z"/>
<path style="fill:#FFE15A;" d="M204.496,59.501l15.336,1.667l6.542-13.97c0.847-1.809,3.509-1.499,3.917,0.457l3.154,15.1 l15.308,1.905c1.982,0.247,2.509,2.874,0.776,3.866l-13.387,7.665l2.919,15.147c0.378,1.961-1.958,3.275-3.437,1.933 l-11.427-10.363l-13.504,7.457c-1.748,0.965-3.719-0.85-2.901-2.672l6.324-14.07l-11.265-10.539 C201.393,61.721,202.511,59.285,204.496,59.501z"/>
<path style="fill:#FFE15A;" d="M228.739,208.997l-9.122,12.44l-14.723-4.604c-1.906-0.596-3.474,1.577-2.307,3.198l9.012,12.52 l-8.928,12.58c-1.156,1.629,0.426,3.791,2.329,3.183l14.692-4.702l9.205,12.378c1.192,1.603,3.738,0.766,3.746-1.231l0.068-15.426 l14.617-4.929c1.892-0.638,1.883-3.318-0.013-3.943l-14.65-4.831l-0.171-15.425C232.472,208.206,229.92,207.386,228.739,208.997z"/>
<path style="fill:#FFE15A;" d="M284.281,174.151l-15.336,1.667l-6.542-13.97c-0.847-1.809-3.509-1.499-3.917,0.456l-3.154,15.1 l-15.308,1.905c-1.982,0.247-2.509,2.874-0.776,3.866l13.387,7.665l-2.919,15.147c-0.378,1.961,1.958,3.275,3.437,1.933 l11.427-10.363l13.504,7.457c1.748,0.965,3.719-0.85,2.901-2.672l-6.324-14.07l11.265-10.539 C287.384,176.371,286.266,173.935,284.281,174.151z"/>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -74,7 +74,7 @@
},
"sprites/belt/left_3.png":
{
"frame": {"x":313,"y":112,"w":13,"h":13},
"frame": {"x":289,"y":49,"w":13,"h":13},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":13,"h":13},
@ -82,7 +82,7 @@
},
"sprites/belt/left_4.png":
{
"frame": {"x":289,"y":26,"w":13,"h":13},
"frame": {"x":306,"y":49,"w":13,"h":13},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":13,"h":13},
@ -90,7 +90,7 @@
},
"sprites/belt/left_5.png":
{
"frame": {"x":306,"y":26,"w":13,"h":13},
"frame": {"x":323,"y":49,"w":13,"h":13},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":13,"h":13},
@ -98,7 +98,7 @@
},
"sprites/belt/right_0.png":
{
"frame": {"x":330,"y":112,"w":13,"h":13},
"frame": {"x":313,"y":112,"w":13,"h":13},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":13,"h":13},
@ -106,7 +106,7 @@
},
"sprites/belt/right_1.png":
{
"frame": {"x":347,"y":112,"w":13,"h":13},
"frame": {"x":330,"y":112,"w":13,"h":13},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":13,"h":13},
@ -114,7 +114,7 @@
},
"sprites/belt/right_2.png":
{
"frame": {"x":323,"y":26,"w":13,"h":13},
"frame": {"x":340,"y":49,"w":13,"h":13},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":13,"h":13},
@ -122,7 +122,7 @@
},
"sprites/belt/right_3.png":
{
"frame": {"x":364,"y":111,"w":13,"h":13},
"frame": {"x":347,"y":112,"w":13,"h":13},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":13,"h":13},
@ -130,7 +130,7 @@
},
"sprites/belt/right_4.png":
{
"frame": {"x":381,"y":111,"w":13,"h":13},
"frame": {"x":357,"y":49,"w":13,"h":13},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":13,"h":13},
@ -138,7 +138,7 @@
},
"sprites/belt/right_5.png":
{
"frame": {"x":340,"y":25,"w":13,"h":13},
"frame": {"x":374,"y":49,"w":13,"h":13},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":13,"h":13},
@ -146,7 +146,7 @@
},
"sprites/blueprints/belt_left.png":
{
"frame": {"x":357,"y":23,"w":13,"h":13},
"frame": {"x":391,"y":48,"w":13,"h":13},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":13,"h":13},
@ -154,7 +154,7 @@
},
"sprites/blueprints/belt_right.png":
{
"frame": {"x":374,"y":23,"w":13,"h":13},
"frame": {"x":404,"y":25,"w":13,"h":13},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":13,"h":13},
@ -162,7 +162,7 @@
},
"sprites/blueprints/belt_top.png":
{
"frame": {"x":391,"y":23,"w":13,"h":13},
"frame": {"x":400,"y":85,"w":13,"h":13},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":13,"h":13},
@ -178,7 +178,7 @@
},
"sprites/blueprints/cutter.png":
{
"frame": {"x":207,"y":43,"w":36,"h":19},
"frame": {"x":245,"y":66,"w":36,"h":19},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":36,"h":19},
@ -186,7 +186,7 @@
},
"sprites/blueprints/miner-chainable.png":
{
"frame": {"x":285,"y":3,"w":19,"h":19},
"frame": {"x":285,"y":66,"w":19,"h":19},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":19,"h":19},
@ -194,7 +194,7 @@
},
"sprites/blueprints/miner.png":
{
"frame": {"x":245,"y":89,"w":19,"h":19},
"frame": {"x":285,"y":89,"w":19,"h":19},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":19,"h":19},
@ -202,7 +202,7 @@
},
"sprites/blueprints/mixer.png":
{
"frame": {"x":166,"y":45,"w":37,"h":19},
"frame": {"x":204,"y":68,"w":37,"h":19},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":37,"h":19},
@ -216,6 +216,14 @@
"spriteSourceSize": {"x":0,"y":0,"w":38,"h":38},
"sourceSize": {"w":38,"h":38}
},
"sprites/blueprints/painter-mirrored.png":
{
"frame": {"x":82,"y":49,"w":38,"h":19},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":38,"h":19},
"sourceSize": {"w":38,"h":19}
},
"sprites/blueprints/painter-quad.png":
{
"frame": {"x":3,"y":83,"w":77,"h":19},
@ -226,7 +234,7 @@
},
"sprites/blueprints/painter.png":
{
"frame": {"x":82,"y":49,"w":38,"h":19},
"frame": {"x":124,"y":49,"w":38,"h":19},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":38,"h":19},
@ -234,7 +242,7 @@
},
"sprites/blueprints/rotater-ccw.png":
{
"frame": {"x":268,"y":89,"w":19,"h":19},
"frame": {"x":289,"y":26,"w":19,"h":19},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":19,"h":19},
@ -242,7 +250,7 @@
},
"sprites/blueprints/rotater.png":
{
"frame": {"x":285,"y":66,"w":19,"h":19},
"frame": {"x":312,"y":26,"w":19,"h":19},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":19,"h":19},
@ -250,7 +258,7 @@
},
"sprites/blueprints/splitter-compact-inverse.png":
{
"frame": {"x":291,"y":89,"w":19,"h":19},
"frame": {"x":327,"y":3,"w":19,"h":19},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":19,"h":19},
@ -258,7 +266,7 @@
},
"sprites/blueprints/splitter-compact.png":
{
"frame": {"x":287,"y":43,"w":19,"h":19},
"frame": {"x":308,"y":66,"w":19,"h":19},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":19,"h":19},
@ -266,7 +274,7 @@
},
"sprites/blueprints/splitter.png":
{
"frame": {"x":245,"y":3,"w":36,"h":19},
"frame": {"x":249,"y":43,"w":36,"h":19},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":36,"h":19},
@ -274,7 +282,7 @@
},
"sprites/blueprints/stacker.png":
{
"frame": {"x":204,"y":3,"w":37,"h":19},
"frame": {"x":204,"y":91,"w":37,"h":19},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":37,"h":19},
@ -290,7 +298,7 @@
},
"sprites/blueprints/trash.png":
{
"frame": {"x":308,"y":66,"w":19,"h":19},
"frame": {"x":335,"y":26,"w":19,"h":19},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":19,"h":19},
@ -298,7 +306,7 @@
},
"sprites/blueprints/underground_belt_entry-tier2.png":
{
"frame": {"x":360,"y":89,"w":19,"h":18},
"frame": {"x":381,"y":26,"w":19,"h":18},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":1,"w":19,"h":18},
@ -306,7 +314,7 @@
},
"sprites/blueprints/underground_belt_entry.png":
{
"frame": {"x":354,"y":3,"w":19,"h":16},
"frame": {"x":354,"y":89,"w":19,"h":16},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":3,"w":19,"h":16},
@ -314,7 +322,7 @@
},
"sprites/blueprints/underground_belt_exit-tier2.png":
{
"frame": {"x":356,"y":42,"w":19,"h":16},
"frame": {"x":364,"y":109,"w":19,"h":16},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":19,"h":16},
@ -322,7 +330,7 @@
},
"sprites/blueprints/underground_belt_exit.png":
{
"frame": {"x":377,"y":62,"w":19,"h":16},
"frame": {"x":377,"y":66,"w":19,"h":16},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":19,"h":16},
@ -338,7 +346,7 @@
},
"sprites/buildings/belt_right.png":
{
"frame": {"x":330,"y":112,"w":13,"h":13},
"frame": {"x":313,"y":112,"w":13,"h":13},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":13,"h":13},
@ -362,7 +370,7 @@
},
"sprites/buildings/cutter.png":
{
"frame": {"x":245,"y":66,"w":36,"h":19},
"frame": {"x":287,"y":3,"w":36,"h":19},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":36,"h":19},
@ -378,7 +386,7 @@
},
"sprites/buildings/miner-chainable.png":
{
"frame": {"x":314,"y":89,"w":19,"h":19},
"frame": {"x":350,"y":3,"w":19,"h":19},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":19,"h":19},
@ -386,7 +394,7 @@
},
"sprites/buildings/miner.png":
{
"frame": {"x":310,"y":43,"w":19,"h":19},
"frame": {"x":308,"y":89,"w":19,"h":19},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":19,"h":19},
@ -394,7 +402,7 @@
},
"sprites/buildings/mixer.png":
{
"frame": {"x":204,"y":68,"w":37,"h":19},
"frame": {"x":208,"y":43,"w":37,"h":19},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":37,"h":19},
@ -408,6 +416,14 @@
"spriteSourceSize": {"x":0,"y":0,"w":38,"h":38},
"sourceSize": {"w":38,"h":38}
},
"sprites/buildings/painter-mirrored.png":
{
"frame": {"x":166,"y":45,"w":38,"h":19},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":38,"h":19},
"sourceSize": {"w":38,"h":19}
},
"sprites/buildings/painter-quad.png":
{
"frame": {"x":3,"y":106,"w":77,"h":19},
@ -418,7 +434,7 @@
},
"sprites/buildings/painter.png":
{
"frame": {"x":124,"y":49,"w":38,"h":19},
"frame": {"x":204,"y":3,"w":38,"h":19},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":38,"h":19},
@ -434,7 +450,7 @@
},
"sprites/buildings/rotater.png":
{
"frame": {"x":337,"y":89,"w":19,"h":19},
"frame": {"x":331,"y":89,"w":19,"h":19},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":19,"h":19},
@ -442,7 +458,7 @@
},
"sprites/buildings/splitter-compact-inverse.png":
{
"frame": {"x":308,"y":3,"w":19,"h":19},
"frame": {"x":354,"y":66,"w":19,"h":19},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":19,"h":19},
@ -450,7 +466,7 @@
},
"sprites/buildings/splitter-compact.png":
{
"frame": {"x":333,"y":43,"w":19,"h":19},
"frame": {"x":358,"y":26,"w":19,"h":19},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":19,"h":19},
@ -458,7 +474,7 @@
},
"sprites/buildings/splitter.png":
{
"frame": {"x":247,"y":43,"w":36,"h":19},
"frame": {"x":245,"y":89,"w":36,"h":19},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":36,"h":19},
@ -466,7 +482,7 @@
},
"sprites/buildings/stacker.png":
{
"frame": {"x":204,"y":91,"w":37,"h":19},
"frame": {"x":246,"y":3,"w":37,"h":19},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":37,"h":19},
@ -482,7 +498,7 @@
},
"sprites/buildings/trash.png":
{
"frame": {"x":354,"y":66,"w":19,"h":19},
"frame": {"x":373,"y":3,"w":19,"h":19},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":19,"h":19},
@ -490,7 +506,7 @@
},
"sprites/buildings/underground_belt_entry-tier2.png":
{
"frame": {"x":331,"y":3,"w":19,"h":18},
"frame": {"x":396,"y":3,"w":19,"h":18},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":1,"w":19,"h":18},
@ -498,7 +514,7 @@
},
"sprites/buildings/underground_belt_entry.png":
{
"frame": {"x":383,"y":82,"w":19,"h":16},
"frame": {"x":377,"y":86,"w":19,"h":16},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":3,"w":19,"h":16},
@ -506,7 +522,7 @@
},
"sprites/buildings/underground_belt_exit-tier2.png":
{
"frame": {"x":377,"y":3,"w":19,"h":16},
"frame": {"x":387,"y":106,"w":19,"h":16},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":19,"h":16},
@ -514,7 +530,7 @@
},
"sprites/buildings/underground_belt_exit.png":
{
"frame": {"x":379,"y":40,"w":19,"h":16},
"frame": {"x":400,"y":65,"w":19,"h":16},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":19,"h":16},
@ -538,7 +554,7 @@
},
"sprites/map_overview/belt_forward.png":
{
"frame": {"x":102,"y":72,"w":3,"h":3},
"frame": {"x":111,"y":72,"w":3,"h":3},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":3,"h":3},
@ -546,7 +562,7 @@
},
"sprites/map_overview/belt_left.png":
{
"frame": {"x":109,"y":72,"w":3,"h":3},
"frame": {"x":118,"y":72,"w":3,"h":3},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":3,"h":3},
@ -554,7 +570,7 @@
},
"sprites/map_overview/belt_right.png":
{
"frame": {"x":116,"y":72,"w":3,"h":3},
"frame": {"x":125,"y":72,"w":3,"h":3},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":3,"h":3},
@ -568,6 +584,22 @@
"spriteSourceSize": {"x":0,"y":0,"w":10,"h":10},
"sourceSize": {"w":10,"h":10}
},
"sprites/misc/hub_direction_indicator.png":
{
"frame": {"x":132,"y":72,"w":3,"h":3},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":3,"h":3},
"sourceSize": {"w":3,"h":3}
},
"sprites/misc/lock_direction_indicator.png":
{
"frame": {"x":102,"y":72,"w":5,"h":5},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":5,"h":5},
"sourceSize": {"w":5,"h":5}
},
"sprites/misc/slot_bad_arrow.png":
{
"frame": {"x":187,"y":114,"w":10,"h":10},
@ -594,7 +626,7 @@
},
"sprites/misc/waypoint.png":
{
"frame": {"x":123,"y":72,"w":3,"h":3},
"frame": {"x":139,"y":72,"w":3,"h":3},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":3,"h":3},
@ -605,8 +637,8 @@
"version": "1.0",
"image": "atlas0_10.png",
"format": "RGBA8888",
"size": {"w":407,"h":128},
"size": {"w":422,"h":128},
"scale": "0.1",
"smartupdate": "$TexturePacker:SmartUpdate:3dd7a89f30024dd4787ad4af6b14588a:9ba11f8b02134c4376ab4e0a44f8b850:f159918d23e5952766c6d23ab52278c6$"
"smartupdate": "$TexturePacker:SmartUpdate:8985524bba1a3f16cecab3c03b6aaa06:d614d20bfce033d8a8ab0990af085d16:f159918d23e5952766c6d23ab52278c6$"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 52 KiB

View File

@ -2,7 +2,7 @@
"sprites/belt/forward_0.png":
{
"frame": {"x":1871,"y":1504,"w":100,"h":126},
"frame": {"x":1876,"y":1166,"w":100,"h":126},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":13,"y":0,"w":100,"h":126},
@ -10,7 +10,7 @@
},
"sprites/belt/forward_1.png":
{
"frame": {"x":1871,"y":240,"w":100,"h":126},
"frame": {"x":1876,"y":1296,"w":100,"h":126},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":13,"y":0,"w":100,"h":126},
@ -18,7 +18,7 @@
},
"sprites/belt/forward_2.png":
{
"frame": {"x":1844,"y":394,"w":100,"h":126},
"frame": {"x":1869,"y":1543,"w":100,"h":126},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":13,"y":0,"w":100,"h":126},
@ -26,7 +26,7 @@
},
"sprites/belt/forward_3.png":
{
"frame": {"x":1871,"y":1634,"w":100,"h":126},
"frame": {"x":1857,"y":395,"w":100,"h":126},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":13,"y":0,"w":100,"h":126},
@ -34,7 +34,7 @@
},
"sprites/belt/forward_4.png":
{
"frame": {"x":1433,"y":785,"w":100,"h":126},
"frame": {"x":1865,"y":1690,"w":100,"h":126},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":13,"y":0,"w":100,"h":126},
@ -42,7 +42,7 @@
},
"sprites/belt/forward_5.png":
{
"frame": {"x":917,"y":1564,"w":100,"h":126},
"frame": {"x":920,"y":1370,"w":100,"h":126},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":13,"y":0,"w":100,"h":126},
@ -50,7 +50,7 @@
},
"sprites/belt/left_0.png":
{
"frame": {"x":1021,"y":1563,"w":113,"h":113},
"frame": {"x":1870,"y":1426,"w":113,"h":113},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":13,"w":113,"h":113},
@ -58,7 +58,7 @@
},
"sprites/belt/left_1.png":
{
"frame": {"x":1138,"y":1563,"w":113,"h":113},
"frame": {"x":920,"y":1500,"w":113,"h":113},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":13,"w":113,"h":113},
@ -66,7 +66,7 @@
},
"sprites/belt/left_2.png":
{
"frame": {"x":1255,"y":1563,"w":113,"h":113},
"frame": {"x":935,"y":1617,"w":113,"h":113},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":13,"w":113,"h":113},
@ -74,7 +74,7 @@
},
"sprites/belt/left_3.png":
{
"frame": {"x":1372,"y":1562,"w":113,"h":113},
"frame": {"x":935,"y":1734,"w":113,"h":113},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":13,"w":113,"h":113},
@ -82,7 +82,7 @@
},
"sprites/belt/left_4.png":
{
"frame": {"x":1489,"y":1562,"w":113,"h":113},
"frame": {"x":1052,"y":1721,"w":113,"h":113},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":13,"w":113,"h":113},
@ -90,7 +90,7 @@
},
"sprites/belt/left_5.png":
{
"frame": {"x":1021,"y":1680,"w":113,"h":113},
"frame": {"x":1169,"y":1721,"w":113,"h":113},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":13,"w":113,"h":113},
@ -98,7 +98,7 @@
},
"sprites/belt/right_0.png":
{
"frame": {"x":1138,"y":1680,"w":113,"h":113},
"frame": {"x":1286,"y":1721,"w":113,"h":113},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":13,"y":13,"w":113,"h":113},
@ -106,7 +106,7 @@
},
"sprites/belt/right_1.png":
{
"frame": {"x":1255,"y":1680,"w":113,"h":113},
"frame": {"x":1403,"y":1721,"w":113,"h":113},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":13,"y":13,"w":113,"h":113},
@ -114,7 +114,7 @@
},
"sprites/belt/right_2.png":
{
"frame": {"x":1372,"y":1679,"w":113,"h":113},
"frame": {"x":1520,"y":1721,"w":113,"h":113},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":13,"y":13,"w":113,"h":113},
@ -122,7 +122,7 @@
},
"sprites/belt/right_3.png":
{
"frame": {"x":1489,"y":1679,"w":113,"h":113},
"frame": {"x":1052,"y":1552,"w":113,"h":113},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":13,"y":13,"w":113,"h":113},
@ -130,7 +130,7 @@
},
"sprites/belt/right_4.png":
{
"frame": {"x":1606,"y":1676,"w":113,"h":113},
"frame": {"x":1169,"y":1552,"w":113,"h":113},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":13,"y":13,"w":113,"h":113},
@ -138,7 +138,7 @@
},
"sprites/belt/right_5.png":
{
"frame": {"x":1723,"y":1676,"w":113,"h":113},
"frame": {"x":1286,"y":1554,"w":113,"h":113},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":13,"y":13,"w":113,"h":113},
@ -162,7 +162,7 @@
},
"sprites/blueprints/belt_top.png":
{
"frame": {"x":1871,"y":1374,"w":102,"h":126},
"frame": {"x":1871,"y":240,"w":102,"h":126},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":12,"y":0,"w":102,"h":126},
@ -178,7 +178,7 @@
},
"sprites/blueprints/cutter.png":
{
"frame": {"x":726,"y":979,"w":341,"h":191},
"frame": {"x":1433,"y":785,"w":341,"h":191},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":23,"y":0,"w":341,"h":191},
@ -186,7 +186,7 @@
},
"sprites/blueprints/miner-chainable.png":
{
"frame": {"x":1500,"y":1368,"w":182,"h":190},
"frame": {"x":749,"y":1655,"w":182,"h":190},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":6,"y":0,"w":182,"h":190},
@ -194,7 +194,7 @@
},
"sprites/blueprints/miner.png":
{
"frame": {"x":1437,"y":590,"w":182,"h":190},
"frame": {"x":1690,"y":1174,"w":182,"h":190},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":6,"y":0,"w":182,"h":190},
@ -202,7 +202,7 @@
},
"sprites/blueprints/mixer.png":
{
"frame": {"x":735,"y":590,"w":347,"h":191},
"frame": {"x":1123,"y":590,"w":347,"h":191},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":18,"y":0,"w":347,"h":191},
@ -216,6 +216,14 @@
"spriteSourceSize": {"x":0,"y":0,"w":384,"h":382},
"sourceSize": {"w":384,"h":384}
},
"sprites/blueprints/painter-mirrored.png":
{
"frame": {"x":1485,"y":3,"w":384,"h":192},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":384,"h":192},
"sourceSize": {"w":384,"h":192}
},
"sprites/blueprints/painter-quad.png":
{
"frame": {"x":735,"y":3,"w":746,"h":192},
@ -226,7 +234,7 @@
},
"sprites/blueprints/painter.png":
{
"frame": {"x":1485,"y":3,"w":384,"h":192},
"frame": {"x":1483,"y":199,"w":384,"h":192},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":384,"h":192},
@ -234,7 +242,7 @@
},
"sprites/blueprints/rotater-ccw.png":
{
"frame": {"x":1116,"y":1368,"w":189,"h":191},
"frame": {"x":922,"y":1174,"w":189,"h":191},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":0,"w":189,"h":191},
@ -242,7 +250,7 @@
},
"sprites/blueprints/rotater.png":
{
"frame": {"x":724,"y":1564,"w":189,"h":191},
"frame": {"x":1115,"y":1173,"w":189,"h":191},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":0,"w":189,"h":191},
@ -250,7 +258,7 @@
},
"sprites/blueprints/splitter-compact-inverse.png":
{
"frame": {"x":1652,"y":394,"w":188,"h":182},
"frame": {"x":1756,"y":980,"w":188,"h":182},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":4,"w":188,"h":182},
@ -258,7 +266,7 @@
},
"sprites/blueprints/splitter-compact.png":
{
"frame": {"x":1623,"y":587,"w":185,"h":182},
"frame": {"x":1306,"y":1368,"w":185,"h":182},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":7,"y":4,"w":185,"h":182},
@ -266,7 +274,7 @@
},
"sprites/blueprints/splitter.png":
{
"frame": {"x":1071,"y":979,"w":340,"h":191},
"frame": {"x":726,"y":979,"w":340,"h":191},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":23,"y":0,"w":340,"h":191},
@ -274,7 +282,7 @@
},
"sprites/blueprints/stacker.png":
{
"frame": {"x":1086,"y":590,"w":347,"h":191},
"frame": {"x":1474,"y":590,"w":347,"h":191},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":18,"y":0,"w":347,"h":191},
@ -290,7 +298,7 @@
},
"sprites/blueprints/trash.png":
{
"frame": {"x":724,"y":1368,"w":192,"h":192},
"frame": {"x":726,"y":1174,"w":192,"h":192},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":192,"h":192},
@ -298,7 +306,7 @@
},
"sprites/blueprints/underground_belt_entry-tier2.png":
{
"frame": {"x":1791,"y":1035,"w":183,"h":166},
"frame": {"x":1683,"y":1368,"w":183,"h":166},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":26,"w":183,"h":166},
@ -306,7 +314,7 @@
},
"sprites/blueprints/underground_belt_entry.png":
{
"frame": {"x":1812,"y":580,"w":182,"h":148},
"frame": {"x":192,"y":1702,"w":182,"h":148},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":6,"y":44,"w":182,"h":148},
@ -314,7 +322,7 @@
},
"sprites/blueprints/underground_belt_exit-tier2.png":
{
"frame": {"x":1623,"y":773,"w":185,"h":148},
"frame": {"x":3,"y":1702,"w":185,"h":148},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":185,"h":148},
@ -322,7 +330,7 @@
},
"sprites/blueprints/underground_belt_exit.png":
{
"frame": {"x":1812,"y":732,"w":182,"h":148},
"frame": {"x":1683,"y":1538,"w":182,"h":148},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":6,"y":0,"w":182,"h":148},
@ -330,7 +338,7 @@
},
"sprites/buildings/belt_left.png":
{
"frame": {"x":1021,"y":1563,"w":113,"h":113},
"frame": {"x":1870,"y":1426,"w":113,"h":113},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":13,"w":113,"h":113},
@ -338,7 +346,7 @@
},
"sprites/buildings/belt_right.png":
{
"frame": {"x":1138,"y":1680,"w":113,"h":113},
"frame": {"x":1286,"y":1721,"w":113,"h":113},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":13,"y":13,"w":113,"h":113},
@ -346,7 +354,7 @@
},
"sprites/buildings/belt_top.png":
{
"frame": {"x":1871,"y":1504,"w":100,"h":126},
"frame": {"x":1876,"y":1166,"w":100,"h":126},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":13,"y":0,"w":100,"h":126},
@ -362,7 +370,7 @@
},
"sprites/buildings/cutter.png":
{
"frame": {"x":726,"y":1174,"w":339,"h":190},
"frame": {"x":1070,"y":979,"w":339,"h":190},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":24,"y":0,"w":339,"h":190},
@ -378,7 +386,7 @@
},
"sprites/buildings/miner-chainable.png":
{
"frame": {"x":1469,"y":395,"w":179,"h":188},
"frame": {"x":1825,"y":590,"w":179,"h":188},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":8,"y":1,"w":179,"h":188},
@ -386,7 +394,7 @@
},
"sprites/buildings/miner.png":
{
"frame": {"x":1415,"y":979,"w":179,"h":189},
"frame": {"x":1778,"y":785,"w":179,"h":189},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":8,"y":0,"w":179,"h":189},
@ -408,6 +416,14 @@
"spriteSourceSize": {"x":0,"y":0,"w":384,"h":381},
"sourceSize": {"w":384,"h":384}
},
"sprites/buildings/painter-mirrored.png":
{
"frame": {"x":735,"y":590,"w":384,"h":191},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":384,"h":191},
"sourceSize": {"w":384,"h":192}
},
"sprites/buildings/painter-quad.png":
{
"frame": {"x":735,"y":199,"w":744,"h":192},
@ -418,7 +434,7 @@
},
"sprites/buildings/painter.png":
{
"frame": {"x":1483,"y":199,"w":384,"h":191},
"frame": {"x":1469,"y":395,"w":384,"h":191},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":384,"h":191},
@ -426,7 +442,7 @@
},
"sprites/buildings/rotater-ccw.png":
{
"frame": {"x":1309,"y":1368,"w":187,"h":190},
"frame": {"x":1308,"y":1174,"w":187,"h":190},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":0,"w":187,"h":190},
@ -434,7 +450,7 @@
},
"sprites/buildings/rotater.png":
{
"frame": {"x":1412,"y":1174,"w":187,"h":190},
"frame": {"x":1499,"y":1174,"w":187,"h":190},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":0,"w":187,"h":190},
@ -442,7 +458,7 @@
},
"sprites/buildings/splitter-compact-inverse.png":
{
"frame": {"x":1598,"y":925,"w":187,"h":180},
"frame": {"x":1115,"y":1368,"w":187,"h":180},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":5,"w":187,"h":180},
@ -450,7 +466,7 @@
},
"sprites/buildings/splitter-compact.png":
{
"frame": {"x":1603,"y":1109,"w":184,"h":180},
"frame": {"x":1495,"y":1368,"w":184,"h":180},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":8,"y":5,"w":184,"h":180},
@ -458,7 +474,7 @@
},
"sprites/buildings/splitter.png":
{
"frame": {"x":1069,"y":1174,"w":339,"h":190},
"frame": {"x":1413,"y":980,"w":339,"h":190},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":24,"y":0,"w":339,"h":190},
@ -482,7 +498,7 @@
},
"sprites/buildings/trash.png":
{
"frame": {"x":920,"y":1368,"w":192,"h":191},
"frame": {"x":724,"y":1370,"w":192,"h":191},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":1,"w":192,"h":191},
@ -490,7 +506,7 @@
},
"sprites/buildings/underground_belt_entry-tier2.png":
{
"frame": {"x":1791,"y":1205,"w":181,"h":165},
"frame": {"x":1495,"y":1552,"w":181,"h":165},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":7,"y":27,"w":181,"h":165},
@ -498,7 +514,7 @@
},
"sprites/buildings/underground_belt_entry.png":
{
"frame": {"x":1686,"y":1374,"w":181,"h":147},
"frame": {"x":564,"y":1707,"w":181,"h":147},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":7,"y":45,"w":181,"h":147},
@ -506,7 +522,7 @@
},
"sprites/buildings/underground_belt_exit-tier2.png":
{
"frame": {"x":1812,"y":884,"w":182,"h":147},
"frame": {"x":378,"y":1707,"w":182,"h":147},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":7,"y":0,"w":182,"h":147},
@ -514,7 +530,7 @@
},
"sprites/buildings/underground_belt_exit.png":
{
"frame": {"x":1686,"y":1525,"w":181,"h":147},
"frame": {"x":1680,"y":1690,"w":181,"h":147},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":7,"y":0,"w":181,"h":147},
@ -522,7 +538,7 @@
},
"sprites/debug/acceptor_slot.png":
{
"frame": {"x":1603,"y":1293,"w":50,"h":64},
"frame": {"x":1961,"y":782,"w":50,"h":64},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":7,"y":0,"w":50,"h":64},
@ -530,7 +546,7 @@
},
"sprites/debug/ejector_slot.png":
{
"frame": {"x":1606,"y":1562,"w":50,"h":64},
"frame": {"x":1961,"y":850,"w":50,"h":64},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":7,"y":0,"w":50,"h":64},
@ -538,7 +554,7 @@
},
"sprites/map_overview/belt_forward.png":
{
"frame": {"x":353,"y":1702,"w":24,"h":32},
"frame": {"x":1637,"y":1721,"w":24,"h":32},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":0,"w":24,"h":32},
@ -546,7 +562,7 @@
},
"sprites/map_overview/belt_left.png":
{
"frame": {"x":1433,"y":915,"w":28,"h":28},
"frame": {"x":1893,"y":525,"w":28,"h":28},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":4,"w":28,"h":28},
@ -554,7 +570,7 @@
},
"sprites/map_overview/belt_right.png":
{
"frame": {"x":1433,"y":947,"w":28,"h":28},
"frame": {"x":1080,"y":1669,"w":28,"h":28},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":4,"w":28,"h":28},
@ -562,15 +578,31 @@
},
"sprites/misc/deletion_marker.png":
{
"frame": {"x":267,"y":1702,"w":82,"h":82},
"frame": {"x":1403,"y":1554,"w":82,"h":82},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":7,"y":7,"w":82,"h":82},
"sourceSize": {"w":96,"h":96}
},
"sprites/misc/hub_direction_indicator.png":
{
"frame": {"x":1857,"y":525,"w":32,"h":32},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":32,"h":32},
"sourceSize": {"w":32,"h":32}
},
"sprites/misc/lock_direction_indicator.png":
{
"frame": {"x":1961,"y":918,"w":48,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":9,"w":48,"h":30},
"sourceSize": {"w":48,"h":48}
},
"sprites/misc/slot_bad_arrow.png":
{
"frame": {"x":267,"y":1702,"w":82,"h":82},
"frame": {"x":1403,"y":1554,"w":82,"h":82},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":7,"y":7,"w":82,"h":82},
@ -578,7 +610,7 @@
},
"sprites/misc/slot_good_arrow.png":
{
"frame": {"x":183,"y":1702,"w":80,"h":96},
"frame": {"x":1024,"y":1369,"w":80,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":8,"y":0,"w":80,"h":96},
@ -586,7 +618,7 @@
},
"sprites/misc/storage_overlay.png":
{
"frame": {"x":3,"y":1702,"w":176,"h":86},
"frame": {"x":724,"y":1565,"w":176,"h":86},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":4,"w":176,"h":86},
@ -594,7 +626,7 @@
},
"sprites/misc/waypoint.png":
{
"frame": {"x":1844,"y":524,"w":24,"h":32},
"frame": {"x":1052,"y":1669,"w":24,"h":32},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":0,"w":24,"h":32},
@ -605,8 +637,8 @@
"version": "1.0",
"image": "atlas0_100.png",
"format": "RGBA8888",
"size": {"w":1997,"h":1801},
"size": {"w":2014,"h":1857},
"scale": "1",
"smartupdate": "$TexturePacker:SmartUpdate:3dd7a89f30024dd4787ad4af6b14588a:9ba11f8b02134c4376ab4e0a44f8b850:f159918d23e5952766c6d23ab52278c6$"
"smartupdate": "$TexturePacker:SmartUpdate:8985524bba1a3f16cecab3c03b6aaa06:d614d20bfce033d8a8ab0990af085d16:f159918d23e5952766c6d23ab52278c6$"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 743 KiB

After

Width:  |  Height:  |  Size: 776 KiB

View File

@ -2,7 +2,7 @@
"sprites/belt/forward_0.png":
{
"frame": {"x":479,"y":103,"w":28,"h":32},
"frame": {"x":3,"y":1010,"w":28,"h":32},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":0,"w":28,"h":32},
@ -10,7 +10,7 @@
},
"sprites/belt/forward_1.png":
{
"frame": {"x":479,"y":139,"w":28,"h":32},
"frame": {"x":3,"y":967,"w":28,"h":32},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":0,"w":28,"h":32},
@ -18,7 +18,7 @@
},
"sprites/belt/forward_2.png":
{
"frame": {"x":479,"y":175,"w":28,"h":32},
"frame": {"x":3,"y":1046,"w":28,"h":32},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":0,"w":28,"h":32},
@ -26,7 +26,7 @@
},
"sprites/belt/forward_3.png":
{
"frame": {"x":262,"y":331,"w":28,"h":32},
"frame": {"x":35,"y":1044,"w":28,"h":32},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":0,"w":28,"h":32},
@ -34,7 +34,7 @@
},
"sprites/belt/forward_4.png":
{
"frame": {"x":285,"y":383,"w":28,"h":32},
"frame": {"x":67,"y":1044,"w":28,"h":32},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":0,"w":28,"h":32},
@ -42,7 +42,7 @@
},
"sprites/belt/forward_5.png":
{
"frame": {"x":317,"y":383,"w":28,"h":32},
"frame": {"x":133,"y":1053,"w":28,"h":32},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":0,"w":28,"h":32},
@ -50,7 +50,7 @@
},
"sprites/belt/left_0.png":
{
"frame": {"x":343,"y":159,"w":30,"h":30},
"frame": {"x":143,"y":883,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":2,"w":30,"h":30},
@ -58,7 +58,7 @@
},
"sprites/belt/left_1.png":
{
"frame": {"x":343,"y":193,"w":30,"h":30},
"frame": {"x":143,"y":917,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":2,"w":30,"h":30},
@ -66,7 +66,7 @@
},
"sprites/belt/left_2.png":
{
"frame": {"x":477,"y":211,"w":30,"h":30},
"frame": {"x":143,"y":951,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":2,"w":30,"h":30},
@ -74,7 +74,7 @@
},
"sprites/belt/left_3.png":
{
"frame": {"x":477,"y":245,"w":30,"h":30},
"frame": {"x":35,"y":960,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":2,"w":30,"h":30},
@ -82,7 +82,7 @@
},
"sprites/belt/left_4.png":
{
"frame": {"x":469,"y":279,"w":30,"h":30},
"frame": {"x":69,"y":967,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":2,"w":30,"h":30},
@ -90,7 +90,7 @@
},
"sprites/belt/left_5.png":
{
"frame": {"x":3,"y":331,"w":30,"h":30},
"frame": {"x":35,"y":994,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":2,"w":30,"h":30},
@ -98,7 +98,7 @@
},
"sprites/belt/right_0.png":
{
"frame": {"x":37,"y":331,"w":30,"h":30},
"frame": {"x":103,"y":967,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":2,"w":30,"h":30},
@ -106,7 +106,7 @@
},
"sprites/belt/right_1.png":
{
"frame": {"x":71,"y":331,"w":30,"h":30},
"frame": {"x":137,"y":985,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":2,"w":30,"h":30},
@ -114,7 +114,7 @@
},
"sprites/belt/right_2.png":
{
"frame": {"x":3,"y":296,"w":30,"h":30},
"frame": {"x":171,"y":997,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":2,"w":30,"h":30},
@ -122,7 +122,7 @@
},
"sprites/belt/right_3.png":
{
"frame": {"x":37,"y":296,"w":30,"h":30},
"frame": {"x":205,"y":1010,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":2,"w":30,"h":30},
@ -130,7 +130,7 @@
},
"sprites/belt/right_4.png":
{
"frame": {"x":71,"y":296,"w":30,"h":30},
"frame": {"x":99,"y":1001,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":2,"w":30,"h":30},
@ -138,7 +138,7 @@
},
"sprites/belt/right_5.png":
{
"frame": {"x":105,"y":331,"w":30,"h":30},
"frame": {"x":133,"y":1019,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":2,"w":30,"h":30},
@ -146,7 +146,7 @@
},
"sprites/blueprints/belt_left.png":
{
"frame": {"x":139,"y":331,"w":30,"h":30},
"frame": {"x":99,"y":1035,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":2,"w":30,"h":30},
@ -154,7 +154,7 @@
},
"sprites/blueprints/belt_right.png":
{
"frame": {"x":173,"y":331,"w":30,"h":30},
"frame": {"x":167,"y":1031,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":2,"w":30,"h":30},
@ -162,7 +162,7 @@
},
"sprites/blueprints/belt_top.png":
{
"frame": {"x":467,"y":416,"w":28,"h":32},
"frame": {"x":201,"y":1044,"w":28,"h":32},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":0,"w":28,"h":32},
@ -170,7 +170,7 @@
},
"sprites/blueprints/cutter-quad.png":
{
"frame": {"x":191,"y":55,"w":184,"h":48},
"frame": {"x":3,"y":296,"w":184,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":184,"h":48},
@ -178,7 +178,7 @@
},
"sprites/blueprints/cutter.png":
{
"frame": {"x":95,"y":244,"w":87,"h":48},
"frame": {"x":155,"y":419,"w":87,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":87,"h":48},
@ -186,7 +186,7 @@
},
"sprites/blueprints/miner-chainable.png":
{
"frame": {"x":262,"y":419,"w":47,"h":48},
"frame": {"x":195,"y":3,"w":47,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":47,"h":48},
@ -194,7 +194,7 @@
},
"sprites/blueprints/miner.png":
{
"frame": {"x":313,"y":419,"w":47,"h":48},
"frame": {"x":195,"y":55,"w":47,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":47,"h":48},
@ -202,7 +202,7 @@
},
"sprites/blueprints/mixer.png":
{
"frame": {"x":191,"y":211,"w":89,"h":48},
"frame": {"x":3,"y":808,"w":89,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":0,"w":89,"h":48},
@ -210,12 +210,20 @@
},
"sprites/blueprints/painter-double.png":
{
"frame": {"x":387,"y":3,"w":96,"h":96},
"frame": {"x":3,"y":400,"w":96,"h":96},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":96,"h":96},
"sourceSize": {"w":96,"h":96}
},
"sprites/blueprints/painter-mirrored.png":
{
"frame": {"x":3,"y":600,"w":96,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":96,"h":48},
"sourceSize": {"w":96,"h":48}
},
"sprites/blueprints/painter-quad.png":
{
"frame": {"x":3,"y":3,"w":188,"h":48},
@ -226,7 +234,7 @@
},
"sprites/blueprints/painter.png":
{
"frame": {"x":191,"y":159,"w":96,"h":48},
"frame": {"x":3,"y":652,"w":96,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":96,"h":48},
@ -234,7 +242,7 @@
},
"sprites/blueprints/rotater-ccw.png":
{
"frame": {"x":291,"y":159,"w":48,"h":48},
"frame": {"x":191,"y":107,"w":48,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
@ -242,7 +250,7 @@
},
"sprites/blueprints/rotater.png":
{
"frame": {"x":459,"y":313,"w":48,"h":48},
"frame": {"x":191,"y":159,"w":48,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
@ -250,7 +258,7 @@
},
"sprites/blueprints/splitter-compact-inverse.png":
{
"frame": {"x":210,"y":315,"w":48,"h":48},
"frame": {"x":191,"y":211,"w":48,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
@ -258,7 +266,7 @@
},
"sprites/blueprints/splitter-compact.png":
{
"frame": {"x":415,"y":416,"w":47,"h":47},
"frame": {"x":103,"y":780,"w":47,"h":47},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":47,"h":47},
@ -266,7 +274,7 @@
},
"sprites/blueprints/splitter.png":
{
"frame": {"x":186,"y":263,"w":87,"h":48},
"frame": {"x":155,"y":471,"w":87,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":87,"h":48},
@ -274,7 +282,7 @@
},
"sprites/blueprints/stacker.png":
{
"frame": {"x":284,"y":227,"w":89,"h":48},
"frame": {"x":96,"y":831,"w":89,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":0,"w":89,"h":48},
@ -282,7 +290,7 @@
},
"sprites/blueprints/trash-storage.png":
{
"frame": {"x":3,"y":365,"w":85,"h":96},
"frame": {"x":155,"y":627,"w":85,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":6,"y":0,"w":85,"h":96},
@ -290,7 +298,7 @@
},
"sprites/blueprints/trash.png":
{
"frame": {"x":181,"y":391,"w":48,"h":48},
"frame": {"x":191,"y":263,"w":48,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
@ -298,7 +306,7 @@
},
"sprites/blueprints/underground_belt_entry-tier2.png":
{
"frame": {"x":3,"y":465,"w":48,"h":43},
"frame": {"x":103,"y":503,"w":48,"h":43},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":5,"w":48,"h":43},
@ -306,7 +314,7 @@
},
"sprites/blueprints/underground_belt_entry.png":
{
"frame": {"x":106,"y":465,"w":48,"h":38},
"frame": {"x":103,"y":550,"w":48,"h":38},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":10,"w":48,"h":38},
@ -314,7 +322,7 @@
},
"sprites/blueprints/underground_belt_exit-tier2.png":
{
"frame": {"x":158,"y":465,"w":48,"h":38},
"frame": {"x":103,"y":592,"w":48,"h":38},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":38},
@ -322,7 +330,7 @@
},
"sprites/blueprints/underground_belt_exit.png":
{
"frame": {"x":262,"y":471,"w":48,"h":38},
"frame": {"x":103,"y":634,"w":48,"h":38},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":38},
@ -330,7 +338,7 @@
},
"sprites/buildings/belt_left.png":
{
"frame": {"x":343,"y":159,"w":30,"h":30},
"frame": {"x":143,"y":883,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":2,"w":30,"h":30},
@ -338,7 +346,7 @@
},
"sprites/buildings/belt_right.png":
{
"frame": {"x":37,"y":331,"w":30,"h":30},
"frame": {"x":103,"y":967,"w":30,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":2,"w":30,"h":30},
@ -346,7 +354,7 @@
},
"sprites/buildings/belt_top.png":
{
"frame": {"x":479,"y":103,"w":28,"h":32},
"frame": {"x":3,"y":1010,"w":28,"h":32},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":0,"w":28,"h":32},
@ -354,7 +362,7 @@
},
"sprites/buildings/cutter-quad.png":
{
"frame": {"x":191,"y":107,"w":184,"h":48},
"frame": {"x":3,"y":348,"w":184,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":184,"h":48},
@ -362,7 +370,7 @@
},
"sprites/buildings/cutter.png":
{
"frame": {"x":277,"y":279,"w":87,"h":48},
"frame": {"x":155,"y":523,"w":87,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":87,"h":48},
@ -370,7 +378,7 @@
},
"sprites/buildings/hub.png":
{
"frame": {"x":3,"y":55,"w":184,"h":185},
"frame": {"x":3,"y":107,"w":184,"h":185},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":4,"w":184,"h":185},
@ -378,7 +386,7 @@
},
"sprites/buildings/miner-chainable.png":
{
"frame": {"x":349,"y":365,"w":47,"h":48},
"frame": {"x":103,"y":676,"w":47,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":47,"h":48},
@ -386,7 +394,7 @@
},
"sprites/buildings/miner.png":
{
"frame": {"x":364,"y":417,"w":47,"h":48},
"frame": {"x":103,"y":728,"w":47,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":47,"h":48},
@ -394,7 +402,7 @@
},
"sprites/buildings/mixer.png":
{
"frame": {"x":377,"y":255,"w":88,"h":48},
"frame": {"x":154,"y":727,"w":88,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":0,"w":88,"h":48},
@ -402,15 +410,23 @@
},
"sprites/buildings/painter-double.png":
{
"frame": {"x":379,"y":103,"w":96,"h":96},
"frame": {"x":3,"y":500,"w":96,"h":96},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":96,"h":96},
"sourceSize": {"w":96,"h":96}
},
"sprites/buildings/painter-mirrored.png":
{
"frame": {"x":3,"y":704,"w":96,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":96,"h":48},
"sourceSize": {"w":96,"h":48}
},
"sprites/buildings/painter-quad.png":
{
"frame": {"x":195,"y":3,"w":188,"h":48},
"frame": {"x":3,"y":55,"w":188,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":188,"h":48},
@ -418,7 +434,7 @@
},
"sprites/buildings/painter.png":
{
"frame": {"x":377,"y":203,"w":96,"h":48},
"frame": {"x":3,"y":756,"w":96,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":96,"h":48},
@ -426,7 +442,7 @@
},
"sprites/buildings/rotater-ccw.png":
{
"frame": {"x":210,"y":443,"w":48,"h":48},
"frame": {"x":191,"y":315,"w":48,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
@ -434,7 +450,7 @@
},
"sprites/buildings/rotater.png":
{
"frame": {"x":233,"y":367,"w":48,"h":48},
"frame": {"x":191,"y":367,"w":48,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
@ -442,7 +458,7 @@
},
"sprites/buildings/splitter-compact-inverse.png":
{
"frame": {"x":400,"y":365,"w":48,"h":47},
"frame": {"x":103,"y":452,"w":48,"h":47},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":47},
@ -450,7 +466,7 @@
},
"sprites/buildings/splitter-compact.png":
{
"frame": {"x":452,"y":365,"w":47,"h":47},
"frame": {"x":189,"y":831,"w":47,"h":47},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":47,"h":47},
@ -458,7 +474,7 @@
},
"sprites/buildings/splitter.png":
{
"frame": {"x":368,"y":307,"w":87,"h":48},
"frame": {"x":155,"y":575,"w":87,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":87,"h":48},
@ -466,7 +482,7 @@
},
"sprites/buildings/stacker.png":
{
"frame": {"x":3,"y":244,"w":88,"h":48},
"frame": {"x":154,"y":779,"w":88,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":0,"w":88,"h":48},
@ -474,7 +490,7 @@
},
"sprites/buildings/trash-storage.png":
{
"frame": {"x":92,"y":365,"w":85,"h":96},
"frame": {"x":3,"y":860,"w":85,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":6,"y":0,"w":85,"h":96},
@ -482,7 +498,7 @@
},
"sprites/buildings/trash.png":
{
"frame": {"x":294,"y":331,"w":48,"h":48},
"frame": {"x":103,"y":400,"w":48,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
@ -490,7 +506,7 @@
},
"sprites/buildings/underground_belt_entry-tier2.png":
{
"frame": {"x":55,"y":465,"w":47,"h":42},
"frame": {"x":189,"y":882,"w":47,"h":42},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":6,"w":47,"h":42},
@ -498,7 +514,7 @@
},
"sprites/buildings/underground_belt_entry.png":
{
"frame": {"x":314,"y":471,"w":47,"h":38},
"frame": {"x":92,"y":883,"w":47,"h":38},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":10,"w":47,"h":38},
@ -506,7 +522,7 @@
},
"sprites/buildings/underground_belt_exit-tier2.png":
{
"frame": {"x":365,"y":469,"w":47,"h":38},
"frame": {"x":92,"y":925,"w":47,"h":38},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":47,"h":38},
@ -514,7 +530,7 @@
},
"sprites/buildings/underground_belt_exit.png":
{
"frame": {"x":416,"y":467,"w":47,"h":38},
"frame": {"x":189,"y":928,"w":47,"h":38},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":47,"h":38},
@ -522,7 +538,7 @@
},
"sprites/debug/acceptor_slot.png":
{
"frame": {"x":487,"y":3,"w":14,"h":16},
"frame": {"x":226,"y":970,"w":14,"h":16},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":14,"h":16},
@ -530,7 +546,7 @@
},
"sprites/debug/ejector_slot.png":
{
"frame": {"x":487,"y":23,"w":14,"h":16},
"frame": {"x":226,"y":990,"w":14,"h":16},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":14,"h":16},
@ -538,7 +554,7 @@
},
"sprites/map_overview/belt_forward.png":
{
"frame": {"x":487,"y":43,"w":8,"h":8},
"frame": {"x":171,"y":400,"w":8,"h":8},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":8,"h":8},
@ -546,7 +562,7 @@
},
"sprites/map_overview/belt_left.png":
{
"frame": {"x":499,"y":43,"w":8,"h":8},
"frame": {"x":177,"y":883,"w":8,"h":8},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":8,"h":8},
@ -554,7 +570,7 @@
},
"sprites/map_overview/belt_right.png":
{
"frame": {"x":487,"y":55,"w":8,"h":8},
"frame": {"x":177,"y":895,"w":8,"h":8},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":8,"h":8},
@ -562,15 +578,31 @@
},
"sprites/misc/deletion_marker.png":
{
"frame": {"x":181,"y":365,"w":22,"h":22},
"frame": {"x":165,"y":1065,"w":22,"h":22},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":22,"h":22},
"sourceSize": {"w":24,"h":24}
},
"sprites/misc/hub_direction_indicator.png":
{
"frame": {"x":177,"y":907,"w":8,"h":8},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":8,"h":8},
"sourceSize": {"w":8,"h":8}
},
"sprites/misc/lock_direction_indicator.png":
{
"frame": {"x":155,"y":400,"w":12,"h":10},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":1,"w":12,"h":10},
"sourceSize": {"w":12,"h":12}
},
"sprites/misc/slot_bad_arrow.png":
{
"frame": {"x":181,"y":365,"w":22,"h":22},
"frame": {"x":165,"y":1065,"w":22,"h":22},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":22,"h":22},
@ -578,7 +610,7 @@
},
"sprites/misc/slot_good_arrow.png":
{
"frame": {"x":105,"y":296,"w":22,"h":24},
"frame": {"x":69,"y":1001,"w":22,"h":24},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":22,"h":24},
@ -586,7 +618,7 @@
},
"sprites/misc/storage_overlay.png":
{
"frame": {"x":131,"y":296,"w":45,"h":23},
"frame": {"x":177,"y":970,"w":45,"h":23},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":45,"h":23},
@ -594,7 +626,7 @@
},
"sprites/misc/waypoint.png":
{
"frame": {"x":499,"y":55,"w":8,"h":8},
"frame": {"x":177,"y":919,"w":8,"h":8},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":8,"h":8},
@ -605,8 +637,8 @@
"version": "1.0",
"image": "atlas0_25.png",
"format": "RGBA8888",
"size": {"w":510,"h":512},
"size": {"w":245,"h":1090},
"scale": "0.25",
"smartupdate": "$TexturePacker:SmartUpdate:3dd7a89f30024dd4787ad4af6b14588a:9ba11f8b02134c4376ab4e0a44f8b850:f159918d23e5952766c6d23ab52278c6$"
"smartupdate": "$TexturePacker:SmartUpdate:8985524bba1a3f16cecab3c03b6aaa06:d614d20bfce033d8a8ab0990af085d16:f159918d23e5952766c6d23ab52278c6$"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 160 KiB

After

Width:  |  Height:  |  Size: 166 KiB

View File

@ -2,7 +2,7 @@
"sprites/belt/forward_0.png":
{
"frame": {"x":49,"y":1765,"w":51,"h":63},
"frame": {"x":1966,"y":3,"w":51,"h":63},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":6,"y":0,"w":51,"h":63},
@ -10,7 +10,7 @@
},
"sprites/belt/forward_1.png":
{
"frame": {"x":3,"y":1902,"w":51,"h":63},
"frame": {"x":1835,"y":203,"w":51,"h":63},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":6,"y":0,"w":51,"h":63},
@ -18,7 +18,7 @@
},
"sprites/belt/forward_2.png":
{
"frame": {"x":58,"y":1902,"w":51,"h":63},
"frame": {"x":1879,"y":304,"w":51,"h":63},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":6,"y":0,"w":51,"h":63},
@ -26,7 +26,7 @@
},
"sprites/belt/forward_3.png":
{
"frame": {"x":113,"y":1887,"w":51,"h":63},
"frame": {"x":1934,"y":304,"w":51,"h":63},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":6,"y":0,"w":51,"h":63},
@ -34,7 +34,7 @@
},
"sprites/belt/forward_4.png":
{
"frame": {"x":168,"y":1830,"w":51,"h":63},
"frame": {"x":1844,"y":381,"w":51,"h":63},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":6,"y":0,"w":51,"h":63},
@ -42,7 +42,7 @@
},
"sprites/belt/forward_5.png":
{
"frame": {"x":168,"y":1897,"w":51,"h":63},
"frame": {"x":1899,"y":371,"w":51,"h":63},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":6,"y":0,"w":51,"h":63},
@ -50,7 +50,7 @@
},
"sprites/belt/left_0.png":
{
"frame": {"x":104,"y":1765,"w":57,"h":57},
"frame": {"x":1890,"y":243,"w":57,"h":57},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":6,"w":57,"h":57},
@ -58,7 +58,7 @@
},
"sprites/belt/left_1.png":
{
"frame": {"x":165,"y":1769,"w":57,"h":57},
"frame": {"x":1951,"y":243,"w":57,"h":57},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":6,"w":57,"h":57},
@ -66,7 +66,7 @@
},
"sprites/belt/left_2.png":
{
"frame": {"x":104,"y":1826,"w":57,"h":57},
"frame": {"x":1783,"y":381,"w":57,"h":57},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":6,"w":57,"h":57},
@ -74,7 +74,7 @@
},
"sprites/belt/left_3.png":
{
"frame": {"x":226,"y":1782,"w":57,"h":57},
"frame": {"x":1954,"y":371,"w":57,"h":57},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":6,"w":57,"h":57},
@ -82,7 +82,7 @@
},
"sprites/belt/left_4.png":
{
"frame": {"x":287,"y":1782,"w":57,"h":57},
"frame": {"x":1954,"y":432,"w":57,"h":57},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":6,"w":57,"h":57},
@ -90,7 +90,7 @@
},
"sprites/belt/left_5.png":
{
"frame": {"x":348,"y":1835,"w":57,"h":57},
"frame": {"x":1363,"y":403,"w":57,"h":57},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":6,"w":57,"h":57},
@ -98,7 +98,7 @@
},
"sprites/belt/right_0.png":
{
"frame": {"x":409,"y":1835,"w":57,"h":57},
"frame": {"x":1424,"y":403,"w":57,"h":57},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":6,"y":6,"w":57,"h":57},
@ -106,7 +106,7 @@
},
"sprites/belt/right_1.png":
{
"frame": {"x":223,"y":1896,"w":57,"h":57},
"frame": {"x":1485,"y":403,"w":57,"h":57},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":6,"y":6,"w":57,"h":57},
@ -114,7 +114,7 @@
},
"sprites/belt/right_2.png":
{
"frame": {"x":284,"y":1843,"w":57,"h":57},
"frame": {"x":1546,"y":403,"w":57,"h":57},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":6,"y":6,"w":57,"h":57},
@ -122,7 +122,7 @@
},
"sprites/belt/right_3.png":
{
"frame": {"x":284,"y":1904,"w":57,"h":57},
"frame": {"x":1607,"y":402,"w":57,"h":57},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":6,"y":6,"w":57,"h":57},
@ -130,7 +130,7 @@
},
"sprites/belt/right_4.png":
{
"frame": {"x":345,"y":1896,"w":57,"h":57},
"frame": {"x":1668,"y":402,"w":57,"h":57},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":6,"y":6,"w":57,"h":57},
@ -138,7 +138,7 @@
},
"sprites/belt/right_5.png":
{
"frame": {"x":406,"y":1896,"w":57,"h":57},
"frame": {"x":1952,"y":181,"w":57,"h":57},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":6,"y":6,"w":57,"h":57},
@ -146,7 +146,7 @@
},
"sprites/blueprints/belt_left.png":
{
"frame": {"x":178,"y":1707,"w":58,"h":58},
"frame": {"x":1301,"y":400,"w":58,"h":58},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":5,"w":58,"h":58},
@ -154,7 +154,7 @@
},
"sprites/blueprints/belt_right.png":
{
"frame": {"x":370,"y":1773,"w":58,"h":58},
"frame": {"x":1890,"y":181,"w":58,"h":58},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":5,"w":58,"h":58},
@ -162,7 +162,7 @@
},
"sprites/blueprints/belt_top.png":
{
"frame": {"x":3,"y":1835,"w":53,"h":63},
"frame": {"x":1151,"y":403,"w":53,"h":63},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":53,"h":63},
@ -170,7 +170,7 @@
},
"sprites/blueprints/cutter-quad.png":
{
"frame": {"x":3,"y":574,"w":366,"h":96},
"frame": {"x":3,"y":374,"w":366,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":11,"y":0,"w":366,"h":96},
@ -178,7 +178,7 @@
},
"sprites/blueprints/cutter.png":
{
"frame": {"x":3,"y":1465,"w":172,"h":96},
"frame": {"x":1285,"y":203,"w":172,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":11,"y":0,"w":172,"h":96},
@ -186,7 +186,7 @@
},
"sprites/blueprints/miner-chainable.png":
{
"frame": {"x":179,"y":1507,"w":92,"h":96},
"frame": {"x":1401,"y":303,"w":92,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":0,"w":92,"h":96},
@ -194,7 +194,7 @@
},
"sprites/blueprints/miner.png":
{
"frame": {"x":178,"y":1607,"w":92,"h":96},
"frame": {"x":1497,"y":303,"w":92,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":0,"w":92,"h":96},
@ -202,7 +202,7 @@
},
"sprites/blueprints/mixer.png":
{
"frame": {"x":296,"y":1217,"w":175,"h":96},
"frame": {"x":1143,"y":103,"w":175,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":8,"y":0,"w":175,"h":96},
@ -210,15 +210,23 @@
},
"sprites/blueprints/painter-double.png":
{
"frame": {"x":3,"y":774,"w":192,"h":192},
"frame": {"x":373,"y":203,"w":192,"h":192},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":192,"h":192},
"sourceSize": {"w":192,"h":192}
},
"sprites/blueprints/painter-mirrored.png":
{
"frame": {"x":751,"y":103,"w":192,"h":96},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":192,"h":96},
"sourceSize": {"w":192,"h":96}
},
"sprites/blueprints/painter-quad.png":
{
"frame": {"x":3,"y":3,"w":374,"h":96},
"frame": {"x":373,"y":3,"w":374,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":0,"w":374,"h":96},
@ -226,7 +234,7 @@
},
"sprites/blueprints/painter.png":
{
"frame": {"x":3,"y":1165,"w":192,"h":96},
"frame": {"x":1121,"y":3,"w":192,"h":96},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":192,"h":96},
@ -234,7 +242,7 @@
},
"sprites/blueprints/rotater-ccw.png":
{
"frame": {"x":373,"y":249,"w":96,"h":96},
"frame": {"x":1866,"y":3,"w":96,"h":96},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":96,"h":96},
@ -242,7 +250,7 @@
},
"sprites/blueprints/rotater.png":
{
"frame": {"x":373,"y":349,"w":96,"h":96},
"frame": {"x":1675,"y":103,"w":96,"h":96},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":96,"h":96},
@ -250,7 +258,7 @@
},
"sprites/blueprints/splitter-compact-inverse.png":
{
"frame": {"x":370,"y":849,"w":95,"h":93},
"frame": {"x":1205,"y":303,"w":95,"h":93},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":1,"w":95,"h":93},
@ -258,7 +266,7 @@
},
"sprites/blueprints/splitter-compact.png":
{
"frame": {"x":369,"y":1120,"w":93,"h":93},
"frame": {"x":1304,"y":303,"w":93,"h":93},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":1,"w":93,"h":93},
@ -266,7 +274,7 @@
},
"sprites/blueprints/splitter.png":
{
"frame": {"x":3,"y":1565,"w":171,"h":96},
"frame": {"x":1691,"y":3,"w":171,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":11,"y":0,"w":171,"h":96},
@ -274,7 +282,7 @@
},
"sprites/blueprints/stacker.png":
{
"frame": {"x":296,"y":1317,"w":175,"h":96},
"frame": {"x":1106,"y":203,"w":175,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":8,"y":0,"w":175,"h":96},
@ -282,7 +290,7 @@
},
"sprites/blueprints/trash-storage.png":
{
"frame": {"x":199,"y":774,"w":167,"h":192},
"frame": {"x":765,"y":203,"w":167,"h":192},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":0,"w":167,"h":192},
@ -290,7 +298,7 @@
},
"sprites/blueprints/trash.png":
{
"frame": {"x":373,"y":449,"w":96,"h":96},
"frame": {"x":1636,"y":203,"w":96,"h":96},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":96,"h":96},
@ -298,7 +306,7 @@
},
"sprites/blueprints/underground_belt_entry-tier2.png":
{
"frame": {"x":199,"y":1261,"w":93,"h":84},
"frame": {"x":764,"y":399,"w":93,"h":84},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":12,"w":93,"h":84},
@ -306,7 +314,7 @@
},
"sprites/blueprints/underground_belt_entry.png":
{
"frame": {"x":199,"y":1349,"w":93,"h":75},
"frame": {"x":373,"y":399,"w":93,"h":75},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":21,"w":93,"h":75},
@ -314,7 +322,7 @@
},
"sprites/blueprints/underground_belt_exit-tier2.png":
{
"frame": {"x":369,"y":1041,"w":94,"h":75},
"frame": {"x":957,"y":399,"w":94,"h":75},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":0,"w":94,"h":75},
@ -322,7 +330,7 @@
},
"sprites/blueprints/underground_belt_exit.png":
{
"frame": {"x":181,"y":1428,"w":93,"h":75},
"frame": {"x":470,"y":399,"w":93,"h":75},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":0,"w":93,"h":75},
@ -330,7 +338,7 @@
},
"sprites/buildings/belt_left.png":
{
"frame": {"x":104,"y":1765,"w":57,"h":57},
"frame": {"x":1890,"y":243,"w":57,"h":57},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":6,"w":57,"h":57},
@ -338,7 +346,7 @@
},
"sprites/buildings/belt_right.png":
{
"frame": {"x":409,"y":1835,"w":57,"h":57},
"frame": {"x":1424,"y":403,"w":57,"h":57},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":6,"y":6,"w":57,"h":57},
@ -346,7 +354,7 @@
},
"sprites/buildings/belt_top.png":
{
"frame": {"x":49,"y":1765,"w":51,"h":63},
"frame": {"x":1966,"y":3,"w":51,"h":63},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":6,"y":0,"w":51,"h":63},
@ -354,7 +362,7 @@
},
"sprites/buildings/cutter-quad.png":
{
"frame": {"x":3,"y":674,"w":366,"h":96},
"frame": {"x":751,"y":3,"w":366,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":11,"y":0,"w":366,"h":96},
@ -362,7 +370,7 @@
},
"sprites/buildings/cutter.png":
{
"frame": {"x":275,"y":1517,"w":171,"h":96},
"frame": {"x":1500,"y":103,"w":171,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":11,"y":0,"w":171,"h":96},
@ -370,7 +378,7 @@
},
"sprites/buildings/hub.png":
{
"frame": {"x":3,"y":203,"w":366,"h":367},
"frame": {"x":3,"y":3,"w":366,"h":367},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":10,"w":366,"h":367},
@ -378,7 +386,7 @@
},
"sprites/buildings/miner-chainable.png":
{
"frame": {"x":381,"y":3,"w":91,"h":95},
"frame": {"x":1593,"y":303,"w":91,"h":95},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":0,"w":91,"h":95},
@ -386,7 +394,7 @@
},
"sprites/buildings/miner.png":
{
"frame": {"x":381,"y":102,"w":91,"h":95},
"frame": {"x":1688,"y":303,"w":91,"h":95},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":0,"w":91,"h":95},
@ -394,7 +402,7 @@
},
"sprites/buildings/mixer.png":
{
"frame": {"x":296,"y":1417,"w":174,"h":96},
"frame": {"x":1513,"y":3,"w":174,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":0,"w":174,"h":96},
@ -402,15 +410,23 @@
},
"sprites/buildings/painter-double.png":
{
"frame": {"x":3,"y":970,"w":192,"h":191},
"frame": {"x":569,"y":203,"w":192,"h":191},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":192,"h":191},
"sourceSize": {"w":192,"h":192}
},
"sprites/buildings/painter-mirrored.png":
{
"frame": {"x":947,"y":103,"w":192,"h":96},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":192,"h":96},
"sourceSize": {"w":192,"h":96}
},
"sprites/buildings/painter-quad.png":
{
"frame": {"x":3,"y":103,"w":374,"h":96},
"frame": {"x":373,"y":103,"w":374,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":0,"w":374,"h":96},
@ -418,7 +434,7 @@
},
"sprites/buildings/painter.png":
{
"frame": {"x":3,"y":1265,"w":192,"h":96},
"frame": {"x":1317,"y":3,"w":192,"h":96},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":192,"h":96},
@ -426,7 +442,7 @@
},
"sprites/buildings/rotater-ccw.png":
{
"frame": {"x":373,"y":649,"w":95,"h":96},
"frame": {"x":1736,"y":203,"w":95,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":95,"h":96},
@ -434,7 +450,7 @@
},
"sprites/buildings/rotater.png":
{
"frame": {"x":373,"y":749,"w":95,"h":96},
"frame": {"x":1106,"y":303,"w":95,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":95,"h":96},
@ -442,7 +458,7 @@
},
"sprites/buildings/splitter-compact-inverse.png":
{
"frame": {"x":370,"y":946,"w":94,"h":91},
"frame": {"x":569,"y":398,"w":94,"h":91},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":2,"w":94,"h":91},
@ -450,7 +466,7 @@
},
"sprites/buildings/splitter-compact.png":
{
"frame": {"x":199,"y":1166,"w":93,"h":91},
"frame": {"x":667,"y":398,"w":93,"h":91},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":2,"w":93,"h":91},
@ -458,7 +474,7 @@
},
"sprites/buildings/splitter.png":
{
"frame": {"x":3,"y":1665,"w":171,"h":96},
"frame": {"x":1461,"y":203,"w":171,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":11,"y":0,"w":171,"h":96},
@ -466,7 +482,7 @@
},
"sprites/buildings/stacker.png":
{
"frame": {"x":3,"y":1365,"w":174,"h":96},
"frame": {"x":1322,"y":103,"w":174,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":0,"w":174,"h":96},
@ -474,7 +490,7 @@
},
"sprites/buildings/trash-storage.png":
{
"frame": {"x":199,"y":970,"w":166,"h":192},
"frame": {"x":936,"y":203,"w":166,"h":192},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":0,"w":166,"h":192},
@ -482,7 +498,7 @@
},
"sprites/buildings/trash.png":
{
"frame": {"x":373,"y":549,"w":96,"h":96},
"frame": {"x":1775,"y":103,"w":96,"h":96},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":96,"h":96},
@ -490,7 +506,7 @@
},
"sprites/buildings/underground_belt_entry-tier2.png":
{
"frame": {"x":274,"y":1617,"w":92,"h":83},
"frame": {"x":861,"y":399,"w":92,"h":83},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":13,"w":92,"h":83},
@ -498,7 +514,7 @@
},
"sprites/buildings/underground_belt_entry.png":
{
"frame": {"x":370,"y":1617,"w":92,"h":74},
"frame": {"x":1875,"y":103,"w":92,"h":74},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":22,"w":92,"h":74},
@ -506,7 +522,7 @@
},
"sprites/buildings/underground_belt_exit-tier2.png":
{
"frame": {"x":370,"y":1695,"w":92,"h":74},
"frame": {"x":1783,"y":303,"w":92,"h":74},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":0,"w":92,"h":74},
@ -514,7 +530,7 @@
},
"sprites/buildings/underground_belt_exit.png":
{
"frame": {"x":274,"y":1704,"w":92,"h":74},
"frame": {"x":1055,"y":403,"w":92,"h":74},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":0,"w":92,"h":74},
@ -522,7 +538,7 @@
},
"sprites/debug/acceptor_slot.png":
{
"frame": {"x":240,"y":1707,"w":26,"h":32},
"frame": {"x":1989,"y":304,"w":26,"h":32},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":0,"w":26,"h":32},
@ -530,7 +546,7 @@
},
"sprites/debug/ejector_slot.png":
{
"frame": {"x":240,"y":1743,"w":26,"h":32},
"frame": {"x":1971,"y":116,"w":26,"h":32},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":0,"w":26,"h":32},
@ -538,7 +554,7 @@
},
"sprites/map_overview/belt_forward.png":
{
"frame": {"x":181,"y":1365,"w":14,"h":16},
"frame": {"x":1835,"y":270,"w":14,"h":16},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":14,"h":16},
@ -546,7 +562,7 @@
},
"sprites/map_overview/belt_left.png":
{
"frame": {"x":342,"y":1166,"w":15,"h":15},
"frame": {"x":3,"y":474,"w":15,"h":15},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":1,"w":15,"h":15},
@ -554,7 +570,7 @@
},
"sprites/map_overview/belt_right.png":
{
"frame": {"x":342,"y":1185,"w":15,"h":15},
"frame": {"x":22,"y":474,"w":15,"h":15},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":15,"h":15},
@ -562,15 +578,31 @@
},
"sprites/misc/deletion_marker.png":
{
"frame": {"x":296,"y":1166,"w":42,"h":42},
"frame": {"x":1971,"y":70,"w":42,"h":42},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":3,"w":42,"h":42},
"sourceSize": {"w":48,"h":48}
},
"sprites/misc/hub_direction_indicator.png":
{
"frame": {"x":2001,"y":116,"w":16,"h":16},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":16,"h":16},
"sourceSize": {"w":16,"h":16}
},
"sprites/misc/lock_direction_indicator.png":
{
"frame": {"x":1208,"y":448,"w":24,"h":16},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":4,"w":24,"h":16},
"sourceSize": {"w":24,"h":24}
},
"sprites/misc/slot_bad_arrow.png":
{
"frame": {"x":296,"y":1166,"w":42,"h":42},
"frame": {"x":1971,"y":70,"w":42,"h":42},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":3,"w":42,"h":42},
@ -578,7 +610,7 @@
},
"sprites/misc/slot_good_arrow.png":
{
"frame": {"x":3,"y":1782,"w":42,"h":48},
"frame": {"x":1729,"y":402,"w":42,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":0,"w":42,"h":48},
@ -586,7 +618,7 @@
},
"sprites/misc/storage_overlay.png":
{
"frame": {"x":381,"y":201,"w":89,"h":44},
"frame": {"x":1208,"y":400,"w":89,"h":44},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":89,"h":44},
@ -594,7 +626,7 @@
},
"sprites/misc/waypoint.png":
{
"frame": {"x":181,"y":1385,"w":14,"h":16},
"frame": {"x":1989,"y":340,"w":14,"h":16},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":14,"h":16},
@ -605,8 +637,8 @@
"version": "1.0",
"image": "atlas0_50.png",
"format": "RGBA8888",
"size": {"w":475,"h":1968},
"size": {"w":2020,"h":492},
"scale": "0.5",
"smartupdate": "$TexturePacker:SmartUpdate:3dd7a89f30024dd4787ad4af6b14588a:9ba11f8b02134c4376ab4e0a44f8b850:f159918d23e5952766c6d23ab52278c6$"
"smartupdate": "$TexturePacker:SmartUpdate:8985524bba1a3f16cecab3c03b6aaa06:d614d20bfce033d8a8ab0990af085d16:f159918d23e5952766c6d23ab52278c6$"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 374 KiB

After

Width:  |  Height:  |  Size: 397 KiB

View File

@ -2,7 +2,7 @@
"sprites/belt/forward_0.png":
{
"frame": {"x":1936,"y":151,"w":77,"h":95},
"frame": {"x":1963,"y":102,"w":77,"h":95},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
@ -10,7 +10,7 @@
},
"sprites/belt/forward_1.png":
{
"frame": {"x":1936,"y":250,"w":77,"h":95},
"frame": {"x":1963,"y":201,"w":77,"h":95},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
@ -18,7 +18,7 @@
},
"sprites/belt/forward_2.png":
{
"frame": {"x":1600,"y":708,"w":77,"h":95},
"frame": {"x":1967,"y":300,"w":77,"h":95},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
@ -26,7 +26,7 @@
},
"sprites/belt/forward_3.png":
{
"frame": {"x":1544,"y":808,"w":77,"h":95},
"frame": {"x":1967,"y":399,"w":77,"h":95},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
@ -34,7 +34,7 @@
},
"sprites/belt/forward_4.png":
{
"frame": {"x":1625,"y":807,"w":77,"h":95},
"frame": {"x":1967,"y":498,"w":77,"h":95},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
@ -42,7 +42,7 @@
},
"sprites/belt/forward_5.png":
{
"frame": {"x":1544,"y":907,"w":77,"h":95},
"frame": {"x":1679,"y":952,"w":77,"h":95},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
@ -50,7 +50,7 @@
},
"sprites/belt/left_0.png":
{
"frame": {"x":1680,"y":593,"w":86,"h":86},
"frame": {"x":1217,"y":969,"w":86,"h":86},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
@ -58,7 +58,7 @@
},
"sprites/belt/left_1.png":
{
"frame": {"x":1770,"y":592,"w":86,"h":86},
"frame": {"x":1307,"y":969,"w":86,"h":86},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
@ -66,7 +66,7 @@
},
"sprites/belt/left_2.png":
{
"frame": {"x":1860,"y":592,"w":86,"h":86},
"frame": {"x":1916,"y":597,"w":86,"h":86},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
@ -74,7 +74,7 @@
},
"sprites/belt/left_3.png":
{
"frame": {"x":1681,"y":683,"w":86,"h":86},
"frame": {"x":1916,"y":687,"w":86,"h":86},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
@ -82,7 +82,7 @@
},
"sprites/belt/left_4.png":
{
"frame": {"x":1771,"y":682,"w":86,"h":86},
"frame": {"x":1916,"y":777,"w":86,"h":86},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
@ -90,7 +90,7 @@
},
"sprites/belt/left_5.png":
{
"frame": {"x":1861,"y":682,"w":86,"h":86},
"frame": {"x":1914,"y":867,"w":86,"h":86},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
@ -98,7 +98,7 @@
},
"sprites/belt/right_0.png":
{
"frame": {"x":1706,"y":773,"w":86,"h":86},
"frame": {"x":1499,"y":852,"w":86,"h":86},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
@ -106,7 +106,7 @@
},
"sprites/belt/right_1.png":
{
"frame": {"x":1796,"y":772,"w":86,"h":86},
"frame": {"x":1397,"y":967,"w":86,"h":86},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
@ -114,7 +114,7 @@
},
"sprites/belt/right_2.png":
{
"frame": {"x":1886,"y":772,"w":86,"h":86},
"frame": {"x":1589,"y":862,"w":86,"h":86},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
@ -122,7 +122,7 @@
},
"sprites/belt/right_3.png":
{
"frame": {"x":1716,"y":863,"w":86,"h":86},
"frame": {"x":1679,"y":862,"w":86,"h":86},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
@ -130,7 +130,7 @@
},
"sprites/belt/right_4.png":
{
"frame": {"x":1806,"y":862,"w":86,"h":86},
"frame": {"x":1499,"y":942,"w":86,"h":86},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
@ -138,7 +138,7 @@
},
"sprites/belt/right_5.png":
{
"frame": {"x":1896,"y":862,"w":86,"h":86},
"frame": {"x":1589,"y":952,"w":86,"h":86},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
@ -146,7 +146,7 @@
},
"sprites/blueprints/belt_left.png":
{
"frame": {"x":1924,"y":349,"w":87,"h":87},
"frame": {"x":1397,"y":593,"w":87,"h":87},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":8,"w":87,"h":87},
@ -154,7 +154,7 @@
},
"sprites/blueprints/belt_right.png":
{
"frame": {"x":1625,"y":906,"w":87,"h":87},
"frame": {"x":1397,"y":684,"w":87,"h":87},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":8,"y":8,"w":87,"h":87},
@ -162,7 +162,7 @@
},
"sprites/blueprints/belt_top.png":
{
"frame": {"x":1517,"y":709,"w":79,"h":95},
"frame": {"x":1963,"y":3,"w":79,"h":95},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":8,"y":0,"w":79,"h":95},
@ -186,7 +186,7 @@
},
"sprites/blueprints/miner-chainable.png":
{
"frame": {"x":1784,"y":299,"w":136,"h":143},
"frame": {"x":1827,"y":447,"w":136,"h":143},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":136,"h":143},
@ -194,7 +194,7 @@
},
"sprites/blueprints/miner.png":
{
"frame": {"x":1544,"y":446,"w":136,"h":143},
"frame": {"x":1076,"y":739,"w":136,"h":143},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":136,"h":143},
@ -202,7 +202,7 @@
},
"sprites/blueprints/mixer.png":
{
"frame": {"x":1671,"y":151,"w":261,"h":144},
"frame": {"x":547,"y":738,"w":261,"h":144},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":13,"y":0,"w":261,"h":144},
@ -216,6 +216,14 @@
"spriteSourceSize": {"x":0,"y":0,"w":288,"h":287},
"sourceSize": {"w":288,"h":288}
},
"sprites/blueprints/painter-mirrored.png":
{
"frame": {"x":1119,"y":150,"w":288,"h":144},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":288,"h":144},
"sourceSize": {"w":288,"h":144}
},
"sprites/blueprints/painter-quad.png":
{
"frame": {"x":555,"y":3,"w":560,"h":144},
@ -226,7 +234,7 @@
},
"sprites/blueprints/painter.png":
{
"frame": {"x":1119,"y":150,"w":288,"h":144},
"frame": {"x":1671,"y":3,"w":288,"h":144},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":288,"h":144},
@ -234,7 +242,7 @@
},
"sprites/blueprints/rotater-ccw.png":
{
"frame": {"x":1397,"y":445,"w":143,"h":144},
"frame": {"x":1639,"y":299,"w":143,"h":144},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":143,"h":144},
@ -242,7 +250,7 @@
},
"sprites/blueprints/rotater.png":
{
"frame": {"x":1084,"y":594,"w":143,"h":144},
"frame": {"x":1786,"y":299,"w":143,"h":144},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":143,"h":144},
@ -250,7 +258,7 @@
},
"sprites/blueprints/splitter-compact-inverse.png":
{
"frame": {"x":1071,"y":742,"w":142,"h":138},
"frame": {"x":1071,"y":886,"w":142,"h":138},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":2,"w":142,"h":138},
@ -258,7 +266,7 @@
},
"sprites/blueprints/splitter-compact.png":
{
"frame": {"x":1217,"y":742,"w":139,"h":138},
"frame": {"x":1488,"y":594,"w":139,"h":138},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":2,"w":139,"h":138},
@ -266,7 +274,7 @@
},
"sprites/blueprints/splitter.png":
{
"frame": {"x":1119,"y":298,"w":256,"h":144},
"frame": {"x":811,"y":886,"w":256,"h":144},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":17,"y":0,"w":256,"h":144},
@ -274,7 +282,7 @@
},
"sprites/blueprints/stacker.png":
{
"frame": {"x":555,"y":590,"w":261,"h":144},
"frame": {"x":847,"y":591,"w":261,"h":144},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":13,"y":0,"w":261,"h":144},
@ -290,7 +298,7 @@
},
"sprites/blueprints/trash.png":
{
"frame": {"x":1101,"y":446,"w":144,"h":144},
"frame": {"x":1241,"y":445,"w":144,"h":144},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":144,"h":144},
@ -298,7 +306,7 @@
},
"sprites/blueprints/underground_belt_entry-tier2.png":
{
"frame": {"x":835,"y":885,"w":138,"h":125},
"frame": {"x":1774,"y":594,"w":138,"h":125},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":19,"w":138,"h":125},
@ -306,7 +314,7 @@
},
"sprites/blueprints/underground_belt_entry.png":
{
"frame": {"x":1261,"y":884,"w":138,"h":112},
"frame": {"x":1774,"y":723,"w":138,"h":112},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":32,"w":138,"h":112},
@ -314,7 +322,7 @@
},
"sprites/blueprints/underground_belt_exit-tier2.png":
{
"frame": {"x":1118,"y":884,"w":139,"h":112},
"frame": {"x":1488,"y":736,"w":139,"h":112},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":0,"w":139,"h":112},
@ -322,7 +330,7 @@
},
"sprites/blueprints/underground_belt_exit.png":
{
"frame": {"x":1397,"y":593,"w":138,"h":112},
"frame": {"x":1772,"y":839,"w":138,"h":112},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":0,"w":138,"h":112},
@ -330,7 +338,7 @@
},
"sprites/buildings/belt_left.png":
{
"frame": {"x":1680,"y":593,"w":86,"h":86},
"frame": {"x":1217,"y":969,"w":86,"h":86},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
@ -338,7 +346,7 @@
},
"sprites/buildings/belt_right.png":
{
"frame": {"x":1706,"y":773,"w":86,"h":86},
"frame": {"x":1499,"y":852,"w":86,"h":86},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
@ -346,7 +354,7 @@
},
"sprites/buildings/belt_top.png":
{
"frame": {"x":1936,"y":151,"w":77,"h":95},
"frame": {"x":1963,"y":102,"w":77,"h":95},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
@ -362,7 +370,7 @@
},
"sprites/buildings/cutter.png":
{
"frame": {"x":811,"y":738,"w":256,"h":143},
"frame": {"x":1119,"y":298,"w":256,"h":143},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":17,"y":0,"w":256,"h":143},
@ -378,7 +386,7 @@
},
"sprites/buildings/miner-chainable.png":
{
"frame": {"x":1684,"y":446,"w":136,"h":142},
"frame": {"x":1101,"y":445,"w":136,"h":142},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":136,"h":142},
@ -386,7 +394,7 @@
},
"sprites/buildings/miner.png":
{
"frame": {"x":1824,"y":446,"w":136,"h":142},
"frame": {"x":1112,"y":593,"w":136,"h":142},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":136,"h":142},
@ -394,7 +402,7 @@
},
"sprites/buildings/mixer.png":
{
"frame": {"x":547,"y":738,"w":260,"h":143},
"frame": {"x":812,"y":739,"w":260,"h":143},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":0,"w":260,"h":143},
@ -408,6 +416,14 @@
"spriteSourceSize": {"x":0,"y":0,"w":288,"h":286},
"sourceSize": {"w":288,"h":288}
},
"sprites/buildings/painter-mirrored.png":
{
"frame": {"x":1671,"y":151,"w":288,"h":144},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":288,"h":144},
"sourceSize": {"w":288,"h":144}
},
"sprites/buildings/painter-quad.png":
{
"frame": {"x":555,"y":151,"w":560,"h":144},
@ -418,7 +434,7 @@
},
"sprites/buildings/painter.png":
{
"frame": {"x":1671,"y":3,"w":288,"h":144},
"frame": {"x":555,"y":590,"w":288,"h":144},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":288,"h":144},
@ -426,7 +442,7 @@
},
"sprites/buildings/rotater-ccw.png":
{
"frame": {"x":1231,"y":594,"w":141,"h":143},
"frame": {"x":1537,"y":447,"w":141,"h":143},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":0,"w":141,"h":143},
@ -434,7 +450,7 @@
},
"sprites/buildings/rotater.png":
{
"frame": {"x":1639,"y":299,"w":141,"h":143},
"frame": {"x":1682,"y":447,"w":141,"h":143},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":0,"w":141,"h":143},
@ -442,7 +458,7 @@
},
"sprites/buildings/splitter-compact-inverse.png":
{
"frame": {"x":547,"y":885,"w":141,"h":136},
"frame": {"x":1252,"y":593,"w":141,"h":136},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":3,"w":141,"h":136},
@ -450,7 +466,7 @@
},
"sprites/buildings/splitter-compact.png":
{
"frame": {"x":692,"y":885,"w":139,"h":136},
"frame": {"x":1631,"y":594,"w":139,"h":136},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":3,"w":139,"h":136},
@ -466,7 +482,7 @@
},
"sprites/buildings/stacker.png":
{
"frame": {"x":820,"y":591,"w":260,"h":143},
"frame": {"x":547,"y":886,"w":260,"h":143},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":0,"w":260,"h":143},
@ -482,7 +498,7 @@
},
"sprites/buildings/trash.png":
{
"frame": {"x":1249,"y":446,"w":144,"h":144},
"frame": {"x":1389,"y":445,"w":144,"h":144},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":144,"h":144},
@ -490,7 +506,7 @@
},
"sprites/buildings/underground_belt_entry-tier2.png":
{
"frame": {"x":977,"y":885,"w":137,"h":124},
"frame": {"x":1631,"y":734,"w":137,"h":124},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":20,"w":137,"h":124},
@ -498,7 +514,7 @@
},
"sprites/buildings/underground_belt_entry.png":
{
"frame": {"x":1539,"y":593,"w":137,"h":111},
"frame": {"x":1216,"y":739,"w":137,"h":111},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":33,"w":137,"h":111},
@ -506,7 +522,7 @@
},
"sprites/buildings/underground_belt_exit-tier2.png":
{
"frame": {"x":1376,"y":709,"w":137,"h":111},
"frame": {"x":1217,"y":854,"w":137,"h":111},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":137,"h":111},
@ -514,7 +530,7 @@
},
"sprites/buildings/underground_belt_exit.png":
{
"frame": {"x":1403,"y":824,"w":137,"h":111},
"frame": {"x":1358,"y":852,"w":137,"h":111},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":137,"h":111},
@ -522,7 +538,7 @@
},
"sprites/debug/acceptor_slot.png":
{
"frame": {"x":1963,"y":3,"w":38,"h":48},
"frame": {"x":2006,"y":597,"w":38,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":38,"h":48},
@ -530,7 +546,7 @@
},
"sprites/debug/ejector_slot.png":
{
"frame": {"x":1963,"y":55,"w":38,"h":48},
"frame": {"x":2006,"y":649,"w":38,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":38,"h":48},
@ -538,7 +554,7 @@
},
"sprites/map_overview/belt_forward.png":
{
"frame": {"x":1625,"y":997,"w":20,"h":24},
"frame": {"x":1826,"y":955,"w":20,"h":24},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":0,"w":20,"h":24},
@ -546,7 +562,7 @@
},
"sprites/map_overview/belt_left.png":
{
"frame": {"x":3,"y":994,"w":22,"h":22},
"frame": {"x":206,"y":994,"w":22,"h":22},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":2,"w":22,"h":22},
@ -554,7 +570,7 @@
},
"sprites/map_overview/belt_right.png":
{
"frame": {"x":1963,"y":107,"w":22,"h":22},
"frame": {"x":2006,"y":701,"w":22,"h":22},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":2,"w":22,"h":22},
@ -562,15 +578,31 @@
},
"sprites/misc/deletion_marker.png":
{
"frame": {"x":1716,"y":953,"w":62,"h":62},
"frame": {"x":140,"y":994,"w":62,"h":62},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":5,"w":62,"h":62},
"sourceSize": {"w":72,"h":72}
},
"sprites/misc/hub_direction_indicator.png":
{
"frame": {"x":1933,"y":299,"w":24,"h":24},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":24,"h":24},
"sourceSize": {"w":24,"h":24}
},
"sprites/misc/lock_direction_indicator.png":
{
"frame": {"x":1357,"y":733,"w":36,"h":24},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":6,"w":36,"h":24},
"sourceSize": {"w":36,"h":36}
},
"sprites/misc/slot_bad_arrow.png":
{
"frame": {"x":1716,"y":953,"w":62,"h":62},
"frame": {"x":140,"y":994,"w":62,"h":62},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":5,"w":62,"h":62},
@ -578,7 +610,7 @@
},
"sprites/misc/slot_good_arrow.png":
{
"frame": {"x":1950,"y":592,"w":62,"h":72},
"frame": {"x":1760,"y":955,"w":62,"h":72},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":62,"h":72},
@ -586,7 +618,7 @@
},
"sprites/misc/storage_overlay.png":
{
"frame": {"x":1403,"y":939,"w":133,"h":66},
"frame": {"x":3,"y":994,"w":133,"h":66},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":2,"w":133,"h":66},
@ -594,7 +626,7 @@
},
"sprites/misc/waypoint.png":
{
"frame": {"x":1649,"y":997,"w":20,"h":24},
"frame": {"x":1357,"y":761,"w":20,"h":24},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":0,"w":20,"h":24},
@ -605,8 +637,8 @@
"version": "1.0",
"image": "atlas0_75.png",
"format": "RGBA8888",
"size": {"w":2016,"h":1024},
"size": {"w":2047,"h":1063},
"scale": "0.75",
"smartupdate": "$TexturePacker:SmartUpdate:3dd7a89f30024dd4787ad4af6b14588a:9ba11f8b02134c4376ab4e0a44f8b850:f159918d23e5952766c6d23ab52278c6$"
"smartupdate": "$TexturePacker:SmartUpdate:8985524bba1a3f16cecab3c03b6aaa06:d614d20bfce033d8a8ab0990af085d16:f159918d23e5952766c6d23ab52278c6$"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 735 KiB

After

Width:  |  Height:  |  Size: 780 KiB

View File

@ -324,9 +324,11 @@
</struct>
<key type="filename">sprites/blueprints/cutter.png</key>
<key type="filename">sprites/blueprints/mixer.png</key>
<key type="filename">sprites/blueprints/painter-mirrored.png</key>
<key type="filename">sprites/blueprints/painter.png</key>
<key type="filename">sprites/blueprints/splitter.png</key>
<key type="filename">sprites/blueprints/stacker.png</key>
<key type="filename">sprites/buildings/painter-mirrored.png</key>
<struct type="IndividualSpriteSettings">
<key>pivotPoint</key>
<point_f>0.5,0.5</point_f>
@ -445,6 +447,7 @@
<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>
<key type="filename">sprites/misc/hub_direction_indicator.png</key>
<key type="filename">sprites/misc/waypoint.png</key>
<struct type="IndividualSpriteSettings">
<key>pivotPoint</key>
@ -477,6 +480,21 @@
<key>scale9FromFile</key>
<false/>
</struct>
<key type="filename">sprites/misc/lock_direction_indicator.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>12,12,24,24</rect>
<key>scale9Paddings</key>
<rect>12,12,24,24</rect>
<key>scale9FromFile</key>
<false/>
</struct>
<key type="filename">sprites/misc/storage_overlay.png</key>
<struct type="IndividualSpriteSettings">
<key>pivotPoint</key>

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f61e851402fbc92d6909912fb203c63258fedbdea83e81f7ececb5091f4bee03
size 3732550

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8c334a9f100fce4647b4803d2a8270b30e26d53622b3717bdb81b3ea07f84aed
size 150286082

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 495 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -38,6 +38,10 @@ html {
right: 0;
background: #dee1ea;
@include DarkThemeOverride {
background: $darkModeGameBackground;
}
}
body {
@ -413,6 +417,10 @@ canvas {
display: inline-block;
vertical-align: middle;
}
@include DarkThemeOverride {
color: #fff;
}
}
.prefab_LoadingTextWithAnimDelayed {

View File

@ -15,6 +15,11 @@ $buildingsAndVariants: belt, splitter, splitter-compact, splitter-compact-invers
}
}
// Special case
[data-icon="building_tutorials/painter-mirrored.png"] {
background-image: uiResource("res/ui/building_tutorials/painter.png") !important;
}
$icons: notification_saved, notification_success, notification_upgrade;
@each $icon in $icons {
[data-icon="icons/#{$icon}.png"] {
@ -22,8 +27,8 @@ $icons: notification_saved, notification_success, notification_upgrade;
}
}
$languages: en, de, cs, da, et, es-419, fr, it, pt-BR, sv, tr, el, ru, uk, zh-TW, nb, mt-MT, ar, nl, vi, th,
hu, pl, ja;
$languages: en, de, cs, da, et, es-419, fr, it, pt-BR, sv, tr, el, ru, uk, zh-TW, zh-CN, nb, mt-MT, ar, nl, vi, th,
hu, pl, ja, kor, no, pt-PT;
@each $language in $languages {
[data-languageicon="#{$language}"] {

View File

@ -75,6 +75,15 @@
@include StyleBelowWidth(700px) {
display: none !important;
}
&.compact {
width: unset !important;
grid-template-columns: 1fr;
.buildingImage,
.description > .text {
display: none;
}
}
}
#ingame_HUD_PlacerVariants {
@ -86,6 +95,10 @@
flex-direction: column;
align-items: flex-end;
&.compact {
@include S(top, 150px);
}
.explanation {
text-transform: uppercase;
grid-row: 1 / 2;

View File

@ -21,15 +21,32 @@
}
}
$darkModeDialogBg: darken($darkModeGameBackground, 10);
@include DarkThemeOverride {
background: rgba(#33363d, 0.9);
background: rgba($darkModeDialogBg, 0.9);
@include InlineAnimation(0.12s ease-in-out) {
0% {
background-color: transparent;
opacity: 0.5;
}
100% {
background-color: rgba(#33363d, 0.9);
background-color: rgba($darkModeDialogBg, 0.9);
}
}
> .dialogInner.optionChooserDialog .optionParent {
.option {
background: #3d3f42;
&:hover {
background-color: #424348;
}
&.active {
background: $colorBlueBright;
color: #fff;
}
}
}
}
@ -118,6 +135,14 @@
pointer-events: all;
@include S(width, 350px);
@include DarkThemeOverride {
color: #aaa;
}
a {
color: $colorBlueBright;
}
strong {
font-weight: bold;
}

View File

@ -14,6 +14,10 @@
}
> .binding {
&:not(.visible) {
display: none !important;
}
display: inline-grid;
@include PlainText;
align-items: center;
@ -57,42 +61,6 @@
@include S(margin-left, 5px);
}
}
&:not(.placementActive) .binding.placementOnly,
&.mapOverviewActive .binding.placementOnly {
display: none;
}
&.placementActive:not(.mapOverviewActive) .noPlacementOnly {
display: none;
}
&:not(.mapOverviewActive) .binding.overviewOnly {
display: none;
}
&.mapOverviewActive .noOverviewOnly {
display: none;
}
.binding.placementOnly,
&:not(.placementActive) .binding.noPlacementOnly {
transform-origin: 0% 50%;
@include InlineAnimation(0.3s ease-in-out) {
0% {
color: $colorRedBright;
transform: scale(1.2);
}
}
}
.keybinding.builtinKey {
transition: all 0.1s ease-in-out;
transition-property: background-color, color, border-color;
background: $colorRedBright;
border-color: $colorRedBright;
color: #fff;
}
}
body.uiHidden #ingame_HUD_KeybindingOverlay .binding:not(.hudToggle) {

View File

@ -1,22 +0,0 @@
#ingame_HUD_MassSelector {
position: absolute;
@include S(top, 50px);
left: 50%;
transform: translateX(-50%);
background: $ingameHudBg;
@include S(padding, 6px, 10px);
@include SuperSmallText;
color: #fff;
// color: #f77;
.keybinding {
vertical-align: middle;
@include S(margin, 0, 1px);
position: relative;
top: unset;
left: unset;
right: unset;
bottom: unset;
@include S(margin-top, -2px);
}
}

View File

@ -109,5 +109,9 @@
}
}
}
&.completed {
opacity: 0.5;
}
}
}

View File

@ -241,6 +241,10 @@
&.complete {
background-color: $colorGreenBright;
@include DarkThemeOverride {
background-color: $colorGreenBright;
}
}
}
}

View File

@ -29,7 +29,7 @@
#ingame_HUD_Waypoints {
position: absolute;
@include S(right, 10px);
@include S(top, 60px);
@include S(top, 45px);
display: flex;
flex-direction: column;
@include DarkThemeInvert();
@ -47,6 +47,7 @@
opacity: 0.7;
@include S(margin-bottom, 1px);
font-weight: bold;
&:hover {
opacity: 1;
}
@ -63,5 +64,29 @@
transform: scale(1.5);
}
}
&.hub {
// Transform because there is a canvas before
@include S(margin-left, -2px);
grid-template-columns: auto 1fr;
background: none !important;
@include S(padding-left, 0);
canvas {
@include S(width, 12px);
@include S(height, 12px);
@include S(margin-right, 1px);
}
}
&.shapeIcon {
canvas {
@include S(width, 15px);
@include S(height, 15px);
pointer-events: none;
// Double invert, to make sure it has the right color
@include DarkThemeInvert();
}
}
}
}

View File

@ -37,7 +37,6 @@
@import "ingame_hud/shop";
@import "ingame_hud/game_menu";
@import "ingame_hud/dialogs";
@import "ingame_hud/mass_selector";
@import "ingame_hud/vignette_overlay";
@import "ingame_hud/statistics";
@import "ingame_hud/pinned_shapes";
@ -67,7 +66,6 @@ ingame_HUD_PinnedShapes,
ingame_HUD_GameMenu,
ingame_HUD_KeybindingOverlay,
ingame_HUD_Notifications,
ingame_HUD_MassSelector,
ingame_HUD_DebugInfo,
ingame_HUD_EntityDebugger,
ingame_HUD_InteractiveTutorial,
@ -101,7 +99,6 @@ body.uiHidden {
#ingame_HUD_buildings_toolbar,
#ingame_HUD_PlacementHints,
#ingame_HUD_GameMenu,
#ingame_HUD_MassSelector,
#ingame_HUD_PinnedShapes,
#ingame_HUD_Notifications,
#ingame_HUD_TutorialHints,
@ -115,6 +112,6 @@ body.modalDialogActive,
body.externalAdOpen,
body.ingameDialogOpen {
> *:not(.ingameDialog):not(.modalDialogParent):not(.loadingDialog):not(.gameLoadingOverlay):not(#ingame_HUD_ModalDialogs):not(.noBlur) {
filter: blur(5px) !important;
// filter: blur(5px) !important;
}
}

View File

@ -350,7 +350,7 @@ button,
}
@mixin DarkThemeOverride {
@at-root body[data-theme="dark"] &,
@at-root html[data-theme="dark"] &,
&[data-theme="dark"] {
@content;
}

View File

@ -28,4 +28,10 @@
right: 0;
bottom: 0;
}
@include DarkThemeOverride {
.gameLoadingOverlay {
background: $darkModeGameBackground;
}
}
}

View File

@ -51,4 +51,21 @@
}
}
}
@include DarkThemeOverride {
.content {
.hint {
background: #3b3d40;
}
.category .entry {
color: #c0c4c8;
border-bottom-color: #888;
button {
filter: invert(1);
}
}
}
}
}

View File

@ -37,6 +37,7 @@
.languageChoose {
@include S(border-radius, 8px);
border: solid #222428;
background-color: #fff;
@include S(border-width, 2px);
background-size: cover;
}
@ -233,7 +234,8 @@
@include S(width, 300px);
}
.playButton {
.playButton,
.continueButton {
@include SuperHeading;
@include S(min-width, 130px);
@include S(padding, 15px, 20px);
@ -246,12 +248,21 @@
&:hover {
transform: scale(1.02);
}
&.continueButton {
@include Heading;
}
}
.importButton {
@include S(margin-top, 15px);
}
.newGameButton {
@include S(margin-top, 15px);
@include S(margin-left, 15px);
}
.savegames {
@include S(max-height, 105px);
overflow-y: auto;
@ -390,4 +401,44 @@
}
}
}
@include DarkThemeOverride {
background: $darkModeGameBackground center center / cover !important;
.topButtons {
filter: invert(1);
.languageChoose {
filter: invert(1);
}
}
.mainContainer {
background: darken($darkModeGameBackground, 10);
.savegames .savegame {
background: darken($darkModeGameBackground, 15);
color: white;
}
}
.footer {
> a {
background: darken($darkModeGameBackground, 10);
color: #eee;
}
.author {
color: #bdbdbd;
> a {
color: white;
}
}
.thirdpartyLogo.githubLogo {
filter: invert(1);
}
}
}
}

View File

@ -14,6 +14,10 @@
padding: 10px;
box-sizing: border-box;
background: #eef1f4;
@include DarkThemeOverride {
background: #424242;
}
.version {
@include Heading;
@ -39,6 +43,10 @@
a {
color: $colorBlueBright;
}
li {
@include SuperSmallText;
@include S(margin-bottom, 10px);
}
}
}

View File

@ -88,4 +88,26 @@
}
}
}
@include DarkThemeOverride {
.content {
.setting {
background: darken($darkModeGameBackground, 10);
.value.enum {
// dirty but works
filter: invert(0.85);
color: #222;
}
.value.checkbox {
background-color: #74767b;
&.checked {
background-color: $colorBlueBright;
}
}
}
}
}
}

View File

@ -61,4 +61,21 @@
}
}
}
@include DarkThemeOverride {
.headerBar {
h1 {
color: #e2e0db;
}
.backButton {
filter: invert(1);
}
}
> .container > .content {
background: darken($darkModeGameBackground, 3);
color: #eee;
}
}
}

View File

@ -38,6 +38,8 @@ $ingameHudBg: rgba(#333438, 0.9);
$text3dColor: #f4ffff;
$darkModeGameBackground: #5c606c;
// Dialog properties
$modalDialogBg: rgba(160, 165, 180, 0.8);
$dialogBgColor: lighten($mainBgColor, 10);

View File

@ -14,13 +14,10 @@ import { Vector } from "./core/vector";
import { AdProviderInterface } from "./platform/ad_provider";
import { NoAdProvider } from "./platform/ad_providers/no_ad_provider";
import { AnalyticsInterface } from "./platform/analytics";
import { ShapezGameAnalytics } from "./platform/browser/game_analytics";
import { GoogleAnalyticsImpl } from "./platform/browser/google_analytics";
import { NoGameAnalytics } from "./platform/browser/no_game_analytics";
import { SoundImplBrowser } from "./platform/browser/sound";
import { StorageImplBrowser } from "./platform/browser/storage";
import { StorageImplBrowserIndexedDB } from "./platform/browser/storage_indexed_db";
import { PlatformWrapperImplBrowser } from "./platform/browser/wrapper";
import { StorageImplElectron } from "./platform/electron/storage";
import { PlatformWrapperImplElectron } from "./platform/electron/wrapper";
import { GameAnalyticsInterface } from "./platform/game_analytics";
import { SoundInterface } from "./platform/sound";
@ -36,7 +33,6 @@ import { MainMenuState } from "./states/main_menu";
import { MobileWarningState } from "./states/mobile_warning";
import { PreloadState } from "./states/preload";
import { SettingsState } from "./states/settings";
import { NoGameAnalytics } from "./platform/browser/no_game_analytics";
const logger = createLogger("application");

View File

@ -1,12 +1,95 @@
export const CHANGELOG = [
// {
// version: "1.1.10",
// date: "unreleased",
// entries: [
// "Add and update more translations (Big thank you to all translators!)",
// "Prevent invalid connection if existing underground tunnel entrance exists (by jaysc)",
// ],
// },
{
version: "1.1.16",
date: "21.06.2020",
entries: [
"You can now pickup buildings below your cursor with 'Q'!",
"The game soundtrack has been extended! There are now 4 songs with over 13 minutes of playtime from <a href='https://soundcloud.com/pettersumelius' target='blank'>Peppsen</a>!",
"Refactor keybindings overlay to show more appropriate keybindings",
"Show keybindings for area-select in the upper left instead",
"Automatically deselect area when selecting a new building",
"Raise markers limit from 14 characters to 71 (by Joker-vD)",
"Optimize performance by caching extractor items (by Phlosioneer)",
"Added setting to enable compact building infos, which only show ratios and hide the image / description",
"Apply dark theme to menu as well (by dengr1065)",
"Fix belt planner not placing the last belt",
"Fix buildings getting deleted when right clicking while placing a blueprint",
"Fix for exporting screenshots for huge bases (It was showing an empty file) (by xSparfuchs)",
"Fix buttons not responding when using right click directly after left click (by davidburhans)",
"Fix hub marker being hidden by building info panel",
"Disable dialog background blur since it can cause performance issues",
"Added simplified chinese translations",
"Update translations (Thanks to all translators!)",
],
},
{
version: "1.1.15",
date: "17.06.2020",
entries: [
"You can now place straight belts (and tunnels) by holding SHIFT! (For you, @giantwaffle ❤️)",
"Added continue button to main menu and add seperate 'New game' button (by jaysc)",
"Added setting to disable smart tunnel placement introduced with the last update",
"Added setting to disable vignette",
"Update translations",
],
},
{
version: "1.1.14",
date: "16.06.2020",
entries: [
"There is now an indicator (compass) to the HUB for the HUB Marker!",
"You can now include shape short keys in markers to render shape icons instead of text!",
"Added mirrored variant of the painter",
"When placing tunnels, unnecessary belts inbetween are now removed!",
"You can now drag tunnels and they will automatically expand! (Just try it out, its intuitive)",
],
},
{
version: "1.1.13",
date: "15.06.2020",
entries: [
"Added shift modifier for faster pan (by jaysc)",
"Added Japanese translations",
"Added Portuguese (Portugal) translations",
"Updated icon for Spanish (Latin America) - It was showing a Spanish flag before",
"Updated existing translations",
],
},
{
version: "1.1.12",
date: "14.06.2020",
entries: [
"Huge performance improvements! The game should now run up to 60% faster!",
"Added norwegian translation",
],
},
{
version: "1.1.11",
date: "13.06.2020",
entries: [
"Pinned shapes are now smart, they dynamically update their goal and also unpin when no longer required. Completed objectives are now rendered transparent.",
"You can now cut areas, and also paste the last blueprint again! (by hexy)",
"You can now export your whole base as an image by pressing F3!",
"Improve upgrade number rounding, so there are no goals like '37.4k', instead it will now be '35k'",
"You can now configure the camera movement speed when using WASD (by mini-bomba)",
"Selecting an area now is relative to the world and thus does not move when moving the screen (by Dimava)",
"Allow higher tick-rates up to 500hz (This will burn your PC!)",
"Fix bug regarding number rounding",
"Fix dialog text being hardly readable in dark theme",
"Fix app not starting when the savegames were corrupted - there is now a better error message as well.",
"Further translation updates - Big thanks to all contributors!",
],
},
{
version: "1.1.10",
date: "12.06.2020",
entries: [
"There are now linux builds on steam! Please report any issues in the discord!",
"Steam cloud saves are now available!",
"Added and update more translations (Big thank you to all translators!)",
"Prevent invalid connection if existing underground tunnel entrance exists (by jaysc)",
],
},
{
version: "1.1.9",
date: "11.06.2020",

View File

@ -3,7 +3,7 @@ import { createLogger } from "../core/logging";
import { Signal } from "../core/signal";
import { fastArrayDelete, fastArrayDeleteValueIfContained } from "./utils";
import { Vector } from "./vector";
import { IS_MOBILE } from "./config";
import { IS_MOBILE, SUPPORT_TOUCH } from "./config";
import { SOUNDS } from "../platform/sound";
import { GLOBAL_APP } from "./globals";
@ -119,16 +119,21 @@ export class ClickDetector {
}
}
const options = this.internalGetEventListenerOptions();
this.element.removeEventListener("touchstart", this.handlerTouchStart, options);
this.element.removeEventListener("touchend", this.handlerTouchEnd, options);
this.element.removeEventListener("touchcancel", this.handlerTouchCancel, options);
if (SUPPORT_TOUCH) {
this.element.removeEventListener("touchstart", this.handlerTouchStart, options);
this.element.removeEventListener("touchend", this.handlerTouchEnd, options);
this.element.removeEventListener("touchcancel", this.handlerTouchCancel, options);
}
this.element.removeEventListener("mouseup", this.handlerTouchStart, options);
this.element.removeEventListener("mousedown", this.handlerTouchEnd, options);
this.element.removeEventListener("mouseout", this.handlerTouchCancel, options);
if (this.captureTouchmove) {
this.element.removeEventListener("touchmove", this.handlerTouchMove, options);
if (SUPPORT_TOUCH) {
this.element.removeEventListener("touchmove", this.handlerTouchMove, options);
}
this.element.removeEventListener("mousemove", this.handlerTouchMove, options);
}
@ -186,16 +191,20 @@ export class ClickDetector {
element.addEventListener("click", this.handlerPreventClick, options);
}
element.addEventListener("touchstart", this.handlerTouchStart, options);
element.addEventListener("touchend", this.handlerTouchEnd, options);
element.addEventListener("touchcancel", this.handlerTouchCancel, options);
if (SUPPORT_TOUCH) {
element.addEventListener("touchstart", this.handlerTouchStart, options);
element.addEventListener("touchend", this.handlerTouchEnd, options);
element.addEventListener("touchcancel", this.handlerTouchCancel, options);
}
element.addEventListener("mousedown", this.handlerTouchStart, options);
element.addEventListener("mouseup", this.handlerTouchEnd, options);
element.addEventListener("mouseout", this.handlerTouchCancel, options);
if (this.captureTouchmove) {
element.addEventListener("touchmove", this.handlerTouchMove, options);
if (SUPPORT_TOUCH) {
element.addEventListener("touchmove", this.handlerTouchMove, options);
}
element.addEventListener("mousemove", this.handlerTouchMove, options);
}
@ -316,6 +325,7 @@ export class ClickDetector {
// Ignore right clicks
this.rightClick.dispatch(position, event);
this.cancelled = true;
this.clickDownPosition = null;
return;
}
}

View File

@ -1,3 +1,5 @@
import { queryParamOptions } from "./query_parameters";
export const IS_DEBUG =
G_IS_DEV &&
typeof window !== "undefined" &&
@ -5,9 +7,12 @@ export const IS_DEBUG =
(window.location.host.indexOf("localhost:") >= 0 || window.location.host.indexOf("192.168.0.") >= 0) &&
window.location.search.indexOf("nodebug") < 0;
export const IS_DEMO =
(G_IS_PROD && !G_IS_STANDALONE) ||
(typeof window !== "undefined" && window.location.search.indexOf("demo") >= 0);
export const IS_DEMO = queryParamOptions.fullVersion
? false
: (G_IS_PROD && !G_IS_STANDALONE) ||
(typeof window !== "undefined" && window.location.search.indexOf("demo") >= 0);
export const SUPPORT_TOUCH = false;
const smoothCanvas = true;
@ -79,40 +84,7 @@ export const globalConfig = {
},
rendering: {},
debug: {
/* dev:start */
// fastGameEnter: true,
// noArtificialDelays: true,
// disableSavegameWrite: true,
// showEntityBounds: true,
// showAcceptorEjectors: true,
// disableMusic: true,
// doNotRenderStatics: true,
// disableZoomLimits: true,
// showChunkBorders: true,
// rewardsInstant: true,
allBuildingsUnlocked: true,
blueprintsNoCost: true,
upgradesNoCost: true,
// disableUnlockDialog: true,
// disableLogicTicks: true,
// testClipping: true,
// framePausesBetweenTicks: 40,
// testTranslations: true,
// enableEntityInspector: true,
// testAds: true,
// disableMapOverview: true,
// disableTutorialHints: true,
disableUpgradeNotification: true,
// instantBelts: true,
// instantProcessors: true,
// instantMiners: true,
// resumeGameOnFastEnter: false,
// renderForTrailer: true,
/* dev:end */
},
debug: require("./config.local").default,
// Secret vars
info: {
@ -130,14 +102,15 @@ export const globalConfig = {
export const IS_MOBILE = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
// Automatic calculations
globalConfig.minerSpeedItemsPerSecond = globalConfig.beltSpeedItemsPerSecond / 5;
// Dynamic calculations
if (globalConfig.debug.disableMapOverview) {
globalConfig.mapChunkOverviewMinZoom = 0;
globalConfig.mapChunkPrerenderMinZoom = 0;
}
// Stuff for making the trailer
if (G_IS_DEV && globalConfig.debug.renderForTrailer) {
globalConfig.debug.framePausesBetweenTicks = 32;
// globalConfig.mapChunkOverviewMinZoom = 0.0;
@ -148,3 +121,7 @@ if (G_IS_DEV && globalConfig.debug.renderForTrailer) {
globalConfig.debug.disableSavegameWrite = true;
// globalConfig.beltSpeedItemsPerSecond *= 2;
}
if (globalConfig.debug.fastGameEnter) {
globalConfig.debug.noArtificalDelays = true;
}

View File

@ -0,0 +1,87 @@
export default {
// You can set any debug options here!
/* dev:start */
// -----------------------------------------------------------------------------------
// Quickly enters the game and skips the main menu - good for fast iterating
// fastGameEnter: true,
// -----------------------------------------------------------------------------------
// Skips any delays like transitions between states and such
// noArtificialDelays: true,
// -----------------------------------------------------------------------------------
// Disables writing of savegames, useful for testing the same savegame over and over
// disableSavegameWrite: true,
// -----------------------------------------------------------------------------------
// Shows bounds of all entities
// showEntityBounds: true,
// -----------------------------------------------------------------------------------
// Shows arrows for every ejector / acceptor
// showAcceptorEjectors: true,
// -----------------------------------------------------------------------------------
// Disables the music (Overrides any setting, can cause weird behaviour)
// disableMusic: true,
// -----------------------------------------------------------------------------------
// Do not render static map entities (=most buildings)
// doNotRenderStatics: true,
// -----------------------------------------------------------------------------------
// Allow to zoom freely without limits
// disableZoomLimits: true,
// -----------------------------------------------------------------------------------
// Shows a border arround every chunk
// showChunkBorders: true,
// -----------------------------------------------------------------------------------
// All rewards can be unlocked by passing just 1 of any shape
// rewardsInstant: true,
// -----------------------------------------------------------------------------------
// Unlocks all buildings
// allBuildingsUnlocked: true,
// -----------------------------------------------------------------------------------
// Disables cost of bluepirnts
// blueprintsNoCost: true,
// -----------------------------------------------------------------------------------
// Disables cost of upgrades
// upgradesNoCost: true,
// -----------------------------------------------------------------------------------
// Disables the dialog when completing a level
// disableUnlockDialog: true,
// -----------------------------------------------------------------------------------
// Disables the simulation - This effectively pauses the game.
// disableLogicTicks: true,
// -----------------------------------------------------------------------------------
// Test the rendering if everything is clipped out properly
// testClipping: true,
// -----------------------------------------------------------------------------------
// Allows to render slower, useful for recording at half speed to avoid stuttering
// framePausesBetweenTicks: 1,
// -----------------------------------------------------------------------------------
// Replace all translations with emojis to see which texts are translateable
// testTranslations: true,
// -----------------------------------------------------------------------------------
// Enables an inspector which shows information about the entity below the curosr
// enableEntityInspector: true,
// -----------------------------------------------------------------------------------
// Enables ads in the local build (normally they are deactivated there)
// testAds: true,
// -----------------------------------------------------------------------------------
// Disables the automatic switch to an overview when zooming out
// disableMapOverview: true,
// -----------------------------------------------------------------------------------
// Disables the notification when there are new entries in the changelog since last played
// disableUpgradeNotification: true,
// -----------------------------------------------------------------------------------
// Makes belts almost infinitely fast
// instantBelts: true,
// -----------------------------------------------------------------------------------
// Makes item processors almost infinitely fast
// instantProcessors: true,
// -----------------------------------------------------------------------------------
// Makes miners almost infinitely fast
// instantMiners: true,
// -----------------------------------------------------------------------------------
// When using fastGameEnter, controls whether a new game is started or the last one is resumed
// resumeGameOnFastEnter: false,
// -----------------------------------------------------------------------------------
// Special option used to render the trailer
// renderForTrailer: true,
// -----------------------------------------------------------------------------------
/* dev:end */
};

View File

@ -3,8 +3,14 @@ const options = queryString.parse(location.search);
export let queryParamOptions = {
embedProvider: null,
fullVersion: false,
};
if (options.embed) {
queryParamOptions.embedProvider = options.embed;
}
// Allow testing full version outside of standalone
if (options.fullVersion && !G_IS_RELEASE) {
queryParamOptions.fullVersion = true;
}

View File

@ -377,7 +377,23 @@ export function findNiceValue(num) {
return 0;
}
const roundAmount = 0.5 * Math_pow(10, Math_floor(Math_log10(num) - 1));
let roundAmount = 1;
if (num > 50000) {
roundAmount = 10000;
} else if (num > 20000) {
roundAmount = 5000;
} else if (num > 5000) {
roundAmount = 1000;
} else if (num > 2000) {
roundAmount = 500;
} else if (num > 1000) {
roundAmount = 100;
} else if (num > 100) {
roundAmount = 20;
} else if (num > 20) {
roundAmount = 5;
}
const niceValue = Math_floor(num / roundAmount) * roundAmount;
if (num >= 10) {
return Math_round(niceValue);
@ -389,6 +405,8 @@ export function findNiceValue(num) {
return Math_round(niceValue * 100) / 100;
}
window.fn = findNiceValue;
/**
* Finds a nice integer value
* @see findNiceValue
@ -628,13 +646,12 @@ export function measure(name, target) {
}
/**
* Helper method to create a new div
* @param {Element} parent
* Helper method to create a new div element
* @param {string=} id
* @param {Array<string>=} classes
* @param {string=} innerHTML
*/
export function makeDiv(parent, id = null, classes = [], innerHTML = "") {
export function makeDivElement(id = null, classes = [], innerHTML = "") {
const div = document.createElement("div");
if (id) {
div.id = id;
@ -643,10 +660,51 @@ export function makeDiv(parent, id = null, classes = [], innerHTML = "") {
div.classList.add(classes[i]);
}
div.innerHTML = innerHTML;
return div;
}
/**
* Helper method to create a new div
* @param {Element} parent
* @param {string=} id
* @param {Array<string>=} classes
* @param {string=} innerHTML
*/
export function makeDiv(parent, id = null, classes = [], innerHTML = "") {
const div = makeDivElement(id, classes, innerHTML);
parent.appendChild(div);
return div;
}
/**
* Helper method to create a new div and place before reference Node
* @param {Element} parent
* @param {Element} referenceNode
* @param {string=} id
* @param {Array<string>=} classes
* @param {string=} innerHTML
*/
export function makeDivBefore(parent, referenceNode, id = null, classes = [], innerHTML = "") {
const div = makeDivElement(id, classes, innerHTML);
parent.insertBefore(div, referenceNode);
return div;
}
/**
* Helper method to create a new button element
* @param {Array<string>=} classes
* @param {string=} innerHTML
*/
export function makeButtonElement(classes = [], innerHTML = "") {
const element = document.createElement("button");
for (let i = 0; i < classes.length; ++i) {
element.classList.add(classes[i]);
}
element.classList.add("styledButton");
element.innerHTML = innerHTML;
return element;
}
/**
* Helper method to create a new button
* @param {Element} parent
@ -654,16 +712,24 @@ export function makeDiv(parent, id = null, classes = [], innerHTML = "") {
* @param {string=} innerHTML
*/
export function makeButton(parent, classes = [], innerHTML = "") {
const element = document.createElement("button");
for (let i = 0; i < classes.length; ++i) {
element.classList.add(classes[i]);
}
element.classList.add("styledButton");
element.innerHTML = innerHTML;
const element = makeButtonElement(classes, innerHTML);
parent.appendChild(element);
return element;
}
/**
* Helper method to create a new button and place before reference Node
* @param {Element} parent
* @param {Element} referenceNode
* @param {Array<string>=} classes
* @param {string=} innerHTML
*/
export function makeButtonBefore(parent, referenceNode, classes = [], innerHTML = "") {
const element = makeButtonElement(classes, innerHTML);
parent.insertBefore(element, referenceNode);
return element;
}
/**
* Removes all children of the given element
* @param {Element} elem

View File

@ -10,6 +10,7 @@ import {
Math_atan2,
Math_sin,
Math_cos,
Math_ceil,
} from "./builtins";
const tileSize = globalConfig.tileSize;
@ -303,13 +304,21 @@ export class Vector {
}
/**
* Computes componentwise floor and return a new vector
* Computes componentwise floor and returns a new vector
* @returns {Vector}
*/
floor() {
return new Vector(Math_floor(this.x), Math_floor(this.y));
}
/**
* Computes componentwise ceil and returns a new vector
* @returns {Vector}
*/
ceil() {
return new Vector(Math_ceil(this.x), Math_ceil(this.y));
}
/**
* Computes componentwise round and return a new vector
* @returns {Vector}

View File

@ -22,6 +22,10 @@ export class MetaBeltBaseBuilding extends MetaBuilding {
return "#777";
}
getHasDirectionLockAvailable() {
return true;
}
/**
* @param {GameRoot} root
* @param {string} variant

View File

@ -11,7 +11,7 @@ import { T } from "../../translations";
import { formatItemsPerSecond } from "../../core/utils";
/** @enum {string} */
export const enumPainterVariants = { double: "double", quad: "quad" };
export const enumPainterVariants = { mirrored: "mirrored", double: "double", quad: "quad" };
export class MetaPainterBuilding extends MetaBuilding {
constructor() {
@ -21,6 +21,7 @@ export class MetaPainterBuilding extends MetaBuilding {
getDimensions(variant) {
switch (variant) {
case defaultBuildingVariant:
case enumPainterVariants.mirrored:
return new Vector(2, 1);
case enumPainterVariants.double:
return new Vector(2, 2);
@ -42,7 +43,8 @@ export class MetaPainterBuilding extends MetaBuilding {
*/
getAdditionalStatistics(root, variant) {
switch (variant) {
case defaultBuildingVariant: {
case defaultBuildingVariant:
case enumPainterVariants.mirrored: {
const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.painter);
return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
}
@ -61,7 +63,7 @@ export class MetaPainterBuilding extends MetaBuilding {
* @param {GameRoot} root
*/
getAvailableVariants(root) {
let variants = [defaultBuildingVariant];
let variants = [defaultBuildingVariant, enumPainterVariants.mirrored];
if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_painter_double)) {
variants.push(enumPainterVariants.double);
}
@ -116,7 +118,8 @@ export class MetaPainterBuilding extends MetaBuilding {
*/
updateVariants(entity, rotationVariant, variant) {
switch (variant) {
case defaultBuildingVariant: {
case defaultBuildingVariant:
case enumPainterVariants.mirrored: {
entity.components.ItemAcceptor.setSlots([
{
pos: new Vector(0, 0),
@ -125,7 +128,9 @@ export class MetaPainterBuilding extends MetaBuilding {
},
{
pos: new Vector(1, 0),
directions: [enumDirection.top],
directions: [
variant === defaultBuildingVariant ? enumDirection.top : enumDirection.bottom,
],
filter: enumItemAcceptorItemFilter.color,
},
]);

View File

@ -8,7 +8,7 @@ import {
performanceNow,
} from "../core/builtins";
import { clickDetectorGlobals } from "../core/click_detector";
import { globalConfig } from "../core/config";
import { globalConfig, SUPPORT_TOUCH } from "../core/config";
import { createLogger } from "../core/logging";
import { Rectangle } from "../core/rectangle";
import { Signal, STOP_PROPAGATION } from "../core/signal";
@ -312,32 +312,36 @@ export class Camera extends BasicSerializableObject {
this.eventListenerMouseMove = this.onMouseMove.bind(this);
this.eventListenerMouseUp = this.onMouseUp.bind(this);
this.root.canvas.addEventListener("touchstart", this.eventListenerTouchStart);
this.root.canvas.addEventListener("touchend", this.eventListenerTouchEnd);
this.root.canvas.addEventListener("touchcancel", this.eventListenerTouchEnd);
this.root.canvas.addEventListener("touchmove", this.eventListenerTouchMove);
if (SUPPORT_TOUCH) {
this.root.canvas.addEventListener("touchstart", this.eventListenerTouchStart);
this.root.canvas.addEventListener("touchend", this.eventListenerTouchEnd);
this.root.canvas.addEventListener("touchcancel", this.eventListenerTouchEnd);
this.root.canvas.addEventListener("touchmove", this.eventListenerTouchMove);
}
this.root.canvas.addEventListener("wheel", this.eventListenerMousewheel);
this.root.canvas.addEventListener("mousedown", this.eventListenerMouseDown);
this.root.canvas.addEventListener("mousemove", this.eventListenerMouseMove);
this.root.canvas.addEventListener("mouseup", this.eventListenerMouseUp);
this.root.canvas.addEventListener("mouseout", this.eventListenerMouseUp);
window.addEventListener("mouseup", this.eventListenerMouseUp);
// this.root.canvas.addEventListener("mouseout", this.eventListenerMouseUp);
}
/**
* Cleans up all event listeners
*/
cleanup() {
this.root.canvas.removeEventListener("touchstart", this.eventListenerTouchStart);
this.root.canvas.removeEventListener("touchend", this.eventListenerTouchEnd);
this.root.canvas.removeEventListener("touchcancel", this.eventListenerTouchEnd);
this.root.canvas.removeEventListener("touchmove", this.eventListenerTouchMove);
if (SUPPORT_TOUCH) {
this.root.canvas.removeEventListener("touchstart", this.eventListenerTouchStart);
this.root.canvas.removeEventListener("touchend", this.eventListenerTouchEnd);
this.root.canvas.removeEventListener("touchcancel", this.eventListenerTouchEnd);
this.root.canvas.removeEventListener("touchmove", this.eventListenerTouchMove);
}
this.root.canvas.removeEventListener("wheel", this.eventListenerMousewheel);
this.root.canvas.removeEventListener("mousedown", this.eventListenerMouseDown);
this.root.canvas.removeEventListener("mousemove", this.eventListenerMouseMove);
this.root.canvas.removeEventListener("mouseup", this.eventListenerMouseUp);
this.root.canvas.removeEventListener("mouseout", this.eventListenerMouseUp);
window.removeEventListener("mouseup", this.eventListenerMouseUp);
// this.root.canvas.removeEventListener("mouseout", this.eventListenerMouseUp);
}
/**
@ -885,24 +889,28 @@ export class Camera extends BasicSerializableObject {
let forceY = 0;
const actionMapper = this.root.keyMapper;
if (actionMapper.getBinding(KEYMAPPINGS.navigation.mapMoveUp).isCurrentlyPressed()) {
if (actionMapper.getBinding(KEYMAPPINGS.navigation.mapMoveUp).pressed) {
forceY -= 1;
}
if (actionMapper.getBinding(KEYMAPPINGS.navigation.mapMoveDown).isCurrentlyPressed()) {
if (actionMapper.getBinding(KEYMAPPINGS.navigation.mapMoveDown).pressed) {
forceY += 1;
}
if (actionMapper.getBinding(KEYMAPPINGS.navigation.mapMoveLeft).isCurrentlyPressed()) {
if (actionMapper.getBinding(KEYMAPPINGS.navigation.mapMoveLeft).pressed) {
forceX -= 1;
}
if (actionMapper.getBinding(KEYMAPPINGS.navigation.mapMoveRight).isCurrentlyPressed()) {
if (actionMapper.getBinding(KEYMAPPINGS.navigation.mapMoveRight).pressed) {
forceX += 1;
}
this.center.x += moveAmount * forceX;
this.center.y += moveAmount * forceY;
let movementSpeed =
this.root.app.settings.getMovementSpeed() *
(actionMapper.getBinding(KEYMAPPINGS.navigation.mapMoveFaster).pressed ? 4 : 1);
this.center.x += moveAmount * forceX * movementSpeed;
this.center.y += moveAmount * forceY * movementSpeed;
}
}
}

View File

@ -1,70 +0,0 @@
import { STOP_PROPAGATION } from "../core/signal";
import { GameRoot } from "./root";
import { ClickDetector } from "../core/click_detector";
import { createLogger } from "../core/logging";
const logger = createLogger("canvas_click_interceptor");
export class CanvasClickInterceptor {
/**
* @param {GameRoot} root
*/
constructor(root) {
this.root = root;
this.root.signals.postLoadHook.add(this.initialize, this);
this.root.signals.aboutToDestruct.add(this.cleanup, this);
/** @type {Array<object>} */
this.interceptors = [];
}
initialize() {
this.clickDetector = new ClickDetector(this.root.canvas, {
applyCssClass: null,
captureTouchmove: false,
targetOnly: true,
preventDefault: true,
maxDistance: 13,
clickSound: null,
});
this.clickDetector.click.add(this.onCanvasClick, this);
this.clickDetector.rightClick.add(this.onCanvasRightClick, this);
if (this.root.hud.parts.buildingPlacer) {
this.interceptors.push(this.root.hud.parts.buildingPlacer);
}
logger.log("Registered", this.interceptors.length, "interceptors");
}
cleanup() {
if (this.clickDetector) {
this.clickDetector.cleanup();
}
this.interceptors = [];
}
onCanvasClick(position, event, cancelAction = false) {
if (!this.root.gameInitialized) {
logger.warn("Skipping click outside of game initiaization!");
return;
}
if (this.root.hud.hasBlockingOverlayOpen()) {
return;
}
for (let i = 0; i < this.interceptors.length; ++i) {
const interceptor = this.interceptors[i];
if (interceptor.onCanvasClick(position, cancelAction) === STOP_PROPAGATION) {
// log(this, "Interceptor", interceptor.constructor.name, "catched click");
break;
}
}
}
onCanvasRightClick(position, event) {
this.onCanvasClick(position, event, true);
}
}

View File

@ -64,7 +64,7 @@ export class BeltComponent extends Component {
/**
* Returns if the belt can currently accept an item from the given direction
*/
canAcceptItem(leftoverProgress = 0.0) {
canAcceptItem() {
const firstItem = this.sortedItems[0];
if (!firstItem) {
return true;

View File

@ -20,6 +20,14 @@ export const enumItemAcceptorItemFilter = {
* filter?: enumItemAcceptorItemFilter
* }} ItemAcceptorSlot */
/**
* Contains information about a slot plus its location
* @typedef {{
* slot: ItemAcceptorSlot,
* index: number,
* acceptedDirection: enumDirection
* }} ItemAcceptorLocatedSlot */
export class ItemAcceptorComponent extends Component {
static getId() {
return "ItemAcceptor";
@ -164,11 +172,7 @@ export class ItemAcceptorComponent extends Component {
* Tries to find a slot which accepts the current item
* @param {Vector} targetLocalTile
* @param {enumDirection} fromLocalDirection
* @returns {{
* slot: ItemAcceptorSlot,
* index: number,
* acceptedDirection: enumDirection
* }|null}
* @returns {ItemAcceptorLocatedSlot|null}
*/
findMatchingSlot(targetLocalTile, fromLocalDirection) {
// We need to invert our direction since the acceptor specifies *from* which direction

View File

@ -12,6 +12,7 @@ export class MinerComponent extends Component {
}
static getSchema() {
// cachedMinedItem is not serialized.
return {
lastMiningTime: types.ufloat,
chainable: types.bool,
@ -25,8 +26,6 @@ export class MinerComponent extends Component {
});
}
/**
*/
constructor({ chainable = false }) {
super();
this.lastMiningTime = 0;
@ -38,6 +37,11 @@ export class MinerComponent extends Component {
* @type {Array<BaseItem>}
*/
this.itemChainBuffer = [];
/**
* @type {BaseItem}
*/
this.cachedMinedItem = null;
}
/**

View File

@ -17,7 +17,6 @@ import { SavegameSerializer } from "../savegame/savegame_serializer";
import { AutomaticSave } from "./automatic_save";
import { MetaHubBuilding } from "./buildings/hub";
import { Camera } from "./camera";
import { CanvasClickInterceptor } from "./canvas_click_interceptor";
import { EntityManager } from "./entity_manager";
import { GameSystemManager } from "./game_system_manager";
import { HubGoals } from "./hub_goals";
@ -98,7 +97,6 @@ export class GameCore {
root.logic = new GameLogic(root);
root.hud = new GameHUD(root);
root.time = new GameTime(root);
root.canvasClickInterceptor = new CanvasClickInterceptor(root);
root.automaticSave = new AutomaticSave(root);
root.soundProxy = new SoundProxy(root);
@ -409,7 +407,7 @@ export class GameCore {
}
if (G_IS_DEV) {
root.map.drawStaticEntities(params);
root.map.drawStaticEntityDebugOverlays(params);
}
// END OF GAME CONTENT

View File

@ -136,7 +136,7 @@ export class Entity extends BasicSerializableObject {
* Draws the entity, to override use @see Entity.drawImpl
* @param {DrawParameters} parameters
*/
draw(parameters) {
drawDebugOverlays(parameters) {
const context = parameters.context;
const staticComp = this.components.StaticMapEntity;

View File

@ -92,6 +92,9 @@ export class GameSystemManager {
add("staticMapEntities", StaticMapEntitySystem);
// IMPORTANT: Must be after belt system since belt system can change the
// orientation of an entity after it is placed -> the item acceptor cache
// then would be invalid
add("itemAcceptor", ItemAcceptorSystem);
logger.log("📦 There are", this.systemUpdateOrder.length, "game systems");

View File

@ -2,6 +2,10 @@
import { GameRoot } from "../root";
/* typehints:end */
/* dev:start */
import { TrailerMaker } from "./trailer_maker";
/* dev:end */
import { Signal } from "../../core/signal";
import { DrawParameters } from "../../core/draw_parameters";
import { HUDProcessingOverlay } from "./parts/processing_overlay";
@ -29,10 +33,8 @@ import { HUDModalDialogs } from "./parts/modal_dialogs";
import { HUDPartTutorialHints } from "./parts/tutorial_hints";
import { HUDWaypoints } from "./parts/waypoints";
import { HUDInteractiveTutorial } from "./parts/interactive_tutorial";
/* dev:start */
import { TrailerMaker } from "./trailer_maker";
/* dev:end */
import { HUDScreenshotExporter } from "./parts/screenshot_exporter";
import { Entity } from "../entity";
export class GameHUD {
/**
@ -57,7 +59,6 @@ export class GameHUD {
shop: new HUDShop(this.root),
statistics: new HUDStatistics(this.root),
waypoints: new HUDWaypoints(this.root),
vignetteOverlay: new HUDVignetteOverlay(this.root),
// Must always exist
pinnedShapes: new HUDPinnedShapes(this.root),
@ -66,14 +67,16 @@ export class GameHUD {
// betaOverlay: new HUDBetaOverlay(this.root),
debugInfo: new HUDDebugInfo(this.root),
dialogs: new HUDModalDialogs(this.root),
screenshotExporter: new HUDScreenshotExporter(this.root),
};
this.signals = {
selectedPlacementBuildingChanged: /** @type {TypedSignal<[MetaBuilding|null]>} */ (new Signal()),
shapePinRequested: /** @type {TypedSignal<[ShapeDefinition, number]>} */ (new Signal()),
shapePinRequested: /** @type {TypedSignal<[ShapeDefinition]>} */ (new Signal()),
shapeUnpinRequested: /** @type {TypedSignal<[string]>} */ (new Signal()),
notification: /** @type {TypedSignal<[string, enumNotificationType]>} */ (new Signal()),
buildingsSelectedForCopy: /** @type {TypedSignal<[Array<number>]>} */ (new Signal()),
pasteBlueprintRequested: new Signal(),
};
if (!IS_MOBILE) {
@ -87,11 +90,16 @@ export class GameHUD {
if (IS_DEMO) {
this.parts.watermark = new HUDWatermark(this.root);
}
if (this.root.app.settings.getAllSettings().offerHints) {
this.parts.tutorialHints = new HUDPartTutorialHints(this.root);
this.parts.interactiveTutorial = new HUDInteractiveTutorial(this.root);
}
if (this.root.app.settings.getAllSettings().vignette) {
this.parts.vignetteOverlay = new HUDVignetteOverlay(this.root);
}
const frag = document.createDocumentFragment();
for (const key in this.parts) {
this.parts[key].createElements(frag);

View File

@ -1,15 +1,15 @@
import { DrawParameters } from "../../../core/draw_parameters";
import { STOP_PROPAGATION } from "../../../core/signal";
import { TrackedState } from "../../../core/tracked_state";
import { makeDiv } from "../../../core/utils";
import { Vector } from "../../../core/vector";
import { T } from "../../../translations";
import { enumMouseButton } from "../../camera";
import { KEYMAPPINGS } from "../../key_action_mapper";
import { BaseHUDPart } from "../base_hud_part";
import { Blueprint } from "./blueprint";
import { makeDiv } from "../../../core/utils";
import { DynamicDomAttach } from "../dynamic_dom_attach";
import { blueprintShape } from "../../upgrades";
import { T } from "../../../translations";
import { BaseHUDPart } from "../base_hud_part";
import { DynamicDomAttach } from "../dynamic_dom_attach";
import { Blueprint } from "./blueprint";
export class HUDBlueprintPlacer extends BaseHUDPart {
createElements(parent) {
@ -29,16 +29,14 @@ export class HUDBlueprintPlacer extends BaseHUDPart {
/** @type {TypedTrackedState<Blueprint?>} */
this.currentBlueprint = new TrackedState(this.onBlueprintChanged, this);
/** @type {Blueprint?} */
this.lastBlueprintUsed = null;
const keyActionMapper = this.root.keyMapper;
keyActionMapper.getBinding(KEYMAPPINGS.general.back).add(this.abortPlacement, this);
keyActionMapper
.getBinding(KEYMAPPINGS.placement.abortBuildingPlacement)
.add(this.abortPlacement, this);
keyActionMapper.getBinding(KEYMAPPINGS.placement.pipette).add(this.abortPlacement, this);
keyActionMapper.getBinding(KEYMAPPINGS.placement.rotateWhilePlacing).add(this.rotateBlueprint, this);
keyActionMapper
.getBinding(KEYMAPPINGS.placement.abortBuildingPlacement)
.add(this.abortPlacement, this);
keyActionMapper.getBinding(KEYMAPPINGS.massSelect.pasteLastBlueprint).add(this.pasteBlueprint, this);
this.root.camera.downPreHandler.add(this.onMouseDown, this);
this.root.camera.movePreHandler.add(this.onMouseMove, this);
@ -62,10 +60,9 @@ export class HUDBlueprintPlacer extends BaseHUDPart {
}
update() {
this.domAttach.update(this.currentBlueprint.get());
this.trackedCanAfford.set(
this.currentBlueprint.get() && this.currentBlueprint.get().canAfford(this.root)
);
const currentBlueprint = this.currentBlueprint.get();
this.domAttach.update(currentBlueprint && currentBlueprint.getCost() > 0);
this.trackedCanAfford.set(currentBlueprint && currentBlueprint.canAfford(this.root));
}
/**
@ -73,6 +70,7 @@ export class HUDBlueprintPlacer extends BaseHUDPart {
*/
onBlueprintChanged(blueprint) {
if (blueprint) {
this.lastBlueprintUsed = blueprint;
this.costDisplayText.innerText = "" + blueprint.getCost();
}
}
@ -107,7 +105,7 @@ export class HUDBlueprintPlacer extends BaseHUDPart {
this.root.hubGoals.takeShapeByKey(blueprintShape, cost);
// This actually feels weird
// if (!this.root.keyMapper.getBinding(KEYMAPPINGS.placementModifiers.placeMultiple).isCurrentlyPressed()) {
// if (!this.root.keyMapper.getBinding(KEYMAPPINGS.placementModifiers.placeMultiple).pressed) {
// this.currentBlueprint.set(null);
// }
}
@ -132,11 +130,7 @@ export class HUDBlueprintPlacer extends BaseHUDPart {
rotateBlueprint() {
if (this.currentBlueprint.get()) {
if (
this.root.keyMapper
.getBinding(KEYMAPPINGS.placement.rotateInverseModifier)
.isCurrentlyPressed()
) {
if (this.root.keyMapper.getBinding(KEYMAPPINGS.placement.rotateInverseModifier).pressed) {
this.currentBlueprint.get().rotateCcw();
} else {
this.currentBlueprint.get().rotateCw();
@ -144,6 +138,15 @@ export class HUDBlueprintPlacer extends BaseHUDPart {
}
}
pasteBlueprint() {
if (this.lastBlueprintUsed !== null) {
this.root.hud.signals.pasteBlueprintRequested.dispatch();
this.currentBlueprint.set(this.lastBlueprintUsed);
} else {
this.root.soundProxy.playUiError();
}
}
/**
*
* @param {DrawParameters} parameters

View File

@ -1,84 +1,26 @@
import { Math_abs, Math_degrees, Math_radians } from "../../../core/builtins";
import { Math_radians } from "../../../core/builtins";
import { globalConfig } from "../../../core/config";
import { DrawParameters } from "../../../core/draw_parameters";
import { drawRotatedSprite } from "../../../core/draw_utils";
import { Loader } from "../../../core/loader";
import { STOP_PROPAGATION } from "../../../core/signal";
import { TrackedState } from "../../../core/tracked_state";
import { makeDiv, removeAllChildren } from "../../../core/utils";
import { makeDiv, removeAllChildren, pulseAnimation, clamp } from "../../../core/utils";
import {
enumDirectionToAngle,
enumDirectionToVector,
enumInvertedDirections,
Vector,
} from "../../../core/vector";
import { enumMouseButton } from "../../camera";
import { StaticMapEntityComponent } from "../../components/static_map_entity";
import { Entity } from "../../entity";
import { defaultBuildingVariant, MetaBuilding } from "../../meta_building";
import { BaseHUDPart } from "../base_hud_part";
import { DynamicDomAttach } from "../dynamic_dom_attach";
import { T } from "../../../translations";
import { KEYMAPPINGS } from "../../key_action_mapper";
import { defaultBuildingVariant } from "../../meta_building";
import { THEME } from "../../theme";
import { DynamicDomAttach } from "../dynamic_dom_attach";
import { HUDBuildingPlacerLogic } from "./building_placer_logic";
export class HUDBuildingPlacer extends BaseHUDPart {
initialize() {
/** @type {TypedTrackedState<MetaBuilding?>} */
this.currentMetaBuilding = new TrackedState(this.onSelectedMetaBuildingChanged, this);
this.currentBaseRotation = 0;
/** @type {Entity} */
this.fakeEntity = null;
const keyActionMapper = this.root.keyMapper;
keyActionMapper
.getBinding(KEYMAPPINGS.placement.abortBuildingPlacement)
.add(this.abortPlacement, this);
keyActionMapper.getBinding(KEYMAPPINGS.general.back).add(this.abortPlacement, this);
keyActionMapper.getBinding(KEYMAPPINGS.placement.rotateWhilePlacing).add(this.tryRotate, this);
keyActionMapper.getBinding(KEYMAPPINGS.placement.cycleBuildingVariants).add(this.cycleVariants, this);
this.root.hud.signals.buildingsSelectedForCopy.add(this.abortPlacement, this);
this.domAttach = new DynamicDomAttach(this.root, this.element, {});
this.root.camera.downPreHandler.add(this.onMouseDown, this);
this.root.camera.movePreHandler.add(this.onMouseMove, this);
this.root.camera.upPostHandler.add(this.abortDragging, this);
this.currentlyDragging = false;
this.currentVariant = new TrackedState(this.rerenderVariants, this);
this.variantsAttach = new DynamicDomAttach(this.root, this.variantsElement, {});
/**
* Whether we are currently drag-deleting
*/
this.currentlyDeleting = false;
/**
* Stores which variants for each building we prefer, this is based on what
* the user last selected
*/
this.preferredVariants = {};
/**
* The tile we last dragged onto
* @type {Vector}
* */
this.lastDragTile = null;
/**
* The tile we initially dragged from
* @type {Vector}
*/
this.initialDragTile = null;
this.root.signals.storyGoalCompleted.add(this.rerenderVariants, this);
this.root.signals.upgradePurchased.add(this.rerenderVariants, this);
}
export class HUDBuildingPlacer extends HUDBuildingPlacerLogic {
/**
* @param {HTMLElement} parent
*/
createElements(parent) {
this.element = makeDiv(parent, "ingame_HUD_PlacementHints", [], ``);
@ -96,189 +38,24 @@ export class HUDBuildingPlacer extends BaseHUDPart {
this.buildingInfoElements.tutorialImage = makeDiv(this.element, null, ["buildingImage"]);
this.variantsElement = makeDiv(parent, "ingame_HUD_PlacerVariants");
const compact = this.root.app.settings.getAllSettings().compactBuildingInfo;
this.element.classList.toggle("compact", compact);
this.variantsElement.classList.toggle("compact", compact);
}
abortPlacement() {
if (this.currentMetaBuilding.get()) {
this.currentMetaBuilding.set(null);
return STOP_PROPAGATION;
}
}
initialize() {
super.initialize();
/**
* mouse down pre handler
* @param {Vector} pos
* @param {enumMouseButton} button
*/
onMouseDown(pos, button) {
if (this.root.camera.getIsMapOverlayActive()) {
return;
}
// Bind to signals
this.signals.variantChanged.add(this.rerenderVariants, this);
// Placement
if (button === enumMouseButton.left && this.currentMetaBuilding.get()) {
this.currentlyDragging = true;
this.currentlyDeleting = false;
this.lastDragTile = this.root.camera.screenToWorld(pos).toTileSpace();
this.domAttach = new DynamicDomAttach(this.root, this.element, {});
this.variantsAttach = new DynamicDomAttach(this.root, this.variantsElement, {});
// Place initial building
this.tryPlaceCurrentBuildingAt(this.lastDragTile);
this.currentInterpolatedCornerTile = new Vector();
return STOP_PROPAGATION;
}
// Deletion
if (
button === enumMouseButton.right &&
(!this.currentMetaBuilding.get() ||
!this.root.app.settings.getAllSettings().abortPlacementOnDeletion)
) {
this.currentlyDragging = true;
this.currentlyDeleting = true;
this.lastDragTile = this.root.camera.screenToWorld(pos).toTileSpace();
if (this.root.app.settings.getAllSettings().abortPlacementOnDeletion) {
this.currentMetaBuilding.set(null);
}
return STOP_PROPAGATION;
}
}
/**
* mouse move pre handler
* @param {Vector} pos
*/
onMouseMove(pos) {
if (this.root.camera.getIsMapOverlayActive()) {
return;
}
const metaBuilding = this.currentMetaBuilding.get();
if ((metaBuilding || this.currentlyDeleting) && this.lastDragTile) {
const oldPos = this.lastDragTile;
const newPos = this.root.camera.screenToWorld(pos).toTileSpace();
if (this.root.camera.desiredCenter) {
// Camera is moving
this.lastDragTile = newPos;
return;
}
if (!oldPos.equals(newPos)) {
if (
metaBuilding &&
metaBuilding.getRotateAutomaticallyWhilePlacing(this.currentVariant.get()) &&
!this.root.keyMapper
.getBinding(KEYMAPPINGS.placementModifiers.placementDisableAutoOrientation)
.isCurrentlyPressed()
) {
const delta = newPos.sub(oldPos);
const angleDeg = Math_degrees(delta.angle());
this.currentBaseRotation = (Math.round(angleDeg / 90) * 90 + 360) % 360;
// Holding alt inverts the placement
if (
this.root.keyMapper
.getBinding(KEYMAPPINGS.placementModifiers.placeInverse)
.isCurrentlyPressed()
) {
this.currentBaseRotation = (180 + this.currentBaseRotation) % 360;
}
}
// - Using bresenhams algorithmus
let x0 = oldPos.x;
let y0 = oldPos.y;
let x1 = newPos.x;
let y1 = newPos.y;
var dx = Math_abs(x1 - x0);
var dy = Math_abs(y1 - y0);
var sx = x0 < x1 ? 1 : -1;
var sy = y0 < y1 ? 1 : -1;
var err = dx - dy;
while (this.currentlyDeleting || this.currentMetaBuilding.get()) {
if (this.currentlyDeleting) {
const contents = this.root.map.getTileContentXY(x0, y0);
if (contents && !contents.queuedForDestroy && !contents.destroyed) {
this.root.logic.tryDeleteBuilding(contents);
}
} else {
this.tryPlaceCurrentBuildingAt(new Vector(x0, y0));
}
if (x0 === x1 && y0 === y1) break;
var e2 = 2 * err;
if (e2 > -dy) {
err -= dy;
x0 += sx;
}
if (e2 < dx) {
err += dx;
y0 += sy;
}
}
}
this.lastDragTile = newPos;
return STOP_PROPAGATION;
}
}
update() {
// ALways update since the camera might have moved
const mousePos = this.root.app.mousePosition;
if (mousePos) {
this.onMouseMove(mousePos);
}
}
/**
* aborts any dragging op
*/
abortDragging() {
this.currentlyDragging = true;
this.currentlyDeleting = false;
this.lastDragTile = null;
}
/**
*
* @param {MetaBuilding} metaBuilding
*/
startSelection(metaBuilding) {
this.currentMetaBuilding.set(metaBuilding);
}
/**
* @param {MetaBuilding} metaBuilding
*/
onSelectedMetaBuildingChanged(metaBuilding) {
this.abortDragging();
this.root.hud.signals.selectedPlacementBuildingChanged.dispatch(metaBuilding);
if (metaBuilding) {
const variant = this.preferredVariants[metaBuilding.getId()] || defaultBuildingVariant;
this.currentVariant.set(variant);
this.fakeEntity = new Entity(null);
metaBuilding.setupEntityComponents(this.fakeEntity, null);
this.fakeEntity.addComponent(
new StaticMapEntityComponent({
origin: new Vector(0, 0),
rotation: 0,
tileSize: metaBuilding.getDimensions(this.currentVariant.get()).copy(),
blueprintSpriteKey: "",
})
);
metaBuilding.updateVariants(this.fakeEntity, 0, this.currentVariant.get());
} else {
this.fakeEntity = null;
}
// Since it depends on both, rerender twice
this.rerenderVariants();
this.lockIndicatorSprite = Loader.getSprite("sprites/misc/lock_direction_indicator.png");
}
/**
@ -373,150 +150,6 @@ export class HUDBuildingPlacer extends BaseHUDPart {
}
}
/**
* Cycles through the variants
*/
cycleVariants() {
const metaBuilding = this.currentMetaBuilding.get();
if (!metaBuilding) {
this.currentVariant.set(defaultBuildingVariant);
} else {
const availableVariants = metaBuilding.getAvailableVariants(this.root);
const index = availableVariants.indexOf(this.currentVariant.get());
assert(
index >= 0,
"Current variant was invalid: " + this.currentVariant.get() + " out of " + availableVariants
);
const newIndex = (index + 1) % availableVariants.length;
const newVariant = availableVariants[newIndex];
this.currentVariant.set(newVariant);
this.preferredVariants[metaBuilding.getId()] = newVariant;
}
}
/**
* Tries to rotate
*/
tryRotate() {
const selectedBuilding = this.currentMetaBuilding.get();
if (selectedBuilding) {
if (
this.root.keyMapper
.getBinding(KEYMAPPINGS.placement.rotateInverseModifier)
.isCurrentlyPressed()
) {
this.currentBaseRotation = (this.currentBaseRotation + 270) % 360;
} else {
this.currentBaseRotation = (this.currentBaseRotation + 90) % 360;
}
const staticComp = this.fakeEntity.components.StaticMapEntity;
staticComp.rotation = this.currentBaseRotation;
}
}
/**
* Tries to delete the building under the mouse
*/
deleteBelowCursor() {
const mousePosition = this.root.app.mousePosition;
if (!mousePosition) {
// Not on screen
return;
}
const worldPos = this.root.camera.screenToWorld(mousePosition);
const tile = worldPos.toTileSpace();
const contents = this.root.map.getTileContent(tile);
if (contents) {
this.root.logic.tryDeleteBuilding(contents);
}
}
/**
* Canvas click handler
* @param {Vector} mousePos
* @param {boolean} cancelAction
*/
onCanvasClick(mousePos, cancelAction = false) {
if (cancelAction) {
if (
this.currentMetaBuilding.get() &&
this.root.app.settings.getAllSettings().abortPlacementOnDeletion
) {
this.currentMetaBuilding.set(null);
} else {
this.deleteBelowCursor();
}
return STOP_PROPAGATION;
}
if (!this.currentMetaBuilding.get()) {
return;
}
return STOP_PROPAGATION;
}
/**
* Tries to place the current building at the given tile
* @param {Vector} tile
*/
tryPlaceCurrentBuildingAt(tile) {
if (this.root.camera.zoomLevel < globalConfig.mapChunkOverviewMinZoom) {
// Dont allow placing in overview mode
return;
}
// Transform to world space
const metaBuilding = this.currentMetaBuilding.get();
const { rotation, rotationVariant } = metaBuilding.computeOptimalDirectionAndRotationVariantAtTile(
this.root,
tile,
this.currentBaseRotation,
this.currentVariant.get()
);
if (
this.root.logic.tryPlaceBuilding({
origin: tile,
rotation,
rotationVariant,
originalRotation: this.currentBaseRotation,
building: this.currentMetaBuilding.get(),
variant: this.currentVariant.get(),
})
) {
// Succesfully placed
if (
metaBuilding.getFlipOrientationAfterPlacement() &&
!this.root.keyMapper
.getBinding(KEYMAPPINGS.placementModifiers.placementDisableAutoOrientation)
.isCurrentlyPressed()
) {
this.currentBaseRotation = (180 + this.currentBaseRotation) % 360;
}
if (
!metaBuilding.getStayInPlacementMode() &&
!this.root.keyMapper
.getBinding(KEYMAPPINGS.placementModifiers.placeMultiple)
.isCurrentlyPressed() &&
!this.root.app.settings.getAllSettings().alwaysMultiplace
) {
// Stop placement
this.currentMetaBuilding.set(null);
}
return true;
} else {
return false;
}
}
/**
*
* @param {DrawParameters} parameters
@ -537,14 +170,28 @@ export class HUDBuildingPlacer extends BaseHUDPart {
return;
}
// Draw direction lock
if (this.isDirectionLockActive) {
this.drawDirectionLock(parameters);
} else {
this.drawRegularPlacement(parameters);
}
}
/**
* @param {DrawParameters} parameters
*/
drawRegularPlacement(parameters) {
const mousePosition = this.root.app.mousePosition;
if (!mousePosition) {
// Not on screen
return;
}
const metaBuilding = this.currentMetaBuilding.get();
const worldPos = this.root.camera.screenToWorld(mousePosition);
const tile = worldPos.toTileSpace();
const mouseTile = worldPos.toTileSpace();
// Compute best rotation variant
const {
@ -553,7 +200,7 @@ export class HUDBuildingPlacer extends BaseHUDPart {
connectedEntities,
} = metaBuilding.computeOptimalDirectionAndRotationVariantAtTile(
this.root,
tile,
mouseTile,
this.currentBaseRotation,
this.currentVariant.get()
);
@ -566,7 +213,7 @@ export class HUDBuildingPlacer extends BaseHUDPart {
.getCenter()
.toWorldSpace();
const startWsPoint = tile.toWorldSpaceCenterOfTile();
const startWsPoint = mouseTile.toWorldSpaceCenterOfTile();
const startOffset = connectedWsPoint
.sub(startWsPoint)
@ -591,14 +238,14 @@ export class HUDBuildingPlacer extends BaseHUDPart {
// Synchronize rotation and origin
const staticComp = this.fakeEntity.components.StaticMapEntity;
staticComp.origin = tile;
staticComp.origin = mouseTile;
staticComp.rotation = rotation;
staticComp.tileSize = metaBuilding.getDimensions(this.currentVariant.get());
metaBuilding.updateVariants(this.fakeEntity, rotationVariant, this.currentVariant.get());
// Check if we could place the buildnig
const canBuild = this.root.logic.checkCanPlaceBuilding({
origin: tile,
origin: mouseTile,
rotation,
rotationVariant,
building: metaBuilding,
@ -635,7 +282,7 @@ export class HUDBuildingPlacer extends BaseHUDPart {
const previewSprite = metaBuilding.getBlueprintSprite(rotationVariant, this.currentVariant.get());
staticComp.origin = worldPos.divideScalar(globalConfig.tileSize).subScalars(0.5, 0.5);
staticComp.drawSpriteOnFullEntityBounds(parameters, previewSprite);
staticComp.origin = tile;
staticComp.origin = mouseTile;
// Draw ejectors
if (canBuild) {
@ -644,7 +291,63 @@ export class HUDBuildingPlacer extends BaseHUDPart {
}
/**
*
* @param {DrawParameters} parameters
*/
drawDirectionLock(parameters) {
const mousePosition = this.root.app.mousePosition;
if (!mousePosition) {
// Not on screen
return;
}
const mouseWorld = this.root.camera.screenToWorld(mousePosition);
const mouseTile = mouseWorld.toTileSpace();
parameters.context.fillStyle = THEME.map.directionLock;
parameters.context.strokeStyle = THEME.map.directionLockTrack;
parameters.context.lineWidth = 10;
parameters.context.beginCircle(mouseWorld.x, mouseWorld.y, 4);
parameters.context.fill();
if (this.lastDragTile) {
const startLine = this.lastDragTile.toWorldSpaceCenterOfTile();
const endLine = mouseTile.toWorldSpaceCenterOfTile();
const midLine = this.currentDirectionLockCorner.toWorldSpaceCenterOfTile();
parameters.context.beginCircle(startLine.x, startLine.y, 8);
parameters.context.fill();
parameters.context.beginPath();
parameters.context.moveTo(startLine.x, startLine.y);
parameters.context.lineTo(midLine.x, midLine.y);
parameters.context.lineTo(endLine.x, endLine.y);
parameters.context.stroke();
parameters.context.beginCircle(endLine.x, endLine.y, 5);
parameters.context.fill();
// Draw arrows
const path = this.computeDirectionLockPath();
for (let i = 0; i < path.length - 1; i += 1) {
const { rotation, tile } = path[i];
const worldPos = tile.toWorldSpaceCenterOfTile();
drawRotatedSprite({
parameters,
sprite: this.lockIndicatorSprite,
x: worldPos.x,
y: worldPos.y,
angle: Math_radians(rotation),
size: 12,
offsetY:
-globalConfig.halfTileSize -
clamp((this.root.time.now() * 1.5) % 1.0, 0, 1) * 1 * globalConfig.tileSize +
globalConfig.halfTileSize,
});
}
}
}
/**
* @param {DrawParameters} parameters
*/
drawMatchingAcceptorsAndEjectors(parameters) {

View File

@ -0,0 +1,690 @@
import { Math_abs, Math_degrees, Math_round } from "../../../core/builtins";
import { globalConfig } from "../../../core/config";
import { gMetaBuildingRegistry } from "../../../core/global_registries";
import { Signal, STOP_PROPAGATION } from "../../../core/signal";
import { TrackedState } from "../../../core/tracked_state";
import { Vector } from "../../../core/vector";
import { enumMouseButton } from "../../camera";
import { StaticMapEntityComponent } from "../../components/static_map_entity";
import { Entity } from "../../entity";
import { KEYMAPPINGS } from "../../key_action_mapper";
import { defaultBuildingVariant, MetaBuilding } from "../../meta_building";
import { BaseHUDPart } from "../base_hud_part";
/**
* Contains all logic for the building placer - this doesn't include the rendering
* of info boxes or drawing.
*/
export class HUDBuildingPlacerLogic extends BaseHUDPart {
/**
* Initializes the logic
* @see BaseHUDPart.initialize
*/
initialize() {
/**
* We use a fake entity to get information about how a building will look
* once placed
* @type {Entity}
*/
this.fakeEntity = null;
// Signals
this.signals = {
variantChanged: new Signal(),
draggingStarted: new Signal(),
};
/**
* The current building
* @type {TypedTrackedState<MetaBuilding?>}
*/
this.currentMetaBuilding = new TrackedState(this.onSelectedMetaBuildingChanged, this);
/**
* The current rotation
* @type {number}
*/
this.currentBaseRotation = 0;
/**
* Whether we are currently dragging
* @type {boolean}
*/
this.currentlyDragging = false;
/**
* Current building variant
* @type {TypedTrackedState<string>}
*/
this.currentVariant = new TrackedState(() => this.signals.variantChanged.dispatch());
/**
* Whether we are currently drag-deleting
* @type {boolean}
*/
this.currentlyDeleting = false;
/**
* Stores which variants for each building we prefer, this is based on what
* the user last selected
* @type {Object.<string, string>}
*/
this.preferredVariants = {};
/**
* The tile we last dragged from
* @type {Vector}
*/
this.lastDragTile = null;
/**
* The side for direction lock
* @type {number} (0|1)
*/
this.currentDirectionLockSide = 0;
this.initializeBindings();
}
/**
* Initializes all bindings
*/
initializeBindings() {
// KEYBINDINGS
const keyActionMapper = this.root.keyMapper;
keyActionMapper.getBinding(KEYMAPPINGS.placement.rotateWhilePlacing).add(this.tryRotate, this);
keyActionMapper.getBinding(KEYMAPPINGS.placement.cycleBuildingVariants).add(this.cycleVariants, this);
keyActionMapper
.getBinding(KEYMAPPINGS.placement.switchDirectionLockSide)
.add(this.switchDirectionLockSide, this);
keyActionMapper.getBinding(KEYMAPPINGS.general.back).add(this.abortPlacement, this);
keyActionMapper.getBinding(KEYMAPPINGS.placement.pipette).add(this.startPipette, this);
this.root.gameState.inputReciever.keyup.add(this.checkForDirectionLockSwitch, this);
// BINDINGS TO GAME EVENTS
this.root.hud.signals.buildingsSelectedForCopy.add(this.abortPlacement, this);
this.root.hud.signals.pasteBlueprintRequested.add(this.abortPlacement, this);
this.root.signals.storyGoalCompleted.add(() => this.signals.variantChanged.dispatch());
this.root.signals.upgradePurchased.add(() => this.signals.variantChanged.dispatch());
// MOUSE BINDINGS
this.root.camera.downPreHandler.add(this.onMouseDown, this);
this.root.camera.movePreHandler.add(this.onMouseMove, this);
this.root.camera.upPostHandler.add(this.onMouseUp, this);
}
/**
* Returns if the direction lock is currently active
* @returns {boolean}
*/
get isDirectionLockActive() {
const metaBuilding = this.currentMetaBuilding.get();
return (
metaBuilding &&
metaBuilding.getHasDirectionLockAvailable() &&
this.root.keyMapper.getBinding(KEYMAPPINGS.placementModifiers.lockBeltDirection).pressed
);
}
/**
* Returns the current direction lock corner, that is, the corner between
* mouse and original start point
* @returns {Vector|null}
*/
get currentDirectionLockCorner() {
const mousePosition = this.root.app.mousePosition;
if (!mousePosition) {
// Not on screen
return null;
}
if (!this.lastDragTile) {
// Haven't dragged yet
return null;
}
// Figure which points the line visits
const worldPos = this.root.camera.screenToWorld(mousePosition);
const mouseTile = worldPos.toTileSpace();
if (this.currentDirectionLockSide === 0) {
return new Vector(this.lastDragTile.x, mouseTile.y);
} else {
return new Vector(mouseTile.x, this.lastDragTile.y);
}
}
/**
* Aborts the placement
*/
abortPlacement() {
if (this.currentMetaBuilding.get()) {
this.currentMetaBuilding.set(null);
return STOP_PROPAGATION;
}
}
/**
* Aborts any dragging
*/
abortDragging() {
this.currentlyDragging = true;
this.currentlyDeleting = false;
this.initialPlacementVector = null;
this.lastDragTile = null;
}
/**
* @see BaseHUDPart.update
*/
update() {
// Always update since the camera might have moved
const mousePos = this.root.app.mousePosition;
if (mousePos) {
this.onMouseMove(mousePos);
}
}
/**
* Tries to rotate the current building
*/
tryRotate() {
const selectedBuilding = this.currentMetaBuilding.get();
if (selectedBuilding) {
if (this.root.keyMapper.getBinding(KEYMAPPINGS.placement.rotateInverseModifier).pressed) {
this.currentBaseRotation = (this.currentBaseRotation + 270) % 360;
} else {
this.currentBaseRotation = (this.currentBaseRotation + 90) % 360;
}
const staticComp = this.fakeEntity.components.StaticMapEntity;
staticComp.rotation = this.currentBaseRotation;
}
}
/**
* Tries to delete the building under the mouse
*/
deleteBelowCursor() {
const mousePosition = this.root.app.mousePosition;
if (!mousePosition) {
// Not on screen
return;
}
const worldPos = this.root.camera.screenToWorld(mousePosition);
const tile = worldPos.toTileSpace();
const contents = this.root.map.getTileContent(tile);
if (contents) {
this.root.logic.tryDeleteBuilding(contents);
}
}
/**
* Starts the pipette function
*/
startPipette() {
// Disable in overview
if (this.root.camera.getIsMapOverlayActive()) {
return;
}
const mousePosition = this.root.app.mousePosition;
if (!mousePosition) {
// Not on screen
return;
}
const worldPos = this.root.camera.screenToWorld(mousePosition);
const tile = worldPos.toTileSpace();
const contents = this.root.map.getTileContent(tile);
if (!contents) {
this.currentMetaBuilding.set(null);
return;
}
// Try to extract the building
const extracted = this.hack_reconstructMetaBuildingAndVariantFromBuilding(contents);
if (!extracted) {
this.currentMetaBuilding.set(null);
return;
}
this.currentMetaBuilding.set(extracted.metaBuilding);
this.currentVariant.set(extracted.variant);
this.currentBaseRotation = contents.components.StaticMapEntity.rotation;
// Make sure we selected something, and also make sure it's not a special entity
// if (contents && !contents.components.Unremovable) {
// }
}
/**
* HACK!
*
* This attempts to reconstruct the meta building and its variant from a given entity
* @param {Entity} entity
* @returns {{ metaBuilding: MetaBuilding, variant: string }}
*/
hack_reconstructMetaBuildingAndVariantFromBuilding(entity) {
if (entity.components.Hub) {
// Hub is not copyable
return null;
}
const matches = [];
const metaBuildings = gMetaBuildingRegistry.entries;
for (let i = 0; i < metaBuildings.length; ++i) {
const metaBuilding = metaBuildings[i];
const availableVariants = metaBuilding.getAvailableVariants(this.root);
checkVariant: for (let k = 0; k < availableVariants.length; ++k) {
const variant = availableVariants[k];
let unplaced = metaBuilding.createEntity({
root: this.root,
variant,
origin: new Vector(0, 0),
rotation: 0,
originalRotation: 0,
rotationVariant: 0,
});
// Compare if both entities share the same components
for (let component in entity.components) {
if ((entity.components[component] == null) !== (unplaced.components[component] == null)) {
continue checkVariant;
}
}
// Check for same item processor
if (
entity.components.ItemProcessor &&
entity.components.ItemProcessor.type != unplaced.components.ItemProcessor.type
) {
continue checkVariant;
}
// Check for underground belt
if (
entity.components.UndergroundBelt &&
entity.components.UndergroundBelt.tier != unplaced.components.UndergroundBelt.tier
) {
continue checkVariant;
}
// Check for same sprite key - except for underground belts
// since the sprite may vary here
if (
!entity.components.UndergroundBelt &&
entity.components.StaticMapEntity.spriteKey !=
unplaced.components.StaticMapEntity.spriteKey
) {
continue checkVariant;
}
matches.push({ metaBuilding, variant });
}
}
if (matches.length == 1) {
const staticEntity = entity.components.StaticMapEntity;
const key = staticEntity.spriteKey || staticEntity.blueprintSpriteKey;
assert(
key &&
key.includes(matches[0].metaBuilding.id) &&
(matches[0].variant === defaultBuildingVariant || key.includes(matches[0].variant))
);
return matches[0];
}
return null;
}
switchDirectionLockSide() {
this.currentDirectionLockSide = 1 - this.currentDirectionLockSide;
}
/**
* Checks if the direction lock key got released and if such, resets the placement
* @param {any} args
*/
checkForDirectionLockSwitch({ keyCode }) {
if (
keyCode ===
this.root.keyMapper.getBinding(KEYMAPPINGS.placementModifiers.lockBeltDirection).keyCode
) {
this.abortDragging();
}
}
/**
* Tries to place the current building at the given tile
* @param {Vector} tile
*/
tryPlaceCurrentBuildingAt(tile) {
if (this.root.camera.zoomLevel < globalConfig.mapChunkOverviewMinZoom) {
// Dont allow placing in overview mode
return;
}
const metaBuilding = this.currentMetaBuilding.get();
const { rotation, rotationVariant } = metaBuilding.computeOptimalDirectionAndRotationVariantAtTile(
this.root,
tile,
this.currentBaseRotation,
this.currentVariant.get()
);
const entity = this.root.logic.tryPlaceBuilding({
origin: tile,
rotation,
rotationVariant,
originalRotation: this.currentBaseRotation,
building: this.currentMetaBuilding.get(),
variant: this.currentVariant.get(),
});
if (entity) {
// Succesfully placed, find which entity we actually placed
this.root.signals.entityManuallyPlaced.dispatch(entity);
// Check if we should flip the orientation (used for tunnels)
if (
metaBuilding.getFlipOrientationAfterPlacement() &&
!this.root.keyMapper.getBinding(
KEYMAPPINGS.placementModifiers.placementDisableAutoOrientation
).pressed
) {
this.currentBaseRotation = (180 + this.currentBaseRotation) % 360;
}
// Check if we should stop placement
if (
!metaBuilding.getStayInPlacementMode() &&
!this.root.keyMapper.getBinding(KEYMAPPINGS.placementModifiers.placeMultiple).pressed &&
!this.root.app.settings.getAllSettings().alwaysMultiplace
) {
// Stop placement
this.currentMetaBuilding.set(null);
}
return true;
} else {
return false;
}
}
/**
* Cycles through the variants
*/
cycleVariants() {
const metaBuilding = this.currentMetaBuilding.get();
if (!metaBuilding) {
this.currentVariant.set(defaultBuildingVariant);
} else {
const availableVariants = metaBuilding.getAvailableVariants(this.root);
const index = availableVariants.indexOf(this.currentVariant.get());
assert(
index >= 0,
"Current variant was invalid: " + this.currentVariant.get() + " out of " + availableVariants
);
const newIndex = (index + 1) % availableVariants.length;
const newVariant = availableVariants[newIndex];
this.currentVariant.set(newVariant);
this.preferredVariants[metaBuilding.getId()] = newVariant;
}
}
/**
* Performs the direction locked placement between two points after
* releasing the mouse
*/
executeDirectionLockedPlacement() {
const path = this.computeDirectionLockPath();
this.root.logic.performBulkOperation(() => {
for (let i = 0; i < path.length; ++i) {
const { rotation, tile } = path[i];
this.currentBaseRotation = rotation;
this.tryPlaceCurrentBuildingAt(tile);
}
});
}
/**
* Finds the path which the current direction lock will use
* @returns {Array<{ tile: Vector, rotation: number }>}
*/
computeDirectionLockPath() {
const mousePosition = this.root.app.mousePosition;
if (!mousePosition) {
// Not on screen
return [];
}
let result = [];
// Figure which points the line visits
const worldPos = this.root.camera.screenToWorld(mousePosition);
const mouseTile = worldPos.toTileSpace();
const startTile = this.lastDragTile;
// Place from start to corner
const pathToCorner = this.currentDirectionLockCorner.sub(startTile);
const deltaToCorner = pathToCorner.normalize().round();
const lengthToCorner = Math_round(pathToCorner.length());
let currentPos = startTile.copy();
let rotation = (Math.round(Math_degrees(deltaToCorner.angle()) / 90) * 90 + 360) % 360;
if (lengthToCorner > 0) {
for (let i = 0; i < lengthToCorner; ++i) {
result.push({
tile: currentPos.copy(),
rotation,
});
currentPos.addInplace(deltaToCorner);
}
}
// Place from corner to end
const pathFromCorner = mouseTile.sub(this.currentDirectionLockCorner);
const deltaFromCorner = pathFromCorner.normalize().round();
const lengthFromCorner = Math_round(pathFromCorner.length());
if (lengthFromCorner > 0) {
rotation = (Math.round(Math_degrees(deltaFromCorner.angle()) / 90) * 90 + 360) % 360;
for (let i = 0; i < lengthFromCorner + 1; ++i) {
result.push({
tile: currentPos.copy(),
rotation,
});
currentPos.addInplace(deltaFromCorner);
}
} else {
// Finish last one
result.push({
tile: currentPos.copy(),
rotation,
});
}
return result;
}
/**
* Selects a given building
* @param {MetaBuilding} metaBuilding
*/
startSelection(metaBuilding) {
this.currentMetaBuilding.set(metaBuilding);
}
/**
* Called when the selected buildings changed
* @param {MetaBuilding} metaBuilding
*/
onSelectedMetaBuildingChanged(metaBuilding) {
this.abortDragging();
this.root.hud.signals.selectedPlacementBuildingChanged.dispatch(metaBuilding);
if (metaBuilding) {
const variant = this.preferredVariants[metaBuilding.getId()] || defaultBuildingVariant;
this.currentVariant.set(variant);
this.fakeEntity = new Entity(null);
metaBuilding.setupEntityComponents(this.fakeEntity, null);
this.fakeEntity.addComponent(
new StaticMapEntityComponent({
origin: new Vector(0, 0),
rotation: 0,
tileSize: metaBuilding.getDimensions(this.currentVariant.get()).copy(),
blueprintSpriteKey: "",
})
);
metaBuilding.updateVariants(this.fakeEntity, 0, this.currentVariant.get());
} else {
this.fakeEntity = null;
}
// Since it depends on both, rerender twice
this.signals.variantChanged.dispatch();
}
/**
* mouse down pre handler
* @param {Vector} pos
* @param {enumMouseButton} button
*/
onMouseDown(pos, button) {
if (this.root.camera.getIsMapOverlayActive()) {
// We do not allow dragging if the overlay is active
return;
}
const metaBuilding = this.currentMetaBuilding.get();
// Placement
if (button === enumMouseButton.left && metaBuilding) {
this.currentlyDragging = true;
this.currentlyDeleting = false;
this.lastDragTile = this.root.camera.screenToWorld(pos).toTileSpace();
// Place initial building, but only if direction lock is not active
if (!this.isDirectionLockActive) {
this.tryPlaceCurrentBuildingAt(this.lastDragTile);
}
return STOP_PROPAGATION;
}
// Deletion
if (button === enumMouseButton.right && !metaBuilding) {
this.currentlyDragging = true;
this.currentlyDeleting = true;
this.lastDragTile = this.root.camera.screenToWorld(pos).toTileSpace();
this.deleteBelowCursor();
return STOP_PROPAGATION;
}
// Cancel placement
if (button === enumMouseButton.right && metaBuilding) {
this.currentMetaBuilding.set(null);
}
}
/**
* mouse move pre handler
* @param {Vector} pos
*/
onMouseMove(pos) {
if (this.root.camera.getIsMapOverlayActive()) {
return;
}
// Check for direction lock
if (this.isDirectionLockActive) {
return;
}
const metaBuilding = this.currentMetaBuilding.get();
if ((metaBuilding || this.currentlyDeleting) && this.lastDragTile) {
const oldPos = this.lastDragTile;
let newPos = this.root.camera.screenToWorld(pos).toTileSpace();
// Check if camera is moving, since then we do nothing
if (this.root.camera.desiredCenter) {
this.lastDragTile = newPos;
return;
}
// Check if anything changed
if (!oldPos.equals(newPos)) {
// Automatic Direction
if (
metaBuilding &&
metaBuilding.getRotateAutomaticallyWhilePlacing(this.currentVariant.get()) &&
!this.root.keyMapper.getBinding(
KEYMAPPINGS.placementModifiers.placementDisableAutoOrientation
).pressed
) {
const delta = newPos.sub(oldPos);
const angleDeg = Math_degrees(delta.angle());
this.currentBaseRotation = (Math.round(angleDeg / 90) * 90 + 360) % 360;
// Holding alt inverts the placement
if (this.root.keyMapper.getBinding(KEYMAPPINGS.placementModifiers.placeInverse).pressed) {
this.currentBaseRotation = (180 + this.currentBaseRotation) % 360;
}
}
// bresenham
let x0 = oldPos.x;
let y0 = oldPos.y;
let x1 = newPos.x;
let y1 = newPos.y;
var dx = Math_abs(x1 - x0);
var dy = Math_abs(y1 - y0);
var sx = x0 < x1 ? 1 : -1;
var sy = y0 < y1 ? 1 : -1;
var err = dx - dy;
while (this.currentlyDeleting || this.currentMetaBuilding.get()) {
if (this.currentlyDeleting) {
const contents = this.root.map.getTileContentXY(x0, y0);
if (contents && !contents.queuedForDestroy && !contents.destroyed) {
this.root.logic.tryDeleteBuilding(contents);
}
} else {
this.tryPlaceCurrentBuildingAt(new Vector(x0, y0));
}
if (x0 === x1 && y0 === y1) break;
var e2 = 2 * err;
if (e2 > -dy) {
err -= dy;
x0 += sx;
}
if (e2 < dx) {
err += dx;
y0 += sy;
}
}
}
this.lastDragTile = newPos;
return STOP_PROPAGATION;
}
}
/**
* Mouse up handler
*/
onMouseUp() {
if (this.root.camera.getIsMapOverlayActive()) {
return;
}
// Check for direction lock
if (this.lastDragTile && this.currentlyDragging && this.isDirectionLockActive) {
this.executeDirectionLockedPlacement();
}
this.abortDragging();
}
}

View File

@ -39,7 +39,7 @@ export class HUDInteractiveTutorial extends BaseHUDPart {
"ingame_HUD_InteractiveTutorial",
["animEven"],
`
<strong class="title">Tutorial</strong>
<strong class="title">${T.ingame.interactiveTutorial.title}</strong>
`
);

View File

@ -1,103 +1,316 @@
import { makeDiv } from "../../../core/utils";
import { T } from "../../../translations";
import { getStringForKeyCode, KEYMAPPINGS } from "../../key_action_mapper";
import {
getStringForKeyCode,
KEYCODE_LMB,
KEYCODE_MMB,
KEYCODE_RMB,
KEYMAPPINGS,
} from "../../key_action_mapper";
import { BaseHUDPart } from "../base_hud_part";
import { TrackedState } from "../../../core/tracked_state";
import { DynamicDomAttach } from "../dynamic_dom_attach";
const DIVIDER_TOKEN = "/";
const ADDER_TOKEN = "+";
/**
* @typedef {{ keyCode: number }} KeyCode
*/
/**
* @typedef {{
* condition: () => boolean,
* keys: Array<KeyCode|number|string>,
* label: string,
* cachedElement?: HTMLElement,
* cachedVisibility?: boolean
* }} KeyBinding
*/
export class HUDKeybindingOverlay extends BaseHUDPart {
initialize() {
this.root.hud.signals.selectedPlacementBuildingChanged.add(
this.onSelectedBuildingForPlacementChanged,
this
);
initialize() {}
this.trackedMapOverviewActive = new TrackedState(this.applyCssClasses, this);
/**
* HELPER / Returns if there is a building selected for placement
* @returns {boolean}
*/
get buildingPlacementActive() {
const placer = this.root.hud.parts.buildingPlacer;
return !this.mapOverviewActive && placer && !!placer.currentMetaBuilding.get();
}
/**
* HELPER / Returns if there is a building selected for placement and
* it supports the belt planner
* @returns {boolean}
*/
get buildingPlacementSupportsBeltPlanner() {
const placer = this.root.hud.parts.buildingPlacer;
return (
!this.mapOverviewActive &&
placer &&
placer.currentMetaBuilding.get() &&
placer.currentMetaBuilding.get().getHasDirectionLockAvailable()
);
}
/**
* HELPER / Returns if there is a building selected for placement and
* it has multiplace enabled by default
* @returns {boolean}
*/
get buildingPlacementStaysInPlacement() {
const placer = this.root.hud.parts.buildingPlacer;
return (
!this.mapOverviewActive &&
placer &&
placer.currentMetaBuilding.get() &&
placer.currentMetaBuilding.get().getStayInPlacementMode()
);
}
/**
* HELPER / Returns if there is a blueprint selected for placement
* @returns {boolean}
*/
get blueprintPlacementActive() {
const placer = this.root.hud.parts.blueprintPlacer;
return placer && !!placer.currentBlueprint.get();
}
/**
* HELPER / Returns if the belt planner is currently active
* @returns {boolean}
*/
get beltPlannerActive() {
const placer = this.root.hud.parts.buildingPlacer;
return !this.mapOverviewActive && placer && placer.isDirectionLockActive;
}
/**
* HELPER / Returns if there is a last blueprint available
* @returns {boolean}
*/
get lastBlueprintAvailable() {
const placer = this.root.hud.parts.blueprintPlacer;
return placer && !!placer.lastBlueprintUsed;
}
/**
* HELPER / Returns if there is anything selected on the map
* @returns {boolean}
*/
get anythingSelectedOnMap() {
const selector = this.root.hud.parts.massSelector;
return selector && selector.selectedUids.size > 0;
}
/**
* HELPER / Returns if there is a building or blueprint selected for placement
* @returns {boolean}
*/
get anyPlacementActive() {
return this.buildingPlacementActive || this.blueprintPlacementActive;
}
/**
* HELPER / Returns if the map overview is active
* @returns {boolean}
*/
get mapOverviewActive() {
return this.root.camera.getIsMapOverlayActive();
}
/**
* Initializes the element
* @param {HTMLElement} parent
*/
createElements(parent) {
const mapper = this.root.keyMapper;
const k = KEYMAPPINGS;
const getKeycode = id => {
return getStringForKeyCode(mapper.getBinding(id).keyCode);
};
/** @type {Array<KeyBinding>} */
this.keybindings = [
{
// Move map - Including mouse
label: T.ingame.keybindingsOverlay.moveMap,
keys: [
KEYCODE_LMB,
DIVIDER_TOKEN,
k.navigation.mapMoveUp,
k.navigation.mapMoveLeft,
k.navigation.mapMoveDown,
k.navigation.mapMoveRight,
],
condition: () => !this.anyPlacementActive,
},
this.element = makeDiv(
parent,
"ingame_HUD_KeybindingOverlay",
[],
`
{
// Move map - No mouse
label: T.ingame.keybindingsOverlay.moveMap,
keys: [
k.navigation.mapMoveUp,
k.navigation.mapMoveLeft,
k.navigation.mapMoveDown,
k.navigation.mapMoveRight,
],
condition: () => this.anyPlacementActive,
},
<div class="binding">
<code class="keybinding leftMouse noPlacementOnly"></code><i class="noPlacementOnly"></i>
<code class="keybinding">${getKeycode(KEYMAPPINGS.navigation.mapMoveUp)}</code>
<code class="keybinding">${getKeycode(KEYMAPPINGS.navigation.mapMoveLeft)}</code>
<code class="keybinding">${getKeycode(KEYMAPPINGS.navigation.mapMoveDown)}</code>
<code class="keybinding">${getKeycode(KEYMAPPINGS.navigation.mapMoveRight)}</code>
<label>${T.ingame.keybindingsOverlay.moveMap}</label>
</div>
<div class="binding noPlacementOnly noOverviewOnly">
<code class="keybinding rightMouse"></code>
<label>${T.ingame.keybindingsOverlay.delete}</label>
</div>
<div class="binding noPlacementOnly overviewOnly">
<code class="keybinding rightMouse"></code>
<label>${T.ingame.keybindingsOverlay.createMarker}</label>
</div>
{
// [OVERVIEW] Create marker with right click
label: T.ingame.keybindingsOverlay.createMarker,
keys: [KEYCODE_RMB],
condition: () => this.mapOverviewActive && !this.blueprintPlacementActive,
},
{
// Pipette
label: T.ingame.keybindingsOverlay.pipette,
keys: [k.placement.pipette],
condition: () => !this.mapOverviewActive,
},
<div class="binding noPlacementOnly">
<code class="keybinding builtinKey">${getKeycode(
KEYMAPPINGS.massSelect.massSelectStart
)}</code>+
<code class="keybinding leftMouse"></code>
<label>${T.ingame.keybindingsOverlay.selectBuildings}</label>
</div>
<div class="binding placementOnly">
<code class="keybinding leftMouse"></code>
<label>${T.ingame.keybindingsOverlay.placeBuilding}</label>
</div>
<div class="binding placementOnly">
<code class="keybinding rightMouse"></code><i></i>
<code class="keybinding">${getKeycode(KEYMAPPINGS.placement.abortBuildingPlacement)}</code>
<label>${T.ingame.keybindingsOverlay.stopPlacement}</label>
</div>
{
// Cancel placement
label: T.ingame.keybindingsOverlay.stopPlacement,
keys: [KEYCODE_RMB],
condition: () => this.anyPlacementActive,
},
<div class="binding placementOnly">
<code class="keybinding">${getKeycode(KEYMAPPINGS.placement.rotateWhilePlacing)}</code>
<label>${T.ingame.keybindingsOverlay.rotateBuilding}</label>
</div>
{
// Delete with right click
label: T.ingame.keybindingsOverlay.delete,
keys: [KEYCODE_RMB],
condition: () =>
!this.anyPlacementActive && !this.mapOverviewActive && !this.anythingSelectedOnMap,
},
` +
(this.root.app.settings.getAllSettings().alwaysMultiplace
? ""
: `
<div class="binding placementOnly">
<code class="keybinding builtinKey shift">${getKeycode(
KEYMAPPINGS.placementModifiers.placeMultiple
)}</code>
<label>${T.ingame.keybindingsOverlay.placeMultiple}</label>
</div>`) +
`
`
);
}
{
// Area select
label: T.ingame.keybindingsOverlay.selectBuildings,
keys: [k.massSelect.massSelectStart, ADDER_TOKEN, KEYCODE_LMB],
condition: () => !this.anyPlacementActive && !this.anythingSelectedOnMap,
},
onSelectedBuildingForPlacementChanged(selectedMetaBuilding) {
this.element.classList.toggle("placementActive", !!selectedMetaBuilding);
}
{
// Place building
label: T.ingame.keybindingsOverlay.placeBuilding,
keys: [KEYCODE_LMB],
condition: () => this.anyPlacementActive,
},
applyCssClasses() {
this.element.classList.toggle("mapOverviewActive", this.root.camera.getIsMapOverlayActive());
{
// Rotate
label: T.ingame.keybindingsOverlay.rotateBuilding,
keys: [k.placement.rotateWhilePlacing],
condition: () => this.anyPlacementActive && !this.beltPlannerActive,
},
{
// [BELT PLANNER] Flip Side
label: T.ingame.keybindingsOverlay.plannerSwitchSide,
keys: [k.placement.switchDirectionLockSide],
condition: () => this.beltPlannerActive,
},
{
// Place last blueprint
label: T.ingame.keybindingsOverlay.pasteLastBlueprint,
keys: [k.massSelect.pasteLastBlueprint],
condition: () => !this.blueprintPlacementActive && this.lastBlueprintAvailable,
},
{
// Belt planner
label: T.ingame.keybindingsOverlay.lockBeltDirection,
keys: [k.placementModifiers.lockBeltDirection],
condition: () => this.buildingPlacementSupportsBeltPlanner && !this.beltPlannerActive,
},
{
// [SELECTION] Destroy
label: T.ingame.keybindingsOverlay.delete,
keys: [k.massSelect.confirmMassDelete],
condition: () => this.anythingSelectedOnMap,
},
{
// [SELECTION] Cancel
label: T.ingame.keybindingsOverlay.clearSelection,
keys: [k.general.back],
condition: () => this.anythingSelectedOnMap,
},
{
// [SELECTION] Cut
label: T.ingame.keybindingsOverlay.cutSelection,
keys: [k.massSelect.massSelectCut],
condition: () => this.anythingSelectedOnMap,
},
{
// [SELECTION] Copy
label: T.ingame.keybindingsOverlay.copySelection,
keys: [k.massSelect.massSelectCopy],
condition: () => this.anythingSelectedOnMap,
},
];
if (!this.root.app.settings.getAllSettings().alwaysMultiplace) {
this.keybindings.push({
// Multiplace
label: T.ingame.keybindingsOverlay.placeMultiple,
keys: [k.placementModifiers.placeMultiple],
condition: () => this.anyPlacementActive && !this.buildingPlacementStaysInPlacement,
});
}
this.element = makeDiv(parent, "ingame_HUD_KeybindingOverlay", []);
for (let i = 0; i < this.keybindings.length; ++i) {
let html = "";
const handle = this.keybindings[i];
for (let k = 0; k < handle.keys.length; ++k) {
const key = handle.keys[k];
switch (key) {
case KEYCODE_LMB:
html += `<code class="keybinding leftMouse"></code>`;
break;
case KEYCODE_RMB:
html += `<code class="keybinding rightMouse"></code>`;
break;
case KEYCODE_MMB:
html += `<code class="keybinding middleMouse"></code>`;
break;
case DIVIDER_TOKEN:
html += `<i></i>`;
break;
case ADDER_TOKEN:
html += `+`;
break;
default:
html += `<code class="keybinding">${getStringForKeyCode(
mapper.getBinding(/** @type {KeyCode} */ (key)).keyCode
)}</code>`;
}
}
html += `<label>${handle.label}</label>`;
handle.cachedElement = makeDiv(this.element, null, ["binding"], html);
handle.cachedVisibility = false;
}
}
update() {
this.trackedMapOverviewActive.set(this.root.camera.getIsMapOverlayActive());
for (let i = 0; i < this.keybindings.length; ++i) {
const handle = this.keybindings[i];
const visibility = handle.condition();
if (visibility !== handle.cachedVisibility) {
handle.cachedVisibility = visibility;
handle.cachedElement.classList.toggle("visible", visibility);
}
}
}
}

View File

@ -17,34 +17,17 @@ import { enumHubGoalRewards } from "../../tutorial_goals";
const logger = createLogger("hud/mass_selector");
export class HUDMassSelector extends BaseHUDPart {
createElements(parent) {
const removalKeybinding = this.root.keyMapper
.getBinding(KEYMAPPINGS.massSelect.confirmMassDelete)
.getKeyCodeString();
const abortKeybinding = this.root.keyMapper.getBinding(KEYMAPPINGS.general.back).getKeyCodeString();
const copyKeybinding = this.root.keyMapper
.getBinding(KEYMAPPINGS.massSelect.massSelectCopy)
.getKeyCodeString();
this.element = makeDiv(
parent,
"ingame_HUD_MassSelector",
[],
T.ingame.massSelect.infoText
.replace("<keyDelete>", `<code class='keybinding'>${removalKeybinding}</code>`)
.replace("<keyCopy>", `<code class='keybinding'>${copyKeybinding}</code>`)
.replace("<keyCancel>", `<code class='keybinding'>${abortKeybinding}</code>`)
);
}
createElements(parent) {}
initialize() {
this.deletionMarker = Loader.getSprite("sprites/misc/deletion_marker.png");
this.currentSelectionStart = null;
this.currentSelectionStartWorld = null;
this.currentSelectionEnd = null;
this.selectedUids = new Set();
this.root.signals.entityQueuedForDestroy.add(this.onEntityDestroyed, this);
this.root.hud.signals.pasteBlueprintRequested.add(this.clearSelection, this);
this.root.camera.downPreHandler.add(this.onMouseDown, this);
this.root.camera.movePreHandler.add(this.onMouseMove, this);
@ -54,9 +37,10 @@ export class HUDMassSelector extends BaseHUDPart {
this.root.keyMapper
.getBinding(KEYMAPPINGS.massSelect.confirmMassDelete)
.add(this.confirmDelete, this);
this.root.keyMapper.getBinding(KEYMAPPINGS.massSelect.massSelectCut).add(this.confirmCut, this);
this.root.keyMapper.getBinding(KEYMAPPINGS.massSelect.massSelectCopy).add(this.startCopy, this);
this.domAttach = new DynamicDomAttach(this.root, this.element);
this.root.hud.signals.selectedPlacementBuildingChanged.add(this.clearSelection, this);
}
/**
@ -78,6 +62,13 @@ export class HUDMassSelector extends BaseHUDPart {
}
}
/**
* Clears the entire selection
*/
clearSelection() {
this.selectedUids = new Set();
}
confirmDelete() {
if (this.selectedUids.size > 100) {
const { ok } = this.root.hud.parts.dialogs.showWarning(
@ -123,13 +114,56 @@ export class HUDMassSelector extends BaseHUDPart {
}
}
confirmCut() {
if (!this.root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_blueprints)) {
this.root.hud.parts.dialogs.showInfo(
T.dialogs.blueprintsNotUnlocked.title,
T.dialogs.blueprintsNotUnlocked.desc
);
} else if (this.selectedUids.size > 100) {
const { ok } = this.root.hud.parts.dialogs.showWarning(
T.dialogs.massCutConfirm.title,
T.dialogs.massCutConfirm.desc.replace(
"<count>",
"" + formatBigNumberFull(this.selectedUids.size)
),
["cancel:good", "ok:bad"]
);
ok.add(() => this.doCut());
} else {
this.doCut();
}
}
doCut() {
if (this.selectedUids.size > 0) {
const entityUids = Array.from(this.selectedUids);
// copy code relies on entities still existing, so must copy before deleting.
this.root.hud.signals.buildingsSelectedForCopy.dispatch(entityUids);
for (let i = 0; i < entityUids.length; ++i) {
const uid = entityUids[i];
const entity = this.root.entityMgr.findByUid(uid);
if (!this.root.logic.tryDeleteBuilding(entity)) {
logger.error("Error in mass cut, could not remove building");
this.selectedUids.delete(uid);
}
}
this.root.soundProxy.playUiClick();
} else {
this.root.soundProxy.playUiError();
}
}
/**
* mouse down pre handler
* @param {Vector} pos
* @param {enumMouseButton} mouseButton
*/
onMouseDown(pos, mouseButton) {
if (!this.root.keyMapper.getBinding(KEYMAPPINGS.massSelect.massSelectStart).isCurrentlyPressed()) {
if (!this.root.keyMapper.getBinding(KEYMAPPINGS.massSelect.massSelectStart).pressed) {
return;
}
@ -137,16 +171,12 @@ export class HUDMassSelector extends BaseHUDPart {
return;
}
if (
!this.root.keyMapper
.getBinding(KEYMAPPINGS.massSelect.massSelectSelectMultiple)
.isCurrentlyPressed()
) {
if (!this.root.keyMapper.getBinding(KEYMAPPINGS.massSelect.massSelectSelectMultiple).pressed) {
// Start new selection
this.selectedUids = new Set();
}
this.currentSelectionStart = pos.copy();
this.currentSelectionStartWorld = this.root.camera.screenToWorld(pos.copy());
this.currentSelectionEnd = pos.copy();
return STOP_PROPAGATION;
}
@ -156,14 +186,14 @@ export class HUDMassSelector extends BaseHUDPart {
* @param {Vector} pos
*/
onMouseMove(pos) {
if (this.currentSelectionStart) {
if (this.currentSelectionStartWorld) {
this.currentSelectionEnd = pos.copy();
}
}
onMouseUp() {
if (this.currentSelectionStart) {
const worldStart = this.root.camera.screenToWorld(this.currentSelectionStart);
if (this.currentSelectionStartWorld) {
const worldStart = this.currentSelectionStartWorld;
const worldEnd = this.root.camera.screenToWorld(this.currentSelectionEnd);
const tileStart = worldStart.toTileSpace();
@ -181,15 +211,11 @@ export class HUDMassSelector extends BaseHUDPart {
}
}
this.currentSelectionStart = null;
this.currentSelectionStartWorld = null;
this.currentSelectionEnd = null;
}
}
update() {
this.domAttach.update(this.selectedUids.size > 0);
}
/**
*
* @param {DrawParameters} parameters
@ -197,8 +223,8 @@ export class HUDMassSelector extends BaseHUDPart {
draw(parameters) {
const boundsBorder = 2;
if (this.currentSelectionStart) {
const worldStart = this.root.camera.screenToWorld(this.currentSelectionStart);
if (this.currentSelectionStartWorld) {
const worldStart = this.currentSelectionStartWorld;
const worldEnd = this.root.camera.screenToWorld(this.currentSelectionEnd);
const realWorldStart = worldStart.min(worldEnd);

View File

@ -1,22 +1,54 @@
import { Math_max } from "../../../core/builtins";
import { ClickDetector } from "../../../core/click_detector";
import { formatBigNumber, makeDiv } from "../../../core/utils";
import { formatBigNumber, makeDiv, arrayDelete, arrayDeleteValue } from "../../../core/utils";
import { ShapeDefinition } from "../../shape_definition";
import { BaseHUDPart } from "../base_hud_part";
import { blueprintShape } from "../../upgrades";
import { blueprintShape, UPGRADES } from "../../upgrades";
import { enumHubGoalRewards } from "../../tutorial_goals";
/**
* Manages the pinned shapes on the left side of the screen
*/
export class HUDPinnedShapes extends BaseHUDPart {
constructor(root) {
super(root);
/**
* Store a list of pinned shapes
* @type {Array<string>}
*/
this.pinnedShapes = [];
/**
* Store handles to the currently rendered elements, so we can update them more
* convenient. Also allows for cleaning up handles.
* @type {Array<{
* key: string,
* amountLabel: HTMLElement,
* lastRenderedValue: string,
* element: HTMLElement,
* detector?: ClickDetector
* }>}
*/
this.handles = [];
}
createElements(parent) {
this.element = makeDiv(parent, "ingame_HUD_PinnedShapes", []);
}
/**
* Serializes the pinned shapes
*/
serialize() {
return {
shapes: this.pinnedShapes,
};
}
/**
* Deserializes the pinned shapes
* @param {{ shapes: Array<string>}} data
*/
deserialize(data) {
if (!data || !data.shapes || !Array.isArray(data.shapes)) {
return "Invalid pinned shapes data";
@ -24,48 +56,99 @@ export class HUDPinnedShapes extends BaseHUDPart {
this.pinnedShapes = data.shapes;
}
/**
* Initializes the hud component
*/
initialize() {
/** @type {Array<{ key: string, goal: number }>} */
this.pinnedShapes = [];
/** @type {Array<{key: string, amountLabel: HTMLElement, lastRenderedValue: number, element: HTMLElement, detector?: ClickDetector}>} */
this.handles = [];
this.rerenderFull();
// Connect to any relevant signals
this.root.signals.storyGoalCompleted.add(this.rerenderFull, this);
this.root.signals.upgradePurchased.add(this.updateShapesAfterUpgrade, this);
this.root.signals.postLoadHook.add(this.rerenderFull, this);
this.root.hud.signals.shapePinRequested.add(this.pinNewShape, this);
this.root.hud.signals.shapeUnpinRequested.add(this.unpinShape, this);
// Perform initial render
this.updateShapesAfterUpgrade();
}
/**
* Returns whether a given shape is pinned
* Updates all shapes after an upgrade has been purchased and removes the unused ones
*/
updateShapesAfterUpgrade() {
for (let i = 0; i < this.pinnedShapes.length; ++i) {
const key = this.pinnedShapes[i];
if (key === blueprintShape) {
// Ignore blueprint shapes
continue;
}
let goal = this.findGoalValueForShape(key);
if (!goal) {
// Seems no longer relevant
this.pinnedShapes.splice(i, 1);
i -= 1;
}
}
this.rerenderFull();
}
/**
* Finds the current goal for the given key. If the key is the story goal, returns
* the story goal. If its the blueprint shape, no goal is returned. Otherwise
* it's searched for upgrades.
* @param {string} key
*/
findGoalValueForShape(key) {
if (key === this.root.hubGoals.currentGoal.definition.getHash()) {
return this.root.hubGoals.currentGoal.required;
}
if (key === blueprintShape) {
return null;
}
// Check if this shape is required for any upgrade
for (const upgradeId in UPGRADES) {
const { tiers } = UPGRADES[upgradeId];
const currentTier = this.root.hubGoals.getUpgradeLevel(upgradeId);
const tierHandle = tiers[currentTier];
if (!tierHandle) {
// Max level
continue;
}
for (let i = 0; i < tierHandle.required.length; ++i) {
const { shape, amount } = tierHandle.required[i];
if (shape === key) {
return amount;
}
}
}
return null;
}
/**
* Returns whether a given shape is currently pinned
* @param {string} key
*/
isShapePinned(key) {
if (!this.pinnedShapes) {
return false;
}
if (key === this.root.hubGoals.currentGoal.definition.getHash()) {
return true;
}
if (key === blueprintShape) {
if (key === this.root.hubGoals.currentGoal.definition.getHash() || key === blueprintShape) {
// This is a "special" shape which is always pinned
return true;
}
for (let i = 0; i < this.pinnedShapes.length; ++i) {
if (this.pinnedShapes[i].key === key) {
return true;
}
}
return false;
return this.pinnedShapes.indexOf(key) >= 0;
}
/**
* Rerenders the whole component
*/
rerenderFull() {
const currentGoal = this.root.hubGoals.currentGoal;
const currentKey = currentGoal.definition.getHash();
// First, remove old ones
// First, remove all old shapes
for (let i = 0; i < this.handles.length; ++i) {
this.handles[i].element.remove();
const detector = this.handles[i].detector;
@ -75,28 +158,30 @@ export class HUDPinnedShapes extends BaseHUDPart {
}
this.handles = [];
this.internalPinShape(currentKey, currentGoal.required, false, "goal");
// Pin story goal
this.internalPinShape(currentKey, false, "goal");
// Pin blueprint shape as well
if (this.root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_blueprints)) {
this.internalPinShape(blueprintShape, null, false, "blueprint");
this.internalPinShape(blueprintShape, false, "blueprint");
}
// Pin manually pinned shapes
for (let i = 0; i < this.pinnedShapes.length; ++i) {
const key = this.pinnedShapes[i].key;
const key = this.pinnedShapes[i];
if (key !== currentKey) {
this.internalPinShape(key, this.pinnedShapes[i].goal);
this.internalPinShape(key);
}
}
}
/**
* Pins a shape
* Pins a new shape
* @param {string} key
* @param {number} goal
* @param {boolean} canUnpin
* @param {string=} className
*/
internalPinShape(key, goal, canUnpin = true, className = null) {
internalPinShape(key, canUnpin = true, className = null) {
const definition = this.root.shapeDefinitionMgr.getShapeFromShortKey(key);
const element = makeDiv(this.element, null, ["shape"]);
@ -121,6 +206,7 @@ export class HUDPinnedShapes extends BaseHUDPart {
const amountLabel = makeDiv(element, null, ["amountLabel"], "");
const goal = this.findGoalValueForShape(key);
if (goal) {
makeDiv(element, null, ["goalLabel"], "/" + formatBigNumber(goal));
}
@ -129,18 +215,24 @@ export class HUDPinnedShapes extends BaseHUDPart {
key,
element,
amountLabel,
lastRenderedValue: -1,
lastRenderedValue: "",
});
}
/**
* Updates all amount labels
*/
update() {
for (let i = 0; i < this.handles.length; ++i) {
const handle = this.handles[i];
const currentValue = this.root.hubGoals.getShapesStoredByKey(handle.key);
if (currentValue !== handle.lastRenderedValue) {
handle.lastRenderedValue = currentValue;
handle.amountLabel.innerText = formatBigNumber(currentValue);
const currentValueFormatted = formatBigNumber(currentValue);
if (currentValueFormatted !== handle.lastRenderedValue) {
handle.lastRenderedValue = currentValueFormatted;
handle.amountLabel.innerText = currentValueFormatted;
const goal = this.findGoalValueForShape(handle.key);
handle.element.classList.toggle("completed", goal && currentValue > goal);
}
}
}
@ -150,20 +242,15 @@ export class HUDPinnedShapes extends BaseHUDPart {
* @param {string} key
*/
unpinShape(key) {
for (let i = 0; i < this.pinnedShapes.length; ++i) {
if (this.pinnedShapes[i].key === key) {
this.pinnedShapes.splice(i, 1);
this.rerenderFull();
return;
}
}
arrayDeleteValue(this.pinnedShapes, key);
this.rerenderFull();
}
/**
* Requests to pin a new shape
* @param {ShapeDefinition} definition
* @param {number} goal
*/
pinNewShape(definition, goal) {
pinNewShape(definition) {
const key = definition.getHash();
if (key === this.root.hubGoals.currentGoal.definition.getHash()) {
// Can not pin current goal
@ -171,18 +258,16 @@ export class HUDPinnedShapes extends BaseHUDPart {
}
if (key === blueprintShape) {
// Can not pin the blueprint shape
return;
}
for (let i = 0; i < this.pinnedShapes.length; ++i) {
if (this.pinnedShapes[i].key === key) {
// Already pinned
this.pinnedShapes[i].goal = Math_max(this.pinnedShapes[i].goal, goal);
return;
}
// Check if its already pinned
if (this.pinnedShapes.indexOf(key) >= 0) {
return;
}
this.pinnedShapes.push({ key, goal });
this.pinnedShapes.push(key);
this.rerenderFull();
}
}

View File

@ -0,0 +1,112 @@
import { BaseHUDPart } from "../base_hud_part";
import { KEYMAPPINGS } from "../../key_action_mapper";
import { IS_DEMO, globalConfig } from "../../../core/config";
import { T } from "../../../translations";
import { createLogger } from "../../../core/logging";
import { StaticMapEntityComponent } from "../../components/static_map_entity";
import { Vector } from "../../../core/vector";
import { Math_max, Math_min, Math_floor } from "../../../core/builtins";
import { makeOffscreenBuffer } from "../../../core/buffer_utils";
import { DrawParameters } from "../../../core/draw_parameters";
import { Rectangle } from "../../../core/rectangle";
const logger = createLogger("screenshot_exporter");
export class HUDScreenshotExporter extends BaseHUDPart {
createElements() {}
initialize() {
this.root.keyMapper.getBinding(KEYMAPPINGS.ingame.exportScreenshot).add(this.startExport, this);
}
startExport() {
if (IS_DEMO) {
this.root.hud.parts.dialogs.showFeatureRestrictionInfo(T.demo.features.exportingBase);
return;
}
const { ok } = this.root.hud.parts.dialogs.showInfo(
T.dialogs.exportScreenshotWarning.title,
T.dialogs.exportScreenshotWarning.desc,
["cancel:good", "ok:bad"]
);
ok.add(this.doExport, this);
}
doExport() {
logger.log("Starting export ...");
// Find extends
const staticEntities = this.root.entityMgr.getAllWithComponent(StaticMapEntityComponent);
const minTile = new Vector(0, 0);
const maxTile = new Vector(0, 0);
for (let i = 0; i < staticEntities.length; ++i) {
const bounds = staticEntities[i].components.StaticMapEntity.getTileSpaceBounds();
minTile.x = Math_min(minTile.x, bounds.x);
minTile.y = Math_min(minTile.y, bounds.y);
maxTile.x = Math_max(maxTile.x, bounds.x + bounds.w);
maxTile.y = Math_max(maxTile.y, bounds.y + bounds.h);
}
const minChunk = minTile.divideScalar(globalConfig.mapChunkSize).floor();
const maxChunk = maxTile.divideScalar(globalConfig.mapChunkSize).ceil();
const dimensions = maxChunk.sub(minChunk);
logger.log("Dimensions:", dimensions);
let chunkSizePixels = 128;
const maxDimensions = Math_max(dimensions.x, dimensions.y);
if (maxDimensions > 128) {
chunkSizePixels = Math_max(1, Math_floor(128 * (128 / maxDimensions)));
}
logger.log("ChunkSizePixels:", chunkSizePixels);
const chunkScale = chunkSizePixels / (globalConfig.mapChunkSize * globalConfig.tileSize);
logger.log("Scale:", chunkScale);
logger.log("Allocating buffer, if the factory grew too big it will crash here");
const [canvas, context] = makeOffscreenBuffer(
dimensions.x * chunkSizePixels,
dimensions.y * chunkSizePixels,
{
smooth: true,
reusable: false,
label: "export-buffer",
}
);
logger.log("Got buffer, rendering now ...");
const visibleRect = new Rectangle(
minChunk.x * globalConfig.mapChunkSize * globalConfig.tileSize,
minChunk.y * globalConfig.mapChunkSize * globalConfig.tileSize,
dimensions.x * globalConfig.mapChunkSize * globalConfig.tileSize,
dimensions.y * globalConfig.mapChunkSize * globalConfig.tileSize
);
const parameters = new DrawParameters({
context,
visibleRect,
desiredAtlasScale: "1",
root: this.root,
zoomLevel: chunkScale,
});
context.scale(chunkScale, chunkScale);
context.translate(-visibleRect.x, -visibleRect.y);
// Render all relevant chunks
this.root.map.drawBackground(parameters);
this.root.map.drawForeground(parameters);
// Offer export
logger.log("Rendered buffer, exporting ...");
const image = canvas.toDataURL("image/png");
const link = document.createElement("a");
link.download = "base.png";
link.href = image;
link.click();
logger.log("Done!");
}
}

View File

@ -139,7 +139,7 @@ export class HUDShop extends BaseHUDPart {
pinButton.classList.add("unpinned");
pinButton.classList.remove("pinned", "alreadyPinned");
} else {
this.root.hud.signals.shapePinRequested.dispatch(shapeDef, amount);
this.root.hud.signals.shapePinRequested.dispatch(shapeDef);
pinButton.classList.add("pinned");
pinButton.classList.remove("unpinned");
}

View File

@ -39,7 +39,7 @@ export class HUDUnlockNotification extends BaseHUDPart {
this.btnClose = document.createElement("button");
this.btnClose.classList.add("close", "styledButton");
this.btnClose.innerText = "Next level";
this.btnClose.innerText = T.ingame.levelCompleteNotification.buttonNextLevel;
dialog.appendChild(this.btnClose);
this.trackClicks(this.btnClose, this.requestClose);

View File

@ -2,6 +2,7 @@ import { BaseHUDPart } from "../base_hud_part";
import { DrawParameters } from "../../../core/draw_parameters";
import { makeDiv } from "../../../core/utils";
import { THIRDPARTY_URLS } from "../../../core/config";
import { T } from "../../../translations";
export class HUDWatermark extends BaseHUDPart {
createElements(parent) {
@ -28,15 +29,15 @@ export class HUDWatermark extends BaseHUDPart {
parameters.context.fillStyle = "#f77";
parameters.context.font = "bold " + this.root.app.getEffectiveUiScale() * 17 + "px GameFont";
// parameters.context.textAlign = "center";
parameters.context.fillText("DEMO VERSION", x, this.root.app.getEffectiveUiScale() * 27);
parameters.context.fillText(
T.demoBanners.title.toUpperCase(),
x,
this.root.app.getEffectiveUiScale() * 27
);
parameters.context.font = "bold " + this.root.app.getEffectiveUiScale() * 12 + "px GameFont";
// parameters.context.textAlign = "center";
parameters.context.fillText(
"Please consider to buy the full version!",
x,
this.root.app.getEffectiveUiScale() * 45
);
parameters.context.fillText(T.demoBanners.intro, x, this.root.app.getEffectiveUiScale() * 45);
// parameters.context.textAlign = "left";
}

View File

@ -1,5 +1,5 @@
import { makeOffscreenBuffer } from "../../../core/buffer_utils";
import { Math_max } from "../../../core/builtins";
import { Math_max, Math_PI, Math_radians } from "../../../core/builtins";
import { globalConfig, IS_DEMO } from "../../../core/config";
import { DrawParameters } from "../../../core/draw_parameters";
import { Loader } from "../../../core/loader";
@ -7,7 +7,7 @@ import { DialogWithForm } from "../../../core/modal_dialog_elements";
import { FormElementInput } from "../../../core/modal_dialog_forms";
import { Rectangle } from "../../../core/rectangle";
import { STOP_PROPAGATION } from "../../../core/signal";
import { arrayDeleteValue, lerp, makeDiv, removeAllChildren } from "../../../core/utils";
import { arrayDeleteValue, lerp, makeDiv, removeAllChildren, clamp } from "../../../core/utils";
import { Vector } from "../../../core/vector";
import { T } from "../../../translations";
import { enumMouseButton } from "../../camera";
@ -15,16 +15,28 @@ import { KEYMAPPINGS } from "../../key_action_mapper";
import { BaseHUDPart } from "../base_hud_part";
import { DynamicDomAttach } from "../dynamic_dom_attach";
import { enumNotificationType } from "./notifications";
import { ShapeDefinition } from "../../shape_definition";
/** @typedef {{
* label: string,
* label: string | null,
* center: { x: number, y: number },
* zoomLevel: number,
* deletable: boolean
* zoomLevel: number
* }} Waypoint */
/**
* Used when a shape icon is rendered instead
*/
const SHAPE_LABEL_PLACEHOLDER = " ";
const MAX_LABEL_LENGTH = 71;
export class HUDWaypoints extends BaseHUDPart {
/**
* Creates the overview of waypoints
* @param {HTMLElement} parent
*/
createElements(parent) {
// Create the helper box on the lower right when zooming out
if (this.root.app.settings.getAllSettings().offerHints) {
this.hintElement = makeDiv(
parent,
@ -42,17 +54,23 @@ export class HUDWaypoints extends BaseHUDPart {
);
}
this.waypointSprite = Loader.getSprite("sprites/misc/waypoint.png");
// Create the waypoint list on the upper right
this.waypointsListElement = makeDiv(parent, "ingame_HUD_Waypoints", [], "Waypoints");
}
/**
* Serializes the waypoints
*/
serialize() {
return {
waypoints: this.waypoints,
};
}
/**
* Deserializes the waypoints
* @param {{waypoints: Array<Waypoint>}} data
*/
deserialize(data) {
if (!data || !data.waypoints || !Array.isArray(data.waypoints)) {
return "Invalid waypoints data";
@ -61,21 +79,97 @@ export class HUDWaypoints extends BaseHUDPart {
this.rerenderWaypointList();
}
/**
* Initializes everything
*/
initialize() {
// Cache the sprite for the waypoints
this.waypointSprite = Loader.getSprite("sprites/misc/waypoint.png");
this.directionIndicatorSprite = Loader.getSprite("sprites/misc/hub_direction_indicator.png");
/** @type {Array<Waypoint>}
*/
this.waypoints = [
{
label: null,
center: { x: 0, y: 0 },
zoomLevel: 3,
},
];
// Create a buffer we can use to measure text
this.dummyBuffer = makeOffscreenBuffer(1, 1, {
reusable: false,
label: "waypoints-measure-canvas",
})[1];
// Dynamically attach/detach the lower right hint in the map overview
if (this.hintElement) {
this.domAttach = new DynamicDomAttach(this.root, this.hintElement);
}
// Catch mouse and key events
this.root.camera.downPreHandler.add(this.onMouseDown, this);
this.root.keyMapper
.getBinding(KEYMAPPINGS.navigation.createMarker)
.add(this.requestCreateMarker, this);
/**
* Stores at how much opacity the markers should be rendered on the map.
* This is interpolated over multiple frames so we have some sort of fade effect
*/
this.currentMarkerOpacity = 1;
this.currentCompassOpacity = 0;
// Create buffer which is used to indicate the hub direction
const [canvas, context] = makeOffscreenBuffer(48, 48, {
smooth: true,
reusable: false,
label: "waypoints-compass",
});
this.compassBuffer = { canvas, context };
/**
* Stores a cache from a shape short key to its canvas representation
*/
this.cachedKeyToCanvas = {};
// Initial render
this.rerenderWaypointList();
}
/**
* Re-renders the waypoint list to account for changes
*/
rerenderWaypointList() {
removeAllChildren(this.waypointsListElement);
this.cleanupClickDetectors();
for (let i = 0; i < this.waypoints.length; ++i) {
const waypoint = this.waypoints[i];
const label = this.getWaypointLabel(waypoint);
const element = makeDiv(this.waypointsListElement, null, ["waypoint"]);
element.innerText = waypoint.label;
if (waypoint.deletable) {
if (ShapeDefinition.isValidShortKey(label)) {
const canvas = this.getWaypointCanvas(waypoint);
element.appendChild(canvas);
element.classList.add("shapeIcon");
} else {
element.innerText = label;
}
if (this.isWaypointDeletable(waypoint)) {
const deleteButton = makeDiv(element, null, ["deleteButton"]);
this.trackClicks(deleteButton, () => this.deleteWaypoint(waypoint));
}
if (!waypoint.label) {
// This must be the hub label
element.classList.add("hub");
element.insertBefore(this.compassBuffer.canvas, element.childNodes[0]);
}
this.trackClicks(element, () => this.moveToWaypoint(waypoint), {
targetOnly: true,
});
@ -83,6 +177,7 @@ export class HUDWaypoints extends BaseHUDPart {
}
/**
* Moves the camera to a given waypoint
* @param {Waypoint} waypoint
*/
moveToWaypoint(waypoint) {
@ -91,6 +186,7 @@ export class HUDWaypoints extends BaseHUDPart {
}
/**
* Deletes a waypoint from the list
* @param {Waypoint} waypoint
*/
deleteWaypoint(waypoint) {
@ -98,86 +194,132 @@ export class HUDWaypoints extends BaseHUDPart {
this.rerenderWaypointList();
}
initialize() {
/** @type {Array<Waypoint>}
*/
this.waypoints = [
{
label: T.ingame.waypoints.hub,
center: { x: 0, y: 0 },
zoomLevel: 3,
deletable: false,
},
];
this.dummyBuffer = makeOffscreenBuffer(1, 1, {
reusable: false,
label: "waypoints-measure-canvas",
})[1];
this.root.camera.downPreHandler.add(this.onMouseDown, this);
if (this.hintElement) {
this.domAttach = new DynamicDomAttach(this.root, this.hintElement);
/**
* Gets the canvas for a given waypoint
* @param {Waypoint} waypoint
* @returns {HTMLCanvasElement}
*/
getWaypointCanvas(waypoint) {
const key = waypoint.label;
if (this.cachedKeyToCanvas[key]) {
return this.cachedKeyToCanvas[key];
}
this.root.keyMapper
.getBinding(KEYMAPPINGS.navigation.createMarker)
.add(this.requestCreateMarker, this);
this.currentMarkerOpacity = 1;
this.rerenderWaypointList();
assert(ShapeDefinition.isValidShortKey(key), "Invalid short key: " + key);
const definition = ShapeDefinition.fromShortKey(key);
const preRendered = definition.generateAsCanvas(48);
return (this.cachedKeyToCanvas[key] = preRendered);
}
/**
* Requests to create a marker at the current camera position. If worldPos is set,
* uses that position instead.
* @param {Vector=} worldPos Override the world pos, otherwise it is the camera position
*/
requestCreateMarker(worldPos = null) {
// Construct dialog with input field
const markerNameInput = new FormElementInput({
id: "markerName",
label: null,
placeholder: "",
validator: val => val.length > 0 && val.length < 15,
validator: val =>
val.length > 0 && (val.length < MAX_LABEL_LENGTH || ShapeDefinition.isValidShortKey(val)),
});
const dialog = new DialogWithForm({
app: this.root.app,
title: T.dialogs.createMarker.title,
desc: T.dialogs.createMarker.desc,
formElements: [markerNameInput],
});
this.root.hud.parts.dialogs.internalShowDialog(dialog);
// Compute where to create the marker
const center = worldPos || this.root.camera.center;
dialog.buttonSignals.ok.add(() => {
// Show info that you can have only N markers in the demo,
// actually show this *after* entering the name so you want the
// standalone even more (I'm evil :P)
if (IS_DEMO && this.waypoints.length > 2) {
this.root.hud.parts.dialogs.showFeatureRestrictionInfo("", T.dialogs.markerDemoLimit.desc);
return;
}
this.waypoints.push({
label: markerNameInput.getValue(),
center: { x: center.x, y: center.y },
zoomLevel: Math_max(this.root.camera.zoomLevel, globalConfig.mapChunkOverviewMinZoom + 0.05),
deletable: true,
});
this.waypoints.sort((a, b) => a.label.padStart(20, "0").localeCompare(b.label.padStart(20, "0")));
this.root.hud.signals.notification.dispatch(
T.ingame.waypoints.creationSuccessNotification,
enumNotificationType.success
);
this.rerenderWaypointList();
// Actually create the waypoint
this.addWaypoint(markerNameInput.getValue(), center);
});
}
/**
* Adds a new waypoint at the given location with the given label
* @param {string} label
* @param {Vector} position
*/
addWaypoint(label, position) {
this.waypoints.push({
label,
center: { x: position.x, y: position.y },
// Make sure the zoom is *just* a bit above the zoom level where the map overview
// starts, so you always see all buildings
zoomLevel: Math_max(this.root.camera.zoomLevel, globalConfig.mapChunkOverviewMinZoom + 0.05),
});
// Sort waypoints by name
this.waypoints.sort((a, b) => {
if (!a.label) {
return -1;
}
if (!b.label) {
return 1;
}
return this.getWaypointLabel(a)
.padEnd(MAX_LABEL_LENGTH, "0")
.localeCompare(this.getWaypointLabel(b).padEnd(MAX_LABEL_LENGTH, "0"));
});
// Show notification about creation
this.root.hud.signals.notification.dispatch(
T.ingame.waypoints.creationSuccessNotification,
enumNotificationType.success
);
// Re-render the list and thus add it
this.rerenderWaypointList();
}
/**
* Called every frame to update stuff
*/
update() {
if (this.domAttach) {
this.domAttach.update(this.root.camera.getIsMapOverlayActive());
}
}
/**
* Returns the label for a given waypoint
* @param {Waypoint} waypoint
* @returns {string}
*/
getWaypointLabel(waypoint) {
return waypoint.label || T.ingame.waypoints.hub;
}
/**
* Returns if a waypoint is deletable
* @param {Waypoint} waypoint
* @returns {boolean}
*/
isWaypointDeletable(waypoint) {
return waypoint.label !== null;
}
/**
* Finds the currently intersected waypoint on the map overview under
* the cursor.
*
* @returns {Waypoint | null}
*/
findCurrentIntersectedWaypoint() {
const mousePos = this.root.app.mousePosition;
if (!mousePos) {
@ -197,10 +339,18 @@ export class HUDWaypoints extends BaseHUDPart {
const screenPos = this.root.camera.worldToScreen(
new Vector(waypoint.center.x, waypoint.center.y)
);
let label = this.getWaypointLabel(waypoint);
// Special case for icons
if (ShapeDefinition.isValidShortKey(label)) {
label = SHAPE_LABEL_PLACEHOLDER;
}
const intersectionRect = new Rectangle(
screenPos.x - 7 * scale,
screenPos.y - 12 * scale,
15 * scale + this.dummyBuffer.measureText(waypoint.label).width,
15 * scale + this.dummyBuffer.measureText(label).width,
15 * scale
);
if (intersectionRect.containsPoint(mousePos.x, mousePos.y)) {
@ -210,7 +360,7 @@ export class HUDWaypoints extends BaseHUDPart {
}
/**
*
* Mouse-Down handler
* @param {Vector} pos
* @param {enumMouseButton} button
*/
@ -221,7 +371,7 @@ export class HUDWaypoints extends BaseHUDPart {
this.root.soundProxy.playUiClick();
this.moveToWaypoint(waypoint);
} else if (button === enumMouseButton.right) {
if (waypoint.deletable) {
if (this.isWaypointDeletable(waypoint)) {
this.root.soundProxy.playUiClick();
this.deleteWaypoint(waypoint);
} else {
@ -243,50 +393,111 @@ export class HUDWaypoints extends BaseHUDPart {
}
/**
*
* Rerenders the compass
*/
rerenderWaypointsCompass() {
const context = this.compassBuffer.context;
const dims = 48;
context.clearRect(0, 0, dims, dims);
const indicatorSize = 30;
const cameraPos = this.root.camera.center;
const distanceToHub = cameraPos.length();
const compassVisible = distanceToHub > (10 * globalConfig.tileSize) / this.root.camera.zoomLevel;
const targetCompassAlpha = compassVisible ? 1 : 0;
this.currentCompassOpacity = lerp(this.currentCompassOpacity, targetCompassAlpha, 0.08);
if (this.currentCompassOpacity > 0.01) {
context.globalAlpha = this.currentCompassOpacity;
const angle = cameraPos.angle() + Math_radians(45) + Math_PI / 2;
context.translate(dims / 2, dims / 2);
context.rotate(angle);
this.directionIndicatorSprite.drawCentered(context, 0, 0, indicatorSize);
context.rotate(-angle);
context.translate(-dims / 2, -dims / 2);
context.globalAlpha = 1;
}
const iconOpacity = 1 - this.currentCompassOpacity;
if (iconOpacity > 0.01) {
// Draw icon
context.globalAlpha = iconOpacity;
this.waypointSprite.drawCentered(context, dims / 2, dims / 2, dims * 0.7);
context.globalAlpha = 1;
}
}
/**
* Draws the waypoints on the map
* @param {DrawParameters} parameters
*/
draw(parameters) {
const desiredOpacity = this.root.camera.getIsMapOverlayActive() ? 1 : 0;
this.currentMarkerOpacity = lerp(this.currentMarkerOpacity, desiredOpacity, 0.08);
this.rerenderWaypointsCompass();
// Don't render with low opacity
if (this.currentMarkerOpacity < 0.01) {
return;
}
// Find waypoint below cursor
const selected = this.findCurrentIntersectedWaypoint();
// Determine rendering scale
const scale = (1 / this.root.camera.zoomLevel) * this.root.app.getEffectiveUiScale();
// Render all of 'em
for (let i = 0; i < this.waypoints.length; ++i) {
const waypoint = this.waypoints[i];
const pos = waypoint.center;
parameters.context.globalAlpha = this.currentMarkerOpacity * (selected === waypoint ? 1 : 0.7);
const yOffset = -5 * scale;
const originalLabel = this.getWaypointLabel(waypoint);
let renderLabel = originalLabel;
let isShapeIcon = false;
if (ShapeDefinition.isValidShortKey(originalLabel)) {
renderLabel = SHAPE_LABEL_PLACEHOLDER;
isShapeIcon = true;
}
// Render the background rectangle
parameters.context.font = "bold " + 12 * scale + "px GameFont";
parameters.context.fillStyle = "rgba(255, 255, 255, 0.7)";
parameters.context.fillRect(
pos.x - 7 * scale,
pos.y - 12 * scale,
15 * scale + this.dummyBuffer.measureText(waypoint.label).width / this.root.camera.zoomLevel,
15 * scale + this.dummyBuffer.measureText(renderLabel).width / this.root.camera.zoomLevel,
15 * scale
);
parameters.context.fillStyle = "#000";
parameters.context.textAlign = "left";
parameters.context.textBaseline = "middle";
parameters.context.fillText(waypoint.label, pos.x + 6 * scale, pos.y + 0.5 * scale + yOffset);
parameters.context.textBaseline = "alphabetic";
parameters.context.textAlign = "left";
// Render the text
if (isShapeIcon) {
const canvas = this.getWaypointCanvas(waypoint);
parameters.context.drawImage(
canvas,
pos.x + 6 * scale,
pos.y - 11.5 * scale,
14 * scale,
14 * scale
);
} else {
// Render the text
parameters.context.fillStyle = "#000";
parameters.context.textBaseline = "middle";
parameters.context.fillText(renderLabel, pos.x + 6 * scale, pos.y + 0.5 * scale + yOffset);
parameters.context.textBaseline = "alphabetic";
}
// Render the small icon on the left
this.waypointSprite.drawCentered(parameters.context, pos.x, pos.y + yOffset, 10 * scale);
}
parameters.context.globalAlpha = 1;
}
}

Some files were not shown because too many files have changed in this diff Show More