Restructure buildings
@ -1,148 +1,141 @@
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
|
|
||||||
// Globs for non-ui resources
|
// Globs for non-ui resources
|
||||||
const nonImageResourcesGlobs = ["../res/**/*.woff2", "../res/*.ico", "../res/**/*.webm"];
|
const nonImageResourcesGlobs = ["../res/**/*.woff2", "../res/*.ico", "../res/**/*.webm"];
|
||||||
|
|
||||||
// Globs for ui resources
|
// Globs for ui resources
|
||||||
const imageResourcesGlobs = ["../res/**/*.png", "../res/**/*.svg", "../res/**/*.jpg", "../res/**/*.gif"];
|
const imageResourcesGlobs = ["../res/**/*.png", "../res/**/*.svg", "../res/**/*.jpg", "../res/**/*.gif"];
|
||||||
|
|
||||||
function gulptasksImageResources($, gulp, buildFolder) {
|
function gulptasksImageResources($, gulp, buildFolder) {
|
||||||
// Lossless options
|
// Lossless options
|
||||||
const minifyImagesOptsLossless = () => [
|
const minifyImagesOptsLossless = () => [
|
||||||
$.imageminJpegtran({
|
$.imageminJpegtran({
|
||||||
progressive: true,
|
progressive: true,
|
||||||
}),
|
}),
|
||||||
$.imagemin.svgo({}),
|
$.imagemin.svgo({}),
|
||||||
$.imagemin.optipng({
|
$.imagemin.optipng({
|
||||||
optimizationLevel: 3,
|
optimizationLevel: 3,
|
||||||
}),
|
}),
|
||||||
$.imageminGifsicle({
|
$.imageminGifsicle({
|
||||||
optimizationLevel: 3,
|
optimizationLevel: 3,
|
||||||
colors: 128,
|
colors: 128,
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
// Lossy options
|
// Lossy options
|
||||||
const minifyImagesOpts = () => [
|
const minifyImagesOpts = () => [
|
||||||
$.imagemin.mozjpeg({
|
$.imagemin.mozjpeg({
|
||||||
quality: 80,
|
quality: 80,
|
||||||
maxMemory: 1024 * 1024 * 8,
|
maxMemory: 1024 * 1024 * 8,
|
||||||
}),
|
}),
|
||||||
$.imagemin.svgo({}),
|
$.imagemin.svgo({}),
|
||||||
$.imageminPngquant({
|
$.imageminPngquant({
|
||||||
speed: 1,
|
speed: 1,
|
||||||
strip: true,
|
strip: true,
|
||||||
quality: [0.65, 0.9],
|
quality: [0.65, 0.9],
|
||||||
dithering: false,
|
dithering: false,
|
||||||
verbose: false,
|
verbose: false,
|
||||||
}),
|
}),
|
||||||
$.imagemin.optipng({
|
$.imagemin.optipng({
|
||||||
optimizationLevel: 3,
|
optimizationLevel: 3,
|
||||||
}),
|
}),
|
||||||
$.imageminGifsicle({
|
$.imageminGifsicle({
|
||||||
optimizationLevel: 3,
|
optimizationLevel: 3,
|
||||||
colors: 128,
|
colors: 128,
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
// Where the resources folder are
|
// Where the resources folder are
|
||||||
const resourcesDestFolder = path.join(buildFolder, "res");
|
const resourcesDestFolder = path.join(buildFolder, "res");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if an atlas must use lossless compression
|
* Determines if an atlas must use lossless compression
|
||||||
* @param {string} fname
|
* @param {string} fname
|
||||||
*/
|
*/
|
||||||
function fileMustBeLossless(fname) {
|
function fileMustBeLossless(fname) {
|
||||||
return fname.indexOf("lossless") >= 0;
|
return fname.indexOf("lossless") >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////// ATLAS /////////////////////
|
/////////////// ATLAS /////////////////////
|
||||||
|
|
||||||
// Copies the atlas to the final destination
|
// Copies the atlas to the final destination
|
||||||
gulp.task("imgres.atlas", () => {
|
gulp.task("imgres.atlas", () => {
|
||||||
return gulp
|
return gulp.src(["../res_built/atlas/*.png"]).pipe(gulp.dest(resourcesDestFolder));
|
||||||
.src(["../res_built/atlas/*.png"])
|
});
|
||||||
.pipe($.cached("imgres.atlas"))
|
|
||||||
.pipe(gulp.dest(resourcesDestFolder));
|
// Copies the atlas to the final destination after optimizing it (lossy compression)
|
||||||
});
|
gulp.task("imgres.atlasOptimized", () => {
|
||||||
|
return gulp
|
||||||
// Copies the atlas to the final destination after optimizing it (lossy compression)
|
.src(["../res_built/atlas/*.png"])
|
||||||
gulp.task("imgres.atlasOptimized", () => {
|
.pipe(
|
||||||
return gulp
|
$.if(
|
||||||
.src(["../res_built/atlas/*.png"])
|
fname => fileMustBeLossless(fname.history[0]),
|
||||||
.pipe($.cached("imgres.atlasOptimized"))
|
$.imagemin(minifyImagesOptsLossless()),
|
||||||
.pipe(
|
$.imagemin(minifyImagesOpts())
|
||||||
$.if(
|
)
|
||||||
fname => fileMustBeLossless(fname.history[0]),
|
)
|
||||||
$.imagemin(minifyImagesOptsLossless()),
|
.pipe(gulp.dest(resourcesDestFolder));
|
||||||
$.imagemin(minifyImagesOpts())
|
});
|
||||||
)
|
|
||||||
)
|
//////////////////// RESOURCES //////////////////////
|
||||||
.pipe(gulp.dest(resourcesDestFolder));
|
|
||||||
});
|
// Copies all resources which are no ui resources
|
||||||
|
gulp.task("imgres.copyNonImageResources", () => {
|
||||||
//////////////////// RESOURCES //////////////////////
|
return gulp.src(nonImageResourcesGlobs).pipe(gulp.dest(resourcesDestFolder));
|
||||||
|
});
|
||||||
// Copies all resources which are no ui resources
|
|
||||||
gulp.task("imgres.copyNonImageResources", () => {
|
// Copies all ui resources
|
||||||
return gulp
|
gulp.task("imgres.copyImageResources", () => {
|
||||||
.src(nonImageResourcesGlobs)
|
return gulp
|
||||||
.pipe($.cached("imgres.copyNonImageResources"))
|
.src(imageResourcesGlobs)
|
||||||
.pipe(gulp.dest(resourcesDestFolder));
|
|
||||||
});
|
.pipe($.cached("imgres.copyImageResources"))
|
||||||
|
.pipe(gulp.dest(path.join(resourcesDestFolder)));
|
||||||
// Copies all ui resources
|
});
|
||||||
gulp.task("imgres.copyImageResources", () => {
|
|
||||||
return gulp
|
// Copies all ui resources and optimizes them
|
||||||
.src(imageResourcesGlobs)
|
gulp.task("imgres.copyImageResourcesOptimized", () => {
|
||||||
.pipe($.cached("copyImageResources"))
|
return gulp
|
||||||
.pipe(gulp.dest(path.join(resourcesDestFolder)));
|
.src(imageResourcesGlobs)
|
||||||
});
|
.pipe(
|
||||||
|
$.if(
|
||||||
// Copies all ui resources and optimizes them
|
fname => fileMustBeLossless(fname.history[0]),
|
||||||
gulp.task("imgres.copyImageResourcesOptimized", () => {
|
$.imagemin(minifyImagesOptsLossless()),
|
||||||
return gulp
|
$.imagemin(minifyImagesOpts())
|
||||||
.src(imageResourcesGlobs)
|
)
|
||||||
.pipe($.cached("imgres.copyImageResourcesOptimized"))
|
)
|
||||||
.pipe(
|
.pipe(gulp.dest(path.join(resourcesDestFolder)));
|
||||||
$.if(
|
});
|
||||||
fname => fileMustBeLossless(fname.history[0]),
|
|
||||||
$.imagemin(minifyImagesOptsLossless()),
|
// Copies all resources and optimizes them
|
||||||
$.imagemin(minifyImagesOpts())
|
gulp.task(
|
||||||
)
|
"imgres.allOptimized",
|
||||||
)
|
gulp.parallel(
|
||||||
.pipe(gulp.dest(path.join(resourcesDestFolder)));
|
"imgres.atlasOptimized",
|
||||||
});
|
"imgres.copyNonImageResources",
|
||||||
|
"imgres.copyImageResourcesOptimized"
|
||||||
// Copies all resources and optimizes them
|
)
|
||||||
gulp.task(
|
);
|
||||||
"imgres.allOptimized",
|
|
||||||
gulp.parallel(
|
// Cleans up unused images which are instead inline into the css
|
||||||
"imgres.atlasOptimized",
|
gulp.task("imgres.cleanupUnusedCssInlineImages", () => {
|
||||||
"imgres.copyNonImageResources",
|
return gulp
|
||||||
"imgres.copyImageResourcesOptimized"
|
.src(
|
||||||
)
|
[
|
||||||
);
|
path.join(buildFolder, "res", "ui", "**", "*.png"),
|
||||||
|
path.join(buildFolder, "res", "ui", "**", "*.jpg"),
|
||||||
// Cleans up unused images which are instead inline into the css
|
path.join(buildFolder, "res", "ui", "**", "*.svg"),
|
||||||
gulp.task("imgres.cleanupUnusedCssInlineImages", () => {
|
path.join(buildFolder, "res", "ui", "**", "*.gif"),
|
||||||
return gulp
|
],
|
||||||
.src(
|
{ read: false }
|
||||||
[
|
)
|
||||||
path.join(buildFolder, "res", "ui", "**", "*.png"),
|
.pipe($.if(fname => fname.history[0].indexOf("noinline") < 0, $.clean({ force: true })));
|
||||||
path.join(buildFolder, "res", "ui", "**", "*.jpg"),
|
});
|
||||||
path.join(buildFolder, "res", "ui", "**", "*.svg"),
|
}
|
||||||
path.join(buildFolder, "res", "ui", "**", "*.gif"),
|
|
||||||
],
|
module.exports = {
|
||||||
{ read: false }
|
nonImageResourcesGlobs,
|
||||||
)
|
imageResourcesGlobs,
|
||||||
.pipe($.if(fname => fname.history[0].indexOf("noinline") < 0, $.clean({ force: true })));
|
gulptasksImageResources,
|
||||||
});
|
};
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
nonImageResourcesGlobs,
|
|
||||||
imageResourcesGlobs,
|
|
||||||
gulptasksImageResources,
|
|
||||||
};
|
|
||||||
|
@ -18,7 +18,7 @@ function gulptasksSounds($, gulp, buildFolder) {
|
|||||||
|
|
||||||
function getFileCacheValue(file) {
|
function getFileCacheValue(file) {
|
||||||
const { _isVinyl, base, cwd, contents, history, stat, path } = file;
|
const { _isVinyl, base, cwd, contents, history, stat, path } = file;
|
||||||
const encodedContents = Buffer.from(contents).toString('base64');
|
const encodedContents = Buffer.from(contents).toString("base64");
|
||||||
return { _isVinyl, base, cwd, contents: encodedContents, history, stat, path };
|
return { _isVinyl, base, cwd, contents: encodedContents, history, stat, path };
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,7 +118,6 @@ function gulptasksSounds($, gulp, buildFolder) {
|
|||||||
return gulp
|
return gulp
|
||||||
.src(path.join(builtSoundsDir, "**", "*.mp3"))
|
.src(path.join(builtSoundsDir, "**", "*.mp3"))
|
||||||
.pipe($.plumber())
|
.pipe($.plumber())
|
||||||
.pipe($.cached("sounds.copy"))
|
|
||||||
.pipe(gulp.dest(path.join(buildFolder, "res", "sounds")));
|
.pipe(gulp.dest(path.join(buildFolder, "res", "sounds")));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
BIN
res/ui/building_icons/analyzer.png
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
res/ui/building_icons/comparator.png
Normal file
After Width: | Height: | Size: 8.0 KiB |
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 7.7 KiB |
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 5.9 KiB |
BIN
res/ui/building_icons/transistor.png
Normal file
After Width: | Height: | Size: 5.3 KiB |
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 6.3 KiB |
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 5.8 KiB |
BIN
res/ui/building_tutorials/analyzer.png
Normal file
After Width: | Height: | Size: 233 KiB |
BIN
res/ui/building_tutorials/logic_gate-and.png
Normal file
After Width: | Height: | Size: 281 KiB |
BIN
res/ui/building_tutorials/logic_gate-not.png
Normal file
After Width: | Height: | Size: 287 KiB |
BIN
res/ui/building_tutorials/logic_gate-or.png
Normal file
After Width: | Height: | Size: 283 KiB |
BIN
res/ui/building_tutorials/logic_gate-xor.png
Normal file
After Width: | Height: | Size: 286 KiB |
BIN
res/ui/building_tutorials/transistor.png
Normal file
After Width: | Height: | Size: 260 KiB |
BIN
res/ui/building_tutorials/virtual_processor-cutter.png
Normal file
After Width: | Height: | Size: 116 KiB |
BIN
res/ui/building_tutorials/virtual_processor-painter.png
Normal file
After Width: | Height: | Size: 116 KiB |
BIN
res/ui/building_tutorials/virtual_processor-rotater.png
Normal file
After Width: | Height: | Size: 106 KiB |
BIN
res/ui/building_tutorials/virtual_processor-stacker.png
Normal file
After Width: | Height: | Size: 121 KiB |
BIN
res/ui/building_tutorials/virtual_processor-unstacker.png
Normal file
After Width: | Height: | Size: 121 KiB |
BIN
res/ui/building_tutorials/wire-second.png
Normal file
After Width: | Height: | Size: 107 KiB |
BIN
res/ui/building_tutorials/wire.png
Normal file
After Width: | Height: | Size: 138 KiB |
BIN
res/ui/building_tutorials/wire_tunnel.png
Normal file
After Width: | Height: | Size: 91 KiB |
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 1.3 MiB |
Before Width: | Height: | Size: 278 KiB After Width: | Height: | Size: 279 KiB |
Before Width: | Height: | Size: 701 KiB After Width: | Height: | Size: 703 KiB |
@ -104,7 +104,7 @@
|
|||||||
</struct>
|
</struct>
|
||||||
</struct>
|
</struct>
|
||||||
<key>shapePadding</key>
|
<key>shapePadding</key>
|
||||||
<uint>0</uint>
|
<uint>2</uint>
|
||||||
<key>jpgQuality</key>
|
<key>jpgQuality</key>
|
||||||
<uint>80</uint>
|
<uint>80</uint>
|
||||||
<key>pngOptimizationLevel</key>
|
<key>pngOptimizationLevel</key>
|
||||||
@ -118,7 +118,7 @@
|
|||||||
<key>textureFormat</key>
|
<key>textureFormat</key>
|
||||||
<enum type="SettingsBase::TextureFormat">png</enum>
|
<enum type="SettingsBase::TextureFormat">png</enum>
|
||||||
<key>borderPadding</key>
|
<key>borderPadding</key>
|
||||||
<uint>1</uint>
|
<uint>3</uint>
|
||||||
<key>maxTextureSize</key>
|
<key>maxTextureSize</key>
|
||||||
<QSize>
|
<QSize>
|
||||||
<key>width</key>
|
<key>width</key>
|
||||||
@ -197,7 +197,7 @@
|
|||||||
<key>scaleMode</key>
|
<key>scaleMode</key>
|
||||||
<enum type="ScaleMode">Smooth</enum>
|
<enum type="ScaleMode">Smooth</enum>
|
||||||
<key>extrude</key>
|
<key>extrude</key>
|
||||||
<uint>3</uint>
|
<uint>2</uint>
|
||||||
<key>trimThreshold</key>
|
<key>trimThreshold</key>
|
||||||
<uint>2</uint>
|
<uint>2</uint>
|
||||||
<key>trimMargin</key>
|
<key>trimMargin</key>
|
||||||
@ -260,35 +260,6 @@
|
|||||||
<key type="filename">sprites/blueprints/balancer-merger-inverse.png</key>
|
<key type="filename">sprites/blueprints/balancer-merger-inverse.png</key>
|
||||||
<key type="filename">sprites/blueprints/balancer-merger.png</key>
|
<key type="filename">sprites/blueprints/balancer-merger.png</key>
|
||||||
<key type="filename">sprites/blueprints/balancer-splitter-inverse.png</key>
|
<key type="filename">sprites/blueprints/balancer-splitter-inverse.png</key>
|
||||||
<key type="filename">sprites/blueprints/balancer-splitter.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/constant_signal.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/display.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/lever.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/logic_gate-not.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/logic_gate-or.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/logic_gate-transistor.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/logic_gate-xor.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/logic_gate.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/miner-chainable.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/miner.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/reader.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/rotater-ccw.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/rotater-rotate180.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/rotater.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/trash.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/underground_belt_entry-tier2.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/underground_belt_entry.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/underground_belt_exit-tier2.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/underground_belt_exit.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/virtual_processor-analyzer.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/virtual_processor-painter.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/virtual_processor-rotater.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/virtual_processor-shapecompare.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/virtual_processor-stacker.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/virtual_processor-unstacker.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/virtual_processor.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/wire_tunnel-coating.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/wire_tunnel.png</key>
|
|
||||||
<key type="filename">sprites/buildings/balancer-merger-inverse.png</key>
|
<key type="filename">sprites/buildings/balancer-merger-inverse.png</key>
|
||||||
<key type="filename">sprites/buildings/balancer-merger.png</key>
|
<key type="filename">sprites/buildings/balancer-merger.png</key>
|
||||||
<key type="filename">sprites/buildings/balancer-splitter-inverse.png</key>
|
<key type="filename">sprites/buildings/balancer-splitter-inverse.png</key>
|
||||||
@ -298,13 +269,14 @@
|
|||||||
<key type="filename">sprites/buildings/lever.png</key>
|
<key type="filename">sprites/buildings/lever.png</key>
|
||||||
<key type="filename">sprites/buildings/logic_gate-not.png</key>
|
<key type="filename">sprites/buildings/logic_gate-not.png</key>
|
||||||
<key type="filename">sprites/buildings/logic_gate-or.png</key>
|
<key type="filename">sprites/buildings/logic_gate-or.png</key>
|
||||||
<key type="filename">sprites/buildings/logic_gate-transistor.png</key>
|
|
||||||
<key type="filename">sprites/buildings/logic_gate-xor.png</key>
|
<key type="filename">sprites/buildings/logic_gate-xor.png</key>
|
||||||
<key type="filename">sprites/buildings/logic_gate.png</key>
|
<key type="filename">sprites/buildings/logic_gate.png</key>
|
||||||
<key type="filename">sprites/buildings/miner-chainable.png</key>
|
<key type="filename">sprites/buildings/miner-chainable.png</key>
|
||||||
<key type="filename">sprites/buildings/reader.png</key>
|
<key type="filename">sprites/buildings/reader.png</key>
|
||||||
<key type="filename">sprites/buildings/rotater-ccw.png</key>
|
<key type="filename">sprites/buildings/rotater-ccw.png</key>
|
||||||
<key type="filename">sprites/buildings/rotater-rotate180.png</key>
|
<key type="filename">sprites/buildings/rotater-rotate180.png</key>
|
||||||
|
<key type="filename">sprites/buildings/transistor-mirrored.png</key>
|
||||||
|
<key type="filename">sprites/buildings/transistor.png</key>
|
||||||
<key type="filename">sprites/buildings/underground_belt_entry-tier2.png</key>
|
<key type="filename">sprites/buildings/underground_belt_entry-tier2.png</key>
|
||||||
<key type="filename">sprites/buildings/underground_belt_entry.png</key>
|
<key type="filename">sprites/buildings/underground_belt_entry.png</key>
|
||||||
<key type="filename">sprites/buildings/underground_belt_exit-tier2.png</key>
|
<key type="filename">sprites/buildings/underground_belt_exit-tier2.png</key>
|
||||||
@ -316,26 +288,25 @@
|
|||||||
<key type="filename">sprites/buildings/virtual_processor-stacker.png</key>
|
<key type="filename">sprites/buildings/virtual_processor-stacker.png</key>
|
||||||
<key type="filename">sprites/buildings/virtual_processor-unstacker.png</key>
|
<key type="filename">sprites/buildings/virtual_processor-unstacker.png</key>
|
||||||
<key type="filename">sprites/buildings/virtual_processor.png</key>
|
<key type="filename">sprites/buildings/virtual_processor.png</key>
|
||||||
<key type="filename">sprites/buildings/wire_tunnel-coating.png</key>
|
|
||||||
<key type="filename">sprites/buildings/wire_tunnel.png</key>
|
<key type="filename">sprites/buildings/wire_tunnel.png</key>
|
||||||
<key type="filename">sprites/misc/reader_overlay.png</key>
|
<key type="filename">sprites/misc/reader_overlay.png</key>
|
||||||
<key type="filename">sprites/wires/lever_on.png</key>
|
<key type="filename">sprites/wires/lever_on.png</key>
|
||||||
<key type="filename">sprites/wires/sets/color_cross.png</key>
|
|
||||||
<key type="filename">sprites/wires/sets/color_forward.png</key>
|
|
||||||
<key type="filename">sprites/wires/sets/color_split.png</key>
|
|
||||||
<key type="filename">sprites/wires/sets/color_turn.png</key>
|
|
||||||
<key type="filename">sprites/wires/sets/conflict_cross.png</key>
|
<key type="filename">sprites/wires/sets/conflict_cross.png</key>
|
||||||
<key type="filename">sprites/wires/sets/conflict_forward.png</key>
|
<key type="filename">sprites/wires/sets/conflict_forward.png</key>
|
||||||
<key type="filename">sprites/wires/sets/conflict_split.png</key>
|
<key type="filename">sprites/wires/sets/conflict_split.png</key>
|
||||||
<key type="filename">sprites/wires/sets/conflict_turn.png</key>
|
<key type="filename">sprites/wires/sets/conflict_turn.png</key>
|
||||||
<key type="filename">sprites/wires/sets/regular_cross.png</key>
|
<key type="filename">sprites/wires/sets/first_cross.png</key>
|
||||||
<key type="filename">sprites/wires/sets/regular_forward.png</key>
|
<key type="filename">sprites/wires/sets/first_forward.png</key>
|
||||||
<key type="filename">sprites/wires/sets/regular_split.png</key>
|
<key type="filename">sprites/wires/sets/first_split.png</key>
|
||||||
<key type="filename">sprites/wires/sets/regular_turn.png</key>
|
<key type="filename">sprites/wires/sets/first_turn.png</key>
|
||||||
<key type="filename">sprites/wires/sets/shape_cross.png</key>
|
<key type="filename">sprites/wires/sets/second_cross.png</key>
|
||||||
<key type="filename">sprites/wires/sets/shape_forward.png</key>
|
<key type="filename">sprites/wires/sets/second_forward.png</key>
|
||||||
<key type="filename">sprites/wires/sets/shape_split.png</key>
|
<key type="filename">sprites/wires/sets/second_split.png</key>
|
||||||
<key type="filename">sprites/wires/sets/shape_turn.png</key>
|
<key type="filename">sprites/wires/sets/second_turn.png</key>
|
||||||
|
<key type="filename">sprites/wires/sets/third_cross.png</key>
|
||||||
|
<key type="filename">sprites/wires/sets/third_forward.png</key>
|
||||||
|
<key type="filename">sprites/wires/sets/third_split.png</key>
|
||||||
|
<key type="filename">sprites/wires/sets/third_turn.png</key>
|
||||||
<struct type="IndividualSpriteSettings">
|
<struct type="IndividualSpriteSettings">
|
||||||
<key>pivotPoint</key>
|
<key>pivotPoint</key>
|
||||||
<point_f>0.5,0.5</point_f>
|
<point_f>0.5,0.5</point_f>
|
||||||
@ -350,13 +321,6 @@
|
|||||||
<key>scale9FromFile</key>
|
<key>scale9FromFile</key>
|
||||||
<false/>
|
<false/>
|
||||||
</struct>
|
</struct>
|
||||||
<key type="filename">sprites/blueprints/balancer.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/cutter.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/filter.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/stacker.png</key>
|
|
||||||
<key type="filename">sprites/buildings/balancer.png</key>
|
<key type="filename">sprites/buildings/balancer.png</key>
|
||||||
<key type="filename">sprites/buildings/filter.png</key>
|
<key type="filename">sprites/buildings/filter.png</key>
|
||||||
<key type="filename">sprites/buildings/painter-mirrored.png</key>
|
<key type="filename">sprites/buildings/painter-mirrored.png</key>
|
||||||
@ -374,20 +338,9 @@
|
|||||||
<key>scale9FromFile</key>
|
<key>scale9FromFile</key>
|
||||||
<false/>
|
<false/>
|
||||||
</struct>
|
</struct>
|
||||||
<key type="filename">sprites/blueprints/belt_left.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/belt_right.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/belt_top.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/wire-cross.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/wire-split.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/wire-turn.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/wire.png</key>
|
|
||||||
<key type="filename">sprites/buildings/belt_left.png</key>
|
<key type="filename">sprites/buildings/belt_left.png</key>
|
||||||
<key type="filename">sprites/buildings/belt_right.png</key>
|
<key type="filename">sprites/buildings/belt_right.png</key>
|
||||||
<key type="filename">sprites/buildings/belt_top.png</key>
|
<key type="filename">sprites/buildings/belt_top.png</key>
|
||||||
<key type="filename">sprites/buildings/wire-cross.png</key>
|
|
||||||
<key type="filename">sprites/buildings/wire-split.png</key>
|
|
||||||
<key type="filename">sprites/buildings/wire-turn.png</key>
|
|
||||||
<key type="filename">sprites/buildings/wire.png</key>
|
|
||||||
<struct type="IndividualSpriteSettings">
|
<struct type="IndividualSpriteSettings">
|
||||||
<key>pivotPoint</key>
|
<key>pivotPoint</key>
|
||||||
<point_f>0.5,0.5</point_f>
|
<point_f>0.5,0.5</point_f>
|
||||||
@ -402,8 +355,6 @@
|
|||||||
<key>scale9FromFile</key>
|
<key>scale9FromFile</key>
|
||||||
<false/>
|
<false/>
|
||||||
</struct>
|
</struct>
|
||||||
<key type="filename">sprites/blueprints/cutter-quad.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/painter-quad.png</key>
|
|
||||||
<key type="filename">sprites/buildings/cutter-quad.png</key>
|
<key type="filename">sprites/buildings/cutter-quad.png</key>
|
||||||
<key type="filename">sprites/buildings/painter-quad.png</key>
|
<key type="filename">sprites/buildings/painter-quad.png</key>
|
||||||
<struct type="IndividualSpriteSettings">
|
<struct type="IndividualSpriteSettings">
|
||||||
@ -420,24 +371,6 @@
|
|||||||
<key>scale9FromFile</key>
|
<key>scale9FromFile</key>
|
||||||
<false/>
|
<false/>
|
||||||
</struct>
|
</struct>
|
||||||
<key type="filename">sprites/blueprints/painter-double.png</key>
|
|
||||||
<key type="filename">sprites/blueprints/storage.png</key>
|
|
||||||
<key type="filename">sprites/buildings/painter-double.png</key>
|
|
||||||
<key type="filename">sprites/buildings/storage.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>96,96,192,192</rect>
|
|
||||||
<key>scale9Paddings</key>
|
|
||||||
<rect>96,96,192,192</rect>
|
|
||||||
<key>scale9FromFile</key>
|
|
||||||
<false/>
|
|
||||||
</struct>
|
|
||||||
<key type="filename">sprites/buildings/cutter.png</key>
|
<key type="filename">sprites/buildings/cutter.png</key>
|
||||||
<key type="filename">sprites/buildings/mixer.png</key>
|
<key type="filename">sprites/buildings/mixer.png</key>
|
||||||
<key type="filename">sprites/buildings/painter.png</key>
|
<key type="filename">sprites/buildings/painter.png</key>
|
||||||
@ -493,6 +426,22 @@
|
|||||||
<key>scale9FromFile</key>
|
<key>scale9FromFile</key>
|
||||||
<false/>
|
<false/>
|
||||||
</struct>
|
</struct>
|
||||||
|
<key type="filename">sprites/buildings/painter-double.png</key>
|
||||||
|
<key type="filename">sprites/buildings/storage.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>96,96,192,192</rect>
|
||||||
|
<key>scale9Paddings</key>
|
||||||
|
<rect>96,96,192,192</rect>
|
||||||
|
<key>scale9FromFile</key>
|
||||||
|
<false/>
|
||||||
|
</struct>
|
||||||
<key type="filename">sprites/colors/blue.png</key>
|
<key type="filename">sprites/colors/blue.png</key>
|
||||||
<key type="filename">sprites/colors/cyan.png</key>
|
<key type="filename">sprites/colors/cyan.png</key>
|
||||||
<key type="filename">sprites/colors/green.png</key>
|
<key type="filename">sprites/colors/green.png</key>
|
||||||
|
@ -1,226 +1,213 @@
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Run `yarn global add canvas` first
|
* Run `yarn global add canvas` first
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { createCanvas } = require("canvas");
|
const { createCanvas } = require("canvas");
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
|
|
||||||
const outputFolder = path.join(__dirname, "..", "wires", "sets");
|
const outputFolder = path.join(__dirname, "..", "wires", "sets");
|
||||||
|
|
||||||
const dimensions = 192;
|
const dimensions = 192;
|
||||||
const lineSize = 12;
|
const lineSize = 14;
|
||||||
const lowerLineSize = 20;
|
const lowerLineSize = 32;
|
||||||
|
|
||||||
function hexToRGB(h) {
|
const variants = {
|
||||||
let r = 0,
|
first: "#61ef6f",
|
||||||
g = 0,
|
second: "#f0bd65",
|
||||||
b = 0;
|
third: "#5fb2f1",
|
||||||
|
conflict: "#f74c4c",
|
||||||
// 3 digits
|
};
|
||||||
if (h.length == 4) {
|
|
||||||
r = "0x" + h[1] + h[1];
|
function hexToRGB(h) {
|
||||||
g = "0x" + h[2] + h[2];
|
let r = 0,
|
||||||
b = "0x" + h[3] + h[3];
|
g = 0,
|
||||||
|
b = 0;
|
||||||
// 6 digits
|
|
||||||
} else if (h.length == 7) {
|
// 3 digits
|
||||||
r = "0x" + h[1] + h[2];
|
if (h.length == 4) {
|
||||||
g = "0x" + h[3] + h[4];
|
r = "0x" + h[1] + h[1];
|
||||||
b = "0x" + h[5] + h[6];
|
g = "0x" + h[2] + h[2];
|
||||||
}
|
b = "0x" + h[3] + h[3];
|
||||||
|
|
||||||
return [+r, +g, +b];
|
// 6 digits
|
||||||
}
|
} else if (h.length == 7) {
|
||||||
|
r = "0x" + h[1] + h[2];
|
||||||
function RGBToHSL(r, g, b) {
|
g = "0x" + h[3] + h[4];
|
||||||
// Make r, g, and b fractions of 1
|
b = "0x" + h[5] + h[6];
|
||||||
r /= 255;
|
}
|
||||||
g /= 255;
|
|
||||||
b /= 255;
|
return [+r, +g, +b];
|
||||||
|
}
|
||||||
// Find greatest and smallest channel values
|
|
||||||
let cmin = Math.min(r, g, b),
|
function RGBToHSL(r, g, b) {
|
||||||
cmax = Math.max(r, g, b),
|
// Make r, g, and b fractions of 1
|
||||||
delta = cmax - cmin,
|
r /= 255;
|
||||||
h = 0,
|
g /= 255;
|
||||||
s = 0,
|
b /= 255;
|
||||||
l = 0;
|
|
||||||
// Calculate hue
|
// Find greatest and smallest channel values
|
||||||
// No difference
|
let cmin = Math.min(r, g, b),
|
||||||
if (delta == 0) h = 0;
|
cmax = Math.max(r, g, b),
|
||||||
// Red is max
|
delta = cmax - cmin,
|
||||||
else if (cmax == r) h = ((g - b) / delta) % 6;
|
h = 0,
|
||||||
// Green is max
|
s = 0,
|
||||||
else if (cmax == g) h = (b - r) / delta + 2;
|
l = 0;
|
||||||
// Blue is max
|
// Calculate hue
|
||||||
else h = (r - g) / delta + 4;
|
// No difference
|
||||||
|
if (delta == 0) h = 0;
|
||||||
h = Math.round(h * 60);
|
// Red is max
|
||||||
|
else if (cmax == r) h = ((g - b) / delta) % 6;
|
||||||
// Make negative hues positive behind 360°
|
// Green is max
|
||||||
if (h < 0) h += 360;
|
else if (cmax == g) h = (b - r) / delta + 2;
|
||||||
|
// Blue is max
|
||||||
// Calculate lightness
|
else h = (r - g) / delta + 4;
|
||||||
l = (cmax + cmin) / 2;
|
|
||||||
|
h = Math.round(h * 60);
|
||||||
// Calculate saturation
|
|
||||||
s = delta == 0 ? 0 : delta / (1 - Math.abs(2 * l - 1));
|
// Make negative hues positive behind 360°
|
||||||
|
if (h < 0) h += 360;
|
||||||
// Multiply l and s by 100
|
|
||||||
s = +(s * 100).toFixed(1);
|
// Calculate lightness
|
||||||
l = +(l * 100).toFixed(1);
|
l = (cmax + cmin) / 2;
|
||||||
|
|
||||||
return [h, s, l];
|
// Calculate saturation
|
||||||
}
|
s = delta == 0 ? 0 : delta / (1 - Math.abs(2 * l - 1));
|
||||||
|
|
||||||
function HSLToRGB(h, s, l) {
|
// Multiply l and s by 100
|
||||||
// Must be fractions of 1
|
s = +(s * 100).toFixed(1);
|
||||||
s /= 100;
|
l = +(l * 100).toFixed(1);
|
||||||
l /= 100;
|
|
||||||
|
return [h, s, l];
|
||||||
let c = (1 - Math.abs(2 * l - 1)) * s,
|
}
|
||||||
x = c * (1 - Math.abs(((h / 60) % 2) - 1)),
|
|
||||||
m = l - c / 2,
|
function HSLToRGB(h, s, l) {
|
||||||
r = 0,
|
// Must be fractions of 1
|
||||||
g = 0,
|
s /= 100;
|
||||||
b = 0;
|
l /= 100;
|
||||||
|
|
||||||
if (0 <= h && h < 60) {
|
let c = (1 - Math.abs(2 * l - 1)) * s,
|
||||||
r = c;
|
x = c * (1 - Math.abs(((h / 60) % 2) - 1)),
|
||||||
g = x;
|
m = l - c / 2,
|
||||||
b = 0;
|
r = 0,
|
||||||
} else if (60 <= h && h < 120) {
|
g = 0,
|
||||||
r = x;
|
b = 0;
|
||||||
g = c;
|
|
||||||
b = 0;
|
if (0 <= h && h < 60) {
|
||||||
} else if (120 <= h && h < 180) {
|
r = c;
|
||||||
r = 0;
|
g = x;
|
||||||
g = c;
|
b = 0;
|
||||||
b = x;
|
} else if (60 <= h && h < 120) {
|
||||||
} else if (180 <= h && h < 240) {
|
r = x;
|
||||||
r = 0;
|
g = c;
|
||||||
g = x;
|
b = 0;
|
||||||
b = c;
|
} else if (120 <= h && h < 180) {
|
||||||
} else if (240 <= h && h < 300) {
|
r = 0;
|
||||||
r = x;
|
g = c;
|
||||||
g = 0;
|
b = x;
|
||||||
b = c;
|
} else if (180 <= h && h < 240) {
|
||||||
} else if (300 <= h && h < 360) {
|
r = 0;
|
||||||
r = c;
|
g = x;
|
||||||
g = 0;
|
b = c;
|
||||||
b = x;
|
} else if (240 <= h && h < 300) {
|
||||||
}
|
r = x;
|
||||||
r = Math.round((r + m) * 255);
|
g = 0;
|
||||||
g = Math.round((g + m) * 255);
|
b = c;
|
||||||
b = Math.round((b + m) * 255);
|
} else if (300 <= h && h < 360) {
|
||||||
|
r = c;
|
||||||
return [r, g, b];
|
g = 0;
|
||||||
}
|
b = x;
|
||||||
|
}
|
||||||
async function run() {
|
r = Math.round((r + m) * 255);
|
||||||
console.log("Running");
|
g = Math.round((g + m) * 255);
|
||||||
|
b = Math.round((b + m) * 255);
|
||||||
const variants = {
|
|
||||||
regular: "#25fff2",
|
return [r, g, b];
|
||||||
color: "#eba458",
|
}
|
||||||
shape: "#8858eb",
|
|
||||||
conflict: "#ff3e3e",
|
async function run() {
|
||||||
};
|
console.log("Running");
|
||||||
|
|
||||||
const promises = [];
|
const promises = [];
|
||||||
|
|
||||||
for (const variantId in variants) {
|
for (const variantId in variants) {
|
||||||
const variantColor = variants[variantId];
|
const variantColor = variants[variantId];
|
||||||
const variantHSL = RGBToHSL(...hexToRGB(variantColor));
|
const variantHSL = RGBToHSL(...hexToRGB(variantColor));
|
||||||
const darkenedColor = HSLToRGB(variantHSL[0], variantHSL[1] - 15, variantHSL[2] - 20);
|
const darkenedColor = HSLToRGB(variantHSL[0], variantHSL[1] - 15, variantHSL[2] - 20);
|
||||||
const hexDarkenedColor = "rgb(" + darkenedColor.join(",") + ")";
|
const hexDarkenedColor = "rgb(" + darkenedColor.join(",") + ")";
|
||||||
|
|
||||||
console.log(variantColor, "->", hexToRGB(variantColor), variantHSL, "->", darkenedColor);
|
console.log(variantColor, "->", hexToRGB(variantColor), variantHSL, "->", darkenedColor);
|
||||||
|
|
||||||
const parts = {
|
const parts = {
|
||||||
forward: [[0.5, 0, 0.5, 1]],
|
forward: [[0.5, 0, 0.5, 1]],
|
||||||
turn: [
|
turn: [
|
||||||
[0.5, 0.5, 0.5, 1],
|
[0.5, 0.5, 0.5, 1],
|
||||||
[0.5, 0.5, 1, 0.5],
|
[0.5, 0.5, 1, 0.5],
|
||||||
],
|
],
|
||||||
split: [
|
split: [
|
||||||
[0.5, 0.5, 0.5, 1],
|
[0.5, 0.5, 0.5, 1],
|
||||||
[0, 0.5, 1, 0.5],
|
[0, 0.5, 1, 0.5],
|
||||||
],
|
],
|
||||||
cross: [
|
cross: [
|
||||||
[0, 0.5, 1, 0.5],
|
[0, 0.5, 1, 0.5],
|
||||||
[0.5, 0, 0.5, 1],
|
[0.5, 0, 0.5, 1],
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const partId in parts) {
|
for (const partId in parts) {
|
||||||
const partLines = parts[partId];
|
const partLines = parts[partId];
|
||||||
|
|
||||||
const canvas = createCanvas(dimensions, dimensions);
|
const canvas = createCanvas(dimensions, dimensions);
|
||||||
const context = canvas.getContext("2d");
|
const context = canvas.getContext("2d");
|
||||||
context.quality = "best";
|
context.quality = "best";
|
||||||
context.clearRect(0, 0, dimensions, dimensions);
|
context.clearRect(0, 0, dimensions, dimensions);
|
||||||
|
|
||||||
context.strokeStyle = hexDarkenedColor;
|
const lineCanvas = createCanvas(dimensions, dimensions);
|
||||||
context.lineWidth = lowerLineSize;
|
const lineContext = lineCanvas.getContext("2d");
|
||||||
context.lineCap = "square";
|
lineContext.quality = "best";
|
||||||
context.imageSmoothingEnabled = false;
|
lineContext.clearRect(0, 0, dimensions, dimensions);
|
||||||
|
lineContext.strokeStyle = hexDarkenedColor;
|
||||||
// Draw lower lines
|
lineContext.lineWidth = lowerLineSize;
|
||||||
partLines.forEach(([x1, y1, x2, y2]) => {
|
lineContext.lineCap = "square";
|
||||||
context.beginPath();
|
lineContext.imageSmoothingEnabled = false;
|
||||||
context.moveTo(x1 * dimensions, y1 * dimensions);
|
|
||||||
context.lineTo(x2 * dimensions, y2 * dimensions);
|
// Draw lower lines
|
||||||
context.stroke();
|
partLines.forEach(([x1, y1, x2, y2]) => {
|
||||||
});
|
lineContext.beginPath();
|
||||||
|
lineContext.moveTo(x1 * dimensions, y1 * dimensions);
|
||||||
context.strokeStyle = variantColor;
|
lineContext.lineTo(x2 * dimensions, y2 * dimensions);
|
||||||
context.lineWidth = lineSize;
|
lineContext.stroke();
|
||||||
|
});
|
||||||
// Draw upper lines
|
|
||||||
partLines.forEach(([x1, y1, x2, y2]) => {
|
context.globalAlpha = 0.4;
|
||||||
context.beginPath();
|
context.drawImage(lineCanvas, 0, 0, dimensions, dimensions);
|
||||||
context.moveTo(x1 * dimensions, y1 * dimensions);
|
|
||||||
context.lineTo(x2 * dimensions, y2 * dimensions);
|
context.globalAlpha = 1;
|
||||||
context.stroke();
|
context.imageSmoothingEnabled = false;
|
||||||
});
|
context.lineCap = "square";
|
||||||
|
context.strokeStyle = variantColor;
|
||||||
const out = fs.createWriteStream(path.join(outputFolder, variantId + "_" + partId + ".png"));
|
context.lineWidth = lineSize;
|
||||||
const stream = canvas.createPNGStream();
|
|
||||||
stream.pipe(out);
|
// Draw upper lines
|
||||||
promises.push(new Promise(resolve => stream.on("end", resolve)));
|
partLines.forEach(([x1, y1, x2, y2]) => {
|
||||||
}
|
context.beginPath();
|
||||||
}
|
context.moveTo(x1 * dimensions, y1 * dimensions);
|
||||||
|
context.lineTo(x2 * dimensions, y2 * dimensions);
|
||||||
console.log("Waiting for completion");
|
context.stroke();
|
||||||
await Promise.all(promises);
|
});
|
||||||
|
|
||||||
// Also wait a bit more
|
const out = fs.createWriteStream(path.join(outputFolder, variantId + "_" + partId + ".png"));
|
||||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
const stream = canvas.createPNGStream();
|
||||||
|
stream.pipe(out);
|
||||||
console.log("Copying files to all locations");
|
promises.push(new Promise(resolve => stream.on("end", resolve)));
|
||||||
|
}
|
||||||
// // Copy other files
|
}
|
||||||
fs.copyFileSync(
|
|
||||||
path.join(outputFolder, "regular_forward.png"),
|
console.log("Waiting for completion");
|
||||||
path.join(__dirname, "..", "buildings", "wire.png")
|
await Promise.all(promises);
|
||||||
);
|
|
||||||
fs.copyFileSync(
|
console.log("Done!");
|
||||||
path.join(outputFolder, "regular_turn.png"),
|
}
|
||||||
path.join(__dirname, "..", "buildings", "wire-turn.png")
|
|
||||||
);
|
run();
|
||||||
fs.copyFileSync(
|
|
||||||
path.join(outputFolder, "regular_split.png"),
|
|
||||||
path.join(__dirname, "..", "buildings", "wire-split.png")
|
|
||||||
);
|
|
||||||
fs.copyFileSync(
|
|
||||||
path.join(outputFolder, "regular_cross.png"),
|
|
||||||
path.join(__dirname, "..", "buildings", "wire-cross.png")
|
|
||||||
);
|
|
||||||
|
|
||||||
console.log("Done!");
|
|
||||||
}
|
|
||||||
|
|
||||||
run();
|
|
||||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.3 KiB |
BIN
res_raw/sprites/blueprints/transistor-mirrored.png
Normal file
After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 7.4 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 957 B |
Before Width: | Height: | Size: 854 B |
Before Width: | Height: | Size: 676 B |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 9.5 KiB After Width: | Height: | Size: 9.5 KiB |
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 7.6 KiB |
BIN
res_raw/sprites/buildings/transistor-mirrored.png
Normal file
After Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 7.1 KiB |
Before Width: | Height: | Size: 695 B |
Before Width: | Height: | Size: 503 B |
Before Width: | Height: | Size: 498 B |
Before Width: | Height: | Size: 646 B |
Before Width: | Height: | Size: 4.5 KiB |
@ -1,110 +1,92 @@
|
|||||||
# Requirements: numpy, scipy, Pillow,
|
# Requirements: numpy, scipy, Pillow,
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
import sys
|
import sys
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from scipy import ndimage
|
from scipy import ndimage
|
||||||
from PIL import Image, ImageFilter, ImageChops
|
from PIL import Image, ImageFilter, ImageChops
|
||||||
import math
|
import math
|
||||||
from os import listdir
|
from os import listdir
|
||||||
from os.path import isdir, isfile
|
from os.path import isdir, isfile
|
||||||
|
|
||||||
roberts_cross_v = np.array([[0, 0, 0],
|
generate_blueprint_sprite_v = np.array([[0, 0, 0],
|
||||||
[0, 1, 0],
|
[0, 1, 0],
|
||||||
[0, 0, -1]])
|
[0, 0, -1]])
|
||||||
|
|
||||||
roberts_cross_h = np.array([[0, 0, 0],
|
generate_blueprint_sprite_h = np.array([[0, 0, 0],
|
||||||
[0, 0, 1],
|
[0, 0, 1],
|
||||||
[0, -1, 0]])
|
[0, -1, 0]])
|
||||||
|
|
||||||
|
|
||||||
def rgb2gray(rgb):
|
def rgb2gray(rgb):
|
||||||
return np.dot(rgb[..., :3], [0.2989, 0.5870, 0.1140])
|
return np.dot(rgb[..., :3], [0.2989, 0.5870, 0.1140])
|
||||||
|
|
||||||
|
def process_image(data, outfilename, src_image):
|
||||||
|
img = Image.fromarray(np.asarray(
|
||||||
|
np.clip(data, 0, 255), dtype="uint8"), "L")
|
||||||
def save_image(data, outfilename, src_image):
|
dest = Image.new("RGBA", (img.width, img.height))
|
||||||
img = Image.fromarray(np.asarray(
|
src = img.load()
|
||||||
np.clip(data, 0, 255), dtype="uint8"), "L")
|
dst = dest.load()
|
||||||
dest = Image.new("RGBA", (img.width, img.height))
|
|
||||||
src = img.load()
|
realSrc = src_image.load()
|
||||||
dst = dest.load()
|
mask = src_image.filter(ImageFilter.GaussianBlur(10)).load()
|
||||||
|
orig = src_image.load()
|
||||||
realSrc = src_image.load()
|
|
||||||
mask = src_image.filter(ImageFilter.GaussianBlur(10)).load()
|
# isWire = "wire" in outfilename
|
||||||
orig = src_image.load()
|
isWire = False
|
||||||
|
|
||||||
|
targetR = 104
|
||||||
isWire = "wire" in outfilename
|
targetG = 200
|
||||||
|
targetB = 255
|
||||||
targetR = 104
|
|
||||||
targetG = 200
|
if isWire:
|
||||||
targetB = 255
|
targetR = 255
|
||||||
|
targetG = 104
|
||||||
if isWire:
|
targetB = 232
|
||||||
targetR = 255
|
|
||||||
targetG = 104
|
for x in range(img.width):
|
||||||
targetB = 232
|
for y in range(img.height):
|
||||||
|
realpixl = realSrc[x, y]
|
||||||
for x in range(img.width):
|
greyval = float(src[x, y])
|
||||||
for y in range(img.height):
|
greyval = min(255.0, greyval)
|
||||||
realpixl = realSrc[x, y]
|
greyval = math.pow(
|
||||||
greyval = float(src[x, y])
|
min(1, float(greyval / 255.0 * 1)), 1.5) * 255.0 * 1
|
||||||
greyval = min(255.0, greyval)
|
greyval = max(0, greyval)
|
||||||
greyval = math.pow(
|
alpha = mask[x, y][3] / 255.0 * 1
|
||||||
min(1, float(greyval / 255.0 * 1)), 1.5) * 255.0 * 1
|
|
||||||
greyval = max(0, greyval)
|
edgeFactor = src[x, y] / 255.0
|
||||||
alpha = mask[x, y][3] / 255.0 * 1
|
noEdge = 1 - edgeFactor
|
||||||
|
|
||||||
edgeFactor = src[x, y] / 255.0
|
shadow = min(1, 1 - realpixl[3] / 255.0 - edgeFactor)
|
||||||
noEdge = 1 - edgeFactor
|
noShadow = 1 - shadow
|
||||||
|
|
||||||
shadow = min(1, 1 - realpixl[3] / 255.0 - edgeFactor)
|
dst[x, y] = (
|
||||||
noShadow = 1 - shadow
|
min(255, int((realpixl[0] / 255.0 * 0.4 + 0.6) * targetR * 1.1)),
|
||||||
|
min(255, int((realpixl[1] / 255.0 * 0.4 + 0.6) * targetG * 1.1)),
|
||||||
dst[x, y] = (
|
min(255, int((realpixl[2] / 255.0 * 0.4 + 0.6) * targetB * 1.1)),
|
||||||
min(255, int((realpixl[0] / 255.0 * 0.4 + 0.6) * targetR * 1.1)),
|
min(255, int(float(realpixl[3]) * (0.6 + 5 * edgeFactor))))
|
||||||
min(255, int((realpixl[1] / 255.0 * 0.4 + 0.6) * targetG * 1.1)),
|
|
||||||
min(255, int((realpixl[2] / 255.0 * 0.4 + 0.6) * targetB * 1.1)),
|
|
||||||
min(255, int(float(realpixl[3]) * (0.6 + 5 * edgeFactor))))
|
dest.save(outfilename)
|
||||||
|
|
||||||
|
|
||||||
dest.save(outfilename)
|
def generate_blueprint_sprite(infilename, outfilename):
|
||||||
|
print("Processing", infilename)
|
||||||
|
img = Image.open(infilename)
|
||||||
def roberts_cross(infilename, outfilename):
|
img.load()
|
||||||
print("Processing", infilename)
|
img = img.filter(ImageFilter.GaussianBlur(0.5))
|
||||||
img = Image.open(infilename)
|
|
||||||
img.load()
|
image = rgb2gray(np.asarray(img, dtype="int32"))
|
||||||
img = img.filter(ImageFilter.GaussianBlur(0.5))
|
vertical = ndimage.convolve(image, generate_blueprint_sprite_v)
|
||||||
|
horizontal = ndimage.convolve(image, generate_blueprint_sprite_h)
|
||||||
image = rgb2gray(np.asarray(img, dtype="int32"))
|
output_image = np.sqrt(np.square(horizontal) + np.square(vertical))
|
||||||
vertical = ndimage.convolve(image, roberts_cross_v)
|
process_image(output_image, outfilename, img)
|
||||||
horizontal = ndimage.convolve(image, roberts_cross_h)
|
|
||||||
output_image = np.sqrt(np.square(horizontal) + np.square(vertical))
|
|
||||||
save_image(output_image, outfilename, img)
|
buildings = listdir("buildings")
|
||||||
|
|
||||||
|
for buildingId in buildings:
|
||||||
def generateUiPreview(srcPath, buildingId):
|
if "hub" in buildingId:
|
||||||
print(srcPath, buildingId)
|
continue
|
||||||
img = Image.open(srcPath)
|
if "wire-" in buildingId:
|
||||||
img.load()
|
continue
|
||||||
img.thumbnail((110, 110), Image.ANTIALIAS)
|
generate_blueprint_sprite("buildings/" + buildingId + "", "blueprints/" + buildingId + "")
|
||||||
img.save("../res/ui/hud/building_previews/" + buildingId + ".png")
|
|
||||||
|
|
||||||
img = img.convert("LA")
|
|
||||||
|
|
||||||
data = img.load()
|
|
||||||
for x in range(img.width):
|
|
||||||
for y in range(img.height):
|
|
||||||
data[x, y] = (data[x, y][0], int(data[x, y][1] * 0.5))
|
|
||||||
|
|
||||||
img.save("../res/ui/hud/building_previews/" + buildingId + "_disabled.png")
|
|
||||||
|
|
||||||
|
|
||||||
buildings = listdir("buildings")
|
|
||||||
|
|
||||||
for buildingId in buildings:
|
|
||||||
if "hub" in buildingId:
|
|
||||||
continue
|
|
||||||
roberts_cross("buildings/" + buildingId + "", "blueprints/" + buildingId + "")
|
|
||||||
|
Before Width: | Height: | Size: 701 B |
Before Width: | Height: | Size: 649 B |
Before Width: | Height: | Size: 502 B |
Before Width: | Height: | Size: 501 B |
Before Width: | Height: | Size: 690 B After Width: | Height: | Size: 703 B |
Before Width: | Height: | Size: 642 B After Width: | Height: | Size: 647 B |
Before Width: | Height: | Size: 501 B After Width: | Height: | Size: 520 B |
Before Width: | Height: | Size: 496 B After Width: | Height: | Size: 513 B |
BIN
res_raw/sprites/wires/sets/first_cross.png
Normal file
After Width: | Height: | Size: 707 B |
BIN
res_raw/sprites/wires/sets/first_forward.png
Normal file
After Width: | Height: | Size: 649 B |
BIN
res_raw/sprites/wires/sets/first_split.png
Normal file
After Width: | Height: | Size: 526 B |
BIN
res_raw/sprites/wires/sets/first_turn.png
Normal file
After Width: | Height: | Size: 513 B |
Before Width: | Height: | Size: 695 B |
Before Width: | Height: | Size: 646 B |
Before Width: | Height: | Size: 503 B |
Before Width: | Height: | Size: 498 B |
BIN
res_raw/sprites/wires/sets/second_cross.png
Normal file
After Width: | Height: | Size: 705 B |
Before Width: | Height: | Size: 648 B After Width: | Height: | Size: 651 B |
BIN
res_raw/sprites/wires/sets/second_split.png
Normal file
After Width: | Height: | Size: 525 B |
BIN
res_raw/sprites/wires/sets/second_turn.png
Normal file
After Width: | Height: | Size: 516 B |
Before Width: | Height: | Size: 699 B |
Before Width: | Height: | Size: 501 B |
Before Width: | Height: | Size: 500 B |
BIN
res_raw/sprites/wires/sets/third_cross.png
Normal file
After Width: | Height: | Size: 706 B |
BIN
res_raw/sprites/wires/sets/third_forward.png
Normal file
After Width: | Height: | Size: 651 B |
BIN
res_raw/sprites/wires/sets/third_split.png
Normal file
After Width: | Height: | Size: 527 B |
BIN
res_raw/sprites/wires/sets/third_turn.png
Normal file
After Width: | Height: | Size: 515 B |
@ -1,5 +1,6 @@
|
|||||||
$buildings: belt, cutter, miner, mixer, painter, rotater, balancer, stacker, trash, underground_belt, wire,
|
$buildings: belt, cutter, miner, mixer, painter, rotater, balancer, stacker, trash, underground_belt, wire,
|
||||||
constant_signal, logic_gate, lever, filter, wire_tunnel, display, virtual_processor, reader, storage;
|
constant_signal, logic_gate, lever, filter, wire_tunnel, display, virtual_processor, reader, storage,
|
||||||
|
transistor, analyzer, comparator;
|
||||||
|
|
||||||
@each $building in $buildings {
|
@each $building in $buildings {
|
||||||
[data-icon="building_icons/#{$building}.png"] {
|
[data-icon="building_icons/#{$building}.png"] {
|
||||||
@ -8,10 +9,11 @@ $buildings: belt, cutter, miner, mixer, painter, rotater, balancer, stacker, tra
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$buildingsAndVariants: belt, balancer, balancer-merger, balancer-splitter, underground_belt,
|
$buildingsAndVariants: belt, balancer, underground_belt, underground_belt-tier2, miner, miner-chainable,
|
||||||
underground_belt-tier2, miner, miner-chainable, cutter, cutter-quad, rotater, rotater-ccw, stacker, mixer,
|
cutter, cutter-quad, rotater, rotater-ccw, stacker, mixer, painter-double, painter-quad, trash, storage,
|
||||||
painter, painter-double, painter-quad, trash, storage, reader, rotater-rotate180, lever, display,
|
reader, rotater-rotate180, display, constant_signal, wire, wire_tunnel, logic_gate-or, logic_gate-not,
|
||||||
constant_signal;
|
logic_gate-xor, analyzer, virtual_processor-rotater, virtual_processor-unstacker,
|
||||||
|
virtual_processor-stacker, virtual_processor-painter;
|
||||||
@each $building in $buildingsAndVariants {
|
@each $building in $buildingsAndVariants {
|
||||||
[data-icon="building_tutorials/#{$building}.png"] {
|
[data-icon="building_tutorials/#{$building}.png"] {
|
||||||
/* @load-async */
|
/* @load-async */
|
||||||
@ -19,26 +21,57 @@ $buildingsAndVariants: belt, balancer, balancer-merger, balancer-splitter, under
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// @TODO: New buildings (balancer, wires, etc)
|
|
||||||
|
|
||||||
// Special cases for mirrored vairants
|
// Special cases for mirrored vairants
|
||||||
|
[data-icon="building_tutorials/painter.png"],
|
||||||
[data-icon="building_tutorials/painter-mirrored.png"] {
|
[data-icon="building_tutorials/painter-mirrored.png"] {
|
||||||
/* @load-async */
|
/* @load-async */
|
||||||
background-image: uiResource("res/ui/building_tutorials/painter.png") !important;
|
background-image: uiResource("res/ui/building_tutorials/painter.png") !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[data-icon="building_tutorials/balancer-merger.png"],
|
||||||
[data-icon="building_tutorials/balancer-merger-inverse.png"] {
|
[data-icon="building_tutorials/balancer-merger-inverse.png"] {
|
||||||
/* @load-async */
|
/* @load-async */
|
||||||
background-image: uiResource("res/ui/building_tutorials/balancer-merger.png") !important;
|
background-image: uiResource("res/ui/building_tutorials/balancer-merger.png") !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[data-icon="building_tutorials/balancer-splitter.png"],
|
||||||
[data-icon="building_tutorials/balancer-splitter-inverse.png"] {
|
[data-icon="building_tutorials/balancer-splitter-inverse.png"] {
|
||||||
/* @load-async */
|
/* @load-async */
|
||||||
background-image: uiResource("res/ui/building_tutorials/balancer-splitter.png") !important;
|
background-image: uiResource("res/ui/building_tutorials/balancer-splitter.png") !important;
|
||||||
}
|
}
|
||||||
[data-icon="building_tutorials/filter.png"] {
|
|
||||||
|
[data-icon="building_tutorials/transistor.png"],
|
||||||
|
[data-icon="building_tutorials/transistor-mirrored.png"] {
|
||||||
|
/* @load-async */
|
||||||
|
background-image: uiResource("res/ui/building_tutorials/transistor.png") !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter and lever share tutorials
|
||||||
|
[data-icon="building_tutorials/filter.png"],
|
||||||
|
[data-icon="building_tutorials/lever.png"] {
|
||||||
/* @load-async */
|
/* @load-async */
|
||||||
background-image: uiResource("res/ui/building_tutorials/lever.png") !important;
|
background-image: uiResource("res/ui/building_tutorials/lever.png") !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wire types share tutorials
|
||||||
|
[data-icon="building_tutorials/wire-second.png"],
|
||||||
|
[data-icon="building_tutorials/wire-third.png"] {
|
||||||
|
/* @load-async */
|
||||||
|
background-image: uiResource("res/ui/building_tutorials/wire-second.png") !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Logic gate
|
||||||
|
[data-icon="building_tutorials/logic_gate.png"] {
|
||||||
|
/* @load-async */
|
||||||
|
background-image: uiResource("res/ui/building_tutorials/logic_gate-and.png") !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Virtual processor
|
||||||
|
[data-icon="building_tutorials/virtual_processor.png"] {
|
||||||
|
/* @load-async */
|
||||||
|
background-image: uiResource("res/ui/building_tutorials/virtual_processor-cutter.png") !important;
|
||||||
|
}
|
||||||
|
|
||||||
$icons: notification_saved, notification_success, notification_upgrade;
|
$icons: notification_saved, notification_success, notification_upgrade;
|
||||||
@each $icon in $icons {
|
@each $icon in $icons {
|
||||||
[data-icon="icons/#{$icon}.png"] {
|
[data-icon="icons/#{$icon}.png"] {
|
||||||
|
79
src/js/game/buildings/analyzer.js
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
import { generateMatrixRotations } from "../../core/utils";
|
||||||
|
import { enumDirection, Vector } from "../../core/vector";
|
||||||
|
import { enumLogicGateType, LogicGateComponent } from "../components/logic_gate";
|
||||||
|
import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
|
||||||
|
import { Entity } from "../entity";
|
||||||
|
import { MetaBuilding } from "../meta_building";
|
||||||
|
import { GameRoot } from "../root";
|
||||||
|
|
||||||
|
const overlayMatrix = generateMatrixRotations([1, 1, 0, 1, 1, 1, 0, 1, 0]);
|
||||||
|
|
||||||
|
export class MetaAnalyzerBuilding extends MetaBuilding {
|
||||||
|
constructor() {
|
||||||
|
super("analyzer");
|
||||||
|
}
|
||||||
|
|
||||||
|
getSilhouetteColor() {
|
||||||
|
return "#3a52bc";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {GameRoot} root
|
||||||
|
*/
|
||||||
|
getIsUnlocked(root) {
|
||||||
|
// @todo
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @returns {"wires"} **/
|
||||||
|
getLayer() {
|
||||||
|
return "wires";
|
||||||
|
}
|
||||||
|
|
||||||
|
getDimensions() {
|
||||||
|
return new Vector(1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
getRenderPins() {
|
||||||
|
// We already have it included
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant) {
|
||||||
|
return overlayMatrix[rotation];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the entity at the given location
|
||||||
|
* @param {Entity} entity
|
||||||
|
*/
|
||||||
|
setupEntityComponents(entity) {
|
||||||
|
entity.addComponent(
|
||||||
|
new WiredPinsComponent({
|
||||||
|
slots: [
|
||||||
|
{
|
||||||
|
pos: new Vector(0, 0),
|
||||||
|
direction: enumDirection.left,
|
||||||
|
type: enumPinSlotType.logicalEjector,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: new Vector(0, 0),
|
||||||
|
direction: enumDirection.right,
|
||||||
|
type: enumPinSlotType.logicalEjector,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: new Vector(0, 0),
|
||||||
|
direction: enumDirection.bottom,
|
||||||
|
type: enumPinSlotType.logicalAcceptor,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
entity.addComponent(
|
||||||
|
new LogicGateComponent({
|
||||||
|
type: enumLogicGateType.analyzer,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
72
src/js/game/buildings/comparator.js
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
import { enumDirection, Vector } from "../../core/vector";
|
||||||
|
import { enumLogicGateType, LogicGateComponent } from "../components/logic_gate";
|
||||||
|
import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
|
||||||
|
import { Entity } from "../entity";
|
||||||
|
import { MetaBuilding } from "../meta_building";
|
||||||
|
import { GameRoot } from "../root";
|
||||||
|
|
||||||
|
export class MetaComparatorBuilding extends MetaBuilding {
|
||||||
|
constructor() {
|
||||||
|
super("comparator");
|
||||||
|
}
|
||||||
|
|
||||||
|
getSilhouetteColor() {
|
||||||
|
return "#823cab";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {GameRoot} root
|
||||||
|
*/
|
||||||
|
getIsUnlocked(root) {
|
||||||
|
// @todo
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @returns {"wires"} **/
|
||||||
|
getLayer() {
|
||||||
|
return "wires";
|
||||||
|
}
|
||||||
|
|
||||||
|
getDimensions() {
|
||||||
|
return new Vector(1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
getRenderPins() {
|
||||||
|
// We already have it included
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the entity at the given location
|
||||||
|
* @param {Entity} entity
|
||||||
|
*/
|
||||||
|
setupEntityComponents(entity) {
|
||||||
|
entity.addComponent(
|
||||||
|
new WiredPinsComponent({
|
||||||
|
slots: [
|
||||||
|
{
|
||||||
|
pos: new Vector(0, 0),
|
||||||
|
direction: enumDirection.top,
|
||||||
|
type: enumPinSlotType.logicalEjector,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: new Vector(0, 0),
|
||||||
|
direction: enumDirection.left,
|
||||||
|
type: enumPinSlotType.logicalAcceptor,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: new Vector(0, 0),
|
||||||
|
direction: enumDirection.right,
|
||||||
|
type: enumPinSlotType.logicalAcceptor,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
entity.addComponent(
|
||||||
|
new LogicGateComponent({
|
||||||
|
type: enumLogicGateType.compare,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,9 @@ import { Entity } from "../entity";
|
|||||||
import { MetaBuilding } from "../meta_building";
|
import { MetaBuilding } from "../meta_building";
|
||||||
import { GameRoot } from "../root";
|
import { GameRoot } from "../root";
|
||||||
import { ConstantSignalComponent } from "../components/constant_signal";
|
import { ConstantSignalComponent } from "../components/constant_signal";
|
||||||
|
import { generateMatrixRotations } from "../../core/utils";
|
||||||
|
|
||||||
|
const overlayMatrix = generateMatrixRotations([0, 1, 0, 1, 1, 1, 1, 1, 1]);
|
||||||
|
|
||||||
export class MetaConstantSignalBuilding extends MetaBuilding {
|
export class MetaConstantSignalBuilding extends MetaBuilding {
|
||||||
constructor() {
|
constructor() {
|
||||||
@ -11,7 +14,7 @@ export class MetaConstantSignalBuilding extends MetaBuilding {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getSilhouetteColor() {
|
getSilhouetteColor() {
|
||||||
return "#2bafda";
|
return "#2b84fd";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -35,6 +38,10 @@ export class MetaConstantSignalBuilding extends MetaBuilding {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getSpecialOverlayRenderMatrix(rotation) {
|
||||||
|
return overlayMatrix[rotation];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the entity at the given location
|
* Creates the entity at the given location
|
||||||
* @param {Entity} entity
|
* @param {Entity} entity
|
||||||
|
@ -1,155 +1,151 @@
|
|||||||
import { enumDirection, Vector } from "../../core/vector";
|
import { enumDirection, Vector } from "../../core/vector";
|
||||||
import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
|
import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
|
||||||
import { Entity } from "../entity";
|
import { Entity } from "../entity";
|
||||||
import { MetaBuilding, defaultBuildingVariant } from "../meta_building";
|
import { MetaBuilding, defaultBuildingVariant } from "../meta_building";
|
||||||
import { GameRoot } from "../root";
|
import { GameRoot } from "../root";
|
||||||
import { enumLogicGateType, LogicGateComponent } from "../components/logic_gate";
|
import { enumLogicGateType, LogicGateComponent } from "../components/logic_gate";
|
||||||
|
import { generateMatrixRotations } from "../../core/utils";
|
||||||
/** @enum {string} */
|
|
||||||
export const enumLogicGateVariants = {
|
/** @enum {string} */
|
||||||
not: "not",
|
export const enumLogicGateVariants = {
|
||||||
xor: "xor",
|
not: "not",
|
||||||
or: "or",
|
xor: "xor",
|
||||||
transistor: "transistor",
|
or: "or",
|
||||||
};
|
};
|
||||||
|
|
||||||
/** @enum {string} */
|
/** @enum {string} */
|
||||||
export const enumVariantToGate = {
|
export const enumVariantToGate = {
|
||||||
[defaultBuildingVariant]: enumLogicGateType.and,
|
[defaultBuildingVariant]: enumLogicGateType.and,
|
||||||
[enumLogicGateVariants.not]: enumLogicGateType.not,
|
[enumLogicGateVariants.not]: enumLogicGateType.not,
|
||||||
[enumLogicGateVariants.xor]: enumLogicGateType.xor,
|
[enumLogicGateVariants.xor]: enumLogicGateType.xor,
|
||||||
[enumLogicGateVariants.or]: enumLogicGateType.or,
|
[enumLogicGateVariants.or]: enumLogicGateType.or,
|
||||||
[enumLogicGateVariants.transistor]: enumLogicGateType.transistor,
|
};
|
||||||
};
|
|
||||||
|
const overlayMatrices = {
|
||||||
export class MetaLogicGateBuilding extends MetaBuilding {
|
[defaultBuildingVariant]: generateMatrixRotations([0, 1, 0, 1, 1, 1, 0, 1, 1]),
|
||||||
constructor() {
|
[enumLogicGateVariants.xor]: generateMatrixRotations([0, 1, 0, 1, 1, 1, 0, 1, 1]),
|
||||||
super("logic_gate");
|
[enumLogicGateVariants.or]: generateMatrixRotations([0, 1, 0, 1, 1, 1, 0, 1, 1]),
|
||||||
}
|
[enumLogicGateVariants.not]: generateMatrixRotations([0, 1, 0, 0, 1, 0, 0, 1, 0]),
|
||||||
|
};
|
||||||
getSilhouetteColor() {
|
|
||||||
return "#89dc60";
|
const colors = {
|
||||||
}
|
[defaultBuildingVariant]: "#f48d41",
|
||||||
|
[enumLogicGateVariants.xor]: "#f4a241",
|
||||||
/**
|
[enumLogicGateVariants.or]: "#f4d041",
|
||||||
* @param {GameRoot} root
|
[enumLogicGateVariants.not]: "#f44184",
|
||||||
*/
|
};
|
||||||
getIsUnlocked(root) {
|
|
||||||
// @todo
|
export class MetaLogicGateBuilding extends MetaBuilding {
|
||||||
return true;
|
constructor() {
|
||||||
}
|
super("logic_gate");
|
||||||
|
}
|
||||||
/** @returns {"wires"} **/
|
|
||||||
getLayer() {
|
getSilhouetteColor(variant) {
|
||||||
return "wires";
|
return colors[variant];
|
||||||
}
|
}
|
||||||
|
|
||||||
getDimensions() {
|
/**
|
||||||
return new Vector(1, 1);
|
* @param {GameRoot} root
|
||||||
}
|
*/
|
||||||
|
getIsUnlocked(root) {
|
||||||
getAvailableVariants() {
|
// @todo
|
||||||
return [
|
return true;
|
||||||
defaultBuildingVariant,
|
}
|
||||||
enumLogicGateVariants.not,
|
|
||||||
enumLogicGateVariants.xor,
|
/** @returns {"wires"} **/
|
||||||
enumLogicGateVariants.or,
|
getLayer() {
|
||||||
enumLogicGateVariants.transistor,
|
return "wires";
|
||||||
];
|
}
|
||||||
}
|
|
||||||
|
getDimensions() {
|
||||||
getRenderPins() {
|
return new Vector(1, 1);
|
||||||
// We already have it included
|
}
|
||||||
return false;
|
|
||||||
}
|
getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant) {
|
||||||
|
return overlayMatrices[variant][rotation];
|
||||||
/**
|
}
|
||||||
*
|
|
||||||
* @param {Entity} entity
|
getAvailableVariants() {
|
||||||
* @param {number} rotationVariant
|
return [
|
||||||
*/
|
defaultBuildingVariant,
|
||||||
updateVariants(entity, rotationVariant, variant) {
|
enumLogicGateVariants.or,
|
||||||
const gateType = enumVariantToGate[variant];
|
enumLogicGateVariants.not,
|
||||||
entity.components.LogicGate.type = gateType;
|
enumLogicGateVariants.xor,
|
||||||
|
];
|
||||||
const pinComp = entity.components.WiredPins;
|
}
|
||||||
|
|
||||||
switch (gateType) {
|
getRenderPins() {
|
||||||
case enumLogicGateType.and:
|
// We already have it included
|
||||||
case enumLogicGateType.xor:
|
return false;
|
||||||
case enumLogicGateType.or: {
|
}
|
||||||
pinComp.setSlots([
|
|
||||||
{
|
/**
|
||||||
pos: new Vector(0, 0),
|
*
|
||||||
direction: enumDirection.top,
|
* @param {Entity} entity
|
||||||
type: enumPinSlotType.logicalEjector,
|
* @param {number} rotationVariant
|
||||||
},
|
*/
|
||||||
{
|
updateVariants(entity, rotationVariant, variant) {
|
||||||
pos: new Vector(0, 0),
|
const gateType = enumVariantToGate[variant];
|
||||||
direction: enumDirection.left,
|
entity.components.LogicGate.type = gateType;
|
||||||
type: enumPinSlotType.logicalAcceptor,
|
|
||||||
},
|
const pinComp = entity.components.WiredPins;
|
||||||
{
|
|
||||||
pos: new Vector(0, 0),
|
switch (gateType) {
|
||||||
direction: enumDirection.right,
|
case enumLogicGateType.and:
|
||||||
type: enumPinSlotType.logicalAcceptor,
|
case enumLogicGateType.xor:
|
||||||
},
|
case enumLogicGateType.or: {
|
||||||
]);
|
pinComp.setSlots([
|
||||||
break;
|
{
|
||||||
}
|
pos: new Vector(0, 0),
|
||||||
case enumLogicGateType.transistor: {
|
direction: enumDirection.top,
|
||||||
pinComp.setSlots([
|
type: enumPinSlotType.logicalEjector,
|
||||||
{
|
},
|
||||||
pos: new Vector(0, 0),
|
{
|
||||||
direction: enumDirection.top,
|
pos: new Vector(0, 0),
|
||||||
type: enumPinSlotType.logicalEjector,
|
direction: enumDirection.left,
|
||||||
},
|
type: enumPinSlotType.logicalAcceptor,
|
||||||
{
|
},
|
||||||
pos: new Vector(0, 0),
|
{
|
||||||
direction: enumDirection.left,
|
pos: new Vector(0, 0),
|
||||||
type: enumPinSlotType.logicalAcceptor,
|
direction: enumDirection.right,
|
||||||
},
|
type: enumPinSlotType.logicalAcceptor,
|
||||||
{
|
},
|
||||||
pos: new Vector(0, 0),
|
]);
|
||||||
direction: enumDirection.bottom,
|
break;
|
||||||
type: enumPinSlotType.logicalAcceptor,
|
}
|
||||||
},
|
|
||||||
]);
|
case enumLogicGateType.not: {
|
||||||
break;
|
pinComp.setSlots([
|
||||||
}
|
{
|
||||||
|
pos: new Vector(0, 0),
|
||||||
case enumLogicGateType.not: {
|
direction: enumDirection.top,
|
||||||
pinComp.setSlots([
|
type: enumPinSlotType.logicalEjector,
|
||||||
{
|
},
|
||||||
pos: new Vector(0, 0),
|
{
|
||||||
direction: enumDirection.top,
|
pos: new Vector(0, 0),
|
||||||
type: enumPinSlotType.logicalEjector,
|
direction: enumDirection.bottom,
|
||||||
},
|
type: enumPinSlotType.logicalAcceptor,
|
||||||
{
|
},
|
||||||
pos: new Vector(0, 0),
|
]);
|
||||||
direction: enumDirection.bottom,
|
break;
|
||||||
type: enumPinSlotType.logicalAcceptor,
|
}
|
||||||
},
|
|
||||||
]);
|
default:
|
||||||
break;
|
assertAlways("unknown logic gate type: " + gateType);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
default:
|
|
||||||
assertAlways("unknown logic gate type: " + gateType);
|
/**
|
||||||
}
|
* Creates the entity at the given location
|
||||||
}
|
* @param {Entity} entity
|
||||||
|
*/
|
||||||
/**
|
setupEntityComponents(entity) {
|
||||||
* Creates the entity at the given location
|
entity.addComponent(
|
||||||
* @param {Entity} entity
|
new WiredPinsComponent({
|
||||||
*/
|
slots: [],
|
||||||
setupEntityComponents(entity) {
|
})
|
||||||
entity.addComponent(
|
);
|
||||||
new WiredPinsComponent({
|
|
||||||
slots: [],
|
entity.addComponent(new LogicGateComponent({}));
|
||||||
})
|
}
|
||||||
);
|
}
|
||||||
|
|
||||||
entity.addComponent(new LogicGateComponent({}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
101
src/js/game/buildings/transistor.js
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
import { generateMatrixRotations } from "../../core/utils";
|
||||||
|
import { enumDirection, Vector } from "../../core/vector";
|
||||||
|
import { enumLogicGateType, LogicGateComponent } from "../components/logic_gate";
|
||||||
|
import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
|
||||||
|
import { Entity } from "../entity";
|
||||||
|
import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
|
||||||
|
import { GameRoot } from "../root";
|
||||||
|
|
||||||
|
/** @enum {string} */
|
||||||
|
export const enumTransistorVariants = {
|
||||||
|
mirrored: "mirrored",
|
||||||
|
};
|
||||||
|
|
||||||
|
const overlayMatrices = {
|
||||||
|
[defaultBuildingVariant]: generateMatrixRotations([0, 1, 0, 1, 1, 0, 0, 1, 0]),
|
||||||
|
[enumTransistorVariants.mirrored]: generateMatrixRotations([0, 1, 0, 0, 1, 1, 0, 1, 0]),
|
||||||
|
};
|
||||||
|
|
||||||
|
export class MetaTransistorBuilding extends MetaBuilding {
|
||||||
|
constructor() {
|
||||||
|
super("transistor");
|
||||||
|
}
|
||||||
|
|
||||||
|
getSilhouetteColor() {
|
||||||
|
return "#bc3a61";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {GameRoot} root
|
||||||
|
*/
|
||||||
|
getIsUnlocked(root) {
|
||||||
|
// @todo
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @returns {"wires"} **/
|
||||||
|
getLayer() {
|
||||||
|
return "wires";
|
||||||
|
}
|
||||||
|
|
||||||
|
getDimensions() {
|
||||||
|
return new Vector(1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
getAvailableVariants() {
|
||||||
|
return [defaultBuildingVariant, enumTransistorVariants.mirrored];
|
||||||
|
}
|
||||||
|
|
||||||
|
getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant) {
|
||||||
|
return overlayMatrices[variant][rotation];
|
||||||
|
}
|
||||||
|
|
||||||
|
getRenderPins() {
|
||||||
|
// We already have it included
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Entity} entity
|
||||||
|
* @param {number} rotationVariant
|
||||||
|
*/
|
||||||
|
updateVariants(entity, rotationVariant, variant) {
|
||||||
|
entity.components.WiredPins.slots[1].direction =
|
||||||
|
variant === enumTransistorVariants.mirrored ? enumDirection.right : enumDirection.left;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the entity at the given location
|
||||||
|
* @param {Entity} entity
|
||||||
|
*/
|
||||||
|
setupEntityComponents(entity) {
|
||||||
|
entity.addComponent(
|
||||||
|
new WiredPinsComponent({
|
||||||
|
slots: [
|
||||||
|
{
|
||||||
|
pos: new Vector(0, 0),
|
||||||
|
direction: enumDirection.top,
|
||||||
|
type: enumPinSlotType.logicalEjector,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: new Vector(0, 0),
|
||||||
|
direction: enumDirection.left,
|
||||||
|
type: enumPinSlotType.logicalAcceptor,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pos: new Vector(0, 0),
|
||||||
|
direction: enumDirection.bottom,
|
||||||
|
type: enumPinSlotType.logicalAcceptor,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
entity.addComponent(
|
||||||
|
new LogicGateComponent({
|
||||||
|
type: enumLogicGateType.transistor,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -4,13 +4,15 @@ import { WiredPinsComponent, enumPinSlotType } from "../components/wired_pins";
|
|||||||
import { Entity } from "../entity";
|
import { Entity } from "../entity";
|
||||||
import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
|
import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
|
||||||
import { GameRoot } from "../root";
|
import { GameRoot } from "../root";
|
||||||
|
import { MetaCutterBuilding } from "./cutter";
|
||||||
|
import { MetaPainterBuilding } from "./painter";
|
||||||
|
import { MetaRotaterBuilding } from "./rotater";
|
||||||
|
import { MetaStackerBuilding } from "./stacker";
|
||||||
|
|
||||||
/** @enum {string} */
|
/** @enum {string} */
|
||||||
export const enumVirtualProcessorVariants = {
|
export const enumVirtualProcessorVariants = {
|
||||||
analyzer: "analyzer",
|
|
||||||
rotater: "rotater",
|
rotater: "rotater",
|
||||||
unstacker: "unstacker",
|
unstacker: "unstacker",
|
||||||
shapecompare: "shapecompare",
|
|
||||||
stacker: "stacker",
|
stacker: "stacker",
|
||||||
painter: "painter",
|
painter: "painter",
|
||||||
};
|
};
|
||||||
@ -18,21 +20,27 @@ export const enumVirtualProcessorVariants = {
|
|||||||
/** @enum {string} */
|
/** @enum {string} */
|
||||||
export const enumVariantToGate = {
|
export const enumVariantToGate = {
|
||||||
[defaultBuildingVariant]: enumLogicGateType.cutter,
|
[defaultBuildingVariant]: enumLogicGateType.cutter,
|
||||||
[enumVirtualProcessorVariants.analyzer]: enumLogicGateType.analyzer,
|
|
||||||
[enumVirtualProcessorVariants.rotater]: enumLogicGateType.rotater,
|
[enumVirtualProcessorVariants.rotater]: enumLogicGateType.rotater,
|
||||||
[enumVirtualProcessorVariants.unstacker]: enumLogicGateType.unstacker,
|
[enumVirtualProcessorVariants.unstacker]: enumLogicGateType.unstacker,
|
||||||
[enumVirtualProcessorVariants.shapecompare]: enumLogicGateType.shapecompare,
|
|
||||||
[enumVirtualProcessorVariants.stacker]: enumLogicGateType.stacker,
|
[enumVirtualProcessorVariants.stacker]: enumLogicGateType.stacker,
|
||||||
[enumVirtualProcessorVariants.painter]: enumLogicGateType.painter,
|
[enumVirtualProcessorVariants.painter]: enumLogicGateType.painter,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const colors = {
|
||||||
|
[defaultBuildingVariant]: new MetaCutterBuilding().getSilhouetteColor(),
|
||||||
|
[enumVirtualProcessorVariants.rotater]: new MetaRotaterBuilding().getSilhouetteColor(),
|
||||||
|
[enumVirtualProcessorVariants.unstacker]: new MetaStackerBuilding().getSilhouetteColor(),
|
||||||
|
[enumVirtualProcessorVariants.stacker]: new MetaStackerBuilding().getSilhouetteColor(),
|
||||||
|
[enumVirtualProcessorVariants.painter]: new MetaPainterBuilding().getSilhouetteColor(),
|
||||||
|
};
|
||||||
|
|
||||||
export class MetaVirtualProcessorBuilding extends MetaBuilding {
|
export class MetaVirtualProcessorBuilding extends MetaBuilding {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("virtual_processor");
|
super("virtual_processor");
|
||||||
}
|
}
|
||||||
|
|
||||||
getSilhouetteColor() {
|
getSilhouetteColor(variant) {
|
||||||
return "#823cab";
|
return colors[variant];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -56,11 +64,9 @@ export class MetaVirtualProcessorBuilding extends MetaBuilding {
|
|||||||
return [
|
return [
|
||||||
defaultBuildingVariant,
|
defaultBuildingVariant,
|
||||||
enumVirtualProcessorVariants.rotater,
|
enumVirtualProcessorVariants.rotater,
|
||||||
enumVirtualProcessorVariants.unstacker,
|
|
||||||
enumVirtualProcessorVariants.analyzer,
|
|
||||||
enumVirtualProcessorVariants.stacker,
|
enumVirtualProcessorVariants.stacker,
|
||||||
enumVirtualProcessorVariants.painter,
|
enumVirtualProcessorVariants.painter,
|
||||||
enumVirtualProcessorVariants.shapecompare,
|
enumVirtualProcessorVariants.unstacker,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,7 +86,6 @@ export class MetaVirtualProcessorBuilding extends MetaBuilding {
|
|||||||
const pinComp = entity.components.WiredPins;
|
const pinComp = entity.components.WiredPins;
|
||||||
switch (gateType) {
|
switch (gateType) {
|
||||||
case enumLogicGateType.cutter:
|
case enumLogicGateType.cutter:
|
||||||
case enumLogicGateType.analyzer:
|
|
||||||
case enumLogicGateType.unstacker: {
|
case enumLogicGateType.unstacker: {
|
||||||
pinComp.setSlots([
|
pinComp.setSlots([
|
||||||
{
|
{
|
||||||
@ -116,26 +121,6 @@ export class MetaVirtualProcessorBuilding extends MetaBuilding {
|
|||||||
]);
|
]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case enumLogicGateType.shapecompare: {
|
|
||||||
pinComp.setSlots([
|
|
||||||
{
|
|
||||||
pos: new Vector(0, 0),
|
|
||||||
direction: enumDirection.top,
|
|
||||||
type: enumPinSlotType.logicalEjector,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
pos: new Vector(0, 0),
|
|
||||||
direction: enumDirection.left,
|
|
||||||
type: enumPinSlotType.logicalAcceptor,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
pos: new Vector(0, 0),
|
|
||||||
direction: enumDirection.right,
|
|
||||||
type: enumPinSlotType.logicalAcceptor,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case enumLogicGateType.stacker:
|
case enumLogicGateType.stacker:
|
||||||
case enumLogicGateType.painter: {
|
case enumLogicGateType.painter: {
|
||||||
pinComp.setSlots([
|
pinComp.setSlots([
|
||||||
|
@ -1,263 +1,272 @@
|
|||||||
import { Loader } from "../../core/loader";
|
import { Loader } from "../../core/loader";
|
||||||
import { generateMatrixRotations } from "../../core/utils";
|
import { generateMatrixRotations } from "../../core/utils";
|
||||||
import { enumDirection, enumDirectionToAngle, enumDirectionToVector, Vector } from "../../core/vector";
|
import { enumDirection, Vector } from "../../core/vector";
|
||||||
import { SOUNDS } from "../../platform/sound";
|
import { SOUNDS } from "../../platform/sound";
|
||||||
import { enumWireType, WireComponent } from "../components/wire";
|
import { enumWireType, enumWireVariant, WireComponent } from "../components/wire";
|
||||||
import { Entity } from "../entity";
|
import { Entity } from "../entity";
|
||||||
import { MetaBuilding } from "../meta_building";
|
import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
|
||||||
import { GameRoot } from "../root";
|
import { GameRoot } from "../root";
|
||||||
|
|
||||||
export const arrayWireRotationVariantToType = [
|
export const arrayWireRotationVariantToType = [
|
||||||
enumWireType.regular,
|
enumWireType.forward,
|
||||||
enumWireType.turn,
|
enumWireType.turn,
|
||||||
enumWireType.split,
|
enumWireType.split,
|
||||||
enumWireType.cross,
|
enumWireType.cross,
|
||||||
];
|
];
|
||||||
|
|
||||||
export const wireOverlayMatrices = {
|
export const wireOverlayMatrices = {
|
||||||
[enumWireType.regular]: generateMatrixRotations([0, 1, 0, 0, 1, 0, 0, 1, 0]),
|
[enumWireType.forward]: generateMatrixRotations([0, 1, 0, 0, 1, 0, 0, 1, 0]),
|
||||||
[enumWireType.split]: generateMatrixRotations([0, 0, 0, 1, 1, 1, 0, 1, 0]),
|
[enumWireType.split]: generateMatrixRotations([0, 0, 0, 1, 1, 1, 0, 1, 0]),
|
||||||
[enumWireType.turn]: generateMatrixRotations([0, 0, 0, 0, 1, 1, 0, 1, 0]),
|
[enumWireType.turn]: generateMatrixRotations([0, 0, 0, 0, 1, 1, 0, 1, 0]),
|
||||||
[enumWireType.cross]: generateMatrixRotations([0, 1, 0, 1, 1, 1, 0, 1, 0]),
|
[enumWireType.cross]: generateMatrixRotations([0, 1, 0, 1, 1, 1, 0, 1, 0]),
|
||||||
};
|
};
|
||||||
|
|
||||||
export class MetaWireBuilding extends MetaBuilding {
|
/** @enum {string} */
|
||||||
constructor() {
|
export const wireVariants = {
|
||||||
super("wire");
|
second: "second",
|
||||||
}
|
third: "third",
|
||||||
|
};
|
||||||
getHasDirectionLockAvailable() {
|
|
||||||
return true;
|
const enumWireVariantToVariant = {
|
||||||
}
|
[defaultBuildingVariant]: enumWireVariant.first,
|
||||||
|
[wireVariants.second]: enumWireVariant.second,
|
||||||
getSilhouetteColor() {
|
[wireVariants.third]: enumWireVariant.third,
|
||||||
return "#25fff2";
|
};
|
||||||
}
|
|
||||||
|
export class MetaWireBuilding extends MetaBuilding {
|
||||||
getDimensions() {
|
constructor() {
|
||||||
return new Vector(1, 1);
|
super("wire");
|
||||||
}
|
}
|
||||||
|
|
||||||
getStayInPlacementMode() {
|
getHasDirectionLockAvailable() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
getPlacementSound() {
|
getSilhouetteColor() {
|
||||||
return SOUNDS.placeBelt;
|
return "#61ef6f";
|
||||||
}
|
}
|
||||||
|
|
||||||
getRotateAutomaticallyWhilePlacing() {
|
getAvailableVariants() {
|
||||||
return true;
|
return [defaultBuildingVariant, wireVariants.second, wireVariants.third];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @returns {"wires"} **/
|
getDimensions() {
|
||||||
getLayer() {
|
return new Vector(1, 1);
|
||||||
return "wires";
|
}
|
||||||
}
|
|
||||||
|
getStayInPlacementMode() {
|
||||||
getSprite() {
|
return true;
|
||||||
return null;
|
}
|
||||||
}
|
|
||||||
|
getPlacementSound() {
|
||||||
getIsReplaceable() {
|
return SOUNDS.placeBelt;
|
||||||
return true;
|
}
|
||||||
}
|
|
||||||
|
getRotateAutomaticallyWhilePlacing() {
|
||||||
/**
|
return true;
|
||||||
* @param {GameRoot} root
|
}
|
||||||
*/
|
|
||||||
getIsUnlocked(root) {
|
/** @returns {"wires"} **/
|
||||||
// @todo
|
getLayer() {
|
||||||
return true;
|
return "wires";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
getSprite() {
|
||||||
* Creates the entity at the given location
|
return null;
|
||||||
* @param {Entity} entity
|
}
|
||||||
*/
|
|
||||||
setupEntityComponents(entity) {
|
getIsReplaceable() {
|
||||||
// @todo
|
return true;
|
||||||
entity.addComponent(new WireComponent({}));
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
/**
|
* @param {GameRoot} root
|
||||||
*
|
*/
|
||||||
* @param {Entity} entity
|
getIsUnlocked(root) {
|
||||||
* @param {number} rotationVariant
|
// @todo
|
||||||
*/
|
return true;
|
||||||
updateVariants(entity, rotationVariant) {
|
}
|
||||||
entity.components.Wire.type = arrayWireRotationVariantToType[rotationVariant];
|
|
||||||
}
|
/**
|
||||||
|
* Creates the entity at the given location
|
||||||
/**
|
* @param {Entity} entity
|
||||||
*
|
*/
|
||||||
* @param {number} rotation
|
setupEntityComponents(entity) {
|
||||||
* @param {number} rotationVariant
|
entity.addComponent(new WireComponent({}));
|
||||||
* @param {string} variant
|
}
|
||||||
* @param {Entity} entity
|
|
||||||
*/
|
/**
|
||||||
getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) {
|
*
|
||||||
return wireOverlayMatrices[entity.components.Wire.type][rotation];
|
* @param {Entity} entity
|
||||||
}
|
* @param {number} rotationVariant
|
||||||
|
* @param {string} variant
|
||||||
getPreviewSprite(rotationVariant) {
|
*/
|
||||||
switch (arrayWireRotationVariantToType[rotationVariant]) {
|
updateVariants(entity, rotationVariant, variant) {
|
||||||
case enumWireType.regular: {
|
entity.components.Wire.type = arrayWireRotationVariantToType[rotationVariant];
|
||||||
return Loader.getSprite("sprites/buildings/wire.png");
|
entity.components.Wire.variant = enumWireVariantToVariant[variant];
|
||||||
}
|
}
|
||||||
case enumWireType.turn: {
|
|
||||||
return Loader.getSprite("sprites/buildings/wire-turn.png");
|
/**
|
||||||
}
|
*
|
||||||
case enumWireType.split: {
|
* @param {number} rotation
|
||||||
return Loader.getSprite("sprites/buildings/wire-split.png");
|
* @param {number} rotationVariant
|
||||||
}
|
* @param {string} variant
|
||||||
case enumWireType.cross: {
|
* @param {Entity} entity
|
||||||
return Loader.getSprite("sprites/buildings/wire-cross.png");
|
*/
|
||||||
}
|
getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) {
|
||||||
default: {
|
return wireOverlayMatrices[entity.components.Wire.type][rotation];
|
||||||
assertAlways(false, "Invalid wire rotation variant");
|
}
|
||||||
}
|
|
||||||
}
|
/**
|
||||||
}
|
*
|
||||||
|
* @param {number} rotationVariant
|
||||||
getBlueprintSprite(rotationVariant) {
|
* @param {string} variant
|
||||||
switch (arrayWireRotationVariantToType[rotationVariant]) {
|
* @returns {import("../../core/draw_utils").AtlasSprite}
|
||||||
case enumWireType.regular: {
|
*/
|
||||||
return Loader.getSprite("sprites/blueprints/wire.png");
|
getPreviewSprite(rotationVariant, variant) {
|
||||||
}
|
const wireVariant = enumWireVariantToVariant[variant];
|
||||||
case enumWireType.turn: {
|
switch (arrayWireRotationVariantToType[rotationVariant]) {
|
||||||
return Loader.getSprite("sprites/blueprints/wire-turn.png");
|
case enumWireType.forward: {
|
||||||
}
|
return Loader.getSprite("sprites/wires/sets/" + wireVariant + "_forward.png");
|
||||||
case enumWireType.split: {
|
}
|
||||||
return Loader.getSprite("sprites/blueprints/wire-split.png");
|
case enumWireType.turn: {
|
||||||
}
|
return Loader.getSprite("sprites/wires/sets/" + wireVariant + "_turn.png");
|
||||||
case enumWireType.cross: {
|
}
|
||||||
return Loader.getSprite("sprites/blueprints/wire-cross.png");
|
case enumWireType.split: {
|
||||||
}
|
return Loader.getSprite("sprites/wires/sets/" + wireVariant + "_split.png");
|
||||||
default: {
|
}
|
||||||
assertAlways(false, "Invalid wire rotation variant");
|
case enumWireType.cross: {
|
||||||
}
|
return Loader.getSprite("sprites/wires/sets/" + wireVariant + "_cross.png");
|
||||||
}
|
}
|
||||||
}
|
default: {
|
||||||
|
assertAlways(false, "Invalid wire rotation variant");
|
||||||
/**
|
}
|
||||||
* Should compute the optimal rotation variant on the given tile
|
}
|
||||||
* @param {object} param0
|
}
|
||||||
* @param {GameRoot} param0.root
|
|
||||||
* @param {Vector} param0.tile
|
getBlueprintSprite(rotationVariant, variant) {
|
||||||
* @param {number} param0.rotation
|
return this.getPreviewSprite(rotationVariant, variant);
|
||||||
* @param {string} param0.variant
|
}
|
||||||
* @param {string} param0.layer
|
|
||||||
* @return {{ rotation: number, rotationVariant: number, connectedEntities?: Array<Entity> }}
|
/**
|
||||||
*/
|
* Should compute the optimal rotation variant on the given tile
|
||||||
computeOptimalDirectionAndRotationVariantAtTile({ root, tile, rotation, variant, layer }) {
|
* @param {object} param0
|
||||||
const connections = {
|
* @param {GameRoot} param0.root
|
||||||
top: root.logic.computeWireEdgeStatus({ tile, rotation, edge: enumDirection.top }),
|
* @param {Vector} param0.tile
|
||||||
right: root.logic.computeWireEdgeStatus({ tile, rotation, edge: enumDirection.right }),
|
* @param {number} param0.rotation
|
||||||
bottom: root.logic.computeWireEdgeStatus({ tile, rotation, edge: enumDirection.bottom }),
|
* @param {string} param0.variant
|
||||||
left: root.logic.computeWireEdgeStatus({ tile, rotation, edge: enumDirection.left }),
|
* @param {string} param0.layer
|
||||||
};
|
* @return {{ rotation: number, rotationVariant: number, connectedEntities?: Array<Entity> }}
|
||||||
|
*/
|
||||||
let flag = 0;
|
computeOptimalDirectionAndRotationVariantAtTile({ root, tile, rotation, variant, layer }) {
|
||||||
flag |= connections.top ? 0x1000 : 0;
|
const wireVariant = enumWireVariantToVariant[variant];
|
||||||
flag |= connections.right ? 0x100 : 0;
|
const connections = {
|
||||||
flag |= connections.bottom ? 0x10 : 0;
|
top: root.logic.computeWireEdgeStatus({ tile, wireVariant, edge: enumDirection.top }),
|
||||||
flag |= connections.left ? 0x1 : 0;
|
right: root.logic.computeWireEdgeStatus({ tile, wireVariant, edge: enumDirection.right }),
|
||||||
|
bottom: root.logic.computeWireEdgeStatus({ tile, wireVariant, edge: enumDirection.bottom }),
|
||||||
let targetType = enumWireType.regular;
|
left: root.logic.computeWireEdgeStatus({ tile, wireVariant, edge: enumDirection.left }),
|
||||||
|
};
|
||||||
// First, reset rotation
|
|
||||||
rotation = 0;
|
let flag = 0;
|
||||||
|
flag |= connections.top ? 0x1000 : 0;
|
||||||
switch (flag) {
|
flag |= connections.right ? 0x100 : 0;
|
||||||
case 0x0000:
|
flag |= connections.bottom ? 0x10 : 0;
|
||||||
// Nothing
|
flag |= connections.left ? 0x1 : 0;
|
||||||
break;
|
|
||||||
|
let targetType = enumWireType.forward;
|
||||||
case 0x0001:
|
|
||||||
// Left
|
// First, reset rotation
|
||||||
rotation += 90;
|
rotation = 0;
|
||||||
break;
|
|
||||||
|
switch (flag) {
|
||||||
case 0x0010:
|
case 0x0000:
|
||||||
// Bottom
|
// Nothing
|
||||||
// END
|
break;
|
||||||
break;
|
|
||||||
|
case 0x0001:
|
||||||
case 0x0011:
|
// Left
|
||||||
// Bottom | Left
|
rotation += 90;
|
||||||
targetType = enumWireType.turn;
|
break;
|
||||||
rotation += 90;
|
|
||||||
break;
|
case 0x0010:
|
||||||
|
// Bottom
|
||||||
case 0x0100:
|
// END
|
||||||
// Right
|
break;
|
||||||
rotation += 90;
|
|
||||||
break;
|
case 0x0011:
|
||||||
|
// Bottom | Left
|
||||||
case 0x0101:
|
targetType = enumWireType.turn;
|
||||||
// Right | Left
|
rotation += 90;
|
||||||
rotation += 90;
|
break;
|
||||||
break;
|
|
||||||
|
case 0x0100:
|
||||||
case 0x0110:
|
// Right
|
||||||
// Right | Bottom
|
rotation += 90;
|
||||||
targetType = enumWireType.turn;
|
break;
|
||||||
break;
|
|
||||||
|
case 0x0101:
|
||||||
case 0x0111:
|
// Right | Left
|
||||||
// Right | Bottom | Left
|
rotation += 90;
|
||||||
targetType = enumWireType.split;
|
break;
|
||||||
break;
|
|
||||||
|
case 0x0110:
|
||||||
case 0x1000:
|
// Right | Bottom
|
||||||
// Top
|
targetType = enumWireType.turn;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1001:
|
case 0x0111:
|
||||||
// Top | Left
|
// Right | Bottom | Left
|
||||||
targetType = enumWireType.turn;
|
targetType = enumWireType.split;
|
||||||
rotation += 180;
|
break;
|
||||||
break;
|
|
||||||
|
case 0x1000:
|
||||||
case 0x1010:
|
// Top
|
||||||
// Top | Bottom
|
break;
|
||||||
break;
|
|
||||||
|
case 0x1001:
|
||||||
case 0x1011:
|
// Top | Left
|
||||||
// Top | Bottom | Left
|
targetType = enumWireType.turn;
|
||||||
targetType = enumWireType.split;
|
rotation += 180;
|
||||||
rotation += 90;
|
break;
|
||||||
break;
|
|
||||||
|
case 0x1010:
|
||||||
case 0x1100:
|
// Top | Bottom
|
||||||
// Top | Right
|
break;
|
||||||
targetType = enumWireType.turn;
|
|
||||||
rotation -= 90;
|
case 0x1011:
|
||||||
break;
|
// Top | Bottom | Left
|
||||||
|
targetType = enumWireType.split;
|
||||||
case 0x1101:
|
rotation += 90;
|
||||||
// Top | Right | Left
|
break;
|
||||||
targetType = enumWireType.split;
|
|
||||||
rotation += 180;
|
case 0x1100:
|
||||||
break;
|
// Top | Right
|
||||||
|
targetType = enumWireType.turn;
|
||||||
case 0x1110:
|
rotation -= 90;
|
||||||
// Top | Right | Bottom
|
break;
|
||||||
targetType = enumWireType.split;
|
|
||||||
rotation -= 90;
|
case 0x1101:
|
||||||
break;
|
// Top | Right | Left
|
||||||
|
targetType = enumWireType.split;
|
||||||
case 0x1111:
|
rotation += 180;
|
||||||
// Top | Right | Bottom | Left
|
break;
|
||||||
targetType = enumWireType.cross;
|
|
||||||
break;
|
case 0x1110:
|
||||||
}
|
// Top | Right | Bottom
|
||||||
|
targetType = enumWireType.split;
|
||||||
return {
|
rotation -= 90;
|
||||||
// Clamp rotation
|
break;
|
||||||
rotation: (rotation + 360 * 10) % 360,
|
|
||||||
rotationVariant: arrayWireRotationVariantToType.indexOf(targetType),
|
case 0x1111:
|
||||||
};
|
// Top | Right | Bottom | Left
|
||||||
}
|
targetType = enumWireType.cross;
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
// Clamp rotation
|
||||||
|
rotation: (rotation + 360 * 10) % 360,
|
||||||
|
rotationVariant: arrayWireRotationVariantToType.indexOf(targetType),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,87 +1,58 @@
|
|||||||
import { Vector } from "../../core/vector";
|
import { generateMatrixRotations } from "../../core/utils";
|
||||||
import { Entity } from "../entity";
|
import { Vector } from "../../core/vector";
|
||||||
import { MetaBuilding, defaultBuildingVariant } from "../meta_building";
|
import { WireTunnelComponent } from "../components/wire_tunnel";
|
||||||
import { GameRoot } from "../root";
|
import { Entity } from "../entity";
|
||||||
import { WireTunnelComponent } from "../components/wire_tunnel";
|
import { MetaBuilding } from "../meta_building";
|
||||||
import { generateMatrixRotations } from "../../core/utils";
|
import { GameRoot } from "../root";
|
||||||
|
import { enumHubGoalRewards } from "../tutorial_goals";
|
||||||
/** @enum {string} */
|
|
||||||
export const enumWireTunnelVariants = {
|
const wireTunnelOverlayMatrix = generateMatrixRotations([0, 1, 0, 1, 1, 1, 0, 1, 0]);
|
||||||
coating: "coating",
|
|
||||||
};
|
export class MetaWireTunnelBuilding extends MetaBuilding {
|
||||||
|
constructor() {
|
||||||
const wireTunnelOverlayMatrices = {
|
super("wire_tunnel");
|
||||||
[defaultBuildingVariant]: generateMatrixRotations([0, 1, 0, 1, 1, 1, 0, 1, 0]),
|
}
|
||||||
[enumWireTunnelVariants.coating]: generateMatrixRotations([0, 1, 0, 0, 1, 0, 0, 1, 0]),
|
|
||||||
};
|
getSilhouetteColor() {
|
||||||
|
return "#777a86";
|
||||||
export class MetaWireTunnelBuilding extends MetaBuilding {
|
}
|
||||||
constructor() {
|
|
||||||
super("wire_tunnel");
|
/**
|
||||||
}
|
* @param {GameRoot} root
|
||||||
|
*/
|
||||||
getSilhouetteColor() {
|
getIsUnlocked(root) {
|
||||||
return "#777a86";
|
return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_wires_filters_and_levers);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {GameRoot} root
|
*
|
||||||
*/
|
* @param {number} rotation
|
||||||
getIsUnlocked(root) {
|
* @param {number} rotationVariant
|
||||||
// @todo
|
* @param {string} variant
|
||||||
return true;
|
* @param {Entity} entity
|
||||||
}
|
*/
|
||||||
|
getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) {
|
||||||
/**
|
return wireTunnelOverlayMatrix[rotation];
|
||||||
*
|
}
|
||||||
* @param {number} rotation
|
|
||||||
* @param {number} rotationVariant
|
getIsRotateable() {
|
||||||
* @param {string} variant
|
return false;
|
||||||
* @param {Entity} entity
|
}
|
||||||
*/
|
|
||||||
getSpecialOverlayRenderMatrix(rotation, rotationVariant, variant, entity) {
|
getDimensions() {
|
||||||
return wireTunnelOverlayMatrices[variant][rotation];
|
return new Vector(1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
getIsRotateable(variant) {
|
/** @returns {"wires"} **/
|
||||||
return variant !== defaultBuildingVariant;
|
getLayer() {
|
||||||
}
|
return "wires";
|
||||||
|
}
|
||||||
getDimensions() {
|
|
||||||
return new Vector(1, 1);
|
/**
|
||||||
}
|
* Creates the entity at the given location
|
||||||
|
* @param {Entity} entity
|
||||||
getAvailableVariants() {
|
*/
|
||||||
return [defaultBuildingVariant, enumWireTunnelVariants.coating];
|
setupEntityComponents(entity) {
|
||||||
}
|
entity.addComponent(new WireTunnelComponent({}));
|
||||||
|
}
|
||||||
/** @returns {"wires"} **/
|
}
|
||||||
getLayer() {
|
|
||||||
return "wires";
|
|
||||||
}
|
|
||||||
|
|
||||||
getRotateAutomaticallyWhilePlacing() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
getStayInPlacementMode() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the entity at the given location
|
|
||||||
* @param {Entity} entity
|
|
||||||
*/
|
|
||||||
setupEntityComponents(entity) {
|
|
||||||
entity.addComponent(new WireTunnelComponent({}));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Entity} entity
|
|
||||||
* @param {number} rotationVariant
|
|
||||||
* @param {string} variant
|
|
||||||
*/
|
|
||||||
updateVariants(entity, rotationVariant, variant) {
|
|
||||||
entity.components.WireTunnel.multipleDirections = variant === defaultBuildingVariant;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -12,7 +12,7 @@ export const enumLogicGateType = {
|
|||||||
rotater: "rotater",
|
rotater: "rotater",
|
||||||
unstacker: "unstacker",
|
unstacker: "unstacker",
|
||||||
cutter: "cutter",
|
cutter: "cutter",
|
||||||
shapecompare: "shapecompare",
|
compare: "compare",
|
||||||
stacker: "stacker",
|
stacker: "stacker",
|
||||||
painter: "painter",
|
painter: "painter",
|
||||||
};
|
};
|
||||||
|
@ -63,6 +63,14 @@ export class StaticMapEntityComponent extends Component {
|
|||||||
return getBuildingDataFromCode(this.code).metaInstance;
|
return getBuildingDataFromCode(this.code).metaInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the buildings variant
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
getVariant() {
|
||||||
|
return getBuildingDataFromCode(this.code).variant;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy the current state to another component
|
* Copy the current state to another component
|
||||||
* @param {Component} otherComponent
|
* @param {Component} otherComponent
|
||||||
|
@ -2,12 +2,19 @@ import { Component } from "../component";
|
|||||||
|
|
||||||
/** @enum {string} */
|
/** @enum {string} */
|
||||||
export const enumWireType = {
|
export const enumWireType = {
|
||||||
regular: "regular",
|
forward: "forward",
|
||||||
turn: "turn",
|
turn: "turn",
|
||||||
split: "split",
|
split: "split",
|
||||||
cross: "cross",
|
cross: "cross",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** @enum {string} */
|
||||||
|
export const enumWireVariant = {
|
||||||
|
first: "first",
|
||||||
|
second: "second",
|
||||||
|
third: "third",
|
||||||
|
};
|
||||||
|
|
||||||
export class WireComponent extends Component {
|
export class WireComponent extends Component {
|
||||||
static getId() {
|
static getId() {
|
||||||
return "Wire";
|
return "Wire";
|
||||||
@ -16,54 +23,21 @@ export class WireComponent extends Component {
|
|||||||
/**
|
/**
|
||||||
* @param {object} param0
|
* @param {object} param0
|
||||||
* @param {enumWireType=} param0.type
|
* @param {enumWireType=} param0.type
|
||||||
|
* @param {enumWireVariant=} param0.variant
|
||||||
*/
|
*/
|
||||||
constructor({ type = enumWireType.regular }) {
|
constructor({ type = enumWireType.forward, variant = enumWireVariant.first }) {
|
||||||
super();
|
super();
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The variant of the wire, different variants do not connect
|
||||||
|
* @type {enumWireVariant}
|
||||||
|
*/
|
||||||
|
this.variant = variant;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {import("../systems/wire").WireNetwork}
|
* @type {import("../systems/wire").WireNetwork}
|
||||||
*/
|
*/
|
||||||
this.linkedNetwork = null;
|
this.linkedNetwork = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the local connections
|
|
||||||
* @returns {import("../../core/utils").DirectionalObject}
|
|
||||||
*/
|
|
||||||
getLocalConnections() {
|
|
||||||
return {
|
|
||||||
top: true,
|
|
||||||
right: false,
|
|
||||||
bottom: true,
|
|
||||||
left: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
// switch (this.type) {
|
|
||||||
// case enumWireType.regular:
|
|
||||||
// return {
|
|
||||||
// top: true,
|
|
||||||
// right: false,
|
|
||||||
// bottom: true,
|
|
||||||
// left: false,
|
|
||||||
// };
|
|
||||||
// case enumWireType.turn:
|
|
||||||
// return {
|
|
||||||
// top: false,
|
|
||||||
// right: true,
|
|
||||||
// bottom: true,
|
|
||||||
// left: false,
|
|
||||||
// };
|
|
||||||
// case enumWireType.split:
|
|
||||||
// return {
|
|
||||||
// top: false,
|
|
||||||
// right: true,
|
|
||||||
// bottom: true,
|
|
||||||
// left: true,
|
|
||||||
// };
|
|
||||||
|
|
||||||
// default:
|
|
||||||
// assertAlways(false, "Invalid wire type: " + this.type);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -5,13 +5,8 @@ export class WireTunnelComponent extends Component {
|
|||||||
return "WireTunnel";
|
return "WireTunnel";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
constructor() {
|
||||||
* @param {object} param0
|
|
||||||
* @param {boolean=} param0.multipleDirections
|
|
||||||
*/
|
|
||||||
constructor({ multipleDirections = true }) {
|
|
||||||
super();
|
super();
|
||||||
this.multipleDirections = multipleDirections;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Linked network, only if its not multiple directions
|
* Linked network, only if its not multiple directions
|
||||||
|
@ -5,6 +5,9 @@ import { MetaLogicGateBuilding } from "../../buildings/logic_gate";
|
|||||||
import { MetaLeverBuilding } from "../../buildings/lever";
|
import { MetaLeverBuilding } from "../../buildings/lever";
|
||||||
import { MetaWireTunnelBuilding } from "../../buildings/wire_tunnel";
|
import { MetaWireTunnelBuilding } from "../../buildings/wire_tunnel";
|
||||||
import { MetaVirtualProcessorBuilding } from "../../buildings/virtual_processor";
|
import { MetaVirtualProcessorBuilding } from "../../buildings/virtual_processor";
|
||||||
|
import { MetaTransistorBuilding } from "../../buildings/transistor";
|
||||||
|
import { MetaAnalyzerBuilding } from "../../buildings/analyzer";
|
||||||
|
import { MetaComparatorBuilding } from "../../buildings/comparator";
|
||||||
|
|
||||||
export class HUDWiresToolbar extends HUDBaseToolbar {
|
export class HUDWiresToolbar extends HUDBaseToolbar {
|
||||||
constructor(root) {
|
constructor(root) {
|
||||||
@ -13,9 +16,12 @@ export class HUDWiresToolbar extends HUDBaseToolbar {
|
|||||||
MetaWireBuilding,
|
MetaWireBuilding,
|
||||||
MetaWireTunnelBuilding,
|
MetaWireTunnelBuilding,
|
||||||
MetaConstantSignalBuilding,
|
MetaConstantSignalBuilding,
|
||||||
|
MetaTransistorBuilding,
|
||||||
MetaLogicGateBuilding,
|
MetaLogicGateBuilding,
|
||||||
|
MetaAnalyzerBuilding,
|
||||||
MetaLeverBuilding,
|
MetaLeverBuilding,
|
||||||
MetaVirtualProcessorBuilding,
|
MetaVirtualProcessorBuilding,
|
||||||
|
MetaComparatorBuilding,
|
||||||
],
|
],
|
||||||
visibilityCondition: () =>
|
visibilityCondition: () =>
|
||||||
!this.root.camera.getIsMapOverlayActive() && this.root.currentLayer === "wires",
|
!this.root.camera.getIsMapOverlayActive() && this.root.currentLayer === "wires",
|
||||||
|
@ -64,8 +64,11 @@ export const KEYMAPPINGS = {
|
|||||||
wire: { keyCode: key("1") },
|
wire: { keyCode: key("1") },
|
||||||
wire_tunnel: { keyCode: key("2") },
|
wire_tunnel: { keyCode: key("2") },
|
||||||
constant_signal: { keyCode: key("3") },
|
constant_signal: { keyCode: key("3") },
|
||||||
|
transistor: { keyCode: key("6") },
|
||||||
logic_gate: { keyCode: key("4") },
|
logic_gate: { keyCode: key("4") },
|
||||||
virtual_processor: { keyCode: key("5") },
|
virtual_processor: { keyCode: key("5") },
|
||||||
|
analyzer: { keyCode: key("7") },
|
||||||
|
comparator: { keyCode: key("8") },
|
||||||
},
|
},
|
||||||
|
|
||||||
placement: {
|
placement: {
|
||||||
|
@ -1,23 +1,18 @@
|
|||||||
|
import { globalConfig } from "../core/config";
|
||||||
import { createLogger } from "../core/logging";
|
import { createLogger } from "../core/logging";
|
||||||
import { STOP_PROPAGATION } from "../core/signal";
|
import { STOP_PROPAGATION } from "../core/signal";
|
||||||
import { round2Digits } from "../core/utils";
|
import { round2Digits } from "../core/utils";
|
||||||
import { enumDirection, enumDirectionToVector, enumInvertedDirections, Vector } from "../core/vector";
|
import { enumDirection, enumDirectionToVector, enumInvertedDirections, Vector } from "../core/vector";
|
||||||
import { getBuildingDataFromCode } from "./building_codes";
|
import { getBuildingDataFromCode } from "./building_codes";
|
||||||
|
import { enumWireVariant } from "./components/wire";
|
||||||
import { Entity } from "./entity";
|
import { Entity } from "./entity";
|
||||||
|
import { CHUNK_OVERLAY_RES } from "./map_chunk_view";
|
||||||
import { MetaBuilding } from "./meta_building";
|
import { MetaBuilding } from "./meta_building";
|
||||||
import { GameRoot } from "./root";
|
import { GameRoot } from "./root";
|
||||||
import { WireNetwork } from "./systems/wire";
|
import { WireNetwork } from "./systems/wire";
|
||||||
import { globalConfig } from "../core/config";
|
|
||||||
import { CHUNK_OVERLAY_RES } from "./map_chunk_view";
|
|
||||||
|
|
||||||
const logger = createLogger("ingame/logic");
|
const logger = createLogger("ingame/logic");
|
||||||
|
|
||||||
/** @enum {number} */
|
|
||||||
export const enumWireEdgeFlag = {
|
|
||||||
empty: 0,
|
|
||||||
connected: 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Typing helper
|
* Typing helper
|
||||||
* @typedef {Array<{
|
* @typedef {Array<{
|
||||||
@ -193,28 +188,72 @@ export class GameLogic {
|
|||||||
*
|
*
|
||||||
* Computes the flag for a given tile
|
* Computes the flag for a given tile
|
||||||
* @param {object} param0
|
* @param {object} param0
|
||||||
|
* @param {enumWireVariant} param0.wireVariant
|
||||||
* @param {Vector} param0.tile The tile to check at
|
* @param {Vector} param0.tile The tile to check at
|
||||||
* @param {enumDirection} param0.edge The edge to check for
|
* @param {enumDirection} param0.edge The edge to check for
|
||||||
* @param {number} param0.rotation The local tiles base rotation
|
|
||||||
*/
|
*/
|
||||||
computeWireEdgeStatus({ tile, edge, rotation }) {
|
computeWireEdgeStatus({ wireVariant, tile, edge }) {
|
||||||
const offset = enumDirectionToVector[edge];
|
const offset = enumDirectionToVector[edge];
|
||||||
const refTile = tile.add(offset);
|
const targetTile = tile.add(offset);
|
||||||
// const angle = enumDirectionToAngle[edge];
|
|
||||||
|
|
||||||
// // First, check if this edge can be connected from locally
|
// Search for relevant pins
|
||||||
// const canConnectLocally = rotation === angle || (rotation + 180) % 360 === angle;
|
const pinEntities = this.root.map.getLayersContentsMultipleXY(targetTile.x, targetTile.y);
|
||||||
|
|
||||||
const neighbourStatus = this.getWireEdgeFlag(refTile, edge);
|
// Go over all entities which could have a pin
|
||||||
|
for (let i = 0; i < pinEntities.length; ++i) {
|
||||||
|
const pinEntity = pinEntities[i];
|
||||||
|
const pinComp = pinEntity.components.WiredPins;
|
||||||
|
const staticComp = pinEntity.components.StaticMapEntity;
|
||||||
|
|
||||||
if (neighbourStatus === enumWireEdgeFlag.empty) {
|
// Skip those who don't have pins
|
||||||
// It's empty, no point in connecting
|
if (!pinComp) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Go over all pins
|
||||||
|
const pins = pinComp.slots;
|
||||||
|
for (let k = 0; k < pinComp.slots.length; ++k) {
|
||||||
|
const pinSlot = pins[k];
|
||||||
|
const pinLocation = staticComp.localTileToWorld(pinSlot.pos);
|
||||||
|
const pinDirection = staticComp.localDirectionToWorld(pinSlot.direction);
|
||||||
|
|
||||||
|
// Check if the pin has the right location
|
||||||
|
if (!pinLocation.equals(targetTile)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the pin has the right direction
|
||||||
|
if (pinDirection !== enumInvertedDirections[edge]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Found a pin!
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now check if there's a connectable entity on the wires layer
|
||||||
|
const targetEntity = this.root.map.getTileContent(targetTile, "wires");
|
||||||
|
if (!targetEntity) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (neighbourStatus === enumWireEdgeFlag.connected) {
|
const targetStaticComp = targetEntity.components.StaticMapEntity;
|
||||||
|
|
||||||
|
// Check if its a crossing
|
||||||
|
const wireTunnelComp = targetEntity.components.WireTunnel;
|
||||||
|
if (wireTunnelComp) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if its a wire
|
||||||
|
const wiresComp = targetEntity.components.Wire;
|
||||||
|
if (!wiresComp) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// It's connected if its the same variant
|
||||||
|
return wiresComp.variant === wireVariant;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -303,85 +342,7 @@ export class GameLogic {
|
|||||||
return !!overlayMatrix[localPosition.x + localPosition.y * 3];
|
return !!overlayMatrix[localPosition.x + localPosition.y * 3];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
g(tile, edge) {}
|
||||||
* Gets the flag at the given tile
|
|
||||||
* @param {Vector} tile
|
|
||||||
* @param {enumDirection} edge
|
|
||||||
* @returns {enumWireEdgeFlag}
|
|
||||||
*/
|
|
||||||
getWireEdgeFlag(tile, edge) {
|
|
||||||
// Search for relevant pins
|
|
||||||
const pinEntities = this.root.map.getLayersContentsMultipleXY(tile.x, tile.y);
|
|
||||||
|
|
||||||
// Go over all entities which could have a pin
|
|
||||||
for (let i = 0; i < pinEntities.length; ++i) {
|
|
||||||
const pinEntity = pinEntities[i];
|
|
||||||
const pinComp = pinEntity.components.WiredPins;
|
|
||||||
const staticComp = pinEntity.components.StaticMapEntity;
|
|
||||||
|
|
||||||
// Skip those who don't have pins
|
|
||||||
if (!pinComp) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Go over all pins
|
|
||||||
const pins = pinComp.slots;
|
|
||||||
for (let k = 0; k < pinComp.slots.length; ++k) {
|
|
||||||
const pinSlot = pins[k];
|
|
||||||
const pinLocation = staticComp.localTileToWorld(pinSlot.pos);
|
|
||||||
const pinDirection = staticComp.localDirectionToWorld(pinSlot.direction);
|
|
||||||
|
|
||||||
// Check if the pin has the right location
|
|
||||||
if (!pinLocation.equals(tile)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the pin has the right direction
|
|
||||||
if (pinDirection !== enumInvertedDirections[edge]) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Found a pin!
|
|
||||||
return enumWireEdgeFlag.connected;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now check if there's a connectable wire
|
|
||||||
const targetEntity = this.root.map.getTileContent(tile, "wires");
|
|
||||||
if (!targetEntity) {
|
|
||||||
return enumWireEdgeFlag.empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
const targetStaticComp = targetEntity.components.StaticMapEntity;
|
|
||||||
|
|
||||||
// Check if its a crossing
|
|
||||||
const wireTunnelComp = targetEntity.components.WireTunnel;
|
|
||||||
if (wireTunnelComp) {
|
|
||||||
// Check if the crossing is connected
|
|
||||||
if (wireTunnelComp.multipleDirections) {
|
|
||||||
return enumWireEdgeFlag.connected;
|
|
||||||
} else {
|
|
||||||
// Its a coating, check if it matches the direction
|
|
||||||
const referenceDirection = targetStaticComp.localDirectionToWorld(enumDirection.top);
|
|
||||||
return referenceDirection === edge || enumInvertedDirections[referenceDirection] === edge
|
|
||||||
? enumWireEdgeFlag.connected
|
|
||||||
: enumWireEdgeFlag.empty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if its a wire
|
|
||||||
const wiresComp = targetEntity.components.Wire;
|
|
||||||
if (!wiresComp) {
|
|
||||||
return enumWireEdgeFlag.empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
// const refAngle = enumDirectionToAngle[edge];
|
|
||||||
// const refRotation = targetEntity.components.StaticMapEntity.originalRotation;
|
|
||||||
// const canConnectRemotely = refRotation === refAngle || (refRotation + 180) % 360 === refAngle;
|
|
||||||
|
|
||||||
// Actually connected
|
|
||||||
return enumWireEdgeFlag.connected;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the acceptors and ejectors which affect the current tile
|
* Returns the acceptors and ejectors which affect the current tile
|
||||||
|
@ -1,30 +1,34 @@
|
|||||||
import { gMetaBuildingRegistry } from "../core/global_registries";
|
import { gMetaBuildingRegistry } from "../core/global_registries";
|
||||||
import { createLogger } from "../core/logging";
|
import { createLogger } from "../core/logging";
|
||||||
|
import { T } from "../translations";
|
||||||
|
import { MetaAnalyzerBuilding } from "./buildings/analyzer";
|
||||||
|
import { enumBalancerVariants, MetaBalancerBuilding } from "./buildings/balancer";
|
||||||
import { MetaBeltBuilding } from "./buildings/belt";
|
import { MetaBeltBuilding } from "./buildings/belt";
|
||||||
|
import { MetaComparatorBuilding } from "./buildings/comparator";
|
||||||
|
import { MetaConstantSignalBuilding } from "./buildings/constant_signal";
|
||||||
import { enumCutterVariants, MetaCutterBuilding } from "./buildings/cutter";
|
import { enumCutterVariants, MetaCutterBuilding } from "./buildings/cutter";
|
||||||
|
import { MetaDisplayBuilding } from "./buildings/display";
|
||||||
|
import { MetaFilterBuilding } from "./buildings/filter";
|
||||||
import { MetaHubBuilding } from "./buildings/hub";
|
import { MetaHubBuilding } from "./buildings/hub";
|
||||||
|
import { MetaLeverBuilding } from "./buildings/lever";
|
||||||
|
import { enumLogicGateVariants, MetaLogicGateBuilding } from "./buildings/logic_gate";
|
||||||
import { enumMinerVariants, MetaMinerBuilding } from "./buildings/miner";
|
import { enumMinerVariants, MetaMinerBuilding } from "./buildings/miner";
|
||||||
import { MetaMixerBuilding } from "./buildings/mixer";
|
import { MetaMixerBuilding } from "./buildings/mixer";
|
||||||
import { enumPainterVariants, MetaPainterBuilding } from "./buildings/painter";
|
import { enumPainterVariants, MetaPainterBuilding } from "./buildings/painter";
|
||||||
|
import { MetaReaderBuilding } from "./buildings/reader";
|
||||||
import { enumRotaterVariants, MetaRotaterBuilding } from "./buildings/rotater";
|
import { enumRotaterVariants, MetaRotaterBuilding } from "./buildings/rotater";
|
||||||
import { enumBalancerVariants, MetaBalancerBuilding } from "./buildings/balancer";
|
|
||||||
import { MetaStackerBuilding } from "./buildings/stacker";
|
import { MetaStackerBuilding } from "./buildings/stacker";
|
||||||
|
import { MetaStorageBuilding } from "./buildings/storage";
|
||||||
|
import { MetaTransistorBuilding, enumTransistorVariants } from "./buildings/transistor";
|
||||||
import { MetaTrashBuilding } from "./buildings/trash";
|
import { MetaTrashBuilding } from "./buildings/trash";
|
||||||
import { enumUndergroundBeltVariants, MetaUndergroundBeltBuilding } from "./buildings/underground_belt";
|
import { enumUndergroundBeltVariants, MetaUndergroundBeltBuilding } from "./buildings/underground_belt";
|
||||||
|
import { enumVirtualProcessorVariants, MetaVirtualProcessorBuilding } from "./buildings/virtual_processor";
|
||||||
import { MetaWireBuilding } from "./buildings/wire";
|
import { MetaWireBuilding } from "./buildings/wire";
|
||||||
|
import { MetaWireTunnelBuilding } from "./buildings/wire_tunnel";
|
||||||
import { buildBuildingCodeCache, gBuildingVariants, registerBuildingVariant } from "./building_codes";
|
import { buildBuildingCodeCache, gBuildingVariants, registerBuildingVariant } from "./building_codes";
|
||||||
import { defaultBuildingVariant } from "./meta_building";
|
import { enumWireVariant } from "./components/wire";
|
||||||
import { MetaConstantSignalBuilding } from "./buildings/constant_signal";
|
|
||||||
import { MetaLogicGateBuilding, enumLogicGateVariants } from "./buildings/logic_gate";
|
|
||||||
import { MetaLeverBuilding } from "./buildings/lever";
|
|
||||||
import { MetaFilterBuilding } from "./buildings/filter";
|
|
||||||
import { MetaWireTunnelBuilding, enumWireTunnelVariants } from "./buildings/wire_tunnel";
|
|
||||||
import { MetaDisplayBuilding } from "./buildings/display";
|
|
||||||
import { MetaVirtualProcessorBuilding, enumVirtualProcessorVariants } from "./buildings/virtual_processor";
|
|
||||||
import { MetaReaderBuilding } from "./buildings/reader";
|
|
||||||
import { MetaStorageBuilding } from "./buildings/storage";
|
|
||||||
import { KEYMAPPINGS } from "./key_action_mapper";
|
import { KEYMAPPINGS } from "./key_action_mapper";
|
||||||
import { T } from "../translations";
|
import { defaultBuildingVariant } from "./meta_building";
|
||||||
|
|
||||||
const logger = createLogger("building_registry");
|
const logger = createLogger("building_registry");
|
||||||
|
|
||||||
@ -50,6 +54,9 @@ export function initMetaBuildingRegistry() {
|
|||||||
gMetaBuildingRegistry.register(MetaDisplayBuilding);
|
gMetaBuildingRegistry.register(MetaDisplayBuilding);
|
||||||
gMetaBuildingRegistry.register(MetaVirtualProcessorBuilding);
|
gMetaBuildingRegistry.register(MetaVirtualProcessorBuilding);
|
||||||
gMetaBuildingRegistry.register(MetaReaderBuilding);
|
gMetaBuildingRegistry.register(MetaReaderBuilding);
|
||||||
|
gMetaBuildingRegistry.register(MetaTransistorBuilding);
|
||||||
|
gMetaBuildingRegistry.register(MetaAnalyzerBuilding);
|
||||||
|
gMetaBuildingRegistry.register(MetaComparatorBuilding);
|
||||||
|
|
||||||
// Belt
|
// Belt
|
||||||
registerBuildingVariant(1, MetaBeltBuilding, defaultBuildingVariant, 0);
|
registerBuildingVariant(1, MetaBeltBuilding, defaultBuildingVariant, 0);
|
||||||
@ -109,6 +116,16 @@ export function initMetaBuildingRegistry() {
|
|||||||
registerBuildingVariant(29, MetaWireBuilding, defaultBuildingVariant, 2);
|
registerBuildingVariant(29, MetaWireBuilding, defaultBuildingVariant, 2);
|
||||||
registerBuildingVariant(30, MetaWireBuilding, defaultBuildingVariant, 3);
|
registerBuildingVariant(30, MetaWireBuilding, defaultBuildingVariant, 3);
|
||||||
|
|
||||||
|
registerBuildingVariant(52, MetaWireBuilding, enumWireVariant.second, 0);
|
||||||
|
registerBuildingVariant(53, MetaWireBuilding, enumWireVariant.second, 1);
|
||||||
|
registerBuildingVariant(54, MetaWireBuilding, enumWireVariant.second, 2);
|
||||||
|
registerBuildingVariant(55, MetaWireBuilding, enumWireVariant.second, 3);
|
||||||
|
|
||||||
|
registerBuildingVariant(56, MetaWireBuilding, enumWireVariant.third, 0);
|
||||||
|
registerBuildingVariant(57, MetaWireBuilding, enumWireVariant.third, 1);
|
||||||
|
registerBuildingVariant(58, MetaWireBuilding, enumWireVariant.third, 2);
|
||||||
|
registerBuildingVariant(59, MetaWireBuilding, enumWireVariant.third, 3);
|
||||||
|
|
||||||
// Constant signal
|
// Constant signal
|
||||||
registerBuildingVariant(31, MetaConstantSignalBuilding);
|
registerBuildingVariant(31, MetaConstantSignalBuilding);
|
||||||
|
|
||||||
@ -117,7 +134,10 @@ export function initMetaBuildingRegistry() {
|
|||||||
registerBuildingVariant(34, MetaLogicGateBuilding, enumLogicGateVariants.not);
|
registerBuildingVariant(34, MetaLogicGateBuilding, enumLogicGateVariants.not);
|
||||||
registerBuildingVariant(35, MetaLogicGateBuilding, enumLogicGateVariants.xor);
|
registerBuildingVariant(35, MetaLogicGateBuilding, enumLogicGateVariants.xor);
|
||||||
registerBuildingVariant(36, MetaLogicGateBuilding, enumLogicGateVariants.or);
|
registerBuildingVariant(36, MetaLogicGateBuilding, enumLogicGateVariants.or);
|
||||||
registerBuildingVariant(38, MetaLogicGateBuilding, enumLogicGateVariants.transistor);
|
|
||||||
|
// Transistor
|
||||||
|
registerBuildingVariant(38, MetaTransistorBuilding, defaultBuildingVariant);
|
||||||
|
registerBuildingVariant(60, MetaTransistorBuilding, enumTransistorVariants.mirrored);
|
||||||
|
|
||||||
// Lever
|
// Lever
|
||||||
registerBuildingVariant(33, MetaLeverBuilding);
|
registerBuildingVariant(33, MetaLeverBuilding);
|
||||||
@ -127,20 +147,21 @@ export function initMetaBuildingRegistry() {
|
|||||||
|
|
||||||
// Wire tunnel
|
// Wire tunnel
|
||||||
registerBuildingVariant(39, MetaWireTunnelBuilding);
|
registerBuildingVariant(39, MetaWireTunnelBuilding);
|
||||||
registerBuildingVariant(41, MetaWireTunnelBuilding, enumWireTunnelVariants.coating);
|
|
||||||
|
|
||||||
// Display
|
// Display
|
||||||
registerBuildingVariant(40, MetaDisplayBuilding);
|
registerBuildingVariant(40, MetaDisplayBuilding);
|
||||||
|
|
||||||
// Virtual Processor
|
// Virtual Processor
|
||||||
registerBuildingVariant(42, MetaVirtualProcessorBuilding);
|
registerBuildingVariant(42, MetaVirtualProcessorBuilding);
|
||||||
registerBuildingVariant(43, MetaVirtualProcessorBuilding, enumVirtualProcessorVariants.analyzer);
|
|
||||||
registerBuildingVariant(44, MetaVirtualProcessorBuilding, enumVirtualProcessorVariants.rotater);
|
registerBuildingVariant(44, MetaVirtualProcessorBuilding, enumVirtualProcessorVariants.rotater);
|
||||||
registerBuildingVariant(45, MetaVirtualProcessorBuilding, enumVirtualProcessorVariants.unstacker);
|
registerBuildingVariant(45, MetaVirtualProcessorBuilding, enumVirtualProcessorVariants.unstacker);
|
||||||
registerBuildingVariant(46, MetaVirtualProcessorBuilding, enumVirtualProcessorVariants.shapecompare);
|
|
||||||
registerBuildingVariant(50, MetaVirtualProcessorBuilding, enumVirtualProcessorVariants.stacker);
|
registerBuildingVariant(50, MetaVirtualProcessorBuilding, enumVirtualProcessorVariants.stacker);
|
||||||
registerBuildingVariant(51, MetaVirtualProcessorBuilding, enumVirtualProcessorVariants.painter);
|
registerBuildingVariant(51, MetaVirtualProcessorBuilding, enumVirtualProcessorVariants.painter);
|
||||||
|
|
||||||
|
// Analyzer
|
||||||
|
registerBuildingVariant(46, MetaComparatorBuilding);
|
||||||
|
registerBuildingVariant(43, MetaAnalyzerBuilding);
|
||||||
|
|
||||||
// Reader
|
// Reader
|
||||||
registerBuildingVariant(49, MetaReaderBuilding);
|
registerBuildingVariant(49, MetaReaderBuilding);
|
||||||
|
|
||||||
|
@ -3,11 +3,9 @@ import { enumColors } from "../colors";
|
|||||||
import { enumLogicGateType, LogicGateComponent } from "../components/logic_gate";
|
import { enumLogicGateType, LogicGateComponent } from "../components/logic_gate";
|
||||||
import { enumPinSlotType } from "../components/wired_pins";
|
import { enumPinSlotType } from "../components/wired_pins";
|
||||||
import { GameSystemWithFilter } from "../game_system_with_filter";
|
import { GameSystemWithFilter } from "../game_system_with_filter";
|
||||||
import { BOOL_FALSE_SINGLETON, BOOL_TRUE_SINGLETON, isTruthyItem, BooleanItem } from "../items/boolean_item";
|
import { BOOL_FALSE_SINGLETON, BOOL_TRUE_SINGLETON, isTruthyItem } from "../items/boolean_item";
|
||||||
import { COLOR_ITEM_SINGLETONS, ColorItem } from "../items/color_item";
|
import { COLOR_ITEM_SINGLETONS } from "../items/color_item";
|
||||||
import { ShapeDefinition } from "../shape_definition";
|
import { ShapeDefinition } from "../shape_definition";
|
||||||
import { ShapeItem } from "../items/shape_item";
|
|
||||||
import { enumInvertedDirections } from "../../core/vector";
|
|
||||||
|
|
||||||
export class LogicGateSystem extends GameSystemWithFilter {
|
export class LogicGateSystem extends GameSystemWithFilter {
|
||||||
constructor(root) {
|
constructor(root) {
|
||||||
@ -24,7 +22,7 @@ export class LogicGateSystem extends GameSystemWithFilter {
|
|||||||
[enumLogicGateType.analyzer]: this.compute_ANALYZE.bind(this),
|
[enumLogicGateType.analyzer]: this.compute_ANALYZE.bind(this),
|
||||||
[enumLogicGateType.cutter]: this.compute_CUT.bind(this),
|
[enumLogicGateType.cutter]: this.compute_CUT.bind(this),
|
||||||
[enumLogicGateType.unstacker]: this.compute_UNSTACK.bind(this),
|
[enumLogicGateType.unstacker]: this.compute_UNSTACK.bind(this),
|
||||||
[enumLogicGateType.shapecompare]: this.compute_SHAPECOMPARE.bind(this),
|
[enumLogicGateType.compare]: this.compute_COMPARE.bind(this),
|
||||||
[enumLogicGateType.stacker]: this.compute_STACKER.bind(this),
|
[enumLogicGateType.stacker]: this.compute_STACKER.bind(this),
|
||||||
[enumLogicGateType.painter]: this.compute_PAINTER.bind(this),
|
[enumLogicGateType.painter]: this.compute_PAINTER.bind(this),
|
||||||
};
|
};
|
||||||
@ -318,7 +316,7 @@ export class LogicGateSystem extends GameSystemWithFilter {
|
|||||||
* @param {Array<BaseItem|null>} parameters
|
* @param {Array<BaseItem|null>} parameters
|
||||||
* @returns {BaseItem}
|
* @returns {BaseItem}
|
||||||
*/
|
*/
|
||||||
compute_SHAPECOMPARE(parameters) {
|
compute_COMPARE(parameters) {
|
||||||
const itemA = parameters[0];
|
const itemA = parameters[0];
|
||||||
const itemB = parameters[1];
|
const itemB = parameters[1];
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ import { gMetaBuildingRegistry } from "../../core/global_registries";
|
|||||||
import { Loader } from "../../core/loader";
|
import { Loader } from "../../core/loader";
|
||||||
import { createLogger } from "../../core/logging";
|
import { createLogger } from "../../core/logging";
|
||||||
import { Rectangle } from "../../core/rectangle";
|
import { Rectangle } from "../../core/rectangle";
|
||||||
|
import { AtlasSprite } from "../../core/sprites";
|
||||||
import { StaleAreaDetector } from "../../core/stale_area_detector";
|
import { StaleAreaDetector } from "../../core/stale_area_detector";
|
||||||
import { fastArrayDeleteValueIfContained } from "../../core/utils";
|
import { fastArrayDeleteValueIfContained } from "../../core/utils";
|
||||||
import {
|
import {
|
||||||
@ -13,16 +14,15 @@ import {
|
|||||||
Vector,
|
Vector,
|
||||||
} from "../../core/vector";
|
} from "../../core/vector";
|
||||||
import { BaseItem } from "../base_item";
|
import { BaseItem } from "../base_item";
|
||||||
import { isTrueItem } from "../items/boolean_item";
|
|
||||||
import { arrayWireRotationVariantToType, MetaWireBuilding } from "../buildings/wire";
|
import { arrayWireRotationVariantToType, MetaWireBuilding } from "../buildings/wire";
|
||||||
import { getCodeFromBuildingData } from "../building_codes";
|
import { getCodeFromBuildingData } from "../building_codes";
|
||||||
import { enumWireType, WireComponent } from "../components/wire";
|
import { enumWireType, enumWireVariant, WireComponent } from "../components/wire";
|
||||||
import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
|
import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
|
||||||
import { WireTunnelComponent } from "../components/wire_tunnel";
|
import { WireTunnelComponent } from "../components/wire_tunnel";
|
||||||
import { Entity } from "../entity";
|
import { Entity } from "../entity";
|
||||||
import { GameSystemWithFilter } from "../game_system_with_filter";
|
import { GameSystemWithFilter } from "../game_system_with_filter";
|
||||||
|
import { isTruthyItem } from "../items/boolean_item";
|
||||||
import { MapChunkView } from "../map_chunk_view";
|
import { MapChunkView } from "../map_chunk_view";
|
||||||
import { defaultBuildingVariant } from "../meta_building";
|
|
||||||
|
|
||||||
const logger = createLogger("wires");
|
const logger = createLogger("wires");
|
||||||
|
|
||||||
@ -93,32 +93,22 @@ export class WireSystem extends GameSystemWithFilter {
|
|||||||
constructor(root) {
|
constructor(root) {
|
||||||
super(root, [WireComponent]);
|
super(root, [WireComponent]);
|
||||||
|
|
||||||
this.wireSprites = {
|
/**
|
||||||
regular: {
|
* @type {Object<enumWireVariant, Object<enumWireType, AtlasSprite>>}
|
||||||
[enumWireType.regular]: Loader.getSprite("sprites/wires/sets/regular_forward.png"),
|
*/
|
||||||
[enumWireType.turn]: Loader.getSprite("sprites/wires/sets/regular_turn.png"),
|
this.wireSprites = {};
|
||||||
[enumWireType.split]: Loader.getSprite("sprites/wires/sets/regular_split.png"),
|
|
||||||
[enumWireType.cross]: Loader.getSprite("sprites/wires/sets/regular_cross.png"),
|
const variants = ["conflict", ...Object.keys(enumWireVariant)];
|
||||||
},
|
for (let i = 0; i < variants.length; ++i) {
|
||||||
conflict: {
|
const wireVariant = variants[i];
|
||||||
[enumWireType.regular]: Loader.getSprite("sprites/wires/sets/conflict_forward.png"),
|
const sprites = {};
|
||||||
[enumWireType.turn]: Loader.getSprite("sprites/wires/sets/conflict_turn.png"),
|
for (const wireType in enumWireType) {
|
||||||
[enumWireType.split]: Loader.getSprite("sprites/wires/sets/conflict_split.png"),
|
sprites[wireType] = Loader.getSprite(
|
||||||
[enumWireType.cross]: Loader.getSprite("sprites/wires/sets/conflict_cross.png"),
|
"sprites/wires/sets/" + wireVariant + "_" + wireType + ".png"
|
||||||
},
|
);
|
||||||
shape: {
|
}
|
||||||
[enumWireType.regular]: Loader.getSprite("sprites/wires/sets/shape_forward.png"),
|
this.wireSprites[wireVariant] = sprites;
|
||||||
[enumWireType.turn]: Loader.getSprite("sprites/wires/sets/shape_turn.png"),
|
}
|
||||||
[enumWireType.split]: Loader.getSprite("sprites/wires/sets/shape_split.png"),
|
|
||||||
[enumWireType.cross]: Loader.getSprite("sprites/wires/sets/shape_cross.png"),
|
|
||||||
},
|
|
||||||
color: {
|
|
||||||
[enumWireType.regular]: Loader.getSprite("sprites/wires/sets/color_forward.png"),
|
|
||||||
[enumWireType.turn]: Loader.getSprite("sprites/wires/sets/color_turn.png"),
|
|
||||||
[enumWireType.split]: Loader.getSprite("sprites/wires/sets/color_split.png"),
|
|
||||||
[enumWireType.cross]: Loader.getSprite("sprites/wires/sets/color_cross.png"),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
this.root.signals.entityDestroyed.add(this.queuePlacementUpdate, this);
|
this.root.signals.entityDestroyed.add(this.queuePlacementUpdate, this);
|
||||||
this.root.signals.entityAdded.add(this.queuePlacementUpdate, this);
|
this.root.signals.entityAdded.add(this.queuePlacementUpdate, this);
|
||||||
@ -230,6 +220,13 @@ export class WireSystem extends GameSystemWithFilter {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Once we occur a wire, we store its variant so we don't connect to
|
||||||
|
* mismatching ones
|
||||||
|
* @type {enumWireVariant}
|
||||||
|
*/
|
||||||
|
let variantMask = null;
|
||||||
|
|
||||||
while (entitiesToVisit.length > 0) {
|
while (entitiesToVisit.length > 0) {
|
||||||
const nextData = entitiesToVisit.pop();
|
const nextData = entitiesToVisit.pop();
|
||||||
const nextEntity = nextData.entity;
|
const nextEntity = nextData.entity;
|
||||||
@ -257,13 +254,18 @@ export class WireSystem extends GameSystemWithFilter {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!wireComp.linkedNetwork) {
|
if (!wireComp.linkedNetwork) {
|
||||||
// This one is new! :D
|
if (variantMask && wireComp.variant !== variantMask) {
|
||||||
VERBOSE_WIRES && logger.log(" Visited new wire:", staticComp.origin.toString());
|
// Mismatching variant
|
||||||
wireComp.linkedNetwork = currentNetwork;
|
} else {
|
||||||
currentNetwork.wires.push(nextEntity);
|
// This one is new! :D
|
||||||
|
VERBOSE_WIRES && logger.log(" Visited new wire:", staticComp.origin.toString());
|
||||||
|
wireComp.linkedNetwork = currentNetwork;
|
||||||
|
currentNetwork.wires.push(nextEntity);
|
||||||
|
|
||||||
newSearchDirections = arrayAllDirections;
|
newSearchDirections = arrayAllDirections;
|
||||||
newSearchTile = nextEntity.components.StaticMapEntity.origin;
|
newSearchTile = nextEntity.components.StaticMapEntity.origin;
|
||||||
|
variantMask = wireComp.variant;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,7 +321,8 @@ export class WireSystem extends GameSystemWithFilter {
|
|||||||
const newTargets = this.findSurroundingWireTargets(
|
const newTargets = this.findSurroundingWireTargets(
|
||||||
newSearchTile,
|
newSearchTile,
|
||||||
newSearchDirections,
|
newSearchDirections,
|
||||||
currentNetwork
|
currentNetwork,
|
||||||
|
variantMask
|
||||||
);
|
);
|
||||||
|
|
||||||
VERBOSE_WIRES && logger.log(" Found", newTargets, "new targets to visit!");
|
VERBOSE_WIRES && logger.log(" Found", newTargets, "new targets to visit!");
|
||||||
@ -361,13 +364,21 @@ export class WireSystem extends GameSystemWithFilter {
|
|||||||
* @param {Vector} initialTile
|
* @param {Vector} initialTile
|
||||||
* @param {Array<enumDirection>} directions
|
* @param {Array<enumDirection>} directions
|
||||||
* @param {WireNetwork} network
|
* @param {WireNetwork} network
|
||||||
|
* @param {enumWireVariant=} variantMask Only accept connections to this mask
|
||||||
* @returns {Array<any>}
|
* @returns {Array<any>}
|
||||||
*/
|
*/
|
||||||
findSurroundingWireTargets(initialTile, directions, network) {
|
findSurroundingWireTargets(initialTile, directions, network, variantMask = null) {
|
||||||
let result = [];
|
let result = [];
|
||||||
|
|
||||||
VERBOSE_WIRES &&
|
VERBOSE_WIRES &&
|
||||||
logger.log(" Searching for new targets at", initialTile.toString(), "and d=", directions);
|
logger.log(
|
||||||
|
" Searching for new targets at",
|
||||||
|
initialTile.toString(),
|
||||||
|
"and d=",
|
||||||
|
directions,
|
||||||
|
"with mask=",
|
||||||
|
variantMask
|
||||||
|
);
|
||||||
|
|
||||||
// Go over all directions we should search for
|
// Go over all directions we should search for
|
||||||
for (let i = 0; i < directions.length; ++i) {
|
for (let i = 0; i < directions.length; ++i) {
|
||||||
@ -399,7 +410,11 @@ export class WireSystem extends GameSystemWithFilter {
|
|||||||
const wireComp = entity.components.Wire;
|
const wireComp = entity.components.Wire;
|
||||||
|
|
||||||
// Check for wire
|
// Check for wire
|
||||||
if (wireComp && !wireComp.linkedNetwork) {
|
if (
|
||||||
|
wireComp &&
|
||||||
|
!wireComp.linkedNetwork &&
|
||||||
|
(!variantMask || wireComp.variant === variantMask)
|
||||||
|
) {
|
||||||
// Wires accept connections from everywhere
|
// Wires accept connections from everywhere
|
||||||
result.push({
|
result.push({
|
||||||
entity,
|
entity,
|
||||||
@ -449,17 +464,6 @@ export class WireSystem extends GameSystemWithFilter {
|
|||||||
|
|
||||||
const staticComp = entity.components.StaticMapEntity;
|
const staticComp = entity.components.StaticMapEntity;
|
||||||
|
|
||||||
if (
|
|
||||||
!tunnelComp.multipleDirections &&
|
|
||||||
!(
|
|
||||||
direction === staticComp.localDirectionToWorld(enumDirection.top) ||
|
|
||||||
direction === staticComp.localDirectionToWorld(enumDirection.bottom)
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
// It's a coating, and it doesn't connect here
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute where this tunnel connects to
|
// Compute where this tunnel connects to
|
||||||
const forwardedTile = staticComp.origin.add(offset);
|
const forwardedTile = staticComp.origin.add(offset);
|
||||||
VERBOSE_WIRES &&
|
VERBOSE_WIRES &&
|
||||||
@ -570,8 +574,8 @@ export class WireSystem extends GameSystemWithFilter {
|
|||||||
if (!wireComp.linkedNetwork) {
|
if (!wireComp.linkedNetwork) {
|
||||||
// There is no network, it's empty
|
// There is no network, it's empty
|
||||||
return {
|
return {
|
||||||
spriteSet: this.wireSprites.regular,
|
spriteSet: this.wireSprites[wireComp.variant],
|
||||||
opacity: 0.3,
|
opacity: 0.5,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -584,38 +588,9 @@ export class WireSystem extends GameSystemWithFilter {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const value = network.currentValue;
|
|
||||||
if (!value) {
|
|
||||||
// There is no value stored
|
|
||||||
return {
|
|
||||||
spriteSet: this.wireSprites.regular,
|
|
||||||
opacity: 0.3,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const valueType = value.getItemType();
|
|
||||||
if (valueType === "shape") {
|
|
||||||
return {
|
|
||||||
spriteSet: this.wireSprites.shape,
|
|
||||||
opacity: 1,
|
|
||||||
};
|
|
||||||
} else if (valueType === "color") {
|
|
||||||
return {
|
|
||||||
spriteSet: this.wireSprites.color,
|
|
||||||
opacity: 1,
|
|
||||||
};
|
|
||||||
} else if (valueType === "boolean") {
|
|
||||||
return {
|
|
||||||
spriteSet: this.wireSprites.regular,
|
|
||||||
opacity: isTrueItem(value) ? 1 : 0.5,
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
assertAlways(false, "Unknown item type: " + valueType);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
spriteSet: this.wireSprites.regular,
|
spriteSet: this.wireSprites[wireComp.variant],
|
||||||
opacity: 1,
|
opacity: isTruthyItem(network.currentValue) ? 1 : 0.5,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -641,9 +616,10 @@ export class WireSystem extends GameSystemWithFilter {
|
|||||||
const staticComp = entity.components.StaticMapEntity;
|
const staticComp = entity.components.StaticMapEntity;
|
||||||
parameters.context.globalAlpha = opacity;
|
parameters.context.globalAlpha = opacity;
|
||||||
staticComp.drawSpriteOnBoundsClipped(parameters, sprite, 0);
|
staticComp.drawSpriteOnBoundsClipped(parameters, sprite, 0);
|
||||||
parameters.context.globalAlpha = 1;
|
|
||||||
|
|
||||||
|
// DEBUG Rendering
|
||||||
if (G_IS_DEV && globalConfig.debug.renderWireRotations) {
|
if (G_IS_DEV && globalConfig.debug.renderWireRotations) {
|
||||||
|
parameters.context.globalAlpha = 1;
|
||||||
parameters.context.fillStyle = "red";
|
parameters.context.fillStyle = "red";
|
||||||
parameters.context.font = "5px Tahoma";
|
parameters.context.font = "5px Tahoma";
|
||||||
parameters.context.fillText(
|
parameters.context.fillText(
|
||||||
@ -691,6 +667,8 @@ export class WireSystem extends GameSystemWithFilter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parameters.context.globalAlpha = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -746,6 +724,8 @@ export class WireSystem extends GameSystemWithFilter {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const variant = targetStaticComp.getVariant();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
rotation,
|
rotation,
|
||||||
rotationVariant,
|
rotationVariant,
|
||||||
@ -753,7 +733,7 @@ export class WireSystem extends GameSystemWithFilter {
|
|||||||
root: this.root,
|
root: this.root,
|
||||||
tile: new Vector(x, y),
|
tile: new Vector(x, y),
|
||||||
rotation: targetStaticComp.originalRotation,
|
rotation: targetStaticComp.originalRotation,
|
||||||
variant: defaultBuildingVariant,
|
variant,
|
||||||
layer: targetEntity.layer,
|
layer: targetEntity.layer,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -763,14 +743,10 @@ export class WireSystem extends GameSystemWithFilter {
|
|||||||
if (targetStaticComp.rotation !== rotation || newType !== targetWireComp.type) {
|
if (targetStaticComp.rotation !== rotation || newType !== targetWireComp.type) {
|
||||||
// Change stuff
|
// Change stuff
|
||||||
targetStaticComp.rotation = rotation;
|
targetStaticComp.rotation = rotation;
|
||||||
metaWire.updateVariants(targetEntity, rotationVariant, defaultBuildingVariant);
|
metaWire.updateVariants(targetEntity, rotationVariant, variant);
|
||||||
|
|
||||||
// Update code as well
|
// Update code as well
|
||||||
targetStaticComp.code = getCodeFromBuildingData(
|
targetStaticComp.code = getCodeFromBuildingData(metaWire, variant, rotationVariant);
|
||||||
metaWire,
|
|
||||||
defaultBuildingVariant,
|
|
||||||
rotationVariant
|
|
||||||
);
|
|
||||||
|
|
||||||
// Make sure the chunks know about the update
|
// Make sure the chunks know about the update
|
||||||
this.root.signals.entityChanged.dispatch(targetEntity);
|
this.root.signals.entityChanged.dispatch(targetEntity);
|
||||||
|
@ -566,16 +566,18 @@ buildings:
|
|||||||
default:
|
default:
|
||||||
name: &wire Wire
|
name: &wire Wire
|
||||||
description: &wire_desc Allows to connect logical components and can transfer items, colors or boolean signals.
|
description: &wire_desc Allows to connect logical components and can transfer items, colors or boolean signals.
|
||||||
|
second:
|
||||||
|
name: Wire (Type 2)
|
||||||
|
description: &wire_desc_second Allows to connect logical components and can transfer items, colors or boolean signals. Different colored wires do not connect.
|
||||||
|
third:
|
||||||
|
name: Wire (Type 3)
|
||||||
|
description: *wire_desc_second
|
||||||
|
|
||||||
wire_tunnel:
|
wire_tunnel:
|
||||||
default:
|
default:
|
||||||
name: &wire_tunnel Wire Tunnel
|
name: &wire_tunnel Wire Tunnel
|
||||||
description: Allows to cross two wires without connecting them.
|
description: Allows to cross two wires without connecting them.
|
||||||
|
|
||||||
coating:
|
|
||||||
name: Wire Insulation
|
|
||||||
description: Allows to pass through signals without connecting to other wires on the sides.
|
|
||||||
|
|
||||||
constant_signal:
|
constant_signal:
|
||||||
default:
|
default:
|
||||||
name: &constant_signal Constant Signal
|
name: &constant_signal Constant Signal
|
||||||
@ -589,20 +591,25 @@ buildings:
|
|||||||
logic_gate:
|
logic_gate:
|
||||||
default:
|
default:
|
||||||
name: &logic_gate AND Gate
|
name: &logic_gate AND Gate
|
||||||
description: Emits a truthy boolean signal if both inputs are truthy.
|
description: Emits a boolean "1" if both inputs are truthy.
|
||||||
not:
|
not:
|
||||||
name: NOT
|
name: NOT Gate
|
||||||
description: Inverts the given signal.
|
description: Emits a boolean "1" if the input is not truthy.
|
||||||
xor:
|
xor:
|
||||||
name: XOR
|
name: XOR Gate
|
||||||
description: Emits a truthy signal if one of the inputs is truthy, but not both.
|
description: Emits a boolean "1" if one of the inputs is truthy, but not both.
|
||||||
or:
|
or:
|
||||||
name: OR
|
name: OR Gate
|
||||||
description: Emits a truthy signal if one of the inputs is truthy.
|
description: Emits a boolean "1" if one of the inputs is truthy.
|
||||||
|
|
||||||
transistor:
|
transistor:
|
||||||
name: Gate
|
default:
|
||||||
description: Only forwards the bottom input if the left input is true.
|
name: &transistor Gate
|
||||||
|
description: &transistor_desc Forwards the bottom input if the side input is truthy (a shape, color or "1").
|
||||||
|
|
||||||
|
mirrored:
|
||||||
|
name: *transistor
|
||||||
|
description: *transistor_desc
|
||||||
|
|
||||||
filter:
|
filter:
|
||||||
default:
|
default:
|
||||||
@ -619,14 +626,20 @@ buildings:
|
|||||||
name: &reader Belt Reader
|
name: &reader Belt Reader
|
||||||
description: Allows to measure belt throughput. Outputs the last read item on the wires layer (once unlocked).
|
description: Allows to measure belt throughput. Outputs the last read item on the wires layer (once unlocked).
|
||||||
|
|
||||||
|
analyzer:
|
||||||
|
default:
|
||||||
|
name: &analyzer Shape Analyzer
|
||||||
|
description: Analyzes the top right quadrant of the lowest layer of the shape and returns its shape and color.
|
||||||
|
|
||||||
|
comparator:
|
||||||
|
default:
|
||||||
|
name: &comparator Compare
|
||||||
|
description: Returns boolean "1" if both items are exactly equal. Can compare shapes, items and booleans.
|
||||||
|
|
||||||
virtual_processor:
|
virtual_processor:
|
||||||
default:
|
default:
|
||||||
name: &virtual_processor Virtual Cutter
|
name: &virtual_processor Virtual Cutter
|
||||||
description: Virtually cuts the shape input from top to bottom and returns both halfs.
|
description: Computes
|
||||||
|
|
||||||
analyzer:
|
|
||||||
name: Shape Analyzer
|
|
||||||
description: Analyzes the top right quadrant of the lowest layer of the shape and returns its shape and color
|
|
||||||
|
|
||||||
rotater:
|
rotater:
|
||||||
name: Virtual Rotater
|
name: Virtual Rotater
|
||||||
@ -636,10 +649,6 @@ buildings:
|
|||||||
name: Virtual Unstacker
|
name: Virtual Unstacker
|
||||||
description: Returns the topmost layer to the right, and the remaining ones on the left.
|
description: Returns the topmost layer to the right, and the remaining ones on the left.
|
||||||
|
|
||||||
shapecompare:
|
|
||||||
name: Compare
|
|
||||||
description: Returns true if both items are exactly equal. Can compare shapes, items and booleans.
|
|
||||||
|
|
||||||
stacker:
|
stacker:
|
||||||
name: Virtual Stacker
|
name: Virtual Stacker
|
||||||
description: Virtually stacks the right shape onto the left.
|
description: Virtually stacks the right shape onto the left.
|
||||||
@ -1040,6 +1049,9 @@ keybindings:
|
|||||||
display: *display
|
display: *display
|
||||||
reader: *reader
|
reader: *reader
|
||||||
virtual_processor: *virtual_processor
|
virtual_processor: *virtual_processor
|
||||||
|
transistor: *transistor
|
||||||
|
analyzer: *analyzer
|
||||||
|
comparator: *comparator
|
||||||
# ---
|
# ---
|
||||||
|
|
||||||
pipette: Pipette
|
pipette: Pipette
|
||||||
|