Initial take on wires
3
artwork/buildings/wire.psd
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:cb9537349ef6920b23a1e1a601309a902d4eb05a1075c28b09189638686e2500
|
||||||
|
size 77571
|
BIN
artwork/twitch/brb.png
Normal file
After Width: | Height: | Size: 45 KiB |
BIN
artwork/twitch/starting_soon.png
Normal file
After Width: | Height: | Size: 46 KiB |
3
artwork/twitch/stream_image.psd
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:22db7ba3795716bb5adf1d1eeb80af52ae7e4aa9e267324f5a541b90bf84e053
|
||||||
|
size 548633
|
BIN
artwork/twitch/thanks_for_watching.png
Normal file
After Width: | Height: | Size: 48 KiB |
@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:27c8d1eaa48beb7187e37244bd6ef7f43429be84ac88fffa96a4d72eb0e6565b
|
oid sha256:7f04a2e96f79d013838dc95e0fcc9c2c2b3519cedc5d44602ecde29b85558239
|
||||||
size 158809
|
size 174256
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:590751d33bdb2ffa0f3c7f533688f6f93c37940e1e906be7972c9d5757ab7f69
|
oid sha256:b0e6ae46466addd1bcb55a8005bbfb58fdf9e66c7fbae5620b723bdb21943b1c
|
||||||
size 57790
|
size 89487
|
||||||
|
BIN
res/ui/building_icons/wire.png
Normal file
After Width: | Height: | Size: 7.6 KiB |
@ -872,9 +872,33 @@
|
|||||||
"spriteSourceSize": {"x":0,"y":0,"w":19,"h":16},
|
"spriteSourceSize": {"x":0,"y":0,"w":19,"h":16},
|
||||||
"sourceSize": {"w":19,"h":19}
|
"sourceSize": {"w":19,"h":19}
|
||||||
},
|
},
|
||||||
|
"sprites/blueprints/wire_left.png":
|
||||||
|
{
|
||||||
|
"frame": {"x":596,"y":71,"w":11,"h":11},
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": {"x":0,"y":2,"w":11,"h":11},
|
||||||
|
"sourceSize": {"w":13,"h":13}
|
||||||
|
},
|
||||||
|
"sprites/blueprints/wire_right.png":
|
||||||
|
{
|
||||||
|
"frame": {"x":603,"y":54,"w":11,"h":11},
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": {"x":2,"y":2,"w":11,"h":11},
|
||||||
|
"sourceSize": {"w":13,"h":13}
|
||||||
|
},
|
||||||
|
"sprites/blueprints/wire_top.png":
|
||||||
|
{
|
||||||
|
"frame": {"x":617,"y":20,"w":9,"h":13},
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": {"x":2,"y":0,"w":9,"h":13},
|
||||||
|
"sourceSize": {"w":13,"h":13}
|
||||||
|
},
|
||||||
"sprites/buildings/belt_left.png":
|
"sprites/buildings/belt_left.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":570,"y":105,"w":13,"h":13},
|
"frame": {"x":603,"y":3,"w":13,"h":13},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": false,
|
"trimmed": false,
|
||||||
"spriteSourceSize": {"x":0,"y":0,"w":13,"h":13},
|
"spriteSourceSize": {"x":0,"y":0,"w":13,"h":13},
|
||||||
@ -882,7 +906,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/buildings/belt_right.png":
|
"sprites/buildings/belt_right.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":582,"y":88,"w":13,"h":13},
|
"frame": {"x":570,"y":105,"w":13,"h":13},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": false,
|
"trimmed": false,
|
||||||
"spriteSourceSize": {"x":0,"y":0,"w":13,"h":13},
|
"spriteSourceSize": {"x":0,"y":0,"w":13,"h":13},
|
||||||
@ -1080,6 +1104,30 @@
|
|||||||
"spriteSourceSize": {"x":0,"y":0,"w":19,"h":16},
|
"spriteSourceSize": {"x":0,"y":0,"w":19,"h":16},
|
||||||
"sourceSize": {"w":19,"h":19}
|
"sourceSize": {"w":19,"h":19}
|
||||||
},
|
},
|
||||||
|
"sprites/buildings/wire_left.png":
|
||||||
|
{
|
||||||
|
"frame": {"x":615,"y":37,"w":11,"h":11},
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": {"x":0,"y":2,"w":11,"h":11},
|
||||||
|
"sourceSize": {"w":13,"h":13}
|
||||||
|
},
|
||||||
|
"sprites/buildings/wire_right.png":
|
||||||
|
{
|
||||||
|
"frame": {"x":587,"y":105,"w":11,"h":11},
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": {"x":2,"y":2,"w":11,"h":11},
|
||||||
|
"sourceSize": {"w":13,"h":13}
|
||||||
|
},
|
||||||
|
"sprites/buildings/wire_top.png":
|
||||||
|
{
|
||||||
|
"frame": {"x":614,"y":84,"w":9,"h":13},
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": {"x":2,"y":0,"w":9,"h":13},
|
||||||
|
"sourceSize": {"w":13,"h":13}
|
||||||
|
},
|
||||||
"sprites/debug/acceptor_slot.png":
|
"sprites/debug/acceptor_slot.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":82,"y":72,"w":6,"h":6},
|
"frame": {"x":82,"y":72,"w":6,"h":6},
|
||||||
@ -1122,7 +1170,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/misc/deletion_marker.png":
|
"sprites/misc/deletion_marker.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":603,"y":3,"w":10,"h":10},
|
"frame": {"x":602,"y":101,"w":10,"h":10},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": false,
|
"trimmed": false,
|
||||||
"spriteSourceSize": {"x":0,"y":0,"w":10,"h":10},
|
"spriteSourceSize": {"x":0,"y":0,"w":10,"h":10},
|
||||||
@ -1146,7 +1194,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/misc/slot_bad_arrow.png":
|
"sprites/misc/slot_bad_arrow.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":603,"y":3,"w":10,"h":10},
|
"frame": {"x":602,"y":101,"w":10,"h":10},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": false,
|
"trimmed": false,
|
||||||
"spriteSourceSize": {"x":0,"y":0,"w":10,"h":10},
|
"spriteSourceSize": {"x":0,"y":0,"w":10,"h":10},
|
||||||
@ -1154,7 +1202,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/misc/slot_good_arrow.png":
|
"sprites/misc/slot_good_arrow.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":603,"y":54,"w":10,"h":10},
|
"frame": {"x":602,"y":115,"w":10,"h":10},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": false,
|
"trimmed": false,
|
||||||
"spriteSourceSize": {"x":0,"y":0,"w":10,"h":10},
|
"spriteSourceSize": {"x":0,"y":0,"w":10,"h":10},
|
||||||
@ -1178,18 +1226,26 @@
|
|||||||
},
|
},
|
||||||
"sprites/misc/wires_overlay_tile.png":
|
"sprites/misc/wires_overlay_tile.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":596,"y":71,"w":13,"h":13},
|
"frame": {"x":582,"y":88,"w":13,"h":13},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": false,
|
"trimmed": false,
|
||||||
"spriteSourceSize": {"x":0,"y":0,"w":13,"h":13},
|
"spriteSourceSize": {"x":0,"y":0,"w":13,"h":13},
|
||||||
"sourceSize": {"w":13,"h":13}
|
"sourceSize": {"w":13,"h":13}
|
||||||
},
|
},
|
||||||
"sprites/wires/pin-energy-on.png":
|
"sprites/wires/pin-negative-energy.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":587,"y":105,"w":11,"h":11},
|
"frame": {"x":599,"y":86,"w":11,"h":11},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":1,"y":1,"w":11,"h":11},
|
"spriteSourceSize": {"x":1,"y":0,"w":11,"h":11},
|
||||||
|
"sourceSize": {"w":13,"h":13}
|
||||||
|
},
|
||||||
|
"sprites/wires/pin-positive-energy.png":
|
||||||
|
{
|
||||||
|
"frame": {"x":611,"y":69,"w":11,"h":11},
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": {"x":1,"y":0,"w":11,"h":11},
|
||||||
"sourceSize": {"w":13,"h":13}
|
"sourceSize": {"w":13,"h":13}
|
||||||
}},
|
}},
|
||||||
"meta": {
|
"meta": {
|
||||||
@ -1197,8 +1253,8 @@
|
|||||||
"version": "1.0",
|
"version": "1.0",
|
||||||
"image": "atlas0_10.png",
|
"image": "atlas0_10.png",
|
||||||
"format": "RGBA8888",
|
"format": "RGBA8888",
|
||||||
"size": {"w":616,"h":128},
|
"size": {"w":629,"h":128},
|
||||||
"scale": "0.1",
|
"scale": "0.1",
|
||||||
"smartupdate": "$TexturePacker:SmartUpdate:1e5c68ef1fd4026b263679a3171f1832:b30cc36f2dfbe8399542e279c203efaf:f159918d23e5952766c6d23ab52278c6$"
|
"smartupdate": "$TexturePacker:SmartUpdate:9ea1a09cb2003bf62ce57f52404292e0:0fc8d0e33f315e93d6d057148d691370:f159918d23e5952766c6d23ab52278c6$"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 63 KiB |
Before Width: | Height: | Size: 1.0 MiB After Width: | Height: | Size: 1.0 MiB |
Before Width: | Height: | Size: 206 KiB After Width: | Height: | Size: 201 KiB |
Before Width: | Height: | Size: 471 KiB After Width: | Height: | Size: 476 KiB |
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
"sprites/belt/forward_0.png":
|
"sprites/belt/forward_0.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1880,"y":594,"w":77,"h":95},
|
"frame": {"x":1879,"y":594,"w":77,"h":95},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
||||||
@ -18,7 +18,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/forward_2.png":
|
"sprites/belt/forward_2.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1509,"y":1071,"w":77,"h":95},
|
"frame": {"x":1960,"y":537,"w":77,"h":95},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
||||||
@ -26,7 +26,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/forward_3.png":
|
"sprites/belt/forward_3.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1680,"y":923,"w":77,"h":95},
|
"frame": {"x":1838,"y":1153,"w":77,"h":95},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
||||||
@ -34,7 +34,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/forward_4.png":
|
"sprites/belt/forward_4.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1680,"y":1022,"w":77,"h":95},
|
"frame": {"x":1757,"y":1252,"w":77,"h":95},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
||||||
@ -42,7 +42,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/forward_5.png":
|
"sprites/belt/forward_5.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1770,"y":1049,"w":77,"h":95},
|
"frame": {"x":1838,"y":1252,"w":77,"h":95},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
||||||
@ -50,7 +50,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/forward_6.png":
|
"sprites/belt/forward_6.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1770,"y":1148,"w":77,"h":95},
|
"frame": {"x":1919,"y":1185,"w":77,"h":95},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
||||||
@ -58,7 +58,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/forward_7.png":
|
"sprites/belt/forward_7.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1768,"y":1247,"w":77,"h":95},
|
"frame": {"x":1919,"y":1284,"w":77,"h":95},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
||||||
@ -66,7 +66,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/forward_8.png":
|
"sprites/belt/forward_8.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":713,"y":1307,"w":77,"h":95},
|
"frame": {"x":1323,"y":1290,"w":77,"h":95},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
||||||
@ -74,7 +74,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/forward_9.png":
|
"sprites/belt/forward_9.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":974,"y":1239,"w":77,"h":95},
|
"frame": {"x":1404,"y":1293,"w":77,"h":95},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
||||||
@ -90,7 +90,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/forward_11.png":
|
"sprites/belt/forward_11.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1428,"y":806,"w":77,"h":95},
|
"frame": {"x":1428,"y":816,"w":77,"h":95},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
||||||
@ -106,7 +106,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/forward_13.png":
|
"sprites/belt/forward_13.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1509,"y":873,"w":77,"h":95},
|
"frame": {"x":1428,"y":915,"w":77,"h":95},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
||||||
@ -114,7 +114,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/forward_14.png":
|
"sprites/belt/forward_14.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1428,"y":905,"w":77,"h":95},
|
"frame": {"x":1257,"y":920,"w":77,"h":95},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
||||||
@ -122,7 +122,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/forward_15.png":
|
"sprites/belt/forward_15.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1509,"y":972,"w":77,"h":95},
|
"frame": {"x":1347,"y":1011,"w":77,"h":95},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
||||||
@ -130,7 +130,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/forward_16.png":
|
"sprites/belt/forward_16.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":692,"y":1121,"w":77,"h":95},
|
"frame": {"x":1428,"y":1014,"w":77,"h":95},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
||||||
@ -138,7 +138,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/forward_17.png":
|
"sprites/belt/forward_17.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1257,"y":920,"w":77,"h":95},
|
"frame": {"x":1779,"y":865,"w":77,"h":95},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
||||||
@ -146,7 +146,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/forward_18.png":
|
"sprites/belt/forward_18.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1428,"y":1004,"w":77,"h":95},
|
"frame": {"x":1779,"y":964,"w":77,"h":95},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
||||||
@ -154,7 +154,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/forward_19.png":
|
"sprites/belt/forward_19.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1257,"y":1019,"w":77,"h":95},
|
"frame": {"x":1869,"y":1054,"w":77,"h":95},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
||||||
@ -162,7 +162,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/forward_20.png":
|
"sprites/belt/forward_20.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1327,"y":1118,"w":77,"h":95},
|
"frame": {"x":1960,"y":636,"w":77,"h":95},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
||||||
@ -170,7 +170,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/forward_21.png":
|
"sprites/belt/forward_21.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1417,"y":1193,"w":77,"h":95},
|
"frame": {"x":684,"y":1138,"w":77,"h":95},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
||||||
@ -178,7 +178,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/forward_22.png":
|
"sprites/belt/forward_22.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1417,"y":1292,"w":77,"h":95},
|
"frame": {"x":988,"y":1239,"w":77,"h":95},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
||||||
@ -186,7 +186,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/forward_23.png":
|
"sprites/belt/forward_23.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1961,"y":537,"w":77,"h":95},
|
"frame": {"x":1595,"y":1143,"w":77,"h":95},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
||||||
@ -194,7 +194,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/forward_24.png":
|
"sprites/belt/forward_24.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1961,"y":636,"w":77,"h":95},
|
"frame": {"x":1676,"y":1140,"w":77,"h":95},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
||||||
@ -202,7 +202,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/forward_25.png":
|
"sprites/belt/forward_25.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1880,"y":693,"w":77,"h":95},
|
"frame": {"x":1595,"y":1242,"w":77,"h":95},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
||||||
@ -210,7 +210,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/forward_26.png":
|
"sprites/belt/forward_26.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1961,"y":735,"w":77,"h":95},
|
"frame": {"x":1676,"y":1239,"w":77,"h":95},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
||||||
@ -218,7 +218,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/forward_27.png":
|
"sprites/belt/forward_27.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1680,"y":824,"w":77,"h":95},
|
"frame": {"x":1757,"y":1153,"w":77,"h":95},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
||||||
@ -242,7 +242,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/left_2.png":
|
"sprites/belt/left_2.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1595,"y":734,"w":86,"h":86},
|
"frame": {"x":1590,"y":780,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
||||||
@ -250,7 +250,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/left_3.png":
|
"sprites/belt/left_3.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1590,"y":1094,"w":86,"h":86},
|
"frame": {"x":1257,"y":1019,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
||||||
@ -258,7 +258,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/left_4.png":
|
"sprites/belt/left_4.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1057,"y":1141,"w":86,"h":86},
|
"frame": {"x":1509,"y":1053,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
||||||
@ -266,7 +266,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/left_5.png":
|
"sprites/belt/left_5.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1147,"y":1159,"w":86,"h":86},
|
"frame": {"x":1599,"y":1050,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
||||||
@ -274,7 +274,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/left_6.png":
|
"sprites/belt/left_6.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1237,"y":1118,"w":86,"h":86},
|
"frame": {"x":1689,"y":1050,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
||||||
@ -282,7 +282,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/left_7.png":
|
"sprites/belt/left_7.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1237,"y":1208,"w":86,"h":86},
|
"frame": {"x":1235,"y":1109,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
||||||
@ -290,7 +290,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/left_8.png":
|
"sprites/belt/left_8.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1327,"y":1217,"w":86,"h":86},
|
"frame": {"x":1325,"y":1110,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
||||||
@ -298,7 +298,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/left_9.png":
|
"sprites/belt/left_9.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1408,"y":1103,"w":86,"h":86},
|
"frame": {"x":1415,"y":1113,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
||||||
@ -330,7 +330,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/left_13.png":
|
"sprites/belt/left_13.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1057,"y":1051,"w":86,"h":86},
|
"frame": {"x":1055,"y":1051,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
||||||
@ -346,7 +346,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/left_15.png":
|
"sprites/belt/left_15.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1147,"y":1069,"w":86,"h":86},
|
"frame": {"x":1145,"y":1069,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
||||||
@ -386,7 +386,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/left_20.png":
|
"sprites/belt/left_20.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1590,"y":824,"w":86,"h":86},
|
"frame": {"x":1680,"y":780,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
||||||
@ -394,7 +394,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/left_21.png":
|
"sprites/belt/left_21.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1590,"y":914,"w":86,"h":86},
|
"frame": {"x":1509,"y":873,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
||||||
@ -402,7 +402,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/left_22.png":
|
"sprites/belt/left_22.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1590,"y":1004,"w":86,"h":86},
|
"frame": {"x":1599,"y":870,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
||||||
@ -410,7 +410,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/left_23.png":
|
"sprites/belt/left_23.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":773,"y":1149,"w":86,"h":86},
|
"frame": {"x":1689,"y":870,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
||||||
@ -418,7 +418,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/left_24.png":
|
"sprites/belt/left_24.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":863,"y":1149,"w":86,"h":86},
|
"frame": {"x":1509,"y":963,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
||||||
@ -426,7 +426,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/left_25.png":
|
"sprites/belt/left_25.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":953,"y":1149,"w":86,"h":86},
|
"frame": {"x":1599,"y":960,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
||||||
@ -434,7 +434,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/left_26.png":
|
"sprites/belt/left_26.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1338,"y":921,"w":86,"h":86},
|
"frame": {"x":1689,"y":960,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
||||||
@ -442,7 +442,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/left_27.png":
|
"sprites/belt/left_27.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1338,"y":1011,"w":86,"h":86},
|
"frame": {"x":1338,"y":921,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
||||||
@ -450,7 +450,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/right_0.png":
|
"sprites/belt/right_0.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1498,"y":1170,"w":86,"h":86},
|
"frame": {"x":1505,"y":1143,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
||||||
@ -458,7 +458,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/right_1.png":
|
"sprites/belt/right_1.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1588,"y":1184,"w":86,"h":86},
|
"frame": {"x":1055,"y":1141,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
||||||
@ -466,7 +466,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/right_2.png":
|
"sprites/belt/right_2.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1851,"y":972,"w":86,"h":86},
|
"frame": {"x":1950,"y":735,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
||||||
@ -474,7 +474,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/right_3.png":
|
"sprites/belt/right_3.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1941,"y":1284,"w":86,"h":86},
|
"frame": {"x":808,"y":1239,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
||||||
@ -482,7 +482,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/right_4.png":
|
"sprites/belt/right_4.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":794,"y":1239,"w":86,"h":86},
|
"frame": {"x":898,"y":1239,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
||||||
@ -490,7 +490,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/right_5.png":
|
"sprites/belt/right_5.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":884,"y":1239,"w":86,"h":86},
|
"frame": {"x":718,"y":1329,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
||||||
@ -498,7 +498,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/right_6.png":
|
"sprites/belt/right_6.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":794,"y":1329,"w":86,"h":86},
|
"frame": {"x":808,"y":1329,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
||||||
@ -506,7 +506,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/right_7.png":
|
"sprites/belt/right_7.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":884,"y":1329,"w":86,"h":86},
|
"frame": {"x":898,"y":1329,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
||||||
@ -514,7 +514,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/right_8.png":
|
"sprites/belt/right_8.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1055,"y":1231,"w":86,"h":86},
|
"frame": {"x":988,"y":1338,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
||||||
@ -522,7 +522,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/right_9.png":
|
"sprites/belt/right_9.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1145,"y":1249,"w":86,"h":86},
|
"frame": {"x":1143,"y":1249,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
||||||
@ -530,7 +530,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/right_10.png":
|
"sprites/belt/right_10.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1498,"y":1260,"w":86,"h":86},
|
"frame": {"x":1145,"y":1159,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
||||||
@ -538,7 +538,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/right_11.png":
|
"sprites/belt/right_11.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1588,"y":1274,"w":86,"h":86},
|
"frame": {"x":1235,"y":1199,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
||||||
@ -546,7 +546,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/right_12.png":
|
"sprites/belt/right_12.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1680,"y":1121,"w":86,"h":86},
|
"frame": {"x":1325,"y":1200,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
||||||
@ -554,7 +554,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/right_13.png":
|
"sprites/belt/right_13.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1678,"y":1211,"w":86,"h":86},
|
"frame": {"x":1415,"y":1203,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
||||||
@ -562,7 +562,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/right_14.png":
|
"sprites/belt/right_14.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1678,"y":1301,"w":86,"h":86},
|
"frame": {"x":1505,"y":1233,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
||||||
@ -570,7 +570,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/right_15.png":
|
"sprites/belt/right_15.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1761,"y":779,"w":86,"h":86},
|
"frame": {"x":1770,"y":709,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
||||||
@ -578,7 +578,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/right_16.png":
|
"sprites/belt/right_16.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1761,"y":869,"w":86,"h":86},
|
"frame": {"x":1779,"y":1063,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
||||||
@ -586,7 +586,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/right_17.png":
|
"sprites/belt/right_17.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1761,"y":959,"w":86,"h":86},
|
"frame": {"x":1860,"y":709,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
||||||
@ -594,7 +594,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/right_18.png":
|
"sprites/belt/right_18.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1851,"y":792,"w":86,"h":86},
|
"frame": {"x":1860,"y":799,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
||||||
@ -602,7 +602,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/right_19.png":
|
"sprites/belt/right_19.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1851,"y":882,"w":86,"h":86},
|
"frame": {"x":1860,"y":889,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
||||||
@ -610,7 +610,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/right_20.png":
|
"sprites/belt/right_20.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1941,"y":834,"w":86,"h":86},
|
"frame": {"x":1950,"y":825,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
||||||
@ -618,7 +618,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/right_21.png":
|
"sprites/belt/right_21.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1941,"y":924,"w":86,"h":86},
|
"frame": {"x":1950,"y":915,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
||||||
@ -626,7 +626,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/right_22.png":
|
"sprites/belt/right_22.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1941,"y":1014,"w":86,"h":86},
|
"frame": {"x":1950,"y":1005,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
||||||
@ -634,7 +634,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/right_23.png":
|
"sprites/belt/right_23.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1851,"y":1062,"w":86,"h":86},
|
"frame": {"x":1950,"y":1095,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
||||||
@ -642,7 +642,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/right_24.png":
|
"sprites/belt/right_24.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1851,"y":1152,"w":86,"h":86},
|
"frame": {"x":765,"y":1149,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
||||||
@ -650,7 +650,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/right_25.png":
|
"sprites/belt/right_25.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1941,"y":1104,"w":86,"h":86},
|
"frame": {"x":855,"y":1149,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
||||||
@ -658,7 +658,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/right_26.png":
|
"sprites/belt/right_26.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1941,"y":1194,"w":86,"h":86},
|
"frame": {"x":945,"y":1149,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
||||||
@ -666,7 +666,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/belt/right_27.png":
|
"sprites/belt/right_27.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1851,"y":1242,"w":86,"h":86},
|
"frame": {"x":718,"y":1239,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
||||||
@ -690,7 +690,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/blueprints/belt_top.png":
|
"sprites/blueprints/belt_top.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":692,"y":1022,"w":79,"h":95},
|
"frame": {"x":690,"y":1022,"w":79,"h":95},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":8,"y":0,"w":79,"h":95},
|
"spriteSourceSize": {"x":8,"y":0,"w":79,"h":95},
|
||||||
@ -794,7 +794,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/blueprints/splitter-compact-inverse.png":
|
"sprites/blueprints/splitter-compact-inverse.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":257,"y":1141,"w":142,"h":138},
|
"frame": {"x":3,"y":1286,"w":142,"h":138},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":0,"y":2,"w":142,"h":138},
|
"spriteSourceSize": {"x":0,"y":2,"w":142,"h":138},
|
||||||
@ -802,7 +802,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/blueprints/splitter-compact.png":
|
"sprites/blueprints/splitter-compact.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":543,"y":1162,"w":139,"h":138},
|
"frame": {"x":149,"y":1286,"w":139,"h":138},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":5,"y":2,"w":139,"h":138},
|
"spriteSourceSize": {"x":5,"y":2,"w":139,"h":138},
|
||||||
@ -842,7 +842,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/blueprints/underground_belt_entry-tier2.png":
|
"sprites/blueprints/underground_belt_entry-tier2.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":3,"y":1286,"w":138,"h":125},
|
"frame": {"x":542,"y":1138,"w":138,"h":125},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":4,"y":19,"w":138,"h":125},
|
"spriteSourceSize": {"x":4,"y":19,"w":138,"h":125},
|
||||||
@ -850,7 +850,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/blueprints/underground_belt_entry.png":
|
"sprites/blueprints/underground_belt_entry.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":429,"y":1304,"w":138,"h":112},
|
"frame": {"x":576,"y":1267,"w":138,"h":112},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":4,"y":32,"w":138,"h":112},
|
"spriteSourceSize": {"x":4,"y":32,"w":138,"h":112},
|
||||||
@ -858,7 +858,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/blueprints/underground_belt_exit-tier2.png":
|
"sprites/blueprints/underground_belt_exit-tier2.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":286,"y":1304,"w":139,"h":112},
|
"frame": {"x":547,"y":1022,"w":139,"h":112},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":4,"y":0,"w":139,"h":112},
|
"spriteSourceSize": {"x":4,"y":0,"w":139,"h":112},
|
||||||
@ -866,15 +866,39 @@
|
|||||||
},
|
},
|
||||||
"sprites/blueprints/underground_belt_exit.png":
|
"sprites/blueprints/underground_belt_exit.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":571,"y":1304,"w":138,"h":112},
|
"frame": {"x":1596,"y":594,"w":138,"h":112},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":4,"y":0,"w":138,"h":112},
|
"spriteSourceSize": {"x":4,"y":0,"w":138,"h":112},
|
||||||
"sourceSize": {"w":144,"h":144}
|
"sourceSize": {"w":144,"h":144}
|
||||||
},
|
},
|
||||||
|
"sprites/blueprints/wire_left.png":
|
||||||
|
{
|
||||||
|
"frame": {"x":1428,"y":741,"w":71,"h":71},
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": {"x":0,"y":24,"w":71,"h":71},
|
||||||
|
"sourceSize": {"w":95,"h":95}
|
||||||
|
},
|
||||||
|
"sprites/blueprints/wire_right.png":
|
||||||
|
{
|
||||||
|
"frame": {"x":1860,"y":979,"w":71,"h":71},
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": {"x":24,"y":24,"w":71,"h":71},
|
||||||
|
"sourceSize": {"w":95,"h":95}
|
||||||
|
},
|
||||||
|
"sprites/blueprints/wire_top.png":
|
||||||
|
{
|
||||||
|
"frame": {"x":1963,"y":3,"w":47,"h":95},
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": {"x":24,"y":0,"w":47,"h":95},
|
||||||
|
"sourceSize": {"w":95,"h":95}
|
||||||
|
},
|
||||||
"sprites/buildings/belt_left.png":
|
"sprites/buildings/belt_left.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1235,"y":1298,"w":86,"h":86},
|
"frame": {"x":1078,"y":1339,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":0,"y":9,"w":86,"h":86},
|
||||||
@ -882,7 +906,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/buildings/belt_right.png":
|
"sprites/buildings/belt_right.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1325,"y":1307,"w":86,"h":86},
|
"frame": {"x":1168,"y":1339,"w":86,"h":86},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
"spriteSourceSize": {"x":9,"y":9,"w":86,"h":86},
|
||||||
@ -890,7 +914,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/buildings/belt_top.png":
|
"sprites/buildings/belt_top.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1880,"y":594,"w":77,"h":95},
|
"frame": {"x":1879,"y":594,"w":77,"h":95},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
"spriteSourceSize": {"x":9,"y":0,"w":77,"h":95},
|
||||||
@ -938,7 +962,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/buildings/miner.png":
|
"sprites/buildings/miner.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":403,"y":1135,"w":136,"h":142},
|
"frame": {"x":402,"y":1135,"w":136,"h":142},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":5,"y":0,"w":136,"h":142},
|
"spriteSourceSize": {"x":5,"y":0,"w":136,"h":142},
|
||||||
@ -1002,7 +1026,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/buildings/splitter-compact-inverse.png":
|
"sprites/buildings/splitter-compact-inverse.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":547,"y":1022,"w":141,"h":136},
|
"frame": {"x":257,"y":1141,"w":141,"h":136},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":0,"y":3,"w":141,"h":136},
|
"spriteSourceSize": {"x":0,"y":3,"w":141,"h":136},
|
||||||
@ -1010,7 +1034,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/buildings/splitter-compact.png":
|
"sprites/buildings/splitter-compact.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1596,"y":594,"w":139,"h":136},
|
"frame": {"x":292,"y":1281,"w":139,"h":136},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":5,"y":3,"w":139,"h":136},
|
"spriteSourceSize": {"x":5,"y":3,"w":139,"h":136},
|
||||||
@ -1050,7 +1074,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/buildings/underground_belt_entry-tier2.png":
|
"sprites/buildings/underground_belt_entry-tier2.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":145,"y":1286,"w":137,"h":124},
|
"frame": {"x":435,"y":1281,"w":137,"h":124},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":5,"y":20,"w":137,"h":124},
|
"spriteSourceSize": {"x":5,"y":20,"w":137,"h":124},
|
||||||
@ -1058,7 +1082,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/buildings/underground_belt_entry.png":
|
"sprites/buildings/underground_belt_entry.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1739,"y":594,"w":137,"h":111},
|
"frame": {"x":1738,"y":594,"w":137,"h":111},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":5,"y":33,"w":137,"h":111},
|
"spriteSourceSize": {"x":5,"y":33,"w":137,"h":111},
|
||||||
@ -1066,7 +1090,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/buildings/underground_belt_exit-tier2.png":
|
"sprites/buildings/underground_belt_exit-tier2.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":775,"y":1034,"w":137,"h":111},
|
"frame": {"x":773,"y":1034,"w":137,"h":111},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":5,"y":0,"w":137,"h":111},
|
"spriteSourceSize": {"x":5,"y":0,"w":137,"h":111},
|
||||||
@ -1074,15 +1098,39 @@
|
|||||||
},
|
},
|
||||||
"sprites/buildings/underground_belt_exit.png":
|
"sprites/buildings/underground_belt_exit.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":916,"y":1034,"w":137,"h":111},
|
"frame": {"x":914,"y":1034,"w":137,"h":111},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":5,"y":0,"w":137,"h":111},
|
"spriteSourceSize": {"x":5,"y":0,"w":137,"h":111},
|
||||||
"sourceSize": {"w":144,"h":144}
|
"sourceSize": {"w":144,"h":144}
|
||||||
},
|
},
|
||||||
|
"sprites/buildings/wire_left.png":
|
||||||
|
{
|
||||||
|
"frame": {"x":1069,"y":1231,"w":70,"h":70},
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": {"x":0,"y":25,"w":70,"h":70},
|
||||||
|
"sourceSize": {"w":95,"h":95}
|
||||||
|
},
|
||||||
|
"sprites/buildings/wire_right.png":
|
||||||
|
{
|
||||||
|
"frame": {"x":1485,"y":1323,"w":70,"h":70},
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": {"x":25,"y":25,"w":70,"h":70},
|
||||||
|
"sourceSize": {"w":95,"h":95}
|
||||||
|
},
|
||||||
|
"sprites/buildings/wire_top.png":
|
||||||
|
{
|
||||||
|
"frame": {"x":1963,"y":102,"w":45,"h":95},
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": {"x":25,"y":0,"w":45,"h":95},
|
||||||
|
"sourceSize": {"w":95,"h":95}
|
||||||
|
},
|
||||||
"sprites/debug/acceptor_slot.png":
|
"sprites/debug/acceptor_slot.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1963,"y":145,"w":38,"h":48},
|
"frame": {"x":2000,"y":1185,"w":38,"h":48},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":5,"y":0,"w":38,"h":48},
|
"spriteSourceSize": {"x":5,"y":0,"w":38,"h":48},
|
||||||
@ -1090,7 +1138,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/debug/ejector_slot.png":
|
"sprites/debug/ejector_slot.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1685,"y":734,"w":38,"h":48},
|
"frame": {"x":2000,"y":1237,"w":38,"h":48},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":5,"y":0,"w":38,"h":48},
|
"spriteSourceSize": {"x":5,"y":0,"w":38,"h":48},
|
||||||
@ -1098,7 +1146,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/map_overview/belt_forward.png":
|
"sprites/map_overview/belt_forward.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1768,"y":1346,"w":20,"h":24},
|
"frame": {"x":1836,"y":799,"w":20,"h":24},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":2,"y":0,"w":20,"h":24},
|
"spriteSourceSize": {"x":2,"y":0,"w":20,"h":24},
|
||||||
@ -1106,7 +1154,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/map_overview/belt_left.png":
|
"sprites/map_overview/belt_left.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1935,"y":537,"w":22,"h":22},
|
"frame": {"x":2014,"y":3,"w":22,"h":22},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":0,"y":2,"w":22,"h":22},
|
"spriteSourceSize": {"x":0,"y":2,"w":22,"h":22},
|
||||||
@ -1114,7 +1162,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/map_overview/belt_right.png":
|
"sprites/map_overview/belt_right.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1935,"y":563,"w":22,"h":22},
|
"frame": {"x":684,"y":1237,"w":22,"h":22},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":2,"y":2,"w":22,"h":22},
|
"spriteSourceSize": {"x":2,"y":2,"w":22,"h":22},
|
||||||
@ -1122,7 +1170,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/misc/deletion_marker.png":
|
"sprites/misc/deletion_marker.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1963,"y":79,"w":62,"h":62},
|
"frame": {"x":1770,"y":799,"w":62,"h":62},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":5,"y":5,"w":62,"h":62},
|
"spriteSourceSize": {"x":5,"y":5,"w":62,"h":62},
|
||||||
@ -1138,7 +1186,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/misc/lock_direction_indicator.png":
|
"sprites/misc/lock_direction_indicator.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1498,"y":1350,"w":36,"h":24},
|
"frame": {"x":1069,"y":1305,"w":36,"h":24},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":0,"y":6,"w":36,"h":24},
|
"spriteSourceSize": {"x":0,"y":6,"w":36,"h":24},
|
||||||
@ -1146,7 +1194,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/misc/slot_bad_arrow.png":
|
"sprites/misc/slot_bad_arrow.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1963,"y":79,"w":62,"h":62},
|
"frame": {"x":1770,"y":799,"w":62,"h":62},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":5,"y":5,"w":62,"h":62},
|
"spriteSourceSize": {"x":5,"y":5,"w":62,"h":62},
|
||||||
@ -1154,7 +1202,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/misc/slot_good_arrow.png":
|
"sprites/misc/slot_good_arrow.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1963,"y":3,"w":62,"h":72},
|
"frame": {"x":1963,"y":201,"w":62,"h":72},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":5,"y":0,"w":62,"h":72},
|
"spriteSourceSize": {"x":5,"y":0,"w":62,"h":72},
|
||||||
@ -1162,7 +1210,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/misc/storage_overlay.png":
|
"sprites/misc/storage_overlay.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1739,"y":709,"w":133,"h":66},
|
"frame": {"x":1595,"y":710,"w":133,"h":66},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":2,"y":2,"w":133,"h":66},
|
"spriteSourceSize": {"x":2,"y":2,"w":133,"h":66},
|
||||||
@ -1170,7 +1218,7 @@
|
|||||||
},
|
},
|
||||||
"sprites/misc/waypoint.png":
|
"sprites/misc/waypoint.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":974,"y":1338,"w":20,"h":24},
|
"frame": {"x":1836,"y":827,"w":20,"h":24},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":2,"y":0,"w":20,"h":24},
|
"spriteSourceSize": {"x":2,"y":0,"w":20,"h":24},
|
||||||
@ -1184,12 +1232,20 @@
|
|||||||
"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/wires/pin-energy-on.png":
|
"sprites/wires/pin-negative-energy.png":
|
||||||
{
|
{
|
||||||
"frame": {"x":1428,"y":741,"w":61,"h":61},
|
"frame": {"x":1258,"y":1289,"w":61,"h":71},
|
||||||
"rotated": false,
|
"rotated": false,
|
||||||
"trimmed": true,
|
"trimmed": true,
|
||||||
"spriteSourceSize": {"x":17,"y":17,"w":61,"h":61},
|
"spriteSourceSize": {"x":17,"y":0,"w":61,"h":71},
|
||||||
|
"sourceSize": {"w":96,"h":96}
|
||||||
|
},
|
||||||
|
"sprites/wires/pin-positive-energy.png":
|
||||||
|
{
|
||||||
|
"frame": {"x":1559,"y":1341,"w":61,"h":71},
|
||||||
|
"rotated": false,
|
||||||
|
"trimmed": true,
|
||||||
|
"spriteSourceSize": {"x":17,"y":0,"w":61,"h":71},
|
||||||
"sourceSize": {"w":96,"h":96}
|
"sourceSize": {"w":96,"h":96}
|
||||||
}},
|
}},
|
||||||
"meta": {
|
"meta": {
|
||||||
@ -1197,8 +1253,8 @@
|
|||||||
"version": "1.0",
|
"version": "1.0",
|
||||||
"image": "atlas0_75.png",
|
"image": "atlas0_75.png",
|
||||||
"format": "RGBA8888",
|
"format": "RGBA8888",
|
||||||
"size": {"w":2042,"h":1419},
|
"size": {"w":2042,"h":1428},
|
||||||
"scale": "0.75",
|
"scale": "0.75",
|
||||||
"smartupdate": "$TexturePacker:SmartUpdate:1e5c68ef1fd4026b263679a3171f1832:b30cc36f2dfbe8399542e279c203efaf:f159918d23e5952766c6d23ab52278c6$"
|
"smartupdate": "$TexturePacker:SmartUpdate:9ea1a09cb2003bf62ce57f52404292e0:0fc8d0e33f315e93d6d057148d691370:f159918d23e5952766c6d23ab52278c6$"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Before Width: | Height: | Size: 980 KiB After Width: | Height: | Size: 956 KiB |
BIN
res_raw/sprites/blueprints/wire_left.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
res_raw/sprites/blueprints/wire_right.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
res_raw/sprites/blueprints/wire_top.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
res_raw/sprites/buildings/wire_left.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
BIN
res_raw/sprites/buildings/wire_right.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
res_raw/sprites/buildings/wire_top.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 5.5 KiB |
BIN
res_raw/sprites/wires/pin-negative-energy.png
Normal file
After Width: | Height: | Size: 5.0 KiB |
BIN
res_raw/sprites/wires/pin-positive-energy.png
Normal file
After Width: | Height: | Size: 5.3 KiB |
@ -1,5 +1,5 @@
|
|||||||
$buildings: belt, cutter, miner, mixer, painter, rotater, splitter, stacker, trash, underground_belt,
|
$buildings: belt, cutter, miner, mixer, painter, rotater, splitter, stacker, trash, underground_belt,
|
||||||
energy_generator;
|
energy_generator, wire;
|
||||||
|
|
||||||
@each $building in $buildings {
|
@each $building in $buildings {
|
||||||
[data-icon="building_icons/#{$building}.png"] {
|
[data-icon="building_icons/#{$building}.png"] {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#ingame_HUD_buildings_toolbar {
|
.ingame_buildingsToolbar {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@include S(bottom, 0px);
|
@include S(bottom, 0px);
|
||||||
left: 50%;
|
left: 50%;
|
||||||
|
@ -74,6 +74,7 @@ ingame_HUD_EntityDebugger,
|
|||||||
ingame_HUD_InteractiveTutorial,
|
ingame_HUD_InteractiveTutorial,
|
||||||
ingame_HUD_TutorialHints,
|
ingame_HUD_TutorialHints,
|
||||||
ingame_HUD_buildings_toolbar,
|
ingame_HUD_buildings_toolbar,
|
||||||
|
ingame_HUD_wires_toolbar,
|
||||||
ingame_HUD_BlueprintPlacer,
|
ingame_HUD_BlueprintPlacer,
|
||||||
ingame_HUD_Waypoints_Hint,
|
ingame_HUD_Waypoints_Hint,
|
||||||
ingame_HUD_Watermark,
|
ingame_HUD_Watermark,
|
||||||
|
@ -35,7 +35,7 @@ export default {
|
|||||||
// Unlocks all buildings
|
// Unlocks all buildings
|
||||||
// allBuildingsUnlocked: true,
|
// allBuildingsUnlocked: true,
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
// Disables cost of bluepirnts
|
// Disables cost of blueprints
|
||||||
// blueprintsNoCost: true,
|
// blueprintsNoCost: true,
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
// Disables cost of upgrades
|
// Disables cost of upgrades
|
||||||
@ -92,5 +92,8 @@ export default {
|
|||||||
// Whether to check belt paths
|
// Whether to check belt paths
|
||||||
// checkBeltPaths: true,
|
// checkBeltPaths: true,
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
|
// Whether to items / s instead of items / m in stats
|
||||||
|
// detailedStatistics: true,
|
||||||
|
// -----------------------------------------------------------------------------------
|
||||||
/* dev:end */
|
/* dev:end */
|
||||||
};
|
};
|
||||||
|
@ -5,6 +5,8 @@ import { BasicSerializableObject } from "../savegame/serialization";
|
|||||||
export const enumItemType = {
|
export const enumItemType = {
|
||||||
shape: "shape",
|
shape: "shape",
|
||||||
color: "color",
|
color: "color",
|
||||||
|
positiveEnergy: "positiveEnergy",
|
||||||
|
negativeEnergy: "negativeEnergy",
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -5,7 +5,7 @@ import { epsilonCompare, round4Digits } from "../core/utils";
|
|||||||
import { Vector } from "../core/vector";
|
import { Vector } from "../core/vector";
|
||||||
import { BaseItem } from "./base_item";
|
import { BaseItem } from "./base_item";
|
||||||
import { Entity } from "./entity";
|
import { Entity } from "./entity";
|
||||||
import { GameRoot } from "./root";
|
import { GameRoot, enumLayer } from "./root";
|
||||||
import { Rectangle } from "../core/rectangle";
|
import { Rectangle } from "../core/rectangle";
|
||||||
import { BasicSerializableObject, types } from "../savegame/serialization";
|
import { BasicSerializableObject, types } from "../savegame/serialization";
|
||||||
import { gItemRegistry } from "../core/global_registries";
|
import { gItemRegistry } from "../core/global_registries";
|
||||||
@ -120,6 +120,14 @@ export class BeltPath extends BasicSerializableObject {
|
|||||||
return this.spacingToFirstItem >= globalConfig.itemSpacingOnBelts;
|
return this.spacingToFirstItem >= globalConfig.itemSpacingOnBelts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the layer of the this path
|
||||||
|
* @returns {enumLayer}
|
||||||
|
*/
|
||||||
|
get layer() {
|
||||||
|
return this.entityPath[0].layer;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to accept the item
|
* Tries to accept the item
|
||||||
* @param {BaseItem} item
|
* @param {BaseItem} item
|
||||||
@ -1029,6 +1037,11 @@ export class BeltPath extends BasicSerializableObject {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.entityPath[0].layer !== this.root.currentLayer) {
|
||||||
|
// Don't draw
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
parameters.context.fillStyle = "#d79a25";
|
parameters.context.fillStyle = "#d79a25";
|
||||||
parameters.context.strokeStyle = "#d79a25";
|
parameters.context.strokeStyle = "#d79a25";
|
||||||
parameters.context.beginPath();
|
parameters.context.beginPath();
|
||||||
|
@ -3,7 +3,7 @@ import { Loader } from "../core/loader";
|
|||||||
import { createLogger } from "../core/logging";
|
import { createLogger } from "../core/logging";
|
||||||
import { Vector } from "../core/vector";
|
import { Vector } from "../core/vector";
|
||||||
import { Entity } from "./entity";
|
import { Entity } from "./entity";
|
||||||
import { GameRoot } from "./root";
|
import { GameRoot, enumLayer } from "./root";
|
||||||
import { findNiceIntegerValue } from "../core/utils";
|
import { findNiceIntegerValue } from "../core/utils";
|
||||||
import { blueprintShape } from "./upgrades";
|
import { blueprintShape } from "./upgrades";
|
||||||
import { globalConfig } from "../core/config";
|
import { globalConfig } from "../core/config";
|
||||||
@ -18,6 +18,17 @@ export class Blueprint {
|
|||||||
this.entities = entities;
|
this.entities = entities;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the layer of this blueprint
|
||||||
|
* @returns {enumLayer}
|
||||||
|
*/
|
||||||
|
get layer() {
|
||||||
|
if (this.entities.length === 0) {
|
||||||
|
return enumLayer.regular;
|
||||||
|
}
|
||||||
|
return this.entities[0].layer;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new blueprint from the given entity uids
|
* Creates a new blueprint from the given entity uids
|
||||||
* @param {GameRoot} root
|
* @param {GameRoot} root
|
||||||
@ -183,7 +194,7 @@ export class Blueprint {
|
|||||||
rect.moveBy(tile.x, tile.y);
|
rect.moveBy(tile.x, tile.y);
|
||||||
placementCheck: for (let x = rect.x; x < rect.right(); ++x) {
|
placementCheck: for (let x = rect.x; x < rect.right(); ++x) {
|
||||||
for (let y = rect.y; y < rect.bottom(); ++y) {
|
for (let y = rect.y; y < rect.bottom(); ++y) {
|
||||||
const contents = root.map.getTileContentXY(x, y);
|
const contents = root.map.getLayerContentXY(x, y, entity.layer);
|
||||||
if (contents && !contents.components.ReplaceableMapEntity) {
|
if (contents && !contents.components.ReplaceableMapEntity) {
|
||||||
placeable = false;
|
placeable = false;
|
||||||
break placementCheck;
|
break placementCheck;
|
||||||
@ -194,7 +205,7 @@ export class Blueprint {
|
|||||||
if (placeable) {
|
if (placeable) {
|
||||||
for (let x = rect.x; x < rect.right(); ++x) {
|
for (let x = rect.x; x < rect.right(); ++x) {
|
||||||
for (let y = rect.y; y < rect.bottom(); ++y) {
|
for (let y = rect.y; y < rect.bottom(); ++y) {
|
||||||
const contents = root.map.getTileContentXY(x, y);
|
const contents = root.map.getLayerContentXY(x, y, entity.layer);
|
||||||
if (contents) {
|
if (contents) {
|
||||||
assert(
|
assert(
|
||||||
contents.components.ReplaceableMapEntity,
|
contents.components.ReplaceableMapEntity,
|
||||||
|
@ -9,7 +9,7 @@ import { ItemEjectorComponent } from "../components/item_ejector";
|
|||||||
import { ReplaceableMapEntityComponent } from "../components/replaceable_map_entity";
|
import { ReplaceableMapEntityComponent } from "../components/replaceable_map_entity";
|
||||||
import { Entity } from "../entity";
|
import { Entity } from "../entity";
|
||||||
import { MetaBuilding } from "../meta_building";
|
import { MetaBuilding } from "../meta_building";
|
||||||
import { GameRoot } from "../root";
|
import { GameRoot, enumLayer } from "../root";
|
||||||
|
|
||||||
export const arrayBeltVariantToRotation = [enumDirection.top, enumDirection.left, enumDirection.right];
|
export const arrayBeltVariantToRotation = [enumDirection.top, enumDirection.left, enumDirection.right];
|
||||||
|
|
||||||
@ -146,7 +146,7 @@ export class MetaBeltBaseBuilding extends MetaBuilding {
|
|||||||
const bottomDirection = enumAngleToDirection[(rotation + 180) % 360];
|
const bottomDirection = enumAngleToDirection[(rotation + 180) % 360];
|
||||||
const leftDirection = enumAngleToDirection[(rotation + 270) % 360];
|
const leftDirection = enumAngleToDirection[(rotation + 270) % 360];
|
||||||
|
|
||||||
const { ejectors, acceptors } = root.logic.getEjectorsAndAcceptorsAtTile(tile);
|
const { ejectors, acceptors } = root.logic.getEjectorsAndAcceptorsAtTile(tile, enumLayer.regular);
|
||||||
|
|
||||||
let hasBottomEjector = false;
|
let hasBottomEjector = false;
|
||||||
let hasRightEjector = false;
|
let hasRightEjector = false;
|
||||||
|
@ -2,11 +2,12 @@ import { enumDirection, Vector } from "../../core/vector";
|
|||||||
import { ItemAcceptorComponent } from "../components/item_acceptor";
|
import { ItemAcceptorComponent } from "../components/item_acceptor";
|
||||||
import { Entity } from "../entity";
|
import { Entity } from "../entity";
|
||||||
import { MetaBuilding } from "../meta_building";
|
import { MetaBuilding } from "../meta_building";
|
||||||
import { GameRoot } from "../root";
|
import { GameRoot, enumLayer } from "../root";
|
||||||
import { enumHubGoalRewards } from "../tutorial_goals";
|
import { enumHubGoalRewards } from "../tutorial_goals";
|
||||||
import { EnergyGeneratorComponent } from "../components/energy_generator";
|
import { EnergyGeneratorComponent } from "../components/energy_generator";
|
||||||
import { WiredPinsComponent, enumPinSlotType } from "../components/wired_pins";
|
import { WiredPinsComponent, enumPinSlotType } from "../components/wired_pins";
|
||||||
import { enumItemType } from "../base_item";
|
import { enumItemType } from "../base_item";
|
||||||
|
import { ItemEjectorComponent } from "../components/item_ejector";
|
||||||
|
|
||||||
export class MetaEnergyGenerator extends MetaBuilding {
|
export class MetaEnergyGenerator extends MetaBuilding {
|
||||||
constructor() {
|
constructor() {
|
||||||
@ -71,6 +72,25 @@ export class MetaEnergyGenerator extends MetaBuilding {
|
|||||||
directions: [enumDirection.bottom],
|
directions: [enumDirection.bottom],
|
||||||
filter: enumItemType.shape,
|
filter: enumItemType.shape,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
pos: new Vector(1, 0),
|
||||||
|
directions: [enumDirection.top],
|
||||||
|
layer: enumLayer.wires,
|
||||||
|
filter: enumItemType.negativeEnergy,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
entity.addComponent(
|
||||||
|
new ItemEjectorComponent({
|
||||||
|
slots: [
|
||||||
|
{
|
||||||
|
pos: new Vector(0, 0),
|
||||||
|
direction: enumDirection.top,
|
||||||
|
layer: enumLayer.wires,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@ -87,19 +107,13 @@ export class MetaEnergyGenerator extends MetaBuilding {
|
|||||||
slots: [
|
slots: [
|
||||||
{
|
{
|
||||||
pos: new Vector(0, 0),
|
pos: new Vector(0, 0),
|
||||||
type: enumPinSlotType.energyEjector,
|
type: enumPinSlotType.positiveEnergyEjector,
|
||||||
|
direction: enumDirection.top,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pos: new Vector(1, 0),
|
pos: new Vector(1, 0),
|
||||||
type: enumPinSlotType.energyEjector,
|
type: enumPinSlotType.negativeEnergyAcceptor,
|
||||||
},
|
direction: enumDirection.top,
|
||||||
{
|
|
||||||
pos: new Vector(0, 1),
|
|
||||||
type: enumPinSlotType.energyEjector,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
pos: new Vector(1, 1),
|
|
||||||
type: enumPinSlotType.energyEjector,
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
@ -5,7 +5,7 @@ import { ItemEjectorComponent } from "../components/item_ejector";
|
|||||||
import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor";
|
import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor";
|
||||||
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, enumLayer } from "../root";
|
||||||
import { enumHubGoalRewards } from "../tutorial_goals";
|
import { enumHubGoalRewards } from "../tutorial_goals";
|
||||||
import { T } from "../../translations";
|
import { T } from "../../translations";
|
||||||
import { formatItemsPerSecond } from "../../core/utils";
|
import { formatItemsPerSecond } from "../../core/utils";
|
||||||
@ -128,8 +128,8 @@ export class MetaSplitterBuilding extends MetaBuilding {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
entity.components.ItemAcceptor.beltUnderlays = [
|
entity.components.ItemAcceptor.beltUnderlays = [
|
||||||
{ pos: new Vector(0, 0), direction: enumDirection.top },
|
{ pos: new Vector(0, 0), direction: enumDirection.top, layer: enumLayer.regular },
|
||||||
{ pos: new Vector(1, 0), direction: enumDirection.top },
|
{ pos: new Vector(1, 0), direction: enumDirection.top, layer: enumLayer.regular },
|
||||||
];
|
];
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -156,7 +156,7 @@ export class MetaSplitterBuilding extends MetaBuilding {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
entity.components.ItemAcceptor.beltUnderlays = [
|
entity.components.ItemAcceptor.beltUnderlays = [
|
||||||
{ pos: new Vector(0, 0), direction: enumDirection.top },
|
{ pos: new Vector(0, 0), direction: enumDirection.top, layer: enumLayer.regular },
|
||||||
];
|
];
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -5,7 +5,7 @@ import { ItemEjectorComponent } from "../components/item_ejector";
|
|||||||
import { enumUndergroundBeltMode, UndergroundBeltComponent } from "../components/underground_belt";
|
import { enumUndergroundBeltMode, UndergroundBeltComponent } from "../components/underground_belt";
|
||||||
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, enumLayer } from "../root";
|
||||||
import { globalConfig } from "../../core/config";
|
import { globalConfig } from "../../core/config";
|
||||||
import { enumHubGoalRewards } from "../tutorial_goals";
|
import { enumHubGoalRewards } from "../tutorial_goals";
|
||||||
import { formatItemsPerSecond } from "../../core/utils";
|
import { formatItemsPerSecond } from "../../core/utils";
|
||||||
@ -152,7 +152,8 @@ export class MetaUndergroundBeltBuilding extends MetaBuilding {
|
|||||||
) {
|
) {
|
||||||
tile = tile.addScalars(searchVector.x, searchVector.y);
|
tile = tile.addScalars(searchVector.x, searchVector.y);
|
||||||
|
|
||||||
const contents = root.map.getTileContent(tile);
|
/* WIRES: FIXME */
|
||||||
|
const contents = root.map.getTileContent(tile, enumLayer.regular);
|
||||||
if (contents) {
|
if (contents) {
|
||||||
const undergroundComp = contents.components.UndergroundBelt;
|
const undergroundComp = contents.components.UndergroundBelt;
|
||||||
if (undergroundComp && undergroundComp.tier === tier) {
|
if (undergroundComp && undergroundComp.tier === tier) {
|
||||||
|
226
src/js/game/buildings/wire_base.js
Normal file
@ -0,0 +1,226 @@
|
|||||||
|
import { Loader } from "../../core/loader";
|
||||||
|
import { enumAngleToDirection, enumDirection, Vector } from "../../core/vector";
|
||||||
|
import { SOUNDS } from "../../platform/sound";
|
||||||
|
import { BeltComponent } from "../components/belt";
|
||||||
|
import { ItemAcceptorComponent } from "../components/item_acceptor";
|
||||||
|
import { ItemEjectorComponent } from "../components/item_ejector";
|
||||||
|
import { ReplaceableMapEntityComponent } from "../components/replaceable_map_entity";
|
||||||
|
import { Entity } from "../entity";
|
||||||
|
import { MetaBuilding } from "../meta_building";
|
||||||
|
import { enumLayer, GameRoot } from "../root";
|
||||||
|
|
||||||
|
export const arrayBeltVariantToRotation = [enumDirection.top, enumDirection.left, enumDirection.right];
|
||||||
|
|
||||||
|
export class MetaWireBaseBuilding extends MetaBuilding {
|
||||||
|
constructor() {
|
||||||
|
super("wire");
|
||||||
|
}
|
||||||
|
|
||||||
|
getSilhouetteColor() {
|
||||||
|
return "#c425d7";
|
||||||
|
}
|
||||||
|
|
||||||
|
getLayer() {
|
||||||
|
return enumLayer.wires;
|
||||||
|
}
|
||||||
|
|
||||||
|
getHasDirectionLockAvailable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
getPreviewSprite(rotationVariant) {
|
||||||
|
switch (arrayBeltVariantToRotation[rotationVariant]) {
|
||||||
|
case enumDirection.top: {
|
||||||
|
return Loader.getSprite("sprites/buildings/wire_top.png");
|
||||||
|
}
|
||||||
|
case enumDirection.left: {
|
||||||
|
return Loader.getSprite("sprites/buildings/wire_left.png");
|
||||||
|
}
|
||||||
|
case enumDirection.right: {
|
||||||
|
return Loader.getSprite("sprites/buildings/wire_right.png");
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
assertAlways(false, "Invalid belt rotation variant");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getBlueprintSprite(rotationVariant) {
|
||||||
|
switch (arrayBeltVariantToRotation[rotationVariant]) {
|
||||||
|
case enumDirection.top: {
|
||||||
|
return Loader.getSprite("sprites/blueprints/wire_top.png");
|
||||||
|
}
|
||||||
|
case enumDirection.left: {
|
||||||
|
return Loader.getSprite("sprites/blueprints/wire_left.png");
|
||||||
|
}
|
||||||
|
case enumDirection.right: {
|
||||||
|
return Loader.getSprite("sprites/blueprints/wire_right.png");
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
assertAlways(false, "Invalid belt rotation variant");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getStayInPlacementMode() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
getRotateAutomaticallyWhilePlacing() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
getPlacementSound() {
|
||||||
|
return SOUNDS.placeBelt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the entity at the given location
|
||||||
|
* @param {Entity} entity
|
||||||
|
*/
|
||||||
|
setupEntityComponents(entity) {
|
||||||
|
entity.addComponent(
|
||||||
|
new BeltComponent({
|
||||||
|
direction: enumDirection.top, // updated later
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
entity.addComponent(
|
||||||
|
new ItemAcceptorComponent({
|
||||||
|
slots: [
|
||||||
|
{
|
||||||
|
pos: new Vector(0, 0),
|
||||||
|
directions: [enumDirection.bottom],
|
||||||
|
layer: enumLayer.wires,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
animated: false,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
entity.addComponent(
|
||||||
|
new ItemEjectorComponent({
|
||||||
|
slots: [
|
||||||
|
{
|
||||||
|
pos: new Vector(0, 0),
|
||||||
|
direction: enumDirection.top, // updated later
|
||||||
|
layer: enumLayer.wires,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
instantEject: true,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
// Make this entity replaceable
|
||||||
|
entity.addComponent(new ReplaceableMapEntityComponent());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Entity} entity
|
||||||
|
* @param {number} rotationVariant
|
||||||
|
*/
|
||||||
|
updateVariants(entity, rotationVariant) {
|
||||||
|
entity.components.Belt.direction = arrayBeltVariantToRotation[rotationVariant];
|
||||||
|
entity.components.ItemEjector.slots[0].direction = arrayBeltVariantToRotation[rotationVariant];
|
||||||
|
entity.components.StaticMapEntity.spriteKey = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes optimal belt rotation variant
|
||||||
|
* @param {GameRoot} root
|
||||||
|
* @param {Vector} tile
|
||||||
|
* @param {number} rotation
|
||||||
|
* @param {string} variant
|
||||||
|
* @return {{ rotation: number, rotationVariant: number }}
|
||||||
|
*/
|
||||||
|
computeOptimalDirectionAndRotationVariantAtTile(root, tile, rotation, variant) {
|
||||||
|
const topDirection = enumAngleToDirection[rotation];
|
||||||
|
const rightDirection = enumAngleToDirection[(rotation + 90) % 360];
|
||||||
|
const bottomDirection = enumAngleToDirection[(rotation + 180) % 360];
|
||||||
|
const leftDirection = enumAngleToDirection[(rotation + 270) % 360];
|
||||||
|
|
||||||
|
const { ejectors, acceptors } = root.logic.getEjectorsAndAcceptorsAtTile(tile, enumLayer.wires);
|
||||||
|
|
||||||
|
let hasBottomEjector = false;
|
||||||
|
let hasRightEjector = false;
|
||||||
|
let hasLeftEjector = false;
|
||||||
|
|
||||||
|
let hasTopAcceptor = false;
|
||||||
|
let hasLeftAcceptor = false;
|
||||||
|
let hasRightAcceptor = false;
|
||||||
|
|
||||||
|
// Check all ejectors
|
||||||
|
for (let i = 0; i < ejectors.length; ++i) {
|
||||||
|
const ejector = ejectors[i];
|
||||||
|
|
||||||
|
if (ejector.toDirection === topDirection) {
|
||||||
|
hasBottomEjector = true;
|
||||||
|
} else if (ejector.toDirection === leftDirection) {
|
||||||
|
hasRightEjector = true;
|
||||||
|
} else if (ejector.toDirection === rightDirection) {
|
||||||
|
hasLeftEjector = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check all acceptors
|
||||||
|
for (let i = 0; i < acceptors.length; ++i) {
|
||||||
|
const acceptor = acceptors[i];
|
||||||
|
if (acceptor.fromDirection === bottomDirection) {
|
||||||
|
hasTopAcceptor = true;
|
||||||
|
} else if (acceptor.fromDirection === rightDirection) {
|
||||||
|
hasLeftAcceptor = true;
|
||||||
|
} else if (acceptor.fromDirection === leftDirection) {
|
||||||
|
hasRightAcceptor = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Soo .. if there is any ejector below us we always prioritize
|
||||||
|
// this ejector
|
||||||
|
if (!hasBottomEjector) {
|
||||||
|
// When something ejects to us from the left and nothing from the right,
|
||||||
|
// do a curve from the left to the top
|
||||||
|
|
||||||
|
if (hasRightEjector && !hasLeftEjector) {
|
||||||
|
return {
|
||||||
|
rotation: (rotation + 270) % 360,
|
||||||
|
rotationVariant: 2,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// When something ejects to us from the right and nothing from the left,
|
||||||
|
// do a curve from the right to the top
|
||||||
|
if (hasLeftEjector && !hasRightEjector) {
|
||||||
|
return {
|
||||||
|
rotation: (rotation + 90) % 360,
|
||||||
|
rotationVariant: 1,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// When there is a top acceptor, ignore sides
|
||||||
|
// NOTICE: This makes the belt prefer side turns *way* too much!
|
||||||
|
if (!hasTopAcceptor) {
|
||||||
|
// When there is an acceptor to the right but no acceptor to the left,
|
||||||
|
// do a turn to the right
|
||||||
|
if (hasRightAcceptor && !hasLeftAcceptor) {
|
||||||
|
return {
|
||||||
|
rotation,
|
||||||
|
rotationVariant: 2,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// When there is an acceptor to the left but no acceptor to the right,
|
||||||
|
// do a turn to the left
|
||||||
|
if (hasLeftAcceptor && !hasRightAcceptor) {
|
||||||
|
return {
|
||||||
|
rotation,
|
||||||
|
rotationVariant: 1,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
rotation,
|
||||||
|
rotationVariant: 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,10 @@ import { BaseItem } from "../base_item";
|
|||||||
import { Component } from "../component";
|
import { Component } from "../component";
|
||||||
import { ShapeItem } from "../items/shape_item";
|
import { ShapeItem } from "../items/shape_item";
|
||||||
|
|
||||||
const maxQueueSize = 10;
|
const maxQueueSize = 4;
|
||||||
|
|
||||||
|
export const ENERGY_GENERATOR_EJECT_SLOT = 0;
|
||||||
|
export const ENERGY_GENERATOR_ACCEPT_SLOT = 4;
|
||||||
|
|
||||||
export class EnergyGeneratorComponent extends Component {
|
export class EnergyGeneratorComponent extends Component {
|
||||||
static getId() {
|
static getId() {
|
||||||
@ -12,7 +15,8 @@ export class EnergyGeneratorComponent extends Component {
|
|||||||
|
|
||||||
static getSchema() {
|
static getSchema() {
|
||||||
return {
|
return {
|
||||||
requiredKey: types.string,
|
requiredKey: types.nullable(types.string),
|
||||||
|
itemsInQueue: types.uint,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,20 +39,27 @@ export class EnergyGeneratorComponent extends Component {
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {BaseItem} item
|
* @param {BaseItem} item
|
||||||
|
* @param {number} slot
|
||||||
*/
|
*/
|
||||||
tryTakeItem(item) {
|
tryTakeItem(item, slot) {
|
||||||
if (/** @type {ShapeItem} */ (item).definition.getHash() !== this.requiredKey) {
|
if (slot === ENERGY_GENERATOR_ACCEPT_SLOT) {
|
||||||
// Not our shape
|
// this is the acceptor slot on the wires layer
|
||||||
return false;
|
// just destroy it
|
||||||
}
|
return true;
|
||||||
|
} else {
|
||||||
|
if (/** @type {ShapeItem} */ (item).definition.getHash() !== this.requiredKey) {
|
||||||
|
// Not our shape
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.itemsInQueue >= maxQueueSize) {
|
if (this.itemsInQueue >= maxQueueSize) {
|
||||||
// Queue is full
|
// Queue is full
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Take item and put it into the queue
|
// Take item and put it into the queue
|
||||||
++this.itemsInQueue;
|
++this.itemsInQueue;
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,12 @@ import { enumDirection, enumInvertedDirections, Vector } from "../../core/vector
|
|||||||
import { types } from "../../savegame/serialization";
|
import { types } from "../../savegame/serialization";
|
||||||
import { BaseItem, enumItemType } from "../base_item";
|
import { BaseItem, enumItemType } from "../base_item";
|
||||||
import { Component } from "../component";
|
import { Component } from "../component";
|
||||||
|
import { enumLayer } from "../root";
|
||||||
|
|
||||||
/** @typedef {{
|
/** @typedef {{
|
||||||
* pos: Vector,
|
* pos: Vector,
|
||||||
* directions: enumDirection[],
|
* directions: enumDirection[],
|
||||||
|
* layer: enumLayer,
|
||||||
* filter?: enumItemType
|
* filter?: enumItemType
|
||||||
* }} ItemAcceptorSlot */
|
* }} ItemAcceptorSlot */
|
||||||
|
|
||||||
@ -17,6 +19,13 @@ import { Component } from "../component";
|
|||||||
* acceptedDirection: enumDirection
|
* acceptedDirection: enumDirection
|
||||||
* }} ItemAcceptorLocatedSlot */
|
* }} ItemAcceptorLocatedSlot */
|
||||||
|
|
||||||
|
/** @typedef {{
|
||||||
|
* pos: Vector,
|
||||||
|
* directions: enumDirection[],
|
||||||
|
* layer?: enumLayer,
|
||||||
|
* filter?: enumItemType
|
||||||
|
* }} ItemAcceptorSlotConfig */
|
||||||
|
|
||||||
export class ItemAcceptorComponent extends Component {
|
export class ItemAcceptorComponent extends Component {
|
||||||
static getId() {
|
static getId() {
|
||||||
return "ItemAcceptor";
|
return "ItemAcceptor";
|
||||||
@ -29,6 +38,9 @@ export class ItemAcceptorComponent extends Component {
|
|||||||
pos: types.vector,
|
pos: types.vector,
|
||||||
directions: types.array(types.enum(enumDirection)),
|
directions: types.array(types.enum(enumDirection)),
|
||||||
filter: types.nullable(types.enum(enumItemType)),
|
filter: types.nullable(types.enum(enumItemType)),
|
||||||
|
|
||||||
|
// TODO: MIGRATE
|
||||||
|
layer: types.enum(enumLayer),
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
animated: types.bool,
|
animated: types.bool,
|
||||||
@ -36,6 +48,9 @@ export class ItemAcceptorComponent extends Component {
|
|||||||
types.structured({
|
types.structured({
|
||||||
pos: types.vector,
|
pos: types.vector,
|
||||||
direction: types.enum(enumDirection),
|
direction: types.enum(enumDirection),
|
||||||
|
|
||||||
|
// TODO: MIGRATE
|
||||||
|
layer: types.enum(enumLayer),
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
@ -49,6 +64,7 @@ export class ItemAcceptorComponent extends Component {
|
|||||||
pos: slot.pos.copy(),
|
pos: slot.pos.copy(),
|
||||||
directions: slot.directions.slice(),
|
directions: slot.directions.slice(),
|
||||||
filter: slot.filter,
|
filter: slot.filter,
|
||||||
|
layer: slot.layer,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,6 +74,7 @@ export class ItemAcceptorComponent extends Component {
|
|||||||
beltUnderlaysCopy.push({
|
beltUnderlaysCopy.push({
|
||||||
pos: underlay.pos.copy(),
|
pos: underlay.pos.copy(),
|
||||||
direction: underlay.direction,
|
direction: underlay.direction,
|
||||||
|
layer: underlay.layer,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,9 +88,9 @@ export class ItemAcceptorComponent extends Component {
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {object} param0
|
* @param {object} param0
|
||||||
* @param {Array<{pos: Vector, directions: enumDirection[], filter?: enumItemType}>} param0.slots The slots from which we accept items
|
* @param {Array<ItemAcceptorSlotConfig>} param0.slots The slots from which we accept items
|
||||||
* @param {boolean=} param0.animated Whether to animate item consumption
|
* @param {boolean=} param0.animated Whether to animate item consumption
|
||||||
* @param {Array<{pos: Vector, direction: enumDirection}>=} param0.beltUnderlays Where to render belt underlays
|
* @param {Array<{pos: Vector, direction: enumDirection, layer: enumLayer}>=} param0.beltUnderlays Where to render belt underlays
|
||||||
*/
|
*/
|
||||||
constructor({ slots = [], beltUnderlays = [], animated = true }) {
|
constructor({ slots = [], beltUnderlays = [], animated = true }) {
|
||||||
super();
|
super();
|
||||||
@ -82,7 +99,7 @@ export class ItemAcceptorComponent extends Component {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Fixes belt animations
|
* Fixes belt animations
|
||||||
* @type {Array<{ item: BaseItem, slotIndex: number, animProgress: number, direction: enumDirection}>}
|
* @type {Array<{ item: BaseItem, slotIndex: number, animProgress: number, direction: enumDirection }>}
|
||||||
*/
|
*/
|
||||||
this.itemConsumptionAnimations = [];
|
this.itemConsumptionAnimations = [];
|
||||||
|
|
||||||
@ -94,16 +111,17 @@ export class ItemAcceptorComponent extends Component {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {Array<{pos: Vector, directions: enumDirection[], filter?: enumItemType}>} slots
|
* @param {Array<ItemAcceptorSlotConfig>} slots
|
||||||
*/
|
*/
|
||||||
setSlots(slots) {
|
setSlots(slots) {
|
||||||
/** @type {Array<{pos: Vector, directions: enumDirection[], filter?: enumItemType}>} */
|
/** @type {Array<ItemAcceptorSlot>} */
|
||||||
this.slots = [];
|
this.slots = [];
|
||||||
for (let i = 0; i < slots.length; ++i) {
|
for (let i = 0; i < slots.length; ++i) {
|
||||||
const slot = slots[i];
|
const slot = slots[i];
|
||||||
this.slots.push({
|
this.slots.push({
|
||||||
pos: slot.pos,
|
pos: slot.pos,
|
||||||
directions: slot.directions,
|
directions: slot.directions,
|
||||||
|
layer: slot.layer || enumLayer.regular,
|
||||||
|
|
||||||
// Which type of item to accept (shape | color | all) @see enumItemType
|
// Which type of item to accept (shape | color | all) @see enumItemType
|
||||||
filter: slot.filter,
|
filter: slot.filter,
|
||||||
@ -142,9 +160,10 @@ export class ItemAcceptorComponent extends Component {
|
|||||||
* Tries to find a slot which accepts the current item
|
* Tries to find a slot which accepts the current item
|
||||||
* @param {Vector} targetLocalTile
|
* @param {Vector} targetLocalTile
|
||||||
* @param {enumDirection} fromLocalDirection
|
* @param {enumDirection} fromLocalDirection
|
||||||
|
* @param {enumLayer} layer
|
||||||
* @returns {ItemAcceptorLocatedSlot|null}
|
* @returns {ItemAcceptorLocatedSlot|null}
|
||||||
*/
|
*/
|
||||||
findMatchingSlot(targetLocalTile, fromLocalDirection) {
|
findMatchingSlot(targetLocalTile, fromLocalDirection, layer) {
|
||||||
// We need to invert our direction since the acceptor specifies *from* which direction
|
// We need to invert our direction since the acceptor specifies *from* which direction
|
||||||
// it accepts items, but the ejector specifies *into* which direction it ejects items.
|
// it accepts items, but the ejector specifies *into* which direction it ejects items.
|
||||||
// E.g.: Ejector ejects into "right" direction but acceptor accepts from "left" direction.
|
// E.g.: Ejector ejects into "right" direction but acceptor accepts from "left" direction.
|
||||||
@ -159,6 +178,11 @@ export class ItemAcceptorComponent extends Component {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure the layer matches
|
||||||
|
if (slot.layer !== layer) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the acceptor slot accepts items from our direction
|
// Check if the acceptor slot accepts items from our direction
|
||||||
for (let i = 0; i < slot.directions.length; ++i) {
|
for (let i = 0; i < slot.directions.length; ++i) {
|
||||||
// const localDirection = targetStaticComp.localDirectionToWorld(slot.directions[l]);
|
// const localDirection = targetStaticComp.localDirectionToWorld(slot.directions[l]);
|
||||||
|
@ -4,12 +4,14 @@ import { Component } from "../component";
|
|||||||
import { types } from "../../savegame/serialization";
|
import { types } from "../../savegame/serialization";
|
||||||
import { gItemRegistry } from "../../core/global_registries";
|
import { gItemRegistry } from "../../core/global_registries";
|
||||||
import { Entity } from "../entity";
|
import { Entity } from "../entity";
|
||||||
|
import { enumLayer } from "../root";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {{
|
* @typedef {{
|
||||||
* pos: Vector,
|
* pos: Vector,
|
||||||
* direction: enumDirection,
|
* direction: enumDirection,
|
||||||
* item: BaseItem,
|
* item: BaseItem,
|
||||||
|
* layer: enumLayer,
|
||||||
* progress: number?,
|
* progress: number?,
|
||||||
* cachedDestSlot?: import("./item_acceptor").ItemAcceptorLocatedSlot,
|
* cachedDestSlot?: import("./item_acceptor").ItemAcceptorLocatedSlot,
|
||||||
* cachedTargetEntity?: Entity
|
* cachedTargetEntity?: Entity
|
||||||
@ -32,6 +34,9 @@ export class ItemEjectorComponent extends Component {
|
|||||||
direction: types.enum(enumDirection),
|
direction: types.enum(enumDirection),
|
||||||
item: types.nullable(types.obj(gItemRegistry)),
|
item: types.nullable(types.obj(gItemRegistry)),
|
||||||
progress: types.float,
|
progress: types.float,
|
||||||
|
|
||||||
|
// TODO: Migrate
|
||||||
|
layer: types.enum(enumLayer),
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
@ -44,6 +49,7 @@ export class ItemEjectorComponent extends Component {
|
|||||||
slotsCopy.push({
|
slotsCopy.push({
|
||||||
pos: slot.pos.copy(),
|
pos: slot.pos.copy(),
|
||||||
direction: slot.direction,
|
direction: slot.direction,
|
||||||
|
layer: slot.layer,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +62,7 @@ export class ItemEjectorComponent extends Component {
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {object} param0
|
* @param {object} param0
|
||||||
* @param {Array<{pos: Vector, direction: enumDirection}>=} param0.slots The slots to eject on
|
* @param {Array<{pos: Vector, direction: enumDirection, layer?: enumLayer}>=} param0.slots The slots to eject on
|
||||||
* @param {boolean=} param0.instantEject If the ejection is instant
|
* @param {boolean=} param0.instantEject If the ejection is instant
|
||||||
*/
|
*/
|
||||||
constructor({ slots = [], instantEject = false }) {
|
constructor({ slots = [], instantEject = false }) {
|
||||||
@ -77,7 +83,7 @@ export class ItemEjectorComponent extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Array<{pos: Vector, direction: enumDirection}>} slots The slots to eject on
|
* @param {Array<{pos: Vector, direction: enumDirection, layer?: enumLayer}>} slots The slots to eject on
|
||||||
*/
|
*/
|
||||||
setSlots(slots) {
|
setSlots(slots) {
|
||||||
/** @type {Array<ItemEjectorSlot>} */
|
/** @type {Array<ItemEjectorSlot>} */
|
||||||
@ -89,19 +95,13 @@ export class ItemEjectorComponent extends Component {
|
|||||||
direction: slot.direction,
|
direction: slot.direction,
|
||||||
item: null,
|
item: null,
|
||||||
progress: 0,
|
progress: 0,
|
||||||
|
layer: slot.layer || enumLayer.regular,
|
||||||
cachedDestSlot: null,
|
cachedDestSlot: null,
|
||||||
cachedTargetEntity: null,
|
cachedTargetEntity: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the amount of slots
|
|
||||||
*/
|
|
||||||
getNumSlots() {
|
|
||||||
return this.slots.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns where this slot ejects to
|
* Returns where this slot ejects to
|
||||||
* @param {number} index
|
* @param {number} index
|
||||||
@ -116,26 +116,17 @@ export class ItemEjectorComponent extends Component {
|
|||||||
/**
|
/**
|
||||||
* Returns whether any slot ejects to the given local tile
|
* Returns whether any slot ejects to the given local tile
|
||||||
* @param {Vector} tile
|
* @param {Vector} tile
|
||||||
|
* @param {enumLayer} layer
|
||||||
*/
|
*/
|
||||||
anySlotEjectsToLocalTile(tile) {
|
anySlotEjectsToLocalTile(tile, layer) {
|
||||||
for (let i = 0; i < this.slots.length; ++i) {
|
for (let i = 0; i < this.slots.length; ++i) {
|
||||||
if (this.getSlotTargetLocalTile(i).equals(tile)) {
|
if (this.getSlotTargetLocalTile(i).equals(tile) && this.slots[i].layer === layer) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns if slot # is currently ejecting
|
|
||||||
* @param {number} slotIndex
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
isSlotEjecting(slotIndex) {
|
|
||||||
assert(slotIndex >= 0 && slotIndex < this.slots.length, "Invalid ejector slot: " + slotIndex);
|
|
||||||
return !!this.slots[slotIndex].item;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns if we can eject on a given slot
|
* Returns if we can eject on a given slot
|
||||||
* @param {number} slotIndex
|
* @param {number} slotIndex
|
||||||
@ -148,43 +139,18 @@ export class ItemEjectorComponent extends Component {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the first free slot on this ejector or null if there is none
|
* Returns the first free slot on this ejector or null if there is none
|
||||||
|
* @param {enumLayer} layer
|
||||||
* @returns {number?}
|
* @returns {number?}
|
||||||
*/
|
*/
|
||||||
getFirstFreeSlot() {
|
getFirstFreeSlot(layer) {
|
||||||
for (let i = 0; i < this.slots.length; ++i) {
|
for (let i = 0; i < this.slots.length; ++i) {
|
||||||
if (this.canEjectOnSlot(i)) {
|
if (this.canEjectOnSlot(i) && this.slots[i].layer === layer) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns if any slot is ejecting
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
isAnySlotEjecting() {
|
|
||||||
for (let i = 0; i < this.slots.length; ++i) {
|
|
||||||
if (this.slots[i].item) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns if any slot is free
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
hasAnySlotFree() {
|
|
||||||
for (let i = 0; i < this.slots.length; ++i) {
|
|
||||||
if (this.canEjectOnSlot(i)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to eject a given item
|
* Tries to eject a given item
|
||||||
* @param {number} slotIndex
|
* @param {number} slotIndex
|
||||||
|
@ -1,21 +1,25 @@
|
|||||||
import { Component } from "../component";
|
import { Component } from "../component";
|
||||||
import { Vector } from "../../core/vector";
|
import { Vector, enumDirection } from "../../core/vector";
|
||||||
import { types } from "../../savegame/serialization";
|
import { types } from "../../savegame/serialization";
|
||||||
|
|
||||||
/** @enum {string} */
|
/** @enum {string} */
|
||||||
export const enumPinSlotType = {
|
export const enumPinSlotType = {
|
||||||
energyEjector: "energyEjector",
|
positiveEnergyEjector: "positiveEnergyEjector",
|
||||||
|
negativeEnergyEjector: "negativeEnergyEjector",
|
||||||
|
positiveEnergyAcceptor: "positiveEnergyAcceptor",
|
||||||
|
negativeEnergyAcceptor: "positiveEnergyAcceptor",
|
||||||
};
|
};
|
||||||
|
|
||||||
/** @typedef {{
|
/** @typedef {{
|
||||||
* pos: Vector,
|
* pos: Vector,
|
||||||
* type: enumPinSlotType
|
* type: enumPinSlotType,
|
||||||
|
* direction: enumDirection
|
||||||
* }} WirePinSlotDefinition */
|
* }} WirePinSlotDefinition */
|
||||||
|
|
||||||
/** @typedef {{
|
/** @typedef {{
|
||||||
* pos: Vector,
|
* pos: Vector,
|
||||||
* type: enumPinSlotType,
|
* type: enumPinSlotType,
|
||||||
* value: number
|
* direction: enumDirection
|
||||||
* }} WirePinSlot */
|
* }} WirePinSlot */
|
||||||
|
|
||||||
export class WiredPinsComponent extends Component {
|
export class WiredPinsComponent extends Component {
|
||||||
@ -29,7 +33,6 @@ export class WiredPinsComponent extends Component {
|
|||||||
types.structured({
|
types.structured({
|
||||||
pos: types.vector,
|
pos: types.vector,
|
||||||
type: types.enum(enumPinSlotType),
|
type: types.enum(enumPinSlotType),
|
||||||
value: types.float,
|
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
@ -58,7 +61,7 @@ export class WiredPinsComponent extends Component {
|
|||||||
this.slots.push({
|
this.slots.push({
|
||||||
pos: slotData.pos,
|
pos: slotData.pos,
|
||||||
type: slotData.type,
|
type: slotData.type,
|
||||||
value: 0.0,
|
direction: slotData.direction,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ import { GameHUD } from "./hud/hud";
|
|||||||
import { KeyActionMapper } from "./key_action_mapper";
|
import { KeyActionMapper } from "./key_action_mapper";
|
||||||
import { GameLogic } from "./logic";
|
import { GameLogic } from "./logic";
|
||||||
import { MapView } from "./map_view";
|
import { MapView } from "./map_view";
|
||||||
import { GameRoot, enumEditMode } from "./root";
|
import { GameRoot, enumLayer } from "./root";
|
||||||
import { ShapeDefinitionManager } from "./shape_definition_manager";
|
import { ShapeDefinitionManager } from "./shape_definition_manager";
|
||||||
import { SoundProxy } from "./sound_proxy";
|
import { SoundProxy } from "./sound_proxy";
|
||||||
import { GameTime } from "./time/game_time";
|
import { GameTime } from "./time/game_time";
|
||||||
@ -393,26 +393,36 @@ export class GameCore {
|
|||||||
root.map.drawBackground(params);
|
root.map.drawBackground(params);
|
||||||
|
|
||||||
if (!this.root.camera.getIsMapOverlayActive()) {
|
if (!this.root.camera.getIsMapOverlayActive()) {
|
||||||
systems.itemAcceptor.drawUnderlays(params);
|
systems.itemAcceptor.drawUnderlays(params, enumLayer.regular);
|
||||||
systems.belt.draw(params);
|
systems.belt.drawLayer(params, enumLayer.regular);
|
||||||
systems.itemEjector.draw(params);
|
systems.itemEjector.drawLayer(params, enumLayer.regular);
|
||||||
systems.itemAcceptor.draw(params);
|
systems.itemAcceptor.drawLayer(params, enumLayer.regular);
|
||||||
}
|
}
|
||||||
|
|
||||||
root.map.drawForeground(params);
|
root.map.drawForeground(params);
|
||||||
|
|
||||||
if (!this.root.camera.getIsMapOverlayActive()) {
|
if (!this.root.camera.getIsMapOverlayActive()) {
|
||||||
systems.hub.draw(params);
|
systems.hub.draw(params);
|
||||||
systems.energyGenerator.draw(params);
|
systems.energyGenerator.draw(params);
|
||||||
systems.storage.draw(params);
|
systems.storage.draw(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* wires:start */
|
|
||||||
root.hud.parts.wiresOverlay.draw(params);
|
root.hud.parts.wiresOverlay.draw(params);
|
||||||
|
|
||||||
if (this.root.editMode === enumEditMode.wires) {
|
if (this.root.currentLayer === enumLayer.wires) {
|
||||||
systems.wiredPins.drawWiresLayer(params);
|
if (!this.root.camera.getIsMapOverlayActive()) {
|
||||||
|
systems.itemAcceptor.drawUnderlays(params, enumLayer.wires);
|
||||||
|
}
|
||||||
|
|
||||||
|
root.map.drawWiresLayer(params);
|
||||||
|
|
||||||
|
if (!this.root.camera.getIsMapOverlayActive()) {
|
||||||
|
systems.itemEjector.drawLayer(params, enumLayer.wires);
|
||||||
|
systems.itemAcceptor.drawLayer(params, enumLayer.wires);
|
||||||
|
systems.belt.drawLayer(params, enumLayer.wires);
|
||||||
|
systems.wiredPins.draw(params);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* wires:end */
|
|
||||||
|
|
||||||
if (G_IS_DEV) {
|
if (G_IS_DEV) {
|
||||||
root.map.drawStaticEntityDebugOverlays(params);
|
root.map.drawStaticEntityDebugOverlays(params);
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/* typehints:start */
|
/* typehints:start */
|
||||||
import { GameRoot } from "./root";
|
|
||||||
import { DrawParameters } from "../core/draw_parameters";
|
import { DrawParameters } from "../core/draw_parameters";
|
||||||
import { Component } from "./component";
|
import { Component } from "./component";
|
||||||
/* typehints:end */
|
/* typehints:end */
|
||||||
|
|
||||||
|
import { GameRoot, enumLayer } from "./root";
|
||||||
import { globalConfig } from "../core/config";
|
import { globalConfig } from "../core/config";
|
||||||
import { enumDirectionToVector, enumDirectionToAngle } from "../core/vector";
|
import { enumDirectionToVector, enumDirectionToAngle } from "../core/vector";
|
||||||
import { BasicSerializableObject, types } from "../savegame/serialization";
|
import { BasicSerializableObject, types } from "../savegame/serialization";
|
||||||
@ -34,6 +34,11 @@ export class Entity extends BasicSerializableObject {
|
|||||||
*/
|
*/
|
||||||
this.registered = false;
|
this.registered = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On which layer this entity is
|
||||||
|
*/
|
||||||
|
this.layer = enumLayer.regular;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal entity unique id, set by the @see EntityManager
|
* Internal entity unique id, set by the @see EntityManager
|
||||||
*/
|
*/
|
||||||
@ -72,6 +77,7 @@ export class Entity extends BasicSerializableObject {
|
|||||||
return {
|
return {
|
||||||
uid: types.uint,
|
uid: types.uint,
|
||||||
components: types.keyValueMap(types.objData(gComponentRegistry)),
|
components: types.keyValueMap(types.objData(gComponentRegistry)),
|
||||||
|
layer: types.enum(enumLayer),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,6 +89,7 @@ export class Entity extends BasicSerializableObject {
|
|||||||
for (const key in this.components) {
|
for (const key in this.components) {
|
||||||
clone.components[key] = this.components[key].duplicateWithoutContents();
|
clone.components[key] = this.components[key].duplicateWithoutContents();
|
||||||
}
|
}
|
||||||
|
clone.layer = this.layer;
|
||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,6 +169,9 @@ export class Entity extends BasicSerializableObject {
|
|||||||
const ejectorSprite = Loader.getSprite("sprites/debug/ejector_slot.png");
|
const ejectorSprite = Loader.getSprite("sprites/debug/ejector_slot.png");
|
||||||
for (let i = 0; i < ejectorComp.slots.length; ++i) {
|
for (let i = 0; i < ejectorComp.slots.length; ++i) {
|
||||||
const slot = ejectorComp.slots[i];
|
const slot = ejectorComp.slots[i];
|
||||||
|
if (slot.layer !== this.root.currentLayer) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const slotTile = staticComp.localTileToWorld(slot.pos);
|
const slotTile = staticComp.localTileToWorld(slot.pos);
|
||||||
const direction = staticComp.localDirectionToWorld(slot.direction);
|
const direction = staticComp.localDirectionToWorld(slot.direction);
|
||||||
const directionVector = enumDirectionToVector[direction];
|
const directionVector = enumDirectionToVector[direction];
|
||||||
@ -184,6 +194,9 @@ export class Entity extends BasicSerializableObject {
|
|||||||
const acceptorSprite = Loader.getSprite("sprites/debug/acceptor_slot.png");
|
const acceptorSprite = Loader.getSprite("sprites/debug/acceptor_slot.png");
|
||||||
for (let i = 0; i < acceptorComp.slots.length; ++i) {
|
for (let i = 0; i < acceptorComp.slots.length; ++i) {
|
||||||
const slot = acceptorComp.slots[i];
|
const slot = acceptorComp.slots[i];
|
||||||
|
if (slot.layer !== this.root.currentLayer) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const slotTile = staticComp.localTileToWorld(slot.pos);
|
const slotTile = staticComp.localTileToWorld(slot.pos);
|
||||||
for (let k = 0; k < slot.directions.length; ++k) {
|
for (let k = 0; k < slot.directions.length; ++k) {
|
||||||
const direction = staticComp.localDirectionToWorld(slot.directions[k]);
|
const direction = staticComp.localDirectionToWorld(slot.directions[k]);
|
||||||
|
@ -102,9 +102,7 @@ export class GameSystemManager {
|
|||||||
|
|
||||||
add("staticMapEntities", StaticMapEntitySystem);
|
add("staticMapEntities", StaticMapEntitySystem);
|
||||||
|
|
||||||
/* wires:start */
|
|
||||||
add("wiredPins", WiredPinsSystem);
|
add("wiredPins", WiredPinsSystem);
|
||||||
/* wires:end */
|
|
||||||
|
|
||||||
// IMPORTANT: Must be after belt system since belt system can change the
|
// IMPORTANT: Must be after belt system since belt system can change the
|
||||||
// orientation of an entity after it is placed -> the item acceptor cache
|
// orientation of an entity after it is placed -> the item acceptor cache
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/* typehints:start */
|
/* typehints:start */
|
||||||
import { Component } from "./component";
|
import { Component } from "./component";
|
||||||
import { GameRoot } from "./root";
|
|
||||||
import { Entity } from "./entity";
|
import { Entity } from "./entity";
|
||||||
/* typehints:end */
|
/* typehints:end */
|
||||||
|
|
||||||
|
import { GameRoot, enumLayer } from "./root";
|
||||||
import { GameSystem } from "./game_system";
|
import { GameSystem } from "./game_system";
|
||||||
import { arrayDelete, arrayDeleteValue } from "../core/utils";
|
import { arrayDelete, arrayDeleteValue } from "../core/utils";
|
||||||
import { DrawParameters } from "../core/draw_parameters";
|
import { DrawParameters } from "../core/draw_parameters";
|
||||||
@ -39,8 +39,9 @@ export class GameSystemWithFilter extends GameSystem {
|
|||||||
* Calls a function for each matching entity on the screen, useful for drawing them
|
* Calls a function for each matching entity on the screen, useful for drawing them
|
||||||
* @param {DrawParameters} parameters
|
* @param {DrawParameters} parameters
|
||||||
* @param {function} callback
|
* @param {function} callback
|
||||||
|
* @param {enumLayer=} layerFilter Can be null for no filter
|
||||||
*/
|
*/
|
||||||
forEachMatchingEntityOnScreen(parameters, callback) {
|
forEachMatchingEntityOnScreen(parameters, callback, layerFilter = null) {
|
||||||
const cullRange = parameters.visibleRect.toTileCullRectangle();
|
const cullRange = parameters.visibleRect.toTileCullRectangle();
|
||||||
if (this.allEntities.length < 100) {
|
if (this.allEntities.length < 100) {
|
||||||
// So, its much quicker to simply perform per-entity checking
|
// So, its much quicker to simply perform per-entity checking
|
||||||
@ -48,7 +49,9 @@ export class GameSystemWithFilter extends GameSystem {
|
|||||||
for (let i = 0; i < this.allEntities.length; ++i) {
|
for (let i = 0; i < this.allEntities.length; ++i) {
|
||||||
const entity = this.allEntities[i];
|
const entity = this.allEntities[i];
|
||||||
if (cullRange.containsRect(entity.components.StaticMapEntity.getTileSpaceBounds())) {
|
if (cullRange.containsRect(entity.components.StaticMapEntity.getTileSpaceBounds())) {
|
||||||
callback(parameters, entity);
|
if (!layerFilter || entity.layer === layerFilter) {
|
||||||
|
callback(parameters, entity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -91,10 +94,16 @@ export class GameSystemWithFilter extends GameSystem {
|
|||||||
entityLoop: for (let i = 0; i < entities.length; ++i) {
|
entityLoop: for (let i = 0; i < entities.length; ++i) {
|
||||||
const entity = entities[i];
|
const entity = entities[i];
|
||||||
|
|
||||||
|
// Avoid drawing non-layer contents
|
||||||
|
if (layerFilter && entity.layer !== layerFilter) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Avoid drawing twice
|
// Avoid drawing twice
|
||||||
if (seenUids.has(entity.uid)) {
|
if (seenUids.has(entity.uid)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
seenUids.add(entity.uid);
|
seenUids.add(entity.uid);
|
||||||
|
|
||||||
for (let i = 0; i < requiredComponents.length; ++i) {
|
for (let i = 0; i < requiredComponents.length; ++i) {
|
||||||
|
@ -40,6 +40,7 @@ import { HUDWiresOverlay } from "./parts/wires_overlay";
|
|||||||
import { HUDChangesDebugger } from "./parts/debug_changes";
|
import { HUDChangesDebugger } from "./parts/debug_changes";
|
||||||
import { queryParamOptions } from "../../core/query_parameters";
|
import { queryParamOptions } from "../../core/query_parameters";
|
||||||
import { HUDSandboxController } from "./parts/sandbox_controller";
|
import { HUDSandboxController } from "./parts/sandbox_controller";
|
||||||
|
import { HUDWiresToolbar } from "./parts/wires_toolbar";
|
||||||
|
|
||||||
export class GameHUD {
|
export class GameHUD {
|
||||||
/**
|
/**
|
||||||
@ -56,6 +57,7 @@ export class GameHUD {
|
|||||||
this.parts = {
|
this.parts = {
|
||||||
processingOverlay: new HUDProcessingOverlay(this.root),
|
processingOverlay: new HUDProcessingOverlay(this.root),
|
||||||
buildingsToolbar: new HUDBuildingsToolbar(this.root),
|
buildingsToolbar: new HUDBuildingsToolbar(this.root),
|
||||||
|
wiresToolbar: new HUDWiresToolbar(this.root),
|
||||||
blueprintPlacer: new HUDBlueprintPlacer(this.root),
|
blueprintPlacer: new HUDBlueprintPlacer(this.root),
|
||||||
buildingPlacer: new HUDBuildingPlacer(this.root),
|
buildingPlacer: new HUDBuildingPlacer(this.root),
|
||||||
unlockNotification: new HUDUnlockNotification(this.root),
|
unlockNotification: new HUDUnlockNotification(this.root),
|
||||||
@ -75,9 +77,7 @@ export class GameHUD {
|
|||||||
screenshotExporter: new HUDScreenshotExporter(this.root),
|
screenshotExporter: new HUDScreenshotExporter(this.root),
|
||||||
shapeViewer: new HUDShapeViewer(this.root),
|
shapeViewer: new HUDShapeViewer(this.root),
|
||||||
|
|
||||||
/* wires:start */
|
|
||||||
wiresOverlay: new HUDWiresOverlay(this.root),
|
wiresOverlay: new HUDWiresOverlay(this.root),
|
||||||
/* wires:end */
|
|
||||||
|
|
||||||
// Typing hints
|
// Typing hints
|
||||||
/* typehints:start */
|
/* typehints:start */
|
||||||
@ -87,6 +87,7 @@ export class GameHUD {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.signals = {
|
this.signals = {
|
||||||
|
buildingSelectedForPlacement: /** @type {TypedSignal<[MetaBuilding|null]>} */ (new Signal()),
|
||||||
selectedPlacementBuildingChanged: /** @type {TypedSignal<[MetaBuilding|null]>} */ (new Signal()),
|
selectedPlacementBuildingChanged: /** @type {TypedSignal<[MetaBuilding|null]>} */ (new Signal()),
|
||||||
shapePinRequested: /** @type {TypedSignal<[ShapeDefinition]>} */ (new Signal()),
|
shapePinRequested: /** @type {TypedSignal<[ShapeDefinition]>} */ (new Signal()),
|
||||||
shapeUnpinRequested: /** @type {TypedSignal<[string]>} */ (new Signal()),
|
shapeUnpinRequested: /** @type {TypedSignal<[string]>} */ (new Signal()),
|
||||||
@ -139,7 +140,6 @@ export class GameHUD {
|
|||||||
for (const key in this.parts) {
|
for (const key in this.parts) {
|
||||||
this.parts[key].initialize();
|
this.parts[key].initialize();
|
||||||
}
|
}
|
||||||
this.internalInitSignalConnections();
|
|
||||||
|
|
||||||
this.root.keyMapper.getBinding(KEYMAPPINGS.ingame.toggleHud).add(this.toggleUi, this);
|
this.root.keyMapper.getBinding(KEYMAPPINGS.ingame.toggleHud).add(this.toggleUi, this);
|
||||||
|
|
||||||
@ -205,14 +205,6 @@ export class GameHUD {
|
|||||||
document.body.classList.toggle("uiHidden");
|
document.body.classList.toggle("uiHidden");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes connections between parts
|
|
||||||
*/
|
|
||||||
internalInitSignalConnections() {
|
|
||||||
const p = this.parts;
|
|
||||||
p.buildingsToolbar.sigBuildingSelected.add(p.buildingPlacer.startSelection, p.buildingPlacer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates all parts
|
* Updates all parts
|
||||||
*/
|
*/
|
||||||
|
@ -1,23 +1,26 @@
|
|||||||
import { gMetaBuildingRegistry } from "../../../core/global_registries";
|
import { gMetaBuildingRegistry } from "../../../core/global_registries";
|
||||||
import { Signal, STOP_PROPAGATION } from "../../../core/signal";
|
import { Signal, STOP_PROPAGATION } from "../../../core/signal";
|
||||||
import { TrackedState } from "../../../core/tracked_state";
|
|
||||||
import { makeDiv } from "../../../core/utils";
|
import { makeDiv } from "../../../core/utils";
|
||||||
import { KEYMAPPINGS } from "../../key_action_mapper";
|
import { KEYMAPPINGS } from "../../key_action_mapper";
|
||||||
import { MetaBuilding } from "../../meta_building";
|
import { MetaBuilding } from "../../meta_building";
|
||||||
import { BaseHUDPart } from "../base_hud_part";
|
|
||||||
import { GameRoot } from "../../root";
|
import { GameRoot } from "../../root";
|
||||||
|
import { BaseHUDPart } from "../base_hud_part";
|
||||||
|
import { DynamicDomAttach } from "../dynamic_dom_attach";
|
||||||
|
|
||||||
export class HUDBaseToolbar extends BaseHUDPart {
|
export class HUDBaseToolbar extends BaseHUDPart {
|
||||||
/**
|
/**
|
||||||
* @param {GameRoot} root
|
* @param {GameRoot} root
|
||||||
* @param {Array<typeof MetaBuilding>} supportedBuildings
|
* @param {object} param0
|
||||||
* @param {function} visibilityCondition
|
* @param {Array<typeof MetaBuilding>} param0.supportedBuildings
|
||||||
|
* @param {function} param0.visibilityCondition
|
||||||
|
* @param {string} param0.htmlElementId
|
||||||
*/
|
*/
|
||||||
constructor(root, supportedBuildings, visibilityCondition) {
|
constructor(root, { supportedBuildings, visibilityCondition, htmlElementId }) {
|
||||||
super(root);
|
super(root);
|
||||||
|
|
||||||
this.supportedBuildings = supportedBuildings;
|
this.supportedBuildings = supportedBuildings;
|
||||||
this.visibilityCondition = visibilityCondition;
|
this.visibilityCondition = visibilityCondition;
|
||||||
|
this.htmlElementId = htmlElementId;
|
||||||
|
|
||||||
/** @type {Object.<string, {
|
/** @type {Object.<string, {
|
||||||
* metaBuilding: MetaBuilding,
|
* metaBuilding: MetaBuilding,
|
||||||
@ -27,17 +30,6 @@ export class HUDBaseToolbar extends BaseHUDPart {
|
|||||||
* index: number
|
* index: number
|
||||||
* }>} */
|
* }>} */
|
||||||
this.buildingHandles = {};
|
this.buildingHandles = {};
|
||||||
|
|
||||||
this.sigBuildingSelected = new Signal();
|
|
||||||
this.trackedIsVisisible = new TrackedState(this.onVisibilityChanged, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the visibility of the toolbar changed
|
|
||||||
* @param {boolean} visible
|
|
||||||
*/
|
|
||||||
onVisibilityChanged(visible) {
|
|
||||||
this.element.classList.toggle("visible", visible);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -45,7 +37,7 @@ export class HUDBaseToolbar extends BaseHUDPart {
|
|||||||
* @param {HTMLElement} parent
|
* @param {HTMLElement} parent
|
||||||
*/
|
*/
|
||||||
createElements(parent) {
|
createElements(parent) {
|
||||||
this.element = makeDiv(parent, "ingame_HUD_buildings_toolbar", ["ingame_buildingsToolbar"], "");
|
this.element = makeDiv(parent, this.htmlElementId, ["ingame_buildingsToolbar"], "");
|
||||||
}
|
}
|
||||||
|
|
||||||
initialize() {
|
initialize() {
|
||||||
@ -80,6 +72,10 @@ export class HUDBaseToolbar extends BaseHUDPart {
|
|||||||
this
|
this
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.domAttach = new DynamicDomAttach(this.root, this.element, {
|
||||||
|
timeToKeepSeconds: 0.12,
|
||||||
|
attachClass: "visible",
|
||||||
|
});
|
||||||
this.lastSelectedIndex = 0;
|
this.lastSelectedIndex = 0;
|
||||||
actionMapper.getBinding(KEYMAPPINGS.placement.cycleBuildings).add(this.cycleBuildings, this);
|
actionMapper.getBinding(KEYMAPPINGS.placement.cycleBuildings).add(this.cycleBuildings, this);
|
||||||
}
|
}
|
||||||
@ -88,11 +84,10 @@ export class HUDBaseToolbar extends BaseHUDPart {
|
|||||||
* Updates the toolbar
|
* Updates the toolbar
|
||||||
*/
|
*/
|
||||||
update() {
|
update() {
|
||||||
this.trackedIsVisisible.set(this.visibilityCondition());
|
const visible = this.visibilityCondition();
|
||||||
|
this.domAttach.update(visible);
|
||||||
|
|
||||||
if (!this.trackedIsVisisible.get()) {
|
if (visible) {
|
||||||
// Currently not active
|
|
||||||
} else {
|
|
||||||
for (const buildingId in this.buildingHandles) {
|
for (const buildingId in this.buildingHandles) {
|
||||||
const handle = this.buildingHandles[buildingId];
|
const handle = this.buildingHandles[buildingId];
|
||||||
const newStatus = handle.metaBuilding.getIsUnlocked(this.root);
|
const newStatus = handle.metaBuilding.getIsUnlocked(this.root);
|
||||||
@ -166,7 +161,7 @@ export class HUDBaseToolbar extends BaseHUDPart {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.root.soundProxy.playUiClick();
|
this.root.soundProxy.playUiClick();
|
||||||
this.sigBuildingSelected.dispatch(metaBuilding);
|
this.root.hud.signals.buildingSelectedForPlacement.dispatch(metaBuilding);
|
||||||
this.onSelectedPlacementBuildingChanged(metaBuilding);
|
this.onSelectedPlacementBuildingChanged(metaBuilding);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import { BaseHUDPart } from "../base_hud_part";
|
|||||||
import { DynamicDomAttach } from "../dynamic_dom_attach";
|
import { DynamicDomAttach } from "../dynamic_dom_attach";
|
||||||
import { Blueprint } from "../../blueprint";
|
import { Blueprint } from "../../blueprint";
|
||||||
import { SOUNDS } from "../../../platform/sound";
|
import { SOUNDS } from "../../../platform/sound";
|
||||||
|
import { enumLayer } from "../../root";
|
||||||
|
|
||||||
export class HUDBlueprintPlacer extends BaseHUDPart {
|
export class HUDBlueprintPlacer extends BaseHUDPart {
|
||||||
createElements(parent) {
|
createElements(parent) {
|
||||||
@ -26,7 +27,7 @@ export class HUDBlueprintPlacer extends BaseHUDPart {
|
|||||||
}
|
}
|
||||||
|
|
||||||
initialize() {
|
initialize() {
|
||||||
this.root.hud.signals.buildingsSelectedForCopy.add(this.onBuildingsSelected, this);
|
this.root.hud.signals.buildingsSelectedForCopy.add(this.createBlueprintFromBuildings, this);
|
||||||
|
|
||||||
/** @type {TypedTrackedState<Blueprint?>} */
|
/** @type {TypedTrackedState<Blueprint?>} */
|
||||||
this.currentBlueprint = new TrackedState(this.onBlueprintChanged, this);
|
this.currentBlueprint = new TrackedState(this.onBlueprintChanged, this);
|
||||||
@ -43,6 +44,7 @@ export class HUDBlueprintPlacer extends BaseHUDPart {
|
|||||||
this.root.camera.movePreHandler.add(this.onMouseMove, this);
|
this.root.camera.movePreHandler.add(this.onMouseMove, this);
|
||||||
|
|
||||||
this.root.hud.signals.selectedPlacementBuildingChanged.add(this.abortPlacement, this);
|
this.root.hud.signals.selectedPlacementBuildingChanged.add(this.abortPlacement, this);
|
||||||
|
this.root.signals.editModeChanged.add(this.onEditModeChanged, this);
|
||||||
|
|
||||||
this.domAttach = new DynamicDomAttach(this.root, this.costDisplayParent);
|
this.domAttach = new DynamicDomAttach(this.root, this.costDisplayParent);
|
||||||
this.trackedCanAfford = new TrackedState(this.onCanAffordChanged, this);
|
this.trackedCanAfford = new TrackedState(this.onCanAffordChanged, this);
|
||||||
@ -56,6 +58,24 @@ export class HUDBlueprintPlacer extends BaseHUDPart {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the layer was changed
|
||||||
|
* @param {enumLayer} layer
|
||||||
|
*/
|
||||||
|
onEditModeChanged(layer) {
|
||||||
|
// Check if the layer of the blueprint differs and thus we have to deselect it
|
||||||
|
const blueprint = this.currentBlueprint.get();
|
||||||
|
if (blueprint) {
|
||||||
|
if (blueprint.layer !== layer) {
|
||||||
|
this.currentBlueprint.set(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the blueprint is now affordable or not
|
||||||
|
* @param {boolean} canAfford
|
||||||
|
*/
|
||||||
onCanAffordChanged(canAfford) {
|
onCanAffordChanged(canAfford) {
|
||||||
this.costDisplayParent.classList.toggle("canAfford", canAfford);
|
this.costDisplayParent.classList.toggle("canAfford", canAfford);
|
||||||
}
|
}
|
||||||
@ -67,6 +87,7 @@ export class HUDBlueprintPlacer extends BaseHUDPart {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Called when the blueprint was changed
|
||||||
* @param {Blueprint} blueprint
|
* @param {Blueprint} blueprint
|
||||||
*/
|
*/
|
||||||
onBlueprintChanged(blueprint) {
|
onBlueprintChanged(blueprint) {
|
||||||
@ -105,13 +126,12 @@ export class HUDBlueprintPlacer extends BaseHUDPart {
|
|||||||
const cost = blueprint.getCost();
|
const cost = blueprint.getCost();
|
||||||
this.root.hubGoals.takeShapeByKey(blueprintShape, cost);
|
this.root.hubGoals.takeShapeByKey(blueprintShape, cost);
|
||||||
this.root.soundProxy.playUi(SOUNDS.placeBuilding);
|
this.root.soundProxy.playUi(SOUNDS.placeBuilding);
|
||||||
// This actually feels weird
|
|
||||||
// if (!this.root.keyMapper.getBinding(KEYMAPPINGS.placementModifiers.placeMultiple).pressed) {
|
|
||||||
// this.currentBlueprint.set(null);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mose move handler
|
||||||
|
*/
|
||||||
onMouseMove() {
|
onMouseMove() {
|
||||||
// Prevent movement while blueprint is selected
|
// Prevent movement while blueprint is selected
|
||||||
if (this.currentBlueprint.get()) {
|
if (this.currentBlueprint.get()) {
|
||||||
@ -120,15 +140,19 @@ export class HUDBlueprintPlacer extends BaseHUDPart {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Called when an array of bulidings was selected
|
||||||
* @param {Array<number>} uids
|
* @param {Array<number>} uids
|
||||||
*/
|
*/
|
||||||
onBuildingsSelected(uids) {
|
createBlueprintFromBuildings(uids) {
|
||||||
if (uids.length === 0) {
|
if (uids.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.currentBlueprint.set(Blueprint.fromUids(this.root, uids));
|
this.currentBlueprint.set(Blueprint.fromUids(this.root, uids));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to rotate the current blueprint
|
||||||
|
*/
|
||||||
rotateBlueprint() {
|
rotateBlueprint() {
|
||||||
if (this.currentBlueprint.get()) {
|
if (this.currentBlueprint.get()) {
|
||||||
if (this.root.keyMapper.getBinding(KEYMAPPINGS.placement.rotateInverseModifier).pressed) {
|
if (this.root.keyMapper.getBinding(KEYMAPPINGS.placement.rotateInverseModifier).pressed) {
|
||||||
@ -139,8 +163,17 @@ export class HUDBlueprintPlacer extends BaseHUDPart {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to paste the last blueprint
|
||||||
|
*/
|
||||||
pasteBlueprint() {
|
pasteBlueprint() {
|
||||||
if (this.lastBlueprintUsed !== null) {
|
if (this.lastBlueprintUsed !== null) {
|
||||||
|
if (this.lastBlueprintUsed.layer !== this.root.currentLayer) {
|
||||||
|
// Not compatible
|
||||||
|
this.root.soundProxy.playUiError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.root.hud.signals.pasteBlueprintRequested.dispatch();
|
this.root.hud.signals.pasteBlueprintRequested.dispatch();
|
||||||
this.currentBlueprint.set(this.lastBlueprintUsed);
|
this.currentBlueprint.set(this.lastBlueprintUsed);
|
||||||
} else {
|
} else {
|
||||||
|
@ -49,6 +49,7 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic {
|
|||||||
|
|
||||||
// Bind to signals
|
// Bind to signals
|
||||||
this.signals.variantChanged.add(this.rerenderVariants, this);
|
this.signals.variantChanged.add(this.rerenderVariants, this);
|
||||||
|
this.root.hud.signals.buildingSelectedForPlacement.add(this.startSelection, this);
|
||||||
|
|
||||||
this.domAttach = new DynamicDomAttach(this.root, this.element, {});
|
this.domAttach = new DynamicDomAttach(this.root, this.element, {});
|
||||||
this.variantsAttach = new DynamicDomAttach(this.root, this.variantsElement, {});
|
this.variantsAttach = new DynamicDomAttach(this.root, this.variantsElement, {});
|
||||||
@ -389,7 +390,7 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic {
|
|||||||
const goodArrowSprite = Loader.getSprite("sprites/misc/slot_good_arrow.png");
|
const goodArrowSprite = Loader.getSprite("sprites/misc/slot_good_arrow.png");
|
||||||
const badArrowSprite = Loader.getSprite("sprites/misc/slot_bad_arrow.png");
|
const badArrowSprite = Loader.getSprite("sprites/misc/slot_bad_arrow.png");
|
||||||
|
|
||||||
// Just ignore this code ...
|
// Just ignore the following code please ... thanks!
|
||||||
|
|
||||||
const offsetShift = 10;
|
const offsetShift = 10;
|
||||||
|
|
||||||
@ -397,6 +398,7 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic {
|
|||||||
const slots = acceptorComp.slots;
|
const slots = acceptorComp.slots;
|
||||||
for (let acceptorSlotIndex = 0; acceptorSlotIndex < slots.length; ++acceptorSlotIndex) {
|
for (let acceptorSlotIndex = 0; acceptorSlotIndex < slots.length; ++acceptorSlotIndex) {
|
||||||
const slot = slots[acceptorSlotIndex];
|
const slot = slots[acceptorSlotIndex];
|
||||||
|
|
||||||
const acceptorSlotWsTile = staticComp.localTileToWorld(slot.pos);
|
const acceptorSlotWsTile = staticComp.localTileToWorld(slot.pos);
|
||||||
const acceptorSlotWsPos = acceptorSlotWsTile.toWorldSpaceCenterOfTile();
|
const acceptorSlotWsPos = acceptorSlotWsTile.toWorldSpaceCenterOfTile();
|
||||||
|
|
||||||
@ -409,7 +411,7 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic {
|
|||||||
const worldDirection = staticComp.localDirectionToWorld(direction);
|
const worldDirection = staticComp.localDirectionToWorld(direction);
|
||||||
|
|
||||||
const sourceTile = acceptorSlotWsTile.add(enumDirectionToVector[worldDirection]);
|
const sourceTile = acceptorSlotWsTile.add(enumDirectionToVector[worldDirection]);
|
||||||
const sourceEntity = this.root.map.getTileContent(sourceTile);
|
const sourceEntity = this.root.map.getTileContent(sourceTile, this.root.currentLayer);
|
||||||
|
|
||||||
let sprite = goodArrowSprite;
|
let sprite = goodArrowSprite;
|
||||||
let alpha = 0.5;
|
let alpha = 0.5;
|
||||||
@ -419,7 +421,13 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic {
|
|||||||
const sourceEjector = sourceEntity.components.ItemEjector;
|
const sourceEjector = sourceEntity.components.ItemEjector;
|
||||||
const sourceStaticComp = sourceEntity.components.StaticMapEntity;
|
const sourceStaticComp = sourceEntity.components.StaticMapEntity;
|
||||||
const ejectorAcceptLocalTile = sourceStaticComp.worldToLocalTile(acceptorSlotWsTile);
|
const ejectorAcceptLocalTile = sourceStaticComp.worldToLocalTile(acceptorSlotWsTile);
|
||||||
if (sourceEjector && sourceEjector.anySlotEjectsToLocalTile(ejectorAcceptLocalTile)) {
|
if (
|
||||||
|
sourceEjector &&
|
||||||
|
sourceEjector.anySlotEjectsToLocalTile(
|
||||||
|
ejectorAcceptLocalTile,
|
||||||
|
this.root.currentLayer
|
||||||
|
)
|
||||||
|
) {
|
||||||
sprite = goodArrowSprite;
|
sprite = goodArrowSprite;
|
||||||
}
|
}
|
||||||
alpha = 1.0;
|
alpha = 1.0;
|
||||||
@ -443,7 +451,10 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic {
|
|||||||
if (ejectorComp) {
|
if (ejectorComp) {
|
||||||
const slots = ejectorComp.slots;
|
const slots = ejectorComp.slots;
|
||||||
for (let ejectorSlotIndex = 0; ejectorSlotIndex < slots.length; ++ejectorSlotIndex) {
|
for (let ejectorSlotIndex = 0; ejectorSlotIndex < slots.length; ++ejectorSlotIndex) {
|
||||||
const slot = ejectorComp.slots[ejectorSlotIndex];
|
const slot = slots[ejectorSlotIndex];
|
||||||
|
if (slot.layer !== this.root.currentLayer) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const ejectorSlotWsTile = staticComp.localTileToWorld(
|
const ejectorSlotWsTile = staticComp.localTileToWorld(
|
||||||
ejectorComp.getSlotTargetLocalTile(ejectorSlotIndex)
|
ejectorComp.getSlotTargetLocalTile(ejectorSlotIndex)
|
||||||
@ -451,7 +462,7 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic {
|
|||||||
const ejectorSLotWsPos = ejectorSlotWsTile.toWorldSpaceCenterOfTile();
|
const ejectorSLotWsPos = ejectorSlotWsTile.toWorldSpaceCenterOfTile();
|
||||||
const ejectorSlotWsDirection = staticComp.localDirectionToWorld(slot.direction);
|
const ejectorSlotWsDirection = staticComp.localDirectionToWorld(slot.direction);
|
||||||
|
|
||||||
const destEntity = this.root.map.getTileContent(ejectorSlotWsTile);
|
const destEntity = this.root.map.getTileContent(ejectorSlotWsTile, this.root.currentLayer);
|
||||||
|
|
||||||
let sprite = goodArrowSprite;
|
let sprite = goodArrowSprite;
|
||||||
let alpha = 0.5;
|
let alpha = 0.5;
|
||||||
@ -463,7 +474,9 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic {
|
|||||||
if (destAcceptor) {
|
if (destAcceptor) {
|
||||||
const destLocalTile = destStaticComp.worldToLocalTile(ejectorSlotWsTile);
|
const destLocalTile = destStaticComp.worldToLocalTile(ejectorSlotWsTile);
|
||||||
const destLocalDir = destStaticComp.worldDirectionToLocal(ejectorSlotWsDirection);
|
const destLocalDir = destStaticComp.worldDirectionToLocal(ejectorSlotWsDirection);
|
||||||
if (destAcceptor.findMatchingSlot(destLocalTile, destLocalDir)) {
|
if (
|
||||||
|
destAcceptor.findMatchingSlot(destLocalTile, destLocalDir, this.root.currentLayer)
|
||||||
|
) {
|
||||||
sprite = goodArrowSprite;
|
sprite = goodArrowSprite;
|
||||||
} else {
|
} else {
|
||||||
sprite = badArrowSprite;
|
sprite = badArrowSprite;
|
||||||
|
@ -12,7 +12,7 @@ import { BaseHUDPart } from "../base_hud_part";
|
|||||||
import { SOUNDS } from "../../../platform/sound";
|
import { SOUNDS } from "../../../platform/sound";
|
||||||
import { MetaMinerBuilding, enumMinerVariants } from "../../buildings/miner";
|
import { MetaMinerBuilding, enumMinerVariants } from "../../buildings/miner";
|
||||||
import { enumHubGoalRewards } from "../../tutorial_goals";
|
import { enumHubGoalRewards } from "../../tutorial_goals";
|
||||||
import { enumEditMode } from "../../root";
|
import { enumLayer } from "../../root";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains all logic for the building placer - this doesn't include the rendering
|
* Contains all logic for the building placer - this doesn't include the rendering
|
||||||
@ -125,12 +125,12 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the edit mode got changed
|
* Called when the edit mode got changed
|
||||||
* @param {enumEditMode} editMode
|
* @param {enumLayer} editMode
|
||||||
*/
|
*/
|
||||||
onEditModeChanged(editMode) {
|
onEditModeChanged(editMode) {
|
||||||
const metaBuilding = this.currentMetaBuilding.get();
|
const metaBuilding = this.currentMetaBuilding.get();
|
||||||
if (metaBuilding) {
|
if (metaBuilding) {
|
||||||
if (metaBuilding.getEditLayer() !== editMode) {
|
if (metaBuilding.getLayer() !== editMode) {
|
||||||
// This layer doesn't fit the edit mode anymore
|
// This layer doesn't fit the edit mode anymore
|
||||||
this.currentMetaBuilding.set(null);
|
this.currentMetaBuilding.set(null);
|
||||||
}
|
}
|
||||||
@ -276,7 +276,7 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart {
|
|||||||
|
|
||||||
const worldPos = this.root.camera.screenToWorld(mousePosition);
|
const worldPos = this.root.camera.screenToWorld(mousePosition);
|
||||||
const tile = worldPos.toTileSpace();
|
const tile = worldPos.toTileSpace();
|
||||||
const contents = this.root.map.getTileContent(tile);
|
const contents = this.root.map.getTileContent(tile, this.root.currentLayer);
|
||||||
if (contents) {
|
if (contents) {
|
||||||
if (this.root.logic.tryDeleteBuilding(contents)) {
|
if (this.root.logic.tryDeleteBuilding(contents)) {
|
||||||
this.root.soundProxy.playUi(SOUNDS.destroyBuilding);
|
this.root.soundProxy.playUi(SOUNDS.destroyBuilding);
|
||||||
@ -302,7 +302,7 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart {
|
|||||||
const worldPos = this.root.camera.screenToWorld(mousePosition);
|
const worldPos = this.root.camera.screenToWorld(mousePosition);
|
||||||
const tile = worldPos.toTileSpace();
|
const tile = worldPos.toTileSpace();
|
||||||
|
|
||||||
const contents = this.root.map.getTileContent(tile);
|
const contents = this.root.map.getTileContent(tile, this.root.currentLayer);
|
||||||
if (!contents) {
|
if (!contents) {
|
||||||
const tileBelow = this.root.map.getLowerLayerContentXY(tile.x, tile.y);
|
const tileBelow = this.root.map.getLowerLayerContentXY(tile.x, tile.y);
|
||||||
|
|
||||||
@ -322,6 +322,7 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart {
|
|||||||
|
|
||||||
// Try to extract the building
|
// Try to extract the building
|
||||||
const extracted = this.hack_reconstructMetaBuildingAndVariantFromBuilding(contents);
|
const extracted = this.hack_reconstructMetaBuildingAndVariantFromBuilding(contents);
|
||||||
|
|
||||||
// If the building we are picking is the same as the one we have, clear the cursor.
|
// If the building we are picking is the same as the one we have, clear the cursor.
|
||||||
if (
|
if (
|
||||||
!extracted ||
|
!extracted ||
|
||||||
@ -335,11 +336,6 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart {
|
|||||||
this.currentMetaBuilding.set(extracted.metaBuilding);
|
this.currentMetaBuilding.set(extracted.metaBuilding);
|
||||||
this.currentVariant.set(extracted.variant);
|
this.currentVariant.set(extracted.variant);
|
||||||
this.currentBaseRotation = contents.components.StaticMapEntity.rotation;
|
this.currentBaseRotation = contents.components.StaticMapEntity.rotation;
|
||||||
|
|
||||||
// Make sure we selected something, and also make sure it's not a special entity
|
|
||||||
// if (contents && !contents.components.Unremovable) {
|
|
||||||
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -760,7 +756,7 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart {
|
|||||||
while (this.currentlyDeleting || this.currentMetaBuilding.get()) {
|
while (this.currentlyDeleting || this.currentMetaBuilding.get()) {
|
||||||
if (this.currentlyDeleting) {
|
if (this.currentlyDeleting) {
|
||||||
// Deletion
|
// Deletion
|
||||||
const contents = this.root.map.getTileContentXY(x0, y0);
|
const contents = this.root.map.getLayerContentXY(x0, y0, this.root.currentLayer);
|
||||||
if (contents && !contents.queuedForDestroy && !contents.destroyed) {
|
if (contents && !contents.queuedForDestroy && !contents.destroyed) {
|
||||||
if (this.root.logic.tryDeleteBuilding(contents)) {
|
if (this.root.logic.tryDeleteBuilding(contents)) {
|
||||||
anythingDeleted = true;
|
anythingDeleted = true;
|
||||||
|
@ -9,10 +9,10 @@ import { MetaSplitterBuilding } from "../../buildings/splitter";
|
|||||||
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";
|
||||||
import { enumEditMode } from "../../root";
|
import { enumLayer } from "../../root";
|
||||||
import { HUDBaseToolbar } from "./base_toolbar";
|
import { HUDBaseToolbar } from "./base_toolbar";
|
||||||
|
|
||||||
const toolbarBuildings = [
|
const supportedBuildings = [
|
||||||
MetaBeltBaseBuilding,
|
MetaBeltBaseBuilding,
|
||||||
MetaSplitterBuilding,
|
MetaSplitterBuilding,
|
||||||
MetaUndergroundBeltBuilding,
|
MetaUndergroundBeltBuilding,
|
||||||
@ -24,17 +24,16 @@ const toolbarBuildings = [
|
|||||||
MetaPainterBuilding,
|
MetaPainterBuilding,
|
||||||
MetaTrashBuilding,
|
MetaTrashBuilding,
|
||||||
|
|
||||||
/* wires:start */
|
|
||||||
MetaEnergyGenerator,
|
MetaEnergyGenerator,
|
||||||
/* wires:end */
|
|
||||||
];
|
];
|
||||||
|
|
||||||
export class HUDBuildingsToolbar extends HUDBaseToolbar {
|
export class HUDBuildingsToolbar extends HUDBaseToolbar {
|
||||||
constructor(root) {
|
constructor(root) {
|
||||||
super(
|
super(root, {
|
||||||
root,
|
supportedBuildings,
|
||||||
toolbarBuildings,
|
visibilityCondition: () =>
|
||||||
() => !this.root.camera.getIsMapOverlayActive() && this.root.editMode === enumEditMode.regular
|
!this.root.camera.getIsMapOverlayActive() && this.root.currentLayer === enumLayer.regular,
|
||||||
);
|
htmlElementId: "ingame_HUD_buildings_toolbar",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ import { THEME } from "../../theme";
|
|||||||
import { globalConfig } from "../../../core/config";
|
import { globalConfig } from "../../../core/config";
|
||||||
import { T } from "../../../translations";
|
import { T } from "../../../translations";
|
||||||
import { enumItemType } from "../../base_item";
|
import { enumItemType } from "../../base_item";
|
||||||
import { enumEditMode } from "../../root";
|
import { enumLayer } from "../../root";
|
||||||
|
|
||||||
export class HUDColorBlindHelper extends BaseHUDPart {
|
export class HUDColorBlindHelper extends BaseHUDPart {
|
||||||
createElements(parent) {
|
createElements(parent) {
|
||||||
@ -41,14 +41,14 @@ export class HUDColorBlindHelper extends BaseHUDPart {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.root.editMode !== enumEditMode.regular) {
|
if (this.root.currentLayer !== enumLayer.regular) {
|
||||||
// Not in regular mode
|
// Not in regular mode
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const worldPos = this.root.camera.screenToWorld(mousePosition);
|
const worldPos = this.root.camera.screenToWorld(mousePosition);
|
||||||
const tile = worldPos.toTileSpace();
|
const tile = worldPos.toTileSpace();
|
||||||
const contents = this.root.map.getTileContent(tile);
|
const contents = this.root.map.getTileContent(tile, this.root.currentLayer);
|
||||||
|
|
||||||
if (contents && !contents.components.Miner) {
|
if (contents && !contents.components.Miner) {
|
||||||
const beltComp = contents.components.Belt;
|
const beltComp = contents.components.Belt;
|
||||||
@ -66,6 +66,9 @@ export class HUDColorBlindHelper extends BaseHUDPart {
|
|||||||
if (ejectorComp) {
|
if (ejectorComp) {
|
||||||
for (let i = 0; i < ejectorComp.slots.length; ++i) {
|
for (let i = 0; i < ejectorComp.slots.length; ++i) {
|
||||||
const slot = ejectorComp.slots[i];
|
const slot = ejectorComp.slots[i];
|
||||||
|
if (slot.layer !== this.root.currentLayer) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (slot.item && slot.item.getItemType() === enumItemType.color) {
|
if (slot.item && slot.item.getItemType() === enumItemType.color) {
|
||||||
return /** @type {ColorItem} */ (slot.item).color;
|
return /** @type {ColorItem} */ (slot.item).color;
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ export class HUDEntityDebugger extends BaseHUDPart {
|
|||||||
this.mousePosElem.innerText = worldTile.x + " / " + worldTile.y;
|
this.mousePosElem.innerText = worldTile.x + " / " + worldTile.y;
|
||||||
this.chunkPosElem.innerText = chunk.x + " / " + chunk.y;
|
this.chunkPosElem.innerText = chunk.x + " / " + chunk.y;
|
||||||
|
|
||||||
const entity = this.root.map.getTileContent(worldTile);
|
const entity = this.root.map.getTileContent(worldTile, this.root.currentLayer);
|
||||||
if (entity) {
|
if (entity) {
|
||||||
removeAllChildren(this.entityInfoElem);
|
removeAllChildren(this.entityInfoElem);
|
||||||
let html = "Entity";
|
let html = "Entity";
|
||||||
|
@ -255,14 +255,12 @@ export class HUDKeybindingOverlay extends BaseHUDPart {
|
|||||||
condition: () => this.anythingSelectedOnMap,
|
condition: () => this.anythingSelectedOnMap,
|
||||||
},
|
},
|
||||||
|
|
||||||
/* wires:start */
|
|
||||||
{
|
{
|
||||||
// Switch layers
|
// Switch layers
|
||||||
label: T.ingame.keybindingsOverlay.switchLayers,
|
label: T.ingame.keybindingsOverlay.switchLayers,
|
||||||
keys: [k.ingame.switchLayers],
|
keys: [k.ingame.switchLayers],
|
||||||
condition: () => true,
|
condition: () => true,
|
||||||
},
|
},
|
||||||
/* wires:end */
|
|
||||||
];
|
];
|
||||||
|
|
||||||
if (!this.root.app.settings.getAllSettings().alwaysMultiplace) {
|
if (!this.root.app.settings.getAllSettings().alwaysMultiplace) {
|
||||||
|
@ -210,7 +210,7 @@ export class HUDMassSelector extends BaseHUDPart {
|
|||||||
|
|
||||||
for (let x = realTileStart.x; x <= realTileEnd.x; ++x) {
|
for (let x = realTileStart.x; x <= realTileEnd.x; ++x) {
|
||||||
for (let y = realTileStart.y; y <= realTileEnd.y; ++y) {
|
for (let y = realTileStart.y; y <= realTileEnd.y; ++y) {
|
||||||
const contents = this.root.map.getTileContentXY(x, y);
|
const contents = this.root.map.getLayerContentXY(x, y, this.root.currentLayer);
|
||||||
if (contents && this.root.logic.canDeleteBuilding(contents)) {
|
if (contents && this.root.logic.canDeleteBuilding(contents)) {
|
||||||
this.selectedUids.add(contents.uid);
|
this.selectedUids.add(contents.uid);
|
||||||
}
|
}
|
||||||
@ -259,7 +259,7 @@ export class HUDMassSelector extends BaseHUDPart {
|
|||||||
|
|
||||||
for (let x = realTileStart.x; x <= realTileEnd.x; ++x) {
|
for (let x = realTileStart.x; x <= realTileEnd.x; ++x) {
|
||||||
for (let y = realTileStart.y; y <= realTileEnd.y; ++y) {
|
for (let y = realTileStart.y; y <= realTileEnd.y; ++y) {
|
||||||
const contents = this.root.map.getTileContentXY(x, y);
|
const contents = this.root.map.getLayerContentXY(x, y, this.root.currentLayer);
|
||||||
if (contents && this.root.logic.canDeleteBuilding(contents)) {
|
if (contents && this.root.logic.canDeleteBuilding(contents)) {
|
||||||
const staticComp = contents.components.StaticMapEntity;
|
const staticComp = contents.components.StaticMapEntity;
|
||||||
const bounds = staticComp.getTileSpaceBounds();
|
const bounds = staticComp.getTileSpaceBounds();
|
||||||
|
@ -132,7 +132,7 @@ export class HUDSandboxController extends BaseHUDPart {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.visible = true;
|
this.visible = !G_IS_DEV;
|
||||||
this.domAttach = new DynamicDomAttach(this.root, this.element);
|
this.domAttach = new DynamicDomAttach(this.root, this.element);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import { makeOffscreenBuffer } from "../../../core/buffer_utils";
|
|||||||
import { globalConfig } from "../../../core/config";
|
import { globalConfig } from "../../../core/config";
|
||||||
import { DrawParameters } from "../../../core/draw_parameters";
|
import { DrawParameters } from "../../../core/draw_parameters";
|
||||||
import { KEYMAPPINGS } from "../../key_action_mapper";
|
import { KEYMAPPINGS } from "../../key_action_mapper";
|
||||||
import { enumEditMode } from "../../root";
|
import { enumLayer } from "../../root";
|
||||||
import { THEME } from "../../theme";
|
import { THEME } from "../../theme";
|
||||||
import { BaseHUDPart } from "../base_hud_part";
|
import { BaseHUDPart } from "../base_hud_part";
|
||||||
import { Loader } from "../../../core/loader";
|
import { Loader } from "../../../core/loader";
|
||||||
@ -26,12 +26,12 @@ export class HUDWiresOverlay extends BaseHUDPart {
|
|||||||
* Switches between layers
|
* Switches between layers
|
||||||
*/
|
*/
|
||||||
switchLayers() {
|
switchLayers() {
|
||||||
if (this.root.editMode === enumEditMode.regular) {
|
if (this.root.currentLayer === enumLayer.regular) {
|
||||||
this.root.editMode = enumEditMode.wires;
|
this.root.currentLayer = enumLayer.wires;
|
||||||
} else {
|
} else {
|
||||||
this.root.editMode = enumEditMode.regular;
|
this.root.currentLayer = enumLayer.regular;
|
||||||
}
|
}
|
||||||
this.root.signals.editModeChanged.dispatch(this.root.editMode);
|
this.root.signals.editModeChanged.dispatch(this.root.currentLayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -50,7 +50,7 @@ export class HUDWiresOverlay extends BaseHUDPart {
|
|||||||
}
|
}
|
||||||
|
|
||||||
update() {
|
update() {
|
||||||
const desiredAlpha = this.root.editMode === enumEditMode.wires ? 1.0 : 0.0;
|
const desiredAlpha = this.root.currentLayer === enumLayer.wires ? 1.0 : 0.0;
|
||||||
this.currentAlpha = lerp(this.currentAlpha, desiredAlpha, 0.08);
|
this.currentAlpha = lerp(this.currentAlpha, desiredAlpha, 0.08);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,6 +63,10 @@ export class HUDWiresOverlay extends BaseHUDPart {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.root.camera.getIsMapOverlayActive()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!this.cachedPatternBackground) {
|
if (!this.cachedPatternBackground) {
|
||||||
this.cachedPatternBackground = parameters.context.createPattern(this.tilePatternCanvas, "repeat");
|
this.cachedPatternBackground = parameters.context.createPattern(this.tilePatternCanvas, "repeat");
|
||||||
}
|
}
|
||||||
|
16
src/js/game/hud/parts/wires_toolbar.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { MetaWireBaseBuilding } from "../../buildings/wire_base";
|
||||||
|
import { enumLayer } from "../../root";
|
||||||
|
import { HUDBaseToolbar } from "./base_toolbar";
|
||||||
|
|
||||||
|
const supportedBuildings = [MetaWireBaseBuilding];
|
||||||
|
|
||||||
|
export class HUDWiresToolbar extends HUDBaseToolbar {
|
||||||
|
constructor(root) {
|
||||||
|
super(root, {
|
||||||
|
supportedBuildings,
|
||||||
|
visibilityCondition: () =>
|
||||||
|
!this.root.camera.getIsMapOverlayActive() && this.root.currentLayer === enumLayer.wires,
|
||||||
|
htmlElementId: "ingame_HUD_wires_toolbar",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,12 @@
|
|||||||
import { gItemRegistry } from "../core/global_registries";
|
import { gItemRegistry } from "../core/global_registries";
|
||||||
import { ShapeItem } from "./items/shape_item";
|
import { ShapeItem } from "./items/shape_item";
|
||||||
import { ColorItem } from "./items/color_item";
|
import { ColorItem } from "./items/color_item";
|
||||||
|
import { PositiveEnergyItem } from "./items/positive_energy_item";
|
||||||
|
import { NegativeEnergyItem } from "./items/negative_energy_item";
|
||||||
|
|
||||||
export function initItemRegistry() {
|
export function initItemRegistry() {
|
||||||
gItemRegistry.register(ShapeItem);
|
gItemRegistry.register(ShapeItem);
|
||||||
gItemRegistry.register(ColorItem);
|
gItemRegistry.register(ColorItem);
|
||||||
|
gItemRegistry.register(PositiveEnergyItem);
|
||||||
|
gItemRegistry.register(NegativeEnergyItem);
|
||||||
}
|
}
|
||||||
|
68
src/js/game/items/negative_energy_item.js
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
import { globalConfig } from "../../core/config";
|
||||||
|
import { smoothenDpi } from "../../core/dpi_manager";
|
||||||
|
import { DrawParameters } from "../../core/draw_parameters";
|
||||||
|
import { types } from "../../savegame/serialization";
|
||||||
|
import { BaseItem, enumItemType } from "../base_item";
|
||||||
|
|
||||||
|
export class NegativeEnergyItem extends BaseItem {
|
||||||
|
static getId() {
|
||||||
|
return "negative_energy";
|
||||||
|
}
|
||||||
|
|
||||||
|
static getSchema() {
|
||||||
|
return types.uint;
|
||||||
|
}
|
||||||
|
|
||||||
|
serialize() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
deserialize(data) {}
|
||||||
|
|
||||||
|
getItemType() {
|
||||||
|
return enumItemType.negativeEnergy;
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.bufferGenerator = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} x
|
||||||
|
* @param {number} y
|
||||||
|
* @param {number} size
|
||||||
|
* @param {DrawParameters} parameters
|
||||||
|
*/
|
||||||
|
draw(x, y, parameters, size = 12) {
|
||||||
|
if (!this.bufferGenerator) {
|
||||||
|
this.bufferGenerator = this.internalGenerateBuffer.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
const dpi = smoothenDpi(globalConfig.shapesSharpness * parameters.zoomLevel);
|
||||||
|
|
||||||
|
const key = size + "/" + dpi;
|
||||||
|
const canvas = parameters.root.buffers.getForKey(key, "", size, size, dpi, this.bufferGenerator);
|
||||||
|
parameters.context.drawImage(canvas, x - size / 2, y - size / 2, size, size);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param {HTMLCanvasElement} canvas
|
||||||
|
* @param {CanvasRenderingContext2D} context
|
||||||
|
* @param {number} w
|
||||||
|
* @param {number} h
|
||||||
|
* @param {number} dpi
|
||||||
|
*/
|
||||||
|
internalGenerateBuffer(canvas, context, w, h, dpi) {
|
||||||
|
context.translate((w * dpi) / 2, (h * dpi) / 2);
|
||||||
|
context.scale((dpi * w) / 12, (dpi * h) / 12);
|
||||||
|
|
||||||
|
context.fillStyle = "#1d2725";
|
||||||
|
context.strokeStyle = "#eee";
|
||||||
|
context.lineWidth = 1;
|
||||||
|
context.beginCircle(0, 0, 5);
|
||||||
|
context.fill();
|
||||||
|
context.stroke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const POSITIVE_ENERGY_ITEM_SINGLETON = new NegativeEnergyItem();
|
68
src/js/game/items/positive_energy_item.js
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
import { globalConfig } from "../../core/config";
|
||||||
|
import { smoothenDpi } from "../../core/dpi_manager";
|
||||||
|
import { DrawParameters } from "../../core/draw_parameters";
|
||||||
|
import { types } from "../../savegame/serialization";
|
||||||
|
import { BaseItem, enumItemType } from "../base_item";
|
||||||
|
|
||||||
|
export class PositiveEnergyItem extends BaseItem {
|
||||||
|
static getId() {
|
||||||
|
return "positive_energy";
|
||||||
|
}
|
||||||
|
|
||||||
|
static getSchema() {
|
||||||
|
return types.uint;
|
||||||
|
}
|
||||||
|
|
||||||
|
serialize() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
deserialize(data) {}
|
||||||
|
|
||||||
|
getItemType() {
|
||||||
|
return enumItemType.positiveEnergy;
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.bufferGenerator = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} x
|
||||||
|
* @param {number} y
|
||||||
|
* @param {number} size
|
||||||
|
* @param {DrawParameters} parameters
|
||||||
|
*/
|
||||||
|
draw(x, y, parameters, size = 12) {
|
||||||
|
if (!this.bufferGenerator) {
|
||||||
|
this.bufferGenerator = this.internalGenerateBuffer.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
const dpi = smoothenDpi(globalConfig.shapesSharpness * parameters.zoomLevel);
|
||||||
|
|
||||||
|
const key = size + "/" + dpi;
|
||||||
|
const canvas = parameters.root.buffers.getForKey(key, "", size, size, dpi, this.bufferGenerator);
|
||||||
|
parameters.context.drawImage(canvas, x - size / 2, y - size / 2, size, size);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param {HTMLCanvasElement} canvas
|
||||||
|
* @param {CanvasRenderingContext2D} context
|
||||||
|
* @param {number} w
|
||||||
|
* @param {number} h
|
||||||
|
* @param {number} dpi
|
||||||
|
*/
|
||||||
|
internalGenerateBuffer(canvas, context, w, h, dpi) {
|
||||||
|
context.translate((w * dpi) / 2, (h * dpi) / 2);
|
||||||
|
context.scale((dpi * w) / 12, (dpi * h) / 12);
|
||||||
|
|
||||||
|
context.fillStyle = "#e84a4a";
|
||||||
|
context.strokeStyle = "#eee";
|
||||||
|
context.lineWidth = 1;
|
||||||
|
context.beginCircle(0, 0, 5);
|
||||||
|
context.fill();
|
||||||
|
context.stroke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const POSITIVE_ENERGY_ITEM_SINGLETON = new PositiveEnergyItem();
|
@ -25,9 +25,7 @@ export const KEYMAPPINGS = {
|
|||||||
exportScreenshot: { keyCode: 114 }, // F3PS
|
exportScreenshot: { keyCode: 114 }, // F3PS
|
||||||
toggleFPSInfo: { keyCode: 115 }, // F4
|
toggleFPSInfo: { keyCode: 115 }, // F4
|
||||||
|
|
||||||
/* wires:start */
|
|
||||||
switchLayers: { keyCode: key("Y") },
|
switchLayers: { keyCode: key("Y") },
|
||||||
/* wires:end */
|
|
||||||
},
|
},
|
||||||
|
|
||||||
navigation: {
|
navigation: {
|
||||||
@ -55,10 +53,10 @@ export const KEYMAPPINGS = {
|
|||||||
mixer: { keyCode: key("8") },
|
mixer: { keyCode: key("8") },
|
||||||
painter: { keyCode: key("9") },
|
painter: { keyCode: key("9") },
|
||||||
trash: { keyCode: key("0") },
|
trash: { keyCode: key("0") },
|
||||||
|
|
||||||
/* wires:start */
|
|
||||||
energy_generator: { keyCode: key("O") },
|
energy_generator: { keyCode: key("O") },
|
||||||
/* wires:end */
|
|
||||||
|
// Wires layer
|
||||||
|
wire: { keyCode: key("1") },
|
||||||
},
|
},
|
||||||
|
|
||||||
placement: {
|
placement: {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { GameRoot } from "./root";
|
import { GameRoot, enumLayer, arrayLayers } from "./root";
|
||||||
import { Entity } from "./entity";
|
import { Entity } from "./entity";
|
||||||
import { Vector, enumDirectionToVector, enumDirection } from "../core/vector";
|
import { Vector, enumDirectionToVector, enumDirection } from "../core/vector";
|
||||||
import { MetaBuilding } from "./meta_building";
|
import { MetaBuilding } from "./meta_building";
|
||||||
@ -63,16 +63,16 @@ export class GameLogic {
|
|||||||
blueprintSpriteKey: "",
|
blueprintSpriteKey: "",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const layer = building.getLayer();
|
||||||
const rect = checker.getTileSpaceBounds();
|
const rect = checker.getTileSpaceBounds();
|
||||||
|
|
||||||
for (let x = rect.x; x < rect.x + rect.w; ++x) {
|
for (let x = rect.x; x < rect.x + rect.w; ++x) {
|
||||||
for (let y = rect.y; y < rect.y + rect.h; ++y) {
|
for (let y = rect.y; y < rect.y + rect.h; ++y) {
|
||||||
const contents = this.root.map.getTileContentXY(x, y);
|
const contents = this.root.map.getLayerContentXY(x, y, layer);
|
||||||
if (contents) {
|
if (contents) {
|
||||||
if (
|
if (
|
||||||
!this.checkCanReplaceBuilding({
|
!this.checkCanReplaceBuilding({
|
||||||
original: contents,
|
original: contents,
|
||||||
origin,
|
|
||||||
building,
|
building,
|
||||||
rotation,
|
rotation,
|
||||||
rotationVariant,
|
rotationVariant,
|
||||||
@ -82,6 +82,25 @@ export class GameLogic {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for any pins which are in the way
|
||||||
|
if (layer === enumLayer.wires) {
|
||||||
|
const regularContents = this.root.map.getLayerContentXY(x, y, enumLayer.regular);
|
||||||
|
if (regularContents) {
|
||||||
|
const staticComp = regularContents.components.StaticMapEntity;
|
||||||
|
const pinComponent = regularContents.components.WiredPins;
|
||||||
|
if (pinComponent) {
|
||||||
|
const pins = pinComponent.slots;
|
||||||
|
for (let i = 0; i < pins.length; ++i) {
|
||||||
|
const pos = staticComp.localTileToWorld(pins[i].pos);
|
||||||
|
// Occupied by a pin
|
||||||
|
if (pos.x === x && pos.y === y) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -91,18 +110,22 @@ export class GameLogic {
|
|||||||
* Checks if the given building can be replaced by another
|
* Checks if the given building can be replaced by another
|
||||||
* @param {object} param0
|
* @param {object} param0
|
||||||
* @param {Entity} param0.original
|
* @param {Entity} param0.original
|
||||||
* @param {Vector} param0.origin
|
|
||||||
* @param {number} param0.rotation
|
* @param {number} param0.rotation
|
||||||
* @param {number} param0.rotationVariant
|
* @param {number} param0.rotationVariant
|
||||||
* @param {MetaBuilding} param0.building
|
* @param {MetaBuilding} param0.building
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
checkCanReplaceBuilding({ original, origin, building, rotation, rotationVariant }) {
|
checkCanReplaceBuilding({ original, building, rotation, rotationVariant }) {
|
||||||
if (!original.components.ReplaceableMapEntity) {
|
if (!original.components.ReplaceableMapEntity) {
|
||||||
// Can not get replaced at all
|
// Can not get replaced at all
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (building.getLayer() !== original.layer) {
|
||||||
|
// Layer mismatch
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const staticComp = original.components.StaticMapEntity;
|
const staticComp = original.components.StaticMapEntity;
|
||||||
assert(staticComp, "Building is not static");
|
assert(staticComp, "Building is not static");
|
||||||
const beltComp = original.components.Belt;
|
const beltComp = original.components.Belt;
|
||||||
@ -162,11 +185,12 @@ export class GameLogic {
|
|||||||
blueprintSpriteKey: "",
|
blueprintSpriteKey: "",
|
||||||
});
|
});
|
||||||
|
|
||||||
const rect = checker.getTileSpaceBounds();
|
const layer = building.getLayer();
|
||||||
|
|
||||||
|
const rect = checker.getTileSpaceBounds();
|
||||||
for (let x = rect.x; x < rect.x + rect.w; ++x) {
|
for (let x = rect.x; x < rect.x + rect.w; ++x) {
|
||||||
for (let y = rect.y; y < rect.y + rect.h; ++y) {
|
for (let y = rect.y; y < rect.y + rect.h; ++y) {
|
||||||
const contents = this.root.map.getTileContentXY(x, y);
|
const contents = this.root.map.getLayerContentXY(x, y, layer);
|
||||||
if (contents) {
|
if (contents) {
|
||||||
if (!this.tryDeleteBuilding(contents)) {
|
if (!this.tryDeleteBuilding(contents)) {
|
||||||
logger.error("Building has replaceable component but is also unremovable");
|
logger.error("Building has replaceable component but is also unremovable");
|
||||||
@ -233,9 +257,10 @@ export class GameLogic {
|
|||||||
/**
|
/**
|
||||||
* Returns the acceptors and ejectors which affect the current tile
|
* Returns the acceptors and ejectors which affect the current tile
|
||||||
* @param {Vector} tile
|
* @param {Vector} tile
|
||||||
|
* @param {enumLayer} layer
|
||||||
* @returns {AcceptorsAndEjectorsAffectingTile}
|
* @returns {AcceptorsAndEjectorsAffectingTile}
|
||||||
*/
|
*/
|
||||||
getEjectorsAndAcceptorsAtTile(tile) {
|
getEjectorsAndAcceptorsAtTile(tile, layer) {
|
||||||
/** @type {EjectorsAffectingTile} */
|
/** @type {EjectorsAffectingTile} */
|
||||||
let ejectors = [];
|
let ejectors = [];
|
||||||
/** @type {AcceptorsAffectingTile} */
|
/** @type {AcceptorsAffectingTile} */
|
||||||
@ -247,13 +272,16 @@ export class GameLogic {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const entity = this.root.map.getTileContentXY(tile.x + dx, tile.y + dy);
|
const entity = this.root.map.getLayerContentXY(tile.x + dx, tile.y + dy, layer);
|
||||||
if (entity) {
|
if (entity) {
|
||||||
const staticComp = entity.components.StaticMapEntity;
|
const staticComp = entity.components.StaticMapEntity;
|
||||||
const itemEjector = entity.components.ItemEjector;
|
const itemEjector = entity.components.ItemEjector;
|
||||||
if (itemEjector) {
|
if (itemEjector) {
|
||||||
for (let ejectorSlot = 0; ejectorSlot < itemEjector.slots.length; ++ejectorSlot) {
|
for (let ejectorSlot = 0; ejectorSlot < itemEjector.slots.length; ++ejectorSlot) {
|
||||||
const slot = itemEjector.slots[ejectorSlot];
|
const slot = itemEjector.slots[ejectorSlot];
|
||||||
|
if (slot.layer !== layer) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const wsTile = staticComp.localTileToWorld(slot.pos);
|
const wsTile = staticComp.localTileToWorld(slot.pos);
|
||||||
const wsDirection = staticComp.localDirectionToWorld(slot.direction);
|
const wsDirection = staticComp.localDirectionToWorld(slot.direction);
|
||||||
const targetTile = wsTile.add(enumDirectionToVector[wsDirection]);
|
const targetTile = wsTile.add(enumDirectionToVector[wsDirection]);
|
||||||
@ -272,6 +300,10 @@ export class GameLogic {
|
|||||||
if (itemAcceptor) {
|
if (itemAcceptor) {
|
||||||
for (let acceptorSlot = 0; acceptorSlot < itemAcceptor.slots.length; ++acceptorSlot) {
|
for (let acceptorSlot = 0; acceptorSlot < itemAcceptor.slots.length; ++acceptorSlot) {
|
||||||
const slot = itemAcceptor.slots[acceptorSlot];
|
const slot = itemAcceptor.slots[acceptorSlot];
|
||||||
|
if (slot.layer !== layer) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const wsTile = staticComp.localTileToWorld(slot.pos);
|
const wsTile = staticComp.localTileToWorld(slot.pos);
|
||||||
for (let k = 0; k < slot.directions.length; ++k) {
|
for (let k = 0; k < slot.directions.length; ++k) {
|
||||||
const direction = slot.directions[k];
|
const direction = slot.directions[k];
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
/* typehints:start */
|
import { GameRoot, enumLayer } from "./root";
|
||||||
import { GameRoot } from "./root";
|
|
||||||
/* typehints:end */
|
|
||||||
|
|
||||||
import { globalConfig } from "../core/config";
|
import { globalConfig } from "../core/config";
|
||||||
import { Vector } from "../core/vector";
|
import { Vector } from "../core/vector";
|
||||||
import { Entity } from "./entity";
|
import { Entity } from "./entity";
|
||||||
@ -102,14 +99,15 @@ export class BaseMap extends BasicSerializableObject {
|
|||||||
/**
|
/**
|
||||||
* Returns the tile content of a given tile
|
* Returns the tile content of a given tile
|
||||||
* @param {Vector} tile
|
* @param {Vector} tile
|
||||||
|
* @param {enumLayer} layer
|
||||||
* @returns {Entity} Entity or null
|
* @returns {Entity} Entity or null
|
||||||
*/
|
*/
|
||||||
getTileContent(tile) {
|
getTileContent(tile, layer) {
|
||||||
if (G_IS_DEV) {
|
if (G_IS_DEV) {
|
||||||
this.internalCheckTile(tile);
|
this.internalCheckTile(tile);
|
||||||
}
|
}
|
||||||
const chunk = this.getChunkAtTileOrNull(tile.x, tile.y);
|
const chunk = this.getChunkAtTileOrNull(tile.x, tile.y);
|
||||||
return chunk && chunk.getTileContentFromWorldCoords(tile.x, tile.y);
|
return chunk && chunk.getLayerContentFromWorldCoords(tile.x, tile.y, layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -133,6 +131,29 @@ export class BaseMap extends BasicSerializableObject {
|
|||||||
return chunk && chunk.getTileContentFromWorldCoords(x, y);
|
return chunk && chunk.getTileContentFromWorldCoords(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the tile content of a given tile
|
||||||
|
* @param {number} x
|
||||||
|
* @param {number} y
|
||||||
|
* @param {enumLayer} layer
|
||||||
|
* @returns {Entity} Entity or null
|
||||||
|
*/
|
||||||
|
getLayerContentXY(x, y, layer) {
|
||||||
|
const chunk = this.getChunkAtTileOrNull(x, y);
|
||||||
|
return chunk && chunk.getLayerContentFromWorldCoords(x, y, layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the tile contents of a given tile
|
||||||
|
* @param {number} x
|
||||||
|
* @param {number} y
|
||||||
|
* @returns {Array<Entity>} Entity or null
|
||||||
|
*/
|
||||||
|
getLayersContentsMultipleXY(x, y) {
|
||||||
|
const chunk = this.getChunkAtTileOrNull(x, y);
|
||||||
|
return chunk && chunk.getLayersContentsMultipleFromWorldCoords(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the tile is used
|
* Checks if the tile is used
|
||||||
* @param {Vector} tile
|
* @param {Vector} tile
|
||||||
@ -167,7 +188,12 @@ export class BaseMap extends BasicSerializableObject {
|
|||||||
this.internalCheckTile(tile);
|
this.internalCheckTile(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.getOrCreateChunkAtTile(tile.x, tile.y).setTileContentFromWorldCords(tile.x, tile.y, entity);
|
this.getOrCreateChunkAtTile(tile.x, tile.y).setLayerContentFromWorldCords(
|
||||||
|
tile.x,
|
||||||
|
tile.y,
|
||||||
|
entity,
|
||||||
|
entity.layer
|
||||||
|
);
|
||||||
|
|
||||||
const staticComponent = entity.components.StaticMapEntity;
|
const staticComponent = entity.components.StaticMapEntity;
|
||||||
assert(staticComponent, "Can only place static map entities in tiles");
|
assert(staticComponent, "Can only place static map entities in tiles");
|
||||||
@ -185,7 +211,7 @@ export class BaseMap extends BasicSerializableObject {
|
|||||||
for (let dy = 0; dy < rect.h; ++dy) {
|
for (let dy = 0; dy < rect.h; ++dy) {
|
||||||
const x = rect.x + dx;
|
const x = rect.x + dx;
|
||||||
const y = rect.y + dy;
|
const y = rect.y + dy;
|
||||||
this.getOrCreateChunkAtTile(x, y).setTileContentFromWorldCords(x, y, entity);
|
this.getOrCreateChunkAtTile(x, y).setLayerContentFromWorldCords(x, y, entity, entity.layer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -202,22 +228,11 @@ export class BaseMap extends BasicSerializableObject {
|
|||||||
for (let dy = 0; dy < rect.h; ++dy) {
|
for (let dy = 0; dy < rect.h; ++dy) {
|
||||||
const x = rect.x + dx;
|
const x = rect.x + dx;
|
||||||
const y = rect.y + dy;
|
const y = rect.y + dy;
|
||||||
this.getOrCreateChunkAtTile(x, y).setTileContentFromWorldCords(x, y, null);
|
this.getOrCreateChunkAtTile(x, y).setLayerContentFromWorldCords(x, y, null, entity.layer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets the tiles content
|
|
||||||
* @param {Vector} tile
|
|
||||||
*/
|
|
||||||
clearTile(tile) {
|
|
||||||
if (G_IS_DEV) {
|
|
||||||
this.internalCheckTile(tile);
|
|
||||||
}
|
|
||||||
this.getOrCreateChunkAtTile(tile.x, tile.y).setTileContentFromWorldCords(tile.x, tile.y, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Internal
|
// Internal
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
/* typehints:start */
|
import { GameRoot, enumLayer } from "./root";
|
||||||
import { GameRoot } from "./root";
|
|
||||||
/* typehints:end */
|
|
||||||
|
|
||||||
import { globalConfig } from "../core/config";
|
import { globalConfig } from "../core/config";
|
||||||
import { createLogger } from "../core/logging";
|
import { createLogger } from "../core/logging";
|
||||||
import { clamp, fastArrayDeleteValueIfContained, make2DUndefinedArray } from "../core/utils";
|
import { clamp, fastArrayDeleteValueIfContained, make2DUndefinedArray } from "../core/utils";
|
||||||
@ -37,6 +34,13 @@ export class MapChunk {
|
|||||||
"map-chunk@" + this.x + "|" + this.y
|
"map-chunk@" + this.x + "|" + this.y
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/** @type {Array<Array<?Entity>>} */
|
||||||
|
this.wireContents = make2DUndefinedArray(
|
||||||
|
globalConfig.mapChunkSize,
|
||||||
|
globalConfig.mapChunkSize,
|
||||||
|
"map-chunk-wires@" + this.x + "|" + this.y
|
||||||
|
);
|
||||||
|
|
||||||
/** @type {Array<Array<?BaseItem>>} */
|
/** @type {Array<Array<?BaseItem>>} */
|
||||||
this.lowerLayer = make2DUndefinedArray(
|
this.lowerLayer = make2DUndefinedArray(
|
||||||
globalConfig.mapChunkSize,
|
globalConfig.mapChunkSize,
|
||||||
@ -324,6 +328,53 @@ export class MapChunk {
|
|||||||
return this.contents[localX][localY] || null;
|
return this.contents[localX][localY] || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the contents of this chunk from the given world space coordinates
|
||||||
|
* @param {number} worldX
|
||||||
|
* @param {number} worldY
|
||||||
|
* @param {enumLayer} layer
|
||||||
|
* @returns {Entity=}
|
||||||
|
*/
|
||||||
|
getLayerContentFromWorldCoords(worldX, worldY, layer) {
|
||||||
|
const localX = worldX - this.tileX;
|
||||||
|
const localY = worldY - this.tileY;
|
||||||
|
assert(localX >= 0, "Local X is < 0");
|
||||||
|
assert(localY >= 0, "Local Y is < 0");
|
||||||
|
assert(localX < globalConfig.mapChunkSize, "Local X is >= chunk size");
|
||||||
|
assert(localY < globalConfig.mapChunkSize, "Local Y is >= chunk size");
|
||||||
|
if (layer === enumLayer.regular) {
|
||||||
|
return this.contents[localX][localY] || null;
|
||||||
|
} else {
|
||||||
|
return this.wireContents[localX][localY] || null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns the contents of this chunk from the given world space coordinates
|
||||||
|
* @param {number} worldX
|
||||||
|
* @param {number} worldY
|
||||||
|
* @returns {Array<Entity>}
|
||||||
|
*/
|
||||||
|
getLayersContentsMultipleFromWorldCoords(worldX, worldY) {
|
||||||
|
const localX = worldX - this.tileX;
|
||||||
|
const localY = worldY - this.tileY;
|
||||||
|
assert(localX >= 0, "Local X is < 0");
|
||||||
|
assert(localY >= 0, "Local Y is < 0");
|
||||||
|
assert(localX < globalConfig.mapChunkSize, "Local X is >= chunk size");
|
||||||
|
assert(localY < globalConfig.mapChunkSize, "Local Y is >= chunk size");
|
||||||
|
|
||||||
|
const regularContent = this.contents[localX][localY];
|
||||||
|
const wireContent = this.wireContents[localX][localY];
|
||||||
|
|
||||||
|
const result = [];
|
||||||
|
if (regularContent) {
|
||||||
|
result.push(regularContent);
|
||||||
|
}
|
||||||
|
if (wireContent) {
|
||||||
|
result.push(wireContent);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the chunks contents from the given local coordinates
|
* Returns the chunks contents from the given local coordinates
|
||||||
* @param {number} localX
|
* @param {number} localX
|
||||||
@ -344,22 +395,36 @@ export class MapChunk {
|
|||||||
* @param {number} tileX
|
* @param {number} tileX
|
||||||
* @param {number} tileY
|
* @param {number} tileY
|
||||||
* @param {Entity=} contents
|
* @param {Entity=} contents
|
||||||
|
* @param {enumLayer} layer
|
||||||
*/
|
*/
|
||||||
setTileContentFromWorldCords(tileX, tileY, contents) {
|
setLayerContentFromWorldCords(tileX, tileY, contents, layer) {
|
||||||
const localX = tileX - this.tileX;
|
const localX = tileX - this.tileX;
|
||||||
const localY = tileY - this.tileY;
|
const localY = tileY - this.tileY;
|
||||||
assert(localX >= 0, "Local X is < 0");
|
assert(localX >= 0, "Local X is < 0");
|
||||||
assert(localY >= 0, "Local Y is < 0");
|
assert(localY >= 0, "Local Y is < 0");
|
||||||
assert(localX < globalConfig.mapChunkSize, "Local X is >= chunk size");
|
assert(localX < globalConfig.mapChunkSize, "Local X is >= chunk size");
|
||||||
assert(localY < globalConfig.mapChunkSize, "Local Y is >= chunk size");
|
assert(localY < globalConfig.mapChunkSize, "Local Y is >= chunk size");
|
||||||
const oldContents = this.contents[localX][localY];
|
|
||||||
|
let oldContents;
|
||||||
|
if (layer === enumLayer.regular) {
|
||||||
|
oldContents = this.contents[localX][localY];
|
||||||
|
} else {
|
||||||
|
oldContents = this.wireContents[localX][localY];
|
||||||
|
}
|
||||||
|
|
||||||
assert(contents === null || !oldContents, "Tile already used: " + tileX + " / " + tileY);
|
assert(contents === null || !oldContents, "Tile already used: " + tileX + " / " + tileY);
|
||||||
|
|
||||||
if (oldContents) {
|
if (oldContents) {
|
||||||
// Remove from list
|
// Remove from list
|
||||||
fastArrayDeleteValueIfContained(this.containedEntities, oldContents);
|
fastArrayDeleteValueIfContained(this.containedEntities, oldContents);
|
||||||
}
|
}
|
||||||
this.contents[localX][localY] = contents;
|
|
||||||
|
if (layer === enumLayer.regular) {
|
||||||
|
this.contents[localX][localY] = contents;
|
||||||
|
} else {
|
||||||
|
this.wireContents[localX][localY] = contents;
|
||||||
|
}
|
||||||
|
|
||||||
if (contents) {
|
if (contents) {
|
||||||
if (this.containedEntities.indexOf(contents) < 0) {
|
if (this.containedEntities.indexOf(contents) < 0) {
|
||||||
this.containedEntities.push(contents);
|
this.containedEntities.push(contents);
|
||||||
|
@ -23,6 +23,7 @@ export class MapChunkView extends MapChunk {
|
|||||||
|
|
||||||
this.boundInternalDrawBackgroundToContext = this.internalDrawBackgroundToContext.bind(this);
|
this.boundInternalDrawBackgroundToContext = this.internalDrawBackgroundToContext.bind(this);
|
||||||
this.boundInternalDrawForegroundToContext = this.internalDrawForegroundToContext.bind(this);
|
this.boundInternalDrawForegroundToContext = this.internalDrawForegroundToContext.bind(this);
|
||||||
|
this.boundInternalDrawWiresToContext = this.internalDrawWiresToContext.bind(this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whenever something changes, we increase this number - so we know we need to redraw
|
* Whenever something changes, we increase this number - so we know we need to redraw
|
||||||
@ -99,6 +100,35 @@ export class MapChunkView extends MapChunk {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws the wires layer
|
||||||
|
* @param {DrawParameters} parameters
|
||||||
|
*/
|
||||||
|
drawWiresLayer(parameters) {
|
||||||
|
if (parameters.zoomLevel > globalConfig.mapChunkPrerenderMinZoom) {
|
||||||
|
this.internalDrawWireSystems(parameters);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const dpi = smoothenDpi(parameters.zoomLevel);
|
||||||
|
const buffer = this.root.buffers.getForKey(
|
||||||
|
"" + dpi,
|
||||||
|
this.renderKey + "@wire",
|
||||||
|
chunkSizePixels,
|
||||||
|
chunkSizePixels,
|
||||||
|
dpi,
|
||||||
|
this.boundInternalDrawWiresToContext,
|
||||||
|
{ zoomLevel: parameters.zoomLevel }
|
||||||
|
);
|
||||||
|
parameters.context.drawImage(
|
||||||
|
buffer,
|
||||||
|
this.tileX * globalConfig.tileSize,
|
||||||
|
this.tileY * globalConfig.tileSize,
|
||||||
|
chunkSizePixels,
|
||||||
|
chunkSizePixels
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {HTMLCanvasElement} canvas
|
* @param {HTMLCanvasElement} canvas
|
||||||
@ -181,6 +211,35 @@ export class MapChunkView extends MapChunk {
|
|||||||
this.internalDrawForegroundSystems(parameters);
|
this.internalDrawForegroundSystems(parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {HTMLCanvasElement} canvas
|
||||||
|
* @param {CanvasRenderingContext2D} context
|
||||||
|
* @param {number} w
|
||||||
|
* @param {number} h
|
||||||
|
* @param {number} dpi
|
||||||
|
*/
|
||||||
|
internalDrawWiresToContext(canvas, context, w, h, dpi, { zoomLevel }) {
|
||||||
|
context.scale(dpi, dpi);
|
||||||
|
const parameters = new DrawParameters({
|
||||||
|
context,
|
||||||
|
visibleRect: new Rectangle(
|
||||||
|
this.tileX * globalConfig.tileSize,
|
||||||
|
this.tileY * globalConfig.tileSize,
|
||||||
|
chunkSizePixels,
|
||||||
|
chunkSizePixels
|
||||||
|
),
|
||||||
|
desiredAtlasScale: "1",
|
||||||
|
zoomLevel,
|
||||||
|
root: this.root,
|
||||||
|
});
|
||||||
|
parameters.context.translate(
|
||||||
|
-this.tileX * globalConfig.tileSize,
|
||||||
|
-this.tileY * globalConfig.tileSize
|
||||||
|
);
|
||||||
|
this.internalDrawWireSystems(parameters);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {DrawParameters} parameters
|
* @param {DrawParameters} parameters
|
||||||
*/
|
*/
|
||||||
@ -190,6 +249,16 @@ export class MapChunkView extends MapChunk {
|
|||||||
systems.belt.drawChunk(parameters, this);
|
systems.belt.drawChunk(parameters, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {DrawParameters} parameters
|
||||||
|
*/
|
||||||
|
internalDrawWireSystems(parameters) {
|
||||||
|
const systems = this.root.systemMgr.systems;
|
||||||
|
|
||||||
|
systems.belt.drawWiresChunk(parameters, this);
|
||||||
|
systems.staticMapEntities.drawWiresChunk(parameters, this);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {DrawParameters} parameters
|
* @param {DrawParameters} parameters
|
||||||
*/
|
*/
|
||||||
|
@ -156,6 +156,38 @@ export class MapView extends BaseMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws the maps foreground
|
||||||
|
* @param {DrawParameters} parameters
|
||||||
|
*/
|
||||||
|
drawWiresLayer(parameters) {
|
||||||
|
const cullRange = parameters.visibleRect.toTileCullRectangle();
|
||||||
|
const top = cullRange.top();
|
||||||
|
const right = cullRange.right();
|
||||||
|
const bottom = cullRange.bottom();
|
||||||
|
const left = cullRange.left();
|
||||||
|
|
||||||
|
const border = 1;
|
||||||
|
const minY = top - border;
|
||||||
|
const maxY = bottom + border;
|
||||||
|
const minX = left - border;
|
||||||
|
const maxX = right + border - 1;
|
||||||
|
|
||||||
|
const chunkStartX = Math.floor(minX / globalConfig.mapChunkSize);
|
||||||
|
const chunkStartY = Math.floor(minY / globalConfig.mapChunkSize);
|
||||||
|
|
||||||
|
const chunkEndX = Math.ceil(maxX / globalConfig.mapChunkSize);
|
||||||
|
const chunkEndY = Math.ceil(maxY / globalConfig.mapChunkSize);
|
||||||
|
|
||||||
|
// Render y from top down for proper blending
|
||||||
|
for (let chunkX = chunkStartX; chunkX <= chunkEndX; ++chunkX) {
|
||||||
|
for (let chunkY = chunkStartY; chunkY <= chunkEndY; ++chunkY) {
|
||||||
|
const chunk = this.root.map.getChunk(chunkX, chunkY, true);
|
||||||
|
chunk.drawWiresLayer(parameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draws the map background
|
* Draws the map background
|
||||||
* @param {DrawParameters} parameters
|
* @param {DrawParameters} parameters
|
||||||
|
@ -4,7 +4,7 @@ import { Vector } from "../core/vector";
|
|||||||
import { SOUNDS } from "../platform/sound";
|
import { SOUNDS } from "../platform/sound";
|
||||||
import { StaticMapEntityComponent } from "./components/static_map_entity";
|
import { StaticMapEntityComponent } from "./components/static_map_entity";
|
||||||
import { Entity } from "./entity";
|
import { Entity } from "./entity";
|
||||||
import { enumEditMode, GameRoot } from "./root";
|
import { enumLayer, GameRoot } from "./root";
|
||||||
|
|
||||||
export const defaultBuildingVariant = "default";
|
export const defaultBuildingVariant = "default";
|
||||||
|
|
||||||
@ -26,10 +26,10 @@ export class MetaBuilding {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the edit layer of the building
|
* Returns the edit layer of the building
|
||||||
* @returns {enumEditMode}
|
* @returns {enumLayer}
|
||||||
*/
|
*/
|
||||||
getEditLayer() {
|
getLayer() {
|
||||||
return enumEditMode.regular;
|
return enumLayer.regular;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -180,6 +180,7 @@ export class MetaBuilding {
|
|||||||
*/
|
*/
|
||||||
createEntity({ root, origin, rotation, originalRotation, rotationVariant, variant }) {
|
createEntity({ root, origin, rotation, originalRotation, rotationVariant, variant }) {
|
||||||
const entity = new Entity(root);
|
const entity = new Entity(root);
|
||||||
|
entity.layer = this.getLayer();
|
||||||
const blueprintSprite = this.getBlueprintSprite(rotationVariant, variant);
|
const blueprintSprite = this.getBlueprintSprite(rotationVariant, variant);
|
||||||
entity.addComponent(
|
entity.addComponent(
|
||||||
new StaticMapEntityComponent({
|
new StaticMapEntityComponent({
|
||||||
|
@ -11,6 +11,7 @@ import { MetaTrashBuilding } from "./buildings/trash";
|
|||||||
import { MetaUndergroundBeltBuilding } from "./buildings/underground_belt";
|
import { MetaUndergroundBeltBuilding } from "./buildings/underground_belt";
|
||||||
import { MetaHubBuilding } from "./buildings/hub";
|
import { MetaHubBuilding } from "./buildings/hub";
|
||||||
import { MetaEnergyGenerator } from "./buildings/energy_generator";
|
import { MetaEnergyGenerator } from "./buildings/energy_generator";
|
||||||
|
import { MetaWireBaseBuilding } from "./buildings/wire_base";
|
||||||
|
|
||||||
export function initMetaBuildingRegistry() {
|
export function initMetaBuildingRegistry() {
|
||||||
gMetaBuildingRegistry.register(MetaSplitterBuilding);
|
gMetaBuildingRegistry.register(MetaSplitterBuilding);
|
||||||
@ -25,4 +26,5 @@ export function initMetaBuildingRegistry() {
|
|||||||
gMetaBuildingRegistry.register(MetaUndergroundBeltBuilding);
|
gMetaBuildingRegistry.register(MetaUndergroundBeltBuilding);
|
||||||
gMetaBuildingRegistry.register(MetaHubBuilding);
|
gMetaBuildingRegistry.register(MetaHubBuilding);
|
||||||
gMetaBuildingRegistry.register(MetaEnergyGenerator);
|
gMetaBuildingRegistry.register(MetaEnergyGenerator);
|
||||||
|
gMetaBuildingRegistry.register(MetaWireBaseBuilding);
|
||||||
}
|
}
|
||||||
|
@ -32,11 +32,14 @@ import { KeyActionMapper } from "./key_action_mapper";
|
|||||||
const logger = createLogger("game/root");
|
const logger = createLogger("game/root");
|
||||||
|
|
||||||
/** @enum {string} */
|
/** @enum {string} */
|
||||||
export const enumEditMode = {
|
export const enumLayer = {
|
||||||
regular: "regular",
|
regular: "regular",
|
||||||
wires: "wires",
|
wires: "wires",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** @type {Array<enumLayer>} */
|
||||||
|
export const arrayLayers = [enumLayer.regular, enumLayer.wires];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The game root is basically the whole game state at a given point,
|
* The game root is basically the whole game state at a given point,
|
||||||
* combining all important classes. We don't have globals, but this
|
* combining all important classes. We don't have globals, but this
|
||||||
@ -130,8 +133,8 @@ export class GameRoot {
|
|||||||
/** @type {DynamicTickrate} */
|
/** @type {DynamicTickrate} */
|
||||||
this.dynamicTickrate = null;
|
this.dynamicTickrate = null;
|
||||||
|
|
||||||
/** @type {enumEditMode} */
|
/** @type {enumLayer} */
|
||||||
this.editMode = enumEditMode.regular;
|
this.currentLayer = enumLayer.regular;
|
||||||
|
|
||||||
this.signals = {
|
this.signals = {
|
||||||
// Entities
|
// Entities
|
||||||
@ -165,7 +168,7 @@ export class GameRoot {
|
|||||||
|
|
||||||
bulkOperationFinished: /** @type {TypedSignal<[]>} */ (new Signal()),
|
bulkOperationFinished: /** @type {TypedSignal<[]>} */ (new Signal()),
|
||||||
|
|
||||||
editModeChanged: /** @type {TypedSignal<[enumEditMode]>} */ (new Signal()),
|
editModeChanged: /** @type {TypedSignal<[enumLayer]>} */ (new Signal()),
|
||||||
};
|
};
|
||||||
|
|
||||||
// RNG's
|
// RNG's
|
||||||
|
@ -13,6 +13,9 @@ import { Entity } from "../entity";
|
|||||||
import { GameSystemWithFilter } from "../game_system_with_filter";
|
import { GameSystemWithFilter } from "../game_system_with_filter";
|
||||||
import { MapChunkView } from "../map_chunk_view";
|
import { MapChunkView } from "../map_chunk_view";
|
||||||
import { defaultBuildingVariant } from "../meta_building";
|
import { defaultBuildingVariant } from "../meta_building";
|
||||||
|
import { enumLayer } from "../root";
|
||||||
|
import { MetaWireBaseBuilding } from "../buildings/wire_base";
|
||||||
|
import { enumItemType } from "../base_item";
|
||||||
|
|
||||||
export const BELT_ANIM_COUNT = 28;
|
export const BELT_ANIM_COUNT = 28;
|
||||||
|
|
||||||
@ -33,6 +36,15 @@ export class BeltSystem extends GameSystemWithFilter {
|
|||||||
[enumDirection.right]: Loader.getSprite("sprites/belt/right_0.png"),
|
[enumDirection.right]: Loader.getSprite("sprites/belt/right_0.png"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {Object.<enumDirection, Array<AtlasSprite>>}
|
||||||
|
*/
|
||||||
|
this.wireSprites = {
|
||||||
|
[enumDirection.top]: Loader.getSprite("sprites/buildings/wire_top.png"),
|
||||||
|
[enumDirection.left]: Loader.getSprite("sprites/buildings/wire_left.png"),
|
||||||
|
[enumDirection.right]: Loader.getSprite("sprites/buildings/wire_right.png"),
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {Object.<enumDirection, Array<AtlasSprite>>}
|
* @type {Object.<enumDirection, Array<AtlasSprite>>}
|
||||||
*/
|
*/
|
||||||
@ -120,7 +132,10 @@ export class BeltSystem extends GameSystemWithFilter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const metaBelt = gMetaBuildingRegistry.findByClass(MetaBeltBaseBuilding);
|
/* BIG HACK: We don't actually store the meta building */
|
||||||
|
const metaBelt = gMetaBuildingRegistry.findByClass(
|
||||||
|
entity.layer === enumLayer.regular ? MetaBeltBaseBuilding : MetaWireBaseBuilding
|
||||||
|
);
|
||||||
|
|
||||||
// Compute affected area
|
// Compute affected area
|
||||||
const originalRect = staticComp.getTileSpaceBounds();
|
const originalRect = staticComp.getTileSpaceBounds();
|
||||||
@ -133,7 +148,7 @@ export class BeltSystem extends GameSystemWithFilter {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const targetEntity = this.root.map.getTileContentXY(x, y);
|
const targetEntity = this.root.map.getLayerContentXY(x, y, entity.layer);
|
||||||
if (!targetEntity) {
|
if (!targetEntity) {
|
||||||
// Empty tile
|
// Empty tile
|
||||||
continue;
|
continue;
|
||||||
@ -296,10 +311,14 @@ export class BeltSystem extends GameSystemWithFilter {
|
|||||||
/**
|
/**
|
||||||
* Draws all belt paths
|
* Draws all belt paths
|
||||||
* @param {DrawParameters} parameters
|
* @param {DrawParameters} parameters
|
||||||
|
* @param {enumLayer} layer
|
||||||
*/
|
*/
|
||||||
draw(parameters) {
|
drawLayer(parameters, layer) {
|
||||||
for (let i = 0; i < this.beltPaths.length; ++i) {
|
for (let i = 0; i < this.beltPaths.length; ++i) {
|
||||||
this.beltPaths[i].draw(parameters);
|
const path = this.beltPaths[i];
|
||||||
|
if (path.layer === layer) {
|
||||||
|
path.draw(parameters);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,7 +355,7 @@ export class BeltSystem extends GameSystemWithFilter {
|
|||||||
const followUpVector = enumDirectionToVector[followUpDirection];
|
const followUpVector = enumDirectionToVector[followUpDirection];
|
||||||
|
|
||||||
const followUpTile = staticComp.origin.add(followUpVector);
|
const followUpTile = staticComp.origin.add(followUpVector);
|
||||||
const followUpEntity = this.root.map.getTileContent(followUpTile);
|
const followUpEntity = this.root.map.getLayerContentXY(followUpTile.x, followUpTile.y, entity.layer);
|
||||||
|
|
||||||
// Check if theres a belt at the tile we point to
|
// Check if theres a belt at the tile we point to
|
||||||
if (followUpEntity) {
|
if (followUpEntity) {
|
||||||
@ -349,6 +368,12 @@ export class BeltSystem extends GameSystemWithFilter {
|
|||||||
const acceptorSlots = followUpAcceptor.slots;
|
const acceptorSlots = followUpAcceptor.slots;
|
||||||
for (let i = 0; i < acceptorSlots.length; ++i) {
|
for (let i = 0; i < acceptorSlots.length; ++i) {
|
||||||
const slot = acceptorSlots[i];
|
const slot = acceptorSlots[i];
|
||||||
|
|
||||||
|
// Make sure the acceptor slot is on the same layer
|
||||||
|
if (slot.layer !== entity.layer) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for (let k = 0; k < slot.directions.length; ++k) {
|
for (let k = 0; k < slot.directions.length; ++k) {
|
||||||
const localDirection = followUpStatic.localDirectionToWorld(slot.directions[k]);
|
const localDirection = followUpStatic.localDirectionToWorld(slot.directions[k]);
|
||||||
if (enumInvertedDirections[localDirection] === followUpDirection) {
|
if (enumInvertedDirections[localDirection] === followUpDirection) {
|
||||||
@ -374,7 +399,7 @@ export class BeltSystem extends GameSystemWithFilter {
|
|||||||
const supplyVector = enumDirectionToVector[supplyDirection];
|
const supplyVector = enumDirectionToVector[supplyDirection];
|
||||||
|
|
||||||
const supplyTile = staticComp.origin.add(supplyVector);
|
const supplyTile = staticComp.origin.add(supplyVector);
|
||||||
const supplyEntity = this.root.map.getTileContent(supplyTile);
|
const supplyEntity = this.root.map.getLayerContentXY(supplyTile.x, supplyTile.y, entity.layer);
|
||||||
|
|
||||||
// Check if theres a belt at the tile we point to
|
// Check if theres a belt at the tile we point to
|
||||||
if (supplyEntity) {
|
if (supplyEntity) {
|
||||||
@ -387,6 +412,11 @@ export class BeltSystem extends GameSystemWithFilter {
|
|||||||
const ejectorSlots = supplyEjector.slots;
|
const ejectorSlots = supplyEjector.slots;
|
||||||
for (let i = 0; i < ejectorSlots.length; ++i) {
|
for (let i = 0; i < ejectorSlots.length; ++i) {
|
||||||
const slot = ejectorSlots[i];
|
const slot = ejectorSlots[i];
|
||||||
|
|
||||||
|
// Make sure the ejector slot is on the same layer
|
||||||
|
if (slot.layer !== entity.layer) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const localDirection = supplyStatic.localDirectionToWorld(slot.direction);
|
const localDirection = supplyStatic.localDirectionToWorld(slot.direction);
|
||||||
if (enumInvertedDirections[localDirection] === supplyDirection) {
|
if (enumInvertedDirections[localDirection] === supplyDirection) {
|
||||||
return supplyEntity;
|
return supplyEntity;
|
||||||
@ -510,6 +540,45 @@ export class BeltSystem extends GameSystemWithFilter {
|
|||||||
1;
|
1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws a given chunk
|
||||||
|
* @param {DrawParameters} parameters
|
||||||
|
* @param {MapChunkView} chunk
|
||||||
|
*/
|
||||||
|
drawWiresChunk(parameters, chunk) {
|
||||||
|
if (parameters.zoomLevel < globalConfig.mapChunkOverviewMinZoom) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Limit speed to avoid belts going backwards
|
||||||
|
const speedMultiplier = Math.min(this.root.hubGoals.getBeltBaseSpeed(), 10);
|
||||||
|
|
||||||
|
// SYNC with systems/item_acceptor.js:drawEntityUnderlays!
|
||||||
|
// 126 / 42 is the exact animation speed of the png animation
|
||||||
|
const animationIndex = Math.floor(
|
||||||
|
((this.root.time.realtimeNow() * speedMultiplier * BELT_ANIM_COUNT * 126) / 42) *
|
||||||
|
globalConfig.itemSpacingOnBelts
|
||||||
|
);
|
||||||
|
const contents = chunk.wireContents;
|
||||||
|
for (let y = 0; y < globalConfig.mapChunkSize; ++y) {
|
||||||
|
for (let x = 0; x < globalConfig.mapChunkSize; ++x) {
|
||||||
|
const entity = contents[x][y];
|
||||||
|
|
||||||
|
if (entity && entity.components.Belt) {
|
||||||
|
const direction = entity.components.Belt.direction;
|
||||||
|
const sprite = this.wireSprites[direction];
|
||||||
|
entity.components.StaticMapEntity.drawSpriteOnFullEntityBounds(
|
||||||
|
parameters,
|
||||||
|
sprite,
|
||||||
|
0,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draws the belt path debug overlays
|
* Draws the belt path debug overlays
|
||||||
* @param {DrawParameters} parameters
|
* @param {DrawParameters} parameters
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import { DrawParameters } from "../../core/draw_parameters";
|
import { DrawParameters } from "../../core/draw_parameters";
|
||||||
|
import { formatBigNumber } from "../../core/utils";
|
||||||
import { T } from "../../translations";
|
import { T } from "../../translations";
|
||||||
import { EnergyGeneratorComponent } from "../components/energy_generator";
|
import { EnergyGeneratorComponent, ENERGY_GENERATOR_EJECT_SLOT } from "../components/energy_generator";
|
||||||
import { Entity } from "../entity";
|
import { Entity } from "../entity";
|
||||||
import { GameSystemWithFilter } from "../game_system_with_filter";
|
import { GameSystemWithFilter } from "../game_system_with_filter";
|
||||||
|
import { POSITIVE_ENERGY_ITEM_SINGLETON } from "../items/positive_energy_item";
|
||||||
import { ShapeDefinition } from "../shape_definition";
|
import { ShapeDefinition } from "../shape_definition";
|
||||||
import { formatBigNumber } from "../../core/utils";
|
|
||||||
|
|
||||||
export class EnergyGeneratorSystem extends GameSystemWithFilter {
|
export class EnergyGeneratorSystem extends GameSystemWithFilter {
|
||||||
constructor(root) {
|
constructor(root) {
|
||||||
@ -27,11 +28,18 @@ export class EnergyGeneratorSystem extends GameSystemWithFilter {
|
|||||||
for (let i = 0; i < this.allEntities.length; ++i) {
|
for (let i = 0; i < this.allEntities.length; ++i) {
|
||||||
const entity = this.allEntities[i];
|
const entity = this.allEntities[i];
|
||||||
const energyGenComp = entity.components.EnergyGenerator;
|
const energyGenComp = entity.components.EnergyGenerator;
|
||||||
|
const ejectorComp = entity.components.ItemEjector;
|
||||||
|
|
||||||
if (!energyGenComp.requiredKey) {
|
if (!energyGenComp.requiredKey) {
|
||||||
// Compute required key for this generator
|
// Compute required key for this generator
|
||||||
energyGenComp.requiredKey = this.getShapeRequiredForGenerator(entity);
|
energyGenComp.requiredKey = this.getShapeRequiredForGenerator(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (energyGenComp.itemsInQueue > 0) {
|
||||||
|
if (ejectorComp.tryEject(ENERGY_GENERATOR_EJECT_SLOT, POSITIVE_ENERGY_ITEM_SINGLETON)) {
|
||||||
|
energyGenComp.itemsInQueue -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ import { Loader } from "../../core/loader";
|
|||||||
import { drawRotatedSprite } from "../../core/draw_utils";
|
import { drawRotatedSprite } from "../../core/draw_utils";
|
||||||
import { BELT_ANIM_COUNT } from "./belt";
|
import { BELT_ANIM_COUNT } from "./belt";
|
||||||
import { fastArrayDelete } from "../../core/utils";
|
import { fastArrayDelete } from "../../core/utils";
|
||||||
|
import { enumLayer } from "../root";
|
||||||
|
|
||||||
export class ItemAcceptorSystem extends GameSystemWithFilter {
|
export class ItemAcceptorSystem extends GameSystemWithFilter {
|
||||||
constructor(root) {
|
constructor(root) {
|
||||||
@ -49,19 +50,30 @@ export class ItemAcceptorSystem extends GameSystemWithFilter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
draw(parameters) {
|
/**
|
||||||
this.forEachMatchingEntityOnScreen(parameters, this.drawEntity.bind(this));
|
* Draws the acceptor items
|
||||||
}
|
* @param {DrawParameters} parameters
|
||||||
|
* @param {enumLayer} layer
|
||||||
drawUnderlays(parameters) {
|
*/
|
||||||
this.forEachMatchingEntityOnScreen(parameters, this.drawEntityUnderlays.bind(this));
|
drawLayer(parameters, layer) {
|
||||||
|
this.forEachMatchingEntityOnScreen(parameters, this.drawEntityRegularLayer.bind(this, layer));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Draws the acceptor underlays
|
||||||
|
* @param {DrawParameters} parameters
|
||||||
|
* @param {enumLayer} layer
|
||||||
|
*/
|
||||||
|
drawUnderlays(parameters, layer) {
|
||||||
|
this.forEachMatchingEntityOnScreen(parameters, this.drawEntityUnderlays.bind(this, layer));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {enumLayer} layer
|
||||||
* @param {DrawParameters} parameters
|
* @param {DrawParameters} parameters
|
||||||
* @param {Entity} entity
|
* @param {Entity} entity
|
||||||
*/
|
*/
|
||||||
drawEntity(parameters, entity) {
|
drawEntityRegularLayer(layer, parameters, entity) {
|
||||||
const staticComp = entity.components.StaticMapEntity;
|
const staticComp = entity.components.StaticMapEntity;
|
||||||
const acceptorComp = entity.components.ItemAcceptor;
|
const acceptorComp = entity.components.ItemAcceptor;
|
||||||
|
|
||||||
@ -75,8 +87,12 @@ export class ItemAcceptorSystem extends GameSystemWithFilter {
|
|||||||
];
|
];
|
||||||
|
|
||||||
const slotData = acceptorComp.slots[slotIndex];
|
const slotData = acceptorComp.slots[slotIndex];
|
||||||
const slotWorldPos = staticComp.applyRotationToVector(slotData.pos).add(staticComp.origin);
|
if (slotData.layer !== layer) {
|
||||||
|
// Don't draw non-regular slots for now
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const slotWorldPos = staticComp.applyRotationToVector(slotData.pos).add(staticComp.origin);
|
||||||
const fadeOutDirection = enumDirectionToVector[staticComp.localDirectionToWorld(direction)];
|
const fadeOutDirection = enumDirectionToVector[staticComp.localDirectionToWorld(direction)];
|
||||||
const finalTile = slotWorldPos.subScalars(
|
const finalTile = slotWorldPos.subScalars(
|
||||||
fadeOutDirection.x * (animProgress / 2 - 0.5),
|
fadeOutDirection.x * (animProgress / 2 - 0.5),
|
||||||
@ -91,10 +107,11 @@ export class ItemAcceptorSystem extends GameSystemWithFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param {enumLayer} layer
|
||||||
* @param {DrawParameters} parameters
|
* @param {DrawParameters} parameters
|
||||||
* @param {Entity} entity
|
* @param {Entity} entity
|
||||||
*/
|
*/
|
||||||
drawEntityUnderlays(parameters, entity) {
|
drawEntityUnderlays(layer, parameters, entity) {
|
||||||
const staticComp = entity.components.StaticMapEntity;
|
const staticComp = entity.components.StaticMapEntity;
|
||||||
const acceptorComp = entity.components.ItemAcceptor;
|
const acceptorComp = entity.components.ItemAcceptor;
|
||||||
|
|
||||||
@ -107,7 +124,11 @@ export class ItemAcceptorSystem extends GameSystemWithFilter {
|
|||||||
|
|
||||||
const underlays = acceptorComp.beltUnderlays;
|
const underlays = acceptorComp.beltUnderlays;
|
||||||
for (let i = 0; i < underlays.length; ++i) {
|
for (let i = 0; i < underlays.length; ++i) {
|
||||||
const { pos, direction } = underlays[i];
|
const { pos, direction, layer: underlayLayer } = underlays[i];
|
||||||
|
if (underlayLayer !== layer) {
|
||||||
|
// Not our layer
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const transformedPos = staticComp.localTileToWorld(pos);
|
const transformedPos = staticComp.localTileToWorld(pos);
|
||||||
const angle = enumDirectionToAngle[staticComp.localDirectionToWorld(direction)];
|
const angle = enumDirectionToAngle[staticComp.localDirectionToWorld(direction)];
|
||||||
|
@ -7,6 +7,7 @@ import { BaseItem } from "../base_item";
|
|||||||
import { ItemEjectorComponent } from "../components/item_ejector";
|
import { ItemEjectorComponent } from "../components/item_ejector";
|
||||||
import { Entity } from "../entity";
|
import { Entity } from "../entity";
|
||||||
import { GameSystemWithFilter } from "../game_system_with_filter";
|
import { GameSystemWithFilter } from "../game_system_with_filter";
|
||||||
|
import { enumLayer } from "../root";
|
||||||
|
|
||||||
const logger = createLogger("systems/ejector");
|
const logger = createLogger("systems/ejector");
|
||||||
|
|
||||||
@ -96,8 +97,10 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
|
|||||||
|
|
||||||
for (let x = area.x; x < area.right(); ++x) {
|
for (let x = area.x; x < area.right(); ++x) {
|
||||||
for (let y = area.y; y < area.bottom(); ++y) {
|
for (let y = area.y; y < area.bottom(); ++y) {
|
||||||
const entity = this.root.map.getTileContentXY(x, y);
|
const entities = this.root.map.getLayersContentsMultipleXY(x, y);
|
||||||
if (entity) {
|
for (let i = 0; i < entities.length; ++i) {
|
||||||
|
const entity = entities[i];
|
||||||
|
|
||||||
// Recompute the entity in case its relevant for this system and it
|
// Recompute the entity in case its relevant for this system and it
|
||||||
// hasn't already been computed
|
// hasn't already been computed
|
||||||
if (!recomputedEntities.has(entity.uid) && entity.components.ItemEjector) {
|
if (!recomputedEntities.has(entity.uid) && entity.components.ItemEjector) {
|
||||||
@ -134,37 +137,45 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
|
|||||||
const ejectSlotTargetWsTile = ejectSlotWsTile.add(ejectSlotWsDirectionVector);
|
const ejectSlotTargetWsTile = ejectSlotWsTile.add(ejectSlotWsDirectionVector);
|
||||||
|
|
||||||
// Try to find the given acceptor component to take the item
|
// Try to find the given acceptor component to take the item
|
||||||
const targetEntity = this.root.map.getTileContent(ejectSlotTargetWsTile);
|
// Since there can be cross layer dependencies, check on all layers
|
||||||
if (!targetEntity) {
|
const targetEntities = this.root.map.getLayersContentsMultipleXY(
|
||||||
// No consumer for item
|
ejectSlotTargetWsTile.x,
|
||||||
continue;
|
ejectSlotTargetWsTile.y
|
||||||
}
|
|
||||||
|
|
||||||
const targetAcceptorComp = targetEntity.components.ItemAcceptor;
|
|
||||||
const targetStaticComp = targetEntity.components.StaticMapEntity;
|
|
||||||
if (!targetAcceptorComp) {
|
|
||||||
// Entity doesn't accept items
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const matchingSlot = targetAcceptorComp.findMatchingSlot(
|
|
||||||
targetStaticComp.worldToLocalTile(ejectSlotTargetWsTile),
|
|
||||||
targetStaticComp.worldDirectionToLocal(ejectSlotWsDirection)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!matchingSlot) {
|
for (let i = 0; i < targetEntities.length; ++i) {
|
||||||
// No matching slot found
|
const targetEntity = targetEntities[i];
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ok we found a connection
|
const targetAcceptorComp = targetEntity.components.ItemAcceptor;
|
||||||
if (ejectorComp.cachedConnectedSlots) {
|
const targetStaticComp = targetEntity.components.StaticMapEntity;
|
||||||
ejectorComp.cachedConnectedSlots.push(ejectorSlot);
|
if (!targetAcceptorComp) {
|
||||||
} else {
|
// Entity doesn't accept items
|
||||||
ejectorComp.cachedConnectedSlots = [ejectorSlot];
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const matchingSlot = targetAcceptorComp.findMatchingSlot(
|
||||||
|
targetStaticComp.worldToLocalTile(ejectSlotTargetWsTile),
|
||||||
|
targetStaticComp.worldDirectionToLocal(ejectSlotWsDirection),
|
||||||
|
ejectorSlot.layer
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!matchingSlot) {
|
||||||
|
// No matching slot found
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ok we found a connection
|
||||||
|
if (ejectorComp.cachedConnectedSlots) {
|
||||||
|
ejectorComp.cachedConnectedSlots.push(ejectorSlot);
|
||||||
|
} else {
|
||||||
|
ejectorComp.cachedConnectedSlots = [ejectorSlot];
|
||||||
|
}
|
||||||
|
|
||||||
|
// A slot can always be connected to one other slot only
|
||||||
|
ejectorSlot.cachedTargetEntity = targetEntity;
|
||||||
|
ejectorSlot.cachedDestSlot = matchingSlot;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
ejectorSlot.cachedTargetEntity = targetEntity;
|
|
||||||
ejectorSlot.cachedDestSlot = matchingSlot;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,7 +303,7 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
|
|||||||
|
|
||||||
const energyGeneratorComp = receiver.components.EnergyGenerator;
|
const energyGeneratorComp = receiver.components.EnergyGenerator;
|
||||||
if (energyGeneratorComp) {
|
if (energyGeneratorComp) {
|
||||||
if (energyGeneratorComp.tryTakeItem(item)) {
|
if (energyGeneratorComp.tryTakeItem(item, slotIndex)) {
|
||||||
// Passed it over
|
// Passed it over
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -304,15 +315,21 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
draw(parameters) {
|
/**
|
||||||
this.forEachMatchingEntityOnScreen(parameters, this.drawSingleEntity.bind(this));
|
* Draws the given layer
|
||||||
|
* @param {DrawParameters} parameters
|
||||||
|
* @param {enumLayer} layer
|
||||||
|
*/
|
||||||
|
drawLayer(parameters, layer) {
|
||||||
|
this.forEachMatchingEntityOnScreen(parameters, this.drawSingleEntity.bind(this, layer));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param {enumLayer} layer
|
||||||
* @param {DrawParameters} parameters
|
* @param {DrawParameters} parameters
|
||||||
* @param {Entity} entity
|
* @param {Entity} entity
|
||||||
*/
|
*/
|
||||||
drawSingleEntity(parameters, entity) {
|
drawSingleEntity(layer, parameters, entity) {
|
||||||
const ejectorComp = entity.components.ItemEjector;
|
const ejectorComp = entity.components.ItemEjector;
|
||||||
const staticComp = entity.components.StaticMapEntity;
|
const staticComp = entity.components.StaticMapEntity;
|
||||||
|
|
||||||
@ -323,11 +340,17 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
|
|||||||
for (let i = 0; i < ejectorComp.slots.length; ++i) {
|
for (let i = 0; i < ejectorComp.slots.length; ++i) {
|
||||||
const slot = ejectorComp.slots[i];
|
const slot = ejectorComp.slots[i];
|
||||||
const ejectedItem = slot.item;
|
const ejectedItem = slot.item;
|
||||||
|
|
||||||
if (!ejectedItem) {
|
if (!ejectedItem) {
|
||||||
// No item
|
// No item
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (slot.layer !== layer) {
|
||||||
|
// Not our layer
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const realPosition = slot.pos.rotateFastMultipleOf90(staticComp.rotation);
|
const realPosition = slot.pos.rotateFastMultipleOf90(staticComp.rotation);
|
||||||
const realDirection = Vector.transformDirectionFromMultipleOf90(
|
const realDirection = Vector.transformDirectionFromMultipleOf90(
|
||||||
slot.direction,
|
slot.direction,
|
||||||
|
@ -6,6 +6,7 @@ import { Entity } from "../entity";
|
|||||||
import { GameSystemWithFilter } from "../game_system_with_filter";
|
import { GameSystemWithFilter } from "../game_system_with_filter";
|
||||||
import { ColorItem } from "../items/color_item";
|
import { ColorItem } from "../items/color_item";
|
||||||
import { ShapeItem } from "../items/shape_item";
|
import { ShapeItem } from "../items/shape_item";
|
||||||
|
import { enumLayer } from "../root";
|
||||||
|
|
||||||
export class ItemProcessorSystem extends GameSystemWithFilter {
|
export class ItemProcessorSystem extends GameSystemWithFilter {
|
||||||
constructor(root) {
|
constructor(root) {
|
||||||
@ -48,11 +49,14 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
if (ejectorComp.canEjectOnSlot(preferredSlot)) {
|
if (ejectorComp.canEjectOnSlot(preferredSlot)) {
|
||||||
slot = preferredSlot;
|
slot = preferredSlot;
|
||||||
} else {
|
} else {
|
||||||
slot = ejectorComp.getFirstFreeSlot();
|
/* FIXME: WIRES */
|
||||||
|
slot = ejectorComp.getFirstFreeSlot(enumLayer.regular);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
/* FIXME: WIRES */
|
||||||
|
|
||||||
// We can eject on any slot
|
// We can eject on any slot
|
||||||
slot = ejectorComp.getFirstFreeSlot();
|
slot = ejectorComp.getFirstFreeSlot(enumLayer.regular);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (slot !== null) {
|
if (slot !== null) {
|
||||||
|
@ -6,6 +6,7 @@ import { MinerComponent } from "../components/miner";
|
|||||||
import { Entity } from "../entity";
|
import { Entity } from "../entity";
|
||||||
import { GameSystemWithFilter } from "../game_system_with_filter";
|
import { GameSystemWithFilter } from "../game_system_with_filter";
|
||||||
import { MapChunkView } from "../map_chunk_view";
|
import { MapChunkView } from "../map_chunk_view";
|
||||||
|
import { enumLayer } from "../root";
|
||||||
|
|
||||||
export class MinerSystem extends GameSystemWithFilter {
|
export class MinerSystem extends GameSystemWithFilter {
|
||||||
constructor(root) {
|
constructor(root) {
|
||||||
@ -74,7 +75,7 @@ export class MinerSystem extends GameSystemWithFilter {
|
|||||||
const ejectingDirection = staticComp.localDirectionToWorld(ejectingSlot.direction);
|
const ejectingDirection = staticComp.localDirectionToWorld(ejectingSlot.direction);
|
||||||
|
|
||||||
const targetTile = ejectingPos.add(enumDirectionToVector[ejectingDirection]);
|
const targetTile = ejectingPos.add(enumDirectionToVector[ejectingDirection]);
|
||||||
const targetContents = this.root.map.getTileContent(targetTile);
|
const targetContents = this.root.map.getTileContent(targetTile, enumLayer.regular);
|
||||||
|
|
||||||
// Check if we are connected to another miner and thus do not eject directly
|
// Check if we are connected to another miner and thus do not eject directly
|
||||||
if (targetContents) {
|
if (targetContents) {
|
||||||
|
@ -4,6 +4,7 @@ import { globalConfig } from "../../core/config";
|
|||||||
import { MapChunkView } from "../map_chunk_view";
|
import { MapChunkView } from "../map_chunk_view";
|
||||||
import { Loader } from "../../core/loader";
|
import { Loader } from "../../core/loader";
|
||||||
import { enumDirection } from "../../core/vector";
|
import { enumDirection } from "../../core/vector";
|
||||||
|
import { enumLayer } from "../root";
|
||||||
|
|
||||||
export class StaticMapEntitySystem extends GameSystem {
|
export class StaticMapEntitySystem extends GameSystem {
|
||||||
constructor(root) {
|
constructor(root) {
|
||||||
@ -40,7 +41,6 @@ export class StaticMapEntitySystem extends GameSystem {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
drawnUids.add(entity.uid);
|
drawnUids.add(entity.uid);
|
||||||
|
|
||||||
const staticComp = entity.components.StaticMapEntity;
|
const staticComp = entity.components.StaticMapEntity;
|
||||||
if (drawOutlinesOnly) {
|
if (drawOutlinesOnly) {
|
||||||
const rect = staticComp.getTileSpaceBounds();
|
const rect = staticComp.getTileSpaceBounds();
|
||||||
@ -68,4 +68,36 @@ export class StaticMapEntitySystem extends GameSystem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws the static wire entities
|
||||||
|
* @param {DrawParameters} parameters
|
||||||
|
* @param {MapChunkView} chunk
|
||||||
|
*/
|
||||||
|
drawWiresChunk(parameters, chunk) {
|
||||||
|
if (G_IS_DEV && globalConfig.debug.doNotRenderStatics) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const drawnUids = new Set();
|
||||||
|
const contents = chunk.wireContents;
|
||||||
|
for (let y = 0; y < globalConfig.mapChunkSize; ++y) {
|
||||||
|
for (let x = 0; x < globalConfig.mapChunkSize; ++x) {
|
||||||
|
const entity = contents[x][y];
|
||||||
|
if (entity) {
|
||||||
|
if (drawnUids.has(entity.uid)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
drawnUids.add(entity.uid);
|
||||||
|
const staticComp = entity.components.StaticMapEntity;
|
||||||
|
|
||||||
|
const spriteKey = staticComp.spriteKey;
|
||||||
|
if (spriteKey) {
|
||||||
|
const sprite = Loader.getSprite(spriteKey);
|
||||||
|
staticComp.drawSpriteOnFullEntityBounds(parameters, sprite, 2, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import { Entity } from "../entity";
|
|||||||
import { DrawParameters } from "../../core/draw_parameters";
|
import { DrawParameters } from "../../core/draw_parameters";
|
||||||
import { formatBigNumber, lerp } from "../../core/utils";
|
import { formatBigNumber, lerp } from "../../core/utils";
|
||||||
import { Loader } from "../../core/loader";
|
import { Loader } from "../../core/loader";
|
||||||
|
import { enumLayer } from "../root";
|
||||||
|
|
||||||
export class StorageSystem extends GameSystemWithFilter {
|
export class StorageSystem extends GameSystemWithFilter {
|
||||||
constructor(root) {
|
constructor(root) {
|
||||||
@ -20,7 +21,9 @@ export class StorageSystem extends GameSystemWithFilter {
|
|||||||
// Eject from storage
|
// Eject from storage
|
||||||
if (storageComp.storedItem && storageComp.storedCount > 0) {
|
if (storageComp.storedItem && storageComp.storedCount > 0) {
|
||||||
const ejectorComp = entity.components.ItemEjector;
|
const ejectorComp = entity.components.ItemEjector;
|
||||||
const nextSlot = ejectorComp.getFirstFreeSlot();
|
|
||||||
|
/* FIXME: WIRES */
|
||||||
|
const nextSlot = ejectorComp.getFirstFreeSlot(enumLayer.regular);
|
||||||
if (nextSlot !== null) {
|
if (nextSlot !== null) {
|
||||||
if (ejectorComp.tryEject(nextSlot, storageComp.storedItem)) {
|
if (ejectorComp.tryEject(nextSlot, storageComp.storedItem)) {
|
||||||
storageComp.storedCount--;
|
storageComp.storedCount--;
|
||||||
|
@ -13,6 +13,7 @@ import { enumUndergroundBeltMode, UndergroundBeltComponent } from "../components
|
|||||||
import { Entity } from "../entity";
|
import { Entity } from "../entity";
|
||||||
import { GameSystemWithFilter } from "../game_system_with_filter";
|
import { GameSystemWithFilter } from "../game_system_with_filter";
|
||||||
import { fastArrayDelete } from "../../core/utils";
|
import { fastArrayDelete } from "../../core/utils";
|
||||||
|
import { enumLayer } from "../root";
|
||||||
|
|
||||||
const logger = createLogger("tunnels");
|
const logger = createLogger("tunnels");
|
||||||
|
|
||||||
@ -95,7 +96,7 @@ export class UndergroundBeltSystem extends GameSystemWithFilter {
|
|||||||
let matchingEntrance = null;
|
let matchingEntrance = null;
|
||||||
for (let i = 0; i < range; ++i) {
|
for (let i = 0; i < range; ++i) {
|
||||||
currentPos.addInplace(offset);
|
currentPos.addInplace(offset);
|
||||||
const contents = this.root.map.getTileContent(currentPos);
|
const contents = this.root.map.getTileContent(currentPos, entity.layer);
|
||||||
if (!contents) {
|
if (!contents) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -128,7 +129,7 @@ export class UndergroundBeltSystem extends GameSystemWithFilter {
|
|||||||
for (let i = 0; i < matchingEntrance.range; ++i) {
|
for (let i = 0; i < matchingEntrance.range; ++i) {
|
||||||
currentPos.addInplace(offset);
|
currentPos.addInplace(offset);
|
||||||
|
|
||||||
const contents = this.root.map.getTileContent(currentPos);
|
const contents = this.root.map.getTileContent(currentPos, entity.layer);
|
||||||
if (!contents) {
|
if (!contents) {
|
||||||
allBeltsMatch = false;
|
allBeltsMatch = false;
|
||||||
break;
|
break;
|
||||||
@ -156,7 +157,7 @@ export class UndergroundBeltSystem extends GameSystemWithFilter {
|
|||||||
// All belts between this are obsolete, so drop them
|
// All belts between this are obsolete, so drop them
|
||||||
for (let i = 0; i < matchingEntrance.range; ++i) {
|
for (let i = 0; i < matchingEntrance.range; ++i) {
|
||||||
currentPos.addInplace(offset);
|
currentPos.addInplace(offset);
|
||||||
const contents = this.root.map.getTileContent(currentPos);
|
const contents = this.root.map.getTileContent(currentPos, entity.layer);
|
||||||
assert(contents, "Invalid smart underground belt logic");
|
assert(contents, "Invalid smart underground belt logic");
|
||||||
this.root.logic.tryDeleteBuilding(contents);
|
this.root.logic.tryDeleteBuilding(contents);
|
||||||
}
|
}
|
||||||
@ -169,8 +170,8 @@ export class UndergroundBeltSystem extends GameSystemWithFilter {
|
|||||||
const posBefore = currentPos.copy();
|
const posBefore = currentPos.copy();
|
||||||
currentPos.addInplace(offset);
|
currentPos.addInplace(offset);
|
||||||
|
|
||||||
const entityBefore = this.root.map.getTileContent(posBefore);
|
const entityBefore = this.root.map.getTileContent(posBefore, entity.layer);
|
||||||
const entityAfter = this.root.map.getTileContent(currentPos);
|
const entityAfter = this.root.map.getTileContent(currentPos, entity.layer);
|
||||||
|
|
||||||
if (!entityBefore || !entityAfter) {
|
if (!entityBefore || !entityAfter) {
|
||||||
continue;
|
continue;
|
||||||
@ -233,16 +234,16 @@ export class UndergroundBeltSystem extends GameSystemWithFilter {
|
|||||||
|
|
||||||
for (let x = area.x; x < area.right(); ++x) {
|
for (let x = area.x; x < area.right(); ++x) {
|
||||||
for (let y = area.y; y < area.bottom(); ++y) {
|
for (let y = area.y; y < area.bottom(); ++y) {
|
||||||
const entity = this.root.map.getTileContentXY(x, y);
|
const entities = this.root.map.getLayersContentsMultipleXY(x, y);
|
||||||
if (!entity) {
|
for (let i = 0; i < entities.length; ++i) {
|
||||||
continue;
|
const entity = entities[i];
|
||||||
}
|
const undergroundComp = entity.components.UndergroundBelt;
|
||||||
const undergroundComp = entity.components.UndergroundBelt;
|
if (!undergroundComp) {
|
||||||
if (!undergroundComp) {
|
continue;
|
||||||
continue;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
undergroundComp.cachedLinkedEntity = null;
|
undergroundComp.cachedLinkedEntity = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -297,7 +298,7 @@ export class UndergroundBeltSystem extends GameSystemWithFilter {
|
|||||||
) {
|
) {
|
||||||
currentTile = currentTile.add(searchVector);
|
currentTile = currentTile.add(searchVector);
|
||||||
|
|
||||||
const potentialReceiver = this.root.map.getTileContent(currentTile);
|
const potentialReceiver = this.root.map.getTileContent(currentTile, enumLayer.regular);
|
||||||
if (!potentialReceiver) {
|
if (!potentialReceiver) {
|
||||||
// Empty tile
|
// Empty tile
|
||||||
continue;
|
continue;
|
||||||
@ -393,7 +394,8 @@ export class UndergroundBeltSystem extends GameSystemWithFilter {
|
|||||||
|
|
||||||
if (remainingTime <= 0) {
|
if (remainingTime <= 0) {
|
||||||
const ejectorComp = entity.components.ItemEjector;
|
const ejectorComp = entity.components.ItemEjector;
|
||||||
const nextSlotIndex = ejectorComp.getFirstFreeSlot();
|
|
||||||
|
const nextSlotIndex = ejectorComp.getFirstFreeSlot(entity.layer);
|
||||||
if (nextSlotIndex !== null) {
|
if (nextSlotIndex !== null) {
|
||||||
if (ejectorComp.tryEject(nextSlotIndex, nextItem)) {
|
if (ejectorComp.tryEject(nextSlotIndex, nextItem)) {
|
||||||
items.shift();
|
items.shift();
|
||||||
|
@ -1,17 +1,22 @@
|
|||||||
import { GameSystemWithFilter } from "../game_system_with_filter";
|
|
||||||
import { WiredPinsComponent, enumPinSlotType } from "../components/wired_pins";
|
|
||||||
import { DrawParameters } from "../../core/draw_parameters";
|
|
||||||
import { Entity } from "../entity";
|
|
||||||
import { THEME } from "../theme";
|
|
||||||
import { Loader } from "../../core/loader";
|
|
||||||
import { globalConfig } from "../../core/config";
|
import { globalConfig } from "../../core/config";
|
||||||
|
import { DrawParameters } from "../../core/draw_parameters";
|
||||||
|
import { WiredPinsComponent, enumPinSlotType } from "../components/wired_pins";
|
||||||
|
import { Entity } from "../entity";
|
||||||
|
import { GameSystemWithFilter } from "../game_system_with_filter";
|
||||||
|
import { MapChunkView } from "../map_chunk_view";
|
||||||
|
import { Loader } from "../../core/loader";
|
||||||
|
|
||||||
export class WiredPinsSystem extends GameSystemWithFilter {
|
export class WiredPinsSystem extends GameSystemWithFilter {
|
||||||
constructor(root) {
|
constructor(root) {
|
||||||
super(root, [WiredPinsComponent]);
|
super(root, [WiredPinsComponent]);
|
||||||
|
|
||||||
this.pinSprites = {
|
this.pinSprites = {
|
||||||
[enumPinSlotType.energyEjector]: [Loader.getSprite("sprites/wires/pin-energy-on.png")],
|
[enumPinSlotType.positiveEnergyEjector]: Loader.getSprite(
|
||||||
|
"sprites/wires/pin-positive-energy.png"
|
||||||
|
),
|
||||||
|
[enumPinSlotType.negativeEnergyAcceptor]: Loader.getSprite(
|
||||||
|
"sprites/wires/pin-negative-energy.png"
|
||||||
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -19,25 +24,22 @@ export class WiredPinsSystem extends GameSystemWithFilter {
|
|||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
drawWiresLayer(parameters) {
|
/**
|
||||||
this.forEachMatchingEntityOnScreen(parameters, this.drawEntityPins.bind(this));
|
* Draws the given layer
|
||||||
|
* @param {DrawParameters} parameters
|
||||||
|
*/
|
||||||
|
draw(parameters) {
|
||||||
|
this.forEachMatchingEntityOnScreen(parameters, this.drawSingleEntity.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Draws a given chunk
|
||||||
* @param {DrawParameters} parameters
|
* @param {DrawParameters} parameters
|
||||||
* @param {Entity} entity
|
* @param {Entity} entity
|
||||||
*/
|
*/
|
||||||
drawEntityPins(parameters, entity) {
|
drawSingleEntity(parameters, entity) {
|
||||||
const staticComp = entity.components.StaticMapEntity;
|
const staticComp = entity.components.StaticMapEntity;
|
||||||
|
const slots = entity.components.WiredPins.slots;
|
||||||
if (!staticComp.shouldBeDrawn(parameters)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const pinsComp = entity.components.WiredPins;
|
|
||||||
|
|
||||||
const slots = pinsComp.slots;
|
|
||||||
|
|
||||||
for (let i = 0; i < slots.length; ++i) {
|
for (let i = 0; i < slots.length; ++i) {
|
||||||
const slot = slots[i];
|
const slot = slots[i];
|
||||||
@ -45,7 +47,7 @@ export class WiredPinsSystem extends GameSystemWithFilter {
|
|||||||
|
|
||||||
const worldPos = tile.toWorldSpaceCenterOfTile();
|
const worldPos = tile.toWorldSpaceCenterOfTile();
|
||||||
|
|
||||||
this.pinSprites[slot.type][0].drawCachedCentered(
|
this.pinSprites[slot.type].drawCachedCentered(
|
||||||
parameters,
|
parameters,
|
||||||
worldPos.x,
|
worldPos.x,
|
||||||
worldPos.y,
|
worldPos.y,
|
||||||
|
@ -441,6 +441,11 @@ buildings:
|
|||||||
name: &belt Conveyor Belt
|
name: &belt Conveyor Belt
|
||||||
description: Transports items, hold and drag to place multiple.
|
description: Transports items, hold and drag to place multiple.
|
||||||
|
|
||||||
|
wire:
|
||||||
|
default:
|
||||||
|
name: &wire Wire
|
||||||
|
description: Allows to transport energy
|
||||||
|
|
||||||
miner: # Internal name for the Extractor
|
miner: # Internal name for the Extractor
|
||||||
default:
|
default:
|
||||||
name: &miner Extractor
|
name: &miner Extractor
|
||||||
@ -801,6 +806,7 @@ keybindings:
|
|||||||
energy_generator: *energy_generator
|
energy_generator: *energy_generator
|
||||||
painter: *painter
|
painter: *painter
|
||||||
trash: *trash
|
trash: *trash
|
||||||
|
wire: *wire
|
||||||
|
|
||||||
pipette: Pipette
|
pipette: Pipette
|
||||||
rotateWhilePlacing: Rotate
|
rotateWhilePlacing: Rotate
|
||||||
|