1
0
mirror of https://github.com/tobspr/shapez.io.git synced 2024-10-27 20:34:29 +00:00

Rebalance the whole game, rename splitter -> balancer

This commit is contained in:
tobspr 2020-09-22 14:47:59 +02:00
parent b0058cb59b
commit c6eb1dad04
42 changed files with 1005 additions and 981 deletions

View File

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

View File

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

View File

@ -336,6 +336,46 @@
"spriteSourceSize": {"x":4,"y":4,"w":44,"h":44}, "spriteSourceSize": {"x":4,"y":4,"w":44,"h":44},
"sourceSize": {"w":48,"h":48} "sourceSize": {"w":48,"h":48}
}, },
"sprites/blueprints/balancer-merger-inverse.png":
{
"frame": {"x":310,"y":112,"w":48,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
"sourceSize": {"w":48,"h":48}
},
"sprites/blueprints/balancer-merger.png":
{
"frame": {"x":208,"y":376,"w":47,"h":47},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":47,"h":47},
"sourceSize": {"w":48,"h":48}
},
"sprites/blueprints/balancer-splitter-inverse.png":
{
"frame": {"x":310,"y":166,"w":48,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
"sourceSize": {"w":48,"h":48}
},
"sprites/blueprints/balancer-splitter.png":
{
"frame": {"x":261,"y":376,"w":47,"h":47},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":47,"h":47},
"sourceSize": {"w":48,"h":48}
},
"sprites/blueprints/balancer.png":
{
"frame": {"x":770,"y":58,"w":87,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":87,"h":48},
"sourceSize": {"w":96,"h":48}
},
"sprites/blueprints/belt_left.png": "sprites/blueprints/belt_left.png":
{ {
"frame": {"x":305,"y":486,"w":44,"h":44}, "frame": {"x":305,"y":486,"w":44,"h":44},
@ -378,7 +418,7 @@
}, },
"sprites/blueprints/cutter.png": "sprites/blueprints/cutter.png":
{ {
"frame": {"x":770,"y":58,"w":87,"h":48}, "frame": {"x":863,"y":58,"w":87,"h":48},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":87,"h":48}, "spriteSourceSize": {"x":5,"y":0,"w":87,"h":48},
@ -434,7 +474,7 @@
}, },
"sprites/blueprints/logic_gate-xor.png": "sprites/blueprints/logic_gate-xor.png":
{ {
"frame": {"x":310,"y":112,"w":48,"h":48}, "frame": {"x":965,"y":4,"w":48,"h":48},
"rotated": false, "rotated": false,
"trimmed": false, "trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48}, "spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
@ -506,7 +546,7 @@
}, },
"sprites/blueprints/reader.png": "sprites/blueprints/reader.png":
{ {
"frame": {"x":310,"y":166,"w":48,"h":48}, "frame": {"x":956,"y":58,"w":48,"h":48},
"rotated": false, "rotated": false,
"trimmed": false, "trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48}, "spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
@ -514,7 +554,7 @@
}, },
"sprites/blueprints/rotater-ccw.png": "sprites/blueprints/rotater-ccw.png":
{ {
"frame": {"x":965,"y":4,"w":48,"h":48}, "frame": {"x":950,"y":112,"w":48,"h":48},
"rotated": false, "rotated": false,
"trimmed": false, "trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48}, "spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
@ -522,29 +562,13 @@
}, },
"sprites/blueprints/rotater-rotate180.png": "sprites/blueprints/rotater-rotate180.png":
{ {
"frame": {"x":956,"y":58,"w":48,"h":48}, "frame": {"x":950,"y":166,"w":48,"h":48},
"rotated": false, "rotated": false,
"trimmed": false, "trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48}, "spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
"sourceSize": {"w":48,"h":48} "sourceSize": {"w":48,"h":48}
}, },
"sprites/blueprints/rotater.png": "sprites/blueprints/rotater.png":
{
"frame": {"x":950,"y":112,"w":48,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
"sourceSize": {"w":48,"h":48}
},
"sprites/blueprints/splitter-compact-inverse.png":
{
"frame": {"x":950,"y":166,"w":48,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
"sourceSize": {"w":48,"h":48}
},
"sprites/blueprints/splitter-compact-merge-inverse.png":
{ {
"frame": {"x":582,"y":166,"w":48,"h":48}, "frame": {"x":582,"y":166,"w":48,"h":48},
"rotated": false, "rotated": false,
@ -552,30 +576,6 @@
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48}, "spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
"sourceSize": {"w":48,"h":48} "sourceSize": {"w":48,"h":48}
}, },
"sprites/blueprints/splitter-compact-merge.png":
{
"frame": {"x":208,"y":376,"w":47,"h":47},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":47,"h":47},
"sourceSize": {"w":48,"h":48}
},
"sprites/blueprints/splitter-compact.png":
{
"frame": {"x":261,"y":376,"w":47,"h":47},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":47,"h":47},
"sourceSize": {"w":48,"h":48}
},
"sprites/blueprints/splitter.png":
{
"frame": {"x":863,"y":58,"w":87,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":87,"h":48},
"sourceSize": {"w":96,"h":48}
},
"sprites/blueprints/stacker.png": "sprites/blueprints/stacker.png":
{ {
"frame": {"x":870,"y":4,"w":89,"h":48}, "frame": {"x":870,"y":4,"w":89,"h":48},
@ -736,6 +736,46 @@
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":47}, "spriteSourceSize": {"x":0,"y":0,"w":48,"h":47},
"sourceSize": {"w":48,"h":48} "sourceSize": {"w":48,"h":48}
}, },
"sprites/buildings/balancer-merger-inverse.png":
{
"frame": {"x":442,"y":249,"w":48,"h":47},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":47},
"sourceSize": {"w":48,"h":48}
},
"sprites/buildings/balancer-merger.png":
{
"frame": {"x":207,"y":429,"w":47,"h":47},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":47,"h":47},
"sourceSize": {"w":48,"h":48}
},
"sprites/buildings/balancer-splitter-inverse.png":
{
"frame": {"x":496,"y":249,"w":48,"h":47},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":47},
"sourceSize": {"w":48,"h":48}
},
"sprites/buildings/balancer-splitter.png":
{
"frame": {"x":260,"y":429,"w":47,"h":47},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":47,"h":47},
"sourceSize": {"w":48,"h":48}
},
"sprites/buildings/balancer.png":
{
"frame": {"x":582,"y":112,"w":87,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":87,"h":48},
"sourceSize": {"w":96,"h":48}
},
"sprites/buildings/belt_left.png": "sprites/buildings/belt_left.png":
{ {
"frame": {"x":487,"y":302,"w":44,"h":44}, "frame": {"x":487,"y":302,"w":44,"h":44},
@ -778,7 +818,7 @@
}, },
"sprites/buildings/cutter.png": "sprites/buildings/cutter.png":
{ {
"frame": {"x":582,"y":112,"w":87,"h":48}, "frame": {"x":675,"y":112,"w":87,"h":48},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":87,"h":48}, "spriteSourceSize": {"x":5,"y":0,"w":87,"h":48},
@ -944,46 +984,6 @@
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48}, "spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
"sourceSize": {"w":48,"h":48} "sourceSize": {"w":48,"h":48}
}, },
"sprites/buildings/splitter-compact-inverse.png":
{
"frame": {"x":442,"y":249,"w":48,"h":47},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":47},
"sourceSize": {"w":48,"h":48}
},
"sprites/buildings/splitter-compact-merge-inverse.png":
{
"frame": {"x":496,"y":249,"w":48,"h":47},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":47},
"sourceSize": {"w":48,"h":48}
},
"sprites/buildings/splitter-compact-merge.png":
{
"frame": {"x":207,"y":429,"w":47,"h":47},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":47,"h":47},
"sourceSize": {"w":48,"h":48}
},
"sprites/buildings/splitter-compact.png":
{
"frame": {"x":260,"y":429,"w":47,"h":47},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":47,"h":47},
"sourceSize": {"w":48,"h":48}
},
"sprites/buildings/splitter.png":
{
"frame": {"x":675,"y":112,"w":87,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":87,"h":48},
"sourceSize": {"w":96,"h":48}
},
"sprites/buildings/stacker.png": "sprites/buildings/stacker.png":
{ {
"frame": {"x":676,"y":58,"w":88,"h":48}, "frame": {"x":676,"y":58,"w":88,"h":48},
@ -1551,6 +1551,6 @@
"format": "RGBA8888", "format": "RGBA8888",
"size": {"w":1024,"h":1024}, "size": {"w":1024,"h":1024},
"scale": "0.25", "scale": "0.25",
"smartupdate": "$TexturePacker:SmartUpdate:6428a34334a71261053e6374332fbd0f:de76d600c9c903298cb6652e0ef02898:908b89f5ca8ff73e331a35a3b14d0604$" "smartupdate": "$TexturePacker:SmartUpdate:c57f50d18c59efc0edbd4a3a732323a4:3fcf23da2ddc6370c437cf41f6d44ed0:908b89f5ca8ff73e331a35a3b14d0604$"
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 279 KiB

After

Width:  |  Height:  |  Size: 281 KiB

View File

@ -336,6 +336,46 @@
"spriteSourceSize": {"x":9,"y":9,"w":87,"h":87}, "spriteSourceSize": {"x":9,"y":9,"w":87,"h":87},
"sourceSize": {"w":96,"h":96} "sourceSize": {"w":96,"h":96}
}, },
"sprites/blueprints/balancer-merger-inverse.png":
{
"frame": {"x":453,"y":1170,"w":95,"h":93},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":1,"w":95,"h":93},
"sourceSize": {"w":96,"h":96}
},
"sprites/blueprints/balancer-merger.png":
{
"frame": {"x":4,"y":1320,"w":93,"h":93},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":1,"w":93,"h":93},
"sourceSize": {"w":96,"h":96}
},
"sprites/blueprints/balancer-splitter-inverse.png":
{
"frame": {"x":348,"y":1180,"w":95,"h":93},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":1,"w":95,"h":93},
"sourceSize": {"w":96,"h":96}
},
"sprites/blueprints/balancer-splitter.png":
{
"frame": {"x":694,"y":1113,"w":93,"h":93},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":1,"w":93,"h":93},
"sourceSize": {"w":96,"h":96}
},
"sprites/blueprints/balancer.png":
{
"frame": {"x":184,"y":581,"w":172,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":11,"y":0,"w":172,"h":96},
"sourceSize": {"w":192,"h":96}
},
"sprites/blueprints/belt_left.png": "sprites/blueprints/belt_left.png":
{ {
"frame": {"x":479,"y":1639,"w":87,"h":87}, "frame": {"x":479,"y":1639,"w":87,"h":87},
@ -378,7 +418,7 @@
}, },
"sprites/blueprints/cutter.png": "sprites/blueprints/cutter.png":
{ {
"frame": {"x":184,"y":581,"w":172,"h":96}, "frame": {"x":362,"y":616,"w":172,"h":96},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":11,"y":0,"w":172,"h":96}, "spriteSourceSize": {"x":11,"y":0,"w":172,"h":96},
@ -536,46 +576,6 @@
"spriteSourceSize": {"x":0,"y":0,"w":96,"h":96}, "spriteSourceSize": {"x":0,"y":0,"w":96,"h":96},
"sourceSize": {"w":96,"h":96} "sourceSize": {"w":96,"h":96}
}, },
"sprites/blueprints/splitter-compact-inverse.png":
{
"frame": {"x":453,"y":1170,"w":95,"h":93},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":1,"w":95,"h":93},
"sourceSize": {"w":96,"h":96}
},
"sprites/blueprints/splitter-compact-merge-inverse.png":
{
"frame": {"x":348,"y":1180,"w":95,"h":93},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":1,"w":95,"h":93},
"sourceSize": {"w":96,"h":96}
},
"sprites/blueprints/splitter-compact-merge.png":
{
"frame": {"x":4,"y":1320,"w":93,"h":93},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":1,"w":93,"h":93},
"sourceSize": {"w":96,"h":96}
},
"sprites/blueprints/splitter-compact.png":
{
"frame": {"x":694,"y":1113,"w":93,"h":93},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":1,"w":93,"h":93},
"sourceSize": {"w":96,"h":96}
},
"sprites/blueprints/splitter.png":
{
"frame": {"x":362,"y":616,"w":172,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":11,"y":0,"w":172,"h":96},
"sourceSize": {"w":192,"h":96}
},
"sprites/blueprints/stacker.png": "sprites/blueprints/stacker.png":
{ {
"frame": {"x":185,"y":479,"w":175,"h":96}, "frame": {"x":185,"y":479,"w":175,"h":96},
@ -736,6 +736,46 @@
"spriteSourceSize": {"x":2,"y":2,"w":93,"h":91}, "spriteSourceSize": {"x":2,"y":2,"w":93,"h":91},
"sourceSize": {"w":96,"h":96} "sourceSize": {"w":96,"h":96}
}, },
"sprites/buildings/balancer-merger-inverse.png":
{
"frame": {"x":105,"y":1237,"w":94,"h":91},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":2,"w":94,"h":91},
"sourceSize": {"w":96,"h":96}
},
"sprites/buildings/balancer-merger.png":
{
"frame": {"x":554,"y":1174,"w":93,"h":91},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":2,"w":93,"h":91},
"sourceSize": {"w":96,"h":96}
},
"sprites/buildings/balancer-splitter-inverse.png":
{
"frame": {"x":246,"y":1183,"w":95,"h":91},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":2,"w":95,"h":91},
"sourceSize": {"w":96,"h":96}
},
"sprites/buildings/balancer-splitter.png":
{
"frame": {"x":449,"y":1269,"w":93,"h":91},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":2,"w":93,"h":91},
"sourceSize": {"w":96,"h":96}
},
"sprites/buildings/balancer.png":
{
"frame": {"x":740,"y":807,"w":171,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":11,"y":0,"w":171,"h":96},
"sourceSize": {"w":192,"h":96}
},
"sprites/buildings/belt_left.png": "sprites/buildings/belt_left.png":
{ {
"frame": {"x":200,"y":1441,"w":87,"h":87}, "frame": {"x":200,"y":1441,"w":87,"h":87},
@ -778,7 +818,7 @@
}, },
"sprites/buildings/cutter.png": "sprites/buildings/cutter.png":
{ {
"frame": {"x":740,"y":807,"w":171,"h":96}, "frame": {"x":4,"y":683,"w":171,"h":96},
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": true,
"spriteSourceSize": {"x":11,"y":0,"w":171,"h":96}, "spriteSourceSize": {"x":11,"y":0,"w":171,"h":96},
@ -944,46 +984,6 @@
"spriteSourceSize": {"x":1,"y":0,"w":95,"h":96}, "spriteSourceSize": {"x":1,"y":0,"w":95,"h":96},
"sourceSize": {"w":96,"h":96} "sourceSize": {"w":96,"h":96}
}, },
"sprites/buildings/splitter-compact-inverse.png":
{
"frame": {"x":105,"y":1237,"w":94,"h":91},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":2,"w":94,"h":91},
"sourceSize": {"w":96,"h":96}
},
"sprites/buildings/splitter-compact-merge-inverse.png":
{
"frame": {"x":246,"y":1183,"w":95,"h":91},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":2,"w":95,"h":91},
"sourceSize": {"w":96,"h":96}
},
"sprites/buildings/splitter-compact-merge.png":
{
"frame": {"x":554,"y":1174,"w":93,"h":91},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":2,"w":93,"h":91},
"sourceSize": {"w":96,"h":96}
},
"sprites/buildings/splitter-compact.png":
{
"frame": {"x":449,"y":1269,"w":93,"h":91},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":2,"w":93,"h":91},
"sourceSize": {"w":96,"h":96}
},
"sprites/buildings/splitter.png":
{
"frame": {"x":4,"y":683,"w":171,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":11,"y":0,"w":171,"h":96},
"sourceSize": {"w":192,"h":96}
},
"sprites/buildings/stacker.png": "sprites/buildings/stacker.png":
{ {
"frame": {"x":4,"y":581,"w":174,"h":96}, "frame": {"x":4,"y":581,"w":174,"h":96},
@ -1551,6 +1551,6 @@
"format": "RGBA8888", "format": "RGBA8888",
"size": {"w":1024,"h":2048}, "size": {"w":1024,"h":2048},
"scale": "0.5", "scale": "0.5",
"smartupdate": "$TexturePacker:SmartUpdate:6428a34334a71261053e6374332fbd0f:de76d600c9c903298cb6652e0ef02898:908b89f5ca8ff73e331a35a3b14d0604$" "smartupdate": "$TexturePacker:SmartUpdate:c57f50d18c59efc0edbd4a3a732323a4:3fcf23da2ddc6370c437cf41f6d44ed0:908b89f5ca8ff73e331a35a3b14d0604$"
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 697 KiB

After

Width:  |  Height:  |  Size: 700 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 47 KiB

View File

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

@ -1,4 +1,4 @@
$buildings: belt, cutter, miner, mixer, painter, rotater, splitter, 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; constant_signal, logic_gate, lever, filter, wire_tunnel, display, virtual_processor, reader;
@each $building in $buildings { @each $building in $buildings {
@ -7,7 +7,7 @@ $buildings: belt, cutter, miner, mixer, painter, rotater, splitter, stacker, tra
} }
} }
$buildingsAndVariants: belt, splitter, splitter-compact, splitter-compact-inverse, underground_belt, $buildingsAndVariants: belt, balancer, balancer-merger, balancer-splitter, underground_belt,
underground_belt-tier2, miner, miner-chainable, cutter, cutter-quad, rotater, rotater-ccw, rotater-fl, underground_belt-tier2, miner, miner-chainable, cutter, cutter-quad, rotater, rotater-ccw, rotater-fl,
stacker, mixer, painter, painter-double, painter-quad, trash, trash-storage; stacker, mixer, painter, painter-double, painter-quad, trash, trash-storage;
@each $building in $buildingsAndVariants { @each $building in $buildingsAndVariants {
@ -16,10 +16,18 @@ $buildingsAndVariants: belt, splitter, splitter-compact, splitter-compact-invers
} }
} }
// Special case // @TODO: New buildings (balancer, wires, etc)
// Special cases for mirrored vairants
[data-icon="building_tutorials/painter-mirrored.png"] { [data-icon="building_tutorials/painter-mirrored.png"] {
background-image: uiResource("res/ui/building_tutorials/painter.png") !important; background-image: uiResource("res/ui/building_tutorials/painter.png") !important;
} }
[data-icon="building_tutorials/balancer-merger-inverse.png"] {
background-image: uiResource("res/ui/building_tutorials/balancer-merger.png") !important;
}
[data-icon="building_tutorials/balancer-splitter-inverse.png"] {
background-image: uiResource("res/ui/building_tutorials/balancer-splitter.png") !important;
}
$icons: notification_saved, notification_success, notification_upgrade; $icons: notification_saved, notification_success, notification_upgrade;
@each $icon in $icons { @each $icon in $icons {

View File

@ -24,7 +24,7 @@ export const CHANGELOG = [
"Mark pinned shapes in statistics dialog and show them first (inspired by davidburhans)", "Mark pinned shapes in statistics dialog and show them first (inspired by davidburhans)",
"Added setting to show chunk borders", "Added setting to show chunk borders",
"Quad painters have been reworked! They now are integrated with the wires, and only paint the shape when the value is 1 (inspired by dengr1605)", "Quad painters have been reworked! They now are integrated with the wires, and only paint the shape when the value is 1 (inspired by dengr1605)",
"There are now compact 1x1 splitters available to be unlocked!", "There are now compact 1x1 balancers available to be unlocked!",
"Replaced level completion sound to be less distracting", "Replaced level completion sound to be less distracting",
"Allow editing waypoints (by isaisstillalive)", "Allow editing waypoints (by isaisstillalive)",
"Show confirmation when cutting area which is too expensive to get pasted again (by isaisstillalive)", "Show confirmation when cutting area which is too expensive to get pasted again (by isaisstillalive)",

View File

@ -11,29 +11,29 @@ import { formatItemsPerSecond } from "../../core/utils";
import { BeltUnderlaysComponent } from "../components/belt_underlays"; import { BeltUnderlaysComponent } from "../components/belt_underlays";
/** @enum {string} */ /** @enum {string} */
export const enumSplitterVariants = { export const enumBalancerVariants = {
compact: "compact", merger: "merger",
compactInverse: "compact-inverse", mergerInverse: "merger-inverse",
compactMerge: "compact-merge", splitter: "splitter",
compactMergeInverse: "compact-merge-inverse", splitterInverse: "splitter-inverse",
}; };
export class MetaSplitterBuilding extends MetaBuilding { export class MetaBalancerBuilding extends MetaBuilding {
constructor() { constructor() {
super("splitter"); super("balancer");
} }
getDimensions(variant) { getDimensions(variant) {
switch (variant) { switch (variant) {
case defaultBuildingVariant: case defaultBuildingVariant:
return new Vector(2, 1); return new Vector(2, 1);
case enumSplitterVariants.compact: case enumBalancerVariants.merger:
case enumSplitterVariants.compactInverse: case enumBalancerVariants.mergerInverse:
case enumSplitterVariants.compactMerge: case enumBalancerVariants.splitter:
case enumSplitterVariants.compactMergeInverse: case enumBalancerVariants.splitterInverse:
return new Vector(1, 1); return new Vector(1, 1);
default: default:
assertAlways(false, "Unknown splitter variant: " + variant); assertAlways(false, "Unknown balancer variant: " + variant);
} }
} }
@ -43,7 +43,7 @@ export class MetaSplitterBuilding extends MetaBuilding {
* @returns {Array<[string, string]>} * @returns {Array<[string, string]>}
*/ */
getAdditionalStatistics(root, variant) { getAdditionalStatistics(root, variant) {
const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.splitter); const speed = root.hubGoals.getProcessorBaseSpeed(enumItemProcessorTypes.balancer);
return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]]; return [[T.ingame.buildingPlacement.infoTexts.speed, formatItemsPerSecond(speed)]];
} }
@ -57,12 +57,12 @@ export class MetaSplitterBuilding extends MetaBuilding {
getAvailableVariants(root) { getAvailableVariants(root) {
let available = [defaultBuildingVariant]; let available = [defaultBuildingVariant];
if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_splitter_compact)) { if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_merger)) {
available.push(enumSplitterVariants.compact, enumSplitterVariants.compactInverse); available.push(enumBalancerVariants.merger, enumBalancerVariants.mergerInverse);
} }
if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_merger_compact)) { if (root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_splitter)) {
available.push(enumSplitterVariants.compactMerge, enumSplitterVariants.compactMergeInverse); available.push(enumBalancerVariants.splitter, enumBalancerVariants.splitterInverse);
} }
return available; return available;
@ -72,7 +72,7 @@ export class MetaSplitterBuilding extends MetaBuilding {
* @param {GameRoot} root * @param {GameRoot} root
*/ */
getIsUnlocked(root) { getIsUnlocked(root) {
return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_splitter); return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_balancer);
} }
/** /**
@ -89,7 +89,7 @@ export class MetaSplitterBuilding extends MetaBuilding {
entity.addComponent( entity.addComponent(
new ItemProcessorComponent({ new ItemProcessorComponent({
inputsPerCharge: 1, inputsPerCharge: 1,
processorType: enumItemProcessorTypes.splitter, processorType: enumItemProcessorTypes.balancer,
}) })
); );
@ -135,8 +135,8 @@ export class MetaSplitterBuilding extends MetaBuilding {
break; break;
} }
case enumSplitterVariants.compact: case enumBalancerVariants.merger:
case enumSplitterVariants.compactInverse: { case enumBalancerVariants.mergerInverse: {
entity.components.ItemAcceptor.setSlots([ entity.components.ItemAcceptor.setSlots([
{ {
pos: new Vector(0, 0), pos: new Vector(0, 0),
@ -145,7 +145,7 @@ export class MetaSplitterBuilding extends MetaBuilding {
{ {
pos: new Vector(0, 0), pos: new Vector(0, 0),
directions: [ directions: [
variant === enumSplitterVariants.compactInverse variant === enumBalancerVariants.mergerInverse
? enumDirection.left ? enumDirection.left
: enumDirection.right, : enumDirection.right,
], ],
@ -162,8 +162,8 @@ export class MetaSplitterBuilding extends MetaBuilding {
break; break;
} }
case enumSplitterVariants.compactMerge: case enumBalancerVariants.splitter:
case enumSplitterVariants.compactMergeInverse: { case enumBalancerVariants.splitterInverse: {
entity.components.ItemAcceptor.setSlots([ entity.components.ItemAcceptor.setSlots([
{ {
pos: new Vector(0, 0), pos: new Vector(0, 0),
@ -179,7 +179,7 @@ export class MetaSplitterBuilding extends MetaBuilding {
{ {
pos: new Vector(0, 0), pos: new Vector(0, 0),
direction: direction:
variant === enumSplitterVariants.compactMergeInverse variant === enumBalancerVariants.splitterInverse
? enumDirection.left ? enumDirection.left
: enumDirection.right, : enumDirection.right,
}, },
@ -192,7 +192,7 @@ export class MetaSplitterBuilding extends MetaBuilding {
break; break;
} }
default: default:
assertAlways(false, "Unknown splitter variant: " + variant); assertAlways(false, "Unknown balancer variant: " + variant);
} }
} }
} }

View File

@ -895,7 +895,7 @@ export class Camera extends BasicSerializableObject {
return; return;
} }
const panAreaPixels = Math.min(this.root.gameWidth, this.root.gameHeight) * 0.015; const panAreaPixels = 2;
const panVelocity = new Vector(); const panVelocity = new Vector();
if (mousePos.x < panAreaPixels) { if (mousePos.x < panAreaPixels) {

View File

@ -4,7 +4,7 @@ import { Component } from "../component";
/** @enum {string} */ /** @enum {string} */
export const enumItemProcessorTypes = { export const enumItemProcessorTypes = {
splitter: "splitter", balancer: "balancer",
cutter: "cutter", cutter: "cutter",
cutterQuad: "cutterQuad", cutterQuad: "cutterQuad",
rotater: "rotater", rotater: "rotater",
@ -57,14 +57,14 @@ export class ItemProcessorComponent extends Component {
* *
*/ */
constructor({ constructor({
processorType = enumItemProcessorTypes.splitter, processorType = enumItemProcessorTypes.balancer,
processingRequirement = null, processingRequirement = null,
inputsPerCharge = 1, inputsPerCharge = 1,
}) { }) {
super(); super();
// Which slot to emit next, this is only a preference and if it can't emit // Which slot to emit next, this is only a preference and if it can't emit
// it will take the other one. Some machines ignore this (e.g. the splitter) to make // it will take the other one. Some machines ignore this (e.g. the balancer) to make
// sure the outputs always match // sure the outputs always match
this.nextOutputSlot = 0; this.nextOutputSlot = 0;

View File

@ -43,11 +43,11 @@ export class HubGoals extends BasicSerializableObject {
// Compute upgrade improvements // Compute upgrade improvements
for (const upgradeId in UPGRADES) { for (const upgradeId in UPGRADES) {
const upgradeHandle = UPGRADES[upgradeId]; const tiers = UPGRADES[upgradeId];
const level = this.upgradeLevels[upgradeId] || 0; const level = this.upgradeLevels[upgradeId] || 0;
let totalImprovement = upgradeHandle.baseValue || 1; let totalImprovement = 1;
for (let i = 0; i < level; ++i) { for (let i = 0; i < level; ++i) {
totalImprovement += upgradeHandle.tiers[i].improvement; totalImprovement += tiers[i].improvement;
} }
this.upgradeImprovements[upgradeId] = totalImprovement; this.upgradeImprovements[upgradeId] = totalImprovement;
} }
@ -98,7 +98,7 @@ export class HubGoals extends BasicSerializableObject {
*/ */
this.upgradeImprovements = {}; this.upgradeImprovements = {};
for (const key in UPGRADES) { for (const key in UPGRADES) {
this.upgradeImprovements[key] = UPGRADES[key].baseValue || 1; this.upgradeImprovements[key] = 1;
} }
this.createNextGoal(); this.createNextGoal();
@ -212,7 +212,7 @@ export class HubGoals extends BasicSerializableObject {
this.currentGoal = { this.currentGoal = {
/** @type {ShapeDefinition} */ /** @type {ShapeDefinition} */
definition: this.createRandomShape(), definition: this.createRandomShape(),
required: 10000 + findNiceIntegerValue(this.level * 2000), required: findNiceIntegerValue(5000 + Math.pow(this.level * 2000, 0.75)),
reward: enumHubGoalRewards.no_reward_freeplay, reward: enumHubGoalRewards.no_reward_freeplay,
}; };
} }
@ -243,10 +243,10 @@ export class HubGoals extends BasicSerializableObject {
* @param {string} upgradeId * @param {string} upgradeId
*/ */
canUnlockUpgrade(upgradeId) { canUnlockUpgrade(upgradeId) {
const handle = UPGRADES[upgradeId]; const tiers = UPGRADES[upgradeId];
const currentLevel = this.getUpgradeLevel(upgradeId); const currentLevel = this.getUpgradeLevel(upgradeId);
if (currentLevel >= handle.tiers.length) { if (currentLevel >= tiers.length) {
// Max level // Max level
return false; return false;
} }
@ -255,7 +255,7 @@ export class HubGoals extends BasicSerializableObject {
return true; return true;
} }
const tierData = handle.tiers[currentLevel]; const tierData = tiers[currentLevel];
for (let i = 0; i < tierData.required.length; ++i) { for (let i = 0; i < tierData.required.length; ++i) {
const requirement = tierData.required[i]; const requirement = tierData.required[i];
@ -290,10 +290,10 @@ export class HubGoals extends BasicSerializableObject {
return false; return false;
} }
const handle = UPGRADES[upgradeId]; const upgradeTiers = UPGRADES[upgradeId];
const currentLevel = this.getUpgradeLevel(upgradeId); const currentLevel = this.getUpgradeLevel(upgradeId);
const tierData = handle.tiers[currentLevel]; const tierData = upgradeTiers[currentLevel];
if (!tierData) { if (!tierData) {
return false; return false;
} }
@ -399,7 +399,7 @@ export class HubGoals extends BasicSerializableObject {
case enumItemProcessorTypes.trash: case enumItemProcessorTypes.trash:
case enumItemProcessorTypes.hub: case enumItemProcessorTypes.hub:
return 1e30; return 1e30;
case enumItemProcessorTypes.splitter: case enumItemProcessorTypes.balancer:
return globalConfig.beltSpeedItemsPerSecond * this.upgradeImprovements.belt * 2; return globalConfig.beltSpeedItemsPerSecond * this.upgradeImprovements.belt * 2;
case enumItemProcessorTypes.reader: case enumItemProcessorTypes.reader:
return globalConfig.beltSpeedItemsPerSecond * this.upgradeImprovements.belt; return globalConfig.beltSpeedItemsPerSecond * this.upgradeImprovements.belt;

View File

@ -8,7 +8,7 @@ import { MetaMixerBuilding } from "../../buildings/mixer";
import { MetaPainterBuilding } from "../../buildings/painter"; import { MetaPainterBuilding } from "../../buildings/painter";
import { MetaReaderBuilding } from "../../buildings/reader"; import { MetaReaderBuilding } from "../../buildings/reader";
import { MetaRotaterBuilding } from "../../buildings/rotater"; import { MetaRotaterBuilding } from "../../buildings/rotater";
import { MetaSplitterBuilding } from "../../buildings/splitter"; import { MetaBalancerBuilding } from "../../buildings/balancer";
import { MetaStackerBuilding } from "../../buildings/stacker"; import { MetaStackerBuilding } from "../../buildings/stacker";
import { MetaTrashBuilding } from "../../buildings/trash"; import { MetaTrashBuilding } from "../../buildings/trash";
import { MetaUndergroundBeltBuilding } from "../../buildings/underground_belt"; import { MetaUndergroundBeltBuilding } from "../../buildings/underground_belt";
@ -16,7 +16,7 @@ import { HUDBaseToolbar } from "./base_toolbar";
const supportedBuildings = [ const supportedBuildings = [
MetaBeltBuilding, MetaBeltBuilding,
MetaSplitterBuilding, MetaBalancerBuilding,
MetaUndergroundBeltBuilding, MetaUndergroundBeltBuilding,
MetaMinerBuilding, MetaMinerBuilding,
MetaCutterBuilding, MetaCutterBuilding,

View File

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

View File

@ -89,8 +89,8 @@ export class HUDSandboxController extends BaseHUDPart {
} }
modifyUpgrade(id, amount) { modifyUpgrade(id, amount) {
const handle = UPGRADES[id]; const upgradeTiers = UPGRADES[id];
const maxLevel = handle.tiers.length; const maxLevel = upgradeTiers.length;
this.root.hubGoals.upgradeLevels[id] = Math.max( this.root.hubGoals.upgradeLevels[id] = Math.max(
0, 0,
@ -100,7 +100,7 @@ export class HUDSandboxController extends BaseHUDPart {
// Compute improvement // Compute improvement
let improvement = 1; let improvement = 1;
for (let i = 0; i < this.root.hubGoals.upgradeLevels[id]; ++i) { for (let i = 0; i < this.root.hubGoals.upgradeLevels[id]; ++i) {
improvement += handle.tiers[i].improvement; improvement += upgradeTiers[i].improvement;
} }
this.root.hubGoals.upgradeImprovements[id] = improvement; this.root.hubGoals.upgradeImprovements[id] = improvement;
this.root.signals.upgradePurchased.dispatch(id); this.root.signals.upgradePurchased.dispatch(id);

View File

@ -59,11 +59,11 @@ export class HUDShop extends BaseHUDPart {
rerenderFull() { rerenderFull() {
for (const upgradeId in this.upgradeToElements) { for (const upgradeId in this.upgradeToElements) {
const handle = this.upgradeToElements[upgradeId]; const handle = this.upgradeToElements[upgradeId];
const { tiers } = UPGRADES[upgradeId]; const upgradeTiers = UPGRADES[upgradeId];
const currentTier = this.root.hubGoals.getUpgradeLevel(upgradeId); const currentTier = this.root.hubGoals.getUpgradeLevel(upgradeId);
const currentTierMultiplier = this.root.hubGoals.upgradeImprovements[upgradeId]; const currentTierMultiplier = this.root.hubGoals.upgradeImprovements[upgradeId];
const tierHandle = tiers[currentTier]; const tierHandle = upgradeTiers[currentTier];
// Set tier // Set tier
handle.elemTierLabel.innerText = T.ingame.shop.tier.replace( handle.elemTierLabel.innerText = T.ingame.shop.tier.replace(

View File

@ -45,7 +45,7 @@ export const KEYMAPPINGS = {
buildings: { buildings: {
belt: { keyCode: key("1") }, belt: { keyCode: key("1") },
splitter: { keyCode: key("2") }, balancer: { keyCode: key("2") },
underground_belt: { keyCode: key("3") }, underground_belt: { keyCode: key("3") },
miner: { keyCode: key("4") }, miner: { keyCode: key("4") },
cutter: { keyCode: key("5") }, cutter: { keyCode: key("5") },

View File

@ -7,7 +7,7 @@ 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 { enumRotaterVariants, MetaRotaterBuilding } from "./buildings/rotater"; import { enumRotaterVariants, MetaRotaterBuilding } from "./buildings/rotater";
import { enumSplitterVariants, MetaSplitterBuilding } from "./buildings/splitter"; import { enumBalancerVariants, MetaBalancerBuilding } from "./buildings/balancer";
import { MetaStackerBuilding } from "./buildings/stacker"; import { MetaStackerBuilding } from "./buildings/stacker";
import { enumTrashVariants, MetaTrashBuilding } from "./buildings/trash"; import { enumTrashVariants, MetaTrashBuilding } from "./buildings/trash";
import { enumUndergroundBeltVariants, MetaUndergroundBeltBuilding } from "./buildings/underground_belt"; import { enumUndergroundBeltVariants, MetaUndergroundBeltBuilding } from "./buildings/underground_belt";
@ -26,7 +26,7 @@ import { MetaReaderBuilding } from "./buildings/reader";
const logger = createLogger("building_registry"); const logger = createLogger("building_registry");
export function initMetaBuildingRegistry() { export function initMetaBuildingRegistry() {
gMetaBuildingRegistry.register(MetaSplitterBuilding); gMetaBuildingRegistry.register(MetaBalancerBuilding);
gMetaBuildingRegistry.register(MetaMinerBuilding); gMetaBuildingRegistry.register(MetaMinerBuilding);
gMetaBuildingRegistry.register(MetaCutterBuilding); gMetaBuildingRegistry.register(MetaCutterBuilding);
gMetaBuildingRegistry.register(MetaRotaterBuilding); gMetaBuildingRegistry.register(MetaRotaterBuilding);
@ -52,12 +52,12 @@ export function initMetaBuildingRegistry() {
registerBuildingVariant(2, MetaBeltBuilding, defaultBuildingVariant, 1); registerBuildingVariant(2, MetaBeltBuilding, defaultBuildingVariant, 1);
registerBuildingVariant(3, MetaBeltBuilding, defaultBuildingVariant, 2); registerBuildingVariant(3, MetaBeltBuilding, defaultBuildingVariant, 2);
// Splitter // Balancer
registerBuildingVariant(4, MetaSplitterBuilding); registerBuildingVariant(4, MetaBalancerBuilding);
registerBuildingVariant(5, MetaSplitterBuilding, enumSplitterVariants.compact); registerBuildingVariant(5, MetaBalancerBuilding, enumBalancerVariants.merger);
registerBuildingVariant(6, MetaSplitterBuilding, enumSplitterVariants.compactInverse); registerBuildingVariant(6, MetaBalancerBuilding, enumBalancerVariants.mergerInverse);
registerBuildingVariant(47, MetaSplitterBuilding, enumSplitterVariants.compactMerge); registerBuildingVariant(47, MetaBalancerBuilding, enumBalancerVariants.splitter);
registerBuildingVariant(48, MetaSplitterBuilding, enumSplitterVariants.compactMergeInverse); registerBuildingVariant(48, MetaBalancerBuilding, enumBalancerVariants.splitterInverse);
// Miner // Miner
registerBuildingVariant(7, MetaMinerBuilding); registerBuildingVariant(7, MetaMinerBuilding);

View File

@ -45,7 +45,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
* @type {Object<enumItemProcessorTypes, function(ProcessorImplementationPayload) : string>} * @type {Object<enumItemProcessorTypes, function(ProcessorImplementationPayload) : string>}
*/ */
this.handlers = { this.handlers = {
[enumItemProcessorTypes.splitter]: this.process_SPLITTER, [enumItemProcessorTypes.balancer]: this.process_BALANCER,
[enumItemProcessorTypes.cutter]: this.process_CUTTER, [enumItemProcessorTypes.cutter]: this.process_CUTTER,
[enumItemProcessorTypes.cutterQuad]: this.process_CUTTER_QUAD, [enumItemProcessorTypes.cutterQuad]: this.process_CUTTER_QUAD,
[enumItemProcessorTypes.rotater]: this.process_ROTATER, [enumItemProcessorTypes.rotater]: this.process_ROTATER,
@ -305,8 +305,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
/** /**
* @param {ProcessorImplementationPayload} payload * @param {ProcessorImplementationPayload} payload
*/ */
process_SPLITTER(payload) { process_BALANCER(payload) {
// trackProduction = false;
const availableSlots = payload.entity.components.ItemEjector.slots.length; const availableSlots = payload.entity.components.ItemEjector.slots.length;
const processorComp = payload.entity.components.ItemProcessor; const processorComp = payload.entity.components.ItemProcessor;

View File

@ -11,21 +11,19 @@ export const enumHubGoalRewards = {
reward_painter: "reward_painter", reward_painter: "reward_painter",
reward_mixer: "reward_mixer", reward_mixer: "reward_mixer",
reward_stacker: "reward_stacker", reward_stacker: "reward_stacker",
reward_splitter: "reward_splitter", reward_balancer: "reward_balancer",
reward_tunnel: "reward_tunnel", reward_tunnel: "reward_tunnel",
reward_rotater_ccw: "reward_rotater_ccw", reward_rotater_ccw: "reward_rotater_ccw",
reward_rotater_180: "reward_rotater_fl", reward_rotater_180: "reward_rotater_180",
reward_miner_chainable: "reward_miner_chainable", reward_miner_chainable: "reward_miner_chainable",
reward_underground_belt_tier_2: "reward_underground_belt_tier_2", reward_underground_belt_tier_2: "reward_underground_belt_tier_2",
reward_splitter_compact: "reward_splitter_compact", reward_splitter: "reward_splitter",
reward_cutter_quad: "reward_cutter_quad", reward_cutter_quad: "reward_cutter_quad",
reward_painter_double: "reward_painter_double", reward_painter_double: "reward_painter_double",
reward_painter_quad: "reward_painter_quad", reward_painter_quad: "reward_painter_quad",
reward_storage: "reward_storage", reward_storage: "reward_storage",
reward_merger: "reward_merger",
// @todo: unlock
reward_merger_compact: "reward_compact_merger",
reward_blueprints: "reward_blueprints", reward_blueprints: "reward_blueprints",
reward_freeplay: "reward_freeplay", reward_freeplay: "reward_freeplay",
@ -55,14 +53,14 @@ export const tutorialGoals = [
// Rectangle // Rectangle
{ {
shape: "RuRuRuRu", // miners t1 shape: "RuRuRuRu", // miners t1
required: 100, required: 85,
reward: enumHubGoalRewards.reward_splitter, reward: enumHubGoalRewards.reward_balancer,
}, },
// 4 // 4
{ {
shape: "RuRu----", // processors t2 shape: "RuRu----", // processors t2
required: 120, required: 100,
reward: enumHubGoalRewards.reward_rotater, reward: enumHubGoalRewards.reward_rotater,
}, },
@ -70,14 +68,14 @@ export const tutorialGoals = [
// Rotater // Rotater
{ {
shape: "Cu----Cu", // belts t2 shape: "Cu----Cu", // belts t2
required: 200, required: 175,
reward: enumHubGoalRewards.reward_tunnel, reward: enumHubGoalRewards.reward_tunnel,
}, },
// 6 // 6
{ {
shape: "Cu------", // miners t2 shape: "Cu------", // miners t2
required: 400, required: 250,
reward: enumHubGoalRewards.reward_painter, reward: enumHubGoalRewards.reward_painter,
}, },
@ -85,14 +83,14 @@ export const tutorialGoals = [
// Painter // Painter
{ {
shape: "CrCrCrCr", // unused shape: "CrCrCrCr", // unused
required: 800, required: 500,
reward: enumHubGoalRewards.reward_rotater_ccw, reward: enumHubGoalRewards.reward_rotater_ccw,
}, },
// 8 // 8
{ {
shape: "RbRb----", // painter t2 shape: "RbRb----", // painter t2
required: 1000, required: 700,
reward: enumHubGoalRewards.reward_mixer, reward: enumHubGoalRewards.reward_mixer,
}, },
@ -100,15 +98,15 @@ export const tutorialGoals = [
// Mixing (purple) // Mixing (purple)
{ {
shape: "CpCpCpCp", // belts t3 shape: "CpCpCpCp", // belts t3
required: 1400, required: 800,
reward: enumHubGoalRewards.reward_splitter_compact, reward: enumHubGoalRewards.reward_splitter,
}, },
// 10 // 10
// Star shape + cyan // Star shape + cyan
{ {
shape: "ScScScSc", // miners t3 shape: "ScScScSc", // miners t3
required: 1600, required: 900,
reward: enumHubGoalRewards.reward_stacker, reward: enumHubGoalRewards.reward_stacker,
}, },
@ -116,7 +114,7 @@ export const tutorialGoals = [
// Stacker // Stacker
{ {
shape: "CgScScCg", // processors t3 shape: "CgScScCg", // processors t3
required: 1800, required: 1000,
reward: enumHubGoalRewards.reward_miner_chainable, reward: enumHubGoalRewards.reward_miner_chainable,
}, },
@ -124,49 +122,56 @@ export const tutorialGoals = [
// Blueprints // Blueprints
{ {
shape: "CbCbCbRb:CwCwCwCw", shape: "CbCbCbRb:CwCwCwCw",
required: 2000, required: 1250,
reward: enumHubGoalRewards.reward_blueprints, reward: enumHubGoalRewards.reward_blueprints,
}, },
// 13 // 13
{ {
shape: "RpRpRpRp:CwCwCwCw", // painting t3 shape: "RpRpRpRp:CwCwCwCw", // painting t3
required: 12000, required: 5000,
reward: enumHubGoalRewards.reward_underground_belt_tier_2, reward: enumHubGoalRewards.reward_underground_belt_tier_2,
}, },
// 14 // 14
{ {
shape: "SrSrSrSr:CyCyCyCy", // unused shape: "SrSrSrSr:CyCyCyCy", // unused
required: 16000, required: 7500,
reward: enumHubGoalRewards.reward_storage, reward: enumHubGoalRewards.reward_storage,
}, },
// 15 // 15
{ {
shape: "SrSrSrSr:CyCyCyCy:SwSwSwSw", // belts t4 (two variants) shape: "SrSrSrSr:CyCyCyCy:SwSwSwSw", // belts t4 (two variants)
required: 25000, required: 15000,
reward: enumHubGoalRewards.reward_cutter_quad, reward: enumHubGoalRewards.reward_cutter_quad,
}, },
// 16 // 16
{ {
shape: "CbRbRbCb:CwCwCwCw:WbWbWbWb", // miner t4 (two variants) shape: "CbRbRbCb:CwCwCwCw:WbWbWbWb", // miner t4 (two variants)
required: 50000, required: 20000,
reward: enumHubGoalRewards.reward_painter_double, reward: enumHubGoalRewards.reward_painter_double,
}, },
// 17 // 17
{ {
shape: "WrRgWrRg:CwCrCwCr:SgSgSgSg", // processors t4 (two variants) shape: "CbRbRbCb:CwCwCwCw:WbWbWbWb", // rotater 180
required: 120000, required: 25000,
reward: enumHubGoalRewards.reward_painter_quad, reward: enumHubGoalRewards.reward_rotater_180,
}, },
// 18 // 18
{
shape: "WrRgWrRg:CwCrCwCr:SgSgSgSg", // processors t4 (two variants)
required: 30000,
reward: enumHubGoalRewards.reward_painter_quad,
},
// 19
{ {
shape: finalGameShape, shape: finalGameShape,
required: 250000, required: 50000,
reward: enumHubGoalRewards.reward_freeplay, reward: enumHubGoalRewards.reward_freeplay,
}, },
]; ];

View File

@ -4,7 +4,7 @@ import { MetaRotaterBuilding, enumRotaterVariants } from "./buildings/rotater";
import { MetaPainterBuilding, enumPainterVariants } from "./buildings/painter"; import { MetaPainterBuilding, enumPainterVariants } from "./buildings/painter";
import { MetaMixerBuilding } from "./buildings/mixer"; import { MetaMixerBuilding } from "./buildings/mixer";
import { MetaStackerBuilding } from "./buildings/stacker"; import { MetaStackerBuilding } from "./buildings/stacker";
import { MetaSplitterBuilding, enumSplitterVariants } from "./buildings/splitter"; import { MetaBalancerBuilding, enumBalancerVariants } from "./buildings/balancer";
import { MetaUndergroundBeltBuilding, enumUndergroundBeltVariants } from "./buildings/underground_belt"; import { MetaUndergroundBeltBuilding, enumUndergroundBeltVariants } from "./buildings/underground_belt";
import { MetaMinerBuilding, enumMinerVariants } from "./buildings/miner"; import { MetaMinerBuilding, enumMinerVariants } from "./buildings/miner";
import { MetaTrashBuilding, enumTrashVariants } from "./buildings/trash"; import { MetaTrashBuilding, enumTrashVariants } from "./buildings/trash";
@ -29,7 +29,7 @@ export const enumHubGoalRewardsToContentUnlocked = {
[enumHubGoalRewards.reward_painter]: typed([[MetaPainterBuilding, defaultBuildingVariant]]), [enumHubGoalRewards.reward_painter]: typed([[MetaPainterBuilding, defaultBuildingVariant]]),
[enumHubGoalRewards.reward_mixer]: typed([[MetaMixerBuilding, defaultBuildingVariant]]), [enumHubGoalRewards.reward_mixer]: typed([[MetaMixerBuilding, defaultBuildingVariant]]),
[enumHubGoalRewards.reward_stacker]: typed([[MetaStackerBuilding, defaultBuildingVariant]]), [enumHubGoalRewards.reward_stacker]: typed([[MetaStackerBuilding, defaultBuildingVariant]]),
[enumHubGoalRewards.reward_splitter]: typed([[MetaSplitterBuilding, defaultBuildingVariant]]), [enumHubGoalRewards.reward_balancer]: typed([[MetaBalancerBuilding, defaultBuildingVariant]]),
[enumHubGoalRewards.reward_tunnel]: typed([[MetaUndergroundBeltBuilding, defaultBuildingVariant]]), [enumHubGoalRewards.reward_tunnel]: typed([[MetaUndergroundBeltBuilding, defaultBuildingVariant]]),
[enumHubGoalRewards.reward_rotater_ccw]: typed([[MetaRotaterBuilding, enumRotaterVariants.ccw]]), [enumHubGoalRewards.reward_rotater_ccw]: typed([[MetaRotaterBuilding, enumRotaterVariants.ccw]]),
@ -38,9 +38,8 @@ export const enumHubGoalRewardsToContentUnlocked = {
[enumHubGoalRewards.reward_underground_belt_tier_2]: typed([ [enumHubGoalRewards.reward_underground_belt_tier_2]: typed([
[MetaUndergroundBeltBuilding, enumUndergroundBeltVariants.tier2], [MetaUndergroundBeltBuilding, enumUndergroundBeltVariants.tier2],
]), ]),
[enumHubGoalRewards.reward_splitter_compact]: typed([ [enumHubGoalRewards.reward_splitter]: typed([[MetaBalancerBuilding, enumBalancerVariants.splitter]]),
[MetaSplitterBuilding, enumSplitterVariants.compact], [enumHubGoalRewards.reward_merger]: typed([[MetaBalancerBuilding, enumBalancerVariants.merger]]),
]),
[enumHubGoalRewards.reward_cutter_quad]: typed([[MetaCutterBuilding, enumCutterVariants.quad]]), [enumHubGoalRewards.reward_cutter_quad]: typed([[MetaCutterBuilding, enumCutterVariants.quad]]),
[enumHubGoalRewards.reward_painter_double]: typed([[MetaPainterBuilding, enumPainterVariants.double]]), [enumHubGoalRewards.reward_painter_double]: typed([[MetaPainterBuilding, enumPainterVariants.double]]),
[enumHubGoalRewards.reward_painter_quad]: typed([[MetaPainterBuilding, enumPainterVariants.quad]]), [enumHubGoalRewards.reward_painter_quad]: typed([[MetaPainterBuilding, enumPainterVariants.quad]]),

View File

@ -1,175 +1,160 @@
import { findNiceIntegerValue } from "../core/utils"; import { findNiceIntegerValue } from "../core/utils";
import { ShapeDefinition } from "./shape_definition"; import { ShapeDefinition } from "./shape_definition";
export const finalGameShape = "RuCw--Cw:----Ru--"; export const finalGameShape = "RuCw--Cw:----Ru--";
export const blueprintShape = "CbCbCbRb:CwCwCwCw"; export const blueprintShape = "CbCbCbRb:CwCwCwCw";
export const UPGRADES = { const fixedImprovements = [0.5, 0.5, 1, 1, 2, 2];
belt: {
tiers: [ /** @typedef {{
{ * shape: string,
required: [{ shape: "CuCuCuCu", amount: 150 }], * amount: number
improvement: 1, * }} UpgradeRequirement */
},
{ /** @typedef {{
required: [{ shape: "--CuCu--", amount: 1200 }], * required: Array<UpgradeRequirement>
improvement: 2, * improvement?: number,
}, * excludePrevious?: boolean
{ * }} TierRequirement */
required: [{ shape: "CpCpCpCp", amount: 15000 }],
improvement: 2, /** @typedef {Array<TierRequirement>} UpgradeTiers */
},
{ /** @type {Object<string, UpgradeTiers>} */
required: [{ shape: "SrSrSrSr:CyCyCyCy", amount: 40000 }], export const UPGRADES = {
improvement: 2, belt: [
}, {
{ required: [{ shape: "CuCuCuCu", amount: 150 }],
required: [{ shape: "SrSrSrSr:CyCyCyCy:SwSwSwSw", amount: 40000 }], },
improvement: 2, {
}, required: [{ shape: "--CuCu--", amount: 1000 }],
{ },
required: [{ shape: finalGameShape, amount: 150000 }], {
improvement: 5, required: [{ shape: "CpCpCpCp", amount: 5000 }],
excludePrevious: true, },
}, {
], required: [{ shape: "SrSrSrSr:CyCyCyCy", amount: 12000 }],
}, },
{
miner: { required: [{ shape: "SrSrSrSr:CyCyCyCy:SwSwSwSw", amount: 20000 }],
tiers: [ },
{ {
required: [{ shape: "RuRuRuRu", amount: 400 }], required: [{ shape: finalGameShape, amount: 75000 }],
improvement: 1, excludePrevious: true,
}, },
{ ],
required: [{ shape: "Cu------", amount: 4000 }],
improvement: 2, miner: [
}, {
{ required: [{ shape: "RuRuRuRu", amount: 400 }],
required: [{ shape: "ScScScSc", amount: 20000 }], },
improvement: 2, {
}, required: [{ shape: "Cu------", amount: 3000 }],
{ },
required: [{ shape: "CwCwCwCw:WbWbWbWb", amount: 40000 }], {
improvement: 2, required: [{ shape: "ScScScSc", amount: 7000 }],
}, },
{ {
required: [{ shape: "CbRbRbCb:CwCwCwCw:WbWbWbWb", amount: 40000 }], required: [{ shape: "CwCwCwCw:WbWbWbWb", amount: 15000 }],
improvement: 2, },
}, {
{ required: [{ shape: "CbRbRbCb:CwCwCwCw:WbWbWbWb", amount: 30000 }],
required: [{ shape: finalGameShape, amount: 150000 }], },
improvement: 5, {
excludePrevious: true, required: [{ shape: finalGameShape, amount: 85000 }],
}, excludePrevious: true,
], },
}, ],
processors: { processors: [
tiers: [ {
{ required: [{ shape: "SuSuSuSu", amount: 600 }],
required: [{ shape: "SuSuSuSu", amount: 1000 }], },
improvement: 1, {
}, required: [{ shape: "RuRu----", amount: 2000 }],
{ },
required: [{ shape: "RuRu----", amount: 2000 }], {
improvement: 2, required: [{ shape: "CgScScCg", amount: 15000 }],
}, },
{ {
required: [{ shape: "CgScScCg", amount: 25000 }], required: [{ shape: "CwCrCwCr:SgSgSgSg", amount: 20000 }],
improvement: 2, },
}, {
{ required: [{ shape: "WrRgWrRg:CwCrCwCr:SgSgSgSg", amount: 30000 }],
required: [{ shape: "CwCrCwCr:SgSgSgSg", amount: 40000 }], },
improvement: 2, {
}, required: [{ shape: finalGameShape, amount: 100000 }],
{ excludePrevious: true,
required: [{ shape: "WrRgWrRg:CwCrCwCr:SgSgSgSg", amount: 40000 }], },
improvement: 2, ],
},
{ painting: [
required: [{ shape: finalGameShape, amount: 150000 }], {
improvement: 5, required: [{ shape: "RbRb----", amount: 1000 }],
excludePrevious: true, },
}, {
], required: [{ shape: "WrWrWrWr", amount: 3000 }],
}, },
{
painting: { required: [{ shape: "RpRpRpRp:CwCwCwCw", amount: 15000 }],
tiers: [ },
{ {
required: [{ shape: "RbRb----", amount: 1500 }], required: [{ shape: "WpWpWpWp:CwCwCwCw:WpWpWpWp", amount: 20000 }],
improvement: 2, },
}, {
{ required: [{ shape: "WpWpWpWp:CwCwCwCw:WpWpWpWp:CwCwCwCw", amount: 30000 }],
required: [{ shape: "WrWrWrWr", amount: 4000 }], },
improvement: 1, {
}, required: [{ shape: finalGameShape, amount: 125000 }],
{ excludePrevious: true,
required: [{ shape: "RpRpRpRp:CwCwCwCw", amount: 30000 }], },
improvement: 2, ],
}, };
{
required: [{ shape: "WpWpWpWp:CwCwCwCw:WpWpWpWp", amount: 40000 }], // Tiers need % of the previous tier as requirement too
improvement: 2, const tierGrowth = 1.8;
},
{ // Automatically generate tier levels
required: [{ shape: "WpWpWpWp:CwCwCwCw:WpWpWpWp:CwCwCwCw", amount: 40000 }], for (const upgradeId in UPGRADES) {
improvement: 2, const upgradeTiers = UPGRADES[upgradeId];
},
{ let currentTierRequirements = [];
required: [{ shape: finalGameShape, amount: 150000 }], for (let i = 0; i < upgradeTiers.length; ++i) {
improvement: 5, const tierHandle = upgradeTiers[i];
excludePrevious: true, tierHandle.improvement = fixedImprovements[i];
}, const originalRequired = tierHandle.required.slice();
],
}, for (let k = currentTierRequirements.length - 1; k >= 0; --k) {
}; const oldTierRequirement = currentTierRequirements[k];
if (!tierHandle.excludePrevious) {
// Tiers need % of the previous tier as requirement too tierHandle.required.unshift({
const tierGrowth = 2.5; shape: oldTierRequirement.shape,
amount: oldTierRequirement.amount,
// Automatically generate tier levels });
for (const upgradeId in UPGRADES) { }
const upgrade = UPGRADES[upgradeId]; }
currentTierRequirements.push(
let currentTierRequirements = []; ...originalRequired.map(req => ({
for (let i = 0; i < upgrade.tiers.length; ++i) { amount: req.amount,
const tierHandle = upgrade.tiers[i]; shape: req.shape,
const originalRequired = tierHandle.required.slice(); }))
);
for (let k = currentTierRequirements.length - 1; k >= 0; --k) { currentTierRequirements.forEach(tier => {
const oldTierRequirement = currentTierRequirements[k]; tier.amount = findNiceIntegerValue(tier.amount * tierGrowth);
if (!tierHandle.excludePrevious) { });
tierHandle.required.unshift({ }
shape: oldTierRequirement.shape, }
amount: oldTierRequirement.amount,
}); // VALIDATE
} if (G_IS_DEV) {
} for (const upgradeId in UPGRADES) {
currentTierRequirements.push( UPGRADES[upgradeId].forEach(tier => {
...originalRequired.map(req => ({ tier.required.forEach(({ shape }) => {
amount: req.amount, try {
shape: req.shape, ShapeDefinition.fromShortKey(shape);
})) } catch (ex) {
); throw new Error("Invalid upgrade goal: '" + ex + "' for shape" + shape);
currentTierRequirements.forEach(tier => { }
tier.amount = findNiceIntegerValue(tier.amount * tierGrowth); });
}); });
} }
} }
if (G_IS_DEV) {
for (const upgradeId in UPGRADES) {
const upgrade = UPGRADES[upgradeId];
upgrade.tiers.forEach(tier => {
tier.required.forEach(({ shape }) => {
try {
ShapeDefinition.fromShortKey(shape);
} catch (ex) {
throw new Error("Invalid upgrade goal: '" + ex + "' for shape" + shape);
}
});
});
}
}

View File

@ -192,10 +192,9 @@ export class ShapezGameAnalytics extends GameAnalyticsInterface {
// Check if its required to unlock an upgrade // Check if its required to unlock an upgrade
for (const upgradeKey in UPGRADES) { for (const upgradeKey in UPGRADES) {
const handle = UPGRADES[upgradeKey]; const upgradeTiers = UPGRADES[upgradeKey];
const tiers = handle.tiers; for (let i = 0; i < upgradeTiers.length; ++i) {
for (let i = 0; i < tiers.length; ++i) { const tier = upgradeTiers[i];
const tier = tiers[i];
const required = tier.required; const required = tier.required;
for (let k = 0; k < required.length; ++k) { for (let k = 0; k < required.length; ++k) {
if (required[k].shape === key) { if (required[k].shape === key) {

View File

@ -7,7 +7,7 @@ import { enumMinerVariants, MetaMinerBuilding } from "../../game/buildings/miner
import { MetaMixerBuilding } from "../../game/buildings/mixer.js"; import { MetaMixerBuilding } from "../../game/buildings/mixer.js";
import { enumPainterVariants, MetaPainterBuilding } from "../../game/buildings/painter.js"; import { enumPainterVariants, MetaPainterBuilding } from "../../game/buildings/painter.js";
import { enumRotaterVariants, MetaRotaterBuilding } from "../../game/buildings/rotater.js"; import { enumRotaterVariants, MetaRotaterBuilding } from "../../game/buildings/rotater.js";
import { enumSplitterVariants, MetaSplitterBuilding } from "../../game/buildings/splitter.js"; import { enumBalancerVariants, MetaBalancerBuilding } from "../../game/buildings/balancer.js";
import { MetaStackerBuilding } from "../../game/buildings/stacker.js"; import { MetaStackerBuilding } from "../../game/buildings/stacker.js";
import { enumTrashVariants, MetaTrashBuilding } from "../../game/buildings/trash.js"; import { enumTrashVariants, MetaTrashBuilding } from "../../game/buildings/trash.js";
import { import {
@ -33,6 +33,15 @@ function findCode(metaBuilding, variant = defaultBuildingVariant, rotationVarian
return getCodeFromBuildingData(gMetaBuildingRegistry.findByClass(metaBuilding), variant, rotationVariant); return getCodeFromBuildingData(gMetaBuildingRegistry.findByClass(metaBuilding), variant, rotationVariant);
} }
/**
* Rebalances a value from the old balancing to the new one
* @param {number} value
* @returns {number}
*/
function rebalance(value) {
return Math.round(Math.pow(value, 0.75));
}
export class SavegameInterface_V1006 extends SavegameInterface_V1005 { export class SavegameInterface_V1006 extends SavegameInterface_V1005 {
getVersion() { getVersion() {
return 1006; return 1006;
@ -49,15 +58,15 @@ export class SavegameInterface_V1006 extends SavegameInterface_V1005 {
"sprites/blueprints/belt_left.png": findCode(MetaBeltBuilding, defaultBuildingVariant, 1), "sprites/blueprints/belt_left.png": findCode(MetaBeltBuilding, defaultBuildingVariant, 1),
"sprites/blueprints/belt_right.png": findCode(MetaBeltBuilding, defaultBuildingVariant, 2), "sprites/blueprints/belt_right.png": findCode(MetaBeltBuilding, defaultBuildingVariant, 2),
// Splitter // Splitter (=Balancer)
"sprites/blueprints/splitter.png": findCode(MetaSplitterBuilding), "sprites/blueprints/splitter.png": findCode(MetaBalancerBuilding),
"sprites/blueprints/splitter-compact.png": findCode( "sprites/blueprints/splitter-compact.png": findCode(
MetaSplitterBuilding, MetaBalancerBuilding,
enumSplitterVariants.compact enumBalancerVariants.merger
), ),
"sprites/blueprints/splitter-compact-inverse.png": findCode( "sprites/blueprints/splitter-compact-inverse.png": findCode(
MetaSplitterBuilding, MetaBalancerBuilding,
enumSplitterVariants.compactInverse enumBalancerVariants.mergerInverse
), ),
// Underground belt // Underground belt
@ -133,6 +142,17 @@ export class SavegameInterface_V1006 extends SavegameInterface_V1005 {
return true; return true;
} }
// Reduce stored shapes
const stored = dump.hubGoals.storedShapes;
for (const shapeKey in stored) {
stored[shapeKey] = rebalance(stored[shapeKey]);
}
// Reduce goals
if (dump.hubGoals.currentGoal) {
dump.hubGoals.currentGoal.required = rebalance(dump.hubGoals.currentGoal.required);
}
// Update entities // Update entities
const entities = dump.entities; const entities = dump.entities;
for (let i = 0; i < entities.length; ++i) { for (let i = 0; i < entities.length; ++i) {

View File

@ -484,25 +484,25 @@ buildings:
name: Tunnel Tier II name: Tunnel Tier II
description: Allows you to tunnel resources under buildings and belts. description: Allows you to tunnel resources under buildings and belts.
# Internal name for the Balancer # Balancer
splitter: balancer:
default: default:
name: &splitter Balancer name: &balancer Balancer
description: Multifunctional - Evenly distributes all inputs onto all outputs. description: Multifunctional - Evenly distributes all inputs onto all outputs.
compact: merger:
name: Merger (compact) name: Merger (compact)
description: Merges two conveyor belts into one. description: Merges two conveyor belts into one.
compact-inverse: merger-inverse:
name: Merger (compact) name: Merger (compact)
description: Merges two conveyor belts into one. description: Merges two conveyor belts into one.
compact-merge: splitter:
name: Splitter (compact) name: Splitter (compact)
description: Splits one conveyor belt into two. description: Splits one conveyor belt into two.
compact-merge-inverse: splitter-inverse:
name: Splitter (compact) name: Splitter (compact)
description: Splits one conveyor belt into two. description: Splits one conveyor belt into two.
@ -673,8 +673,8 @@ storyRewards:
title: Combiner title: Combiner
desc: You can now combine shapes with the <strong>combiner</strong>! Both inputs are combined, and if they can be put next to each other, they will be <strong>fused</strong>. If not, the right input is <strong>stacked on top</strong> of the left input! desc: You can now combine shapes with the <strong>combiner</strong>! Both inputs are combined, and if they can be put next to each other, they will be <strong>fused</strong>. If not, the right input is <strong>stacked on top</strong> of the left input!
reward_splitter: reward_balancer:
title: Splitter/Merger title: Balancer
desc: The multifunctional <strong>balancer</strong> has been unlocked - It can be used to build bigger factories by <strong>splitting and merging items</strong> onto multiple belts!<br><br> desc: The multifunctional <strong>balancer</strong> has been unlocked - It can be used to build bigger factories by <strong>splitting and merging items</strong> onto multiple belts!<br><br>
reward_tunnel: reward_tunnel:
@ -693,10 +693,15 @@ storyRewards:
title: Tunnel Tier II title: Tunnel Tier II
desc: You have unlocked a new variant of the <strong>tunnel</strong> - It has a <strong>bigger range</strong>, and you can also mix-n-match those tunnels now! desc: You have unlocked a new variant of the <strong>tunnel</strong> - It has a <strong>bigger range</strong>, and you can also mix-n-match those tunnels now!
reward_splitter_compact: reward_merger:
title: Compact Balancer title: Compact Merger
desc: >- desc: >-
You have unlocked a compact variant of the <strong>balancer</strong> - It accepts two inputs and merges them into one belt! You have unlocked a merger variant of the <strong>balancer</strong> - It accepts two inputs and merges them into one belt!
reward_splitter:
title: Compact Splitter
desc: >-
You have unlocked a merger variant of the <strong>balancer</strong> - It accepts one input and splits them into two!
reward_cutter_quad: reward_cutter_quad:
title: Quad Cutting title: Quad Cutting
@ -722,6 +727,10 @@ storyRewards:
title: Blueprints title: Blueprints
desc: You can now <strong>copy and paste</strong> parts of your factory! Select an area (Hold CTRL, then drag with your mouse), and press 'C' to copy it.<br><br>Pasting it is <strong>not free</strong>, you need to produce <strong>blueprint shapes</strong> to afford it! (Those you just delivered). desc: You can now <strong>copy and paste</strong> parts of your factory! Select an area (Hold CTRL, then drag with your mouse), and press 'C' to copy it.<br><br>Pasting it is <strong>not free</strong>, you need to produce <strong>blueprint shapes</strong> to afford it! (Those you just delivered).
reward_rotater_180:
title: Rotater (180 degrees)
desc: You just unlocked the 180 degress <strong>rotater</strong>! - It allows you to rotate a shape by 180 degress (Surprise! :D)
# Special reward, which is shown when there is no reward actually # Special reward, which is shown when there is no reward actually
no_reward: no_reward:
title: Next level title: Next level
@ -962,7 +971,7 @@ keybindings:
# --- Do not translate the values in this section # --- Do not translate the values in this section
belt: *belt belt: *belt
splitter: *splitter balancer: *balancer
underground_belt: *underground_belt underground_belt: *underground_belt
miner: *miner miner: *miner
cutter: *cutter cutter: *cutter