Add belt reader building

This commit is contained in:
tobspr 2020-08-29 10:38:23 +02:00
parent bb739c80fa
commit 06e276f021
28 changed files with 1397 additions and 1069 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

View File

@ -10,7 +10,7 @@
},
"sprites/belt/built/forward_1.png":
{
"frame": {"x":1545,"y":991,"w":116,"h":144},
"frame": {"x":433,"y":1038,"w":116,"h":144},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":0,"w":116,"h":144},
@ -18,7 +18,7 @@
},
"sprites/belt/built/forward_2.png":
{
"frame": {"x":428,"y":1186,"w":116,"h":144},
"frame": {"x":433,"y":1186,"w":116,"h":144},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":0,"w":116,"h":144},
@ -26,7 +26,7 @@
},
"sprites/belt/built/forward_3.png":
{
"frame": {"x":427,"y":1334,"w":116,"h":144},
"frame": {"x":430,"y":1334,"w":116,"h":144},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":0,"w":116,"h":144},
@ -34,7 +34,7 @@
},
"sprites/belt/built/forward_4.png":
{
"frame": {"x":421,"y":1482,"w":116,"h":144},
"frame": {"x":426,"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":3,"y":1870,"w":116,"h":144},
"frame": {"x":3,"y":1860,"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":123,"y":1870,"w":116,"h":144},
"frame": {"x":123,"y":1860,"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":971,"y":1297,"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},
@ -74,7 +74,7 @@
},
"sprites/belt/built/forward_9.png":
{
"frame": {"x":420,"y":1630,"w":116,"h":144},
"frame": {"x":363,"y":1861,"w":116,"h":144},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":0,"w":116,"h":144},
@ -82,7 +82,7 @@
},
"sprites/belt/built/forward_10.png":
{
"frame": {"x":1545,"y":1139,"w":116,"h":144},
"frame": {"x":1545,"y":991,"w":116,"h":144},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":0,"w":116,"h":144},
@ -90,7 +90,7 @@
},
"sprites/belt/built/forward_11.png":
{
"frame": {"x":1534,"y":1287,"w":116,"h":144},
"frame": {"x":1544,"y":1139,"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":1532,"y":1435,"w":116,"h":144},
"frame": {"x":1540,"y":1287,"w":116,"h":144},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":0,"w":116,"h":144},
@ -106,7 +106,7 @@
},
"sprites/belt/built/forward_13.png":
{
"frame": {"x":433,"y":1038,"w":116,"h":144},
"frame": {"x":1533,"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":541,"y":1525,"w":130,"h":130},
"frame": {"x":981,"y":1456,"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":1091,"y":1363,"w":130,"h":130},
"frame": {"x":835,"y":1545,"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":675,"y":1557,"w":130,"h":130},
"frame": {"x":690,"y":1578,"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":540,"y":1659,"w":130,"h":130},
"frame": {"x":546,"y":1593,"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":809,"y":1590,"w":130,"h":130},
"frame": {"x":1115,"y":1458,"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":674,"y":1691,"w":130,"h":130},
"frame": {"x":969,"y":1590,"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":1225,"y":1404,"w":130,"h":130},
"frame": {"x":824,"y":1679,"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":1088,"y":1497,"w":130,"h":130},
"frame": {"x":680,"y":1712,"w":130,"h":130},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":14,"w":130,"h":130},
@ -202,7 +202,7 @@
},
"sprites/belt/built/left_11.png":
{
"frame": {"x":146,"y":1437,"w":130,"h":130},
"frame": {"x":151,"y":1437,"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":145,"y":1571,"w":130,"h":130},
"frame": {"x":146,"y":1571,"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":943,"y":1593,"w":130,"h":130},
"frame": {"x":540,"y":1727,"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":808,"y":1724,"w":130,"h":130},
"frame": {"x":735,"y":1846,"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":363,"y":1778,"w":130,"h":130},
"frame": {"x":1137,"y":1808,"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":363,"y":1912,"w":130,"h":130},
"frame": {"x":1271,"y":1674,"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":497,"y":1793,"w":130,"h":130},
"frame": {"x":1271,"y":1808,"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":631,"y":1825,"w":130,"h":130},
"frame": {"x":1405,"y":1583,"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":765,"y":1858,"w":130,"h":130},
"frame": {"x":1539,"y":1606,"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":1031,"y":1861,"w":130,"h":130},
"frame": {"x":1405,"y":1717,"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":1165,"y":1765,"w":130,"h":130},
"frame": {"x":1405,"y":1851,"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":1165,"y":1899,"w":130,"h":130},
"frame": {"x":1673,"y":1618,"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":1359,"y":1449,"w":130,"h":130},
"frame": {"x":869,"y":1813,"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":1222,"y":1538,"w":130,"h":130},
"frame": {"x":1003,"y":1724,"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":1077,"y":1631,"w":130,"h":130},
"frame": {"x":1003,"y":1858,"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":942,"y":1727,"w":130,"h":130},
"frame": {"x":1137,"y":1674,"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":1356,"y":1583,"w":130,"h":130},
"frame": {"x":1539,"y":1740,"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":1490,"y":1583,"w":130,"h":130},
"frame": {"x":1539,"y":1874,"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":968,"y":1445,"w":116,"h":144},
"frame": {"x":483,"y":1861,"w":116,"h":144},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":0,"w":116,"h":144},
@ -386,7 +386,7 @@
},
"sprites/blueprints/display.png":
{
"frame": {"x":899,"y":1861,"w":128,"h":136},
"frame": {"x":603,"y":1861,"w":128,"h":136},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":8,"y":8,"w":128,"h":136},
@ -418,7 +418,7 @@
},
"sprites/blueprints/logic_gate-or.png":
{
"frame": {"x":1249,"y":989,"w":144,"h":123},
"frame": {"x":3,"y":1317,"w":144,"h":123},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":144,"h":123},
@ -442,7 +442,7 @@
},
"sprites/blueprints/logic_gate.png":
{
"frame": {"x":1249,"y":852,"w":144,"h":133},
"frame": {"x":3,"y":1180,"w":144,"h":133},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":144,"h":133},
@ -450,7 +450,7 @@
},
"sprites/blueprints/miner-chainable.png":
{
"frame": {"x":3,"y":1723,"w":136,"h":143},
"frame": {"x":695,"y":1431,"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":831,"y":1297,"w":136,"h":143},
"frame": {"x":550,"y":1446,"w":136,"h":143},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":136,"h":143},
@ -504,9 +504,17 @@
"spriteSourceSize": {"x":0,"y":0,"w":288,"h":144},
"sourceSize": {"w":288,"h":144}
},
"sprites/blueprints/reader.png":
{
"frame": {"x":1660,"y":1311,"w":142,"h":144},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":0,"w":142,"h":144},
"sourceSize": {"w":144,"h":144}
},
"sprites/blueprints/rotater-ccw.png":
{
"frame": {"x":1665,"y":1198,"w":143,"h":144},
"frame": {"x":1397,"y":1022,"w":143,"h":144},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":143,"h":144},
@ -514,7 +522,7 @@
},
"sprites/blueprints/rotater-fl.png":
{
"frame": {"x":1242,"y":1116,"w":142,"h":144},
"frame": {"x":1891,"y":1384,"w":142,"h":144},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":142,"h":144},
@ -522,7 +530,7 @@
},
"sprites/blueprints/rotater.png":
{
"frame": {"x":1897,"y":1257,"w":143,"h":144},
"frame": {"x":1246,"y":1023,"w":143,"h":144},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":143,"h":144},
@ -530,7 +538,7 @@
},
"sprites/blueprints/splitter-compact-inverse.png":
{
"frame": {"x":1095,"y":1221,"w":142,"h":138},
"frame": {"x":1891,"y":1532,"w":142,"h":138},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":2,"w":142,"h":138},
@ -538,7 +546,7 @@
},
"sprites/blueprints/splitter-compact-merge-inverse.png":
{
"frame": {"x":1388,"y":1160,"w":142,"h":138},
"frame": {"x":808,"y":1033,"w":142,"h":138},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":2,"w":142,"h":138},
@ -546,7 +554,7 @@
},
"sprites/blueprints/splitter-compact-merge.png":
{
"frame": {"x":1881,"y":1552,"w":139,"h":138},
"frame": {"x":954,"y":1033,"w":139,"h":138},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":2,"w":139,"h":138},
@ -554,7 +562,7 @@
},
"sprites/blueprints/splitter-compact.png":
{
"frame": {"x":559,"y":1036,"w":139,"h":138},
"frame": {"x":3,"y":1444,"w":139,"h":138},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":2,"w":139,"h":138},
@ -594,7 +602,7 @@
},
"sprites/blueprints/underground_belt_entry-tier2.png":
{
"frame": {"x":3,"y":1466,"w":138,"h":125},
"frame": {"x":1329,"y":1454,"w":138,"h":125},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":19,"w":138,"h":125},
@ -602,7 +610,7 @@
},
"sprites/blueprints/underground_belt_entry.png":
{
"frame": {"x":696,"y":1180,"w":138,"h":112},
"frame": {"x":698,"y":1315,"w":138,"h":112},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":32,"w":138,"h":112},
@ -610,7 +618,7 @@
},
"sprites/blueprints/underground_belt_exit-tier2.png":
{
"frame": {"x":553,"y":1178,"w":139,"h":112},
"frame": {"x":1044,"y":1225,"w":139,"h":112},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":0,"w":139,"h":112},
@ -618,7 +626,7 @@
},
"sprites/blueprints/underground_belt_exit.png":
{
"frame": {"x":548,"y":1294,"w":138,"h":112},
"frame": {"x":553,"y":1330,"w":138,"h":112},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":0,"w":138,"h":112},
@ -642,7 +650,7 @@
},
"sprites/blueprints/virtual_processor-shapecompare.png":
{
"frame": {"x":1397,"y":852,"w":144,"h":133},
"frame": {"x":285,"y":1181,"w":144,"h":133},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":144,"h":133},
@ -658,7 +666,7 @@
},
"sprites/blueprints/virtual_processor.png":
{
"frame": {"x":285,"y":1037,"w":144,"h":141},
"frame": {"x":3,"y":1035,"w":144,"h":141},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":3,"w":144,"h":141},
@ -674,7 +682,7 @@
},
"sprites/blueprints/wire-split.png":
{
"frame": {"x":1397,"y":989,"w":144,"h":82},
"frame": {"x":1249,"y":852,"w":144,"h":82},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":62,"w":144,"h":82},
@ -682,7 +690,7 @@
},
"sprites/blueprints/wire-turn.png":
{
"frame": {"x":1813,"y":1144,"w":82,"h":82},
"frame": {"x":1811,"y":1192,"w":82,"h":82},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":62,"y":62,"w":82,"h":82},
@ -706,7 +714,7 @@
},
"sprites/blueprints/wire_tunnel.png":
{
"frame": {"x":285,"y":1322,"w":138,"h":135},
"frame": {"x":1187,"y":1319,"w":138,"h":135},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":4,"w":138,"h":135},
@ -722,7 +730,7 @@
},
"sprites/buildings/belt_right.png":
{
"frame": {"x":943,"y":1593,"w":130,"h":130},
"frame": {"x":540,"y":1727,"w":130,"h":130},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":14,"w":130,"h":130},
@ -802,7 +810,7 @@
},
"sprites/buildings/logic_gate-or.png":
{
"frame": {"x":948,"y":1170,"w":143,"h":123},
"frame": {"x":1897,"y":1257,"w":143,"h":123},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":143,"h":123},
@ -818,7 +826,7 @@
},
"sprites/buildings/logic_gate-xor.png":
{
"frame": {"x":801,"y":1033,"w":143,"h":143},
"frame": {"x":1665,"y":1028,"w":143,"h":143},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":143,"h":143},
@ -826,7 +834,7 @@
},
"sprites/buildings/logic_gate.png":
{
"frame": {"x":1095,"y":1085,"w":143,"h":132},
"frame": {"x":1664,"y":1175,"w":143,"h":132},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":143,"h":132},
@ -834,7 +842,7 @@
},
"sprites/buildings/miner-chainable.png":
{
"frame": {"x":688,"y":1411,"w":136,"h":142},
"frame": {"x":280,"y":1596,"w":136,"h":142},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":136,"h":142},
@ -842,7 +850,7 @@
},
"sprites/buildings/miner.png":
{
"frame": {"x":828,"y":1444,"w":136,"h":142},
"frame": {"x":3,"y":1714,"w":136,"h":142},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":136,"h":142},
@ -888,9 +896,17 @@
"spriteSourceSize": {"x":0,"y":0,"w":288,"h":144},
"sourceSize": {"w":288,"h":144}
},
"sprites/buildings/reader.png":
{
"frame": {"x":1243,"y":1171,"w":141,"h":144},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":0,"w":141,"h":144},
"sourceSize": {"w":144,"h":144}
},
"sprites/buildings/rotater-ccw.png":
{
"frame": {"x":1387,"y":1302,"w":141,"h":143},
"frame": {"x":1388,"y":1307,"w":141,"h":143},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":0,"w":141,"h":143},
@ -898,7 +914,7 @@
},
"sprites/buildings/rotater-fl.png":
{
"frame": {"x":1654,"y":1346,"w":141,"h":143},
"frame": {"x":1653,"y":1459,"w":141,"h":143},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":141,"h":143},
@ -906,7 +922,7 @@
},
"sprites/buildings/rotater.png":
{
"frame": {"x":1884,"y":1405,"w":141,"h":143},
"frame": {"x":553,"y":1183,"w":141,"h":143},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":0,"w":141,"h":143},
@ -914,7 +930,7 @@
},
"sprites/buildings/splitter-compact-inverse.png":
{
"frame": {"x":1652,"y":1493,"w":141,"h":136},
"frame": {"x":285,"y":1318,"w":141,"h":136},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":3,"w":141,"h":136},
@ -922,7 +938,7 @@
},
"sprites/buildings/splitter-compact-merge-inverse.png":
{
"frame": {"x":1241,"y":1264,"w":142,"h":136},
"frame": {"x":1097,"y":1085,"w":142,"h":136},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":3,"w":142,"h":136},
@ -930,7 +946,7 @@
},
"sprites/buildings/splitter-compact-merge.png":
{
"frame": {"x":285,"y":1182,"w":139,"h":136},
"frame": {"x":758,"y":1175,"w":139,"h":136},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":3,"w":139,"h":136},
@ -938,7 +954,7 @@
},
"sprites/buildings/splitter-compact.png":
{
"frame": {"x":3,"y":1326,"w":139,"h":136},
"frame": {"x":901,"y":1175,"w":139,"h":136},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":3,"w":139,"h":136},
@ -978,7 +994,7 @@
},
"sprites/buildings/underground_belt_entry-tier2.png":
{
"frame": {"x":3,"y":1595,"w":137,"h":124},
"frame": {"x":3,"y":1586,"w":137,"h":124},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":20,"w":137,"h":124},
@ -986,7 +1002,7 @@
},
"sprites/buildings/underground_belt_entry.png":
{
"frame": {"x":690,"y":1296,"w":137,"h":111},
"frame": {"x":840,"y":1315,"w":137,"h":111},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":33,"w":137,"h":111},
@ -994,7 +1010,7 @@
},
"sprites/buildings/underground_belt_exit-tier2.png":
{
"frame": {"x":547,"y":1410,"w":137,"h":111},
"frame": {"x":981,"y":1341,"w":137,"h":111},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":137,"h":111},
@ -1002,7 +1018,7 @@
},
"sprites/buildings/underground_belt_exit.png":
{
"frame": {"x":279,"y":1599,"w":137,"h":111},
"frame": {"x":840,"y":1430,"w":137,"h":111},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":137,"h":111},
@ -1026,7 +1042,7 @@
},
"sprites/buildings/virtual_processor-shapecompare.png":
{
"frame": {"x":948,"y":1033,"w":143,"h":133},
"frame": {"x":1393,"y":1170,"w":143,"h":133},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":143,"h":133},
@ -1034,7 +1050,7 @@
},
"sprites/buildings/virtual_processor-unstacker.png":
{
"frame": {"x":3,"y":1035,"w":144,"h":143},
"frame": {"x":559,"y":1036,"w":144,"h":143},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":1,"w":144,"h":143},
@ -1042,7 +1058,7 @@
},
"sprites/buildings/virtual_processor.png":
{
"frame": {"x":3,"y":1182,"w":144,"h":140},
"frame": {"x":285,"y":1037,"w":144,"h":140},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":4,"w":144,"h":140},
@ -1058,7 +1074,7 @@
},
"sprites/buildings/wire-split.png":
{
"frame": {"x":1098,"y":1000,"w":144,"h":81},
"frame": {"x":1397,"y":852,"w":144,"h":81},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":63,"w":144,"h":81},
@ -1090,7 +1106,7 @@
},
"sprites/buildings/wire_tunnel.png":
{
"frame": {"x":280,"y":1461,"w":137,"h":134},
"frame": {"x":285,"y":1458,"w":137,"h":134},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":5,"w":137,"h":134},
@ -1122,7 +1138,7 @@
},
"sprites/misc/processor_disabled.png":
{
"frame": {"x":1799,"y":1485,"w":78,"h":81},
"frame": {"x":1798,"y":1533,"w":78,"h":81},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":10,"y":10,"w":78,"h":81},
@ -1136,6 +1152,14 @@
"spriteSourceSize": {"x":17,"y":8,"w":65,"h":84},
"sourceSize": {"w":96,"h":96}
},
"sprites/misc/reader_overlay.png":
{
"frame": {"x":708,"y":888,"w":98,"h":70},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":22,"y":38,"w":98,"h":70},
"sourceSize": {"w":144,"h":144}
},
"sprites/misc/slot_bad_arrow.png":
{
"frame": {"x":255,"y":638,"w":35,"h":35},
@ -1154,7 +1178,7 @@
},
"sprites/misc/storage_overlay.png":
{
"frame": {"x":708,"y":988,"w":89,"h":44},
"frame": {"x":1812,"y":1144,"w":89,"h":44},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":89,"h":44},
@ -1162,7 +1186,7 @@
},
"sprites/misc/waypoint.png":
{
"frame": {"x":702,"y":1084,"w":38,"h":48},
"frame": {"x":758,"y":1114,"w":38,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":38,"h":48},
@ -1226,7 +1250,7 @@
},
"sprites/wires/display/white.png":
{
"frame": {"x":1797,"y":1570,"w":47,"h":47},
"frame": {"x":707,"y":1062,"w":47,"h":47},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":47,"h":47},
@ -1234,7 +1258,7 @@
},
"sprites/wires/display/yellow.png":
{
"frame": {"x":1797,"y":1621,"w":47,"h":47},
"frame": {"x":707,"y":1113,"w":47,"h":47},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":47,"h":47},
@ -1266,7 +1290,7 @@
},
"sprites/wires/network_conflict.png":
{
"frame": {"x":702,"y":1036,"w":47,"h":44},
"frame": {"x":707,"y":1164,"w":47,"h":44},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":2,"w":47,"h":44},
@ -1274,7 +1298,7 @@
},
"sprites/wires/network_empty.png":
{
"frame": {"x":753,"y":1036,"w":41,"h":48},
"frame": {"x":758,"y":1062,"w":41,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":0,"w":41,"h":48},
@ -1282,7 +1306,7 @@
},
"sprites/wires/overlay_tile.png":
{
"frame": {"x":708,"y":888,"w":96,"h":96},
"frame": {"x":708,"y":962,"w":96,"h":96},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":96,"h":96},
@ -1306,7 +1330,7 @@
},
"sprites/wires/sets/color_split.png":
{
"frame": {"x":1397,"y":1075,"w":144,"h":81},
"frame": {"x":1397,"y":937,"w":144,"h":81},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":63,"w":144,"h":81},
@ -1314,7 +1338,7 @@
},
"sprites/wires/sets/color_turn.png":
{
"frame": {"x":1812,"y":1230,"w":81,"h":81},
"frame": {"x":1811,"y":1278,"w":81,"h":81},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":63,"y":63,"w":81,"h":81},
@ -1338,7 +1362,7 @@
},
"sprites/wires/sets/conflict_split.png":
{
"frame": {"x":1665,"y":1028,"w":144,"h":81},
"frame": {"x":1249,"y":938,"w":144,"h":81},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":63,"w":144,"h":81},
@ -1346,7 +1370,7 @@
},
"sprites/wires/sets/conflict_turn.png":
{
"frame": {"x":1812,"y":1315,"w":81,"h":81},
"frame": {"x":1806,"y":1363,"w":81,"h":81},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":63,"y":63,"w":81,"h":81},
@ -1370,7 +1394,7 @@
},
"sprites/wires/sets/regular_split.png":
{
"frame": {"x":1098,"y":1000,"w":144,"h":81},
"frame": {"x":1397,"y":852,"w":144,"h":81},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":63,"w":144,"h":81},
@ -1402,7 +1426,7 @@
},
"sprites/wires/sets/shape_split.png":
{
"frame": {"x":1665,"y":1113,"w":144,"h":81},
"frame": {"x":1098,"y":1000,"w":144,"h":81},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":63,"w":144,"h":81},
@ -1410,7 +1434,7 @@
},
"sprites/wires/sets/shape_turn.png":
{
"frame": {"x":1799,"y":1400,"w":81,"h":81},
"frame": {"x":1806,"y":1448,"w":81,"h":81},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":63,"y":63,"w":81,"h":81},
@ -1431,6 +1455,6 @@
"format": "RGBA8888",
"size": {"w":2048,"h":2048},
"scale": "0.75",
"smartupdate": "$TexturePacker:SmartUpdate:1923b9c910205fb09957b67f92de02b9:0d87df06f18965307bf9d18b414f603d:908b89f5ca8ff73e331a35a3b14d0604$"
"smartupdate": "$TexturePacker:SmartUpdate:3b1717ceee14135311380de9706938d5:e834c7745e235246a53bcb721a2e3be3:908b89f5ca8ff73e331a35a3b14d0604$"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

View File

@ -2,7 +2,7 @@
"sprites/belt/built/forward_0.png":
{
"frame": {"x":3,"y":957,"w":40,"h":48},
"frame": {"x":405,"y":817,"w":40,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":0,"w":40,"h":48},
@ -10,7 +10,7 @@
},
"sprites/belt/built/forward_1.png":
{
"frame": {"x":47,"y":957,"w":40,"h":48},
"frame": {"x":252,"y":893,"w":40,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":0,"w":40,"h":48},
@ -18,7 +18,7 @@
},
"sprites/belt/built/forward_2.png":
{
"frame": {"x":448,"y":821,"w":40,"h":48},
"frame": {"x":3,"y":930,"w":40,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":0,"w":40,"h":48},
@ -26,7 +26,7 @@
},
"sprites/belt/built/forward_3.png":
{
"frame": {"x":135,"y":938,"w":40,"h":48},
"frame": {"x":95,"y":960,"w":40,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":0,"w":40,"h":48},
@ -34,7 +34,7 @@
},
"sprites/belt/built/forward_4.png":
{
"frame": {"x":179,"y":938,"w":40,"h":48},
"frame": {"x":139,"y":960,"w":40,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":0,"w":40,"h":48},
@ -42,7 +42,7 @@
},
"sprites/belt/built/forward_5.png":
{
"frame": {"x":223,"y":937,"w":40,"h":48},
"frame": {"x":183,"y":954,"w":40,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":0,"w":40,"h":48},
@ -50,7 +50,7 @@
},
"sprites/belt/built/forward_6.png":
{
"frame": {"x":349,"y":867,"w":40,"h":48},
"frame": {"x":449,"y":819,"w":40,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":0,"w":40,"h":48},
@ -58,7 +58,7 @@
},
"sprites/belt/built/forward_7.png":
{
"frame": {"x":393,"y":867,"w":40,"h":48},
"frame": {"x":400,"y":869,"w":40,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":0,"w":40,"h":48},
@ -66,7 +66,7 @@
},
"sprites/belt/built/forward_8.png":
{
"frame": {"x":293,"y":877,"w":40,"h":48},
"frame": {"x":352,"y":913,"w":40,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":0,"w":40,"h":48},
@ -74,7 +74,7 @@
},
"sprites/belt/built/forward_9.png":
{
"frame": {"x":437,"y":873,"w":40,"h":48},
"frame": {"x":227,"y":965,"w":40,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":0,"w":40,"h":48},
@ -82,7 +82,7 @@
},
"sprites/belt/built/forward_10.png":
{
"frame": {"x":91,"y":933,"w":40,"h":48},
"frame": {"x":201,"y":901,"w":40,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":0,"w":40,"h":48},
@ -90,7 +90,7 @@
},
"sprites/belt/built/forward_11.png":
{
"frame": {"x":249,"y":847,"w":40,"h":48},
"frame": {"x":150,"y":902,"w":40,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":0,"w":40,"h":48},
@ -98,7 +98,7 @@
},
"sprites/belt/built/forward_12.png":
{
"frame": {"x":198,"y":885,"w":40,"h":48},
"frame": {"x":99,"y":908,"w":40,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":0,"w":40,"h":48},
@ -106,7 +106,7 @@
},
"sprites/belt/built/forward_13.png":
{
"frame": {"x":147,"y":886,"w":40,"h":48},
"frame": {"x":51,"y":927,"w":40,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":0,"w":40,"h":48},
@ -130,7 +130,7 @@
},
"sprites/belt/built/left_2.png":
{
"frame": {"x":208,"y":741,"w":44,"h":44},
"frame": {"x":324,"y":643,"w":44,"h":44},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":4,"w":44,"h":44},
@ -138,7 +138,7 @@
},
"sprites/belt/built/left_3.png":
{
"frame": {"x":157,"y":742,"w":44,"h":44},
"frame": {"x":223,"y":611,"w":44,"h":44},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":4,"w":44,"h":44},
@ -146,7 +146,7 @@
},
"sprites/belt/built/left_4.png":
{
"frame": {"x":105,"y":749,"w":44,"h":44},
"frame": {"x":275,"y":659,"w":44,"h":44},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":4,"w":44,"h":44},
@ -154,7 +154,7 @@
},
"sprites/belt/built/left_5.png":
{
"frame": {"x":54,"y":789,"w":44,"h":44},
"frame": {"x":323,"y":691,"w":44,"h":44},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":4,"w":44,"h":44},
@ -162,7 +162,7 @@
},
"sprites/belt/built/left_6.png":
{
"frame": {"x":3,"y":813,"w":44,"h":44},
"frame": {"x":261,"y":749,"w":44,"h":44},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":4,"w":44,"h":44},
@ -170,7 +170,7 @@
},
"sprites/belt/built/left_7.png":
{
"frame": {"x":364,"y":723,"w":44,"h":44},
"frame": {"x":208,"y":757,"w":44,"h":44},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":4,"w":44,"h":44},
@ -178,7 +178,7 @@
},
"sprites/belt/built/left_8.png":
{
"frame": {"x":311,"y":733,"w":44,"h":44},
"frame": {"x":363,"y":769,"w":44,"h":44},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":4,"w":44,"h":44},
@ -186,7 +186,7 @@
},
"sprites/belt/built/left_9.png":
{
"frame": {"x":256,"y":751,"w":44,"h":44},
"frame": {"x":309,"y":781,"w":44,"h":44},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":4,"w":44,"h":44},
@ -218,7 +218,7 @@
},
"sprites/belt/built/left_13.png":
{
"frame": {"x":324,"y":643,"w":44,"h":44},
"frame": {"x":464,"y":615,"w":44,"h":44},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":4,"w":44,"h":44},
@ -226,7 +226,7 @@
},
"sprites/belt/built/right_0.png":
{
"frame": {"x":205,"y":789,"w":44,"h":44},
"frame": {"x":256,"y":797,"w":44,"h":44},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":4,"w":44,"h":44},
@ -234,7 +234,7 @@
},
"sprites/belt/built/right_1.png":
{
"frame": {"x":153,"y":790,"w":44,"h":44},
"frame": {"x":208,"y":805,"w":44,"h":44},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":4,"w":44,"h":44},
@ -242,7 +242,7 @@
},
"sprites/belt/built/right_2.png":
{
"frame": {"x":304,"y":781,"w":44,"h":44},
"frame": {"x":357,"y":817,"w":44,"h":44},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":4,"w":44,"h":44},
@ -250,7 +250,7 @@
},
"sprites/belt/built/right_3.png":
{
"frame": {"x":253,"y":799,"w":44,"h":44},
"frame": {"x":304,"y":829,"w":44,"h":44},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":4,"w":44,"h":44},
@ -258,7 +258,7 @@
},
"sprites/belt/built/right_4.png":
{
"frame": {"x":201,"y":837,"w":44,"h":44},
"frame": {"x":256,"y":845,"w":44,"h":44},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":4,"w":44,"h":44},
@ -266,7 +266,7 @@
},
"sprites/belt/built/right_5.png":
{
"frame": {"x":150,"y":838,"w":44,"h":44},
"frame": {"x":204,"y":853,"w":44,"h":44},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":4,"w":44,"h":44},
@ -274,7 +274,7 @@
},
"sprites/belt/built/right_6.png":
{
"frame": {"x":99,"y":845,"w":44,"h":44},
"frame": {"x":153,"y":854,"w":44,"h":44},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":4,"w":44,"h":44},
@ -282,7 +282,7 @@
},
"sprites/belt/built/right_7.png":
{
"frame": {"x":51,"y":885,"w":44,"h":44},
"frame": {"x":102,"y":860,"w":44,"h":44},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":4,"w":44,"h":44},
@ -290,7 +290,7 @@
},
"sprites/belt/built/right_8.png":
{
"frame": {"x":3,"y":909,"w":44,"h":44},
"frame": {"x":51,"y":879,"w":44,"h":44},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":4,"w":44,"h":44},
@ -298,7 +298,7 @@
},
"sprites/belt/built/right_9.png":
{
"frame": {"x":352,"y":819,"w":44,"h":44},
"frame": {"x":3,"y":882,"w":44,"h":44},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":4,"w":44,"h":44},
@ -306,7 +306,7 @@
},
"sprites/belt/built/right_10.png":
{
"frame": {"x":102,"y":797,"w":44,"h":44},
"frame": {"x":156,"y":806,"w":44,"h":44},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":4,"w":44,"h":44},
@ -314,7 +314,7 @@
},
"sprites/belt/built/right_11.png":
{
"frame": {"x":51,"y":837,"w":44,"h":44},
"frame": {"x":105,"y":812,"w":44,"h":44},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":4,"w":44,"h":44},
@ -322,7 +322,7 @@
},
"sprites/belt/built/right_12.png":
{
"frame": {"x":3,"y":861,"w":44,"h":44},
"frame": {"x":54,"y":831,"w":44,"h":44},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":4,"w":44,"h":44},
@ -330,7 +330,7 @@
},
"sprites/belt/built/right_13.png":
{
"frame": {"x":359,"y":771,"w":44,"h":44},
"frame": {"x":3,"y":834,"w":44,"h":44},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":4,"w":44,"h":44},
@ -338,7 +338,7 @@
},
"sprites/blueprints/belt_left.png":
{
"frame": {"x":400,"y":819,"w":44,"h":44},
"frame": {"x":352,"y":865,"w":44,"h":44},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":4,"w":44,"h":44},
@ -346,7 +346,7 @@
},
"sprites/blueprints/belt_right.png":
{
"frame": {"x":301,"y":829,"w":44,"h":44},
"frame": {"x":304,"y":877,"w":44,"h":44},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":4,"w":44,"h":44},
@ -354,7 +354,7 @@
},
"sprites/blueprints/belt_top.png":
{
"frame": {"x":267,"y":929,"w":40,"h":48},
"frame": {"x":271,"y":965,"w":40,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":0,"w":40,"h":48},
@ -418,7 +418,7 @@
},
"sprites/blueprints/logic_gate-or.png":
{
"frame": {"x":159,"y":571,"w":48,"h":42},
"frame": {"x":371,"y":723,"w":48,"h":42},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":42},
@ -442,7 +442,7 @@
},
"sprites/blueprints/logic_gate.png":
{
"frame": {"x":55,"y":504,"w":48,"h":45},
"frame": {"x":55,"y":555,"w":48,"h":45},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":45},
@ -450,7 +450,7 @@
},
"sprites/blueprints/miner-chainable.png":
{
"frame": {"x":107,"y":646,"w":47,"h":48},
"frame": {"x":55,"y":682,"w":47,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":47,"h":48},
@ -458,7 +458,7 @@
},
"sprites/blueprints/miner.png":
{
"frame": {"x":55,"y":686,"w":47,"h":48},
"frame": {"x":3,"y":689,"w":47,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":47,"h":48},
@ -504,7 +504,7 @@
"spriteSourceSize": {"x":0,"y":0,"w":96,"h":48},
"sourceSize": {"w":96,"h":48}
},
"sprites/blueprints/rotater-ccw.png":
"sprites/blueprints/reader.png":
{
"frame": {"x":291,"y":211,"w":48,"h":48},
"rotated": false,
@ -512,7 +512,7 @@
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
"sourceSize": {"w":48,"h":48}
},
"sprites/blueprints/rotater-fl.png":
"sprites/blueprints/rotater-ccw.png":
{
"frame": {"x":274,"y":399,"w":48,"h":48},
"rotated": false,
@ -520,7 +520,7 @@
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
"sourceSize": {"w":48,"h":48}
},
"sprites/blueprints/rotater.png":
"sprites/blueprints/rotater-fl.png":
{
"frame": {"x":374,"y":411,"w":48,"h":48},
"rotated": false,
@ -528,7 +528,7 @@
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
"sourceSize": {"w":48,"h":48}
},
"sprites/blueprints/splitter-compact-inverse.png":
"sprites/blueprints/rotater.png":
{
"frame": {"x":274,"y":451,"w":48,"h":48},
"rotated": false,
@ -536,7 +536,7 @@
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
"sourceSize": {"w":48,"h":48}
},
"sprites/blueprints/splitter-compact-merge-inverse.png":
"sprites/blueprints/splitter-compact-inverse.png":
{
"frame": {"x":374,"y":463,"w":48,"h":48},
"rotated": false,
@ -544,9 +544,17 @@
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
"sourceSize": {"w":48,"h":48}
},
"sprites/blueprints/splitter-compact-merge-inverse.png":
{
"frame": {"x":374,"y":515,"w":48,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
"sourceSize": {"w":48,"h":48}
},
"sprites/blueprints/splitter-compact-merge.png":
{
"frame": {"x":158,"y":649,"w":47,"h":47},
"frame": {"x":54,"y":734,"w":47,"h":47},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":47,"h":47},
@ -554,7 +562,7 @@
},
"sprites/blueprints/splitter-compact.png":
{
"frame": {"x":106,"y":698,"w":47,"h":47},
"frame": {"x":3,"y":741,"w":47,"h":47},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":47,"h":47},
@ -586,7 +594,7 @@
},
"sprites/blueprints/trash.png":
{
"frame": {"x":374,"y":515,"w":48,"h":48},
"frame": {"x":3,"y":400,"w":48,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
@ -594,7 +602,7 @@
},
"sprites/blueprints/underground_belt_entry-tier2.png":
{
"frame": {"x":107,"y":553,"w":48,"h":43},
"frame": {"x":223,"y":659,"w":48,"h":43},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":5,"w":48,"h":43},
@ -602,7 +610,7 @@
},
"sprites/blueprints/underground_belt_entry.png":
{
"frame": {"x":55,"y":602,"w":48,"h":38},
"frame": {"x":3,"y":605,"w":48,"h":38},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":10,"w":48,"h":38},
@ -610,7 +618,7 @@
},
"sprites/blueprints/underground_belt_exit-tier2.png":
{
"frame": {"x":3,"y":604,"w":48,"h":38},
"frame": {"x":3,"y":647,"w":48,"h":38},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":38},
@ -618,7 +626,7 @@
},
"sprites/blueprints/underground_belt_exit.png":
{
"frame": {"x":55,"y":644,"w":48,"h":38},
"frame": {"x":107,"y":604,"w":48,"h":38},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":38},
@ -626,7 +634,7 @@
},
"sprites/blueprints/virtual_processor-analyzer.png":
{
"frame": {"x":3,"y":400,"w":48,"h":48},
"frame": {"x":55,"y":400,"w":48,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
@ -642,7 +650,7 @@
},
"sprites/blueprints/virtual_processor-shapecompare.png":
{
"frame": {"x":107,"y":504,"w":48,"h":45},
"frame": {"x":3,"y":556,"w":48,"h":45},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":45},
@ -650,7 +658,7 @@
},
"sprites/blueprints/virtual_processor-unstacker.png":
{
"frame": {"x":55,"y":400,"w":48,"h":48},
"frame": {"x":107,"y":400,"w":48,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
@ -658,7 +666,7 @@
},
"sprites/blueprints/virtual_processor.png":
{
"frame": {"x":107,"y":400,"w":48,"h":48},
"frame": {"x":3,"y":452,"w":48,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
@ -666,7 +674,7 @@
},
"sprites/blueprints/wire-cross.png":
{
"frame": {"x":3,"y":452,"w":48,"h":48},
"frame": {"x":55,"y":452,"w":48,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
@ -690,7 +698,7 @@
},
"sprites/blueprints/wire.png":
{
"frame": {"x":437,"y":693,"w":8,"h":48},
"frame": {"x":437,"y":722,"w":8,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":20,"y":0,"w":8,"h":48},
@ -698,7 +706,7 @@
},
"sprites/blueprints/wire_tunnel-coating.png":
{
"frame": {"x":425,"y":609,"w":13,"h":47},
"frame": {"x":425,"y":638,"w":13,"h":47},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":17,"y":0,"w":13,"h":47},
@ -706,7 +714,7 @@
},
"sprites/blueprints/wire_tunnel.png":
{
"frame": {"x":449,"y":719,"w":48,"h":47},
"frame": {"x":55,"y":504,"w":48,"h":47},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":47},
@ -722,7 +730,7 @@
},
"sprites/buildings/belt_right.png":
{
"frame": {"x":205,"y":789,"w":44,"h":44},
"frame": {"x":256,"y":797,"w":44,"h":44},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":4,"w":44,"h":44},
@ -730,7 +738,7 @@
},
"sprites/buildings/belt_top.png":
{
"frame": {"x":3,"y":957,"w":40,"h":48},
"frame": {"x":405,"y":817,"w":40,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":0,"w":40,"h":48},
@ -802,7 +810,7 @@
},
"sprites/buildings/logic_gate-or.png":
{
"frame": {"x":107,"y":600,"w":48,"h":42},
"frame": {"x":55,"y":604,"w":48,"h":42},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":42},
@ -818,7 +826,7 @@
},
"sprites/buildings/logic_gate-xor.png":
{
"frame": {"x":55,"y":452,"w":48,"h":48},
"frame": {"x":107,"y":452,"w":48,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
@ -826,7 +834,7 @@
},
"sprites/buildings/logic_gate.png":
{
"frame": {"x":55,"y":553,"w":48,"h":45},
"frame": {"x":107,"y":555,"w":48,"h":45},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":45},
@ -834,7 +842,7 @@
},
"sprites/buildings/miner-chainable.png":
{
"frame": {"x":3,"y":710,"w":47,"h":48},
"frame": {"x":159,"y":703,"w":47,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":47,"h":48},
@ -842,7 +850,7 @@
},
"sprites/buildings/miner.png":
{
"frame": {"x":211,"y":643,"w":47,"h":48},
"frame": {"x":106,"y":710,"w":47,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":47,"h":48},
@ -888,15 +896,7 @@
"spriteSourceSize": {"x":0,"y":0,"w":96,"h":48},
"sourceSize": {"w":96,"h":48}
},
"sprites/buildings/rotater-ccw.png":
{
"frame": {"x":107,"y":452,"w":48,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
"sourceSize": {"w":48,"h":48}
},
"sprites/buildings/rotater-fl.png":
"sprites/buildings/reader.png":
{
"frame": {"x":179,"y":467,"w":48,"h":48},
"rotated": false,
@ -904,7 +904,7 @@
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
"sourceSize": {"w":48,"h":48}
},
"sprites/buildings/rotater.png":
"sprites/buildings/rotater-ccw.png":
{
"frame": {"x":273,"y":503,"w":48,"h":48},
"rotated": false,
@ -912,9 +912,25 @@
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
"sourceSize": {"w":48,"h":48}
},
"sprites/buildings/rotater-fl.png":
{
"frame": {"x":273,"y":555,"w":48,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
"sourceSize": {"w":48,"h":48}
},
"sprites/buildings/rotater.png":
{
"frame": {"x":373,"y":567,"w":48,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
"sourceSize": {"w":48,"h":48}
},
"sprites/buildings/splitter-compact-inverse.png":
{
"frame": {"x":448,"y":770,"w":48,"h":47},
"frame": {"x":107,"y":504,"w":48,"h":47},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":47},
@ -922,7 +938,7 @@
},
"sprites/buildings/splitter-compact-merge-inverse.png":
{
"frame": {"x":3,"y":504,"w":48,"h":47},
"frame": {"x":171,"y":571,"w":48,"h":47},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":47},
@ -930,7 +946,7 @@
},
"sprites/buildings/splitter-compact-merge.png":
{
"frame": {"x":54,"y":738,"w":47,"h":47},
"frame": {"x":210,"y":706,"w":47,"h":47},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":47,"h":47},
@ -938,7 +954,7 @@
},
"sprites/buildings/splitter-compact.png":
{
"frame": {"x":3,"y":762,"w":47,"h":47},
"frame": {"x":157,"y":755,"w":47,"h":47},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":47,"h":47},
@ -970,7 +986,7 @@
},
"sprites/buildings/trash.png":
{
"frame": {"x":273,"y":555,"w":48,"h":48},
"frame": {"x":373,"y":619,"w":48,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
@ -978,7 +994,7 @@
},
"sprites/buildings/underground_belt_entry-tier2.png":
{
"frame": {"x":209,"y":695,"w":47,"h":42},
"frame": {"x":54,"y":785,"w":47,"h":42},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":6,"w":47,"h":42},
@ -986,7 +1002,7 @@
},
"sprites/buildings/underground_belt_entry.png":
{
"frame": {"x":157,"y":700,"w":47,"h":38},
"frame": {"x":3,"y":792,"w":47,"h":38},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":10,"w":47,"h":38},
@ -994,7 +1010,7 @@
},
"sprites/buildings/underground_belt_exit-tier2.png":
{
"frame": {"x":313,"y":691,"w":47,"h":38},
"frame": {"x":261,"y":707,"w":47,"h":38},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":47,"h":38},
@ -1002,7 +1018,7 @@
},
"sprites/buildings/underground_belt_exit.png":
{
"frame": {"x":260,"y":709,"w":47,"h":38},
"frame": {"x":312,"y":739,"w":47,"h":38},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":0,"w":47,"h":38},
@ -1010,7 +1026,7 @@
},
"sprites/buildings/virtual_processor-analyzer.png":
{
"frame": {"x":373,"y":567,"w":48,"h":48},
"frame": {"x":178,"y":519,"w":48,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
@ -1026,7 +1042,7 @@
},
"sprites/buildings/virtual_processor-shapecompare.png":
{
"frame": {"x":3,"y":555,"w":48,"h":45},
"frame": {"x":171,"y":622,"w":48,"h":45},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":45},
@ -1034,7 +1050,7 @@
},
"sprites/buildings/virtual_processor-unstacker.png":
{
"frame": {"x":178,"y":519,"w":48,"h":48},
"frame": {"x":272,"y":607,"w":48,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
@ -1042,7 +1058,7 @@
},
"sprites/buildings/virtual_processor.png":
{
"frame": {"x":272,"y":607,"w":48,"h":48},
"frame": {"x":372,"y":671,"w":48,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
@ -1050,7 +1066,7 @@
},
"sprites/buildings/wire-cross.png":
{
"frame": {"x":373,"y":619,"w":48,"h":48},
"frame": {"x":459,"y":663,"w":48,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
@ -1058,7 +1074,7 @@
},
"sprites/buildings/wire-split.png":
{
"frame": {"x":3,"y":646,"w":48,"h":28},
"frame": {"x":107,"y":646,"w":48,"h":28},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":20,"w":48,"h":28},
@ -1074,7 +1090,7 @@
},
"sprites/buildings/wire.png":
{
"frame": {"x":424,"y":698,"w":8,"h":48},
"frame": {"x":501,"y":767,"w":8,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":20,"y":0,"w":8,"h":48},
@ -1082,7 +1098,7 @@
},
"sprites/buildings/wire_tunnel-coating.png":
{
"frame": {"x":442,"y":643,"w":12,"h":46},
"frame": {"x":442,"y":672,"w":12,"h":46},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":18,"y":1,"w":12,"h":46},
@ -1090,7 +1106,7 @@
},
"sprites/buildings/wire_tunnel.png":
{
"frame": {"x":262,"y":659,"w":47,"h":46},
"frame": {"x":105,"y":762,"w":47,"h":46},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":1,"y":1,"w":47,"h":46},
@ -1136,9 +1152,17 @@
"spriteSourceSize": {"x":5,"y":2,"w":23,"h":29},
"sourceSize": {"w":32,"h":32}
},
"sprites/misc/reader_overlay.png":
{
"frame": {"x":425,"y":609,"w":35,"h":25},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":6,"y":12,"w":35,"h":25},
"sourceSize": {"w":48,"h":48}
},
"sprites/misc/slot_bad_arrow.png":
{
"frame": {"x":442,"y":609,"w":13,"h":13},
"frame": {"x":442,"y":638,"w":13,"h":13},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":13,"h":13},
@ -1146,7 +1170,7 @@
},
"sprites/misc/slot_good_arrow.png":
{
"frame": {"x":442,"y":626,"w":13,"h":13},
"frame": {"x":442,"y":655,"w":13,"h":13},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":13,"h":13},
@ -1170,7 +1194,7 @@
},
"sprites/wires/boolean_false.png":
{
"frame": {"x":425,"y":660,"w":12,"h":15},
"frame": {"x":424,"y":689,"w":12,"h":15},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":1,"w":12,"h":15},
@ -1178,7 +1202,7 @@
},
"sprites/wires/boolean_true.png":
{
"frame": {"x":424,"y":679,"w":9,"h":15},
"frame": {"x":424,"y":708,"w":9,"h":15},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":1,"w":9,"h":15},
@ -1290,7 +1314,7 @@
},
"sprites/wires/sets/color_cross.png":
{
"frame": {"x":459,"y":615,"w":48,"h":48},
"frame": {"x":458,"y":715,"w":48,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
@ -1298,7 +1322,7 @@
},
"sprites/wires/sets/color_forward.png":
{
"frame": {"x":501,"y":719,"w":8,"h":48},
"frame": {"x":159,"y":520,"w":8,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":20,"y":0,"w":8,"h":48},
@ -1306,7 +1330,7 @@
},
"sprites/wires/sets/color_split.png":
{
"frame": {"x":3,"y":678,"w":48,"h":28},
"frame": {"x":55,"y":650,"w":48,"h":28},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":20,"w":48,"h":28},
@ -1322,7 +1346,7 @@
},
"sprites/wires/sets/conflict_cross.png":
{
"frame": {"x":372,"y":671,"w":48,"h":48},
"frame": {"x":449,"y":767,"w":48,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
@ -1330,7 +1354,7 @@
},
"sprites/wires/sets/conflict_forward.png":
{
"frame": {"x":436,"y":745,"w":8,"h":48},
"frame": {"x":159,"y":572,"w":8,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":20,"y":0,"w":8,"h":48},
@ -1338,7 +1362,7 @@
},
"sprites/wires/sets/conflict_split.png":
{
"frame": {"x":211,"y":611,"w":48,"h":28},
"frame": {"x":159,"y":671,"w":48,"h":28},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":20,"w":48,"h":28},
@ -1354,7 +1378,7 @@
},
"sprites/wires/sets/regular_cross.png":
{
"frame": {"x":373,"y":619,"w":48,"h":48},
"frame": {"x":459,"y":663,"w":48,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
@ -1362,7 +1386,7 @@
},
"sprites/wires/sets/regular_forward.png":
{
"frame": {"x":424,"y":698,"w":8,"h":48},
"frame": {"x":501,"y":767,"w":8,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":20,"y":0,"w":8,"h":48},
@ -1370,7 +1394,7 @@
},
"sprites/wires/sets/regular_split.png":
{
"frame": {"x":3,"y":646,"w":48,"h":28},
"frame": {"x":107,"y":646,"w":48,"h":28},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":20,"w":48,"h":28},
@ -1386,7 +1410,7 @@
},
"sprites/wires/sets/shape_cross.png":
{
"frame": {"x":458,"y":667,"w":48,"h":48},
"frame": {"x":3,"y":504,"w":48,"h":48},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":48,"h":48},
@ -1394,7 +1418,7 @@
},
"sprites/wires/sets/shape_forward.png":
{
"frame": {"x":500,"y":771,"w":8,"h":48},
"frame": {"x":423,"y":727,"w":8,"h":48},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":20,"y":0,"w":8,"h":48},
@ -1402,7 +1426,7 @@
},
"sprites/wires/sets/shape_split.png":
{
"frame": {"x":159,"y":617,"w":48,"h":28},
"frame": {"x":107,"y":678,"w":48,"h":28},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":20,"w":48,"h":28},
@ -1431,6 +1455,6 @@
"format": "RGBA8888",
"size": {"w":512,"h":1024},
"scale": "0.25",
"smartupdate": "$TexturePacker:SmartUpdate:1923b9c910205fb09957b67f92de02b9:0d87df06f18965307bf9d18b414f603d:908b89f5ca8ff73e331a35a3b14d0604$"
"smartupdate": "$TexturePacker:SmartUpdate:3b1717ceee14135311380de9706938d5:e834c7745e235246a53bcb721a2e3be3:908b89f5ca8ff73e331a35a3b14d0604$"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 269 KiB

After

Width:  |  Height:  |  Size: 272 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 653 KiB

After

Width:  |  Height:  |  Size: 659 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

@ -1,5 +1,5 @@
$buildings: belt, cutter, miner, mixer, painter, rotater, splitter, stacker, trash, underground_belt, wire,
constant_signal, logic_gate, lever, filter, wire_tunnel, display, virtual_processor;
constant_signal, logic_gate, lever, filter, wire_tunnel, display, virtual_processor, reader;
@each $building in $buildings {
[data-icon="building_icons/#{$building}.png"] {

View File

@ -18,6 +18,7 @@ export const CHANGELOG = [
"Updated and added new translations (Thanks to all contributors!)",
"Added setting to be able to delete buildings while placing (inspired by hexy)",
"Mark pinned shapes in statistics dialog and show them first (inspired by davidburhans)",
"Quad painters have been reworked! They now are integrated with the wires, and only paint the shape when the value is 1 (inspired by dengr1605)",
"There are now compact 1x1 splitters available to be unlocked!",
"Allow editing waypoints (by isaisstillalive)",
"Show confirmation when cutting area which is too expensive to get pasted again (by isaisstillalive)",

View File

@ -1,136 +1,136 @@
import { queryParamOptions } from "./query_parameters";
export const IS_DEBUG =
G_IS_DEV &&
typeof window !== "undefined" &&
window.location.port === "3005" &&
(window.location.host.indexOf("localhost:") >= 0 || window.location.host.indexOf("192.168.0.") >= 0) &&
window.location.search.indexOf("nodebug") < 0;
export const IS_DEMO = queryParamOptions.fullVersion
? false
: (!G_IS_DEV && !G_IS_STANDALONE) ||
(typeof window !== "undefined" && window.location.search.indexOf("demo") >= 0);
export const SUPPORT_TOUCH = false;
const smoothCanvas = true;
export const THIRDPARTY_URLS = {
discord: "https://discord.gg/HN7EVzV",
github: "https://github.com/tobspr/shapez.io",
reddit: "https://www.reddit.com/r/shapezio",
standaloneStorePage: "https://store.steampowered.com/app/1318690/shapezio/",
};
export const globalConfig = {
// Size of a single tile in Pixels.
// NOTICE: Update webpack.production.config too!
tileSize: 32,
halfTileSize: 16,
// Which dpi the assets have
assetsDpi: 192 / 32,
assetsSharpness: 1.5,
shapesSharpness: 1.4,
// Production analytics
statisticsGraphDpi: 2.5,
statisticsGraphSlices: 100,
analyticsSliceDurationSeconds: G_IS_DEV ? 1 : 10,
minimumTickRate: 25,
maximumTickRate: 500,
// Map
mapChunkSize: 16,
mapChunkOverviewMinZoom: 0.9,
mapChunkWorldSize: null, // COMPUTED
// Belt speeds
// NOTICE: Update webpack.production.config too!
beltSpeedItemsPerSecond: 2,
minerSpeedItemsPerSecond: 0, // COMPUTED
defaultItemDiameter: 20,
itemSpacingOnBelts: 0.63,
wiresSpeedItemsPerSecond: 6,
undergroundBeltMaxTilesByTier: [5, 8],
buildingSpeeds: {
cutter: 1 / 4,
cutterQuad: 1 / 4,
rotater: 1 / 1,
rotaterCCW: 1 / 1,
rotaterFL: 1 / 1,
painter: 1 / 6,
painterDouble: 1 / 8,
painterQuad: 1 / 8,
mixer: 1 / 5,
stacker: 1 / 6,
advancedProcessor: 1 / 3,
filter: 1,
},
// Zooming
initialZoom: 1.9,
minZoomLevel: 0.1,
maxZoomLevel: 3,
// Global game speed
gameSpeed: 1,
warmupTimeSecondsFast: 0.1,
warmupTimeSecondsRegular: 1,
smoothing: {
smoothMainCanvas: smoothCanvas && true,
quality: "low", // Low is CRUCIAL for mobile performance!
},
rendering: {},
debug: require("./config.local").default,
// Secret vars
info: {
// Binary file salt
file: "Ec'])@^+*9zMevK3uMV4432x9%iK'=",
// Savegame salt
sgSalt: "}95Q3%8/.837Lqym_BJx%q7)pAHJbF",
// Analytics key
analyticsApiKey: "baf6a50f0cc7dfdec5a0e21c88a1c69a4b34bc4a",
},
};
export const IS_MOBILE = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
// Automatic calculations
globalConfig.minerSpeedItemsPerSecond = globalConfig.beltSpeedItemsPerSecond / 5;
globalConfig.mapChunkWorldSize = globalConfig.mapChunkSize * globalConfig.tileSize;
// Dynamic calculations
if (globalConfig.debug.disableMapOverview) {
globalConfig.mapChunkOverviewMinZoom = 0;
}
// Stuff for making the trailer
if (G_IS_DEV && globalConfig.debug.renderForTrailer) {
globalConfig.debug.framePausesBetweenTicks = 32;
// globalConfig.mapChunkOverviewMinZoom = 0.0;
// globalConfig.debug.instantBelts = true;
// globalConfig.debug.instantProcessors = true;
// globalConfig.debug.instantMiners = true;
globalConfig.debug.disableSavegameWrite = true;
// globalConfig.beltSpeedItemsPerSecond *= 2;
}
if (globalConfig.debug.fastGameEnter) {
globalConfig.debug.noArtificalDelays = true;
}
import { queryParamOptions } from "./query_parameters";
export const IS_DEBUG =
G_IS_DEV &&
typeof window !== "undefined" &&
window.location.port === "3005" &&
(window.location.host.indexOf("localhost:") >= 0 || window.location.host.indexOf("192.168.0.") >= 0) &&
window.location.search.indexOf("nodebug") < 0;
export const IS_DEMO = queryParamOptions.fullVersion
? false
: (!G_IS_DEV && !G_IS_STANDALONE) ||
(typeof window !== "undefined" && window.location.search.indexOf("demo") >= 0);
export const SUPPORT_TOUCH = false;
const smoothCanvas = true;
export const THIRDPARTY_URLS = {
discord: "https://discord.gg/HN7EVzV",
github: "https://github.com/tobspr/shapez.io",
reddit: "https://www.reddit.com/r/shapezio",
standaloneStorePage: "https://store.steampowered.com/app/1318690/shapezio/",
};
export const globalConfig = {
// Size of a single tile in Pixels.
// NOTICE: Update webpack.production.config too!
tileSize: 32,
halfTileSize: 16,
// Which dpi the assets have
assetsDpi: 192 / 32,
assetsSharpness: 1.5,
shapesSharpness: 1.4,
// Production analytics
statisticsGraphDpi: 2.5,
statisticsGraphSlices: 100,
analyticsSliceDurationSeconds: G_IS_DEV ? 1 : 10,
minimumTickRate: 25,
maximumTickRate: 500,
// Map
mapChunkSize: 16,
mapChunkOverviewMinZoom: 0.9,
mapChunkWorldSize: null, // COMPUTED
// Belt speeds
// NOTICE: Update webpack.production.config too!
beltSpeedItemsPerSecond: 2,
minerSpeedItemsPerSecond: 0, // COMPUTED
defaultItemDiameter: 20,
itemSpacingOnBelts: 0.63,
wiresSpeedItemsPerSecond: 6,
undergroundBeltMaxTilesByTier: [5, 8],
readerAnalyzeIntervalSeconds: 10,
buildingSpeeds: {
cutter: 1 / 4,
cutterQuad: 1 / 4,
rotater: 1 / 1,
rotaterCCW: 1 / 1,
rotaterFL: 1 / 1,
painter: 1 / 6,
painterDouble: 1 / 8,
painterQuad: 1 / 8,
mixer: 1 / 5,
stacker: 1 / 6,
},
// Zooming
initialZoom: 1.9,
minZoomLevel: 0.1,
maxZoomLevel: 3,
// Global game speed
gameSpeed: 1,
warmupTimeSecondsFast: 0.1,
warmupTimeSecondsRegular: 1,
smoothing: {
smoothMainCanvas: smoothCanvas && true,
quality: "low", // Low is CRUCIAL for mobile performance!
},
rendering: {},
debug: require("./config.local").default,
// Secret vars
info: {
// Binary file salt
file: "Ec'])@^+*9zMevK3uMV4432x9%iK'=",
// Savegame salt
sgSalt: "}95Q3%8/.837Lqym_BJx%q7)pAHJbF",
// Analytics key
analyticsApiKey: "baf6a50f0cc7dfdec5a0e21c88a1c69a4b34bc4a",
},
};
export const IS_MOBILE = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
// Automatic calculations
globalConfig.minerSpeedItemsPerSecond = globalConfig.beltSpeedItemsPerSecond / 5;
globalConfig.mapChunkWorldSize = globalConfig.mapChunkSize * globalConfig.tileSize;
// Dynamic calculations
if (globalConfig.debug.disableMapOverview) {
globalConfig.mapChunkOverviewMinZoom = 0;
}
// Stuff for making the trailer
if (G_IS_DEV && globalConfig.debug.renderForTrailer) {
globalConfig.debug.framePausesBetweenTicks = 32;
// globalConfig.mapChunkOverviewMinZoom = 0.0;
// globalConfig.debug.instantBelts = true;
// globalConfig.debug.instantProcessors = true;
// globalConfig.debug.instantMiners = true;
globalConfig.debug.disableSavegameWrite = true;
// globalConfig.beltSpeedItemsPerSecond *= 2;
}
if (globalConfig.debug.fastGameEnter) {
globalConfig.debug.noArtificalDelays = true;
}

View File

@ -1,16 +1,15 @@
import { enumDirection, Vector } from "../../core/vector";
import { ItemAcceptorComponent } from "../components/item_acceptor";
import { ItemEjectorComponent } from "../components/item_ejector";
import {
enumItemProcessorRequirements,
enumItemProcessorTypes,
ItemProcessorComponent,
} from "../components/item_processor";
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() {

View File

@ -0,0 +1,101 @@
import { enumDirection, Vector } from "../../core/vector";
import { ItemAcceptorComponent } from "../components/item_acceptor";
import { ItemEjectorComponent } from "../components/item_ejector";
import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor";
import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins";
import { Entity } from "../entity";
import { MetaBuilding } from "../meta_building";
import { GameRoot } from "../root";
import { BeltUnderlaysComponent } from "../components/belt_underlays";
import { BeltReaderComponent } from "../components/belt_reader";
export class MetaReaderBuilding extends MetaBuilding {
constructor() {
super("reader");
}
getSilhouetteColor() {
return "#25fff2";
}
/**
* @param {GameRoot} root
*/
getIsUnlocked(root) {
// @todo
return true;
}
getDimensions() {
return new Vector(1, 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.right,
type: enumPinSlotType.logicalEjector,
},
{
pos: new Vector(0, 0),
direction: enumDirection.left,
type: enumPinSlotType.logicalEjector,
},
],
})
);
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,
},
],
})
);
entity.addComponent(
new ItemProcessorComponent({
processorType: enumItemProcessorTypes.reader,
inputsPerCharge: 1,
})
);
entity.addComponent(
new BeltUnderlaysComponent({
underlays: [
{
pos: new Vector(0, 0),
direction: enumDirection.top,
},
],
})
);
entity.addComponent(new BeltReaderComponent());
}
}

View File

@ -16,6 +16,7 @@ import { LogicGateComponent } from "./components/logic_gate";
import { LeverComponent } from "./components/lever";
import { WireTunnelComponent } from "./components/wire_tunnel";
import { DisplayComponent } from "./components/display";
import { BeltReaderComponent } from "./components/belt_reader";
export function initComponentRegistry() {
gComponentRegistry.register(StaticMapEntityComponent);
@ -35,6 +36,7 @@ export function initComponentRegistry() {
gComponentRegistry.register(LeverComponent);
gComponentRegistry.register(WireTunnelComponent);
gComponentRegistry.register(DisplayComponent);
gComponentRegistry.register(BeltReaderComponent);
// IMPORTANT ^^^^^ UPDATE ENTITY COMPONENT STORAGE AFTERWARDS

View File

@ -0,0 +1,40 @@
import { Component } from "../component";
import { BaseItem } from "../base_item";
export class BeltReaderComponent extends Component {
static getId() {
return "BeltReader";
}
duplicateWithoutContents() {
return new BeltReaderComponent();
}
constructor() {
super();
/**
* Which items went through the reader, we only store the time
* @type {Array<number>}
*/
this.lastItemTimes = [];
/**
* Which item passed the reader last
* @type {BaseItem}
*/
this.lastItem = null;
/**
* Stores the last throughput we computed
* @type {number}
*/
this.lastThroughput = 0;
/**
* Stores when we last computed the throughput
* @type {number}
*/
this.lastThroughputComputation = 0;
}
}

View File

@ -20,6 +20,7 @@ export const enumItemProcessorTypes = {
painterQuad: "painterQuad",
hub: "hub",
filter: "filter",
reader: "reader",
};
/** @enum {string} */

View File

@ -1,82 +1,86 @@
/* typehints:start */
import { BeltComponent } from "./components/belt";
import { BeltUnderlaysComponent } from "./components/belt_underlays";
import { HubComponent } from "./components/hub";
import { ItemAcceptorComponent } from "./components/item_acceptor";
import { ItemEjectorComponent } from "./components/item_ejector";
import { ItemProcessorComponent } from "./components/item_processor";
import { MinerComponent } from "./components/miner";
import { StaticMapEntityComponent } from "./components/static_map_entity";
import { StorageComponent } from "./components/storage";
import { UndergroundBeltComponent } from "./components/underground_belt";
import { WiredPinsComponent } from "./components/wired_pins";
import { WireComponent } from "./components/wire";
import { ConstantSignalComponent } from "./components/constant_signal";
import { LogicGateComponent } from "./components/logic_gate";
import { LeverComponent } from "./components/lever";
import { WireTunnelComponent } from "./components/wire_tunnel";
import { DisplayComponent } from "./components/display";
/* typehints:end */
/**
* Typedefs for all entity components. These are not actually present on the entity,
* thus they are undefined by default
*/
export class EntityComponentStorage {
constructor() {
/* typehints:start */
/** @type {StaticMapEntityComponent} */
this.StaticMapEntity;
/** @type {BeltComponent} */
this.Belt;
/** @type {ItemEjectorComponent} */
this.ItemEjector;
/** @type {ItemAcceptorComponent} */
this.ItemAcceptor;
/** @type {MinerComponent} */
this.Miner;
/** @type {ItemProcessorComponent} */
this.ItemProcessor;
/** @type {UndergroundBeltComponent} */
this.UndergroundBelt;
/** @type {HubComponent} */
this.Hub;
/** @type {StorageComponent} */
this.Storage;
/** @type {WiredPinsComponent} */
this.WiredPins;
/** @type {BeltUnderlaysComponent} */
this.BeltUnderlays;
/** @type {WireComponent} */
this.Wire;
/** @type {ConstantSignalComponent} */
this.ConstantSignal;
/** @type {LogicGateComponent} */
this.LogicGate;
/** @type {LeverComponent} */
this.Lever;
/** @type {WireTunnelComponent} */
this.WireTunnel;
/** @type {DisplayComponent} */
this.Display;
/* typehints:end */
}
}
/* typehints:start */
import { BeltComponent } from "./components/belt";
import { BeltUnderlaysComponent } from "./components/belt_underlays";
import { HubComponent } from "./components/hub";
import { ItemAcceptorComponent } from "./components/item_acceptor";
import { ItemEjectorComponent } from "./components/item_ejector";
import { ItemProcessorComponent } from "./components/item_processor";
import { MinerComponent } from "./components/miner";
import { StaticMapEntityComponent } from "./components/static_map_entity";
import { StorageComponent } from "./components/storage";
import { UndergroundBeltComponent } from "./components/underground_belt";
import { WiredPinsComponent } from "./components/wired_pins";
import { WireComponent } from "./components/wire";
import { ConstantSignalComponent } from "./components/constant_signal";
import { LogicGateComponent } from "./components/logic_gate";
import { LeverComponent } from "./components/lever";
import { WireTunnelComponent } from "./components/wire_tunnel";
import { DisplayComponent } from "./components/display";
import { BeltReaderComponent } from "./components/belt_reader";
/* typehints:end */
/**
* Typedefs for all entity components. These are not actually present on the entity,
* thus they are undefined by default
*/
export class EntityComponentStorage {
constructor() {
/* typehints:start */
/** @type {StaticMapEntityComponent} */
this.StaticMapEntity;
/** @type {BeltComponent} */
this.Belt;
/** @type {ItemEjectorComponent} */
this.ItemEjector;
/** @type {ItemAcceptorComponent} */
this.ItemAcceptor;
/** @type {MinerComponent} */
this.Miner;
/** @type {ItemProcessorComponent} */
this.ItemProcessor;
/** @type {UndergroundBeltComponent} */
this.UndergroundBelt;
/** @type {HubComponent} */
this.Hub;
/** @type {StorageComponent} */
this.Storage;
/** @type {WiredPinsComponent} */
this.WiredPins;
/** @type {BeltUnderlaysComponent} */
this.BeltUnderlays;
/** @type {WireComponent} */
this.Wire;
/** @type {ConstantSignalComponent} */
this.ConstantSignal;
/** @type {LogicGateComponent} */
this.LogicGate;
/** @type {LeverComponent} */
this.Lever;
/** @type {WireTunnelComponent} */
this.WireTunnel;
/** @type {DisplayComponent} */
this.Display;
/** @type {BeltReaderComponent} */
this.BeltReader;
/* typehints:end */
}
}

View File

@ -21,6 +21,7 @@ import { LogicGateSystem } from "./systems/logic_gate";
import { LeverSystem } from "./systems/lever";
import { DisplaySystem } from "./systems/display";
import { ItemProcessorOverlaysSystem } from "./systems/item_processor_overlays";
import { BeltReaderSystem } from "./systems/belt_reader";
const logger = createLogger("game_system_manager");
@ -88,6 +89,9 @@ export class GameSystemManager {
/** @type {ItemProcessorOverlaysSystem} */
itemProcessorOverlays: null,
/** @type {BeltReaderSystem} */
beltReader: null,
/* typehints:end */
};
this.systemUpdateOrder = [];
@ -141,6 +145,7 @@ export class GameSystemManager {
// 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);
add("beltReader", BeltReaderSystem);
// Wires must be after all gate, signal etc logic!
add("wire", WireSystem);

View File

@ -1,447 +1,448 @@
import { globalConfig } from "../core/config";
import { clamp, findNiceIntegerValue, randomChoice, randomInt } from "../core/utils";
import { BasicSerializableObject, types } from "../savegame/serialization";
import { enumColors } from "./colors";
import { enumItemProcessorTypes } from "./components/item_processor";
import { GameRoot } from "./root";
import { enumSubShape, ShapeDefinition } from "./shape_definition";
import { enumHubGoalRewards, tutorialGoals } from "./tutorial_goals";
import { UPGRADES } from "./upgrades";
export class HubGoals extends BasicSerializableObject {
static getId() {
return "HubGoals";
}
static getSchema() {
return {
level: types.uint,
storedShapes: types.keyValueMap(types.uint),
upgradeLevels: types.keyValueMap(types.uint),
currentGoal: types.structured({
definition: types.knownType(ShapeDefinition),
required: types.uint,
reward: types.nullable(types.enum(enumHubGoalRewards)),
}),
};
}
deserialize(data) {
const errorCode = super.deserialize(data);
if (errorCode) {
return errorCode;
}
// Compute gained rewards
for (let i = 0; i < this.level - 1; ++i) {
if (i < tutorialGoals.length) {
const reward = tutorialGoals[i].reward;
this.gainedRewards[reward] = (this.gainedRewards[reward] || 0) + 1;
}
}
// Compute upgrade improvements
for (const upgradeId in UPGRADES) {
const upgradeHandle = UPGRADES[upgradeId];
const level = this.upgradeLevels[upgradeId] || 0;
let totalImprovement = upgradeHandle.baseValue || 1;
for (let i = 0; i < level; ++i) {
totalImprovement += upgradeHandle.tiers[i].improvement;
}
this.upgradeImprovements[upgradeId] = totalImprovement;
}
// Compute current goal
const goal = tutorialGoals[this.level - 1];
if (goal) {
this.currentGoal = {
/** @type {ShapeDefinition} */
definition: this.root.shapeDefinitionMgr.getShapeFromShortKey(goal.shape),
required: goal.required,
reward: goal.reward,
};
}
}
/**
* @param {GameRoot} root
*/
constructor(root) {
super();
this.root = root;
this.level = 1;
/**
* Which story rewards we already gained
* @type {Object.<string, number>}
*/
this.gainedRewards = {};
/**
* Mapping from shape hash -> amount
* @type {Object<string, number>}
*/
this.storedShapes = {};
/**
* Stores the levels for all upgrades
* @type {Object<string, number>}
*/
this.upgradeLevels = {};
/**
* Stores the improvements for all upgrades
* @type {Object<string, number>}
*/
this.upgradeImprovements = {};
for (const key in UPGRADES) {
this.upgradeImprovements[key] = UPGRADES[key].baseValue || 1;
}
this.createNextGoal();
// Allow quickly switching goals in dev mode
if (G_IS_DEV) {
window.addEventListener("keydown", ev => {
if (ev.key === "b") {
// root is not guaranteed to exist within ~0.5s after loading in
if (this.root && this.root.app && this.root.app.gameAnalytics) {
this.onGoalCompleted();
}
}
});
}
}
/**
* Returns how much of the current shape is stored
* @param {ShapeDefinition} definition
* @returns {number}
*/
getShapesStored(definition) {
return this.storedShapes[definition.getHash()] || 0;
}
/**
* @param {string} key
* @param {number} amount
*/
takeShapeByKey(key, amount) {
assert(this.getShapesStoredByKey(key) >= amount, "Can not afford: " + key + " x " + amount);
assert(amount >= 0, "Amount < 0 for " + key);
assert(Number.isInteger(amount), "Invalid amount: " + amount);
this.storedShapes[key] = (this.storedShapes[key] || 0) - amount;
return;
}
/**
* Returns how much of the current shape is stored
* @param {string} key
* @returns {number}
*/
getShapesStoredByKey(key) {
return this.storedShapes[key] || 0;
}
/**
* Returns how much of the current goal was already delivered
*/
getCurrentGoalDelivered() {
return this.getShapesStored(this.currentGoal.definition);
}
/**
* Returns the current level of a given upgrade
* @param {string} upgradeId
*/
getUpgradeLevel(upgradeId) {
return this.upgradeLevels[upgradeId] || 0;
}
/**
* Returns whether the given reward is already unlocked
* @param {enumHubGoalRewards} reward
*/
isRewardUnlocked(reward) {
if (G_IS_DEV && globalConfig.debug.allBuildingsUnlocked) {
return true;
}
return !!this.gainedRewards[reward];
}
/**
* Handles the given definition, by either accounting it towards the
* goal or otherwise granting some points
* @param {ShapeDefinition} definition
*/
handleDefinitionDelivered(definition) {
const hash = definition.getHash();
this.storedShapes[hash] = (this.storedShapes[hash] || 0) + 1;
this.root.signals.shapeDelivered.dispatch(definition);
// Check if we have enough for the next level
const targetHash = this.currentGoal.definition.getHash();
if (
this.storedShapes[targetHash] >= this.currentGoal.required ||
(G_IS_DEV && globalConfig.debug.rewardsInstant)
) {
this.onGoalCompleted();
}
}
/**
* Creates the next goal
*/
createNextGoal() {
const storyIndex = this.level - 1;
if (storyIndex < tutorialGoals.length) {
const { shape, required, reward } = tutorialGoals[storyIndex];
this.currentGoal = {
/** @type {ShapeDefinition} */
definition: this.root.shapeDefinitionMgr.getShapeFromShortKey(shape),
required,
reward,
};
return;
}
this.currentGoal = {
/** @type {ShapeDefinition} */
definition: this.createRandomShape(),
required: 10000 + findNiceIntegerValue(this.level * 2000),
reward: enumHubGoalRewards.no_reward_freeplay,
};
}
/**
* Called when the level was completed
*/
onGoalCompleted() {
const reward = this.currentGoal.reward;
this.gainedRewards[reward] = (this.gainedRewards[reward] || 0) + 1;
this.root.app.gameAnalytics.handleLevelCompleted(this.level);
++this.level;
this.createNextGoal();
this.root.signals.storyGoalCompleted.dispatch(this.level - 1, reward);
}
/**
* Returns whether we are playing in free-play
*/
isFreePlay() {
return this.level >= tutorialGoals.length;
}
/**
* Returns whether a given upgrade can be unlocked
* @param {string} upgradeId
*/
canUnlockUpgrade(upgradeId) {
const handle = UPGRADES[upgradeId];
const currentLevel = this.getUpgradeLevel(upgradeId);
if (currentLevel >= handle.tiers.length) {
// Max level
return false;
}
if (G_IS_DEV && globalConfig.debug.upgradesNoCost) {
return true;
}
const tierData = handle.tiers[currentLevel];
for (let i = 0; i < tierData.required.length; ++i) {
const requirement = tierData.required[i];
if ((this.storedShapes[requirement.shape] || 0) < requirement.amount) {
return false;
}
}
return true;
}
/**
* Returns the number of available upgrades
* @returns {number}
*/
getAvailableUpgradeCount() {
let count = 0;
for (const upgradeId in UPGRADES) {
if (this.canUnlockUpgrade(upgradeId)) {
++count;
}
}
return count;
}
/**
* Tries to unlock the given upgrade
* @param {string} upgradeId
* @returns {boolean}
*/
tryUnlockUpgrade(upgradeId) {
if (!this.canUnlockUpgrade(upgradeId)) {
return false;
}
const handle = UPGRADES[upgradeId];
const currentLevel = this.getUpgradeLevel(upgradeId);
const tierData = handle.tiers[currentLevel];
if (!tierData) {
return false;
}
if (G_IS_DEV && globalConfig.debug.upgradesNoCost) {
// Dont take resources
} else {
for (let i = 0; i < tierData.required.length; ++i) {
const requirement = tierData.required[i];
// Notice: Don't have to check for hash here
this.storedShapes[requirement.shape] -= requirement.amount;
}
}
this.upgradeLevels[upgradeId] = (this.upgradeLevels[upgradeId] || 0) + 1;
this.upgradeImprovements[upgradeId] += tierData.improvement;
this.root.signals.upgradePurchased.dispatch(upgradeId);
this.root.app.gameAnalytics.handleUpgradeUnlocked(upgradeId, currentLevel);
return true;
}
/**
* @returns {ShapeDefinition}
*/
createRandomShape() {
const layerCount = clamp(this.level / 25, 2, 4);
/** @type {Array<import("./shape_definition").ShapeLayer>} */
let layers = [];
const randomColor = () => randomChoice(Object.values(enumColors));
const randomShape = () => randomChoice(Object.values(enumSubShape));
let anyIsMissingTwo = false;
for (let i = 0; i < layerCount; ++i) {
/** @type {import("./shape_definition").ShapeLayer} */
const layer = [null, null, null, null];
for (let quad = 0; quad < 4; ++quad) {
layer[quad] = {
subShape: randomShape(),
color: randomColor(),
};
}
// Sometimes shapes are missing
if (Math.random() > 0.85) {
layer[randomInt(0, 3)] = null;
}
// Sometimes they actually are missing *two* ones!
// Make sure at max only one layer is missing it though, otherwise we could
// create an uncreateable shape
if (Math.random() > 0.95 && !anyIsMissingTwo) {
layer[randomInt(0, 3)] = null;
anyIsMissingTwo = true;
}
layers.push(layer);
}
const definition = new ShapeDefinition({ layers });
return this.root.shapeDefinitionMgr.registerOrReturnHandle(definition);
}
////////////// HELPERS
/**
* Belt speed
* @returns {number} items / sec
*/
getBeltBaseSpeed() {
return globalConfig.beltSpeedItemsPerSecond * this.upgradeImprovements.belt;
}
/**
* Underground belt speed
* @returns {number} items / sec
*/
getUndergroundBeltBaseSpeed() {
return globalConfig.beltSpeedItemsPerSecond * this.upgradeImprovements.belt;
}
/**
* Miner speed
* @returns {number} items / sec
*/
getMinerBaseSpeed() {
return globalConfig.minerSpeedItemsPerSecond * this.upgradeImprovements.miner;
}
/**
* Processor speed
* @param {enumItemProcessorTypes} processorType
* @returns {number} items / sec
*/
getProcessorBaseSpeed(processorType) {
switch (processorType) {
case enumItemProcessorTypes.splitterWires:
return globalConfig.wiresSpeedItemsPerSecond * 2;
case enumItemProcessorTypes.trash:
case enumItemProcessorTypes.hub:
return 1e30;
case enumItemProcessorTypes.splitter:
return globalConfig.beltSpeedItemsPerSecond * this.upgradeImprovements.belt * 2;
case enumItemProcessorTypes.filter:
return globalConfig.beltSpeedItemsPerSecond * this.upgradeImprovements.belt;
case enumItemProcessorTypes.mixer:
case enumItemProcessorTypes.painter:
case enumItemProcessorTypes.painterDouble:
case enumItemProcessorTypes.painterQuad: {
assert(
globalConfig.buildingSpeeds[processorType],
"Processor type has no speed set in globalConfig.buildingSpeeds: " + processorType
);
return (
globalConfig.beltSpeedItemsPerSecond *
this.upgradeImprovements.painting *
globalConfig.buildingSpeeds[processorType]
);
}
case enumItemProcessorTypes.cutter:
case enumItemProcessorTypes.cutterQuad:
case enumItemProcessorTypes.rotater:
case enumItemProcessorTypes.rotaterCCW:
case enumItemProcessorTypes.rotaterFL:
case enumItemProcessorTypes.stacker: {
assert(
globalConfig.buildingSpeeds[processorType],
"Processor type has no speed set in globalConfig.buildingSpeeds: " + processorType
);
return (
globalConfig.beltSpeedItemsPerSecond *
this.upgradeImprovements.processors *
globalConfig.buildingSpeeds[processorType]
);
}
default:
assertAlways(false, "invalid processor type: " + processorType);
}
return 1 / globalConfig.beltSpeedItemsPerSecond;
}
}
import { globalConfig } from "../core/config";
import { clamp, findNiceIntegerValue, randomChoice, randomInt } from "../core/utils";
import { BasicSerializableObject, types } from "../savegame/serialization";
import { enumColors } from "./colors";
import { enumItemProcessorTypes } from "./components/item_processor";
import { GameRoot } from "./root";
import { enumSubShape, ShapeDefinition } from "./shape_definition";
import { enumHubGoalRewards, tutorialGoals } from "./tutorial_goals";
import { UPGRADES } from "./upgrades";
export class HubGoals extends BasicSerializableObject {
static getId() {
return "HubGoals";
}
static getSchema() {
return {
level: types.uint,
storedShapes: types.keyValueMap(types.uint),
upgradeLevels: types.keyValueMap(types.uint),
currentGoal: types.structured({
definition: types.knownType(ShapeDefinition),
required: types.uint,
reward: types.nullable(types.enum(enumHubGoalRewards)),
}),
};
}
deserialize(data) {
const errorCode = super.deserialize(data);
if (errorCode) {
return errorCode;
}
// Compute gained rewards
for (let i = 0; i < this.level - 1; ++i) {
if (i < tutorialGoals.length) {
const reward = tutorialGoals[i].reward;
this.gainedRewards[reward] = (this.gainedRewards[reward] || 0) + 1;
}
}
// Compute upgrade improvements
for (const upgradeId in UPGRADES) {
const upgradeHandle = UPGRADES[upgradeId];
const level = this.upgradeLevels[upgradeId] || 0;
let totalImprovement = upgradeHandle.baseValue || 1;
for (let i = 0; i < level; ++i) {
totalImprovement += upgradeHandle.tiers[i].improvement;
}
this.upgradeImprovements[upgradeId] = totalImprovement;
}
// Compute current goal
const goal = tutorialGoals[this.level - 1];
if (goal) {
this.currentGoal = {
/** @type {ShapeDefinition} */
definition: this.root.shapeDefinitionMgr.getShapeFromShortKey(goal.shape),
required: goal.required,
reward: goal.reward,
};
}
}
/**
* @param {GameRoot} root
*/
constructor(root) {
super();
this.root = root;
this.level = 1;
/**
* Which story rewards we already gained
* @type {Object.<string, number>}
*/
this.gainedRewards = {};
/**
* Mapping from shape hash -> amount
* @type {Object<string, number>}
*/
this.storedShapes = {};
/**
* Stores the levels for all upgrades
* @type {Object<string, number>}
*/
this.upgradeLevels = {};
/**
* Stores the improvements for all upgrades
* @type {Object<string, number>}
*/
this.upgradeImprovements = {};
for (const key in UPGRADES) {
this.upgradeImprovements[key] = UPGRADES[key].baseValue || 1;
}
this.createNextGoal();
// Allow quickly switching goals in dev mode
if (G_IS_DEV) {
window.addEventListener("keydown", ev => {
if (ev.key === "b") {
// root is not guaranteed to exist within ~0.5s after loading in
if (this.root && this.root.app && this.root.app.gameAnalytics) {
this.onGoalCompleted();
}
}
});
}
}
/**
* Returns how much of the current shape is stored
* @param {ShapeDefinition} definition
* @returns {number}
*/
getShapesStored(definition) {
return this.storedShapes[definition.getHash()] || 0;
}
/**
* @param {string} key
* @param {number} amount
*/
takeShapeByKey(key, amount) {
assert(this.getShapesStoredByKey(key) >= amount, "Can not afford: " + key + " x " + amount);
assert(amount >= 0, "Amount < 0 for " + key);
assert(Number.isInteger(amount), "Invalid amount: " + amount);
this.storedShapes[key] = (this.storedShapes[key] || 0) - amount;
return;
}
/**
* Returns how much of the current shape is stored
* @param {string} key
* @returns {number}
*/
getShapesStoredByKey(key) {
return this.storedShapes[key] || 0;
}
/**
* Returns how much of the current goal was already delivered
*/
getCurrentGoalDelivered() {
return this.getShapesStored(this.currentGoal.definition);
}
/**
* Returns the current level of a given upgrade
* @param {string} upgradeId
*/
getUpgradeLevel(upgradeId) {
return this.upgradeLevels[upgradeId] || 0;
}
/**
* Returns whether the given reward is already unlocked
* @param {enumHubGoalRewards} reward
*/
isRewardUnlocked(reward) {
if (G_IS_DEV && globalConfig.debug.allBuildingsUnlocked) {
return true;
}
return !!this.gainedRewards[reward];
}
/**
* Handles the given definition, by either accounting it towards the
* goal or otherwise granting some points
* @param {ShapeDefinition} definition
*/
handleDefinitionDelivered(definition) {
const hash = definition.getHash();
this.storedShapes[hash] = (this.storedShapes[hash] || 0) + 1;
this.root.signals.shapeDelivered.dispatch(definition);
// Check if we have enough for the next level
const targetHash = this.currentGoal.definition.getHash();
if (
this.storedShapes[targetHash] >= this.currentGoal.required ||
(G_IS_DEV && globalConfig.debug.rewardsInstant)
) {
this.onGoalCompleted();
}
}
/**
* Creates the next goal
*/
createNextGoal() {
const storyIndex = this.level - 1;
if (storyIndex < tutorialGoals.length) {
const { shape, required, reward } = tutorialGoals[storyIndex];
this.currentGoal = {
/** @type {ShapeDefinition} */
definition: this.root.shapeDefinitionMgr.getShapeFromShortKey(shape),
required,
reward,
};
return;
}
this.currentGoal = {
/** @type {ShapeDefinition} */
definition: this.createRandomShape(),
required: 10000 + findNiceIntegerValue(this.level * 2000),
reward: enumHubGoalRewards.no_reward_freeplay,
};
}
/**
* Called when the level was completed
*/
onGoalCompleted() {
const reward = this.currentGoal.reward;
this.gainedRewards[reward] = (this.gainedRewards[reward] || 0) + 1;
this.root.app.gameAnalytics.handleLevelCompleted(this.level);
++this.level;
this.createNextGoal();
this.root.signals.storyGoalCompleted.dispatch(this.level - 1, reward);
}
/**
* Returns whether we are playing in free-play
*/
isFreePlay() {
return this.level >= tutorialGoals.length;
}
/**
* Returns whether a given upgrade can be unlocked
* @param {string} upgradeId
*/
canUnlockUpgrade(upgradeId) {
const handle = UPGRADES[upgradeId];
const currentLevel = this.getUpgradeLevel(upgradeId);
if (currentLevel >= handle.tiers.length) {
// Max level
return false;
}
if (G_IS_DEV && globalConfig.debug.upgradesNoCost) {
return true;
}
const tierData = handle.tiers[currentLevel];
for (let i = 0; i < tierData.required.length; ++i) {
const requirement = tierData.required[i];
if ((this.storedShapes[requirement.shape] || 0) < requirement.amount) {
return false;
}
}
return true;
}
/**
* Returns the number of available upgrades
* @returns {number}
*/
getAvailableUpgradeCount() {
let count = 0;
for (const upgradeId in UPGRADES) {
if (this.canUnlockUpgrade(upgradeId)) {
++count;
}
}
return count;
}
/**
* Tries to unlock the given upgrade
* @param {string} upgradeId
* @returns {boolean}
*/
tryUnlockUpgrade(upgradeId) {
if (!this.canUnlockUpgrade(upgradeId)) {
return false;
}
const handle = UPGRADES[upgradeId];
const currentLevel = this.getUpgradeLevel(upgradeId);
const tierData = handle.tiers[currentLevel];
if (!tierData) {
return false;
}
if (G_IS_DEV && globalConfig.debug.upgradesNoCost) {
// Dont take resources
} else {
for (let i = 0; i < tierData.required.length; ++i) {
const requirement = tierData.required[i];
// Notice: Don't have to check for hash here
this.storedShapes[requirement.shape] -= requirement.amount;
}
}
this.upgradeLevels[upgradeId] = (this.upgradeLevels[upgradeId] || 0) + 1;
this.upgradeImprovements[upgradeId] += tierData.improvement;
this.root.signals.upgradePurchased.dispatch(upgradeId);
this.root.app.gameAnalytics.handleUpgradeUnlocked(upgradeId, currentLevel);
return true;
}
/**
* @returns {ShapeDefinition}
*/
createRandomShape() {
const layerCount = clamp(this.level / 25, 2, 4);
/** @type {Array<import("./shape_definition").ShapeLayer>} */
let layers = [];
const randomColor = () => randomChoice(Object.values(enumColors));
const randomShape = () => randomChoice(Object.values(enumSubShape));
let anyIsMissingTwo = false;
for (let i = 0; i < layerCount; ++i) {
/** @type {import("./shape_definition").ShapeLayer} */
const layer = [null, null, null, null];
for (let quad = 0; quad < 4; ++quad) {
layer[quad] = {
subShape: randomShape(),
color: randomColor(),
};
}
// Sometimes shapes are missing
if (Math.random() > 0.85) {
layer[randomInt(0, 3)] = null;
}
// Sometimes they actually are missing *two* ones!
// Make sure at max only one layer is missing it though, otherwise we could
// create an uncreateable shape
if (Math.random() > 0.95 && !anyIsMissingTwo) {
layer[randomInt(0, 3)] = null;
anyIsMissingTwo = true;
}
layers.push(layer);
}
const definition = new ShapeDefinition({ layers });
return this.root.shapeDefinitionMgr.registerOrReturnHandle(definition);
}
////////////// HELPERS
/**
* Belt speed
* @returns {number} items / sec
*/
getBeltBaseSpeed() {
return globalConfig.beltSpeedItemsPerSecond * this.upgradeImprovements.belt;
}
/**
* Underground belt speed
* @returns {number} items / sec
*/
getUndergroundBeltBaseSpeed() {
return globalConfig.beltSpeedItemsPerSecond * this.upgradeImprovements.belt;
}
/**
* Miner speed
* @returns {number} items / sec
*/
getMinerBaseSpeed() {
return globalConfig.minerSpeedItemsPerSecond * this.upgradeImprovements.miner;
}
/**
* Processor speed
* @param {enumItemProcessorTypes} processorType
* @returns {number} items / sec
*/
getProcessorBaseSpeed(processorType) {
switch (processorType) {
case enumItemProcessorTypes.splitterWires:
return globalConfig.wiresSpeedItemsPerSecond * 2;
case enumItemProcessorTypes.trash:
case enumItemProcessorTypes.hub:
return 1e30;
case enumItemProcessorTypes.splitter:
return globalConfig.beltSpeedItemsPerSecond * this.upgradeImprovements.belt * 2;
case enumItemProcessorTypes.filter:
case enumItemProcessorTypes.reader:
return globalConfig.beltSpeedItemsPerSecond * this.upgradeImprovements.belt;
case enumItemProcessorTypes.mixer:
case enumItemProcessorTypes.painter:
case enumItemProcessorTypes.painterDouble:
case enumItemProcessorTypes.painterQuad: {
assert(
globalConfig.buildingSpeeds[processorType],
"Processor type has no speed set in globalConfig.buildingSpeeds: " + processorType
);
return (
globalConfig.beltSpeedItemsPerSecond *
this.upgradeImprovements.painting *
globalConfig.buildingSpeeds[processorType]
);
}
case enumItemProcessorTypes.cutter:
case enumItemProcessorTypes.cutterQuad:
case enumItemProcessorTypes.rotater:
case enumItemProcessorTypes.rotaterCCW:
case enumItemProcessorTypes.rotaterFL:
case enumItemProcessorTypes.stacker: {
assert(
globalConfig.buildingSpeeds[processorType],
"Processor type has no speed set in globalConfig.buildingSpeeds: " + processorType
);
return (
globalConfig.beltSpeedItemsPerSecond *
this.upgradeImprovements.processors *
globalConfig.buildingSpeeds[processorType]
);
}
default:
assertAlways(false, "invalid processor type: " + processorType);
}
return 1 / globalConfig.beltSpeedItemsPerSecond;
}
}

View File

@ -1,41 +1,43 @@
import { MetaBeltBaseBuilding } from "../../buildings/belt_base";
import { MetaCutterBuilding } from "../../buildings/cutter";
import { MetaMinerBuilding } from "../../buildings/miner";
import { MetaMixerBuilding } from "../../buildings/mixer";
import { MetaPainterBuilding } from "../../buildings/painter";
import { MetaRotaterBuilding } from "../../buildings/rotater";
import { MetaSplitterBuilding } from "../../buildings/splitter";
import { MetaStackerBuilding } from "../../buildings/stacker";
import { MetaTrashBuilding } from "../../buildings/trash";
import { MetaUndergroundBeltBuilding } from "../../buildings/underground_belt";
import { HUDBaseToolbar } from "./base_toolbar";
import { MetaLeverBuilding } from "../../buildings/lever";
import { MetaFilterBuilding } from "../../buildings/filter";
import { MetaDisplayBuilding } from "../../buildings/display";
const supportedBuildings = [
MetaBeltBaseBuilding,
MetaSplitterBuilding,
MetaUndergroundBeltBuilding,
MetaMinerBuilding,
MetaCutterBuilding,
MetaRotaterBuilding,
MetaStackerBuilding,
MetaMixerBuilding,
MetaPainterBuilding,
MetaTrashBuilding,
MetaLeverBuilding,
MetaFilterBuilding,
MetaDisplayBuilding,
];
export class HUDBuildingsToolbar extends HUDBaseToolbar {
constructor(root) {
super(root, {
supportedBuildings,
visibilityCondition: () =>
!this.root.camera.getIsMapOverlayActive() && this.root.currentLayer === "regular",
htmlElementId: "ingame_HUD_buildings_toolbar",
});
}
}
import { MetaBeltBaseBuilding } from "../../buildings/belt_base";
import { MetaCutterBuilding } from "../../buildings/cutter";
import { MetaMinerBuilding } from "../../buildings/miner";
import { MetaMixerBuilding } from "../../buildings/mixer";
import { MetaPainterBuilding } from "../../buildings/painter";
import { MetaRotaterBuilding } from "../../buildings/rotater";
import { MetaSplitterBuilding } from "../../buildings/splitter";
import { MetaStackerBuilding } from "../../buildings/stacker";
import { MetaTrashBuilding } from "../../buildings/trash";
import { MetaUndergroundBeltBuilding } from "../../buildings/underground_belt";
import { HUDBaseToolbar } from "./base_toolbar";
import { MetaLeverBuilding } from "../../buildings/lever";
import { MetaFilterBuilding } from "../../buildings/filter";
import { MetaDisplayBuilding } from "../../buildings/display";
import { MetaReaderBuilding } from "../../buildings/reader";
const supportedBuildings = [
MetaBeltBaseBuilding,
MetaSplitterBuilding,
MetaUndergroundBeltBuilding,
MetaMinerBuilding,
MetaCutterBuilding,
MetaRotaterBuilding,
MetaStackerBuilding,
MetaMixerBuilding,
MetaPainterBuilding,
MetaTrashBuilding,
MetaLeverBuilding,
MetaFilterBuilding,
MetaDisplayBuilding,
MetaReaderBuilding,
];
export class HUDBuildingsToolbar extends HUDBaseToolbar {
constructor(root) {
super(root, {
supportedBuildings,
visibilityCondition: () =>
!this.root.camera.getIsMapOverlayActive() && this.root.currentLayer === "regular",
htmlElementId: "ingame_HUD_buildings_toolbar",
});
}
}

View File

@ -58,6 +58,7 @@ export const KEYMAPPINGS = {
lever: { keyCode: key("L") },
filter: { keyCode: key("B") },
display: { keyCode: key("N") },
reader: { keyCode: key("J") },
wire: { keyCode: key("1") },
wire_tunnel: { keyCode: key("2") },

View File

@ -22,6 +22,7 @@ import { MetaFilterBuilding } from "./buildings/filter";
import { MetaWireTunnelBuilding, enumWireTunnelVariants } from "./buildings/wire_tunnel";
import { MetaDisplayBuilding } from "./buildings/display";
import { MetaVirtualProcessorBuilding, enumVirtualProcessorVariants } from "./buildings/virtual_processor";
import { MetaReaderBuilding } from "./buildings/reader";
const logger = createLogger("building_registry");
@ -45,6 +46,7 @@ export function initMetaBuildingRegistry() {
gMetaBuildingRegistry.register(MetaWireTunnelBuilding);
gMetaBuildingRegistry.register(MetaDisplayBuilding);
gMetaBuildingRegistry.register(MetaVirtualProcessorBuilding);
gMetaBuildingRegistry.register(MetaReaderBuilding);
// Belt
registerBuildingVariant(1, MetaBeltBaseBuilding, defaultBuildingVariant, 0);
@ -132,6 +134,9 @@ export function initMetaBuildingRegistry() {
registerBuildingVariant(45, MetaVirtualProcessorBuilding, enumVirtualProcessorVariants.unstacker);
registerBuildingVariant(46, MetaVirtualProcessorBuilding, enumVirtualProcessorVariants.shapecompare);
// Reader
registerBuildingVariant(49, MetaReaderBuilding);
// Propagate instances
for (const key in gBuildingVariants) {
gBuildingVariants[key].metaInstance = gMetaBuildingRegistry.findByClass(

View File

@ -0,0 +1,40 @@
import { GameSystemWithFilter } from "../game_system_with_filter";
import { BeltReaderComponent } from "../components/belt_reader";
import { globalConfig } from "../../core/config";
import { BOOL_TRUE_SINGLETON, BOOL_FALSE_SINGLETON } from "../items/boolean_item";
export class BeltReaderSystem extends GameSystemWithFilter {
constructor(root) {
super(root, [BeltReaderComponent]);
}
update() {
const now = this.root.time.now();
const minimumTime = now - globalConfig.readerAnalyzeIntervalSeconds;
const minimumTimeForThroughput = now - 1;
for (let i = 0; i < this.allEntities.length; ++i) {
const entity = this.allEntities[i];
const readerComp = entity.components.BeltReader;
const pinsComp = entity.components.WiredPins;
// Remove outdated items
while (readerComp.lastItemTimes[0] < minimumTime) {
readerComp.lastItemTimes.shift();
}
pinsComp.slots[1].value = readerComp.lastItem;
pinsComp.slots[0].value =
(readerComp.lastItemTimes[readerComp.lastItemTimes.length - 1] || 0) >
minimumTimeForThroughput
? BOOL_TRUE_SINGLETON
: BOOL_FALSE_SINGLETON;
if (now - readerComp.lastThroughputComputation > 0.5) {
readerComp.lastThroughputComputation = now;
readerComp.lastThroughput =
readerComp.lastItemTimes.length / globalConfig.readerAnalyzeIntervalSeconds;
}
}
}
}

View File

@ -8,7 +8,7 @@ import {
} from "../components/item_processor";
import { Entity } from "../entity";
import { GameSystemWithFilter } from "../game_system_with_filter";
import { BOOL_TRUE_SINGLETON, isTrueItem } from "../items/boolean_item";
import { BOOL_TRUE_SINGLETON, isTrueItem, BooleanItem } from "../items/boolean_item";
import { ColorItem, COLOR_ITEM_SINGLETONS } from "../items/color_item";
import { ShapeItem } from "../items/shape_item";
@ -506,8 +506,20 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
break;
}
// HUB
// READER
case enumItemProcessorTypes.reader: {
// Pass through the item
const item = itemsBySlot[0].item;
outItems.push({ item });
// Track the item
const readerComp = entity.components.BeltReader;
readerComp.lastItemTimes.push(this.root.time.now());
readerComp.lastItem = item;
break;
}
// HUB
case enumItemProcessorTypes.hub: {
trackProduction = false;

View File

@ -1,11 +1,11 @@
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";
import { enumItemProcessorRequirements, enumItemProcessorTypes } from "../components/item_processor";
import { Entity } from "../entity";
import { GameSystem } from "../game_system";
import { isTrueItem } from "../items/boolean_item";
import { MapChunkView } from "../map_chunk_view";
export class ItemProcessorOverlaysSystem extends GameSystem {
constructor(root) {
@ -14,6 +14,8 @@ export class ItemProcessorOverlaysSystem extends GameSystem {
this.spriteDisabled = Loader.getSprite("sprites/misc/processor_disabled.png");
this.spriteDisconnected = Loader.getSprite("sprites/misc/processor_disconnected.png");
this.readerOverlaySprite = Loader.getSprite("sprites/misc/reader_overlay.png");
this.drawnUids = new Set();
this.root.signals.gameFrameStarted.add(this.clearDrawnUids, this);
@ -38,7 +40,8 @@ export class ItemProcessorOverlaysSystem extends GameSystem {
}
const requirement = processorComp.processingRequirement;
if (!requirement) {
if (!requirement && processorComp.type !== enumItemProcessorTypes.reader) {
continue;
}
@ -58,9 +61,41 @@ export class ItemProcessorOverlaysSystem extends GameSystem {
break;
}
}
if (processorComp.type === enumItemProcessorTypes.reader) {
this.drawReaderOverlays(parameters, entity);
}
}
}
/**
*
* @param {import("../../core/draw_utils").DrawParameters} parameters
* @param {Entity} entity
*/
drawReaderOverlays(parameters, entity) {
const staticComp = entity.components.StaticMapEntity;
const readerComp = entity.components.BeltReader;
this.readerOverlaySprite.drawCachedCentered(
parameters,
(staticComp.origin.x + 0.5) * globalConfig.tileSize,
(staticComp.origin.y + 0.5) * globalConfig.tileSize,
globalConfig.tileSize
);
parameters.context.fillStyle = "#333439";
parameters.context.textAlign = "center";
parameters.context.font = "bold 10px GameFont";
parameters.context.fillText(
"" + Math.round(readerComp.lastThroughput * 10) / 10,
(staticComp.origin.x + 0.5) * globalConfig.tileSize,
(staticComp.origin.y + 0.62) * globalConfig.tileSize
);
parameters.context.textAlign = "left";
}
/**
*
* @param {import("../../core/draw_utils").DrawParameters} parameters

View File

@ -604,6 +604,12 @@ buildings:
# TEMP
description: Can be connected on the wires layer to show a color or shape. When inputting a boolean item, the display will be white if the value is 1.
reader:
default:
name: &reader Belt Reader
# TEMP
description: Allows to read the current item from a belt, as well as measuring the throughput.
virtual_processor:
default:
name: &virtual_processor Virtual Cutter
@ -921,6 +927,7 @@ keybindings:
filter: *filter
wire_tunnel: *wire_tunnel
display: *display
reader: *reader
# ---
pipette: Pipette