diff --git a/res_built/atlas/atlas0_hq.json b/res_built/atlas/atlas0_hq.json index 9edcc70f..23e86df2 100644 --- a/res_built/atlas/atlas0_hq.json +++ b/res_built/atlas/atlas0_hq.json @@ -2,7 +2,7 @@ "sprites/belt/built/forward_0.png": { - "frame": {"x":440,"y":742,"w":116,"h":144}, + "frame": {"x":969,"y":1181,"w":116,"h":144}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":14,"y":0,"w":116,"h":144}, @@ -10,7 +10,7 @@ }, "sprites/belt/built/forward_1.png": { - "frame": {"x":1815,"y":1070,"w":116,"h":144}, + "frame": {"x":1490,"y":1317,"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":1804,"y":1366,"w":116,"h":144}, + "frame": {"x":266,"y":1588,"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":1924,"y":1405,"w":116,"h":144}, + "frame": {"x":386,"y":1588,"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":439,"y":1038,"w":116,"h":144}, + "frame": {"x":627,"y":1472,"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":1801,"y":1514,"w":116,"h":144}, + "frame": {"x":932,"y":1329,"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":1921,"y":1553,"w":116,"h":144}, + "frame": {"x":1052,"y":1329,"w":116,"h":144}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":14,"y":0,"w":116,"h":144}, @@ -58,7 +58,7 @@ }, "sprites/belt/built/forward_7.png": { - "frame": {"x":1801,"y":1662,"w":116,"h":144}, + "frame": {"x":1172,"y":1329,"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":1921,"y":1701,"w":116,"h":144}, + "frame": {"x":1292,"y":1329,"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":137,"y":1849,"w":116,"h":144}, + "frame": {"x":1555,"y":1465,"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":1539,"y":1139,"w":116,"h":144}, + "frame": {"x":812,"y":1329,"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":1538,"y":1287,"w":116,"h":144}, + "frame": {"x":507,"y":1472,"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":1806,"y":1218,"w":116,"h":144}, + "frame": {"x":146,"y":1588,"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":1926,"y":1257,"w":116,"h":144}, + "frame": {"x":3,"y":1730,"w":116,"h":144}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":14,"y":0,"w":116,"h":144}, @@ -114,7 +114,7 @@ }, "sprites/belt/built/left_0.png": { - "frame": {"x":3,"y":1182,"w":130,"h":130}, + "frame": {"x":1909,"y":3,"w":130,"h":130}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":14,"w":130,"h":130}, @@ -122,7 +122,7 @@ }, "sprites/belt/built/left_1.png": { - "frame": {"x":137,"y":1182,"w":130,"h":130}, + "frame": {"x":405,"y":1767,"w":130,"h":130}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":14,"w":130,"h":130}, @@ -130,7 +130,7 @@ }, "sprites/belt/built/left_2.png": { - "frame": {"x":283,"y":1703,"w":130,"h":130}, + "frame": {"x":1755,"y":1216,"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":389,"y":1849,"w":130,"h":130}, + "frame": {"x":1675,"y":1478,"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":417,"y":1703,"w":130,"h":130}, + "frame": {"x":1687,"y":1612,"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":523,"y":1849,"w":130,"h":130}, + "frame": {"x":1809,"y":1478,"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":551,"y":1703,"w":130,"h":130}, + "frame": {"x":1438,"y":1738,"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":657,"y":1849,"w":130,"h":130}, + "frame": {"x":1170,"y":1741,"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":791,"y":1408,"w":130,"h":130}, + "frame": {"x":908,"y":1755,"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":685,"y":1703,"w":130,"h":130}, + "frame": {"x":759,"y":1863,"w":130,"h":130}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":14,"w":130,"h":130}, @@ -194,7 +194,7 @@ }, "sprites/belt/built/left_10.png": { - "frame": {"x":425,"y":1186,"w":130,"h":130}, + "frame": {"x":263,"y":1882,"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":425,"y":1320,"w":130,"h":130}, + "frame": {"x":1170,"y":1607,"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":424,"y":1454,"w":130,"h":130}, + "frame": {"x":1304,"y":1607,"w":130,"h":130}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":14,"w":130,"h":130}, @@ -218,7 +218,7 @@ }, "sprites/belt/built/left_13.png": { - "frame": {"x":144,"y":1465,"w":130,"h":130}, + "frame": {"x":1755,"y":1082,"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":925,"y":1476,"w":130,"h":130}, + "frame": {"x":539,"y":1891,"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":565,"y":1542,"w":130,"h":130}, + "frame": {"x":397,"y":1901,"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":1461,"y":1703,"w":130,"h":130}, + "frame": {"x":1821,"y":1612,"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":791,"y":1849,"w":130,"h":130}, + "frame": {"x":1572,"y":1746,"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":925,"y":1610,"w":130,"h":130}, + "frame": {"x":1438,"y":1872,"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":1059,"y":1740,"w":130,"h":130}, + "frame": {"x":1706,"y":1746,"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":1193,"y":1805,"w":130,"h":130}, + "frame": {"x":1840,"y":1746,"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":1327,"y":1827,"w":130,"h":130}, + "frame": {"x":1042,"y":1875,"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":925,"y":1744,"w":130,"h":130}, + "frame": {"x":893,"y":1889,"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":1059,"y":1874,"w":130,"h":130}, + "frame": {"x":1176,"y":1875,"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":699,"y":1542,"w":130,"h":130}, + "frame": {"x":1304,"y":1741,"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":1059,"y":1606,"w":130,"h":130}, + "frame": {"x":1889,"y":1082,"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":1193,"y":1671,"w":130,"h":130}, + "frame": {"x":1893,"y":937,"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":1327,"y":1693,"w":130,"h":130}, + "frame": {"x":1889,"y":1216,"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":925,"y":1878,"w":130,"h":130}, + "frame": {"x":1572,"y":1880,"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":1461,"y":1849,"w":130,"h":130}, + "frame": {"x":1706,"y":1880,"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":3,"y":1318,"w":116,"h":144}, + "frame": {"x":1816,"y":660,"w":116,"h":144}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":14,"y":0,"w":116,"h":144}, @@ -362,7 +362,7 @@ }, "sprites/blueprints/constant_signal.png": { - "frame": {"x":1938,"y":847,"w":105,"h":127}, + "frame": {"x":778,"y":1593,"w":105,"h":127}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":20,"y":0,"w":105,"h":127}, @@ -370,7 +370,7 @@ }, "sprites/blueprints/cutter-quad.png": { - "frame": {"x":3,"y":151,"w":548,"h":144}, + "frame": {"x":555,"y":151,"w":548,"h":144}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":17,"y":0,"w":548,"h":144}, @@ -378,7 +378,7 @@ }, "sprites/blueprints/cutter.png": { - "frame": {"x":847,"y":298,"w":256,"h":144}, + "frame": {"x":547,"y":1028,"w":256,"h":144}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":17,"y":0,"w":256,"h":144}, @@ -386,7 +386,7 @@ }, "sprites/blueprints/display.png": { - "frame": {"x":257,"y":1849,"w":128,"h":136}, + "frame": {"x":646,"y":1620,"w":128,"h":136}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":8,"y":8,"w":128,"h":136}, @@ -394,7 +394,7 @@ }, "sprites/blueprints/filter.png": { - "frame": {"x":1107,"y":556,"w":268,"h":144}, + "frame": {"x":839,"y":738,"w":268,"h":144}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":16,"y":0,"w":268,"h":144}, @@ -402,7 +402,7 @@ }, "sprites/blueprints/lever.png": { - "frame": {"x":1823,"y":732,"w":111,"h":129}, + "frame": {"x":3,"y":1878,"w":111,"h":129}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":17,"y":4,"w":111,"h":129}, @@ -410,7 +410,7 @@ }, "sprites/blueprints/logic_gate-not.png": { - "frame": {"x":1545,"y":843,"w":123,"h":144}, + "frame": {"x":1237,"y":1181,"w":123,"h":144}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":11,"y":0,"w":123,"h":144}, @@ -418,7 +418,7 @@ }, "sprites/blueprints/logic_gate-or.png": { - "frame": {"x":1249,"y":996,"w":144,"h":123}, + "frame": {"x":1384,"y":446,"w":144,"h":123}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":0,"w":144,"h":123}, @@ -426,7 +426,7 @@ }, "sprites/blueprints/logic_gate-transistor.png": { - "frame": {"x":708,"y":888,"w":101,"h":144}, + "frame": {"x":1936,"y":660,"w":101,"h":144}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":0,"w":101,"h":144}, @@ -434,7 +434,7 @@ }, "sprites/blueprints/logic_gate-xor.png": { - "frame": {"x":291,"y":890,"w":144,"h":143}, + "frame": {"x":1111,"y":741,"w":144,"h":143}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":0,"w":144,"h":143}, @@ -442,7 +442,7 @@ }, "sprites/blueprints/logic_gate.png": { - "frame": {"x":1397,"y":852,"w":144,"h":133}, + "frame": {"x":969,"y":594,"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":151,"y":1035,"w":136,"h":143}, + "frame": {"x":889,"y":1477,"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":123,"y":1318,"w":136,"h":143}, + "frame": {"x":506,"y":1620,"w":136,"h":143}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":5,"y":0,"w":136,"h":143}, @@ -466,7 +466,7 @@ }, "sprites/blueprints/mixer.png": { - "frame": {"x":1676,"y":584,"w":261,"h":144}, + "frame": {"x":1411,"y":3,"w":261,"h":144}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":13,"y":0,"w":261,"h":144}, @@ -474,7 +474,7 @@ }, "sprites/blueprints/painter-double.png": { - "frame": {"x":1683,"y":3,"w":288,"h":287}, + "frame": {"x":255,"y":704,"w":288,"h":287}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":0,"w":288,"h":287}, @@ -482,7 +482,7 @@ }, "sprites/blueprints/painter-mirrored.png": { - "frame": {"x":555,"y":298,"w":288,"h":144}, + "frame": {"x":3,"y":996,"w":288,"h":144}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":288,"h":144}, @@ -490,7 +490,7 @@ }, "sprites/blueprints/painter-quad.png": { - "frame": {"x":3,"y":3,"w":560,"h":144}, + "frame": {"x":3,"y":556,"w":560,"h":144}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":5,"y":0,"w":560,"h":144}, @@ -498,7 +498,7 @@ }, "sprites/blueprints/painter.png": { - "frame": {"x":3,"y":299,"w":288,"h":144}, + "frame": {"x":821,"y":446,"w":288,"h":144}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":288,"h":144}, @@ -506,7 +506,7 @@ }, "sprites/blueprints/reader.png": { - "frame": {"x":938,"y":1181,"w":141,"h":144}, + "frame": {"x":296,"y":1440,"w":141,"h":144}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":2,"y":0,"w":141,"h":144}, @@ -514,7 +514,7 @@ }, "sprites/blueprints/rotater-ccw.png": { - "frame": {"x":1245,"y":1123,"w":143,"h":144}, + "frame": {"x":520,"y":1324,"w":143,"h":144}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":1,"y":0,"w":143,"h":144}, @@ -522,7 +522,7 @@ }, "sprites/blueprints/rotater-fl.png": { - "frame": {"x":1658,"y":1325,"w":142,"h":144}, + "frame": {"x":150,"y":1440,"w":142,"h":144}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":0,"w":142,"h":144}, @@ -530,7 +530,7 @@ }, "sprites/blueprints/rotater.png": { - "frame": {"x":1097,"y":1171,"w":143,"h":144}, + "frame": {"x":3,"y":1440,"w":143,"h":144}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":1,"y":0,"w":143,"h":144}, @@ -538,7 +538,7 @@ }, "sprites/blueprints/splitter-compact-inverse.png": { - "frame": {"x":560,"y":1036,"w":142,"h":138}, + "frame": {"x":1458,"y":942,"w":142,"h":138}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":2,"w":142,"h":138}, @@ -546,7 +546,7 @@ }, "sprites/blueprints/splitter-compact-merge-inverse.png": { - "frame": {"x":792,"y":1118,"w":142,"h":138}, + "frame": {"x":1604,"y":942,"w":142,"h":138}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":2,"w":142,"h":138}, @@ -554,7 +554,7 @@ }, "sprites/blueprints/splitter-compact-merge.png": { - "frame": {"x":1373,"y":1409,"w":139,"h":138}, + "frame": {"x":3,"y":1588,"w":139,"h":138}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":5,"y":2,"w":139,"h":138}, @@ -562,7 +562,7 @@ }, "sprites/blueprints/splitter-compact.png": { - "frame": {"x":1373,"y":1551,"w":139,"h":138}, + "frame": {"x":1412,"y":1465,"w":139,"h":138}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":5,"y":2,"w":139,"h":138}, @@ -570,15 +570,15 @@ }, "sprites/blueprints/splitter.png": { - "frame": {"x":295,"y":299,"w":256,"h":144}, + "frame": {"x":839,"y":886,"w":257,"h":144}, "rotated": false, "trimmed": true, - "spriteSourceSize": {"x":17,"y":0,"w":256,"h":144}, + "spriteSourceSize": {"x":17,"y":0,"w":257,"h":144}, "sourceSize": {"w":288,"h":144} }, "sprites/blueprints/stacker.png": { - "frame": {"x":295,"y":594,"w":261,"h":144}, + "frame": {"x":1399,"y":151,"w":261,"h":144}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":13,"y":0,"w":261,"h":144}, @@ -586,7 +586,7 @@ }, "sprites/blueprints/trash-storage.png": { - "frame": {"x":847,"y":593,"w":250,"h":288}, + "frame": {"x":567,"y":446,"w":250,"h":288}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":21,"y":0,"w":250,"h":288}, @@ -594,7 +594,7 @@ }, "sprites/blueprints/trash.png": { - "frame": {"x":292,"y":742,"w":144,"h":144}, + "frame": {"x":295,"y":995,"w":144,"h":144}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":144,"h":144}, @@ -602,7 +602,7 @@ }, "sprites/blueprints/underground_belt_entry-tier2.png": { - "frame": {"x":1516,"y":1574,"w":138,"h":125}, + "frame": {"x":1816,"y":808,"w":138,"h":125}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":4,"y":19,"w":138,"h":125}, @@ -610,7 +610,7 @@ }, "sprites/blueprints/underground_belt_entry.png": { - "frame": {"x":283,"y":1182,"w":138,"h":112}, + "frame": {"x":747,"y":1477,"w":138,"h":112}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":4,"y":32,"w":138,"h":112}, @@ -618,7 +618,7 @@ }, "sprites/blueprints/underground_belt_exit-tier2.png": { - "frame": {"x":1225,"y":1555,"w":139,"h":112}, + "frame": {"x":1623,"y":826,"w":139,"h":112}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":4,"y":0,"w":139,"h":112}, @@ -626,7 +626,7 @@ }, "sprites/blueprints/underground_belt_exit.png": { - "frame": {"x":283,"y":1298,"w":138,"h":112}, + "frame": {"x":123,"y":1736,"w":138,"h":112}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":4,"y":0,"w":138,"h":112}, @@ -634,7 +634,7 @@ }, "sprites/blueprints/virtual_processor-analyzer.png": { - "frame": {"x":3,"y":887,"w":144,"h":144}, + "frame": {"x":3,"y":1144,"w":144,"h":144}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":144,"h":144}, @@ -642,7 +642,7 @@ }, "sprites/blueprints/virtual_processor-rotater.png": { - "frame": {"x":1545,"y":991,"w":118,"h":144}, + "frame": {"x":1490,"y":1169,"w":118,"h":144}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":14,"y":0,"w":118,"h":144}, @@ -650,7 +650,7 @@ }, "sprites/blueprints/virtual_processor-shapecompare.png": { - "frame": {"x":1397,"y":989,"w":144,"h":133}, + "frame": {"x":1259,"y":741,"w":144,"h":133}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":0,"w":144,"h":133}, @@ -658,7 +658,7 @@ }, "sprites/blueprints/virtual_processor-stacker.png": { - "frame": {"x":961,"y":1033,"w":132,"h":144}, + "frame": {"x":685,"y":1176,"w":132,"h":144}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":0,"w":132,"h":144}, @@ -666,7 +666,7 @@ }, "sprites/blueprints/virtual_processor-unstacker.png": { - "frame": {"x":1101,"y":704,"w":144,"h":144}, + "frame": {"x":151,"y":1144,"w":144,"h":144}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":144,"h":144}, @@ -674,7 +674,7 @@ }, "sprites/blueprints/virtual_processor.png": { - "frame": {"x":291,"y":1037,"w":144,"h":141}, + "frame": {"x":1100,"y":888,"w":144,"h":141}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":3,"w":144,"h":141}, @@ -682,7 +682,7 @@ }, "sprites/blueprints/wire-cross.png": { - "frame": {"x":1249,"y":704,"w":144,"h":144}, + "frame": {"x":299,"y":1143,"w":144,"h":144}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":144,"h":144}, @@ -690,7 +690,7 @@ }, "sprites/blueprints/wire-split.png": { - "frame": {"x":1098,"y":1000,"w":144,"h":82}, + "frame": {"x":1384,"y":573,"w":144,"h":82}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":62,"w":144,"h":82}, @@ -698,7 +698,7 @@ }, "sprites/blueprints/wire-turn.png": { - "frame": {"x":706,"y":1036,"w":82,"h":82}, + "frame": {"x":1371,"y":1015,"w":82,"h":82}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":62,"y":62,"w":82,"h":82}, @@ -706,7 +706,7 @@ }, "sprites/blueprints/wire.png": { - "frame": {"x":1107,"y":151,"w":20,"h":144}, + "frame": {"x":447,"y":1143,"w":20,"h":144}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":62,"y":0,"w":20,"h":144}, @@ -714,7 +714,7 @@ }, "sprites/blueprints/wire_tunnel-coating.png": { - "frame": {"x":255,"y":677,"w":33,"h":134}, + "frame": {"x":447,"y":1291,"w":33,"h":134}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":56,"y":5,"w":33,"h":134}, @@ -722,7 +722,7 @@ }, "sprites/blueprints/wire_tunnel.png": { - "frame": {"x":1516,"y":1435,"w":138,"h":135}, + "frame": {"x":1612,"y":1224,"w":138,"h":135}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":4,"y":4,"w":138,"h":135}, @@ -730,7 +730,7 @@ }, "sprites/buildings/belt_left.png": { - "frame": {"x":3,"y":1182,"w":130,"h":130}, + "frame": {"x":1909,"y":3,"w":130,"h":130}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":14,"w":130,"h":130}, @@ -738,7 +738,7 @@ }, "sprites/buildings/belt_right.png": { - "frame": {"x":925,"y":1476,"w":130,"h":130}, + "frame": {"x":539,"y":1891,"w":130,"h":130}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":14,"y":14,"w":130,"h":130}, @@ -746,7 +746,7 @@ }, "sprites/buildings/belt_top.png": { - "frame": {"x":440,"y":742,"w":116,"h":144}, + "frame": {"x":969,"y":1181,"w":116,"h":144}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":14,"y":0,"w":116,"h":144}, @@ -754,7 +754,7 @@ }, "sprites/buildings/constant_signal.png": { - "frame": {"x":1941,"y":716,"w":104,"h":127}, + "frame": {"x":1438,"y":1607,"w":104,"h":127}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":20,"y":0,"w":104,"h":127}, @@ -762,7 +762,7 @@ }, "sprites/buildings/cutter-quad.png": { - "frame": {"x":555,"y":151,"w":548,"h":143}, + "frame": {"x":555,"y":299,"w":548,"h":143}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":17,"y":0,"w":548,"h":143}, @@ -770,7 +770,7 @@ }, "sprites/buildings/cutter.png": { - "frame": {"x":847,"y":446,"w":256,"h":143}, + "frame": {"x":829,"y":1034,"w":256,"h":143}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":17,"y":0,"w":256,"h":143}, @@ -778,7 +778,7 @@ }, "sprites/buildings/display.png": { - "frame": {"x":1545,"y":704,"w":126,"h":135}, + "frame": {"x":778,"y":1724,"w":126,"h":135}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":9,"w":126,"h":135}, @@ -786,7 +786,7 @@ }, "sprites/buildings/filter.png": { - "frame": {"x":1379,"y":556,"w":267,"h":144}, + "frame": {"x":1113,"y":446,"w":267,"h":144}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":17,"y":0,"w":267,"h":144}, @@ -794,7 +794,7 @@ }, "sprites/buildings/hub.png": { - "frame": {"x":1131,"y":3,"w":548,"h":549}, + "frame": {"x":3,"y":3,"w":548,"h":549}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":14,"y":16,"w":548,"h":549}, @@ -802,7 +802,7 @@ }, "sprites/buildings/lever.png": { - "frame": {"x":1823,"y":865,"w":109,"h":127}, + "frame": {"x":646,"y":1760,"w":109,"h":127}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":18,"y":5,"w":109,"h":127}, @@ -810,7 +810,7 @@ }, "sprites/buildings/logic_gate-not.png": { - "frame": {"x":972,"y":885,"w":122,"h":144}, + "frame": {"x":1364,"y":1181,"w":122,"h":144}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":12,"y":0,"w":122,"h":144}, @@ -818,7 +818,7 @@ }, "sprites/buildings/logic_gate-or.png": { - "frame": {"x":1659,"y":1198,"w":143,"h":123}, + "frame": {"x":1532,"y":531,"w":143,"h":123}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":1,"y":0,"w":143,"h":123}, @@ -826,7 +826,7 @@ }, "sprites/buildings/logic_gate-transistor.png": { - "frame": {"x":151,"y":887,"w":100,"h":144}, + "frame": {"x":443,"y":995,"w":100,"h":144}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":1,"y":0,"w":100,"h":144}, @@ -834,7 +834,7 @@ }, "sprites/buildings/logic_gate-xor.png": { - "frame": {"x":1392,"y":1126,"w":143,"h":143}, + "frame": {"x":1485,"y":659,"w":143,"h":143}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":1,"y":0,"w":143,"h":143}, @@ -842,7 +842,7 @@ }, "sprites/buildings/logic_gate.png": { - "frame": {"x":1391,"y":1273,"w":143,"h":132}, + "frame": {"x":1476,"y":806,"w":143,"h":132}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":1,"y":0,"w":143,"h":132}, @@ -850,7 +850,7 @@ }, "sprites/buildings/miner-chainable.png": { - "frame": {"x":3,"y":1703,"w":136,"h":142}, + "frame": {"x":265,"y":1736,"w":136,"h":142}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":5,"y":0,"w":136,"h":142}, @@ -858,7 +858,7 @@ }, "sprites/buildings/miner.png": { - "frame": {"x":143,"y":1703,"w":136,"h":142}, + "frame": {"x":123,"y":1852,"w":136,"h":142}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":5,"y":0,"w":136,"h":142}, @@ -866,7 +866,7 @@ }, "sprites/buildings/mixer.png": { - "frame": {"x":560,"y":594,"w":260,"h":143}, + "frame": {"x":1107,"y":299,"w":260,"h":143}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":14,"y":0,"w":260,"h":143}, @@ -874,7 +874,7 @@ }, "sprites/buildings/painter-double.png": { - "frame": {"x":1683,"y":294,"w":288,"h":286}, + "frame": {"x":547,"y":738,"w":288,"h":286}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":0,"w":288,"h":286}, @@ -882,7 +882,7 @@ }, "sprites/buildings/painter-mirrored.png": { - "frame": {"x":555,"y":446,"w":288,"h":144}, + "frame": {"x":1107,"y":151,"w":288,"h":144}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":288,"h":144}, @@ -890,7 +890,7 @@ }, "sprites/buildings/painter-quad.png": { - "frame": {"x":567,"y":3,"w":560,"h":144}, + "frame": {"x":555,"y":3,"w":560,"h":144}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":5,"y":0,"w":560,"h":144}, @@ -898,7 +898,7 @@ }, "sprites/buildings/painter.png": { - "frame": {"x":3,"y":447,"w":288,"h":144}, + "frame": {"x":1119,"y":3,"w":288,"h":144}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":288,"h":144}, @@ -906,7 +906,7 @@ }, "sprites/buildings/reader.png": { - "frame": {"x":790,"y":1260,"w":141,"h":144}, + "frame": {"x":667,"y":1324,"w":141,"h":144}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":2,"y":0,"w":141,"h":144}, @@ -914,7 +914,7 @@ }, "sprites/buildings/rotater-ccw.png": { - "frame": {"x":1083,"y":1319,"w":141,"h":143}, + "frame": {"x":1812,"y":139,"w":141,"h":143}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":2,"y":0,"w":141,"h":143}, @@ -922,7 +922,7 @@ }, "sprites/buildings/rotater-fl.png": { - "frame": {"x":935,"y":1329,"w":141,"h":143}, + "frame": {"x":1671,"y":679,"w":141,"h":143}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":1,"y":0,"w":141,"h":143}, @@ -930,7 +930,7 @@ }, "sprites/buildings/rotater.png": { - "frame": {"x":1228,"y":1408,"w":141,"h":143}, + "frame": {"x":1800,"y":513,"w":141,"h":143}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":2,"y":0,"w":141,"h":143}, @@ -938,7 +938,7 @@ }, "sprites/buildings/splitter-compact-inverse.png": { - "frame": {"x":1080,"y":1466,"w":141,"h":136}, + "frame": {"x":1845,"y":371,"w":141,"h":136}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":3,"w":141,"h":136}, @@ -946,7 +946,7 @@ }, "sprites/buildings/splitter-compact-merge-inverse.png": { - "frame": {"x":559,"y":1178,"w":142,"h":136}, + "frame": {"x":1699,"y":373,"w":142,"h":136}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":3,"w":142,"h":136}, @@ -954,7 +954,7 @@ }, "sprites/buildings/splitter-compact-merge.png": { - "frame": {"x":1658,"y":1473,"w":139,"h":136}, + "frame": {"x":1612,"y":1084,"w":139,"h":136}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":5,"y":3,"w":139,"h":136}, @@ -962,7 +962,7 @@ }, "sprites/buildings/splitter-compact.png": { - "frame": {"x":1658,"y":1613,"w":139,"h":136}, + "frame": {"x":1750,"y":942,"w":139,"h":136}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":5,"y":3,"w":139,"h":136}, @@ -970,7 +970,7 @@ }, "sprites/buildings/splitter.png": { - "frame": {"x":295,"y":447,"w":256,"h":143}, + "frame": {"x":1117,"y":594,"w":256,"h":143}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":17,"y":0,"w":256,"h":143}, @@ -978,7 +978,7 @@ }, "sprites/buildings/stacker.png": { - "frame": {"x":560,"y":741,"w":260,"h":143}, + "frame": {"x":1371,"y":299,"w":260,"h":143}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":14,"y":0,"w":260,"h":143}, @@ -986,7 +986,7 @@ }, "sprites/buildings/trash-storage.png": { - "frame": {"x":3,"y":595,"w":248,"h":288}, + "frame": {"x":3,"y":704,"w":248,"h":288}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":22,"y":0,"w":248,"h":288}, @@ -994,7 +994,7 @@ }, "sprites/buildings/trash.png": { - "frame": {"x":1397,"y":704,"w":144,"h":144}, + "frame": {"x":537,"y":1176,"w":144,"h":144}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":144,"h":144}, @@ -1002,7 +1002,7 @@ }, "sprites/buildings/underground_belt_entry-tier2.png": { - "frame": {"x":3,"y":1476,"w":137,"h":124}, + "frame": {"x":1029,"y":1477,"w":137,"h":124}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":5,"y":20,"w":137,"h":124}, @@ -1010,7 +1010,7 @@ }, "sprites/buildings/underground_belt_entry.png": { - "frame": {"x":283,"y":1414,"w":137,"h":111}, + "frame": {"x":1170,"y":1477,"w":137,"h":111}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":5,"y":33,"w":137,"h":111}, @@ -1018,7 +1018,7 @@ }, "sprites/buildings/underground_belt_exit-tier2.png": { - "frame": {"x":283,"y":1529,"w":137,"h":111}, + "frame": {"x":1546,"y":1613,"w":137,"h":111}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":5,"y":0,"w":137,"h":111}, @@ -1026,7 +1026,7 @@ }, "sprites/buildings/underground_belt_exit.png": { - "frame": {"x":424,"y":1588,"w":137,"h":111}, + "frame": {"x":1675,"y":1363,"w":137,"h":111}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":5,"y":0,"w":137,"h":111}, @@ -1034,7 +1034,7 @@ }, "sprites/buildings/virtual_processor-analyzer.png": { - "frame": {"x":1675,"y":732,"w":144,"h":144}, + "frame": {"x":3,"y":1292,"w":144,"h":144}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":144,"h":144}, @@ -1042,7 +1042,7 @@ }, "sprites/buildings/virtual_processor-rotater.png": { - "frame": {"x":439,"y":890,"w":117,"h":144}, + "frame": {"x":1679,"y":531,"w":117,"h":144}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":14,"y":0,"w":117,"h":144}, @@ -1050,7 +1050,7 @@ }, "sprites/buildings/virtual_processor-shapecompare.png": { - "frame": {"x":1244,"y":1271,"w":143,"h":133}, + "frame": {"x":1664,"y":236,"w":143,"h":133}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":1,"y":0,"w":143,"h":133}, @@ -1058,7 +1058,7 @@ }, "sprites/buildings/virtual_processor-stacker.png": { - "frame": {"x":3,"y":1849,"w":130,"h":144}, + "frame": {"x":1237,"y":1033,"w":130,"h":144}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":1,"y":0,"w":130,"h":144}, @@ -1066,7 +1066,7 @@ }, "sprites/buildings/virtual_processor-unstacker.png": { - "frame": {"x":3,"y":1035,"w":144,"h":143}, + "frame": {"x":1089,"y":1182,"w":144,"h":143}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":1,"w":144,"h":143}, @@ -1074,7 +1074,7 @@ }, "sprites/buildings/virtual_processor.png": { - "frame": {"x":1249,"y":852,"w":144,"h":140}, + "frame": {"x":821,"y":594,"w":144,"h":140}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":4,"w":144,"h":140}, @@ -1082,7 +1082,7 @@ }, "sprites/buildings/wire-cross.png": { - "frame": {"x":1672,"y":880,"w":144,"h":144}, + "frame": {"x":151,"y":1292,"w":144,"h":144}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":144,"h":144}, @@ -1090,7 +1090,7 @@ }, "sprites/buildings/wire-split.png": { - "frame": {"x":1667,"y":1028,"w":144,"h":81}, + "frame": {"x":1259,"y":878,"w":144,"h":81}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":63,"w":144,"h":81}, @@ -1098,7 +1098,7 @@ }, "sprites/buildings/wire-turn.png": { - "frame": {"x":1941,"y":631,"w":81,"h":81}, + "frame": {"x":1824,"y":3,"w":81,"h":81}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":63,"y":63,"w":81,"h":81}, @@ -1106,7 +1106,7 @@ }, "sprites/buildings/wire.png": { - "frame": {"x":2027,"y":272,"w":18,"h":144}, + "frame": {"x":471,"y":1143,"w":18,"h":144}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":63,"y":0,"w":18,"h":144}, @@ -1114,7 +1114,7 @@ }, "sprites/buildings/wire_tunnel-coating.png": { - "frame": {"x":255,"y":815,"w":32,"h":134}, + "frame": {"x":484,"y":1291,"w":32,"h":134}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":56,"y":5,"w":32,"h":134}, @@ -1122,7 +1122,7 @@ }, "sprites/buildings/wire_tunnel.png": { - "frame": {"x":559,"y":1318,"w":137,"h":134}, + "frame": {"x":1029,"y":1607,"w":137,"h":134}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":5,"y":5,"w":137,"h":134}, @@ -1130,7 +1130,7 @@ }, "sprites/debug/acceptor_slot.png": { - "frame": {"x":1107,"y":447,"w":12,"h":12}, + "frame": {"x":547,"y":704,"w":12,"h":12}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, @@ -1138,7 +1138,7 @@ }, "sprites/debug/ejector_slot.png": { - "frame": {"x":1107,"y":463,"w":12,"h":12}, + "frame": {"x":547,"y":720,"w":12,"h":12}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":12,"h":12}, @@ -1146,7 +1146,7 @@ }, "sprites/misc/hub_direction_indicator.png": { - "frame": {"x":1975,"y":272,"w":48,"h":48}, + "frame": {"x":1341,"y":963,"w":48,"h":48}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":48,"h":48}, @@ -1154,7 +1154,7 @@ }, "sprites/misc/processor_disabled.png": { - "frame": {"x":3,"y":1606,"w":78,"h":81}, + "frame": {"x":1957,"y":137,"w":78,"h":81}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":10,"y":10,"w":78,"h":81}, @@ -1162,7 +1162,7 @@ }, "sprites/misc/processor_disconnected.png": { - "frame": {"x":1975,"y":3,"w":65,"h":84}, + "frame": {"x":1407,"y":733,"w":65,"h":84}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":17,"y":8,"w":65,"h":84}, @@ -1170,7 +1170,7 @@ }, "sprites/misc/reader_overlay.png": { - "frame": {"x":1820,"y":996,"w":104,"h":70}, + "frame": {"x":1377,"y":659,"w":104,"h":70}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":20,"y":38,"w":104,"h":70}, @@ -1178,7 +1178,7 @@ }, "sprites/misc/slot_bad_arrow.png": { - "frame": {"x":255,"y":638,"w":35,"h":35}, + "frame": {"x":1393,"y":976,"w":35,"h":35}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":2,"y":2,"w":35,"h":35}, @@ -1186,7 +1186,7 @@ }, "sprites/misc/slot_good_arrow.png": { - "frame": {"x":255,"y":595,"w":35,"h":39}, + "frame": {"x":1632,"y":658,"w":35,"h":39}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":2,"y":0,"w":35,"h":39}, @@ -1194,7 +1194,7 @@ }, "sprites/misc/storage_overlay.png": { - "frame": {"x":1935,"y":1209,"w":89,"h":44}, + "frame": {"x":1248,"y":963,"w":89,"h":44}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":1,"y":1,"w":89,"h":44}, @@ -1202,7 +1202,7 @@ }, "sprites/misc/waypoint.png": { - "frame": {"x":48,"y":1997,"w":38,"h":48}, + "frame": {"x":1407,"y":873,"w":38,"h":48}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":5,"y":0,"w":38,"h":48}, @@ -1210,7 +1210,7 @@ }, "sprites/wires/boolean_false.png": { - "frame": {"x":255,"y":953,"w":31,"h":41}, + "frame": {"x":1422,"y":1101,"w":31,"h":41}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":5,"w":31,"h":41}, @@ -1218,7 +1218,7 @@ }, "sprites/wires/boolean_true.png": { - "frame": {"x":1650,"y":556,"w":22,"h":41}, + "frame": {"x":1635,"y":299,"w":22,"h":41}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":11,"y":5,"w":22,"h":41}, @@ -1226,7 +1226,7 @@ }, "sprites/wires/display/blue.png": { - "frame": {"x":1975,"y":376,"w":47,"h":47}, + "frame": {"x":1728,"y":88,"w":47,"h":47}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":1,"y":1,"w":47,"h":47}, @@ -1234,7 +1234,7 @@ }, "sprites/wires/display/cyan.png": { - "frame": {"x":1975,"y":427,"w":47,"h":47}, + "frame": {"x":1779,"y":88,"w":47,"h":47}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":1,"y":1,"w":47,"h":47}, @@ -1242,7 +1242,7 @@ }, "sprites/wires/display/green.png": { - "frame": {"x":1975,"y":478,"w":47,"h":47}, + "frame": {"x":1407,"y":925,"w":47,"h":47}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":1,"y":1,"w":47,"h":47}, @@ -1250,7 +1250,7 @@ }, "sprites/wires/display/purple.png": { - "frame": {"x":1975,"y":529,"w":47,"h":47}, + "frame": {"x":1371,"y":1101,"w":47,"h":47}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":1,"y":1,"w":47,"h":47}, @@ -1258,7 +1258,7 @@ }, "sprites/wires/display/red.png": { - "frame": {"x":1975,"y":580,"w":47,"h":47}, + "frame": {"x":1830,"y":88,"w":47,"h":47}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":1,"y":1,"w":47,"h":47}, @@ -1266,7 +1266,7 @@ }, "sprites/wires/display/white.png": { - "frame": {"x":90,"y":1997,"w":47,"h":47}, + "frame": {"x":1957,"y":222,"w":47,"h":47}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":1,"y":1,"w":47,"h":47}, @@ -1274,7 +1274,7 @@ }, "sprites/wires/display/yellow.png": { - "frame": {"x":141,"y":1997,"w":47,"h":47}, + "frame": {"x":1981,"y":273,"w":47,"h":47}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":1,"y":1,"w":47,"h":47}, @@ -1282,7 +1282,7 @@ }, "sprites/wires/lever_on.png": { - "frame": {"x":1936,"y":978,"w":109,"h":127}, + "frame": {"x":908,"y":1624,"w":109,"h":127}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":18,"y":5,"w":109,"h":127}, @@ -1290,7 +1290,7 @@ }, "sprites/wires/logical_acceptor.png": { - "frame": {"x":1975,"y":91,"w":62,"h":106}, + "frame": {"x":441,"y":1439,"w":62,"h":106}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":43,"y":0,"w":62,"h":106}, @@ -1298,7 +1298,7 @@ }, "sprites/wires/logical_ejector.png": { - "frame": {"x":1975,"y":201,"w":60,"h":67}, + "frame": {"x":1635,"y":373,"w":60,"h":67}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":44,"y":0,"w":60,"h":67}, @@ -1306,7 +1306,7 @@ }, "sprites/wires/network_conflict.png": { - "frame": {"x":192,"y":1997,"w":47,"h":44}, + "frame": {"x":1542,"y":1084,"w":47,"h":44}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":1,"y":2,"w":47,"h":44}, @@ -1314,7 +1314,7 @@ }, "sprites/wires/network_empty.png": { - "frame": {"x":3,"y":1997,"w":41,"h":48}, + "frame": {"x":1407,"y":821,"w":41,"h":48}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":5,"y":0,"w":41,"h":48}, @@ -1322,7 +1322,7 @@ }, "sprites/wires/overlay_tile.png": { - "frame": {"x":1935,"y":1109,"w":96,"h":96}, + "frame": {"x":1945,"y":511,"w":96,"h":96}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":96,"h":96}, @@ -1330,7 +1330,7 @@ }, "sprites/wires/sets/color_cross.png": { - "frame": {"x":1101,"y":852,"w":144,"h":144}, + "frame": {"x":299,"y":1291,"w":144,"h":144}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":144,"h":144}, @@ -1338,7 +1338,7 @@ }, "sprites/wires/sets/color_forward.png": { - "frame": {"x":2026,"y":420,"w":18,"h":144}, + "frame": {"x":493,"y":1143,"w":18,"h":144}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":63,"y":0,"w":18,"h":144}, @@ -1346,7 +1346,7 @@ }, "sprites/wires/sets/color_split.png": { - "frame": {"x":1667,"y":1113,"w":144,"h":81}, + "frame": {"x":1532,"y":446,"w":144,"h":81}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":63,"w":144,"h":81}, @@ -1354,7 +1354,7 @@ }, "sprites/wires/sets/color_turn.png": { - "frame": {"x":706,"y":1122,"w":81,"h":81}, + "frame": {"x":1457,"y":1084,"w":81,"h":81}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":63,"y":63,"w":81,"h":81}, @@ -1362,7 +1362,7 @@ }, "sprites/wires/sets/conflict_cross.png": { - "frame": {"x":824,"y":885,"w":144,"h":144}, + "frame": {"x":1089,"y":1034,"w":144,"h":144}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":144,"h":144}, @@ -1370,7 +1370,7 @@ }, "sprites/wires/sets/conflict_forward.png": { - "frame": {"x":2026,"y":568,"w":18,"h":144}, + "frame": {"x":515,"y":1143,"w":18,"h":144}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":63,"y":0,"w":18,"h":144}, @@ -1378,7 +1378,7 @@ }, "sprites/wires/sets/conflict_split.png": { - "frame": {"x":813,"y":1033,"w":144,"h":81}, + "frame": {"x":1664,"y":151,"w":144,"h":81}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":63,"w":144,"h":81}, @@ -1386,7 +1386,7 @@ }, "sprites/wires/sets/conflict_turn.png": { - "frame": {"x":705,"y":1207,"w":81,"h":81}, + "frame": {"x":1811,"y":286,"w":81,"h":81}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":63,"y":63,"w":81,"h":81}, @@ -1394,7 +1394,7 @@ }, "sprites/wires/sets/regular_cross.png": { - "frame": {"x":1672,"y":880,"w":144,"h":144}, + "frame": {"x":151,"y":1292,"w":144,"h":144}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":144,"h":144}, @@ -1402,7 +1402,7 @@ }, "sprites/wires/sets/regular_forward.png": { - "frame": {"x":2027,"y":272,"w":18,"h":144}, + "frame": {"x":471,"y":1143,"w":18,"h":144}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":63,"y":0,"w":18,"h":144}, @@ -1410,7 +1410,7 @@ }, "sprites/wires/sets/regular_split.png": { - "frame": {"x":1667,"y":1028,"w":144,"h":81}, + "frame": {"x":1259,"y":878,"w":144,"h":81}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":63,"w":144,"h":81}, @@ -1418,7 +1418,7 @@ }, "sprites/wires/sets/regular_turn.png": { - "frame": {"x":1941,"y":631,"w":81,"h":81}, + "frame": {"x":1824,"y":3,"w":81,"h":81}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":63,"y":63,"w":81,"h":81}, @@ -1426,7 +1426,7 @@ }, "sprites/wires/sets/shape_cross.png": { - "frame": {"x":560,"y":888,"w":144,"h":144}, + "frame": {"x":821,"y":1181,"w":144,"h":144}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":144,"h":144}, @@ -1434,7 +1434,7 @@ }, "sprites/wires/sets/shape_forward.png": { - "frame": {"x":1107,"y":299,"w":18,"h":144}, + "frame": {"x":807,"y":1028,"w":18,"h":144}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":63,"y":0,"w":18,"h":144}, @@ -1442,7 +1442,7 @@ }, "sprites/wires/sets/shape_split.png": { - "frame": {"x":1097,"y":1086,"w":144,"h":81}, + "frame": {"x":1676,"y":3,"w":144,"h":81}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":63,"w":144,"h":81}, @@ -1450,7 +1450,7 @@ }, "sprites/wires/sets/shape_turn.png": { - "frame": {"x":705,"y":1292,"w":81,"h":81}, + "frame": {"x":1896,"y":286,"w":81,"h":81}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":63,"y":63,"w":81,"h":81}, @@ -1458,7 +1458,7 @@ }, "sprites/wires/wires_preview.png": { - "frame": {"x":1975,"y":324,"w":48,"h":48}, + "frame": {"x":1676,"y":88,"w":48,"h":48}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":48,"h":48}, @@ -1471,6 +1471,6 @@ "format": "RGBA8888", "size": {"w":2048,"h":2048}, "scale": "0.75", - "smartupdate": "$TexturePacker:SmartUpdate:d21082eda6f288e04b0739186004794d:0912211652d1c400e2846013f9de057b:908b89f5ca8ff73e331a35a3b14d0604$" + "smartupdate": "$TexturePacker:SmartUpdate:64d35c8d649d4bb41c7539e7e89c0865:2a9399f9a7c16dc686a4fb0941b02e6b:908b89f5ca8ff73e331a35a3b14d0604$" } } diff --git a/res_built/atlas/atlas0_hq.png b/res_built/atlas/atlas0_hq.png index f56d35d0..da9224c1 100644 Binary files a/res_built/atlas/atlas0_hq.png and b/res_built/atlas/atlas0_hq.png differ diff --git a/res_built/atlas/atlas0_lq.json b/res_built/atlas/atlas0_lq.json index c5cdf2ad..3815e9d9 100644 --- a/res_built/atlas/atlas0_lq.json +++ b/res_built/atlas/atlas0_lq.json @@ -1471,6 +1471,6 @@ "format": "RGBA8888", "size": {"w":512,"h":1024}, "scale": "0.25", - "smartupdate": "$TexturePacker:SmartUpdate:d21082eda6f288e04b0739186004794d:0912211652d1c400e2846013f9de057b:908b89f5ca8ff73e331a35a3b14d0604$" + "smartupdate": "$TexturePacker:SmartUpdate:64d35c8d649d4bb41c7539e7e89c0865:2a9399f9a7c16dc686a4fb0941b02e6b:908b89f5ca8ff73e331a35a3b14d0604$" } } diff --git a/res_built/atlas/atlas0_lq.png b/res_built/atlas/atlas0_lq.png index 1c60156c..15d6529a 100644 Binary files a/res_built/atlas/atlas0_lq.png and b/res_built/atlas/atlas0_lq.png differ diff --git a/res_built/atlas/atlas0_mq.json b/res_built/atlas/atlas0_mq.json index c5d7d311..81d510a9 100644 --- a/res_built/atlas/atlas0_mq.json +++ b/res_built/atlas/atlas0_mq.json @@ -2,7 +2,7 @@ "sprites/belt/built/forward_0.png": { - "frame": {"x":943,"y":803,"w":78,"h":96}, + "frame": {"x":565,"y":1569,"w":78,"h":96}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":0,"w":78,"h":96}, @@ -10,7 +10,7 @@ }, "sprites/belt/built/forward_1.png": { - "frame": {"x":94,"y":1746,"w":78,"h":96}, + "frame": {"x":468,"y":1618,"w":78,"h":96}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":0,"w":78,"h":96}, @@ -18,7 +18,7 @@ }, "sprites/belt/built/forward_2.png": { - "frame": {"x":754,"y":1555,"w":78,"h":96}, + "frame": {"x":3,"y":1793,"w":78,"h":96}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":0,"w":78,"h":96}, @@ -26,7 +26,7 @@ }, "sprites/belt/built/forward_3.png": { - "frame": {"x":653,"y":1564,"w":78,"h":96}, + "frame": {"x":3,"y":1893,"w":78,"h":96}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":0,"w":78,"h":96}, @@ -34,7 +34,7 @@ }, "sprites/belt/built/forward_4.png": { - "frame": {"x":556,"y":1601,"w":78,"h":96}, + "frame": {"x":85,"y":1885,"w":78,"h":96}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":0,"w":78,"h":96}, @@ -42,7 +42,7 @@ }, "sprites/belt/built/forward_5.png": { - "frame": {"x":458,"y":1663,"w":78,"h":96}, + "frame": {"x":167,"y":1885,"w":78,"h":96}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":0,"w":78,"h":96}, @@ -50,7 +50,7 @@ }, "sprites/belt/built/forward_6.png": { - "frame": {"x":359,"y":1711,"w":78,"h":96}, + "frame": {"x":844,"y":1565,"w":78,"h":96}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":0,"w":78,"h":96}, @@ -58,7 +58,7 @@ }, "sprites/belt/built/forward_7.png": { - "frame": {"x":268,"y":1771,"w":78,"h":96}, + "frame": {"x":746,"y":1643,"w":78,"h":96}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":0,"w":78,"h":96}, @@ -66,7 +66,7 @@ }, "sprites/belt/built/forward_8.png": { - "frame": {"x":176,"y":1835,"w":78,"h":96}, + "frame": {"x":647,"y":1663,"w":78,"h":96}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":0,"w":78,"h":96}, @@ -74,7 +74,7 @@ }, "sprites/belt/built/forward_9.png": { - "frame": {"x":85,"y":1846,"w":78,"h":96}, + "frame": {"x":550,"y":1669,"w":78,"h":96}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":0,"w":78,"h":96}, @@ -82,7 +82,7 @@ }, "sprites/belt/built/forward_10.png": { - "frame": {"x":3,"y":1789,"w":78,"h":96}, + "frame": {"x":372,"y":1620,"w":78,"h":96}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":0,"w":78,"h":96}, @@ -90,7 +90,7 @@ }, "sprites/belt/built/forward_11.png": { - "frame": {"x":3,"y":1889,"w":78,"h":96}, + "frame": {"x":276,"y":1669,"w":78,"h":96}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":0,"w":78,"h":96}, @@ -98,7 +98,7 @@ }, "sprites/belt/built/forward_12.png": { - "frame": {"x":856,"y":1469,"w":78,"h":96}, + "frame": {"x":184,"y":1727,"w":78,"h":96}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":0,"w":78,"h":96}, @@ -106,7 +106,7 @@ }, "sprites/belt/built/forward_13.png": { - "frame": {"x":938,"y":1469,"w":78,"h":96}, + "frame": {"x":91,"y":1785,"w":78,"h":96}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":0,"w":78,"h":96}, @@ -114,7 +114,7 @@ }, "sprites/belt/built/left_0.png": { - "frame": {"x":403,"y":911,"w":87,"h":87}, + "frame": {"x":600,"y":1205,"w":87,"h":87}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":9,"w":87,"h":87}, @@ -122,7 +122,7 @@ }, "sprites/belt/built/left_1.png": { - "frame": {"x":403,"y":1002,"w":87,"h":87}, + "frame": {"x":488,"y":1254,"w":87,"h":87}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":9,"w":87,"h":87}, @@ -130,7 +130,7 @@ }, "sprites/belt/built/left_2.png": { - "frame": {"x":3,"y":1516,"w":87,"h":87}, + "frame": {"x":488,"y":1345,"w":87,"h":87}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":9,"w":87,"h":87}, @@ -138,7 +138,7 @@ }, "sprites/belt/built/left_3.png": { - "frame": {"x":785,"y":1191,"w":87,"h":87}, + "frame": {"x":390,"y":1347,"w":87,"h":87}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":9,"w":87,"h":87}, @@ -146,7 +146,7 @@ }, "sprites/belt/built/left_4.png": { - "frame": {"x":876,"y":1196,"w":87,"h":87}, + "frame": {"x":292,"y":1396,"w":87,"h":87}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":9,"w":87,"h":87}, @@ -154,7 +154,7 @@ }, "sprites/belt/built/left_5.png": { - "frame": {"x":785,"y":1282,"w":87,"h":87}, + "frame": {"x":195,"y":1454,"w":87,"h":87}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":9,"w":87,"h":87}, @@ -162,7 +162,7 @@ }, "sprites/belt/built/left_6.png": { - "frame": {"x":685,"y":1287,"w":87,"h":87}, + "frame": {"x":99,"y":1508,"w":87,"h":87}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":9,"w":87,"h":87}, @@ -170,7 +170,7 @@ }, "sprites/belt/built/left_7.png": { - "frame": {"x":583,"y":1325,"w":87,"h":87}, + "frame": {"x":3,"y":1517,"w":87,"h":87}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":9,"w":87,"h":87}, @@ -178,7 +178,7 @@ }, "sprites/belt/built/left_8.png": { - "frame": {"x":482,"y":1381,"w":87,"h":87}, + "frame": {"x":883,"y":1283,"w":87,"h":87}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":9,"w":87,"h":87}, @@ -186,7 +186,7 @@ }, "sprites/belt/built/left_9.png": { - "frame": {"x":383,"y":1429,"w":87,"h":87}, + "frame": {"x":782,"y":1361,"w":87,"h":87}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":9,"w":87,"h":87}, @@ -194,7 +194,7 @@ }, "sprites/belt/built/left_10.png": { - "frame": {"x":391,"y":1338,"w":87,"h":87}, + "frame": {"x":896,"y":1192,"w":87,"h":87}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":9,"w":87,"h":87}, @@ -202,7 +202,7 @@ }, "sprites/belt/built/left_11.png": { - "frame": {"x":292,"y":1398,"w":87,"h":87}, + "frame": {"x":792,"y":1270,"w":87,"h":87}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":9,"w":87,"h":87}, @@ -210,7 +210,7 @@ }, "sprites/belt/built/left_12.png": { - "frame": {"x":196,"y":1462,"w":87,"h":87}, + "frame": {"x":691,"y":1290,"w":87,"h":87}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":9,"w":87,"h":87}, @@ -218,7 +218,7 @@ }, "sprites/belt/built/left_13.png": { - "frame": {"x":99,"y":1473,"w":87,"h":87}, + "frame": {"x":579,"y":1296,"w":87,"h":87}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":9,"w":87,"h":87}, @@ -226,7 +226,7 @@ }, "sprites/belt/built/right_0.png": { - "frame": {"x":287,"y":1489,"w":87,"h":87}, + "frame": {"x":670,"y":1381,"w":87,"h":87}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":9,"w":87,"h":87}, @@ -234,7 +234,7 @@ }, "sprites/belt/built/right_1.png": { - "frame": {"x":190,"y":1553,"w":87,"h":87}, + "frame": {"x":579,"y":1387,"w":87,"h":87}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":9,"w":87,"h":87}, @@ -242,7 +242,7 @@ }, "sprites/belt/built/right_2.png": { - "frame": {"x":674,"y":1378,"w":87,"h":87}, + "frame": {"x":94,"y":1599,"w":87,"h":87}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":9,"w":87,"h":87}, @@ -250,7 +250,7 @@ }, "sprites/belt/built/right_3.png": { - "frame": {"x":573,"y":1416,"w":87,"h":87}, + "frame": {"x":3,"y":1608,"w":87,"h":87}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":9,"w":87,"h":87}, @@ -258,7 +258,7 @@ }, "sprites/belt/built/right_4.png": { - "frame": {"x":474,"y":1472,"w":87,"h":87}, + "frame": {"x":873,"y":1374,"w":87,"h":87}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":9,"w":87,"h":87}, @@ -266,7 +266,7 @@ }, "sprites/belt/built/right_5.png": { - "frame": {"x":378,"y":1520,"w":87,"h":87}, + "frame": {"x":761,"y":1452,"w":87,"h":87}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":9,"w":87,"h":87}, @@ -274,7 +274,7 @@ }, "sprites/belt/built/right_6.png": { - "frame": {"x":281,"y":1580,"w":87,"h":87}, + "frame": {"x":670,"y":1472,"w":87,"h":87}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":9,"w":87,"h":87}, @@ -282,7 +282,7 @@ }, "sprites/belt/built/right_7.png": { - "frame": {"x":185,"y":1644,"w":87,"h":87}, + "frame": {"x":572,"y":1478,"w":87,"h":87}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":9,"w":87,"h":87}, @@ -290,7 +290,7 @@ }, "sprites/belt/built/right_8.png": { - "frame": {"x":94,"y":1655,"w":87,"h":87}, + "frame": {"x":474,"y":1527,"w":87,"h":87}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":9,"w":87,"h":87}, @@ -298,7 +298,7 @@ }, "sprites/belt/built/right_9.png": { - "frame": {"x":3,"y":1698,"w":87,"h":87}, + "frame": {"x":377,"y":1529,"w":87,"h":87}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":9,"w":87,"h":87}, @@ -306,7 +306,7 @@ }, "sprites/belt/built/right_10.png": { - "frame": {"x":94,"y":1564,"w":87,"h":87}, + "frame": {"x":481,"y":1436,"w":87,"h":87}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":9,"w":87,"h":87}, @@ -314,7 +314,7 @@ }, "sprites/belt/built/right_11.png": { - "frame": {"x":3,"y":1607,"w":87,"h":87}, + "frame": {"x":383,"y":1438,"w":87,"h":87}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":9,"w":87,"h":87}, @@ -322,7 +322,7 @@ }, "sprites/belt/built/right_12.png": { - "frame": {"x":876,"y":1287,"w":87,"h":87}, + "frame": {"x":286,"y":1487,"w":87,"h":87}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":9,"w":87,"h":87}, @@ -330,7 +330,7 @@ }, "sprites/belt/built/right_13.png": { - "frame": {"x":776,"y":1373,"w":87,"h":87}, + "frame": {"x":190,"y":1545,"w":87,"h":87}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":9,"w":87,"h":87}, @@ -338,7 +338,7 @@ }, "sprites/blueprints/belt_left.png": { - "frame": {"x":867,"y":1378,"w":87,"h":87}, + "frame": {"x":281,"y":1578,"w":87,"h":87}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":9,"w":87,"h":87}, @@ -346,7 +346,7 @@ }, "sprites/blueprints/belt_right.png": { - "frame": {"x":765,"y":1464,"w":87,"h":87}, + "frame": {"x":185,"y":1636,"w":87,"h":87}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":9,"w":87,"h":87}, @@ -354,7 +354,7 @@ }, "sprites/blueprints/belt_top.png": { - "frame": {"x":85,"y":1946,"w":78,"h":96}, + "frame": {"x":454,"y":1718,"w":78,"h":96}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":0,"w":78,"h":96}, @@ -386,7 +386,7 @@ }, "sprites/blueprints/display.png": { - "frame": {"x":664,"y":1469,"w":86,"h":91}, + "frame": {"x":94,"y":1690,"w":86,"h":91}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":5,"y":5,"w":86,"h":91}, @@ -402,7 +402,7 @@ }, "sprites/blueprints/lever.png": { - "frame": {"x":167,"y":1935,"w":75,"h":86}, + "frame": {"x":944,"y":803,"w":75,"h":86}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":11,"y":3,"w":75,"h":86}, @@ -410,7 +410,7 @@ }, "sprites/blueprints/logic_gate-not.png": { - "frame": {"x":469,"y":1563,"w":83,"h":96}, + "frame": {"x":852,"y":1465,"w":83,"h":96}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":7,"y":0,"w":83,"h":96}, @@ -418,7 +418,7 @@ }, "sprites/blueprints/logic_gate-or.png": { - "frame": {"x":303,"y":903,"w":96,"h":82}, + "frame": {"x":203,"y":970,"w":96,"h":82}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":0,"w":96,"h":82}, @@ -442,7 +442,7 @@ }, "sprites/blueprints/logic_gate.png": { - "frame": {"x":910,"y":1103,"w":96,"h":89}, + "frame": {"x":103,"y":873,"w":96,"h":89}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":0,"w":96,"h":89}, @@ -450,7 +450,7 @@ }, "sprites/blueprints/miner-chainable.png": { - "frame": {"x":100,"y":1373,"w":92,"h":96}, + "frame": {"x":100,"y":1330,"w":92,"h":96}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":3,"y":0,"w":92,"h":96}, @@ -458,7 +458,7 @@ }, "sprites/blueprints/miner.png": { - "frame": {"x":3,"y":1416,"w":92,"h":96}, + "frame": {"x":3,"y":1339,"w":92,"h":96}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":3,"y":0,"w":92,"h":96}, @@ -506,7 +506,7 @@ }, "sprites/blueprints/reader.png": { - "frame": {"x":3,"y":926,"w":95,"h":96}, + "frame": {"x":403,"y":1052,"w":95,"h":96}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":1,"y":0,"w":95,"h":96}, @@ -522,7 +522,7 @@ }, "sprites/blueprints/rotater-fl.png": { - "frame": {"x":102,"y":983,"w":95,"h":96}, + "frame": {"x":303,"y":1107,"w":95,"h":96}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":0,"w":95,"h":96}, @@ -538,7 +538,7 @@ }, "sprites/blueprints/splitter-compact-inverse.png": { - "frame": {"x":300,"y":1047,"w":95,"h":93}, + "frame": {"x":601,"y":1108,"w":95,"h":93}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":1,"w":95,"h":93}, @@ -546,7 +546,7 @@ }, "sprites/blueprints/splitter-compact-merge-inverse.png": { - "frame": {"x":201,"y":1111,"w":95,"h":93}, + "frame": {"x":501,"y":1157,"w":95,"h":93}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":1,"w":95,"h":93}, @@ -554,7 +554,7 @@ }, "sprites/blueprints/splitter-compact-merge.png": { - "frame": {"x":300,"y":1144,"w":93,"h":93}, + "frame": {"x":3,"y":1154,"w":93,"h":93}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":3,"y":1,"w":93,"h":93}, @@ -562,7 +562,7 @@ }, "sprites/blueprints/splitter-compact.png": { - "frame": {"x":201,"y":1208,"w":93,"h":93}, + "frame": {"x":100,"y":1154,"w":93,"h":93}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":3,"y":1,"w":93,"h":93}, @@ -570,10 +570,10 @@ }, "sprites/blueprints/splitter.png": { - "frame": {"x":3,"y":574,"w":171,"h":96}, + "frame": {"x":3,"y":574,"w":172,"h":96}, "rotated": false, "trimmed": true, - "spriteSourceSize": {"x":11,"y":0,"w":171,"h":96}, + "spriteSourceSize": {"x":11,"y":0,"w":172,"h":96}, "sourceSize": {"w":192,"h":96} }, "sprites/blueprints/stacker.png": @@ -586,7 +586,7 @@ }, "sprites/blueprints/trash-storage.png": { - "frame": {"x":528,"y":603,"w":167,"h":192}, + "frame": {"x":529,"y":603,"w":167,"h":192}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":14,"y":0,"w":167,"h":192}, @@ -602,7 +602,7 @@ }, "sprites/blueprints/underground_belt_entry-tier2.png": { - "frame": {"x":397,"y":1172,"w":93,"h":84}, + "frame": {"x":3,"y":1251,"w":93,"h":84}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":2,"y":12,"w":93,"h":84}, @@ -610,7 +610,7 @@ }, "sprites/blueprints/underground_belt_entry.png": { - "frame": {"x":298,"y":1241,"w":93,"h":75}, + "frame": {"x":100,"y":1251,"w":93,"h":75}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":2,"y":21,"w":93,"h":75}, @@ -618,7 +618,7 @@ }, "sprites/blueprints/underground_belt_exit-tier2.png": { - "frame": {"x":399,"y":1093,"w":94,"h":75}, + "frame": {"x":200,"y":1114,"w":94,"h":75}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":2,"y":0,"w":94,"h":75}, @@ -626,7 +626,7 @@ }, "sprites/blueprints/underground_belt_exit.png": { - "frame": {"x":198,"y":1305,"w":93,"h":75}, + "frame": {"x":197,"y":1288,"w":93,"h":75}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":2,"y":0,"w":93,"h":75}, @@ -642,7 +642,7 @@ }, "sprites/blueprints/virtual_processor-rotater.png": { - "frame": {"x":276,"y":1671,"w":79,"h":96}, + "frame": {"x":761,"y":1543,"w":79,"h":96}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":0,"w":79,"h":96}, @@ -650,7 +650,7 @@ }, "sprites/blueprints/virtual_processor-shapecompare.png": { - "frame": {"x":3,"y":774,"w":96,"h":89}, + "frame": {"x":3,"y":874,"w":96,"h":89}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":0,"w":96,"h":89}, @@ -658,7 +658,7 @@ }, "sprites/blueprints/virtual_processor-stacker.png": { - "frame": {"x":931,"y":903,"w":88,"h":96}, + "frame": {"x":931,"y":893,"w":88,"h":96}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":0,"w":88,"h":96}, @@ -674,7 +674,7 @@ }, "sprites/blueprints/virtual_processor.png": { - "frame": {"x":710,"y":1090,"w":96,"h":94}, + "frame": {"x":203,"y":774,"w":96,"h":94}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":2,"w":96,"h":94}, @@ -690,7 +690,7 @@ }, "sprites/blueprints/wire-split.png": { - "frame": {"x":3,"y":867,"w":96,"h":55}, + "frame": {"x":303,"y":990,"w":96,"h":55}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":41,"w":96,"h":55}, @@ -706,7 +706,7 @@ }, "sprites/blueprints/wire.png": { - "frame": {"x":699,"y":603,"w":14,"h":96}, + "frame": {"x":468,"y":894,"w":14,"h":96}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":41,"y":0,"w":14,"h":96}, @@ -722,7 +722,7 @@ }, "sprites/blueprints/wire_tunnel.png": { - "frame": {"x":101,"y":1278,"w":93,"h":91}, + "frame": {"x":197,"y":1193,"w":93,"h":91}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":2,"y":2,"w":93,"h":91}, @@ -730,7 +730,7 @@ }, "sprites/buildings/belt_left.png": { - "frame": {"x":403,"y":911,"w":87,"h":87}, + "frame": {"x":600,"y":1205,"w":87,"h":87}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":9,"w":87,"h":87}, @@ -738,7 +738,7 @@ }, "sprites/buildings/belt_right.png": { - "frame": {"x":287,"y":1489,"w":87,"h":87}, + "frame": {"x":670,"y":1381,"w":87,"h":87}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":9,"w":87,"h":87}, @@ -746,7 +746,7 @@ }, "sprites/buildings/belt_top.png": { - "frame": {"x":943,"y":803,"w":78,"h":96}, + "frame": {"x":565,"y":1569,"w":78,"h":96}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":0,"w":78,"h":96}, @@ -770,7 +770,7 @@ }, "sprites/buildings/cutter.png": { - "frame": {"x":178,"y":574,"w":171,"h":96}, + "frame": {"x":179,"y":574,"w":171,"h":96}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":11,"y":0,"w":171,"h":96}, @@ -778,7 +778,7 @@ }, "sprites/buildings/display.png": { - "frame": {"x":565,"y":1507,"w":84,"h":90}, + "frame": {"x":3,"y":1699,"w":84,"h":90}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":6,"y":6,"w":84,"h":90}, @@ -810,7 +810,7 @@ }, "sprites/buildings/logic_gate-not.png": { - "frame": {"x":372,"y":1611,"w":82,"h":96}, + "frame": {"x":939,"y":1465,"w":82,"h":96}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":8,"y":0,"w":82,"h":96}, @@ -818,7 +818,7 @@ }, "sprites/buildings/logic_gate-or.png": { - "frame": {"x":203,"y":866,"w":96,"h":83}, + "frame": {"x":303,"y":903,"w":96,"h":83}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":0,"w":96,"h":83}, @@ -834,7 +834,7 @@ }, "sprites/buildings/logic_gate-xor.png": { - "frame": {"x":610,"y":1033,"w":96,"h":95}, + "frame": {"x":103,"y":774,"w":96,"h":95}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":0,"w":96,"h":95}, @@ -842,7 +842,7 @@ }, "sprites/buildings/logic_gate.png": { - "frame": {"x":203,"y":774,"w":96,"h":88}, + "frame": {"x":3,"y":967,"w":96,"h":88}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":0,"w":96,"h":88}, @@ -850,7 +850,7 @@ }, "sprites/buildings/miner-chainable.png": { - "frame": {"x":690,"y":1188,"w":91,"h":95}, + "frame": {"x":897,"y":1093,"w":91,"h":95}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":3,"y":0,"w":91,"h":95}, @@ -858,7 +858,7 @@ }, "sprites/buildings/miner.png": { - "frame": {"x":590,"y":1226,"w":91,"h":95}, + "frame": {"x":801,"y":1171,"w":91,"h":95}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":3,"y":0,"w":91,"h":95}, @@ -906,7 +906,7 @@ }, "sprites/buildings/reader.png": { - "frame": {"x":3,"y":1026,"w":95,"h":96}, + "frame": {"x":603,"y":1008,"w":95,"h":96}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":1,"y":0,"w":95,"h":96}, @@ -914,7 +914,7 @@ }, "sprites/buildings/rotater-ccw.png": { - "frame": {"x":201,"y":1011,"w":95,"h":96}, + "frame": {"x":502,"y":1057,"w":95,"h":96}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":1,"y":0,"w":95,"h":96}, @@ -922,7 +922,7 @@ }, "sprites/buildings/rotater-fl.png": { - "frame": {"x":102,"y":1083,"w":95,"h":96}, + "frame": {"x":402,"y":1152,"w":95,"h":96}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":0,"w":95,"h":96}, @@ -930,7 +930,7 @@ }, "sprites/buildings/rotater.png": { - "frame": {"x":3,"y":1126,"w":95,"h":96}, + "frame": {"x":702,"y":1090,"w":95,"h":96}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":1,"y":0,"w":95,"h":96}, @@ -938,7 +938,7 @@ }, "sprites/buildings/splitter-compact-inverse.png": { - "frame": {"x":3,"y":1226,"w":94,"h":91}, + "frame": {"x":102,"y":1059,"w":94,"h":91}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":2,"w":94,"h":91}, @@ -946,7 +946,7 @@ }, "sprites/buildings/splitter-compact-merge-inverse.png": { - "frame": {"x":102,"y":1183,"w":95,"h":91}, + "frame": {"x":3,"y":1059,"w":95,"h":91}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":2,"w":95,"h":91}, @@ -954,7 +954,7 @@ }, "sprites/buildings/splitter-compact-merge.png": { - "frame": {"x":3,"y":1321,"w":93,"h":91}, + "frame": {"x":294,"y":1207,"w":93,"h":91}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":3,"y":2,"w":93,"h":91}, @@ -962,7 +962,7 @@ }, "sprites/buildings/splitter-compact.png": { - "frame": {"x":497,"y":1099,"w":93,"h":91}, + "frame": {"x":391,"y":1252,"w":93,"h":91}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":3,"y":2,"w":93,"h":91}, @@ -970,7 +970,7 @@ }, "sprites/buildings/splitter.png": { - "frame": {"x":353,"y":603,"w":171,"h":96}, + "frame": {"x":354,"y":603,"w":171,"h":96}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":11,"y":0,"w":171,"h":96}, @@ -986,7 +986,7 @@ }, "sprites/buildings/trash-storage.png": { - "frame": {"x":736,"y":694,"w":166,"h":192}, + "frame": {"x":737,"y":694,"w":166,"h":192}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":14,"y":0,"w":166,"h":192}, @@ -1002,7 +1002,7 @@ }, "sprites/buildings/underground_belt_entry-tier2.png": { - "frame": {"x":494,"y":1194,"w":92,"h":83}, + "frame": {"x":196,"y":1367,"w":92,"h":83}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":3,"y":13,"w":92,"h":83}, @@ -1010,7 +1010,7 @@ }, "sprites/buildings/underground_belt_entry.png": { - "frame": {"x":395,"y":1260,"w":92,"h":74}, + "frame": {"x":99,"y":1430,"w":92,"h":74}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":3,"y":22,"w":92,"h":74}, @@ -1018,7 +1018,7 @@ }, "sprites/buildings/underground_belt_exit-tier2.png": { - "frame": {"x":295,"y":1320,"w":92,"h":74}, + "frame": {"x":3,"y":1439,"w":92,"h":74}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":3,"y":0,"w":92,"h":74}, @@ -1026,7 +1026,7 @@ }, "sprites/buildings/underground_belt_exit.png": { - "frame": {"x":196,"y":1384,"w":92,"h":74}, + "frame": {"x":801,"y":1093,"w":92,"h":74}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":3,"y":0,"w":92,"h":74}, @@ -1034,7 +1034,7 @@ }, "sprites/buildings/virtual_processor-analyzer.png": { - "frame": {"x":622,"y":933,"w":96,"h":96}, + "frame": {"x":622,"y":908,"w":96,"h":96}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":96,"h":96}, @@ -1042,7 +1042,7 @@ }, "sprites/buildings/virtual_processor-rotater.png": { - "frame": {"x":185,"y":1735,"w":79,"h":96}, + "frame": {"x":663,"y":1563,"w":79,"h":96}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":9,"y":0,"w":79,"h":96}, @@ -1050,7 +1050,7 @@ }, "sprites/buildings/virtual_processor-shapecompare.png": { - "frame": {"x":103,"y":774,"w":96,"h":89}, + "frame": {"x":103,"y":966,"w":96,"h":89}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":0,"w":96,"h":89}, @@ -1058,7 +1058,7 @@ }, "sprites/buildings/virtual_processor-stacker.png": { - "frame": {"x":491,"y":1281,"w":88,"h":96}, + "frame": {"x":700,"y":1190,"w":88,"h":96}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":0,"w":88,"h":96}, @@ -1066,7 +1066,7 @@ }, "sprites/buildings/virtual_processor-unstacker.png": { - "frame": {"x":510,"y":999,"w":96,"h":96}, + "frame": {"x":831,"y":893,"w":96,"h":96}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":96,"h":96}, @@ -1074,7 +1074,7 @@ }, "sprites/buildings/virtual_processor.png": { - "frame": {"x":810,"y":1093,"w":96,"h":94}, + "frame": {"x":203,"y":872,"w":96,"h":94}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":2,"w":96,"h":94}, @@ -1082,7 +1082,7 @@ }, "sprites/buildings/wire-cross.png": { - "frame": {"x":831,"y":893,"w":96,"h":96}, + "frame": {"x":722,"y":990,"w":96,"h":96}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":96,"h":96}, @@ -1090,7 +1090,7 @@ }, "sprites/buildings/wire-split.png": { - "frame": {"x":103,"y":867,"w":96,"h":54}, + "frame": {"x":403,"y":994,"w":96,"h":54}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":42,"w":96,"h":54}, @@ -1122,7 +1122,7 @@ }, "sprites/buildings/wire_tunnel.png": { - "frame": {"x":594,"y":1132,"w":92,"h":90}, + "frame": {"x":294,"y":1302,"w":92,"h":90}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":3,"y":3,"w":92,"h":90}, @@ -1146,7 +1146,7 @@ }, "sprites/misc/hub_direction_indicator.png": { - "frame": {"x":695,"y":851,"w":32,"h":32}, + "frame": {"x":695,"y":802,"w":32,"h":32}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":32,"h":32}, @@ -1178,7 +1178,7 @@ }, "sprites/misc/slot_bad_arrow.png": { - "frame": {"x":717,"y":605,"w":24,"h":24}, + "frame": {"x":449,"y":862,"w":24,"h":24}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":1,"y":1,"w":24,"h":24}, @@ -1210,7 +1210,7 @@ }, "sprites/wires/boolean_false.png": { - "frame": {"x":717,"y":633,"w":21,"h":28}, + "frame": {"x":477,"y":862,"w":21,"h":28}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":6,"y":3,"w":21,"h":28}, @@ -1218,7 +1218,7 @@ }, "sprites/wires/boolean_true.png": { - "frame": {"x":717,"y":665,"w":15,"h":28}, + "frame": {"x":449,"y":890,"w":15,"h":28}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":7,"y":3,"w":15,"h":28}, @@ -1226,7 +1226,7 @@ }, "sprites/wires/display/blue.png": { - "frame": {"x":699,"y":703,"w":33,"h":33}, + "frame": {"x":700,"y":654,"w":33,"h":33}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":33,"h":33}, @@ -1234,7 +1234,7 @@ }, "sprites/wires/display/cyan.png": { - "frame": {"x":699,"y":740,"w":33,"h":33}, + "frame": {"x":700,"y":691,"w":33,"h":33}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":33,"h":33}, @@ -1242,7 +1242,7 @@ }, "sprites/wires/display/green.png": { - "frame": {"x":699,"y":777,"w":33,"h":33}, + "frame": {"x":700,"y":728,"w":33,"h":33}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":33,"h":33}, @@ -1250,7 +1250,7 @@ }, "sprites/wires/display/purple.png": { - "frame": {"x":906,"y":782,"w":33,"h":33}, + "frame": {"x":700,"y":765,"w":33,"h":33}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":33,"h":33}, @@ -1258,7 +1258,7 @@ }, "sprites/wires/display/red.png": { - "frame": {"x":906,"y":819,"w":33,"h":33}, + "frame": {"x":907,"y":782,"w":33,"h":33}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":33,"h":33}, @@ -1266,7 +1266,7 @@ }, "sprites/wires/display/white.png": { - "frame": {"x":906,"y":856,"w":33,"h":33}, + "frame": {"x":907,"y":819,"w":33,"h":33}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":33,"h":33}, @@ -1274,7 +1274,7 @@ }, "sprites/wires/display/yellow.png": { - "frame": {"x":695,"y":814,"w":33,"h":33}, + "frame": {"x":907,"y":856,"w":33,"h":33}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":33,"h":33}, @@ -1298,7 +1298,7 @@ }, "sprites/wires/logical_ejector.png": { - "frame": {"x":449,"y":862,"w":41,"h":45}, + "frame": {"x":700,"y":605,"w":41,"h":45}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":29,"y":0,"w":41,"h":45}, @@ -1306,7 +1306,7 @@ }, "sprites/wires/network_conflict.png": { - "frame": {"x":622,"y":899,"w":32,"h":30}, + "frame": {"x":695,"y":874,"w":32,"h":30}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":1,"w":32,"h":30}, @@ -1330,7 +1330,7 @@ }, "sprites/wires/sets/color_cross.png": { - "frame": {"x":722,"y":990,"w":96,"h":96}, + "frame": {"x":822,"y":993,"w":96,"h":96}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":96,"h":96}, @@ -1346,7 +1346,7 @@ }, "sprites/wires/sets/color_split.png": { - "frame": {"x":103,"y":925,"w":96,"h":54}, + "frame": {"x":303,"y":1049,"w":96,"h":54}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":42,"w":96,"h":54}, @@ -1362,7 +1362,7 @@ }, "sprites/wires/sets/conflict_cross.png": { - "frame": {"x":822,"y":993,"w":96,"h":96}, + "frame": {"x":922,"y":993,"w":96,"h":96}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":96,"h":96}, @@ -1378,7 +1378,7 @@ }, "sprites/wires/sets/conflict_split.png": { - "frame": {"x":203,"y":953,"w":96,"h":54}, + "frame": {"x":203,"y":1056,"w":96,"h":54}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":42,"w":96,"h":54}, @@ -1394,7 +1394,7 @@ }, "sprites/wires/sets/regular_cross.png": { - "frame": {"x":831,"y":893,"w":96,"h":96}, + "frame": {"x":722,"y":990,"w":96,"h":96}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":96,"h":96}, @@ -1410,7 +1410,7 @@ }, "sprites/wires/sets/regular_split.png": { - "frame": {"x":103,"y":867,"w":96,"h":54}, + "frame": {"x":403,"y":994,"w":96,"h":54}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":42,"w":96,"h":54}, @@ -1426,7 +1426,7 @@ }, "sprites/wires/sets/shape_cross.png": { - "frame": {"x":922,"y":1003,"w":96,"h":96}, + "frame": {"x":3,"y":774,"w":96,"h":96}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":96,"h":96}, @@ -1434,7 +1434,7 @@ }, "sprites/wires/sets/shape_forward.png": { - "frame": {"x":494,"y":903,"w":12,"h":96}, + "frame": {"x":486,"y":894,"w":12,"h":96}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":42,"y":0,"w":12,"h":96}, @@ -1442,7 +1442,7 @@ }, "sprites/wires/sets/shape_split.png": { - "frame": {"x":303,"y":989,"w":96,"h":54}, + "frame": {"x":503,"y":999,"w":96,"h":54}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":42,"w":96,"h":54}, @@ -1458,7 +1458,7 @@ }, "sprites/wires/wires_preview.png": { - "frame": {"x":695,"y":887,"w":32,"h":32}, + "frame": {"x":695,"y":838,"w":32,"h":32}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":32,"h":32}, @@ -1471,6 +1471,6 @@ "format": "RGBA8888", "size": {"w":1024,"h":2048}, "scale": "0.5", - "smartupdate": "$TexturePacker:SmartUpdate:d21082eda6f288e04b0739186004794d:0912211652d1c400e2846013f9de057b:908b89f5ca8ff73e331a35a3b14d0604$" + "smartupdate": "$TexturePacker:SmartUpdate:64d35c8d649d4bb41c7539e7e89c0865:2a9399f9a7c16dc686a4fb0941b02e6b:908b89f5ca8ff73e331a35a3b14d0604$" } } diff --git a/res_built/atlas/atlas0_mq.png b/res_built/atlas/atlas0_mq.png index 9e9b97c6..6fb0ba3d 100644 Binary files a/res_built/atlas/atlas0_mq.png and b/res_built/atlas/atlas0_mq.png differ diff --git a/res_raw/sprites/blueprints/splitter.png b/res_raw/sprites/blueprints/splitter.png index 984a99a8..52473772 100644 Binary files a/res_raw/sprites/blueprints/splitter.png and b/res_raw/sprites/blueprints/splitter.png differ diff --git a/res_raw/sprites/buildings/splitter.png b/res_raw/sprites/buildings/splitter.png index 7cd9a2ef..d1d12ad9 100644 Binary files a/res_raw/sprites/buildings/splitter.png and b/res_raw/sprites/buildings/splitter.png differ diff --git a/src/js/core/sprites.js b/src/js/core/sprites.js index bdcc65b4..928a9dcc 100644 --- a/src/js/core/sprites.js +++ b/src/js/core/sprites.js @@ -1,360 +1,393 @@ -import { DrawParameters } from "./draw_parameters"; -import { Rectangle } from "./rectangle"; -import { round3Digits } from "./utils"; - -const floorSpriteCoordinates = false; - -export const ORIGINAL_SPRITE_SCALE = "0.75"; - -export class BaseSprite { - /** - * Returns the raw handle - * @returns {HTMLImageElement|HTMLCanvasElement} - */ - getRawTexture() { - abstract; - return null; - } - - /** - * Draws the sprite - * @param {CanvasRenderingContext2D} context - * @param {number} x - * @param {number} y - * @param {number} w - * @param {number} h - */ - draw(context, x, y, w, h) { - // eslint-disable-line no-unused-vars - abstract; - } -} - -/** - * Position of a sprite within an atlas - */ -export class SpriteAtlasLink { - /** - * - * @param {object} param0 - * @param {number} param0.packedX - * @param {number} param0.packedY - * @param {number} param0.packOffsetX - * @param {number} param0.packOffsetY - * @param {number} param0.packedW - * @param {number} param0.packedH - * @param {number} param0.w - * @param {number} param0.h - * @param {HTMLImageElement|HTMLCanvasElement} param0.atlas - */ - constructor({ w, h, packedX, packedY, packOffsetX, packOffsetY, packedW, packedH, atlas }) { - this.packedX = packedX; - this.packedY = packedY; - this.packedW = packedW; - this.packedH = packedH; - this.packOffsetX = packOffsetX; - this.packOffsetY = packOffsetY; - this.atlas = atlas; - this.w = w; - this.h = h; - } -} - -export class AtlasSprite extends BaseSprite { - /** - * - * @param {string} spriteName - */ - constructor(spriteName = "sprite") { - super(); - /** @type {Object.} */ - this.linksByResolution = {}; - this.spriteName = spriteName; - } - - getRawTexture() { - return this.linksByResolution[ORIGINAL_SPRITE_SCALE].atlas; - } - - /** - * Draws the sprite onto a regular context using no contexts - * @see {BaseSprite.draw} - */ - draw(context, x, y, w, h) { - if (G_IS_DEV) { - assert(context instanceof CanvasRenderingContext2D, "Not a valid context"); - } - - const link = this.linksByResolution[ORIGINAL_SPRITE_SCALE]; - - assert( - link, - "Link not known: " + - ORIGINAL_SPRITE_SCALE + - " (having " + - Object.keys(this.linksByResolution) + - ")" - ); - - const width = w || link.w; - const height = h || link.h; - - const scaleW = width / link.w; - const scaleH = height / link.h; - - context.drawImage( - link.atlas, - - link.packedX, - link.packedY, - link.packedW, - link.packedH, - - x + link.packOffsetX * scaleW, - y + link.packOffsetY * scaleH, - link.packedW * scaleW, - link.packedH * scaleH - ); - } - - /** - * - * @param {DrawParameters} parameters - * @param {number} x - * @param {number} y - * @param {number} size - * @param {boolean=} clipping - */ - drawCachedCentered(parameters, x, y, size, clipping = true) { - this.drawCached(parameters, x - size / 2, y - size / 2, size, size, clipping); - } - - /** - * - * @param {CanvasRenderingContext2D} context - * @param {number} x - * @param {number} y - * @param {number} size - */ - drawCentered(context, x, y, size) { - this.draw(context, x - size / 2, y - size / 2, size, size); - } - - /** - * Draws the sprite - * @param {DrawParameters} parameters - * @param {number} x - * @param {number} y - * @param {number} w - * @param {number} h - * @param {boolean=} clipping Whether to perform culling - */ - drawCached(parameters, x, y, w = null, h = null, clipping = true) { - if (G_IS_DEV) { - assert(parameters instanceof DrawParameters, "Not a valid context"); - assert(!!w && w > 0, "Not a valid width:" + w); - assert(!!h && h > 0, "Not a valid height:" + h); - } - - const visibleRect = parameters.visibleRect; - - const scale = parameters.desiredAtlasScale; - const link = this.linksByResolution[scale]; - - if (!link) { - assert(false, `Link not known: ${scale} (having ${Object.keys(this.linksByResolution)})`); - } - - const scaleW = w / link.w; - const scaleH = h / link.h; - - let destX = x + link.packOffsetX * scaleW; - let destY = y + link.packOffsetY * scaleH; - let destW = link.packedW * scaleW; - let destH = link.packedH * scaleH; - - let srcX = link.packedX; - let srcY = link.packedY; - let srcW = link.packedW; - let srcH = link.packedH; - - let intersection = null; - - if (clipping) { - const rect = new Rectangle(destX, destY, destW, destH); - intersection = rect.getIntersection(visibleRect); - if (!intersection) { - return; - } - - srcX += (intersection.x - destX) / scaleW; - srcY += (intersection.y - destY) / scaleH; - - srcW *= intersection.w / destW; - srcH *= intersection.h / destH; - - destX = intersection.x; - destY = intersection.y; - - destW = intersection.w; - destH = intersection.h; - } - - if (floorSpriteCoordinates) { - parameters.context.drawImage( - link.atlas, - - // atlas src pos - Math.floor(srcX), - Math.floor(srcY), - - // atlas src size - Math.floor(srcW), - Math.floor(srcH), - - // dest pos - Math.floor(destX), - Math.floor(destY), - - // dest size - Math.floor(destW), - Math.floor(destH) - ); - } else { - parameters.context.drawImage( - link.atlas, - - // atlas src pos - srcX, - srcY, - - // atlas src siize - srcW, - srcH, - - // dest pos and size - destX, - destY, - destW, - destH - ); - } - } - - /** - * Renders into an html element - * @param {HTMLElement} element - * @param {number} w - * @param {number} h - */ - renderToHTMLElement(element, w = 1, h = 1) { - element.style.position = "relative"; - element.innerHTML = this.getAsHTML(w, h); - } - - /** - * Returns the html to render as icon - * @param {number} w - * @param {number} h - */ - getAsHTML(w, h) { - const link = this.linksByResolution["0.5"]; - - // Find out how much we have to scale it so that it fits - const scaleX = w / link.w; - const scaleY = h / link.h; - - // Find out how big the scaled atlas is - const atlasW = link.atlas.width * scaleX; - const atlasH = link.atlas.height * scaleY; - - // @ts-ignore - const srcSafe = link.atlas.src.replaceAll("\\", "/"); - - // Find out how big we render the sprite - const widthAbsolute = scaleX * link.packedW; - const heightAbsolute = scaleY * link.packedH; - - // Compute the position in the relative container - const leftRelative = (link.packOffsetX * scaleX) / w; - const topRelative = (link.packOffsetY * scaleY) / h; - const widthRelative = widthAbsolute / w; - const heightRelative = heightAbsolute / h; - - // Scale the atlas relative to the width and height of the element - const bgW = atlasW / widthAbsolute; - const bgH = atlasH / heightAbsolute; - - // Figure out what the position of the atlas is - const bgX = link.packedX * scaleX; - const bgY = link.packedY * scaleY; - - // Fuck you, whoever thought its a good idea to make background-position work like it does now - const bgXRelative = -bgX / (widthAbsolute - atlasW); - const bgYRelative = -bgY / (heightAbsolute - atlasH); - - return ` - - `; - } -} - -export class RegularSprite extends BaseSprite { - constructor(sprite, w, h) { - super(); - this.w = w; - this.h = h; - this.sprite = sprite; - } - - getRawTexture() { - return this.sprite; - } - - /** - * Draws the sprite, do *not* use this for sprites which are rendered! Only for drawing - * images into buffers - * @param {CanvasRenderingContext2D} context - * @param {number} x - * @param {number} y - * @param {number} w - * @param {number} h - */ - draw(context, x, y, w, h) { - assert(context, "No context given"); - assert(x !== undefined, "No x given"); - assert(y !== undefined, "No y given"); - assert(w !== undefined, "No width given"); - assert(h !== undefined, "No height given"); - context.drawImage(this.sprite, x, y, w, h); - } - - /** - * Draws the sprite, do *not* use this for sprites which are rendered! Only for drawing - * images into buffers - * @param {CanvasRenderingContext2D} context - * @param {number} x - * @param {number} y - * @param {number} w - * @param {number} h - */ - drawCentered(context, x, y, w, h) { - assert(context, "No context given"); - assert(x !== undefined, "No x given"); - assert(y !== undefined, "No y given"); - assert(w !== undefined, "No width given"); - assert(h !== undefined, "No height given"); - context.drawImage(this.sprite, x - w / 2, y - h / 2, w, h); - } -} +import { DrawParameters } from "./draw_parameters"; +import { Rectangle } from "./rectangle"; +import { round3Digits } from "./utils"; + +export const ORIGINAL_SPRITE_SCALE = "0.75"; +export const FULL_CLIP_RECT = new Rectangle(0, 0, 1, 1); + +export class BaseSprite { + /** + * Returns the raw handle + * @returns {HTMLImageElement|HTMLCanvasElement} + */ + getRawTexture() { + abstract; + return null; + } + + /** + * Draws the sprite + * @param {CanvasRenderingContext2D} context + * @param {number} x + * @param {number} y + * @param {number} w + * @param {number} h + */ + draw(context, x, y, w, h) { + // eslint-disable-line no-unused-vars + abstract; + } +} + +/** + * Position of a sprite within an atlas + */ +export class SpriteAtlasLink { + /** + * + * @param {object} param0 + * @param {number} param0.packedX + * @param {number} param0.packedY + * @param {number} param0.packOffsetX + * @param {number} param0.packOffsetY + * @param {number} param0.packedW + * @param {number} param0.packedH + * @param {number} param0.w + * @param {number} param0.h + * @param {HTMLImageElement|HTMLCanvasElement} param0.atlas + */ + constructor({ w, h, packedX, packedY, packOffsetX, packOffsetY, packedW, packedH, atlas }) { + this.packedX = packedX; + this.packedY = packedY; + this.packedW = packedW; + this.packedH = packedH; + this.packOffsetX = packOffsetX; + this.packOffsetY = packOffsetY; + this.atlas = atlas; + this.w = w; + this.h = h; + } +} + +export class AtlasSprite extends BaseSprite { + /** + * + * @param {string} spriteName + */ + constructor(spriteName = "sprite") { + super(); + /** @type {Object.} */ + this.linksByResolution = {}; + this.spriteName = spriteName; + } + + getRawTexture() { + return this.linksByResolution[ORIGINAL_SPRITE_SCALE].atlas; + } + + /** + * Draws the sprite onto a regular context using no contexts + * @see {BaseSprite.draw} + */ + draw(context, x, y, w, h) { + if (G_IS_DEV) { + assert(context instanceof CanvasRenderingContext2D, "Not a valid context"); + } + + const link = this.linksByResolution[ORIGINAL_SPRITE_SCALE]; + + assert( + link, + "Link not known: " + + ORIGINAL_SPRITE_SCALE + + " (having " + + Object.keys(this.linksByResolution) + + ")" + ); + + const width = w || link.w; + const height = h || link.h; + + const scaleW = width / link.w; + const scaleH = height / link.h; + + context.drawImage( + link.atlas, + + link.packedX, + link.packedY, + link.packedW, + link.packedH, + + x + link.packOffsetX * scaleW, + y + link.packOffsetY * scaleH, + link.packedW * scaleW, + link.packedH * scaleH + ); + } + + /** + * + * @param {DrawParameters} parameters + * @param {number} x + * @param {number} y + * @param {number} size + * @param {boolean=} clipping + */ + drawCachedCentered(parameters, x, y, size, clipping = true) { + this.drawCached(parameters, x - size / 2, y - size / 2, size, size, clipping); + } + + /** + * + * @param {CanvasRenderingContext2D} context + * @param {number} x + * @param {number} y + * @param {number} size + */ + drawCentered(context, x, y, size) { + this.draw(context, x - size / 2, y - size / 2, size, size); + } + + /** + * Draws the sprite + * @param {DrawParameters} parameters + * @param {number} x + * @param {number} y + * @param {number} w + * @param {number} h + * @param {boolean=} clipping Whether to perform culling + */ + drawCached(parameters, x, y, w = null, h = null, clipping = true) { + if (G_IS_DEV) { + assert(parameters instanceof DrawParameters, "Not a valid context"); + assert(!!w && w > 0, "Not a valid width:" + w); + assert(!!h && h > 0, "Not a valid height:" + h); + } + + const visibleRect = parameters.visibleRect; + + const scale = parameters.desiredAtlasScale; + const link = this.linksByResolution[scale]; + + if (!link) { + assert(false, `Link not known: ${scale} (having ${Object.keys(this.linksByResolution)})`); + } + + const scaleW = w / link.w; + const scaleH = h / link.h; + + let destX = x + link.packOffsetX * scaleW; + let destY = y + link.packOffsetY * scaleH; + let destW = link.packedW * scaleW; + let destH = link.packedH * scaleH; + + let srcX = link.packedX; + let srcY = link.packedY; + let srcW = link.packedW; + let srcH = link.packedH; + + let intersection = null; + + if (clipping) { + const rect = new Rectangle(destX, destY, destW, destH); + intersection = rect.getIntersection(visibleRect); + if (!intersection) { + return; + } + + srcX += (intersection.x - destX) / scaleW; + srcY += (intersection.y - destY) / scaleH; + + srcW *= intersection.w / destW; + srcH *= intersection.h / destH; + + destX = intersection.x; + destY = intersection.y; + + destW = intersection.w; + destH = intersection.h; + } + + parameters.context.drawImage( + link.atlas, + + // atlas src pos + srcX, + srcY, + + // atlas src siize + srcW, + srcH, + + // dest pos and size + destX, + destY, + destW, + destH + ); + } + + /** + * Draws a subset of the sprite. Does NO culling + * @param {DrawParameters} parameters + * @param {number} x + * @param {number} y + * @param {number} w + * @param {number} h + * @param {Rectangle=} clipRect The rectangle in local space (0 ... 1) to draw of the image + */ + drawCachedWithClipRect(parameters, x, y, w = null, h = null, clipRect = FULL_CLIP_RECT) { + if (G_IS_DEV) { + assert(parameters instanceof DrawParameters, "Not a valid context"); + assert(!!w && w > 0, "Not a valid width:" + w); + assert(!!h && h > 0, "Not a valid height:" + h); + assert(clipRect, "No clip rect given!"); + } + + const scale = parameters.desiredAtlasScale; + const link = this.linksByResolution[scale]; + + if (!link) { + assert(false, `Link not known: ${scale} (having ${Object.keys(this.linksByResolution)})`); + } + + const scaleW = w / link.w; + const scaleH = h / link.h; + + let destX = x + link.packOffsetX * scaleW + clipRect.x * w; + let destY = y + link.packOffsetY * scaleH + clipRect.y * h; + let destW = link.packedW * scaleW * clipRect.w; + let destH = link.packedH * scaleH * clipRect.h; + + let srcX = link.packedX + clipRect.x * link.packedW; + let srcY = link.packedY + clipRect.y * link.packedH; + let srcW = link.packedW * clipRect.w; + let srcH = link.packedH * clipRect.h; + + parameters.context.drawImage( + link.atlas, + + // atlas src pos + srcX, + srcY, + + // atlas src siize + srcW, + srcH, + + // dest pos and size + destX, + destY, + destW, + destH + ); + } + + /** + * Renders into an html element + * @param {HTMLElement} element + * @param {number} w + * @param {number} h + */ + renderToHTMLElement(element, w = 1, h = 1) { + element.style.position = "relative"; + element.innerHTML = this.getAsHTML(w, h); + } + + /** + * Returns the html to render as icon + * @param {number} w + * @param {number} h + */ + getAsHTML(w, h) { + const link = this.linksByResolution["0.5"]; + + // Find out how much we have to scale it so that it fits + const scaleX = w / link.w; + const scaleY = h / link.h; + + // Find out how big the scaled atlas is + const atlasW = link.atlas.width * scaleX; + const atlasH = link.atlas.height * scaleY; + + // @ts-ignore + const srcSafe = link.atlas.src.replaceAll("\\", "/"); + + // Find out how big we render the sprite + const widthAbsolute = scaleX * link.packedW; + const heightAbsolute = scaleY * link.packedH; + + // Compute the position in the relative container + const leftRelative = (link.packOffsetX * scaleX) / w; + const topRelative = (link.packOffsetY * scaleY) / h; + const widthRelative = widthAbsolute / w; + const heightRelative = heightAbsolute / h; + + // Scale the atlas relative to the width and height of the element + const bgW = atlasW / widthAbsolute; + const bgH = atlasH / heightAbsolute; + + // Figure out what the position of the atlas is + const bgX = link.packedX * scaleX; + const bgY = link.packedY * scaleY; + + // Fuck you, whoever thought its a good idea to make background-position work like it does now + const bgXRelative = -bgX / (widthAbsolute - atlasW); + const bgYRelative = -bgY / (heightAbsolute - atlasH); + + return ` + + `; + } +} + +export class RegularSprite extends BaseSprite { + constructor(sprite, w, h) { + super(); + this.w = w; + this.h = h; + this.sprite = sprite; + } + + getRawTexture() { + return this.sprite; + } + + /** + * Draws the sprite, do *not* use this for sprites which are rendered! Only for drawing + * images into buffers + * @param {CanvasRenderingContext2D} context + * @param {number} x + * @param {number} y + * @param {number} w + * @param {number} h + */ + draw(context, x, y, w, h) { + assert(context, "No context given"); + assert(x !== undefined, "No x given"); + assert(y !== undefined, "No y given"); + assert(w !== undefined, "No width given"); + assert(h !== undefined, "No height given"); + context.drawImage(this.sprite, x, y, w, h); + } + + /** + * Draws the sprite, do *not* use this for sprites which are rendered! Only for drawing + * images into buffers + * @param {CanvasRenderingContext2D} context + * @param {number} x + * @param {number} y + * @param {number} w + * @param {number} h + */ + drawCentered(context, x, y, w, h) { + assert(context, "No context given"); + assert(x !== undefined, "No x given"); + assert(y !== undefined, "No y given"); + assert(w !== undefined, "No width given"); + assert(h !== undefined, "No height given"); + context.drawImage(this.sprite, x - w / 2, y - h / 2, w, h); + } +} diff --git a/src/js/core/stale_area_detector.js b/src/js/core/stale_area_detector.js index f8e77f0c..06415fd2 100644 --- a/src/js/core/stale_area_detector.js +++ b/src/js/core/stale_area_detector.js @@ -1,50 +1,86 @@ -import { createLogger } from "./logging"; -import { Rectangle } from "./rectangle"; -import { globalConfig } from "./config"; - -const logger = createLogger("stale_areas"); - -export class StaleAreaDetector { - /** - * - * @param {object} param0 - * @param {import("../game/root").GameRoot} param0.root - * @param {string} param0.name The name for reference - * @param {(Rectangle) => void} param0.recomputeMethod Method which recomputes the given area - */ - constructor({ root, name, recomputeMethod }) { - this.root = root; - this.name = name; - this.recomputeMethod = recomputeMethod; - - /** @type {Rectangle} */ - this.staleArea = null; - } - - /** - * Invalidates the given area - * @param {Rectangle} area - */ - invalidate(area) { - // logger.log(this.name, "invalidated", area.toString()); - if (this.staleArea) { - this.staleArea = this.staleArea.getUnion(area); - } else { - this.staleArea = area.clone(); - } - } - - /** - * Updates the stale area - */ - update() { - if (this.staleArea) { - logger.log(this.name, "is recomputing", this.staleArea.toString()); - if (G_IS_DEV && globalConfig.debug.renderChanges) { - this.root.hud.parts.changesDebugger.renderChange(this.name, this.staleArea, "#fd145b"); - } - this.recomputeMethod(this.staleArea); - this.staleArea = null; - } - } -} +import { Component } from "../game/component"; +import { Entity } from "../game/entity"; +import { globalConfig } from "./config"; +import { createLogger } from "./logging"; +import { Rectangle } from "./rectangle"; + +const logger = createLogger("stale_areas"); + +export class StaleAreaDetector { + /** + * + * @param {object} param0 + * @param {import("../game/root").GameRoot} param0.root + * @param {string} param0.name The name for reference + * @param {(Rectangle) => void} param0.recomputeMethod Method which recomputes the given area + */ + constructor({ root, name, recomputeMethod }) { + this.root = root; + this.name = name; + this.recomputeMethod = recomputeMethod; + + /** @type {Rectangle} */ + this.staleArea = null; + } + + /** + * Invalidates the given area + * @param {Rectangle} area + */ + invalidate(area) { + // logger.log(this.name, "invalidated", area.toString()); + if (this.staleArea) { + this.staleArea = this.staleArea.getUnion(area); + } else { + this.staleArea = area.clone(); + } + } + + /** + * Makes this detector recompute the area of an entity whenever + * it changes in any way + * @param {Array} components + * @param {number} tilesAround + */ + recomputeOnComponentsChanged(components, tilesAround = 1) { + const componentIds = components.map(component => component.getId()); + + /** + * Internal checker method + * @param {Entity} entity + */ + const checker = entity => { + // Check for all components + for (let i = 0; i < componentIds.length; ++i) { + if (entity.components[componentIds[i]]) { + // Entity is relevant, compute affected area + const area = entity.components.StaticMapEntity.getTileSpaceBounds().expandedInAllDirections( + tilesAround + ); + this.invalidate(area); + return; + } + } + }; + + this.root.signals.entityAdded.add(checker); + this.root.signals.entityChanged.add(checker); + this.root.signals.entityComponentRemoved.add(checker); + this.root.signals.entityGotNewComponent.add(checker); + this.root.signals.entityDestroyed.add(checker); + } + + /** + * Updates the stale area + */ + update() { + if (this.staleArea) { + logger.log(this.name, "is recomputing", this.staleArea.toString()); + if (G_IS_DEV && globalConfig.debug.renderChanges) { + this.root.hud.parts.changesDebugger.renderChange(this.name, this.staleArea, "#fd145b"); + } + this.recomputeMethod(this.staleArea); + this.staleArea = null; + } + } +} diff --git a/src/js/game/buildings/splitter.js b/src/js/game/buildings/splitter.js index d512e002..c58d593d 100644 --- a/src/js/game/buildings/splitter.js +++ b/src/js/game/buildings/splitter.js @@ -96,6 +96,7 @@ export class MetaSplitterBuilding extends MetaBuilding { entity.addComponent( new ItemEjectorComponent({ slots: [], // set later + renderFloatingItems: false, }) ); diff --git a/src/js/game/components/belt_underlays.js b/src/js/game/components/belt_underlays.js index cb516b1a..c794564f 100644 --- a/src/js/game/components/belt_underlays.js +++ b/src/js/game/components/belt_underlays.js @@ -1,33 +1,56 @@ -import { Component } from "../component"; -import { types } from "../../savegame/serialization"; -import { enumDirection, Vector } from "../../core/vector"; - -export class BeltUnderlaysComponent extends Component { - static getId() { - return "BeltUnderlays"; - } - - duplicateWithoutContents() { - const beltUnderlaysCopy = []; - for (let i = 0; i < this.underlays.length; ++i) { - const underlay = this.underlays[i]; - beltUnderlaysCopy.push({ - pos: underlay.pos.copy(), - direction: underlay.direction, - }); - } - - return new BeltUnderlaysComponent({ - underlays: beltUnderlaysCopy, - }); - } - - /** - * @param {object} param0 - * @param {Array<{pos: Vector, direction: enumDirection}>=} param0.underlays Where to render belt underlays - */ - constructor({ underlays }) { - super(); - this.underlays = underlays; - } -} +import { enumDirection, Vector } from "../../core/vector"; +import { Component } from "../component"; + +/** + * Store which type an underlay is, this is cached so we can easily + * render it. + * + * Full: Render underlay at top and bottom of tile + * Bottom Only: Only render underlay at the bottom half + * Top Only: + * @enum {string} + */ +export const enumClippedBeltUnderlayType = { + full: "full", + bottomOnly: "bottomOnly", + topOnly: "topOnly", + none: "none", +}; + +/** + * @typedef {{ + * pos: Vector, + * direction: enumDirection, + * cachedType?: enumClippedBeltUnderlayType + * }} BeltUnderlayTile + */ + +export class BeltUnderlaysComponent extends Component { + static getId() { + return "BeltUnderlays"; + } + + duplicateWithoutContents() { + const beltUnderlaysCopy = []; + for (let i = 0; i < this.underlays.length; ++i) { + const underlay = this.underlays[i]; + beltUnderlaysCopy.push({ + pos: underlay.pos.copy(), + direction: underlay.direction, + }); + } + + return new BeltUnderlaysComponent({ + underlays: beltUnderlaysCopy, + }); + } + + /** + * @param {object} param0 + * @param {Array=} param0.underlays Where to render belt underlays + */ + constructor({ underlays = [] }) { + super(); + this.underlays = underlays; + } +} diff --git a/src/js/game/components/item_ejector.js b/src/js/game/components/item_ejector.js index b9a23c38..7839ba0a 100644 --- a/src/js/game/components/item_ejector.js +++ b/src/js/game/components/item_ejector.js @@ -1,161 +1,159 @@ -import { enumDirection, enumDirectionToVector, Vector } from "../../core/vector"; -import { types } from "../../savegame/serialization"; -import { BaseItem } from "../base_item"; -import { BeltPath } from "../belt_path"; -import { Component } from "../component"; -import { Entity } from "../entity"; -import { typeItemSingleton } from "../item_resolver"; - -/** - * @typedef {{ - * pos: Vector, - * direction: enumDirection, - * item: BaseItem, - * progress: number?, - * cachedDestSlot?: import("./item_acceptor").ItemAcceptorLocatedSlot, - * cachedBeltPath?: BeltPath, - * cachedTargetEntity?: Entity - * }} ItemEjectorSlot - */ - -export class ItemEjectorComponent extends Component { - static getId() { - return "ItemEjector"; - } - - static getSchema() { - // The cachedDestSlot, cachedTargetEntity fields are not serialized. - return { - slots: types.array( - types.structured({ - item: types.nullable(typeItemSingleton), - progress: types.float, - }) - ), - }; - } - - duplicateWithoutContents() { - const slotsCopy = []; - for (let i = 0; i < this.slots.length; ++i) { - const slot = this.slots[i]; - slotsCopy.push({ - pos: slot.pos.copy(), - direction: slot.direction, - }); - } - - return new ItemEjectorComponent({ - slots: slotsCopy, - }); - } - - /** - * - * @param {object} param0 - * @param {Array<{pos: Vector, direction: enumDirection }>=} param0.slots The slots to eject on - */ - constructor({ slots = [] }) { - super(); - - this.setSlots(slots); - - /** - * Whether this ejector slot is enabled - */ - this.enabled = true; - } - - /** - * @param {Array<{pos: Vector, direction: enumDirection }>} slots The slots to eject on - */ - setSlots(slots) { - /** @type {Array} */ - this.slots = []; - for (let i = 0; i < slots.length; ++i) { - const slot = slots[i]; - this.slots.push({ - pos: slot.pos, - direction: slot.direction, - item: null, - progress: 0, - cachedDestSlot: null, - cachedTargetEntity: null, - }); - } - } - - /** - * Returns where this slot ejects to - * @param {ItemEjectorSlot} slot - * @returns {Vector} - */ - getSlotTargetLocalTile(slot) { - const directionVector = enumDirectionToVector[slot.direction]; - return slot.pos.add(directionVector); - } - - /** - * Returns whether any slot ejects to the given local tile - * @param {Vector} tile - */ - anySlotEjectsToLocalTile(tile) { - for (let i = 0; i < this.slots.length; ++i) { - if (this.getSlotTargetLocalTile(this.slots[i]).equals(tile)) { - return true; - } - } - return false; - } - - /** - * Returns if we can eject on a given slot - * @param {number} slotIndex - * @returns {boolean} - */ - canEjectOnSlot(slotIndex) { - assert(slotIndex >= 0 && slotIndex < this.slots.length, "Invalid ejector slot: " + slotIndex); - return !this.slots[slotIndex].item; - } - - /** - * Returns the first free slot on this ejector or null if there is none - * @returns {number?} - */ - getFirstFreeSlot() { - for (let i = 0; i < this.slots.length; ++i) { - if (this.canEjectOnSlot(i)) { - return i; - } - } - return null; - } - - /** - * Tries to eject a given item - * @param {number} slotIndex - * @param {BaseItem} item - * @returns {boolean} - */ - tryEject(slotIndex, item) { - if (!this.canEjectOnSlot(slotIndex)) { - return false; - } - this.slots[slotIndex].item = item; - this.slots[slotIndex].progress = 0; - return true; - } - - /** - * Clears the given slot and returns the item it had - * @param {number} slotIndex - * @returns {BaseItem|null} - */ - takeSlotItem(slotIndex) { - const slot = this.slots[slotIndex]; - const item = slot.item; - slot.item = null; - slot.progress = 0.0; - return item; - } -} +import { enumDirection, enumDirectionToVector, Vector } from "../../core/vector"; +import { types } from "../../savegame/serialization"; +import { BaseItem } from "../base_item"; +import { BeltPath } from "../belt_path"; +import { Component } from "../component"; +import { Entity } from "../entity"; +import { typeItemSingleton } from "../item_resolver"; + +/** + * @typedef {{ + * pos: Vector, + * direction: enumDirection, + * item: BaseItem, + * progress: number?, + * cachedDestSlot?: import("./item_acceptor").ItemAcceptorLocatedSlot, + * cachedBeltPath?: BeltPath, + * cachedTargetEntity?: Entity + * }} ItemEjectorSlot + */ + +export class ItemEjectorComponent extends Component { + static getId() { + return "ItemEjector"; + } + + static getSchema() { + // The cachedDestSlot, cachedTargetEntity fields are not serialized. + return { + slots: types.array( + types.structured({ + item: types.nullable(typeItemSingleton), + progress: types.float, + }) + ), + }; + } + + duplicateWithoutContents() { + const slotsCopy = []; + for (let i = 0; i < this.slots.length; ++i) { + const slot = this.slots[i]; + slotsCopy.push({ + pos: slot.pos.copy(), + direction: slot.direction, + }); + } + + return new ItemEjectorComponent({ + slots: slotsCopy, + renderFloatingItems: this.renderFloatingItems, + }); + } + + /** + * + * @param {object} param0 + * @param {Array<{pos: Vector, direction: enumDirection }>=} param0.slots The slots to eject on + * @param {boolean=} param0.renderFloatingItems Whether to render items even if they are not connected + */ + constructor({ slots = [], renderFloatingItems = true }) { + super(); + + this.setSlots(slots); + this.renderFloatingItems = renderFloatingItems; + } + + /** + * @param {Array<{pos: Vector, direction: enumDirection }>} slots The slots to eject on + */ + setSlots(slots) { + /** @type {Array} */ + this.slots = []; + for (let i = 0; i < slots.length; ++i) { + const slot = slots[i]; + this.slots.push({ + pos: slot.pos, + direction: slot.direction, + item: null, + progress: 0, + cachedDestSlot: null, + cachedTargetEntity: null, + }); + } + } + + /** + * Returns where this slot ejects to + * @param {ItemEjectorSlot} slot + * @returns {Vector} + */ + getSlotTargetLocalTile(slot) { + const directionVector = enumDirectionToVector[slot.direction]; + return slot.pos.add(directionVector); + } + + /** + * Returns whether any slot ejects to the given local tile + * @param {Vector} tile + */ + anySlotEjectsToLocalTile(tile) { + for (let i = 0; i < this.slots.length; ++i) { + if (this.getSlotTargetLocalTile(this.slots[i]).equals(tile)) { + return true; + } + } + return false; + } + + /** + * Returns if we can eject on a given slot + * @param {number} slotIndex + * @returns {boolean} + */ + canEjectOnSlot(slotIndex) { + assert(slotIndex >= 0 && slotIndex < this.slots.length, "Invalid ejector slot: " + slotIndex); + return !this.slots[slotIndex].item; + } + + /** + * Returns the first free slot on this ejector or null if there is none + * @returns {number?} + */ + getFirstFreeSlot() { + for (let i = 0; i < this.slots.length; ++i) { + if (this.canEjectOnSlot(i)) { + return i; + } + } + return null; + } + + /** + * Tries to eject a given item + * @param {number} slotIndex + * @param {BaseItem} item + * @returns {boolean} + */ + tryEject(slotIndex, item) { + if (!this.canEjectOnSlot(slotIndex)) { + return false; + } + this.slots[slotIndex].item = item; + this.slots[slotIndex].progress = 0; + return true; + } + + /** + * Clears the given slot and returns the item it had + * @param {number} slotIndex + * @returns {BaseItem|null} + */ + takeSlotItem(slotIndex) { + const slot = this.slots[slotIndex]; + const item = slot.item; + slot.item = null; + slot.progress = 0.0; + return item; + } +} diff --git a/src/js/game/systems/belt_underlays.js b/src/js/game/systems/belt_underlays.js index 5bdf2331..f180b82d 100644 --- a/src/js/game/systems/belt_underlays.js +++ b/src/js/game/systems/belt_underlays.js @@ -1,84 +1,300 @@ -import { globalConfig } from "../../core/config"; -import { drawRotatedSprite } from "../../core/draw_utils"; -import { Loader } from "../../core/loader"; -import { enumDirectionToAngle } from "../../core/vector"; -import { BeltUnderlaysComponent } from "../components/belt_underlays"; -import { GameSystemWithFilter } from "../game_system_with_filter"; -import { BELT_ANIM_COUNT } from "./belt"; -import { MapChunkView } from "../map_chunk_view"; -import { DrawParameters } from "../../core/draw_parameters"; - -export class BeltUnderlaysSystem extends GameSystemWithFilter { - constructor(root) { - super(root, [BeltUnderlaysComponent]); - - this.underlayBeltSprites = []; - - for (let i = 0; i < BELT_ANIM_COUNT; ++i) { - this.underlayBeltSprites.push(Loader.getSprite("sprites/belt/built/forward_" + i + ".png")); - } - } - - /** - * Draws a given chunk - * @param {DrawParameters} parameters - * @param {MapChunkView} chunk - */ - drawChunk(parameters, chunk) { - // Limit speed to avoid belts going backwards - const speedMultiplier = Math.min(this.root.hubGoals.getBeltBaseSpeed(), 10); - - const contents = chunk.containedEntitiesByLayer.regular; - for (let i = 0; i < contents.length; ++i) { - const entity = contents[i]; - const underlayComp = entity.components.BeltUnderlays; - if (!underlayComp) { - continue; - } - - const staticComp = entity.components.StaticMapEntity; - const underlays = underlayComp.underlays; - for (let i = 0; i < underlays.length; ++i) { - const { pos, direction } = underlays[i]; - const transformedPos = staticComp.localTileToWorld(pos); - - // Culling - if (!chunk.tileSpaceRectangle.containsPoint(transformedPos.x, transformedPos.y)) { - continue; - } - - const destX = transformedPos.x * globalConfig.tileSize; - const destY = transformedPos.y * globalConfig.tileSize; - - // Culling, #2 - if ( - !parameters.visibleRect.containsRect4Params( - destX, - destY, - globalConfig.tileSize, - globalConfig.tileSize - ) - ) { - continue; - } - - const angle = enumDirectionToAngle[staticComp.localDirectionToWorld(direction)]; - - // SYNC with systems/belt.js:drawSingleEntity! - const animationIndex = Math.floor( - ((this.root.time.realtimeNow() * speedMultiplier * BELT_ANIM_COUNT * 126) / 42) * - globalConfig.itemSpacingOnBelts - ); - - drawRotatedSprite({ - parameters, - sprite: this.underlayBeltSprites[animationIndex % this.underlayBeltSprites.length], - x: destX + globalConfig.halfTileSize, - y: destY + globalConfig.halfTileSize, - angle: Math.radians(angle), - size: globalConfig.tileSize, - }); - } - } - } -} +import { globalConfig } from "../../core/config"; +import { DrawParameters } from "../../core/draw_parameters"; +import { Loader } from "../../core/loader"; +import { Rectangle } from "../../core/rectangle"; +import { FULL_CLIP_RECT } from "../../core/sprites"; +import { StaleAreaDetector } from "../../core/stale_area_detector"; +import { + enumDirection, + enumDirectionToAngle, + enumDirectionToVector, + enumInvertedDirections, + Vector, +} from "../../core/vector"; +import { BeltComponent } from "../components/belt"; +import { BeltUnderlaysComponent, enumClippedBeltUnderlayType } from "../components/belt_underlays"; +import { ItemAcceptorComponent } from "../components/item_acceptor"; +import { ItemEjectorComponent } from "../components/item_ejector"; +import { Entity } from "../entity"; +import { GameSystemWithFilter } from "../game_system_with_filter"; +import { MapChunkView } from "../map_chunk_view"; +import { BELT_ANIM_COUNT } from "./belt"; + +/** + * Mapping from underlay type to clip rect + * @type {Object} + */ +const enumUnderlayTypeToClipRect = { + [enumClippedBeltUnderlayType.none]: null, + [enumClippedBeltUnderlayType.full]: FULL_CLIP_RECT, + [enumClippedBeltUnderlayType.topOnly]: new Rectangle(0, 0, 1, 0.5), + [enumClippedBeltUnderlayType.bottomOnly]: new Rectangle(0, 0.5, 1, 0.5), +}; + +export class BeltUnderlaysSystem extends GameSystemWithFilter { + constructor(root) { + super(root, [BeltUnderlaysComponent]); + + this.underlayBeltSprites = []; + + for (let i = 0; i < BELT_ANIM_COUNT; ++i) { + this.underlayBeltSprites.push(Loader.getSprite("sprites/belt/built/forward_" + i + ".png")); + } + + // Automatically recompute areas + this.staleArea = new StaleAreaDetector({ + root, + name: "belt-underlay", + recomputeMethod: this.recomputeStaleArea.bind(this), + }); + + this.staleArea.recomputeOnComponentsChanged( + [BeltUnderlaysComponent, BeltComponent, ItemAcceptorComponent, ItemEjectorComponent], + 1 + ); + } + + update() { + this.staleArea.update(); + } + + /** + * Called when an area changed - Resets all caches in the given area + * @param {Rectangle} area + */ + recomputeStaleArea(area) { + for (let x = 0; x < area.w; ++x) { + for (let y = 0; y < area.h; ++y) { + const tileX = area.x + x; + const tileY = area.y + y; + const entity = this.root.map.getLayerContentXY(tileX, tileY, "regular"); + if (entity) { + const underlayComp = entity.components.BeltUnderlays; + if (underlayComp) { + for (let i = 0; i < underlayComp.underlays.length; ++i) { + underlayComp.underlays[i].cachedType = null; + } + } + } + } + } + } + + /** + * Checks if a given tile is connected and has an acceptor + * @param {Vector} tile + * @param {enumDirection} fromDirection + * @returns {boolean} + */ + checkIsAcceptorConnected(tile, fromDirection) { + const contents = this.root.map.getLayerContentXY(tile.x, tile.y, "regular"); + if (!contents) { + return false; + } + + const staticComp = contents.components.StaticMapEntity; + + // Check if its a belt, since then its simple + const beltComp = contents.components.Belt; + if (beltComp) { + return staticComp.localDirectionToWorld(enumDirection.bottom) === fromDirection; + } + + // Check if there's an item acceptor + const acceptorComp = contents.components.ItemAcceptor; + if (acceptorComp) { + // Check each slot to see if its connected + for (let i = 0; i < acceptorComp.slots.length; ++i) { + const slot = acceptorComp.slots[i]; + const slotTile = staticComp.localTileToWorld(slot.pos); + + // Step 1: Check if the tile matches + if (!slotTile.equals(tile)) { + continue; + } + + // Step 2: Check if any of the directions matches + for (let j = 0; j < slot.directions.length; ++j) { + const slotDirection = staticComp.localDirectionToWorld(slot.directions[j]); + if (slotDirection === fromDirection) { + return true; + } + } + } + } + + return false; + } + + /** + * Checks if a given tile is connected and has an ejector + * @param {Vector} tile + * @param {enumDirection} toDirection + * @returns {boolean} + */ + checkIsEjectorConnected(tile, toDirection) { + const contents = this.root.map.getLayerContentXY(tile.x, tile.y, "regular"); + if (!contents) { + return false; + } + + const staticComp = contents.components.StaticMapEntity; + + // Check if its a belt, since then its simple + const beltComp = contents.components.Belt; + if (beltComp) { + return staticComp.localDirectionToWorld(beltComp.direction) === toDirection; + } + + // Check for an ejector + const ejectorComp = contents.components.ItemEjector; + if (ejectorComp) { + // Check each slot to see if its connected + for (let i = 0; i < ejectorComp.slots.length; ++i) { + const slot = ejectorComp.slots[i]; + const slotTile = staticComp.localTileToWorld(slot.pos); + + // Step 1: Check if the tile matches + if (!slotTile.equals(tile)) { + continue; + } + + // Step 2: Check if the direction matches + const slotDirection = staticComp.localDirectionToWorld(slot.direction); + if (slotDirection === toDirection) { + return true; + } + } + } + + return false; + } + + /** + * Computes the flag for a given tile + * @param {Entity} entity + * @param {import("../components/belt_underlays").BeltUnderlayTile} underlayTile + * @returns {enumClippedBeltUnderlayType} The type of the underlay + */ + computeBeltUnderlayType(entity, underlayTile) { + if (underlayTile.cachedType) { + return underlayTile.cachedType; + } + + const staticComp = entity.components.StaticMapEntity; + + const transformedPos = staticComp.localTileToWorld(underlayTile.pos); + const destX = transformedPos.x * globalConfig.tileSize; + const destY = transformedPos.y * globalConfig.tileSize; + + // Extract direction and angle + const worldDirection = staticComp.localDirectionToWorld(underlayTile.direction); + const worldDirectionVector = enumDirectionToVector[worldDirection]; + + // Figure out if there is anything connected at the top + const connectedTop = this.checkIsAcceptorConnected( + transformedPos.add(worldDirectionVector), + enumInvertedDirections[worldDirection] + ); + + // Figure out if there is anything connected at the bottom + const connectedBottom = this.checkIsEjectorConnected( + transformedPos.sub(worldDirectionVector), + worldDirection + ); + + let flag = enumClippedBeltUnderlayType.none; + + if (connectedTop && connectedBottom) { + flag = enumClippedBeltUnderlayType.full; + } else if (connectedTop) { + flag = enumClippedBeltUnderlayType.topOnly; + } else if (connectedBottom) { + flag = enumClippedBeltUnderlayType.bottomOnly; + } + + return (underlayTile.cachedType = flag); + } + + /** + * Draws a given chunk + * @param {DrawParameters} parameters + * @param {MapChunkView} chunk + */ + drawChunk(parameters, chunk) { + // Limit speed to avoid belts going backwards + const speedMultiplier = Math.min(this.root.hubGoals.getBeltBaseSpeed(), 10); + + const contents = chunk.containedEntitiesByLayer.regular; + for (let i = 0; i < contents.length; ++i) { + const entity = contents[i]; + const underlayComp = entity.components.BeltUnderlays; + if (!underlayComp) { + continue; + } + + const staticComp = entity.components.StaticMapEntity; + const underlays = underlayComp.underlays; + for (let i = 0; i < underlays.length; ++i) { + // Extract underlay parameters + const { pos, direction } = underlays[i]; + const transformedPos = staticComp.localTileToWorld(pos); + const destX = transformedPos.x * globalConfig.tileSize; + const destY = transformedPos.y * globalConfig.tileSize; + + // Culling, Part 1: Check if the chunk contains the tile + if (!chunk.tileSpaceRectangle.containsPoint(transformedPos.x, transformedPos.y)) { + continue; + } + + // Culling, Part 2: Check if the overlay is visible + if ( + !parameters.visibleRect.containsRect4Params( + destX, + destY, + globalConfig.tileSize, + globalConfig.tileSize + ) + ) { + continue; + } + + // Extract direction and angle + const worldDirection = staticComp.localDirectionToWorld(direction); + const angle = enumDirectionToAngle[worldDirection]; + + const underlayType = this.computeBeltUnderlayType(entity, underlays[i]); + const clipRect = enumUnderlayTypeToClipRect[underlayType]; + if (!clipRect) { + // Empty + return; + } + + // Actually draw the sprite + const x = destX + globalConfig.halfTileSize; + const y = destY + globalConfig.halfTileSize; + const angleRadians = Math.radians(angle); + + // SYNC with systems/belt.js:drawSingleEntity! + const animationIndex = Math.floor( + ((this.root.time.realtimeNow() * speedMultiplier * BELT_ANIM_COUNT * 126) / 42) * + globalConfig.itemSpacingOnBelts + ); + parameters.context.translate(x, y); + parameters.context.rotate(angleRadians); + this.underlayBeltSprites[ + animationIndex % this.underlayBeltSprites.length + ].drawCachedWithClipRect( + parameters, + -globalConfig.halfTileSize, + -globalConfig.halfTileSize, + globalConfig.tileSize, + globalConfig.tileSize, + clipRect + ); + parameters.context.rotate(-angleRadians); + parameters.context.translate(-x, -y); + } + } + } +} diff --git a/src/js/game/systems/item_ejector.js b/src/js/game/systems/item_ejector.js index 925dcc2e..8fe1cbc5 100644 --- a/src/js/game/systems/item_ejector.js +++ b/src/js/game/systems/item_ejector.js @@ -198,9 +198,6 @@ export class ItemEjectorSystem extends GameSystemWithFilter { for (let i = 0; i < this.allEntities.length; ++i) { const sourceEntity = this.allEntities[i]; const sourceEjectorComp = sourceEntity.components.ItemEjector; - if (!sourceEjectorComp.enabled) { - continue; - } const slots = sourceEjectorComp.slots; for (let j = 0; j < slots.length; ++j) { @@ -211,8 +208,6 @@ export class ItemEjectorSystem extends GameSystemWithFilter { continue; } - const targetEntity = sourceSlot.cachedTargetEntity; - // Advance items on the slot sourceSlot.progress = Math.min( 1, @@ -245,15 +240,16 @@ export class ItemEjectorSystem extends GameSystemWithFilter { } // Check if the target acceptor can actually accept this item + const destEntity = sourceSlot.cachedTargetEntity; const destSlot = sourceSlot.cachedDestSlot; if (destSlot) { - const targetAcceptorComp = targetEntity.components.ItemAcceptor; + const targetAcceptorComp = destEntity.components.ItemAcceptor; if (!targetAcceptorComp.canAcceptItem(destSlot.index, item)) { continue; } // Try to hand over the item - if (this.tryPassOverItem(item, targetEntity, destSlot.index)) { + if (this.tryPassOverItem(item, destEntity, destSlot.index)) { // Handover successful, clear slot targetAcceptorComp.onItemAccepted(destSlot.index, destSlot.acceptedDirection, item); sourceSlot.item = null; @@ -357,6 +353,11 @@ export class ItemEjectorSystem extends GameSystemWithFilter { continue; } + if (!ejectorComp.renderFloatingItems && !slot.cachedTargetEntity) { + // Not connected to any building + continue; + } + const realPosition = staticComp.localTileToWorld(slot.pos); if (!chunk.tileSpaceRectangle.containsPoint(realPosition.x, realPosition.y)) { // Not within this chunk