Rework quad painter and filter, rework logic gates

This commit is contained in:
tobspr 2020-08-29 09:35:14 +02:00
parent 674d8a139e
commit bb739c80fa
24 changed files with 3016 additions and 2857 deletions

View File

@ -34,7 +34,7 @@
},
"sprites/belt/built/forward_4.png":
{
"frame": {"x":971,"y":1317,"w":116,"h":144},
"frame": {"x":421,"y":1482,"w":116,"h":144},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":0,"w":116,"h":144},
@ -42,7 +42,7 @@
},
"sprites/belt/built/forward_5.png":
{
"frame": {"x":421,"y":1482,"w":116,"h":144},
"frame": {"x":3,"y":1870,"w":116,"h":144},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":0,"w":116,"h":144},
@ -50,7 +50,7 @@
},
"sprites/belt/built/forward_6.png":
{
"frame": {"x":414,"y":1630,"w":116,"h":144},
"frame": {"x":123,"y":1870,"w":116,"h":144},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":0,"w":116,"h":144},
@ -58,7 +58,7 @@
},
"sprites/belt/built/forward_7.png":
{
"frame": {"x":969,"y":1465,"w":116,"h":144},
"frame": {"x":243,"y":1839,"w":116,"h":144},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":0,"w":116,"h":144},
@ -66,7 +66,7 @@
},
"sprites/belt/built/forward_8.png":
{
"frame": {"x":412,"y":1778,"w":116,"h":144},
"frame": {"x":971,"y":1297,"w":116,"h":144},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":0,"w":116,"h":144},
@ -74,7 +74,7 @@
},
"sprites/belt/built/forward_9.png":
{
"frame": {"x":961,"y":1613,"w":116,"h":144},
"frame": {"x":420,"y":1630,"w":116,"h":144},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":0,"w":116,"h":144},
@ -98,7 +98,7 @@
},
"sprites/belt/built/forward_12.png":
{
"frame": {"x":1530,"y":1435,"w":116,"h":144},
"frame": {"x":1532,"y":1435,"w":116,"h":144},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":0,"w":116,"h":144},
@ -130,7 +130,7 @@
},
"sprites/belt/built/left_2.png":
{
"frame": {"x":3,"y":1696,"w":130,"h":130},
"frame": {"x":541,"y":1525,"w":130,"h":130},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":14,"w":130,"h":130},
@ -138,7 +138,7 @@
},
"sprites/belt/built/left_3.png":
{
"frame": {"x":541,"y":1580,"w":130,"h":130},
"frame": {"x":1091,"y":1363,"w":130,"h":130},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":14,"w":130,"h":130},
@ -146,7 +146,7 @@
},
"sprites/belt/built/left_4.png":
{
"frame": {"x":278,"y":1687,"w":130,"h":130},
"frame": {"x":675,"y":1557,"w":130,"h":130},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":14,"w":130,"h":130},
@ -154,7 +154,7 @@
},
"sprites/belt/built/left_5.png":
{
"frame": {"x":137,"y":1705,"w":130,"h":130},
"frame": {"x":540,"y":1659,"w":130,"h":130},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":14,"w":130,"h":130},
@ -162,7 +162,7 @@
},
"sprites/belt/built/left_6.png":
{
"frame": {"x":3,"y":1830,"w":130,"h":130},
"frame": {"x":809,"y":1590,"w":130,"h":130},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":14,"w":130,"h":130},
@ -170,7 +170,7 @@
},
"sprites/belt/built/left_7.png":
{
"frame": {"x":1091,"y":1354,"w":130,"h":130},
"frame": {"x":674,"y":1691,"w":130,"h":130},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":14,"w":130,"h":130},
@ -178,7 +178,7 @@
},
"sprites/belt/built/left_8.png":
{
"frame": {"x":827,"y":1578,"w":130,"h":130},
"frame": {"x":1225,"y":1404,"w":130,"h":130},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":14,"w":130,"h":130},
@ -186,7 +186,7 @@
},
"sprites/belt/built/left_9.png":
{
"frame": {"x":534,"y":1714,"w":130,"h":130},
"frame": {"x":1088,"y":1497,"w":130,"h":130},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":14,"w":130,"h":130},
@ -210,7 +210,7 @@
},
"sprites/belt/built/left_12.png":
{
"frame": {"x":280,"y":1553,"w":130,"h":130},
"frame": {"x":145,"y":1571,"w":130,"h":130},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":14,"w":130,"h":130},
@ -218,7 +218,7 @@
},
"sprites/belt/built/left_13.png":
{
"frame": {"x":144,"y":1571,"w":130,"h":130},
"frame": {"x":144,"y":1705,"w":130,"h":130},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":14,"w":130,"h":130},
@ -226,7 +226,7 @@
},
"sprites/belt/built/right_0.png":
{
"frame": {"x":271,"y":1821,"w":130,"h":130},
"frame": {"x":943,"y":1593,"w":130,"h":130},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":14,"w":130,"h":130},
@ -234,7 +234,7 @@
},
"sprites/belt/built/right_1.png":
{
"frame": {"x":137,"y":1839,"w":130,"h":130},
"frame": {"x":808,"y":1724,"w":130,"h":130},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":14,"w":130,"h":130},
@ -242,7 +242,7 @@
},
"sprites/belt/built/right_2.png":
{
"frame": {"x":532,"y":1848,"w":130,"h":130},
"frame": {"x":363,"y":1778,"w":130,"h":130},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":14,"w":130,"h":130},
@ -250,7 +250,7 @@
},
"sprites/belt/built/right_3.png":
{
"frame": {"x":1359,"y":1447,"w":130,"h":130},
"frame": {"x":363,"y":1912,"w":130,"h":130},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":14,"w":130,"h":130},
@ -258,7 +258,7 @@
},
"sprites/belt/built/right_4.png":
{
"frame": {"x":1223,"y":1539,"w":130,"h":130},
"frame": {"x":497,"y":1793,"w":130,"h":130},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":14,"w":130,"h":130},
@ -266,7 +266,7 @@
},
"sprites/belt/built/right_5.png":
{
"frame": {"x":1081,"y":1622,"w":130,"h":130},
"frame": {"x":631,"y":1825,"w":130,"h":130},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":14,"w":130,"h":130},
@ -274,7 +274,7 @@
},
"sprites/belt/built/right_6.png":
{
"frame": {"x":1357,"y":1581,"w":130,"h":130},
"frame": {"x":765,"y":1858,"w":130,"h":130},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":14,"w":130,"h":130},
@ -282,7 +282,7 @@
},
"sprites/belt/built/right_7.png":
{
"frame": {"x":1215,"y":1673,"w":130,"h":130},
"frame": {"x":1031,"y":1861,"w":130,"h":130},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":14,"w":130,"h":130},
@ -290,7 +290,7 @@
},
"sprites/belt/built/right_8.png":
{
"frame": {"x":1081,"y":1756,"w":130,"h":130},
"frame": {"x":1165,"y":1765,"w":130,"h":130},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":14,"w":130,"h":130},
@ -298,7 +298,7 @@
},
"sprites/belt/built/right_9.png":
{
"frame": {"x":798,"y":1909,"w":130,"h":130},
"frame": {"x":1165,"y":1899,"w":130,"h":130},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":14,"w":130,"h":130},
@ -306,7 +306,7 @@
},
"sprites/belt/built/right_10.png":
{
"frame": {"x":1225,"y":1405,"w":130,"h":130},
"frame": {"x":1359,"y":1449,"w":130,"h":130},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":14,"w":130,"h":130},
@ -314,7 +314,7 @@
},
"sprites/belt/built/right_11.png":
{
"frame": {"x":1089,"y":1488,"w":130,"h":130},
"frame": {"x":1222,"y":1538,"w":130,"h":130},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":14,"w":130,"h":130},
@ -322,7 +322,7 @@
},
"sprites/belt/built/right_12.png":
{
"frame": {"x":827,"y":1712,"w":130,"h":130},
"frame": {"x":1077,"y":1631,"w":130,"h":130},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":14,"w":130,"h":130},
@ -330,7 +330,7 @@
},
"sprites/belt/built/right_13.png":
{
"frame": {"x":668,"y":1717,"w":130,"h":130},
"frame": {"x":942,"y":1727,"w":130,"h":130},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":14,"w":130,"h":130},
@ -338,7 +338,7 @@
},
"sprites/blueprints/belt_left.png":
{
"frame": {"x":932,"y":1909,"w":130,"h":130},
"frame": {"x":1356,"y":1583,"w":130,"h":130},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":14,"w":130,"h":130},
@ -346,7 +346,7 @@
},
"sprites/blueprints/belt_right.png":
{
"frame": {"x":1066,"y":1909,"w":130,"h":130},
"frame": {"x":1490,"y":1583,"w":130,"h":130},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":14,"w":130,"h":130},
@ -354,7 +354,7 @@
},
"sprites/blueprints/belt_top.png":
{
"frame": {"x":961,"y":1761,"w":116,"h":144},
"frame": {"x":968,"y":1445,"w":116,"h":144},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":0,"w":116,"h":144},
@ -362,7 +362,7 @@
},
"sprites/blueprints/constant_signal.png":
{
"frame": {"x":1938,"y":759,"w":105,"h":127},
"frame": {"x":1938,"y":847,"w":105,"h":127},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":20,"y":0,"w":105,"h":127},
@ -386,7 +386,7 @@
},
"sprites/blueprints/display.png":
{
"frame": {"x":666,"y":1909,"w":128,"h":136},
"frame": {"x":899,"y":1861,"w":128,"h":136},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":8,"y":8,"w":128,"h":136},
@ -450,7 +450,7 @@
},
"sprites/blueprints/miner-chainable.png":
{
"frame": {"x":689,"y":1424,"w":136,"h":143},
"frame": {"x":3,"y":1723,"w":136,"h":143},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":136,"h":143},
@ -458,7 +458,7 @@
},
"sprites/blueprints/miner.png":
{
"frame": {"x":547,"y":1433,"w":136,"h":143},
"frame": {"x":831,"y":1297,"w":136,"h":143},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":136,"h":143},
@ -514,7 +514,7 @@
},
"sprites/blueprints/rotater-fl.png":
{
"frame": {"x":948,"y":1169,"w":142,"h":144},
"frame": {"x":1242,"y":1116,"w":142,"h":144},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":142,"h":144},
@ -522,7 +522,7 @@
},
"sprites/blueprints/rotater.png":
{
"frame": {"x":1899,"y":1169,"w":143,"h":144},
"frame": {"x":1897,"y":1257,"w":143,"h":144},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":143,"h":144},
@ -530,7 +530,7 @@
},
"sprites/blueprints/splitter-compact-inverse.png":
{
"frame": {"x":1242,"y":1116,"w":142,"h":138},
"frame": {"x":1095,"y":1221,"w":142,"h":138},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":2,"w":142,"h":138},
@ -538,7 +538,7 @@
},
"sprites/blueprints/splitter-compact-merge-inverse.png":
{
"frame": {"x":1094,"y":1212,"w":142,"h":138},
"frame": {"x":1388,"y":1160,"w":142,"h":138},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":2,"w":142,"h":138},
@ -546,7 +546,7 @@
},
"sprites/blueprints/splitter-compact-merge.png":
{
"frame": {"x":1650,"y":1493,"w":139,"h":138},
"frame": {"x":1881,"y":1552,"w":139,"h":138},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":2,"w":139,"h":138},
@ -554,7 +554,7 @@
},
"sprites/blueprints/splitter-compact.png":
{
"frame": {"x":1844,"y":1604,"w":139,"h":138},
"frame": {"x":559,"y":1036,"w":139,"h":138},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":2,"w":139,"h":138},
@ -594,7 +594,7 @@
},
"sprites/blueprints/underground_belt_entry-tier2.png":
{
"frame": {"x":553,"y":1176,"w":138,"h":125},
"frame": {"x":3,"y":1466,"w":138,"h":125},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":19,"w":138,"h":125},
@ -602,7 +602,7 @@
},
"sprites/blueprints/underground_belt_entry.png":
{
"frame": {"x":285,"y":1322,"w":138,"h":112},
"frame": {"x":696,"y":1180,"w":138,"h":112},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":32,"w":138,"h":112},
@ -610,7 +610,7 @@
},
"sprites/blueprints/underground_belt_exit-tier2.png":
{
"frame": {"x":3,"y":1326,"w":139,"h":112},
"frame": {"x":553,"y":1178,"w":139,"h":112},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":0,"w":139,"h":112},
@ -618,7 +618,7 @@
},
"sprites/blueprints/underground_belt_exit.png":
{
"frame": {"x":3,"y":1442,"w":138,"h":112},
"frame": {"x":548,"y":1294,"w":138,"h":112},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":0,"w":138,"h":112},
@ -634,7 +634,7 @@
},
"sprites/blueprints/virtual_processor-rotater.png":
{
"frame": {"x":1925,"y":1021,"w":118,"h":144},
"frame": {"x":1925,"y":1109,"w":118,"h":144},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":0,"w":118,"h":144},
@ -706,7 +706,7 @@
},
"sprites/blueprints/wire_tunnel.png":
{
"frame": {"x":702,"y":1170,"w":138,"h":135},
"frame": {"x":285,"y":1322,"w":138,"h":135},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":4,"w":138,"h":135},
@ -722,7 +722,7 @@
},
"sprites/buildings/belt_right.png":
{
"frame": {"x":271,"y":1821,"w":130,"h":130},
"frame": {"x":943,"y":1593,"w":130,"h":130},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":14,"w":130,"h":130},
@ -738,7 +738,7 @@
},
"sprites/buildings/constant_signal.png":
{
"frame": {"x":1941,"y":628,"w":104,"h":127},
"frame": {"x":1941,"y":716,"w":104,"h":127},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":20,"y":0,"w":104,"h":127},
@ -802,7 +802,7 @@
},
"sprites/buildings/logic_gate-or.png":
{
"frame": {"x":1095,"y":1085,"w":143,"h":123},
"frame": {"x":948,"y":1170,"w":143,"h":123},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":143,"h":123},
@ -818,7 +818,7 @@
},
"sprites/buildings/logic_gate-xor.png":
{
"frame": {"x":1897,"y":1317,"w":143,"h":143},
"frame": {"x":801,"y":1033,"w":143,"h":143},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":143,"h":143},
@ -826,7 +826,7 @@
},
"sprites/buildings/logic_gate.png":
{
"frame": {"x":948,"y":1033,"w":143,"h":132},
"frame": {"x":1095,"y":1085,"w":143,"h":132},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":143,"h":132},
@ -834,7 +834,7 @@
},
"sprites/buildings/miner-chainable.png":
{
"frame": {"x":829,"y":1432,"w":136,"h":142},
"frame": {"x":688,"y":1411,"w":136,"h":142},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":136,"h":142},
@ -842,7 +842,7 @@
},
"sprites/buildings/miner.png":
{
"frame": {"x":687,"y":1571,"w":136,"h":142},
"frame": {"x":828,"y":1444,"w":136,"h":142},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":136,"h":142},
@ -890,7 +890,7 @@
},
"sprites/buildings/rotater-ccw.png":
{
"frame": {"x":1240,"y":1258,"w":141,"h":143},
"frame": {"x":1387,"y":1302,"w":141,"h":143},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":0,"w":141,"h":143},
@ -898,7 +898,7 @@
},
"sprites/buildings/rotater-fl.png":
{
"frame": {"x":1385,"y":1300,"w":141,"h":143},
"frame": {"x":1654,"y":1346,"w":141,"h":143},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":141,"h":143},
@ -906,7 +906,7 @@
},
"sprites/buildings/rotater.png":
{
"frame": {"x":1654,"y":1346,"w":141,"h":143},
"frame": {"x":1884,"y":1405,"w":141,"h":143},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":0,"w":141,"h":143},
@ -914,7 +914,7 @@
},
"sprites/buildings/splitter-compact-inverse.png":
{
"frame": {"x":1884,"y":1464,"w":141,"h":136},
"frame": {"x":1652,"y":1493,"w":141,"h":136},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":3,"w":141,"h":136},
@ -922,7 +922,7 @@
},
"sprites/buildings/splitter-compact-merge-inverse.png":
{
"frame": {"x":1388,"y":1160,"w":142,"h":136},
"frame": {"x":1241,"y":1264,"w":142,"h":136},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":3,"w":142,"h":136},
@ -930,7 +930,7 @@
},
"sprites/buildings/splitter-compact-merge.png":
{
"frame": {"x":559,"y":1036,"w":139,"h":136},
"frame": {"x":285,"y":1182,"w":139,"h":136},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":3,"w":139,"h":136},
@ -938,7 +938,7 @@
},
"sprites/buildings/splitter-compact.png":
{
"frame": {"x":285,"y":1182,"w":139,"h":136},
"frame": {"x":3,"y":1326,"w":139,"h":136},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":3,"w":139,"h":136},
@ -978,7 +978,7 @@
},
"sprites/buildings/underground_belt_entry-tier2.png":
{
"frame": {"x":548,"y":1305,"w":137,"h":124},
"frame": {"x":3,"y":1595,"w":137,"h":124},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":20,"w":137,"h":124},
@ -986,7 +986,7 @@
},
"sprites/buildings/underground_belt_entry.png":
{
"frame": {"x":280,"y":1438,"w":137,"h":111},
"frame": {"x":690,"y":1296,"w":137,"h":111},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":33,"w":137,"h":111},
@ -994,7 +994,7 @@
},
"sprites/buildings/underground_belt_exit-tier2.png":
{
"frame": {"x":689,"y":1309,"w":137,"h":111},
"frame": {"x":547,"y":1410,"w":137,"h":111},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":137,"h":111},
@ -1002,7 +1002,7 @@
},
"sprites/buildings/underground_belt_exit.png":
{
"frame": {"x":830,"y":1317,"w":137,"h":111},
"frame": {"x":279,"y":1599,"w":137,"h":111},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":137,"h":111},
@ -1026,7 +1026,7 @@
},
"sprites/buildings/virtual_processor-shapecompare.png":
{
"frame": {"x":801,"y":1033,"w":143,"h":133},
"frame": {"x":948,"y":1033,"w":143,"h":133},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":143,"h":133},
@ -1066,7 +1066,7 @@
},
"sprites/buildings/wire-turn.png":
{
"frame": {"x":1812,"y":1230,"w":81,"h":81},
"frame": {"x":1941,"y":631,"w":81,"h":81},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":63,"y":63,"w":81,"h":81},
@ -1074,7 +1074,7 @@
},
"sprites/buildings/wire.png":
{
"frame": {"x":2027,"y":184,"w":18,"h":144},
"frame": {"x":2027,"y":272,"w":18,"h":144},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":63,"y":0,"w":18,"h":144},
@ -1090,7 +1090,7 @@
},
"sprites/buildings/wire_tunnel.png":
{
"frame": {"x":3,"y":1558,"w":137,"h":134},
"frame": {"x":280,"y":1461,"w":137,"h":134},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":5,"w":137,"h":134},
@ -1114,12 +1114,28 @@
},
"sprites/misc/hub_direction_indicator.png":
{
"frame": {"x":1975,"y":184,"w":48,"h":48},
"frame": {"x":1975,"y":272,"w":48,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
"sourceSize": {"w":48,"h":48}
},
"sprites/misc/processor_disabled.png":
{
"frame": {"x":1799,"y":1485,"w":78,"h":81},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":10,"y":10,"w":78,"h":81},
"sourceSize": {"w":96,"h":96}
},
"sprites/misc/processor_disconnected.png":
{
"frame": {"x":1975,"y":3,"w":65,"h":84},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":17,"y":8,"w":65,"h":84},
"sourceSize": {"w":96,"h":96}
},
"sprites/misc/slot_bad_arrow.png":
{
"frame": {"x":255,"y":638,"w":35,"h":35},
@ -1146,7 +1162,7 @@
},
"sprites/misc/waypoint.png":
{
"frame": {"x":1987,"y":1656,"w":38,"h":48},
"frame": {"x":702,"y":1084,"w":38,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":38,"h":48},
@ -1170,7 +1186,7 @@
},
"sprites/wires/display/blue.png":
{
"frame": {"x":1975,"y":288,"w":47,"h":47},
"frame": {"x":1975,"y":376,"w":47,"h":47},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":47,"h":47},
@ -1178,7 +1194,7 @@
},
"sprites/wires/display/cyan.png":
{
"frame": {"x":1975,"y":339,"w":47,"h":47},
"frame": {"x":1975,"y":427,"w":47,"h":47},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":47,"h":47},
@ -1186,7 +1202,7 @@
},
"sprites/wires/display/green.png":
{
"frame": {"x":1975,"y":390,"w":47,"h":47},
"frame": {"x":1975,"y":478,"w":47,"h":47},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":47,"h":47},
@ -1194,7 +1210,7 @@
},
"sprites/wires/display/purple.png":
{
"frame": {"x":1975,"y":441,"w":47,"h":47},
"frame": {"x":1975,"y":529,"w":47,"h":47},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":47,"h":47},
@ -1202,7 +1218,7 @@
},
"sprites/wires/display/red.png":
{
"frame": {"x":1975,"y":492,"w":47,"h":47},
"frame": {"x":1975,"y":580,"w":47,"h":47},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":47,"h":47},
@ -1210,7 +1226,7 @@
},
"sprites/wires/display/white.png":
{
"frame": {"x":1975,"y":543,"w":47,"h":47},
"frame": {"x":1797,"y":1570,"w":47,"h":47},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":47,"h":47},
@ -1218,7 +1234,7 @@
},
"sprites/wires/display/yellow.png":
{
"frame": {"x":1793,"y":1570,"w":47,"h":47},
"frame": {"x":1797,"y":1621,"w":47,"h":47},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":47,"h":47},
@ -1226,7 +1242,7 @@
},
"sprites/wires/lever_on.png":
{
"frame": {"x":1936,"y":890,"w":109,"h":127},
"frame": {"x":1936,"y":978,"w":109,"h":127},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":18,"y":5,"w":109,"h":127},
@ -1234,7 +1250,7 @@
},
"sprites/wires/logical_acceptor.png":
{
"frame": {"x":1975,"y":3,"w":62,"h":106},
"frame": {"x":1975,"y":91,"w":62,"h":106},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":43,"y":0,"w":62,"h":106},
@ -1242,7 +1258,7 @@
},
"sprites/wires/logical_ejector.png":
{
"frame": {"x":1975,"y":113,"w":60,"h":67},
"frame": {"x":1975,"y":201,"w":60,"h":67},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":44,"y":0,"w":60,"h":67},
@ -1250,7 +1266,7 @@
},
"sprites/wires/network_conflict.png":
{
"frame": {"x":1793,"y":1621,"w":47,"h":44},
"frame": {"x":702,"y":1036,"w":47,"h":44},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":2,"w":47,"h":44},
@ -1258,7 +1274,7 @@
},
"sprites/wires/network_empty.png":
{
"frame": {"x":1987,"y":1604,"w":41,"h":48},
"frame": {"x":753,"y":1036,"w":41,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":41,"h":48},
@ -1282,7 +1298,7 @@
},
"sprites/wires/sets/color_forward.png":
{
"frame": {"x":2026,"y":332,"w":18,"h":144},
"frame": {"x":2026,"y":420,"w":18,"h":144},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":63,"y":0,"w":18,"h":144},
@ -1298,7 +1314,7 @@
},
"sprites/wires/sets/color_turn.png":
{
"frame": {"x":1812,"y":1315,"w":81,"h":81},
"frame": {"x":1812,"y":1230,"w":81,"h":81},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":63,"y":63,"w":81,"h":81},
@ -1314,7 +1330,7 @@
},
"sprites/wires/sets/conflict_forward.png":
{
"frame": {"x":2026,"y":480,"w":18,"h":144},
"frame": {"x":2026,"y":568,"w":18,"h":144},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":63,"y":0,"w":18,"h":144},
@ -1330,7 +1346,7 @@
},
"sprites/wires/sets/conflict_turn.png":
{
"frame": {"x":1799,"y":1400,"w":81,"h":81},
"frame": {"x":1812,"y":1315,"w":81,"h":81},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":63,"y":63,"w":81,"h":81},
@ -1346,7 +1362,7 @@
},
"sprites/wires/sets/regular_forward.png":
{
"frame": {"x":2027,"y":184,"w":18,"h":144},
"frame": {"x":2027,"y":272,"w":18,"h":144},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":63,"y":0,"w":18,"h":144},
@ -1362,7 +1378,7 @@
},
"sprites/wires/sets/regular_turn.png":
{
"frame": {"x":1812,"y":1230,"w":81,"h":81},
"frame": {"x":1941,"y":631,"w":81,"h":81},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":63,"y":63,"w":81,"h":81},
@ -1394,7 +1410,7 @@
},
"sprites/wires/sets/shape_turn.png":
{
"frame": {"x":1799,"y":1485,"w":81,"h":81},
"frame": {"x":1799,"y":1400,"w":81,"h":81},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":63,"y":63,"w":81,"h":81},
@ -1402,7 +1418,7 @@
},
"sprites/wires/wires_preview.png":
{
"frame": {"x":1975,"y":236,"w":48,"h":48},
"frame": {"x":1975,"y":324,"w":48,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
@ -1415,6 +1431,6 @@
"format": "RGBA8888",
"size": {"w":2048,"h":2048},
"scale": "0.75",
"smartupdate": "$TexturePacker:SmartUpdate:65dccccf359b3f3582914eac20260366:f9eee0054558f8bf77da34f281176a03:908b89f5ca8ff73e331a35a3b14d0604$"
"smartupdate": "$TexturePacker:SmartUpdate:1923b9c910205fb09957b67f92de02b9:0d87df06f18965307bf9d18b414f603d:908b89f5ca8ff73e331a35a3b14d0604$"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 266 KiB

After

Width:  |  Height:  |  Size: 269 KiB

View File

@ -10,7 +10,7 @@
},
"sprites/belt/built/forward_1.png":
{
"frame": {"x":439,"y":803,"w":78,"h":96},
"frame": {"x":3,"y":1759,"w":78,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":0,"w":78,"h":96},
@ -18,7 +18,7 @@
},
"sprites/belt/built/forward_2.png":
{
"frame": {"x":758,"y":1549,"w":78,"h":96},
"frame": {"x":557,"y":1587,"w":78,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":0,"w":78,"h":96},
@ -26,7 +26,7 @@
},
"sprites/belt/built/forward_3.png":
{
"frame": {"x":658,"y":1555,"w":78,"h":96},
"frame": {"x":459,"y":1653,"w":78,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":0,"w":78,"h":96},
@ -34,7 +34,7 @@
},
"sprites/belt/built/forward_4.png":
{
"frame": {"x":556,"y":1580,"w":78,"h":96},
"frame": {"x":362,"y":1663,"w":78,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":0,"w":78,"h":96},
@ -42,7 +42,7 @@
},
"sprites/belt/built/forward_5.png":
{
"frame": {"x":459,"y":1617,"w":78,"h":96},
"frame": {"x":268,"y":1704,"w":78,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":0,"w":78,"h":96},
@ -50,7 +50,7 @@
},
"sprites/belt/built/forward_6.png":
{
"frame": {"x":359,"y":1647,"w":78,"h":96},
"frame": {"x":177,"y":1761,"w":78,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":0,"w":78,"h":96},
@ -58,7 +58,7 @@
},
"sprites/belt/built/forward_7.png":
{
"frame": {"x":268,"y":1671,"w":78,"h":96},
"frame": {"x":85,"y":1805,"w":78,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":0,"w":78,"h":96},
@ -66,7 +66,7 @@
},
"sprites/belt/built/forward_8.png":
{
"frame": {"x":176,"y":1749,"w":78,"h":96},
"frame": {"x":3,"y":1859,"w":78,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":0,"w":78,"h":96},
@ -74,7 +74,7 @@
},
"sprites/belt/built/forward_9.png":
{
"frame": {"x":85,"y":1821,"w":78,"h":96},
"frame": {"x":85,"y":1905,"w":78,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":0,"w":78,"h":96},
@ -82,7 +82,7 @@
},
"sprites/belt/built/forward_10.png":
{
"frame": {"x":94,"y":1721,"w":78,"h":96},
"frame": {"x":860,"y":1408,"w":78,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":0,"w":78,"h":96},
@ -90,7 +90,7 @@
},
"sprites/belt/built/forward_11.png":
{
"frame": {"x":3,"y":1737,"w":78,"h":96},
"frame": {"x":942,"y":1408,"w":78,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":0,"w":78,"h":96},
@ -98,7 +98,7 @@
},
"sprites/belt/built/forward_12.png":
{
"frame": {"x":859,"y":1500,"w":78,"h":96},
"frame": {"x":757,"y":1465,"w":78,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":0,"w":78,"h":96},
@ -106,7 +106,7 @@
},
"sprites/belt/built/forward_13.png":
{
"frame": {"x":941,"y":1500,"w":78,"h":96},
"frame": {"x":656,"y":1539,"w":78,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":0,"w":78,"h":96},
@ -114,7 +114,7 @@
},
"sprites/belt/built/left_0.png":
{
"frame": {"x":495,"y":1250,"w":87,"h":87},
"frame": {"x":931,"y":942,"w":87,"h":87},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":9,"w":87,"h":87},
@ -122,7 +122,7 @@
},
"sprites/belt/built/left_1.png":
{
"frame": {"x":394,"y":1274,"w":87,"h":87},
"frame": {"x":403,"y":911,"w":87,"h":87},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":9,"w":87,"h":87},
@ -130,7 +130,7 @@
},
"sprites/belt/built/left_2.png":
{
"frame": {"x":789,"y":1185,"w":87,"h":87},
"frame": {"x":99,"y":1432,"w":87,"h":87},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":9,"w":87,"h":87},
@ -138,7 +138,7 @@
},
"sprites/belt/built/left_3.png":
{
"frame": {"x":880,"y":1227,"w":87,"h":87},
"frame": {"x":3,"y":1486,"w":87,"h":87},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":9,"w":87,"h":87},
@ -146,7 +146,7 @@
},
"sprites/belt/built/left_4.png":
{
"frame": {"x":789,"y":1276,"w":87,"h":87},
"frame": {"x":786,"y":1192,"w":87,"h":87},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":9,"w":87,"h":87},
@ -154,7 +154,7 @@
},
"sprites/belt/built/left_5.png":
{
"frame": {"x":690,"y":1282,"w":87,"h":87},
"frame": {"x":687,"y":1266,"w":87,"h":87},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":9,"w":87,"h":87},
@ -162,7 +162,7 @@
},
"sprites/belt/built/left_6.png":
{
"frame": {"x":586,"y":1303,"w":87,"h":87},
"frame": {"x":587,"y":1310,"w":87,"h":87},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":9,"w":87,"h":87},
@ -170,7 +170,7 @@
},
"sprites/belt/built/left_7.png":
{
"frame": {"x":485,"y":1341,"w":87,"h":87},
"frame": {"x":484,"y":1377,"w":87,"h":87},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":9,"w":87,"h":87},
@ -178,7 +178,7 @@
},
"sprites/belt/built/left_8.png":
{
"frame": {"x":386,"y":1365,"w":87,"h":87},
"frame": {"x":384,"y":1381,"w":87,"h":87},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":9,"w":87,"h":87},
@ -186,7 +186,7 @@
},
"sprites/belt/built/left_9.png":
{
"frame": {"x":286,"y":1389,"w":87,"h":87},
"frame": {"x":287,"y":1422,"w":87,"h":87},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":9,"w":87,"h":87},
@ -194,7 +194,7 @@
},
"sprites/belt/built/left_10.png":
{
"frame": {"x":295,"y":1298,"w":87,"h":87},
"frame": {"x":403,"y":1002,"w":87,"h":87},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":9,"w":87,"h":87},
@ -202,7 +202,7 @@
},
"sprites/belt/built/left_11.png":
{
"frame": {"x":195,"y":1376,"w":87,"h":87},
"frame": {"x":393,"y":1290,"w":87,"h":87},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":9,"w":87,"h":87},
@ -210,7 +210,7 @@
},
"sprites/belt/built/left_12.png":
{
"frame": {"x":99,"y":1448,"w":87,"h":87},
"frame": {"x":293,"y":1331,"w":87,"h":87},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":9,"w":87,"h":87},
@ -218,7 +218,7 @@
},
"sprites/belt/built/left_13.png":
{
"frame": {"x":3,"y":1464,"w":87,"h":87},
"frame": {"x":196,"y":1388,"w":87,"h":87},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":9,"w":87,"h":87},
@ -226,7 +226,7 @@
},
"sprites/belt/built/right_0.png":
{
"frame": {"x":190,"y":1467,"w":87,"h":87},
"frame": {"x":190,"y":1479,"w":87,"h":87},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":9,"w":87,"h":87},
@ -234,7 +234,7 @@
},
"sprites/belt/built/right_1.png":
{
"frame": {"x":94,"y":1539,"w":87,"h":87},
"frame": {"x":94,"y":1523,"w":87,"h":87},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":9,"w":87,"h":87},
@ -242,7 +242,7 @@
},
"sprites/belt/built/right_2.png":
{
"frame": {"x":576,"y":1394,"w":87,"h":87},
"frame": {"x":575,"y":1401,"w":87,"h":87},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":9,"w":87,"h":87},
@ -250,7 +250,7 @@
},
"sprites/belt/built/right_3.png":
{
"frame": {"x":477,"y":1432,"w":87,"h":87},
"frame": {"x":475,"y":1468,"w":87,"h":87},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":9,"w":87,"h":87},
@ -258,7 +258,7 @@
},
"sprites/belt/built/right_4.png":
{
"frame": {"x":377,"y":1456,"w":87,"h":87},
"frame": {"x":378,"y":1472,"w":87,"h":87},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":9,"w":87,"h":87},
@ -266,7 +266,7 @@
},
"sprites/belt/built/right_5.png":
{
"frame": {"x":281,"y":1480,"w":87,"h":87},
"frame": {"x":281,"y":1513,"w":87,"h":87},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":9,"w":87,"h":87},
@ -274,7 +274,7 @@
},
"sprites/belt/built/right_6.png":
{
"frame": {"x":185,"y":1558,"w":87,"h":87},
"frame": {"x":185,"y":1570,"w":87,"h":87},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":9,"w":87,"h":87},
@ -282,7 +282,7 @@
},
"sprites/belt/built/right_7.png":
{
"frame": {"x":94,"y":1630,"w":87,"h":87},
"frame": {"x":94,"y":1614,"w":87,"h":87},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":9,"w":87,"h":87},
@ -290,7 +290,7 @@
},
"sprites/belt/built/right_8.png":
{
"frame": {"x":3,"y":1646,"w":87,"h":87},
"frame": {"x":3,"y":1668,"w":87,"h":87},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":9,"w":87,"h":87},
@ -298,7 +298,7 @@
},
"sprites/belt/built/right_9.png":
{
"frame": {"x":872,"y":1409,"w":87,"h":87},
"frame": {"x":869,"y":1317,"w":87,"h":87},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":9,"w":87,"h":87},
@ -306,7 +306,7 @@
},
"sprites/belt/built/right_10.png":
{
"frame": {"x":3,"y":1555,"w":87,"h":87},
"frame": {"x":3,"y":1577,"w":87,"h":87},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":9,"w":87,"h":87},
@ -314,7 +314,7 @@
},
"sprites/belt/built/right_11.png":
{
"frame": {"x":880,"y":1318,"w":87,"h":87},
"frame": {"x":877,"y":1226,"w":87,"h":87},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":9,"w":87,"h":87},
@ -322,7 +322,7 @@
},
"sprites/belt/built/right_12.png":
{
"frame": {"x":781,"y":1367,"w":87,"h":87},
"frame": {"x":778,"y":1283,"w":87,"h":87},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":9,"w":87,"h":87},
@ -330,7 +330,7 @@
},
"sprites/belt/built/right_13.png":
{
"frame": {"x":677,"y":1373,"w":87,"h":87},
"frame": {"x":678,"y":1357,"w":87,"h":87},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":9,"w":87,"h":87},
@ -338,7 +338,7 @@
},
"sprites/blueprints/belt_left.png":
{
"frame": {"x":768,"y":1458,"w":87,"h":87},
"frame": {"x":769,"y":1374,"w":87,"h":87},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":9,"w":87,"h":87},
@ -346,7 +346,7 @@
},
"sprites/blueprints/belt_right.png":
{
"frame": {"x":667,"y":1464,"w":87,"h":87},
"frame": {"x":666,"y":1448,"w":87,"h":87},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":9,"w":87,"h":87},
@ -354,7 +354,7 @@
},
"sprites/blueprints/belt_top.png":
{
"frame": {"x":3,"y":1837,"w":78,"h":96},
"frame": {"x":167,"y":1861,"w":78,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":0,"w":78,"h":96},
@ -386,7 +386,7 @@
},
"sprites/blueprints/display.png":
{
"frame": {"x":568,"y":1485,"w":86,"h":91},
"frame": {"x":566,"y":1492,"w":86,"h":91},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":5,"w":86,"h":91},
@ -410,7 +410,7 @@
},
"sprites/blueprints/logic_gate-not.png":
{
"frame": {"x":372,"y":1547,"w":83,"h":96},
"frame": {"x":372,"y":1563,"w":83,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":7,"y":0,"w":83,"h":96},
@ -418,7 +418,7 @@
},
"sprites/blueprints/logic_gate-or.png":
{
"frame": {"x":3,"y":874,"w":96,"h":82},
"frame": {"x":303,"y":903,"w":96,"h":82},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":96,"h":82},
@ -426,7 +426,7 @@
},
"sprites/blueprints/logic_gate-transistor.png":
{
"frame": {"x":449,"y":703,"w":68,"h":96},
"frame": {"x":451,"y":703,"w":68,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":68,"h":96},
@ -442,7 +442,7 @@
},
"sprites/blueprints/logic_gate.png":
{
"frame": {"x":521,"y":999,"w":96,"h":89},
"frame": {"x":910,"y":1133,"w":96,"h":89},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":96,"h":89},
@ -450,7 +450,7 @@
},
"sprites/blueprints/miner-chainable.png":
{
"frame": {"x":929,"y":942,"w":92,"h":96},
"frame": {"x":496,"y":1178,"w":92,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":0,"w":92,"h":96},
@ -458,7 +458,7 @@
},
"sprites/blueprints/miner.png":
{
"frame": {"x":298,"y":1198,"w":92,"h":96},
"frame": {"x":396,"y":1190,"w":92,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":0,"w":92,"h":96},
@ -514,7 +514,7 @@
},
"sprites/blueprints/rotater-fl.png":
{
"frame": {"x":203,"y":990,"w":95,"h":96},
"frame": {"x":3,"y":926,"w":95,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":95,"h":96},
@ -530,7 +530,7 @@
},
"sprites/blueprints/splitter-compact-inverse.png":
{
"frame": {"x":202,"y":1090,"w":95,"h":93},
"frame": {"x":102,"y":1083,"w":95,"h":93},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":1,"w":95,"h":93},
@ -538,7 +538,7 @@
},
"sprites/blueprints/splitter-compact-merge-inverse.png":
{
"frame": {"x":102,"y":1091,"w":95,"h":93},
"frame": {"x":3,"y":1126,"w":95,"h":93},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":1,"w":95,"h":93},
@ -546,7 +546,7 @@
},
"sprites/blueprints/splitter-compact-merge.png":
{
"frame": {"x":401,"y":1098,"w":93,"h":93},
"frame": {"x":3,"y":1223,"w":93,"h":93},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":1,"w":93,"h":93},
@ -554,7 +554,7 @@
},
"sprites/blueprints/splitter-compact.png":
{
"frame": {"x":301,"y":1101,"w":93,"h":93},
"frame": {"x":399,"y":1093,"w":93,"h":93},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":1,"w":93,"h":93},
@ -586,7 +586,7 @@
},
"sprites/blueprints/trash.png":
{
"frame": {"x":349,"y":703,"w":96,"h":96},
"frame": {"x":351,"y":703,"w":96,"h":96},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":96,"h":96},
@ -594,7 +594,7 @@
},
"sprites/blueprints/underground_belt_entry-tier2.png":
{
"frame": {"x":597,"y":1116,"w":93,"h":84},
"frame": {"x":3,"y":1320,"w":93,"h":84},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":12,"w":93,"h":84},
@ -602,7 +602,7 @@
},
"sprites/blueprints/underground_belt_entry.png":
{
"frame": {"x":498,"y":1171,"w":93,"h":75},
"frame": {"x":496,"y":1099,"w":93,"h":75},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":21,"w":93,"h":75},
@ -610,7 +610,7 @@
},
"sprites/blueprints/underground_belt_exit-tier2.png":
{
"frame": {"x":499,"y":1092,"w":94,"h":75},
"frame": {"x":102,"y":1180,"w":94,"h":75},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":0,"w":94,"h":75},
@ -618,7 +618,7 @@
},
"sprites/blueprints/underground_belt_exit.png":
{
"frame": {"x":398,"y":1195,"w":93,"h":75},
"frame": {"x":593,"y":1132,"w":93,"h":75},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":0,"w":93,"h":75},
@ -626,7 +626,7 @@
},
"sprites/blueprints/virtual_processor-analyzer.png":
{
"frame": {"x":521,"y":799,"w":96,"h":96},
"frame": {"x":523,"y":799,"w":96,"h":96},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":96,"h":96},
@ -634,7 +634,7 @@
},
"sprites/blueprints/virtual_processor-rotater.png":
{
"frame": {"x":276,"y":1571,"w":79,"h":96},
"frame": {"x":185,"y":1661,"w":79,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":0,"w":79,"h":96},
@ -642,7 +642,7 @@
},
"sprites/blueprints/virtual_processor-shapecompare.png":
{
"frame": {"x":621,"y":1023,"w":96,"h":89},
"frame": {"x":3,"y":774,"w":96,"h":89},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":96,"h":89},
@ -650,7 +650,7 @@
},
"sprites/blueprints/virtual_processor-unstacker.png":
{
"frame": {"x":729,"y":890,"w":96,"h":96},
"frame": {"x":349,"y":803,"w":96,"h":96},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":96,"h":96},
@ -658,7 +658,7 @@
},
"sprites/blueprints/virtual_processor.png":
{
"frame": {"x":921,"y":1042,"w":96,"h":94},
"frame": {"x":710,"y":1090,"w":96,"h":94},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":2,"w":96,"h":94},
@ -666,7 +666,7 @@
},
"sprites/blueprints/wire-cross.png":
{
"frame": {"x":829,"y":894,"w":96,"h":96},
"frame": {"x":522,"y":899,"w":96,"h":96},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":96,"h":96},
@ -674,7 +674,7 @@
},
"sprites/blueprints/wire-split.png":
{
"frame": {"x":103,"y":874,"w":96,"h":55},
"frame": {"x":3,"y":867,"w":96,"h":55},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":41,"w":96,"h":55},
@ -706,7 +706,7 @@
},
"sprites/blueprints/wire_tunnel.png":
{
"frame": {"x":201,"y":1187,"w":93,"h":91},
"frame": {"x":299,"y":1142,"w":93,"h":91},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":2,"w":93,"h":91},
@ -714,7 +714,7 @@
},
"sprites/buildings/belt_left.png":
{
"frame": {"x":495,"y":1250,"w":87,"h":87},
"frame": {"x":931,"y":942,"w":87,"h":87},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":9,"w":87,"h":87},
@ -722,7 +722,7 @@
},
"sprites/buildings/belt_right.png":
{
"frame": {"x":190,"y":1467,"w":87,"h":87},
"frame": {"x":190,"y":1479,"w":87,"h":87},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":9,"w":87,"h":87},
@ -762,7 +762,7 @@
},
"sprites/buildings/display.png":
{
"frame": {"x":468,"y":1523,"w":84,"h":90},
"frame": {"x":469,"y":1559,"w":84,"h":90},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":6,"y":6,"w":84,"h":90},
@ -794,7 +794,7 @@
},
"sprites/buildings/logic_gate-not.png":
{
"frame": {"x":435,"y":903,"w":82,"h":96},
"frame": {"x":276,"y":1604,"w":82,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":8,"y":0,"w":82,"h":96},
@ -802,7 +802,7 @@
},
"sprites/buildings/logic_gate-or.png":
{
"frame": {"x":921,"y":1140,"w":96,"h":83},
"frame": {"x":203,"y":866,"w":96,"h":83},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":96,"h":83},
@ -810,7 +810,7 @@
},
"sprites/buildings/logic_gate-transistor.png":
{
"frame": {"x":621,"y":799,"w":68,"h":96},
"frame": {"x":623,"y":799,"w":68,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":68,"h":96},
@ -818,7 +818,7 @@
},
"sprites/buildings/logic_gate-xor.png":
{
"frame": {"x":821,"y":994,"w":96,"h":95},
"frame": {"x":610,"y":1033,"w":96,"h":95},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":96,"h":95},
@ -826,7 +826,7 @@
},
"sprites/buildings/logic_gate.png":
{
"frame": {"x":821,"y":1093,"w":96,"h":88},
"frame": {"x":203,"y":774,"w":96,"h":88},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":96,"h":88},
@ -834,7 +834,7 @@
},
"sprites/buildings/miner-chainable.png":
{
"frame": {"x":694,"y":1183,"w":91,"h":95},
"frame": {"x":592,"y":1211,"w":91,"h":95},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":0,"w":91,"h":95},
@ -842,7 +842,7 @@
},
"sprites/buildings/miner.png":
{
"frame": {"x":595,"y":1204,"w":91,"h":95},
"frame": {"x":492,"y":1278,"w":91,"h":95},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":0,"w":91,"h":95},
@ -890,7 +890,7 @@
},
"sprites/buildings/rotater-ccw.png":
{
"frame": {"x":103,"y":991,"w":95,"h":96},
"frame": {"x":102,"y":983,"w":95,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":95,"h":96},
@ -898,7 +898,7 @@
},
"sprites/buildings/rotater-fl.png":
{
"frame": {"x":3,"y":1018,"w":95,"h":96},
"frame": {"x":3,"y":1026,"w":95,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":95,"h":96},
@ -906,7 +906,7 @@
},
"sprites/buildings/rotater.png":
{
"frame": {"x":302,"y":1001,"w":95,"h":96},
"frame": {"x":201,"y":1011,"w":95,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":95,"h":96},
@ -914,7 +914,7 @@
},
"sprites/buildings/splitter-compact-inverse.png":
{
"frame": {"x":401,"y":1003,"w":94,"h":91},
"frame": {"x":201,"y":1111,"w":94,"h":91},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":2,"w":94,"h":91},
@ -922,7 +922,7 @@
},
"sprites/buildings/splitter-compact-merge-inverse.png":
{
"frame": {"x":3,"y":1118,"w":95,"h":91},
"frame": {"x":300,"y":1047,"w":95,"h":91},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":2,"w":95,"h":91},
@ -930,7 +930,7 @@
},
"sprites/buildings/splitter-compact-merge.png":
{
"frame": {"x":102,"y":1188,"w":93,"h":91},
"frame": {"x":200,"y":1206,"w":93,"h":91},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":2,"w":93,"h":91},
@ -938,7 +938,7 @@
},
"sprites/buildings/splitter-compact.png":
{
"frame": {"x":3,"y":1213,"w":93,"h":91},
"frame": {"x":100,"y":1259,"w":93,"h":91},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":2,"w":93,"h":91},
@ -970,7 +970,7 @@
},
"sprites/buildings/trash.png":
{
"frame": {"x":3,"y":774,"w":96,"h":96},
"frame": {"x":731,"y":890,"w":96,"h":96},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":96,"h":96},
@ -978,7 +978,7 @@
},
"sprites/buildings/underground_belt_entry-tier2.png":
{
"frame": {"x":100,"y":1283,"w":92,"h":83},
"frame": {"x":197,"y":1301,"w":92,"h":83},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":13,"w":92,"h":83},
@ -986,7 +986,7 @@
},
"sprites/buildings/underground_belt_entry.png":
{
"frame": {"x":3,"y":1308,"w":92,"h":74},
"frame": {"x":100,"y":1354,"w":92,"h":74},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":22,"w":92,"h":74},
@ -994,7 +994,7 @@
},
"sprites/buildings/underground_belt_exit-tier2.png":
{
"frame": {"x":99,"y":1370,"w":92,"h":74},
"frame": {"x":3,"y":1408,"w":92,"h":74},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":0,"w":92,"h":74},
@ -1002,7 +1002,7 @@
},
"sprites/buildings/underground_belt_exit.png":
{
"frame": {"x":3,"y":1386,"w":92,"h":74},
"frame": {"x":690,"y":1188,"w":92,"h":74},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":0,"w":92,"h":74},
@ -1010,7 +1010,7 @@
},
"sprites/buildings/virtual_processor-analyzer.png":
{
"frame": {"x":103,"y":774,"w":96,"h":96},
"frame": {"x":622,"y":933,"w":96,"h":96},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":96,"h":96},
@ -1018,7 +1018,7 @@
},
"sprites/buildings/virtual_processor-rotater.png":
{
"frame": {"x":185,"y":1649,"w":79,"h":96},
"frame": {"x":94,"y":1705,"w":79,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":0,"w":79,"h":96},
@ -1026,7 +1026,7 @@
},
"sprites/buildings/virtual_processor-shapecompare.png":
{
"frame": {"x":721,"y":1090,"w":96,"h":89},
"frame": {"x":103,"y":774,"w":96,"h":89},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":96,"h":89},
@ -1034,7 +1034,7 @@
},
"sprites/buildings/virtual_processor-unstacker.png":
{
"frame": {"x":203,"y":774,"w":96,"h":96},
"frame": {"x":510,"y":999,"w":96,"h":96},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":96,"h":96},
@ -1042,7 +1042,7 @@
},
"sprites/buildings/virtual_processor.png":
{
"frame": {"x":335,"y":903,"w":96,"h":94},
"frame": {"x":810,"y":1094,"w":96,"h":94},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":2,"w":96,"h":94},
@ -1050,7 +1050,7 @@
},
"sprites/buildings/wire-cross.png":
{
"frame": {"x":339,"y":803,"w":96,"h":96},
"frame": {"x":831,"y":894,"w":96,"h":96},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":96,"h":96},
@ -1058,7 +1058,7 @@
},
"sprites/buildings/wire-split.png":
{
"frame": {"x":203,"y":874,"w":96,"h":54},
"frame": {"x":103,"y":867,"w":96,"h":54},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":42,"w":96,"h":54},
@ -1090,7 +1090,7 @@
},
"sprites/buildings/wire_tunnel.png":
{
"frame": {"x":199,"y":1282,"w":92,"h":90},
"frame": {"x":297,"y":1237,"w":92,"h":90},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":3,"w":92,"h":90},
@ -1114,12 +1114,28 @@
},
"sprites/misc/hub_direction_indicator.png":
{
"frame": {"x":693,"y":851,"w":32,"h":32},
"frame": {"x":695,"y":851,"w":32,"h":32},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":32,"h":32},
"sourceSize": {"w":32,"h":32}
},
"sprites/misc/processor_disabled.png":
{
"frame": {"x":449,"y":803,"w":53,"h":55},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":6,"y":6,"w":53,"h":55},
"sourceSize": {"w":64,"h":64}
},
"sprites/misc/processor_disconnected.png":
{
"frame": {"x":303,"y":674,"w":44,"h":57},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":11,"y":5,"w":44,"h":57},
"sourceSize": {"w":64,"h":64}
},
"sprites/misc/slot_bad_arrow.png":
{
"frame": {"x":717,"y":605,"w":24,"h":24},
@ -1218,7 +1234,7 @@
},
"sprites/wires/display/yellow.png":
{
"frame": {"x":693,"y":814,"w":33,"h":33},
"frame": {"x":695,"y":814,"w":33,"h":33},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":33,"h":33},
@ -1234,7 +1250,7 @@
},
"sprites/wires/logical_acceptor.png":
{
"frame": {"x":303,"y":674,"w":42,"h":71},
"frame": {"x":303,"y":735,"w":42,"h":71},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":28,"y":0,"w":42,"h":71},
@ -1242,7 +1258,7 @@
},
"sprites/wires/logical_ejector.png":
{
"frame": {"x":303,"y":749,"w":41,"h":45},
"frame": {"x":449,"y":862,"w":41,"h":45},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":29,"y":0,"w":41,"h":45},
@ -1250,7 +1266,7 @@
},
"sprites/wires/network_conflict.png":
{
"frame": {"x":303,"y":798,"w":32,"h":30},
"frame": {"x":622,"y":899,"w":32,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":1,"w":32,"h":30},
@ -1274,7 +1290,7 @@
},
"sprites/wires/sets/color_cross.png":
{
"frame": {"x":521,"y":899,"w":96,"h":96},
"frame": {"x":722,"y":990,"w":96,"h":96},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":96,"h":96},
@ -1290,7 +1306,7 @@
},
"sprites/wires/sets/color_split.png":
{
"frame": {"x":203,"y":932,"w":96,"h":54},
"frame": {"x":103,"y":925,"w":96,"h":54},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":42,"w":96,"h":54},
@ -1306,7 +1322,7 @@
},
"sprites/wires/sets/conflict_cross.png":
{
"frame": {"x":621,"y":923,"w":96,"h":96},
"frame": {"x":822,"y":994,"w":96,"h":96},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":96,"h":96},
@ -1314,7 +1330,7 @@
},
"sprites/wires/sets/conflict_forward.png":
{
"frame": {"x":303,"y":832,"w":12,"h":96},
"frame": {"x":506,"y":803,"w":12,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":42,"y":0,"w":12,"h":96},
@ -1322,7 +1338,7 @@
},
"sprites/wires/sets/conflict_split.png":
{
"frame": {"x":103,"y":933,"w":96,"h":54},
"frame": {"x":203,"y":953,"w":96,"h":54},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":42,"w":96,"h":54},
@ -1338,7 +1354,7 @@
},
"sprites/wires/sets/regular_cross.png":
{
"frame": {"x":339,"y":803,"w":96,"h":96},
"frame": {"x":831,"y":894,"w":96,"h":96},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":96,"h":96},
@ -1354,7 +1370,7 @@
},
"sprites/wires/sets/regular_split.png":
{
"frame": {"x":203,"y":874,"w":96,"h":54},
"frame": {"x":103,"y":867,"w":96,"h":54},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":42,"w":96,"h":54},
@ -1370,7 +1386,7 @@
},
"sprites/wires/sets/shape_cross.png":
{
"frame": {"x":721,"y":990,"w":96,"h":96},
"frame": {"x":922,"y":1033,"w":96,"h":96},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":96,"h":96},
@ -1378,7 +1394,7 @@
},
"sprites/wires/sets/shape_forward.png":
{
"frame": {"x":319,"y":832,"w":12,"h":96},
"frame": {"x":494,"y":903,"w":12,"h":96},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":42,"y":0,"w":12,"h":96},
@ -1386,7 +1402,7 @@
},
"sprites/wires/sets/shape_split.png":
{
"frame": {"x":3,"y":960,"w":96,"h":54},
"frame": {"x":303,"y":989,"w":96,"h":54},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":42,"w":96,"h":54},
@ -1402,7 +1418,7 @@
},
"sprites/wires/wires_preview.png":
{
"frame": {"x":693,"y":887,"w":32,"h":32},
"frame": {"x":695,"y":887,"w":32,"h":32},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":32,"h":32},
@ -1415,6 +1431,6 @@
"format": "RGBA8888",
"size": {"w":1024,"h":2048},
"scale": "0.5",
"smartupdate": "$TexturePacker:SmartUpdate:65dccccf359b3f3582914eac20260366:f9eee0054558f8bf77da34f281176a03:908b89f5ca8ff73e331a35a3b14d0604$"
"smartupdate": "$TexturePacker:SmartUpdate:1923b9c910205fb09957b67f92de02b9:0d87df06f18965307bf9d18b414f603d:908b89f5ca8ff73e331a35a3b14d0604$"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 636 KiB

After

Width:  |  Height:  |  Size: 653 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

File diff suppressed because it is too large Load Diff

View File

@ -1,86 +1,91 @@
import { enumDirection, Vector } from "../../core/vector";
import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
import { Entity } from "../entity";
import { MetaBuilding } from "../meta_building";
import { GameRoot } from "../root";
import { LeverComponent } from "../components/lever";
import { ItemAcceptorComponent } from "../components/item_acceptor";
import { ItemEjectorComponent } from "../components/item_ejector";
import { ItemProcessorComponent, enumItemProcessorTypes } from "../components/item_processor";
export class MetaFilterBuilding extends MetaBuilding {
constructor() {
super("filter");
}
getSilhouetteColor() {
return "#c45c2e";
}
/**
* @param {GameRoot} root
*/
getIsUnlocked(root) {
// @todo
return true;
}
getDimensions() {
return new Vector(2, 1);
}
getShowWiresLayerPreview() {
return true;
}
/**
* Creates the entity at the given location
* @param {Entity} entity
*/
setupEntityComponents(entity) {
entity.addComponent(
new WiredPinsComponent({
slots: [
{
pos: new Vector(0, 0),
direction: enumDirection.left,
type: enumPinSlotType.logicalAcceptor,
},
],
})
);
entity.addComponent(
new ItemAcceptorComponent({
slots: [
{
pos: new Vector(0, 0),
directions: [enumDirection.bottom],
},
],
})
);
entity.addComponent(
new ItemEjectorComponent({
slots: [
{
pos: new Vector(0, 0),
direction: enumDirection.top,
},
{
pos: new Vector(1, 0),
direction: enumDirection.right,
},
],
})
);
entity.addComponent(
new ItemProcessorComponent({
processorType: enumItemProcessorTypes.filter,
inputsPerCharge: 1,
})
);
}
}
import { enumDirection, Vector } from "../../core/vector";
import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
import { Entity } from "../entity";
import { MetaBuilding } from "../meta_building";
import { GameRoot } from "../root";
import { LeverComponent } from "../components/lever";
import { ItemAcceptorComponent } from "../components/item_acceptor";
import { ItemEjectorComponent } from "../components/item_ejector";
import {
ItemProcessorComponent,
enumItemProcessorTypes,
enumItemProcessorRequirements,
} from "../components/item_processor";
export class MetaFilterBuilding extends MetaBuilding {
constructor() {
super("filter");
}
getSilhouetteColor() {
return "#c45c2e";
}
/**
* @param {GameRoot} root
*/
getIsUnlocked(root) {
// @todo
return true;
}
getDimensions() {
return new Vector(2, 1);
}
getShowWiresLayerPreview() {
return true;
}
/**
* Creates the entity at the given location
* @param {Entity} entity
*/
setupEntityComponents(entity) {
entity.addComponent(
new WiredPinsComponent({
slots: [
{
pos: new Vector(0, 0),
direction: enumDirection.left,
type: enumPinSlotType.logicalAcceptor,
},
],
})
);
entity.addComponent(
new ItemAcceptorComponent({
slots: [
{
pos: new Vector(0, 0),
directions: [enumDirection.bottom],
},
],
})
);
entity.addComponent(
new ItemEjectorComponent({
slots: [
{
pos: new Vector(0, 0),
direction: enumDirection.top,
},
{
pos: new Vector(1, 0),
direction: enumDirection.right,
},
],
})
);
entity.addComponent(
new ItemProcessorComponent({
processorType: enumItemProcessorTypes.filter,
inputsPerCharge: 1,
processingRequirement: enumItemProcessorRequirements.filter,
})
);
}
}

View File

@ -3,7 +3,11 @@ import { enumDirection, Vector } from "../../core/vector";
import { T } from "../../translations";
import { ItemAcceptorComponent } from "../components/item_acceptor";
import { ItemEjectorComponent } from "../components/item_ejector";
import { enumItemProcessorTypes, ItemProcessorComponent, enumItemProcessorRequirements } from "../components/item_processor";
import {
enumItemProcessorTypes,
ItemProcessorComponent,
enumItemProcessorRequirements,
} from "../components/item_processor";
import { Entity } from "../entity";
import { defaultBuildingVariant, MetaBuilding } from "../meta_building";
import { GameRoot } from "../root";
@ -120,8 +124,10 @@ export class MetaPainterBuilding extends MetaBuilding {
switch (variant) {
case defaultBuildingVariant:
case enumPainterVariants.mirrored: {
// REGULAR PAINTER
if (entity.components.WiredPins) {
entity.removeComponent(WiredPinsComponent)
entity.removeComponent(WiredPinsComponent);
}
entity.components.ItemAcceptor.setSlots([
@ -139,18 +145,22 @@ export class MetaPainterBuilding extends MetaBuilding {
},
]);
entity.components.ItemEjector.setSlots([
{ pos: new Vector(1, 0), direction: enumDirection.right },
]);
entity.components.ItemProcessor.type = enumItemProcessorTypes.painter;
entity.components.ItemProcessor.processingRequirement = null;
entity.components.ItemProcessor.inputsPerCharge = 2;
entity.components.ItemEjector.setSlots([
{ pos: new Vector(1, 0), direction: enumDirection.right },
]);
break;
}
case enumPainterVariants.double: {
// DOUBLE PAINTER
if (entity.components.WiredPins) {
entity.removeComponent(WiredPinsComponent)
entity.removeComponent(WiredPinsComponent);
}
entity.components.ItemAcceptor.setSlots([
@ -171,43 +181,46 @@ export class MetaPainterBuilding extends MetaBuilding {
},
]);
entity.components.ItemProcessor.type = enumItemProcessorTypes.painterDouble;
entity.components.ItemProcessor.processingRequirement = null;
entity.components.ItemProcessor.inputsPerCharge = 3;
entity.components.ItemEjector.setSlots([
{ pos: new Vector(1, 0), direction: enumDirection.right },
]);
entity.components.ItemProcessor.type = enumItemProcessorTypes.painterDouble;
entity.components.ItemProcessor.processingRequirement = null;
entity.components.ItemProcessor.inputsPerCharge = 3;
break;
}
case enumPainterVariants.quad: {
// QUAD PAINTER
if (!entity.components.WiredPins) {
entity.addComponent(new WiredPinsComponent({
slots: [
{
pos: new Vector(0, 0),
direction: enumDirection.bottom,
type: enumPinSlotType.logicalAcceptor
},
{
pos: new Vector(1, 0),
direction: enumDirection.bottom,
type: enumPinSlotType.logicalAcceptor
},
{
pos: new Vector(2, 0),
direction: enumDirection.bottom,
type: enumPinSlotType.logicalAcceptor
},
{
pos: new Vector(3, 0),
direction: enumDirection.bottom,
type: enumPinSlotType.logicalAcceptor
},
]
}));
entity.addComponent(new WiredPinsComponent({ slots: [] }));
}
entity.components.WiredPins.setSlots([
{
pos: new Vector(0, 0),
direction: enumDirection.bottom,
type: enumPinSlotType.logicalAcceptor,
},
{
pos: new Vector(1, 0),
direction: enumDirection.bottom,
type: enumPinSlotType.logicalAcceptor,
},
{
pos: new Vector(2, 0),
direction: enumDirection.bottom,
type: enumPinSlotType.logicalAcceptor,
},
{
pos: new Vector(3, 0),
direction: enumDirection.bottom,
type: enumPinSlotType.logicalAcceptor,
},
]);
entity.components.ItemAcceptor.setSlots([
{
pos: new Vector(0, 0),
@ -236,15 +249,18 @@ export class MetaPainterBuilding extends MetaBuilding {
},
]);
entity.components.ItemProcessor.type = enumItemProcessorTypes.painterQuad;
entity.components.ItemProcessor.processingRequirement = enumItemProcessorRequirements.painterQuad;
entity.components.ItemProcessor.inputsPerCharge = 5;
entity.components.ItemEjector.setSlots([
{ pos: new Vector(0, 0), direction: enumDirection.top },
]);
entity.components.ItemProcessor.type = enumItemProcessorTypes.painterQuad;
entity.components.ItemProcessor.processingRequirement =
enumItemProcessorRequirements.painterQuad;
entity.components.ItemProcessor.inputsPerCharge = 5;
break;
}
default:
assertAlways(false, "Unknown painter variant: " + variant);
}

View File

@ -43,7 +43,7 @@ export function initComponentRegistry() {
assert(
// @ts-ignore
require.context("./components", false, /.*\.js/i).keys().length ===
gComponentRegistry.getNumEntries(),
gComponentRegistry.getNumEntries(),
"Not all components are registered"
);

View File

@ -24,7 +24,8 @@ export const enumItemProcessorTypes = {
/** @enum {string} */
export const enumItemProcessorRequirements = {
painterQuad: "painterQuad"
painterQuad: "painterQuad",
filter: "filter",
};
export class ItemProcessorComponent extends Component {
@ -71,7 +72,7 @@ export class ItemProcessorComponent extends Component {
constructor({
processorType = enumItemProcessorTypes.splitter,
processingRequirement = null,
inputsPerCharge = 1
inputsPerCharge = 1,
}) {
super();

View File

@ -1,165 +1,171 @@
/* typehints:start */
import { GameRoot } from "./root";
/* typehints:end */
import { createLogger } from "../core/logging";
import { BeltSystem } from "./systems/belt";
import { ItemEjectorSystem } from "./systems/item_ejector";
import { MapResourcesSystem } from "./systems/map_resources";
import { MinerSystem } from "./systems/miner";
import { ItemProcessorSystem } from "./systems/item_processor";
import { UndergroundBeltSystem } from "./systems/underground_belt";
import { HubSystem } from "./systems/hub";
import { StaticMapEntitySystem } from "./systems/static_map_entity";
import { ItemAcceptorSystem } from "./systems/item_acceptor";
import { StorageSystem } from "./systems/storage";
import { WiredPinsSystem } from "./systems/wired_pins";
import { BeltUnderlaysSystem } from "./systems/belt_underlays";
import { WireSystem } from "./systems/wire";
import { ConstantSignalSystem } from "./systems/constant_signal";
import { LogicGateSystem } from "./systems/logic_gate";
import { LeverSystem } from "./systems/lever";
import { DisplaySystem } from "./systems/display";
const logger = createLogger("game_system_manager");
export class GameSystemManager {
/**
*
* @param {GameRoot} root
*/
constructor(root) {
this.root = root;
this.systems = {
/* typehints:start */
/** @type {BeltSystem} */
belt: null,
/** @type {ItemEjectorSystem} */
itemEjector: null,
/** @type {MapResourcesSystem} */
mapResources: null,
/** @type {MinerSystem} */
miner: null,
/** @type {ItemProcessorSystem} */
itemProcessor: null,
/** @type {UndergroundBeltSystem} */
undergroundBelt: null,
/** @type {HubSystem} */
hub: null,
/** @type {StaticMapEntitySystem} */
staticMapEntities: null,
/** @type {ItemAcceptorSystem} */
itemAcceptor: null,
/** @type {StorageSystem} */
storage: null,
/** @type {WiredPinsSystem} */
wiredPins: null,
/** @type {BeltUnderlaysSystem} */
beltUnderlays: null,
/** @type {WireSystem} */
wire: null,
/** @type {ConstantSignalSystem} */
constantSignal: null,
/** @type {LogicGateSystem} */
logicGate: null,
/** @type {LeverSystem} */
lever: null,
/** @type {DisplaySystem} */
display: null,
/* typehints:end */
};
this.systemUpdateOrder = [];
this.internalInitSystems();
}
/**
* Initializes all systems
*/
internalInitSystems() {
const add = (id, systemClass) => {
this.systems[id] = new systemClass(this.root);
this.systemUpdateOrder.push(id);
};
// Order is important!
add("belt", BeltSystem);
add("undergroundBelt", UndergroundBeltSystem);
add("miner", MinerSystem);
add("storage", StorageSystem);
add("itemProcessor", ItemProcessorSystem);
add("itemEjector", ItemEjectorSystem);
add("mapResources", MapResourcesSystem);
add("hub", HubSystem);
add("staticMapEntities", StaticMapEntitySystem);
add("wiredPins", WiredPinsSystem);
add("beltUnderlays", BeltUnderlaysSystem);
add("constantSignal", ConstantSignalSystem);
// IMPORTANT: Must be after belt system since belt system can change the
// orientation of an entity after it is placed -> the item acceptor cache
// then would be invalid
add("itemAcceptor", ItemAcceptorSystem);
// WIRES section
add("lever", LeverSystem);
// IMPORTANT: We have 2 phases: In phase 1 we compute the output values of all gates,
// processors etc. In phase 2 we propagate it through the wires network
add("logicGate", LogicGateSystem);
// Wires must be after all gate, signal etc logic!
add("wire", WireSystem);
add("display", DisplaySystem);
logger.log("📦 There are", this.systemUpdateOrder.length, "game systems");
}
/**
* Updates all systems
*/
update() {
for (let i = 0; i < this.systemUpdateOrder.length; ++i) {
const system = this.systems[this.systemUpdateOrder[i]];
system.update();
}
}
refreshCaches() {
for (let i = 0; i < this.systemUpdateOrder.length; ++i) {
const system = this.systems[this.systemUpdateOrder[i]];
system.refreshCaches();
}
}
}
/* typehints:start */
import { GameRoot } from "./root";
/* typehints:end */
import { createLogger } from "../core/logging";
import { BeltSystem } from "./systems/belt";
import { ItemEjectorSystem } from "./systems/item_ejector";
import { MapResourcesSystem } from "./systems/map_resources";
import { MinerSystem } from "./systems/miner";
import { ItemProcessorSystem } from "./systems/item_processor";
import { UndergroundBeltSystem } from "./systems/underground_belt";
import { HubSystem } from "./systems/hub";
import { StaticMapEntitySystem } from "./systems/static_map_entity";
import { ItemAcceptorSystem } from "./systems/item_acceptor";
import { StorageSystem } from "./systems/storage";
import { WiredPinsSystem } from "./systems/wired_pins";
import { BeltUnderlaysSystem } from "./systems/belt_underlays";
import { WireSystem } from "./systems/wire";
import { ConstantSignalSystem } from "./systems/constant_signal";
import { LogicGateSystem } from "./systems/logic_gate";
import { LeverSystem } from "./systems/lever";
import { DisplaySystem } from "./systems/display";
import { ItemProcessorOverlaysSystem } from "./systems/item_processor_overlays";
const logger = createLogger("game_system_manager");
export class GameSystemManager {
/**
*
* @param {GameRoot} root
*/
constructor(root) {
this.root = root;
this.systems = {
/* typehints:start */
/** @type {BeltSystem} */
belt: null,
/** @type {ItemEjectorSystem} */
itemEjector: null,
/** @type {MapResourcesSystem} */
mapResources: null,
/** @type {MinerSystem} */
miner: null,
/** @type {ItemProcessorSystem} */
itemProcessor: null,
/** @type {UndergroundBeltSystem} */
undergroundBelt: null,
/** @type {HubSystem} */
hub: null,
/** @type {StaticMapEntitySystem} */
staticMapEntities: null,
/** @type {ItemAcceptorSystem} */
itemAcceptor: null,
/** @type {StorageSystem} */
storage: null,
/** @type {WiredPinsSystem} */
wiredPins: null,
/** @type {BeltUnderlaysSystem} */
beltUnderlays: null,
/** @type {WireSystem} */
wire: null,
/** @type {ConstantSignalSystem} */
constantSignal: null,
/** @type {LogicGateSystem} */
logicGate: null,
/** @type {LeverSystem} */
lever: null,
/** @type {DisplaySystem} */
display: null,
/** @type {ItemProcessorOverlaysSystem} */
itemProcessorOverlays: null,
/* typehints:end */
};
this.systemUpdateOrder = [];
this.internalInitSystems();
}
/**
* Initializes all systems
*/
internalInitSystems() {
const add = (id, systemClass) => {
this.systems[id] = new systemClass(this.root);
this.systemUpdateOrder.push(id);
};
// Order is important!
add("belt", BeltSystem);
add("undergroundBelt", UndergroundBeltSystem);
add("miner", MinerSystem);
add("storage", StorageSystem);
add("itemProcessor", ItemProcessorSystem);
add("itemEjector", ItemEjectorSystem);
add("mapResources", MapResourcesSystem);
add("hub", HubSystem);
add("staticMapEntities", StaticMapEntitySystem);
add("wiredPins", WiredPinsSystem);
add("beltUnderlays", BeltUnderlaysSystem);
add("constantSignal", ConstantSignalSystem);
// IMPORTANT: Must be after belt system since belt system can change the
// orientation of an entity after it is placed -> the item acceptor cache
// then would be invalid
add("itemAcceptor", ItemAcceptorSystem);
// WIRES section
add("lever", LeverSystem);
// IMPORTANT: We have 2 phases: In phase 1 we compute the output values of all gates,
// processors etc. In phase 2 we propagate it through the wires network
add("logicGate", LogicGateSystem);
// Wires must be after all gate, signal etc logic!
add("wire", WireSystem);
add("display", DisplaySystem);
add("itemProcessorOverlays", ItemProcessorOverlaysSystem);
logger.log("📦 There are", this.systemUpdateOrder.length, "game systems");
}
/**
* Updates all systems
*/
update() {
for (let i = 0; i < this.systemUpdateOrder.length; ++i) {
const system = this.systems[this.systemUpdateOrder[i]];
system.update();
}
}
refreshCaches() {
for (let i = 0; i < this.systemUpdateOrder.length; ++i) {
const system = this.systems[this.systemUpdateOrder[i]];
system.refreshCaches();
}
}
}

View File

@ -1,62 +1,70 @@
import { DrawParameters } from "../../core/draw_parameters";
import { Loader } from "../../core/loader";
import { types } from "../../savegame/serialization";
import { BaseItem } from "../base_item";
import { globalConfig } from "../../core/config";
export class BooleanItem extends BaseItem {
static getId() {
return "boolean_item";
}
static getSchema() {
return types.uint;
}
serialize() {
return this.value;
}
deserialize(data) {
this.value = data;
}
/** @returns {"boolean"} **/
getItemType() {
return "boolean";
}
/**
* @param {number} value
*/
constructor(value) {
super();
this.value = value ? 1 : 0;
}
/**
* @param {BaseItem} other
*/
equalsImpl(other) {
return this.value === /** @type {BooleanItem} */ (other).value;
}
/**
* @param {number} x
* @param {number} y
* @param {number} diameter
* @param {DrawParameters} parameters
*/
drawItemCenteredImpl(x, y, parameters, diameter = globalConfig.defaultItemDiameter) {
let sprite;
if (this.value) {
sprite = Loader.getSprite("sprites/wires/boolean_true.png");
} else {
sprite = Loader.getSprite("sprites/wires/boolean_false.png");
}
sprite.drawCachedCentered(parameters, x, y, diameter);
}
}
export const BOOL_FALSE_SINGLETON = new BooleanItem(0);
export const BOOL_TRUE_SINGLETON = new BooleanItem(1);
import { DrawParameters } from "../../core/draw_parameters";
import { Loader } from "../../core/loader";
import { types } from "../../savegame/serialization";
import { BaseItem } from "../base_item";
import { globalConfig } from "../../core/config";
export class BooleanItem extends BaseItem {
static getId() {
return "boolean_item";
}
static getSchema() {
return types.uint;
}
serialize() {
return this.value;
}
deserialize(data) {
this.value = data;
}
/** @returns {"boolean"} **/
getItemType() {
return "boolean";
}
/**
* @param {number} value
*/
constructor(value) {
super();
this.value = value ? 1 : 0;
}
/**
* @param {BaseItem} other
*/
equalsImpl(other) {
return this.value === /** @type {BooleanItem} */ (other).value;
}
/**
* @param {number} x
* @param {number} y
* @param {number} diameter
* @param {DrawParameters} parameters
*/
drawItemCenteredImpl(x, y, parameters, diameter = globalConfig.defaultItemDiameter) {
let sprite;
if (this.value) {
sprite = Loader.getSprite("sprites/wires/boolean_true.png");
} else {
sprite = Loader.getSprite("sprites/wires/boolean_false.png");
}
sprite.drawCachedCentered(parameters, x, y, diameter);
}
}
export const BOOL_FALSE_SINGLETON = new BooleanItem(0);
export const BOOL_TRUE_SINGLETON = new BooleanItem(1);
/**
*
* @param {BaseItem} item
*/
export function isTrueItem(item) {
return item && item.getItemType() === "boolean" && /** @type {BooleanItem} */ (item).value;
}

View File

@ -69,6 +69,7 @@ export class MapChunkView extends MapChunk {
systems.lever.drawChunk(parameters, this);
systems.display.drawChunk(parameters, this);
systems.storage.drawChunk(parameters, this);
systems.itemProcessorOverlays.drawChunk(parameters, this);
}
/**

View File

@ -1,99 +1,97 @@
import { globalConfig } from "../../core/config";
import { Loader } from "../../core/loader";
import { BaseItem } from "../base_item";
import { enumColors } from "../colors";
import { DisplayComponent } from "../components/display";
import { GameSystemWithFilter } from "../game_system_with_filter";
import { ColorItem, COLOR_ITEM_SINGLETONS } from "../items/color_item";
import { MapChunkView } from "../map_chunk_view";
import { BooleanItem } from "../items/boolean_item";
export class DisplaySystem extends GameSystemWithFilter {
constructor(root) {
super(root, [DisplayComponent]);
/** @type {Object<string, import("../../core/draw_utils").AtlasSprite>} */
this.displaySprites = {};
for (const colorId in enumColors) {
if (colorId === enumColors.uncolored) {
continue;
}
this.displaySprites[colorId] = Loader.getSprite("sprites/wires/display/" + colorId + ".png");
}
}
/**
* Returns the color / value a display should show
* @param {BaseItem} value
* @returns {BaseItem}
*/
getDisplayItem(value) {
if (!value) {
return null;
}
switch (value.getItemType()) {
case "boolean": {
return /** @type {BooleanItem} */ (value).value
? COLOR_ITEM_SINGLETONS[enumColors.white]
: null;
}
case "color": {
const item = /**@type {ColorItem} */ (value);
return item.color === enumColors.uncolored ? null : item;
}
case "shape": {
return value;
}
default:
assertAlways(false, "Unknown item type: " + value.getItemType());
}
}
/**
* Draws a given chunk
* @param {import("../../core/draw_utils").DrawParameters} parameters
* @param {MapChunkView} chunk
*/
drawChunk(parameters, chunk) {
const contents = chunk.containedEntitiesByLayer.regular;
for (let i = 0; i < contents.length; ++i) {
const entity = contents[i];
if (entity && entity.components.Display) {
const pinsComp = entity.components.WiredPins;
const network = pinsComp.slots[0].linkedNetwork;
if (!network || !network.currentValue) {
continue;
}
const value = this.getDisplayItem(network.currentValue);
if (!value) {
continue;
}
const origin = entity.components.StaticMapEntity.origin;
if (value.getItemType() === "color") {
this.displaySprites[/** @type {ColorItem} */ (value).color].drawCachedCentered(
parameters,
(origin.x + 0.5) * globalConfig.tileSize,
(origin.y + 0.5) * globalConfig.tileSize,
globalConfig.tileSize
);
} else if (value.getItemType() === "shape") {
value.drawItemCenteredClipped(
(origin.x + 0.5) * globalConfig.tileSize,
(origin.y + 0.5) * globalConfig.tileSize,
parameters,
30
);
}
}
}
}
}
import { globalConfig } from "../../core/config";
import { Loader } from "../../core/loader";
import { BaseItem } from "../base_item";
import { enumColors } from "../colors";
import { DisplayComponent } from "../components/display";
import { GameSystemWithFilter } from "../game_system_with_filter";
import { isTrueItem } from "../items/boolean_item";
import { ColorItem, COLOR_ITEM_SINGLETONS } from "../items/color_item";
import { MapChunkView } from "../map_chunk_view";
export class DisplaySystem extends GameSystemWithFilter {
constructor(root) {
super(root, [DisplayComponent]);
/** @type {Object<string, import("../../core/draw_utils").AtlasSprite>} */
this.displaySprites = {};
for (const colorId in enumColors) {
if (colorId === enumColors.uncolored) {
continue;
}
this.displaySprites[colorId] = Loader.getSprite("sprites/wires/display/" + colorId + ".png");
}
}
/**
* Returns the color / value a display should show
* @param {BaseItem} value
* @returns {BaseItem}
*/
getDisplayItem(value) {
if (!value) {
return null;
}
switch (value.getItemType()) {
case "boolean": {
return isTrueItem(value) ? COLOR_ITEM_SINGLETONS[enumColors.white] : null;
}
case "color": {
const item = /**@type {ColorItem} */ (value);
return item.color === enumColors.uncolored ? null : item;
}
case "shape": {
return value;
}
default:
assertAlways(false, "Unknown item type: " + value.getItemType());
}
}
/**
* Draws a given chunk
* @param {import("../../core/draw_utils").DrawParameters} parameters
* @param {MapChunkView} chunk
*/
drawChunk(parameters, chunk) {
const contents = chunk.containedEntitiesByLayer.regular;
for (let i = 0; i < contents.length; ++i) {
const entity = contents[i];
if (entity && entity.components.Display) {
const pinsComp = entity.components.WiredPins;
const network = pinsComp.slots[0].linkedNetwork;
if (!network || !network.currentValue) {
continue;
}
const value = this.getDisplayItem(network.currentValue);
if (!value) {
continue;
}
const origin = entity.components.StaticMapEntity.origin;
if (value.getItemType() === "color") {
this.displaySprites[/** @type {ColorItem} */ (value).color].drawCachedCentered(
parameters,
(origin.x + 0.5) * globalConfig.tileSize,
(origin.y + 0.5) * globalConfig.tileSize,
globalConfig.tileSize
);
} else if (value.getItemType() === "shape") {
value.drawItemCenteredClipped(
(origin.x + 0.5) * globalConfig.tileSize,
(origin.y + 0.5) * globalConfig.tileSize,
parameters,
30
);
}
}
}
}
}

View File

@ -1,388 +1,381 @@
import { globalConfig } from "../../core/config";
import { DrawParameters } from "../../core/draw_parameters";
import { createLogger } from "../../core/logging";
import { Rectangle } from "../../core/rectangle";
import { enumDirection, enumDirectionToVector, Vector } from "../../core/vector";
import { BaseItem } from "../base_item";
import { ItemEjectorComponent } from "../components/item_ejector";
import { Entity } from "../entity";
import { GameSystemWithFilter } from "../game_system_with_filter";
import { enumItemProcessorTypes } from "../components/item_processor";
import { MapChunkView } from "../map_chunk_view";
const logger = createLogger("systems/ejector");
export class ItemEjectorSystem extends GameSystemWithFilter {
constructor(root) {
super(root, [ItemEjectorComponent]);
this.root.signals.entityAdded.add(this.checkForCacheInvalidation, this);
this.root.signals.entityDestroyed.add(this.checkForCacheInvalidation, this);
this.root.signals.postLoadHook.add(this.recomputeCache, this);
/**
* @type {Rectangle}
*/
this.areaToRecompute = null;
}
/**
*
* @param {Entity} entity
*/
checkForCacheInvalidation(entity) {
if (!this.root.gameInitialized) {
return;
}
if (!entity.components.StaticMapEntity) {
return;
}
// Optimize for the common case: adding or removing one building at a time. Clicking
// and dragging can cause up to 4 add/remove signals.
const staticComp = entity.components.StaticMapEntity;
const bounds = staticComp.getTileSpaceBounds();
const expandedBounds = bounds.expandedInAllDirections(2);
if (this.areaToRecompute) {
this.areaToRecompute = this.areaToRecompute.getUnion(expandedBounds);
} else {
this.areaToRecompute = expandedBounds;
}
}
/**
* Precomputes the cache, which makes up for a huge performance improvement
*/
recomputeCache() {
if (this.areaToRecompute) {
logger.log("Recomputing cache using rectangle");
if (G_IS_DEV && globalConfig.debug.renderChanges) {
this.root.hud.parts.changesDebugger.renderChange(
"ejector-area",
this.areaToRecompute,
"#fe50a6"
);
}
this.recomputeAreaCache();
this.areaToRecompute = null;
} else {
logger.log("Full cache recompute");
if (G_IS_DEV && globalConfig.debug.renderChanges) {
this.root.hud.parts.changesDebugger.renderChange(
"ejector-full",
new Rectangle(-1000, -1000, 2000, 2000),
"#fe50a6"
);
}
// Try to find acceptors for every ejector
for (let i = 0; i < this.allEntities.length; ++i) {
const entity = this.allEntities[i];
this.recomputeSingleEntityCache(entity);
}
}
}
/**
* Recomputes the cache in the given area
*/
recomputeAreaCache() {
const area = this.areaToRecompute;
let entryCount = 0;
logger.log("Recomputing area:", area.x, area.y, "/", area.w, area.h);
// Store the entities we already recomputed, so we don't do work twice
const recomputedEntities = new Set();
for (let x = area.x; x < area.right(); ++x) {
for (let y = area.y; y < area.bottom(); ++y) {
const entities = this.root.map.getLayersContentsMultipleXY(x, y);
for (let i = 0; i < entities.length; ++i) {
const entity = entities[i];
// Recompute the entity in case its relevant for this system and it
// hasn't already been computed
if (!recomputedEntities.has(entity.uid) && entity.components.ItemEjector) {
recomputedEntities.add(entity.uid);
this.recomputeSingleEntityCache(entity);
}
}
}
}
return entryCount;
}
/**
* @param {Entity} entity
*/
recomputeSingleEntityCache(entity) {
const ejectorComp = entity.components.ItemEjector;
const staticComp = entity.components.StaticMapEntity;
for (let slotIndex = 0; slotIndex < ejectorComp.slots.length; ++slotIndex) {
const ejectorSlot = ejectorComp.slots[slotIndex];
// Clear the old cache.
ejectorSlot.cachedDestSlot = null;
ejectorSlot.cachedTargetEntity = null;
ejectorSlot.cachedBeltPath = null;
// Figure out where and into which direction we eject items
const ejectSlotWsTile = staticComp.localTileToWorld(ejectorSlot.pos);
const ejectSlotWsDirection = staticComp.localDirectionToWorld(ejectorSlot.direction);
const ejectSlotWsDirectionVector = enumDirectionToVector[ejectSlotWsDirection];
const ejectSlotTargetWsTile = ejectSlotWsTile.add(ejectSlotWsDirectionVector);
// Try to find the given acceptor component to take the item
// Since there can be cross layer dependencies, check on all layers
const targetEntities = this.root.map.getLayersContentsMultipleXY(
ejectSlotTargetWsTile.x,
ejectSlotTargetWsTile.y
);
for (let i = 0; i < targetEntities.length; ++i) {
const targetEntity = targetEntities[i];
const targetStaticComp = targetEntity.components.StaticMapEntity;
const targetBeltComp = targetEntity.components.Belt;
// Check for belts (special case)
if (targetBeltComp) {
const beltAcceptingDirection = targetStaticComp.localDirectionToWorld(enumDirection.top);
if (ejectSlotWsDirection === beltAcceptingDirection) {
ejectorSlot.cachedTargetEntity = targetEntity;
ejectorSlot.cachedBeltPath = targetBeltComp.assignedPath;
break;
}
}
// Check for item acceptors
const targetAcceptorComp = targetEntity.components.ItemAcceptor;
if (!targetAcceptorComp) {
// Entity doesn't accept items
continue;
}
const matchingSlot = targetAcceptorComp.findMatchingSlot(
targetStaticComp.worldToLocalTile(ejectSlotTargetWsTile),
targetStaticComp.worldDirectionToLocal(ejectSlotWsDirection)
);
if (!matchingSlot) {
// No matching slot found
continue;
}
// A slot can always be connected to one other slot only
ejectorSlot.cachedTargetEntity = targetEntity;
ejectorSlot.cachedDestSlot = matchingSlot;
break;
}
}
}
update() {
if (this.areaToRecompute) {
this.recomputeCache();
}
// Precompute effective belt speed
let progressGrowth = 2 * this.root.dynamicTickrate.deltaSeconds;
if (G_IS_DEV && globalConfig.debug.instantBelts) {
progressGrowth = 1;
}
// Go over all cache entries
for (let i = 0; i < this.allEntities.length; ++i) {
const sourceEntity = this.allEntities[i];
const sourceEjectorComp = sourceEntity.components.ItemEjector;
if (!sourceEjectorComp.enabled) {
continue;
}
const slots = sourceEjectorComp.slots;
for (let j = 0; j < slots.length; ++j) {
const sourceSlot = slots[j];
const item = sourceSlot.item;
if (!item) {
// No item available to be ejected
continue;
}
const targetEntity = sourceSlot.cachedTargetEntity;
// Advance items on the slot
sourceSlot.progress = Math.min(
1,
sourceSlot.progress +
progressGrowth *
this.root.hubGoals.getBeltBaseSpeed() *
globalConfig.itemSpacingOnBelts
);
// Check if we are still in the process of ejecting, can't proceed then
if (sourceSlot.progress < 1.0) {
continue;
}
// Check if we are ejecting to a belt path
const destPath = sourceSlot.cachedBeltPath;
if (destPath) {
// Try passing the item over
if (destPath.tryAcceptItem(item)) {
sourceSlot.item = null;
}
// Always stop here, since there can *either* be a belt path *or*
// a slot
continue;
}
// Check if the target acceptor can actually accept this item
const destSlot = sourceSlot.cachedDestSlot;
if (destSlot) {
const targetAcceptorComp = targetEntity.components.ItemAcceptor;
if (!targetAcceptorComp.canAcceptItem(destSlot.index, item)) {
continue;
}
// Try to hand over the item
if (this.tryPassOverItem(item, targetEntity, destSlot.index)) {
// Handover successful, clear slot
targetAcceptorComp.onItemAccepted(destSlot.index, destSlot.acceptedDirection, item);
sourceSlot.item = null;
continue;
}
}
}
}
}
/**
*
* @param {BaseItem} item
* @param {Entity} receiver
* @param {number} slotIndex
*/
tryPassOverItem(item, receiver, slotIndex) {
// Try figuring out how what to do with the item
// TODO: Kinda hacky. How to solve this properly? Don't want to go through inheritance hell.
// Also its just a few cases (hope it stays like this .. :x).
const beltComp = receiver.components.Belt;
if (beltComp) {
const path = beltComp.assignedPath;
assert(path, "belt has no path");
if (path.tryAcceptItem(item)) {
return true;
}
// Belt can have nothing else
return false;
}
const itemProcessorComp = receiver.components.ItemProcessor;
if (itemProcessorComp) {
// @todo HACK
// Check if there are pins, and if so if they are connected
if (itemProcessorComp.type === enumItemProcessorTypes.filter) {
const pinsComp = receiver.components.WiredPins;
if (pinsComp && pinsComp.slots.length === 1) {
const network = pinsComp.slots[0].linkedNetwork;
if (!network || !network.currentValue) {
return false;
}
}
}
// Its an item processor ..
if (itemProcessorComp.tryTakeItem(item, slotIndex)) {
return true;
}
// Item processor can have nothing else
return false;
}
const undergroundBeltComp = receiver.components.UndergroundBelt;
if (undergroundBeltComp) {
// Its an underground belt. yay.
if (
undergroundBeltComp.tryAcceptExternalItem(
item,
this.root.hubGoals.getUndergroundBeltBaseSpeed()
)
) {
return true;
}
// Underground belt can have nothing else
return false;
}
const storageComp = receiver.components.Storage;
if (storageComp) {
// It's a storage
if (storageComp.canAcceptItem(item)) {
storageComp.takeItem(item);
return true;
}
// Storage can't have anything else
return false;
}
return false;
}
/**
* @param {DrawParameters} parameters
* @param {MapChunkView} chunk
*/
drawChunk(parameters, chunk) {
const contents = chunk.containedEntitiesByLayer.regular;
for (let i = 0; i < contents.length; ++i) {
const entity = contents[i];
const ejectorComp = entity.components.ItemEjector;
if (!ejectorComp) {
continue;
}
const staticComp = entity.components.StaticMapEntity;
for (let i = 0; i < ejectorComp.slots.length; ++i) {
const slot = ejectorComp.slots[i];
const ejectedItem = slot.item;
if (!ejectedItem) {
// No item
continue;
}
const realPosition = staticComp.localTileToWorld(slot.pos);
if (!chunk.tileSpaceRectangle.containsPoint(realPosition.x, realPosition.y)) {
// Not within this chunk
continue;
}
const realDirection = staticComp.localDirectionToWorld(slot.direction);
const realDirectionVector = enumDirectionToVector[realDirection];
const tileX = realPosition.x + 0.5 + realDirectionVector.x * 0.5 * slot.progress;
const tileY = realPosition.y + 0.5 + realDirectionVector.y * 0.5 * slot.progress;
const worldX = tileX * globalConfig.tileSize;
const worldY = tileY * globalConfig.tileSize;
ejectedItem.drawItemCenteredClipped(
worldX,
worldY,
parameters,
globalConfig.defaultItemDiameter
);
}
}
}
}
import { globalConfig } from "../../core/config";
import { DrawParameters } from "../../core/draw_parameters";
import { createLogger } from "../../core/logging";
import { Rectangle } from "../../core/rectangle";
import { enumDirection, enumDirectionToVector, Vector } from "../../core/vector";
import { BaseItem } from "../base_item";
import { ItemEjectorComponent } from "../components/item_ejector";
import { Entity } from "../entity";
import { GameSystemWithFilter } from "../game_system_with_filter";
import { enumItemProcessorTypes } from "../components/item_processor";
import { MapChunkView } from "../map_chunk_view";
const logger = createLogger("systems/ejector");
export class ItemEjectorSystem extends GameSystemWithFilter {
constructor(root) {
super(root, [ItemEjectorComponent]);
this.root.signals.entityAdded.add(this.checkForCacheInvalidation, this);
this.root.signals.entityDestroyed.add(this.checkForCacheInvalidation, this);
this.root.signals.postLoadHook.add(this.recomputeCache, this);
/**
* @type {Rectangle}
*/
this.areaToRecompute = null;
}
/**
*
* @param {Entity} entity
*/
checkForCacheInvalidation(entity) {
if (!this.root.gameInitialized) {
return;
}
if (!entity.components.StaticMapEntity) {
return;
}
// Optimize for the common case: adding or removing one building at a time. Clicking
// and dragging can cause up to 4 add/remove signals.
const staticComp = entity.components.StaticMapEntity;
const bounds = staticComp.getTileSpaceBounds();
const expandedBounds = bounds.expandedInAllDirections(2);
if (this.areaToRecompute) {
this.areaToRecompute = this.areaToRecompute.getUnion(expandedBounds);
} else {
this.areaToRecompute = expandedBounds;
}
}
/**
* Precomputes the cache, which makes up for a huge performance improvement
*/
recomputeCache() {
if (this.areaToRecompute) {
logger.log("Recomputing cache using rectangle");
if (G_IS_DEV && globalConfig.debug.renderChanges) {
this.root.hud.parts.changesDebugger.renderChange(
"ejector-area",
this.areaToRecompute,
"#fe50a6"
);
}
this.recomputeAreaCache();
this.areaToRecompute = null;
} else {
logger.log("Full cache recompute");
if (G_IS_DEV && globalConfig.debug.renderChanges) {
this.root.hud.parts.changesDebugger.renderChange(
"ejector-full",
new Rectangle(-1000, -1000, 2000, 2000),
"#fe50a6"
);
}
// Try to find acceptors for every ejector
for (let i = 0; i < this.allEntities.length; ++i) {
const entity = this.allEntities[i];
this.recomputeSingleEntityCache(entity);
}
}
}
/**
* Recomputes the cache in the given area
*/
recomputeAreaCache() {
const area = this.areaToRecompute;
let entryCount = 0;
logger.log("Recomputing area:", area.x, area.y, "/", area.w, area.h);
// Store the entities we already recomputed, so we don't do work twice
const recomputedEntities = new Set();
for (let x = area.x; x < area.right(); ++x) {
for (let y = area.y; y < area.bottom(); ++y) {
const entities = this.root.map.getLayersContentsMultipleXY(x, y);
for (let i = 0; i < entities.length; ++i) {
const entity = entities[i];
// Recompute the entity in case its relevant for this system and it
// hasn't already been computed
if (!recomputedEntities.has(entity.uid) && entity.components.ItemEjector) {
recomputedEntities.add(entity.uid);
this.recomputeSingleEntityCache(entity);
}
}
}
}
return entryCount;
}
/**
* @param {Entity} entity
*/
recomputeSingleEntityCache(entity) {
const ejectorComp = entity.components.ItemEjector;
const staticComp = entity.components.StaticMapEntity;
for (let slotIndex = 0; slotIndex < ejectorComp.slots.length; ++slotIndex) {
const ejectorSlot = ejectorComp.slots[slotIndex];
// Clear the old cache.
ejectorSlot.cachedDestSlot = null;
ejectorSlot.cachedTargetEntity = null;
ejectorSlot.cachedBeltPath = null;
// Figure out where and into which direction we eject items
const ejectSlotWsTile = staticComp.localTileToWorld(ejectorSlot.pos);
const ejectSlotWsDirection = staticComp.localDirectionToWorld(ejectorSlot.direction);
const ejectSlotWsDirectionVector = enumDirectionToVector[ejectSlotWsDirection];
const ejectSlotTargetWsTile = ejectSlotWsTile.add(ejectSlotWsDirectionVector);
// Try to find the given acceptor component to take the item
// Since there can be cross layer dependencies, check on all layers
const targetEntities = this.root.map.getLayersContentsMultipleXY(
ejectSlotTargetWsTile.x,
ejectSlotTargetWsTile.y
);
for (let i = 0; i < targetEntities.length; ++i) {
const targetEntity = targetEntities[i];
const targetStaticComp = targetEntity.components.StaticMapEntity;
const targetBeltComp = targetEntity.components.Belt;
// Check for belts (special case)
if (targetBeltComp) {
const beltAcceptingDirection = targetStaticComp.localDirectionToWorld(enumDirection.top);
if (ejectSlotWsDirection === beltAcceptingDirection) {
ejectorSlot.cachedTargetEntity = targetEntity;
ejectorSlot.cachedBeltPath = targetBeltComp.assignedPath;
break;
}
}
// Check for item acceptors
const targetAcceptorComp = targetEntity.components.ItemAcceptor;
if (!targetAcceptorComp) {
// Entity doesn't accept items
continue;
}
const matchingSlot = targetAcceptorComp.findMatchingSlot(
targetStaticComp.worldToLocalTile(ejectSlotTargetWsTile),
targetStaticComp.worldDirectionToLocal(ejectSlotWsDirection)
);
if (!matchingSlot) {
// No matching slot found
continue;
}
// A slot can always be connected to one other slot only
ejectorSlot.cachedTargetEntity = targetEntity;
ejectorSlot.cachedDestSlot = matchingSlot;
break;
}
}
}
update() {
if (this.areaToRecompute) {
this.recomputeCache();
}
// Precompute effective belt speed
let progressGrowth = 2 * this.root.dynamicTickrate.deltaSeconds;
if (G_IS_DEV && globalConfig.debug.instantBelts) {
progressGrowth = 1;
}
// Go over all cache entries
for (let i = 0; i < this.allEntities.length; ++i) {
const sourceEntity = this.allEntities[i];
const sourceEjectorComp = sourceEntity.components.ItemEjector;
if (!sourceEjectorComp.enabled) {
continue;
}
const slots = sourceEjectorComp.slots;
for (let j = 0; j < slots.length; ++j) {
const sourceSlot = slots[j];
const item = sourceSlot.item;
if (!item) {
// No item available to be ejected
continue;
}
const targetEntity = sourceSlot.cachedTargetEntity;
// Advance items on the slot
sourceSlot.progress = Math.min(
1,
sourceSlot.progress +
progressGrowth *
this.root.hubGoals.getBeltBaseSpeed() *
globalConfig.itemSpacingOnBelts
);
// Check if we are still in the process of ejecting, can't proceed then
if (sourceSlot.progress < 1.0) {
continue;
}
// Check if we are ejecting to a belt path
const destPath = sourceSlot.cachedBeltPath;
if (destPath) {
// Try passing the item over
if (destPath.tryAcceptItem(item)) {
sourceSlot.item = null;
}
// Always stop here, since there can *either* be a belt path *or*
// a slot
continue;
}
// Check if the target acceptor can actually accept this item
const destSlot = sourceSlot.cachedDestSlot;
if (destSlot) {
const targetAcceptorComp = targetEntity.components.ItemAcceptor;
if (!targetAcceptorComp.canAcceptItem(destSlot.index, item)) {
continue;
}
// Try to hand over the item
if (this.tryPassOverItem(item, targetEntity, destSlot.index)) {
// Handover successful, clear slot
targetAcceptorComp.onItemAccepted(destSlot.index, destSlot.acceptedDirection, item);
sourceSlot.item = null;
continue;
}
}
}
}
}
/**
*
* @param {BaseItem} item
* @param {Entity} receiver
* @param {number} slotIndex
*/
tryPassOverItem(item, receiver, slotIndex) {
// Try figuring out how what to do with the item
// TODO: Kinda hacky. How to solve this properly? Don't want to go through inheritance hell.
// Also its just a few cases (hope it stays like this .. :x).
const beltComp = receiver.components.Belt;
if (beltComp) {
const path = beltComp.assignedPath;
assert(path, "belt has no path");
if (path.tryAcceptItem(item)) {
return true;
}
// Belt can have nothing else
return false;
}
const itemProcessorComp = receiver.components.ItemProcessor;
if (itemProcessorComp) {
// Check for potential filters
if (!this.root.systemMgr.systems.itemProcessor.checkRequirements(receiver, item, slotIndex)) {
return false;
}
// Its an item processor ..
if (itemProcessorComp.tryTakeItem(item, slotIndex)) {
return true;
}
// Item processor can have nothing else
return false;
}
const undergroundBeltComp = receiver.components.UndergroundBelt;
if (undergroundBeltComp) {
// Its an underground belt. yay.
if (
undergroundBeltComp.tryAcceptExternalItem(
item,
this.root.hubGoals.getUndergroundBeltBaseSpeed()
)
) {
return true;
}
// Underground belt can have nothing else
return false;
}
const storageComp = receiver.components.Storage;
if (storageComp) {
// It's a storage
if (storageComp.canAcceptItem(item)) {
storageComp.takeItem(item);
return true;
}
// Storage can't have anything else
return false;
}
return false;
}
/**
* @param {DrawParameters} parameters
* @param {MapChunkView} chunk
*/
drawChunk(parameters, chunk) {
const contents = chunk.containedEntitiesByLayer.regular;
for (let i = 0; i < contents.length; ++i) {
const entity = contents[i];
const ejectorComp = entity.components.ItemEjector;
if (!ejectorComp) {
continue;
}
const staticComp = entity.components.StaticMapEntity;
for (let i = 0; i < ejectorComp.slots.length; ++i) {
const slot = ejectorComp.slots[i];
const ejectedItem = slot.item;
if (!ejectedItem) {
// No item
continue;
}
const realPosition = staticComp.localTileToWorld(slot.pos);
if (!chunk.tileSpaceRectangle.containsPoint(realPosition.x, realPosition.y)) {
// Not within this chunk
continue;
}
const realDirection = staticComp.localDirectionToWorld(slot.direction);
const realDirectionVector = enumDirectionToVector[realDirection];
const tileX = realPosition.x + 0.5 + realDirectionVector.x * 0.5 * slot.progress;
const tileY = realPosition.y + 0.5 + realDirectionVector.y * 0.5 * slot.progress;
const worldX = tileX * globalConfig.tileSize;
const worldY = tileY * globalConfig.tileSize;
ejectedItem.drawItemCenteredClipped(
worldX,
worldY,
parameters,
globalConfig.defaultItemDiameter
);
}
}
}
}

View File

@ -1,10 +1,14 @@
import { globalConfig } from "../../core/config";
import { BaseItem } from "../base_item";
import { enumColors, enumColorMixingResults } from "../colors";
import { enumItemProcessorTypes, ItemProcessorComponent, enumItemProcessorRequirements } from "../components/item_processor";
import { enumColorMixingResults, enumColors } from "../colors";
import {
enumItemProcessorRequirements,
enumItemProcessorTypes,
ItemProcessorComponent,
} from "../components/item_processor";
import { Entity } from "../entity";
import { GameSystemWithFilter } from "../game_system_with_filter";
import { BOOL_TRUE_SINGLETON, BOOL_FALSE_SINGLETON } from "../items/boolean_item";
import { BOOL_TRUE_SINGLETON, isTrueItem } from "../items/boolean_item";
import { ColorItem, COLOR_ITEM_SINGLETONS } from "../items/color_item";
import { ShapeItem } from "../items/shape_item";
@ -68,78 +72,154 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
}
}
// Check if we have an empty queue and can start a new charge
if (processorComp.itemsToEject.length === 0) {
if (entity.components.ItemProcessor.processingRequirement) {
if (this.canProcess(entity)) {
this.startNewCharge(entity);
}
} else if (processorComp.inputSlots.length >= processorComp.inputsPerCharge) {
if (this.canProcess(entity)) {
this.startNewCharge(entity);
}
}
}
}
/**
* Returns true if the entity should accept the given item on the given slot.
* This should only be called with matching items! I.e. if a color item is expected
* on the given slot, then only a color item must be passed.
* @param {Entity} entity
* @param {BaseItem} item The item to accept
* @param {number} slotIndex The slot index
* @returns {boolean}
*/
checkRequirements(entity, item, slotIndex) {
const itemProcessorComp = entity.components.ItemProcessor;
const pinsComp = entity.components.WiredPins;
switch (itemProcessorComp.processingRequirement) {
case enumItemProcessorRequirements.painterQuad: {
if (slotIndex === 0) {
// Always accept the shape
return true;
}
// Check the network value at the given slot
const network = pinsComp.slots[slotIndex - 1].linkedNetwork;
const slotIsEnabled = network && isTrueItem(network.currentValue);
if (!slotIsEnabled) {
return false;
}
return true;
}
case enumItemProcessorRequirements.filter: {
const network = pinsComp.slots[0].linkedNetwork;
if (!network || !network.currentValue) {
// Item filter is not connected
return false;
}
// Check if "false" was passed in
const item = network.currentValue;
if (item.getItemType() === "boolean") {
if (!(/** @type {BooleanItem} */ (item).value)) {
return false;
}
}
// Otherwise, all good
return true;
}
// By default, everything is accepted
default:
return true;
}
}
/**
* Checks whether it's possible to process something
* @param {Entity} entity
*/
canProcess(entity) {
switch (entity.components.ItemProcessor.processingRequirement) {
case enumItemProcessorRequirements.painterQuad: {
// For quad-painter, pins match slots
// boolean true means "disable input"
// a color means "disable if not matched"
const processorComp = entity.components.ItemProcessor;
const processorComp = entity.components.ItemProcessor;
switch (processorComp.processingRequirement) {
// DEFAULT
// By default, we can start processing once all inputs are there
case null: {
return processorComp.inputSlots.length >= processorComp.inputsPerCharge;
}
// QUAD PAINTER
// For the quad painter, it might be possible to start processing earlier
case enumItemProcessorRequirements.painterQuad: {
const pinsComp = entity.components.WiredPins;
/** @type {Object.<string, { item: BaseItem, sourceSlot: number }>} */
/** @type {Object.<number, { item: BaseItem, sourceSlot: number }>} */
const itemsBySlot = {};
for (let i = 0; i < processorComp.inputSlots.length; ++i) {
itemsBySlot[processorComp.inputSlots[i].sourceSlot] = processorComp.inputSlots[i];
}
// first slot is the shape
if (!itemsBySlot[0]) return false;
// First slot is the shape, so if it's not there we can't do anything
if (!itemsBySlot[0]) {
return false;
}
const shapeItem = /** @type {ShapeItem} */ (itemsBySlot[0].item);
const slotStatus = [];
// Here we check just basic things`
// Stop processing if anything except TRUE is
// set and there is no item.
// Check which slots are enabled
for (let i = 0; i < 4; ++i) {
const netValue = pinsComp.slots[i].linkedNetwork ?
pinsComp.slots[i].linkedNetwork.currentValue :
null;
// Extract the network value on the Nth pin
const networkValue = pinsComp.slots[i].linkedNetwork
? pinsComp.slots[i].linkedNetwork.currentValue
: null;
const currentItem = itemsBySlot[i + 1];
// If there is no "1" on that slot, don't paint there
if (!isTrueItem(networkValue)) {
slotStatus.push(false);
continue;
}
if ((netValue == null || !netValue.equals(BOOL_TRUE_SINGLETON)) && currentItem == null) {
let quadCount = 0;
slotStatus.push(true);
}
// All slots are disabled
if (!slotStatus.includes(true)) {
return false;
}
// Check if all colors of the enabled slots are there
for (let i = 0; i < slotStatus.length; ++i) {
if (slotStatus[i] && !itemsBySlot[1 + i]) {
// A slot which is enabled wasn't enabled. Make sure if there is anything on the quadrant,
// it is not possible to paint, but if there is nothing we can ignore it
for (let j = 0; j < 4; ++j) {
const layer = shapeItem.definition.layers[j];
if (layer && layer[i]) {
quadCount++;
return false;
}
}
if (quadCount > 0) {
return false;
}
}
}
return true;
}
// FILTER
// Double check with linked network
case enumItemProcessorRequirements.filter: {
const network = entity.components.WiredPins.slots[0].linkedNetwork;
if (!network || !network.currentValue) {
// Item filter is not connected
return false;
}
return processorComp.inputSlots.length >= processorComp.inputsPerCharge;
}
default:
assertAlways(
false,
"Unknown requirement for " + entity.components.ItemProcessor.processingRequirement
);
assertAlways(false, "Unknown requirement for " + processorComp.processingRequirement);
}
}
@ -375,60 +455,22 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
const shapeItem = /** @type {ShapeItem} */ (itemsBySlot[0].item);
assert(shapeItem instanceof ShapeItem, "Input for painter is not a shape");
/** @type {Array<ColorItem>} */
const colorItems = [].fill(null, 0, 4);
/** @type {Array<enumColors>} */
const colors = [null, null, null, null];
for (let i = 0; i < 4; ++i) {
if (itemsBySlot[i + 1]) {
colorItems[i] = /** @type {ColorItem} */ (itemsBySlot[i + 1].item);
assert(colorItems[i] instanceof ColorItem, "Input for painter is not a color");
colors[i] = /** @type {ColorItem} */ (itemsBySlot[i + 1].item).color;
}
}
const pinValues = entity.components.WiredPins.slots
.map(slot => slot.linkedNetwork ? slot.linkedNetwork.currentValue : BOOL_FALSE_SINGLETON);
// @todo cleanup
const colorTL = colorItems[0];
const colorTR = colorItems[1];
const colorBR = colorItems[2];
const colorBL = colorItems[3];
/** @type {Array<boolean>} */
let skipped = [];
for (let i = 0; i < 4; ++i) {
skipped[i] = pinValues[i] ? pinValues[i].equals(BOOL_TRUE_SINGLETON) : false;
}
for (let i = 0; i < 4; ++i) {
if (colorItems[i] == null) {
skipped[i] = false; // make sure we never insert null item back
} else if (pinValues[i] instanceof ColorItem) {
// if pin value is a color, skip anything except that color
// but still require any color, because it would not work on
// slow factories.
if (!colorItems[i].equals(pinValues[i])) {
skipped[i] = true;
}
}
}
const toColor = [
(!skipped[0] && colorTL) ? colorTL.color : null,
(!skipped[1] && colorTR) ? colorTR.color : null,
(!skipped[2] && colorBR) ? colorBR.color : null,
(!skipped[3] && colorBL) ? colorBL.color : null,
];
const colorizedDefinition = this.root.shapeDefinitionMgr.shapeActionPaintWith4Colors(
shapeItem.definition,
/** @type {[enumColors, enumColors, enumColors, enumColors]} */(toColor)
/** @type {[string, string, string, string]} */ (colors)
);
outItems.push({
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(colorizedDefinition),
});
break;
}

View File

@ -0,0 +1,101 @@
import { GameSystem } from "../game_system";
import { MapChunkView } from "../map_chunk_view";
import { enumItemProcessorRequirements } from "../components/item_processor";
import { Entity } from "../entity";
import { isTrueItem } from "../items/boolean_item";
import { globalConfig } from "../../core/config";
import { Loader } from "../../core/loader";
import { smoothPulse } from "../../core/utils";
export class ItemProcessorOverlaysSystem extends GameSystem {
constructor(root) {
super(root);
this.spriteDisabled = Loader.getSprite("sprites/misc/processor_disabled.png");
this.spriteDisconnected = Loader.getSprite("sprites/misc/processor_disconnected.png");
this.drawnUids = new Set();
this.root.signals.gameFrameStarted.add(this.clearDrawnUids, this);
}
clearDrawnUids() {
this.drawnUids.clear();
}
/**
*
* @param {import("../../core/draw_utils").DrawParameters} parameters
* @param {MapChunkView} chunk
*/
drawChunk(parameters, chunk) {
const contents = chunk.containedEntitiesByLayer.regular;
for (let i = 0; i < contents.length; ++i) {
const entity = contents[i];
const processorComp = entity.components.ItemProcessor;
if (!processorComp) {
continue;
}
const requirement = processorComp.processingRequirement;
if (!requirement) {
continue;
}
if (this.drawnUids.has(entity.uid)) {
continue;
}
this.drawnUids.add(entity.uid);
switch (requirement) {
case enumItemProcessorRequirements.painterQuad: {
this.drawConnectedSlotRequirement(parameters, entity);
break;
}
case enumItemProcessorRequirements.filter: {
this.drawConnectedSlotRequirement(parameters, entity);
break;
}
}
}
}
/**
*
* @param {import("../../core/draw_utils").DrawParameters} parameters
* @param {Entity} entity
*/
drawConnectedSlotRequirement(parameters, entity) {
const staticComp = entity.components.StaticMapEntity;
const pinsComp = entity.components.WiredPins;
let anySlotConnected = false;
// Check if any slot has a value
for (let i = 0; i < pinsComp.slots.length; ++i) {
const slot = pinsComp.slots[i];
const network = slot.linkedNetwork;
if (network && network.currentValue) {
anySlotConnected = true;
if (isTrueItem(network.currentValue)) {
// No need to draw anything
return;
}
}
}
const pulse = smoothPulse(this.root.time.now());
parameters.context.globalAlpha = 0.6 + 0.4 * pulse;
const sprite = anySlotConnected ? this.spriteDisabled : this.spriteDisconnected;
sprite.drawCachedCentered(
parameters,
(staticComp.origin.x + 0.5) * globalConfig.tileSize,
(staticComp.origin.y + 0.5) * globalConfig.tileSize,
globalConfig.tileSize * (0.7 + 0.2 * pulse)
);
parameters.context.globalAlpha = 1;
}
}

View File

@ -3,7 +3,7 @@ import { enumColors } from "../colors";
import { enumLogicGateType, LogicGateComponent } from "../components/logic_gate";
import { enumPinSlotType } from "../components/wired_pins";
import { GameSystemWithFilter } from "../game_system_with_filter";
import { BOOL_FALSE_SINGLETON, BOOL_TRUE_SINGLETON, BooleanItem } from "../items/boolean_item";
import { BOOL_FALSE_SINGLETON, BOOL_TRUE_SINGLETON, isTrueItem } from "../items/boolean_item";
import { COLOR_ITEM_SINGLETONS } from "../items/color_item";
import { ShapeDefinition } from "../shape_definition";
import { ShapeItem } from "../items/shape_item";
@ -76,28 +76,9 @@ export class LogicGateSystem extends GameSystemWithFilter {
*/
compute_AND(parameters) {
assert(parameters.length === 2, "bad parameter count for AND");
const param1 = parameters[0];
const param2 = parameters[1];
if (!param1 || !param2) {
// Not enough params
return BOOL_FALSE_SINGLETON;
}
const itemType = param1.getItemType();
if (itemType !== param2.getItemType()) {
// Differing type
return BOOL_FALSE_SINGLETON;
}
if (itemType === "boolean") {
return /** @type {BooleanItem} */ (param1).value && /** @type {BooleanItem} */ (param2).value
? BOOL_TRUE_SINGLETON
: BOOL_FALSE_SINGLETON;
}
return BOOL_FALSE_SINGLETON;
return isTrueItem(parameters[0]) && isTrueItem(parameters[1])
? BOOL_TRUE_SINGLETON
: BOOL_FALSE_SINGLETON;
}
/**
@ -105,18 +86,7 @@ export class LogicGateSystem extends GameSystemWithFilter {
* @returns {BaseItem}
*/
compute_NOT(parameters) {
const item = parameters[0];
if (!item) {
return BOOL_TRUE_SINGLETON;
}
if (item.getItemType() !== "boolean") {
// Not a boolean actually
return BOOL_FALSE_SINGLETON;
}
const value = /** @type {BooleanItem} */ (item).value;
return value ? BOOL_FALSE_SINGLETON : BOOL_TRUE_SINGLETON;
return isTrueItem(parameters[0]) ? BOOL_FALSE_SINGLETON : BOOL_TRUE_SINGLETON;
}
/**
@ -125,27 +95,9 @@ export class LogicGateSystem extends GameSystemWithFilter {
*/
compute_XOR(parameters) {
assert(parameters.length === 2, "bad parameter count for XOR");
const param1 = parameters[0];
const param2 = parameters[1];
if (!param1 && !param2) {
// Not enough params
return BOOL_FALSE_SINGLETON;
}
// Check for the right types
if (param1 && param1.getItemType() !== "boolean") {
return BOOL_FALSE_SINGLETON;
}
if (param2 && param2.getItemType() !== "boolean") {
return BOOL_FALSE_SINGLETON;
}
const valueParam1 = param1 ? /** @type {BooleanItem} */ (param1).value : 0;
const valueParam2 = param2 ? /** @type {BooleanItem} */ (param2).value : 0;
return valueParam1 ^ valueParam2 ? BOOL_TRUE_SINGLETON : BOOL_FALSE_SINGLETON;
return isTrueItem(parameters[0]) ^ isTrueItem(parameters[1])
? BOOL_TRUE_SINGLETON
: BOOL_FALSE_SINGLETON;
}
/**
@ -154,20 +106,9 @@ export class LogicGateSystem extends GameSystemWithFilter {
*/
compute_OR(parameters) {
assert(parameters.length === 2, "bad parameter count for OR");
const param1 = parameters[0];
const param2 = parameters[1];
if (!param1 && !param2) {
// Not enough params
return BOOL_FALSE_SINGLETON;
}
const valueParam1 =
param1 && param1.getItemType() === "boolean" ? /** @type {BooleanItem} */ (param1).value : 0;
const valueParam2 =
param2 && param2.getItemType() === "boolean" ? /** @type {BooleanItem} */ (param2).value : 0;
return valueParam1 || valueParam2 ? BOOL_TRUE_SINGLETON : BOOL_FALSE_SINGLETON;
return isTrueItem(parameters[0]) || isTrueItem(parameters[1])
? BOOL_TRUE_SINGLETON
: BOOL_FALSE_SINGLETON;
}
/**
@ -176,21 +117,11 @@ export class LogicGateSystem extends GameSystemWithFilter {
*/
compute_IF(parameters) {
assert(parameters.length === 2, "bad parameter count for IF");
const flag = parameters[0];
const value = parameters[1];
if (!flag || !value) {
// Not enough params
return null;
}
if (flag.getItemType() !== "boolean") {
// Flag is not a boolean
return null;
}
// pass through item
if (/** @type {BooleanItem} */ (flag).value) {
if (isTrueItem(flag)) {
return value;
}

File diff suppressed because it is too large Load Diff