diff --git a/build.gradle b/build.gradle index 0bd3d4bb2..b89d16ba4 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ buildscript { maven { url = 'https://files.minecraftforge.net/maven' } jcenter() mavenCentral() - maven { url='https://dist.creeper.host/Sponge/maven' } + maven { url='https://repo.spongepowered.org/repository/maven-public/' } } dependencies { classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '3.+', changing: true diff --git a/src/generated/resources/.cache/cache b/src/generated/resources/.cache/cache index f36e7588a..c9b19a220 100644 --- a/src/generated/resources/.cache/cache +++ b/src/generated/resources/.cache/cache @@ -16,7 +16,7 @@ a579c40c43dc2174afb66f42d00d0c4a0efaaeee assets/create/blockstates/andesite_bric 96b5284693da168ab8e0809d86515b5f1a7e763f assets/create/blockstates/andesite_cobblestone_stairs.json 82bd82270aff7d51e9239680ef4dd7b5c899ceb0 assets/create/blockstates/andesite_cobblestone_wall.json 9639b901ffdd2ecccab5575c5c9e6c7b5c901e02 assets/create/blockstates/andesite_encased_shaft.json -53cf4cfd94db1f44e9865b9fe5db383d01a12671 assets/create/blockstates/andesite_funnel.json +ca9a629472625abf741f02b94ce4578292fb14a7 assets/create/blockstates/andesite_funnel.json 398922758a6219544e5b85c91c9cf8a543b437e5 assets/create/blockstates/andesite_pillar.json 1d2d8081581e07d9be4b382aede4f2de4401cc6b assets/create/blockstates/andesite_tunnel.json e555e3c2b2d3f01440e48db4ba88f7e00fd99b6f assets/create/blockstates/basin.json @@ -157,7 +157,7 @@ afff479c0e5284771afa9e7ce513595fe65860ee assets/create/blockstates/gabbro_cobble a1f31a194129cfb65e335b3b96490f9275f9c564 assets/create/blockstates/gabbro_cobblestone_stairs.json a64d8d0924c0b5b192f355343dd9b3a440875f6a assets/create/blockstates/gabbro_cobblestone_wall.json a6b44e8a1c4ce0c7442b2384b41ad36dd133f19b assets/create/blockstates/gabbro_pillar.json -2d7ffcb339b0a38b98935a382ac2a164866255b1 assets/create/blockstates/gantry_pinion.json +23744450886af88ed468aecbbd7b8d7babcbbd6f assets/create/blockstates/gantry_carriage.json 9fa39a44bba30c5ae8fa245b122a837c705462b4 assets/create/blockstates/gantry_shaft.json eca1f0e56efdadb241f42dc6ebb036f1d52213a9 assets/create/blockstates/gearbox.json f34814b17cde3231a1dfb271f3dabf8d6de4fbf6 assets/create/blockstates/gearshift.json @@ -337,7 +337,7 @@ e8b0a401c10d1ba67ed71ba31bd5f9bc28571b65 assets/create/blockstates/powered_toggl d06cd9a1101b18d306a786320aab12018b1325d6 assets/create/blockstates/purple_sail.json 92957119abd5fbcca36a113b2a80255fd70fc303 assets/create/blockstates/purple_seat.json 61035f8afe75ff7bbd291da5d8690bcbebe679eb assets/create/blockstates/purple_valve_handle.json -4439fc83a8c7370ab44b211a3fd48abde20a4728 assets/create/blockstates/radial_chassis.json +6fa36883e76e9e403bb429c8f86b8c0d3bba0cff assets/create/blockstates/radial_chassis.json 45877c4d90a7185c2f304edbd67379d800920439 assets/create/blockstates/red_sail.json da1b08387af7afa0855ee8d040f620c01f20660a assets/create/blockstates/red_seat.json 722fc77bbf387af8a4016e42cbf9501d2b968881 assets/create/blockstates/red_valve_handle.json @@ -401,20 +401,20 @@ a3a11524cd3515fc01d905767b4b7ea782adaf03 assets/create/blockstates/yellow_seat.j 6801fa1f466f172700e573e5b8ee8ee5f9ca4583 assets/create/blockstates/yellow_valve_handle.json 7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json -369f9c6fce0aa11d70efa2e73a4ba2ff12e57e37 assets/create/lang/en_ud.json -1e3157b36cce7bf30abde83323513f8f7c1a7c2c assets/create/lang/en_us.json -7ddb6aa393d89dd1d9d1e27c998783a7db18e831 assets/create/lang/unfinished/de_de.json -525232bd81bef5086d210ceee26742c06818c9e9 assets/create/lang/unfinished/es_es.json -02e31fdd37f3b933ca96531c3d98b1e352e858d9 assets/create/lang/unfinished/es_mx.json -7754dc1f5c493d81189d535841bd32401d328e19 assets/create/lang/unfinished/fr_fr.json -f5064df0df1f055ba8ac42a97831171b2cb724eb assets/create/lang/unfinished/it_it.json -429da2684276d3385e82851f6a0a176c5dd8471e assets/create/lang/unfinished/ja_jp.json -9b0ab4186a35d8484dbee5c41cd4000c98b8a0a2 assets/create/lang/unfinished/ko_kr.json -b362f846ad523840e65ffc94ccd0bc6c694acbb5 assets/create/lang/unfinished/nl_nl.json -14950620733669b606d480c6a25b1f8ddea1fbb5 assets/create/lang/unfinished/pt_br.json -832483d95d4f36c1ee247dde86758c7c768912e9 assets/create/lang/unfinished/ru_ru.json -27f5f218699fd03172ecf6d1033689b0a35f23e2 assets/create/lang/unfinished/zh_cn.json -ac53a2d2146238a6314a51c199afdac98465b01a assets/create/lang/unfinished/zh_tw.json +2b12f3cf99e498899207a8c4855210e7b5dc55cd assets/create/lang/en_ud.json +70c01b50697866652585552dca5c9216934b93e3 assets/create/lang/en_us.json +8723f59cbb46b42a85996195a10b4d68b748b839 assets/create/lang/unfinished/de_de.json +680047cc58a781b0a4fcec0ca36b1194082c6679 assets/create/lang/unfinished/es_es.json +c78a6aa75c3a7afdabb98cfb71d6f5f57d994d04 assets/create/lang/unfinished/es_mx.json +3ee909ec33725d9bfeb8a32e81707b5ad53bfae1 assets/create/lang/unfinished/fr_fr.json +dbd795f8b92e38de488bde470644c92de590c6c4 assets/create/lang/unfinished/it_it.json +b1d41b49c118e588aad2c8edf0e08acf9e14f20a assets/create/lang/unfinished/ja_jp.json +7546ffae02cbda0c17fe77ad6e72a6959303591a assets/create/lang/unfinished/ko_kr.json +030af4ddbc9eaef3f7aafb988e7dac960e232149 assets/create/lang/unfinished/nl_nl.json +3e2dfe4b4d915c48d9e0e130bcb823296310fad9 assets/create/lang/unfinished/pt_br.json +5f423b6846ef1344c7c517af8d7909c6fc284c2e assets/create/lang/unfinished/ru_ru.json +a766c823e582e861782698cc7dba4e52c63e085a assets/create/lang/unfinished/zh_cn.json +25f61a27cc6a48e29fb5db421ce3306b55923cd1 assets/create/lang/unfinished/zh_tw.json 846200eb548d3bfa2e77b41039de159b4b6cfb45 assets/create/models/block/acacia_window.json 1930fa3a3c98d53dd19e4ee7f55bc27fd47aa281 assets/create/models/block/acacia_window_pane_noside.json 1763ea2c9b981d187f5031ba608f3d5d3be3986a assets/create/models/block/acacia_window_pane_noside_alt.json @@ -466,10 +466,10 @@ a033fbac3129bba9211c6c4a0e16c905643afa39 assets/create/models/block/andesite_cob 9841d6a09a09bf4d5d6a39bdc4904d86b3a825f8 assets/create/models/block/andesite_funnel_horizontal_pull_powered.json 86d5df6e365d9b2e9682f0839f61058360828ba2 assets/create/models/block/andesite_funnel_horizontal_push.json 50af1ff6ce9af162d4e438f21952c7215608dc8e assets/create/models/block/andesite_funnel_horizontal_push_powered.json -618d6ca90addb5913c72789f6188c957afa503f3 assets/create/models/block/andesite_funnel_vertical_pull.json -45365708fa75e2cd3d0702fb0e4960861ada27ab assets/create/models/block/andesite_funnel_vertical_pull_powered.json -53bdeba42894242088e8f7e7734a101fa998d0e4 assets/create/models/block/andesite_funnel_vertical_push.json -3e88fa45e22868dae92a014e589585d37eb465ad assets/create/models/block/andesite_funnel_vertical_push_powered.json +75c914bf9448e25fd01d597de48375a9782bef36 assets/create/models/block/andesite_funnel_vertical_filterless_pull.json +4d70a221809f5bc598a0a0e98bd152e9ab7a2f7f assets/create/models/block/andesite_funnel_vertical_filterless_pull_powered.json +a41c7351513a9514dfdc0fc552b646b1d715c977 assets/create/models/block/andesite_funnel_vertical_filterless_push.json +e7931f28887baadd52ac988fc8eeeb84ee6f0d27 assets/create/models/block/andesite_funnel_vertical_filterless_push_powered.json b1d0bb538fc8285b7d3fd77a977d78a104b83b62 assets/create/models/block/andesite_pillar.json aaf2e4259bcfcedd3400e9acb2d64c0cf06f7fb1 assets/create/models/block/andesite_tunnel/cross.json 75f628178fa21a2bd301eea8d1cebf7e94f7d5cc assets/create/models/block/andesite_tunnel/straight.json @@ -1327,7 +1327,7 @@ b10971277417369f421324b28f0a4b47ce4c8625 assets/create/models/item/gabbro_bricks b3d7398dbc16c450928bd76b772c273382687447 assets/create/models/item/gabbro_cobblestone_stairs.json 5680f24b43838cb6632bfcedba282a244bd24db0 assets/create/models/item/gabbro_cobblestone_wall.json 20950b692eecfccd77d96678bb3d909d51f6d787 assets/create/models/item/gabbro_pillar.json -b10f1b188f2bf380628377bd42af2b8f8ffe5611 assets/create/models/item/gantry_pinion.json +a642f570ec8223c066e542f062aff3b7f93e002b assets/create/models/item/gantry_carriage.json b4bfd5041b62f3a0a955fa4872d178b590614f22 assets/create/models/item/gantry_shaft.json 6ab0d17f3d02678ed992e188ff09f6b2c00b5b03 assets/create/models/item/gearbox.json 2fe29893d74c176ea35aed73a169c13dd4ddb2a8 assets/create/models/item/gearshift.json @@ -1585,7 +1585,7 @@ d080b1b25e5bc8baf5aee68691b08c7f12ece3b0 assets/create/models/item/windmill_bear 9f9455ccb5fc9e3cbfce73862b46078346a522a5 assets/create/models/item/zinc_nugget.json b1689617190c05ef34bd18456b0c7ae09bb3210f assets/create/models/item/zinc_ore.json e76041b7ae829fdd7dc0524f6ca4d2f89fca51bb assets/create/sounds.json -5d0cc4c0255dc241e61c173b31ddca70c88d08e4 data/create/advancements/aesthetics.json +0f1b4b980afba9bf2caf583b88e261bba8b10313 data/create/advancements/aesthetics.json 187921fa131b06721bfaf63f2623a28c141aae9a data/create/advancements/andesite_alloy.json 0ea2db7173b5be28b289ea7c9a6a0cf5805c60c7 data/create/advancements/andesite_casing.json 356f4855a2a6c65be3fb51d7d1aabf2ca6034d42 data/create/advancements/arm_blaze_burner.json @@ -1744,7 +1744,7 @@ b42213bffce4e51618e1bba481959208d247c120 data/create/advancements/recipes/create 11d89eca0ccb0f1a8cd27acc9fc0c10d7bf83285 data/create/advancements/recipes/create.base/crafting/kinetics/fluid_pipe.json a2b33e972c7130cbf105f34d88dd7a9a53d5465c data/create/advancements/recipes/create.base/crafting/kinetics/fluid_tank.json a91b11ae44d9b1f479c6dee1f1a4580104059287 data/create/advancements/recipes/create.base/crafting/kinetics/fluid_valve.json -e17c45fc17e1a8e1e618b6eae02fa0aba3247495 data/create/advancements/recipes/create.base/crafting/kinetics/gantry_pinion.json +b2a73fc7e0e4e764c2af400a6e093c2d78d7d37d data/create/advancements/recipes/create.base/crafting/kinetics/gantry_carriage.json d1d2fc2f5c4e89393808c65e015917eabb50dffe data/create/advancements/recipes/create.base/crafting/kinetics/gantry_shaft.json dae9e65a089955c0367dc1453e104c3153ebad79 data/create/advancements/recipes/create.base/crafting/kinetics/gearbox.json 8f9819912605cb2499cb3e79ecb0e709b0e38c19 data/create/advancements/recipes/create.base/crafting/kinetics/gearboxfrom_conversion.json @@ -2455,7 +2455,7 @@ e51893e1601c470da466b35b17251238e15d0361 data/create/loot_tables/blocks/gabbro_b 54879fe6ca3b7271fbb94ec26bef1c3031942d4d data/create/loot_tables/blocks/gabbro_cobblestone_stairs.json ae19749df10663efc51b8b27af310164f250ed38 data/create/loot_tables/blocks/gabbro_cobblestone_wall.json e8d09c919e3b8125d7da0f38383c01bcfc61c7a8 data/create/loot_tables/blocks/gabbro_pillar.json -04e42ba63002ed8ba67780123413f6ff3fb85b02 data/create/loot_tables/blocks/gantry_pinion.json +0ea37ff1af6c6a884670cd12ff1d8fdf223519c5 data/create/loot_tables/blocks/gantry_carriage.json f2883656e417a78e5e4093002eb1e36ffa1157e9 data/create/loot_tables/blocks/gantry_shaft.json b0109b4a4f0f738cbbe6b5911e8c3c0310b76f99 data/create/loot_tables/blocks/gearbox.json 5f39461c5c9d3ad8d84195b06b9468fe2b0fb269 data/create/loot_tables/blocks/gearshift.json @@ -2805,7 +2805,7 @@ f4ae37f736d06ccda5fbba7831a7a174ec916a05 data/create/recipes/crafting/kinetics/f 86ad4d2820e8e2b01de8d977af7796119dfb7430 data/create/recipes/crafting/kinetics/fluid_tank.json 3dad2a849796df268cd3a06ed37376f2cc529957 data/create/recipes/crafting/kinetics/fluid_valve.json 84153bd478c0e63a04c77579d6595043f604b7ab data/create/recipes/crafting/kinetics/furnace_minecart_from_contraption_cart.json -5299a12e9272089e64073c8e151b70a5bc57b53c data/create/recipes/crafting/kinetics/gantry_pinion.json +9e75756423b7f9372a2330a7140f80b1b87bd30e data/create/recipes/crafting/kinetics/gantry_carriage.json 21095a156547d4a7d215964be793f1e960b81c09 data/create/recipes/crafting/kinetics/gantry_shaft.json 5eb05cdf88bccdaddfe7ebfbd8b70d1196d422a6 data/create/recipes/crafting/kinetics/gearbox.json b5da8c58f6b8aba525ae8a12ad906db37b78a566 data/create/recipes/crafting/kinetics/gearboxfrom_conversion.json diff --git a/src/generated/resources/assets/create/blockstates/andesite_funnel.json b/src/generated/resources/assets/create/blockstates/andesite_funnel.json index 7330405c1..9ea4b09ee 100644 --- a/src/generated/resources/assets/create/blockstates/andesite_funnel.json +++ b/src/generated/resources/assets/create/blockstates/andesite_funnel.json @@ -1,21 +1,21 @@ { "variants": { "extracting=false,facing=down,powered=false": { - "model": "create:block/andesite_funnel_vertical_pull", + "model": "create:block/andesite_funnel_vertical_filterless_pull", "x": 180, "y": 180 }, "extracting=true,facing=down,powered=false": { - "model": "create:block/andesite_funnel_vertical_push", + "model": "create:block/andesite_funnel_vertical_filterless_push", "x": 180, "y": 180 }, "extracting=false,facing=up,powered=false": { - "model": "create:block/andesite_funnel_vertical_pull", + "model": "create:block/andesite_funnel_vertical_filterless_pull", "y": 180 }, "extracting=true,facing=up,powered=false": { - "model": "create:block/andesite_funnel_vertical_push", + "model": "create:block/andesite_funnel_vertical_filterless_push", "y": 180 }, "extracting=false,facing=north,powered=false": { @@ -49,21 +49,21 @@ "y": 90 }, "extracting=false,facing=down,powered=true": { - "model": "create:block/andesite_funnel_vertical_pull_powered", + "model": "create:block/andesite_funnel_vertical_filterless_pull_powered", "x": 180, "y": 180 }, "extracting=true,facing=down,powered=true": { - "model": "create:block/andesite_funnel_vertical_push_powered", + "model": "create:block/andesite_funnel_vertical_filterless_push_powered", "x": 180, "y": 180 }, "extracting=false,facing=up,powered=true": { - "model": "create:block/andesite_funnel_vertical_pull_powered", + "model": "create:block/andesite_funnel_vertical_filterless_pull_powered", "y": 180 }, "extracting=true,facing=up,powered=true": { - "model": "create:block/andesite_funnel_vertical_push_powered", + "model": "create:block/andesite_funnel_vertical_filterless_push_powered", "y": 180 }, "extracting=false,facing=north,powered=true": { diff --git a/src/generated/resources/assets/create/blockstates/gantry_pinion.json b/src/generated/resources/assets/create/blockstates/gantry_carriage.json similarity index 53% rename from src/generated/resources/assets/create/blockstates/gantry_pinion.json rename to src/generated/resources/assets/create/blockstates/gantry_carriage.json index 1280e18d4..06cac5b0c 100644 --- a/src/generated/resources/assets/create/blockstates/gantry_pinion.json +++ b/src/generated/resources/assets/create/blockstates/gantry_carriage.json @@ -1,51 +1,51 @@ { "variants": { "axis_along_first=false,facing=down": { - "model": "create:block/gantry_pinion/horizontal", + "model": "create:block/gantry_carriage/horizontal", "x": 270, "y": 90 }, "axis_along_first=true,facing=down": { - "model": "create:block/gantry_pinion/horizontal", + "model": "create:block/gantry_carriage/horizontal", "x": 270 }, "axis_along_first=false,facing=up": { - "model": "create:block/gantry_pinion/horizontal", + "model": "create:block/gantry_carriage/horizontal", "x": 90, "y": 90 }, "axis_along_first=true,facing=up": { - "model": "create:block/gantry_pinion/horizontal", + "model": "create:block/gantry_carriage/horizontal", "x": 90 }, "axis_along_first=false,facing=north": { - "model": "create:block/gantry_pinion/vertical", + "model": "create:block/gantry_carriage/vertical", "y": 180 }, "axis_along_first=true,facing=north": { - "model": "create:block/gantry_pinion/horizontal", + "model": "create:block/gantry_carriage/horizontal", "y": 180 }, "axis_along_first=false,facing=south": { - "model": "create:block/gantry_pinion/vertical" + "model": "create:block/gantry_carriage/vertical" }, "axis_along_first=true,facing=south": { - "model": "create:block/gantry_pinion/horizontal" + "model": "create:block/gantry_carriage/horizontal" }, "axis_along_first=false,facing=west": { - "model": "create:block/gantry_pinion/horizontal", + "model": "create:block/gantry_carriage/horizontal", "y": 90 }, "axis_along_first=true,facing=west": { - "model": "create:block/gantry_pinion/vertical", + "model": "create:block/gantry_carriage/vertical", "y": 90 }, "axis_along_first=false,facing=east": { - "model": "create:block/gantry_pinion/horizontal", + "model": "create:block/gantry_carriage/horizontal", "y": 270 }, "axis_along_first=true,facing=east": { - "model": "create:block/gantry_pinion/vertical", + "model": "create:block/gantry_carriage/vertical", "y": 270 } } diff --git a/src/generated/resources/assets/create/blockstates/radial_chassis.json b/src/generated/resources/assets/create/blockstates/radial_chassis.json index 8bd829ffc..f97d8c8bc 100644 --- a/src/generated/resources/assets/create/blockstates/radial_chassis.json +++ b/src/generated/resources/assets/create/blockstates/radial_chassis.json @@ -89,8 +89,8 @@ }, { "when": { - "axis": "x", - "sticky_west": "true" + "sticky_west": "true", + "axis": "x" }, "apply": { "model": "create:block/radial_chassis_side_x_sticky", @@ -99,8 +99,8 @@ }, { "when": { - "axis": "y", - "sticky_west": "true" + "sticky_west": "true", + "axis": "y" }, "apply": { "model": "create:block/radial_chassis_side_y_sticky", @@ -109,8 +109,8 @@ }, { "when": { - "axis": "z", - "sticky_west": "true" + "sticky_west": "true", + "axis": "z" }, "apply": { "model": "create:block/radial_chassis_side_z_sticky", @@ -119,8 +119,8 @@ }, { "when": { - "axis": "x", - "sticky_west": "false" + "sticky_west": "false", + "axis": "x" }, "apply": { "model": "create:block/radial_chassis_side_x", @@ -129,8 +129,8 @@ }, { "when": { - "axis": "y", - "sticky_west": "false" + "sticky_west": "false", + "axis": "y" }, "apply": { "model": "create:block/radial_chassis_side_y", @@ -139,8 +139,8 @@ }, { "when": { - "axis": "z", - "sticky_west": "false" + "sticky_west": "false", + "axis": "z" }, "apply": { "model": "create:block/radial_chassis_side_z", @@ -149,8 +149,8 @@ }, { "when": { - "axis": "x", - "sticky_north": "true" + "sticky_north": "true", + "axis": "x" }, "apply": { "model": "create:block/radial_chassis_side_x_sticky" @@ -158,8 +158,8 @@ }, { "when": { - "axis": "y", - "sticky_north": "true" + "sticky_north": "true", + "axis": "y" }, "apply": { "model": "create:block/radial_chassis_side_y_sticky", @@ -168,8 +168,8 @@ }, { "when": { - "axis": "z", - "sticky_north": "true" + "sticky_north": "true", + "axis": "z" }, "apply": { "model": "create:block/radial_chassis_side_x_sticky", @@ -178,8 +178,8 @@ }, { "when": { - "axis": "x", - "sticky_north": "false" + "sticky_north": "false", + "axis": "x" }, "apply": { "model": "create:block/radial_chassis_side_x" @@ -187,8 +187,8 @@ }, { "when": { - "axis": "y", - "sticky_north": "false" + "sticky_north": "false", + "axis": "y" }, "apply": { "model": "create:block/radial_chassis_side_y", @@ -197,8 +197,8 @@ }, { "when": { - "axis": "z", - "sticky_north": "false" + "sticky_north": "false", + "axis": "z" }, "apply": { "model": "create:block/radial_chassis_side_x", @@ -207,8 +207,8 @@ }, { "when": { - "axis": "x", - "sticky_east": "true" + "sticky_east": "true", + "axis": "x" }, "apply": { "model": "create:block/radial_chassis_side_x_sticky", @@ -217,8 +217,8 @@ }, { "when": { - "axis": "y", - "sticky_east": "true" + "sticky_east": "true", + "axis": "y" }, "apply": { "model": "create:block/radial_chassis_side_y_sticky", @@ -227,8 +227,8 @@ }, { "when": { - "axis": "z", - "sticky_east": "true" + "sticky_east": "true", + "axis": "z" }, "apply": { "model": "create:block/radial_chassis_side_z_sticky" @@ -236,8 +236,8 @@ }, { "when": { - "axis": "x", - "sticky_east": "false" + "sticky_east": "false", + "axis": "x" }, "apply": { "model": "create:block/radial_chassis_side_x", @@ -246,8 +246,8 @@ }, { "when": { - "axis": "y", - "sticky_east": "false" + "sticky_east": "false", + "axis": "y" }, "apply": { "model": "create:block/radial_chassis_side_y", @@ -256,8 +256,8 @@ }, { "when": { - "axis": "z", - "sticky_east": "false" + "sticky_east": "false", + "axis": "z" }, "apply": { "model": "create:block/radial_chassis_side_z" diff --git a/src/generated/resources/assets/create/lang/en_ud.json b/src/generated/resources/assets/create/lang/en_ud.json index 992efe5b8..d700f301e 100644 --- a/src/generated/resources/assets/create/lang/en_ud.json +++ b/src/generated/resources/assets/create/lang/en_ud.json @@ -158,7 +158,7 @@ "block.create.gabbro_cobblestone_stairs": "s\u0279\u0131\u0250\u0287S \u01DDuo\u0287s\u01DD\u05DFqqo\u0186 o\u0279qq\u0250\u2141", "block.create.gabbro_cobblestone_wall": "\u05DF\u05DF\u0250M \u01DDuo\u0287s\u01DD\u05DFqqo\u0186 o\u0279qq\u0250\u2141", "block.create.gabbro_pillar": "\u0279\u0250\u05DF\u05DF\u0131\u0500 o\u0279qq\u0250\u2141", - "block.create.gantry_pinion": "uo\u0131u\u0131\u0500 \u028E\u0279\u0287u\u0250\u2141", + "block.create.gantry_carriage": "\u01DDb\u0250\u0131\u0279\u0279\u0250\u0186 \u028E\u0279\u0287u\u0250\u2141", "block.create.gantry_shaft": "\u0287\u025F\u0250\u0265S \u028E\u0279\u0287u\u0250\u2141", "block.create.gearbox": "xoq\u0279\u0250\u01DD\u2141", "block.create.gearshift": "\u0287\u025F\u0131\u0265s\u0279\u0250\u01DD\u2141", diff --git a/src/generated/resources/assets/create/lang/en_us.json b/src/generated/resources/assets/create/lang/en_us.json index d1b1f9528..097193486 100644 --- a/src/generated/resources/assets/create/lang/en_us.json +++ b/src/generated/resources/assets/create/lang/en_us.json @@ -161,7 +161,7 @@ "block.create.gabbro_cobblestone_stairs": "Gabbro Cobblestone Stairs", "block.create.gabbro_cobblestone_wall": "Gabbro Cobblestone Wall", "block.create.gabbro_pillar": "Gabbro Pillar", - "block.create.gantry_pinion": "Gantry Pinion", + "block.create.gantry_carriage": "Gantry Carriage", "block.create.gantry_shaft": "Gantry Shaft", "block.create.gearbox": "Gearbox", "block.create.gearshift": "Gearshift", @@ -1808,6 +1808,221 @@ "create.tooltip.randomWipDescription7": "This one maybe isn't for you. What about that one?", "create.tooltip.randomWipDescription8": "Use it and regret your decision immediately.", + + "_": "->------------------------] Ponder Content [------------------------<-", + + "create.ponder.hold_to_ponder": "Hold [%1$s] to Ponder", + "create.ponder.subject": "Subject of this scene", + "create.ponder.pondering": "Pondering about...", + "create.ponder.identify_mode": "Identify mode active.\nUnpause with [%1$s]", + "create.ponder.associated": "Associated Entries", + "create.ponder.shared.movement_anchors": "With the help of Chassis or Super Glue, larger structures can be moved.", + "create.ponder.shared.rpm32": "32 RPM", + "create.ponder.shared.sneak_and": "Sneak +", + "create.ponder.shared.rpm8": "8 RPM", + "create.ponder.shared.ctrl_and": "Ctrl +", + "create.ponder.shared.rpm16_source": "Source: 16 RPM", + "create.ponder.shared.rpm16": "16 RPM", + "create.ponder.tag.kinetic_sources": "Kinetic Sources", + "create.ponder.tag.kinetic_sources.description": "Components which generate Rotational Force", + "create.ponder.tag.contraption_actor": "Contraption Actors", + "create.ponder.tag.contraption_actor.description": "Components which expose special behaviour when attached to a moving contraption", + "create.ponder.tag.arm_targets": "Targets for Mechanical Arms", + "create.ponder.tag.arm_targets.description": "Components which can be selected as inputs or outputs to the Mechanical Arm", + "create.ponder.tag.logistics": "Item Transportation", + "create.ponder.tag.logistics.description": "Components which help moving items around", + "create.ponder.tag.movement_anchor": "Movement Anchors", + "create.ponder.tag.movement_anchor.description": "Components which allow the creation of moving contraptions, animating an attached structure in a variety of ways", + "create.ponder.tag.decoration": "Aesthetics", + "create.ponder.tag.decoration.description": "Components used mostly for decorative purposes", + "create.ponder.tag.kinetic_appliances": "Kinetic Appliances", + "create.ponder.tag.kinetic_appliances.description": "Components which make use of Rotational Force", + "create.ponder.tag.redstone": "Logic Components", + "create.ponder.tag.redstone.description": "Components which help with redstone engineering", + "create.ponder.tag.creative": "Creative Mode", + "create.ponder.tag.creative.description": "Components not usually available for Survival Mode", + "create.ponder.tag.kinetic_relays": "Kinetic Blocks", + "create.ponder.tag.kinetic_relays.description": "Components which help relaying Rotational Force elsewhere", + "create.ponder.tag.fluids": "Fluid Manipulators", + "create.ponder.tag.fluids.description": "Components which help relaying and making use of Fluids", + + "create.ponder.belt_casing.header": "Encasing Belts", + "create.ponder.belt_casing.text_1": "Brass or Andesite Casing can be used to decorate Mechanical Belts", + "create.ponder.belt_casing.text_2": "A wrench can be used to remove the casing", + + "create.ponder.belt_connector.header": "Using Mechanical Belts", + "create.ponder.belt_connector.text_1": "Right-Clicking two shafts with a belt item will connect them together", + "create.ponder.belt_connector.text_2": "Accidental selections can be canceled with Right-Click while Sneaking", + "create.ponder.belt_connector.text_3": "Additional Shafts can be added throughout the Belt", + "create.ponder.belt_connector.text_4": "Shafts connected via Belts will rotate with Identical Speed and Direction", + "create.ponder.belt_connector.text_5": "Added shafts can be removed using the wrench", + "create.ponder.belt_connector.text_6": "Mechanical Belts can be dyed for aesthetic purposes", + + "create.ponder.belt_directions.header": "Valid Orientations for Mechanical Belts", + "create.ponder.belt_directions.text_1": "Belts cannot connect in arbitrary directions", + "create.ponder.belt_directions.text_2": "1. They can connect horizontally", + "create.ponder.belt_directions.text_3": "2. They can connect diagonally", + "create.ponder.belt_directions.text_4": "3. They can connect vertically", + "create.ponder.belt_directions.text_5": "4. And they can connect vertical shafts horizontally", + "create.ponder.belt_directions.text_6": "These are all possible directions.\nBelts can span any Length between 2 and 20 blocks", + + "create.ponder.belt_transport.header": "Using Mechanical Belts for Logistics", + "create.ponder.belt_transport.text_1": "Moving belts will transport Items and other Entities", + "create.ponder.belt_transport.text_2": "Right-Click with an empty hand to take items off a belt", + + "create.ponder.brass_funnel.header": "The Brass Funnel", + "create.ponder.brass_funnel.text_1": "Andesite Funnels can only ever extract single items.", + "create.ponder.brass_funnel.text_2": "Brass Funnels can extract up to a full stack.", + "create.ponder.brass_funnel.text_3": "Scrolling on the filter slot allows for precise control over the extracted stack size.", + "create.ponder.brass_funnel.text_4": "Using items on the filter slot will restrict the funnel to only transfer matching stacks.", + + "create.ponder.chain_drive.header": "Relaying rotational force with Chain Drives", + "create.ponder.chain_drive.text_1": "Chain Drives relay rotation to each other in a row", + "create.ponder.chain_drive.text_2": "All shafts connected like this will rotate in the same direction", + "create.ponder.chain_drive.text_3": "Any part of the row can be rotated by 90 degrees", + + "create.ponder.chain_gearshift.header": "Controlling rotational speed with Chain Gearshifts", + "create.ponder.chain_gearshift.text_1": "Unpowered Chain Gearshifts behave exacly like Chain Drives", + "create.ponder.chain_gearshift.text_2": "When Powered, the speed transmitted to other Chain Drives in the row is doubled", + "create.ponder.chain_gearshift.text_3": "Whenever the Powered Gearshift is not at the source, its speed will be halved instead", + "create.ponder.chain_gearshift.text_4": "In both cases, Chain Drives in the row always run at 2x the speed of the Powered Gearshift", + "create.ponder.chain_gearshift.text_5": "Using analog signals, the ratio can be adjusted more precisely between 1 and 2", + "create.ponder.chain_gearshift.text_6": "12 RPM", + + "create.ponder.clutch.header": "Controlling rotational force using a Clutch", + "create.ponder.clutch.text_1": "Clutches will relay rotation in a straight line", + "create.ponder.clutch.text_2": "When powered by Redstone, it breaks the connection", + + "create.ponder.cog_speedup.header": "Gearshifting with Cogs", + "create.ponder.cog_speedup.text_1": "Large and Small cogs can be connected diagonally", + "create.ponder.cog_speedup.text_2": "Shifting from large to small cogs, the conveyed speed will be doubled", + "create.ponder.cog_speedup.text_3": "Shifting the opposite way, the conveyed speed will be halved", + + "create.ponder.cogwheel.header": "Relaying rotational force using Cogwheels", + "create.ponder.cogwheel.text_1": "Cogwheels will relay rotation to other adjacent cogwheels", + "create.ponder.cogwheel.text_2": "Neighbouring shafts connected like this will rotate in opposite directions", + + "create.ponder.creative_motor.header": "Generating Rotational Force using Creative Motors", + "create.ponder.creative_motor.text_1": "Creative motors are a compact and configurable source of Rotational Force", + "create.ponder.creative_motor.text_2": "Scrolling on the back panel changes the RPM of the motors' rotational output", + + "create.ponder.fan_direction.header": "Air flow of Encased Fans", + "create.ponder.fan_direction.text_1": "Encased Fans use Rotational Force to create an Air Current", + "create.ponder.fan_direction.text_2": "Strength and Direction of Flow depends on the Rotational Input", + + "create.ponder.fan_processing.header": "Processing Items using Encased Fans", + "create.ponder.fan_processing.text_1": "When passing through lava, the Air Flow becomes Heated", + "create.ponder.fan_processing.text_2": "Items caught in the area will be smelted", + "create.ponder.fan_processing.text_3": "Food items thrown here would be incinerated", + "create.ponder.fan_processing.text_4": "Instead, a setup for Smoking using Fire should be used for them", + "create.ponder.fan_processing.text_5": "Air Flows passing through water create a Washing Setup", + "create.ponder.fan_processing.text_6": "Some interesting new processing can be done with it", + "create.ponder.fan_processing.text_7": "The Speed of the Fan does NOT affect the processing speed, only its range", + "create.ponder.fan_processing.text_8": "Fan Processing can also be applied to Items on Depots and Belts", + + "create.ponder.fan_source.header": "Generating Rotational Force using Encased Fans", + "create.ponder.fan_source.text_1": "Fans facing down into a source of heat can provide Rotational Force", + "create.ponder.fan_source.text_2": "When given a Redstone Signal, the Fans will start providing power", + + "create.ponder.funnel_compat.header": "Funnel compatibility", + "create.ponder.funnel_compat.text_1": "Funnels should also interact nicely with a handful of other components.", + "create.ponder.funnel_compat.text_2": "Vertical Saws", + "create.ponder.funnel_compat.text_3": "Depots", + "create.ponder.funnel_compat.text_4": "Item Drains", + + "create.ponder.funnel_direction.header": "Direction of Transfer", + "create.ponder.funnel_direction.text_1": "Placed normally, it pulls items from the inventory.", + "create.ponder.funnel_direction.text_2": "Placed while sneaking, it puts items into the inventory.", + "create.ponder.funnel_direction.text_3": "Using a wrench, the funnel can be flipped after placement.", + "create.ponder.funnel_direction.text_4": "Same rules will apply for most orientations.", + "create.ponder.funnel_direction.text_5": "Funnels on belts will extract/insert depending on its movement direction.", + + "create.ponder.funnel_intro.header": "Using funnels", + "create.ponder.funnel_intro.text_1": "Funnels are ideal for transferring items from and to inventories.", + + "create.ponder.funnel_redstone.header": "Redstone control", + "create.ponder.funnel_redstone.text_1": "Redstone power will prevent any funnel from acting.", + + "create.ponder.funnel_transfer.header": "Direct transfer", + "create.ponder.funnel_transfer.text_1": "Funnels cannot ever transfer between closed inventories directly.", + "create.ponder.funnel_transfer.text_2": "Chutes or Smart chutes might be more suitable for such purposes.", + "create.ponder.funnel_transfer.text_3": "Same applies for horizontal movement.\nA mechanical belt should help here.", + + "create.ponder.gantry_carriage.header": "Using Gantry Carriages", + "create.ponder.gantry_carriage.text_1": "Gantry Carriages can mount to and slide along a Gantry Shaft.", + "create.ponder.gantry_carriage.text_2": "Gantry setups can move attached Blocks.", + + "create.ponder.gantry_cascaded.header": "Cascaded Gantries", + "create.ponder.gantry_cascaded.text_1": "Gantry shafts attach to a carriage without the need of super glue", + "create.ponder.gantry_cascaded.text_2": "Same applies for carriages on moved Gantry Shafts", + "create.ponder.gantry_cascaded.text_3": "Thus, a gantry system can be cascaded to cover multiple axes of movement", + + "create.ponder.gantry_direction.header": "Gantry Movement Direction", + "create.ponder.gantry_direction.text_1": "Gantry Shafts can have opposite orientations", + "create.ponder.gantry_direction.text_2": "The movement direction of carriages depend on their shafts' orientation", + "create.ponder.gantry_direction.text_3": "...as well as the rotation direction of the shaft", + "create.ponder.gantry_direction.text_4": "Same rules apply for the propagated rotation", + + "create.ponder.gantry_redstone.header": "Gantry Power Propagation", + "create.ponder.gantry_redstone.text_1": "Redstone-powered gantry shafts stop moving their carriages", + "create.ponder.gantry_redstone.text_2": "Instead, its rotational force is relayed to the carriages' output shaft", + + "create.ponder.gantry_shaft.header": "Using Gantry Shafts", + "create.ponder.gantry_shaft.text_1": "Gantry Shafts form the basis of a gantry setup. Attached Carriages will move along them.", + "create.ponder.gantry_shaft.text_2": "Gantry setups can move attached Blocks.", + + "create.ponder.gearbox.header": "Relaying rotational force using Gearboxes", + "create.ponder.gearbox.text_1": "Jumping between axes of rotation can get bulky quickly", + "create.ponder.gearbox.text_2": "A gearbox is the more compact equivalent of this setup", + "create.ponder.gearbox.text_3": "Shafts around corners rotate in mirrored directions", + "create.ponder.gearbox.text_4": "Straight connections will be reversed", + + "create.ponder.gearshift.header": "Controlling rotational force using a Gearshift", + "create.ponder.gearshift.text_1": "Gearshifts will relay rotation in a straight line", + "create.ponder.gearshift.text_2": "When powered by Redstone, it reverses the transmission", + + "create.ponder.hand_crank.header": "Generating Rotational Force using Hand Cranks", + "create.ponder.hand_crank.text_1": "Hand Cranks can be used by players to apply rotational force manually", + "create.ponder.hand_crank.text_2": "Hold Right-Click to rotate it Counter-Clockwise", + "create.ponder.hand_crank.text_3": "Its conveyed speed is relatively high", + "create.ponder.hand_crank.text_4": "Sneak and Hold Right-Click to rotate it Clockwise", + + "create.ponder.large_cogwheel.header": "Relaying rotational force using Large Cogwheels", + "create.ponder.large_cogwheel.text_1": "Large cogwheels can connect to each other at right angles", + "create.ponder.large_cogwheel.text_2": "It will help relaying conveyed speed to other axes of rotation", + + "create.ponder.portable_storage_interface.header": "Contraption Storage Exchange", + "create.ponder.portable_storage_interface.text_1": "Inventories on moving contraptions cannot be accessed by players.", + "create.ponder.portable_storage_interface.text_2": "This component can interact with storage without the need to stop the contraption.", + "create.ponder.portable_storage_interface.text_3": "Place a second one with a gap of 1 or 2 blocks inbetween", + "create.ponder.portable_storage_interface.text_4": "Whenever they pass by each other, they will engage in a connection", + "create.ponder.portable_storage_interface.text_5": "While engaged, the stationary interface will represent ALL inventories on the contraption", + "create.ponder.portable_storage_interface.text_6": "Items can now be inserted...", + "create.ponder.portable_storage_interface.text_7": "...or extracted from the contraption", + "create.ponder.portable_storage_interface.text_8": "After no items have been exchanged for a while, the contraption will continue on its way", + + "create.ponder.portable_storage_interface_redstone.header": "Redstone Control", + "create.ponder.portable_storage_interface_redstone.text_1": "Redstone power will prevent the stationary interface from engaging", + + "create.ponder.shaft.header": "Relaying rotational force using Shafts", + "create.ponder.shaft.text_1": "Shafts will relay rotation in a straight line.", + + "create.ponder.shaft_casing.header": "Encasing Shafts", + "create.ponder.shaft_casing.text_1": "Brass or Andesite Casing can be used to decorate Shafts", + + "create.ponder.valve_handle.header": "Generating Rotational Force using Valve Handles", + "create.ponder.valve_handle.text_1": "Valve Handles can be used by players to apply rotational force manually", + "create.ponder.valve_handle.text_2": "Hold Right-Click to rotate it Counter-Clockwise", + "create.ponder.valve_handle.text_3": "Its conveyed speed is slow and precise", + "create.ponder.valve_handle.text_4": "Sneak and Hold Right-Click to rotate it Clockwise", + "create.ponder.valve_handle.text_5": "Valve handles can be dyed for aesthetic purposes", + + "create.ponder.water_wheel.header": "Generating Rotational Force using Water Wheels", + "create.ponder.water_wheel.text_1": "Water Wheels draw force from adjacent Water Currents", + "create.ponder.water_wheel.text_2": "The more faces are powered, the faster the Water Wheel will rotate", + "create.ponder.water_wheel.text_3": "The Wheels' blades should be oriented against the flow", + "create.ponder.water_wheel.text_4": "Facing the opposite way, they will not be as effective", + "_": "Thank you for translating Create!" } \ No newline at end of file diff --git a/src/generated/resources/assets/create/lang/unfinished/de_de.json b/src/generated/resources/assets/create/lang/unfinished/de_de.json index c47bf9b29..8ef6a2ebb 100644 --- a/src/generated/resources/assets/create/lang/unfinished/de_de.json +++ b/src/generated/resources/assets/create/lang/unfinished/de_de.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 978", + "_": "Missing Localizations: 1155", "_": "->------------------------] Game Elements [------------------------<-", @@ -162,7 +162,7 @@ "block.create.gabbro_cobblestone_stairs": "Gabelsteinbruchstein", "block.create.gabbro_cobblestone_wall": "Gabelsteinbruchstein", "block.create.gabbro_pillar": "Gabelsteinsäule", - "block.create.gantry_pinion": "UNLOCALIZED: Gantry Pinion", + "block.create.gantry_carriage": "UNLOCALIZED: Gantry Carriage", "block.create.gantry_shaft": "UNLOCALIZED: Gantry Shaft", "block.create.gearbox": "Getriebe", "block.create.gearshift": "Gangschaltung", @@ -1809,6 +1809,221 @@ "create.tooltip.randomWipDescription7": "UNLOCALIZED: This one maybe isn't for you. What about that one?", "create.tooltip.randomWipDescription8": "UNLOCALIZED: Use it and regret your decision immediately.", + + "_": "->------------------------] Ponder Content [------------------------<-", + + "create.ponder.hold_to_ponder": "UNLOCALIZED: Hold [%1$s] to Ponder", + "create.ponder.subject": "UNLOCALIZED: Subject of this scene", + "create.ponder.pondering": "UNLOCALIZED: Pondering about...", + "create.ponder.identify_mode": "UNLOCALIZED: Identify mode active.\nUnpause with [%1$s]", + "create.ponder.associated": "UNLOCALIZED: Associated Entries", + "create.ponder.shared.movement_anchors": "UNLOCALIZED: With the help of Chassis or Super Glue, larger structures can be moved.", + "create.ponder.shared.rpm32": "UNLOCALIZED: 32 RPM", + "create.ponder.shared.sneak_and": "UNLOCALIZED: Sneak +", + "create.ponder.shared.rpm8": "UNLOCALIZED: 8 RPM", + "create.ponder.shared.ctrl_and": "UNLOCALIZED: Ctrl +", + "create.ponder.shared.rpm16_source": "UNLOCALIZED: Source: 16 RPM", + "create.ponder.shared.rpm16": "UNLOCALIZED: 16 RPM", + "create.ponder.tag.kinetic_sources": "UNLOCALIZED: Kinetic Sources", + "create.ponder.tag.kinetic_sources.description": "UNLOCALIZED: Components which generate Rotational Force", + "create.ponder.tag.contraption_actor": "UNLOCALIZED: Contraption Actors", + "create.ponder.tag.contraption_actor.description": "UNLOCALIZED: Components which expose special behaviour when attached to a moving contraption", + "create.ponder.tag.arm_targets": "UNLOCALIZED: Targets for Mechanical Arms", + "create.ponder.tag.arm_targets.description": "UNLOCALIZED: Components which can be selected as inputs or outputs to the Mechanical Arm", + "create.ponder.tag.logistics": "UNLOCALIZED: Item Transportation", + "create.ponder.tag.logistics.description": "UNLOCALIZED: Components which help moving items around", + "create.ponder.tag.movement_anchor": "UNLOCALIZED: Movement Anchors", + "create.ponder.tag.movement_anchor.description": "UNLOCALIZED: Components which allow the creation of moving contraptions, animating an attached structure in a variety of ways", + "create.ponder.tag.decoration": "UNLOCALIZED: Aesthetics", + "create.ponder.tag.decoration.description": "UNLOCALIZED: Components used mostly for decorative purposes", + "create.ponder.tag.kinetic_appliances": "UNLOCALIZED: Kinetic Appliances", + "create.ponder.tag.kinetic_appliances.description": "UNLOCALIZED: Components which make use of Rotational Force", + "create.ponder.tag.redstone": "UNLOCALIZED: Logic Components", + "create.ponder.tag.redstone.description": "UNLOCALIZED: Components which help with redstone engineering", + "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", + "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", + "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", + "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", + "create.ponder.tag.fluids": "UNLOCALIZED: Fluid Manipulators", + "create.ponder.tag.fluids.description": "UNLOCALIZED: Components which help relaying and making use of Fluids", + + "create.ponder.belt_casing.header": "UNLOCALIZED: Encasing Belts", + "create.ponder.belt_casing.text_1": "UNLOCALIZED: Brass or Andesite Casing can be used to decorate Mechanical Belts", + "create.ponder.belt_casing.text_2": "UNLOCALIZED: A wrench can be used to remove the casing", + + "create.ponder.belt_connector.header": "UNLOCALIZED: Using Mechanical Belts", + "create.ponder.belt_connector.text_1": "UNLOCALIZED: Right-Clicking two shafts with a belt item will connect them together", + "create.ponder.belt_connector.text_2": "UNLOCALIZED: Accidental selections can be canceled with Right-Click while Sneaking", + "create.ponder.belt_connector.text_3": "UNLOCALIZED: Additional Shafts can be added throughout the Belt", + "create.ponder.belt_connector.text_4": "UNLOCALIZED: Shafts connected via Belts will rotate with Identical Speed and Direction", + "create.ponder.belt_connector.text_5": "UNLOCALIZED: Added shafts can be removed using the wrench", + "create.ponder.belt_connector.text_6": "UNLOCALIZED: Mechanical Belts can be dyed for aesthetic purposes", + + "create.ponder.belt_directions.header": "UNLOCALIZED: Valid Orientations for Mechanical Belts", + "create.ponder.belt_directions.text_1": "UNLOCALIZED: Belts cannot connect in arbitrary directions", + "create.ponder.belt_directions.text_2": "UNLOCALIZED: 1. They can connect horizontally", + "create.ponder.belt_directions.text_3": "UNLOCALIZED: 2. They can connect diagonally", + "create.ponder.belt_directions.text_4": "UNLOCALIZED: 3. They can connect vertically", + "create.ponder.belt_directions.text_5": "UNLOCALIZED: 4. And they can connect vertical shafts horizontally", + "create.ponder.belt_directions.text_6": "UNLOCALIZED: These are all possible directions.\nBelts can span any Length between 2 and 20 blocks", + + "create.ponder.belt_transport.header": "UNLOCALIZED: Using Mechanical Belts for Logistics", + "create.ponder.belt_transport.text_1": "UNLOCALIZED: Moving belts will transport Items and other Entities", + "create.ponder.belt_transport.text_2": "UNLOCALIZED: Right-Click with an empty hand to take items off a belt", + + "create.ponder.brass_funnel.header": "UNLOCALIZED: The Brass Funnel", + "create.ponder.brass_funnel.text_1": "UNLOCALIZED: Andesite Funnels can only ever extract single items.", + "create.ponder.brass_funnel.text_2": "UNLOCALIZED: Brass Funnels can extract up to a full stack.", + "create.ponder.brass_funnel.text_3": "UNLOCALIZED: Scrolling on the filter slot allows for precise control over the extracted stack size.", + "create.ponder.brass_funnel.text_4": "UNLOCALIZED: Using items on the filter slot will restrict the funnel to only transfer matching stacks.", + + "create.ponder.chain_drive.header": "UNLOCALIZED: Relaying rotational force with Chain Drives", + "create.ponder.chain_drive.text_1": "UNLOCALIZED: Chain Drives relay rotation to each other in a row", + "create.ponder.chain_drive.text_2": "UNLOCALIZED: All shafts connected like this will rotate in the same direction", + "create.ponder.chain_drive.text_3": "UNLOCALIZED: Any part of the row can be rotated by 90 degrees", + + "create.ponder.chain_gearshift.header": "UNLOCALIZED: Controlling rotational speed with Chain Gearshifts", + "create.ponder.chain_gearshift.text_1": "UNLOCALIZED: Unpowered Chain Gearshifts behave exacly like Chain Drives", + "create.ponder.chain_gearshift.text_2": "UNLOCALIZED: When Powered, the speed transmitted to other Chain Drives in the row is doubled", + "create.ponder.chain_gearshift.text_3": "UNLOCALIZED: Whenever the Powered Gearshift is not at the source, its speed will be halved instead", + "create.ponder.chain_gearshift.text_4": "UNLOCALIZED: In both cases, Chain Drives in the row always run at 2x the speed of the Powered Gearshift", + "create.ponder.chain_gearshift.text_5": "UNLOCALIZED: Using analog signals, the ratio can be adjusted more precisely between 1 and 2", + "create.ponder.chain_gearshift.text_6": "UNLOCALIZED: 12 RPM", + + "create.ponder.clutch.header": "UNLOCALIZED: Controlling rotational force using a Clutch", + "create.ponder.clutch.text_1": "UNLOCALIZED: Clutches will relay rotation in a straight line", + "create.ponder.clutch.text_2": "UNLOCALIZED: When powered by Redstone, it breaks the connection", + + "create.ponder.cog_speedup.header": "UNLOCALIZED: Gearshifting with Cogs", + "create.ponder.cog_speedup.text_1": "UNLOCALIZED: Large and Small cogs can be connected diagonally", + "create.ponder.cog_speedup.text_2": "UNLOCALIZED: Shifting from large to small cogs, the conveyed speed will be doubled", + "create.ponder.cog_speedup.text_3": "UNLOCALIZED: Shifting the opposite way, the conveyed speed will be halved", + + "create.ponder.cogwheel.header": "UNLOCALIZED: Relaying rotational force using Cogwheels", + "create.ponder.cogwheel.text_1": "UNLOCALIZED: Cogwheels will relay rotation to other adjacent cogwheels", + "create.ponder.cogwheel.text_2": "UNLOCALIZED: Neighbouring shafts connected like this will rotate in opposite directions", + + "create.ponder.creative_motor.header": "UNLOCALIZED: Generating Rotational Force using Creative Motors", + "create.ponder.creative_motor.text_1": "UNLOCALIZED: Creative motors are a compact and configurable source of Rotational Force", + "create.ponder.creative_motor.text_2": "UNLOCALIZED: Scrolling on the back panel changes the RPM of the motors' rotational output", + + "create.ponder.fan_direction.header": "UNLOCALIZED: Air flow of Encased Fans", + "create.ponder.fan_direction.text_1": "UNLOCALIZED: Encased Fans use Rotational Force to create an Air Current", + "create.ponder.fan_direction.text_2": "UNLOCALIZED: Strength and Direction of Flow depends on the Rotational Input", + + "create.ponder.fan_processing.header": "UNLOCALIZED: Processing Items using Encased Fans", + "create.ponder.fan_processing.text_1": "UNLOCALIZED: When passing through lava, the Air Flow becomes Heated", + "create.ponder.fan_processing.text_2": "UNLOCALIZED: Items caught in the area will be smelted", + "create.ponder.fan_processing.text_3": "UNLOCALIZED: Food items thrown here would be incinerated", + "create.ponder.fan_processing.text_4": "UNLOCALIZED: Instead, a setup for Smoking using Fire should be used for them", + "create.ponder.fan_processing.text_5": "UNLOCALIZED: Air Flows passing through water create a Washing Setup", + "create.ponder.fan_processing.text_6": "UNLOCALIZED: Some interesting new processing can be done with it", + "create.ponder.fan_processing.text_7": "UNLOCALIZED: The Speed of the Fan does NOT affect the processing speed, only its range", + "create.ponder.fan_processing.text_8": "UNLOCALIZED: Fan Processing can also be applied to Items on Depots and Belts", + + "create.ponder.fan_source.header": "UNLOCALIZED: Generating Rotational Force using Encased Fans", + "create.ponder.fan_source.text_1": "UNLOCALIZED: Fans facing down into a source of heat can provide Rotational Force", + "create.ponder.fan_source.text_2": "UNLOCALIZED: When given a Redstone Signal, the Fans will start providing power", + + "create.ponder.funnel_compat.header": "UNLOCALIZED: Funnel compatibility", + "create.ponder.funnel_compat.text_1": "UNLOCALIZED: Funnels should also interact nicely with a handful of other components.", + "create.ponder.funnel_compat.text_2": "UNLOCALIZED: Vertical Saws", + "create.ponder.funnel_compat.text_3": "UNLOCALIZED: Depots", + "create.ponder.funnel_compat.text_4": "UNLOCALIZED: Item Drains", + + "create.ponder.funnel_direction.header": "UNLOCALIZED: Direction of Transfer", + "create.ponder.funnel_direction.text_1": "UNLOCALIZED: Placed normally, it pulls items from the inventory.", + "create.ponder.funnel_direction.text_2": "UNLOCALIZED: Placed while sneaking, it puts items into the inventory.", + "create.ponder.funnel_direction.text_3": "UNLOCALIZED: Using a wrench, the funnel can be flipped after placement.", + "create.ponder.funnel_direction.text_4": "UNLOCALIZED: Same rules will apply for most orientations.", + "create.ponder.funnel_direction.text_5": "UNLOCALIZED: Funnels on belts will extract/insert depending on its movement direction.", + + "create.ponder.funnel_intro.header": "UNLOCALIZED: Using funnels", + "create.ponder.funnel_intro.text_1": "UNLOCALIZED: Funnels are ideal for transferring items from and to inventories.", + + "create.ponder.funnel_redstone.header": "UNLOCALIZED: Redstone control", + "create.ponder.funnel_redstone.text_1": "UNLOCALIZED: Redstone power will prevent any funnel from acting.", + + "create.ponder.funnel_transfer.header": "UNLOCALIZED: Direct transfer", + "create.ponder.funnel_transfer.text_1": "UNLOCALIZED: Funnels cannot ever transfer between closed inventories directly.", + "create.ponder.funnel_transfer.text_2": "UNLOCALIZED: Chutes or Smart chutes might be more suitable for such purposes.", + "create.ponder.funnel_transfer.text_3": "UNLOCALIZED: Same applies for horizontal movement.\nA mechanical belt should help here.", + + "create.ponder.gantry_carriage.header": "UNLOCALIZED: Using Gantry Carriages", + "create.ponder.gantry_carriage.text_1": "UNLOCALIZED: Gantry Carriages can mount to and slide along a Gantry Shaft.", + "create.ponder.gantry_carriage.text_2": "UNLOCALIZED: Gantry setups can move attached Blocks.", + + "create.ponder.gantry_cascaded.header": "UNLOCALIZED: Cascaded Gantries", + "create.ponder.gantry_cascaded.text_1": "UNLOCALIZED: Gantry shafts attach to a carriage without the need of super glue", + "create.ponder.gantry_cascaded.text_2": "UNLOCALIZED: Same applies for carriages on moved Gantry Shafts", + "create.ponder.gantry_cascaded.text_3": "UNLOCALIZED: Thus, a gantry system can be cascaded to cover multiple axes of movement", + + "create.ponder.gantry_direction.header": "UNLOCALIZED: Gantry Movement Direction", + "create.ponder.gantry_direction.text_1": "UNLOCALIZED: Gantry Shafts can have opposite orientations", + "create.ponder.gantry_direction.text_2": "UNLOCALIZED: The movement direction of carriages depend on their shafts' orientation", + "create.ponder.gantry_direction.text_3": "UNLOCALIZED: ...as well as the rotation direction of the shaft", + "create.ponder.gantry_direction.text_4": "UNLOCALIZED: Same rules apply for the propagated rotation", + + "create.ponder.gantry_redstone.header": "UNLOCALIZED: Gantry Power Propagation", + "create.ponder.gantry_redstone.text_1": "UNLOCALIZED: Redstone-powered gantry shafts stop moving their carriages", + "create.ponder.gantry_redstone.text_2": "UNLOCALIZED: Instead, its rotational force is relayed to the carriages' output shaft", + + "create.ponder.gantry_shaft.header": "UNLOCALIZED: Using Gantry Shafts", + "create.ponder.gantry_shaft.text_1": "UNLOCALIZED: Gantry Shafts form the basis of a gantry setup. Attached Carriages will move along them.", + "create.ponder.gantry_shaft.text_2": "UNLOCALIZED: Gantry setups can move attached Blocks.", + + "create.ponder.gearbox.header": "UNLOCALIZED: Relaying rotational force using Gearboxes", + "create.ponder.gearbox.text_1": "UNLOCALIZED: Jumping between axes of rotation can get bulky quickly", + "create.ponder.gearbox.text_2": "UNLOCALIZED: A gearbox is the more compact equivalent of this setup", + "create.ponder.gearbox.text_3": "UNLOCALIZED: Shafts around corners rotate in mirrored directions", + "create.ponder.gearbox.text_4": "UNLOCALIZED: Straight connections will be reversed", + + "create.ponder.gearshift.header": "UNLOCALIZED: Controlling rotational force using a Gearshift", + "create.ponder.gearshift.text_1": "UNLOCALIZED: Gearshifts will relay rotation in a straight line", + "create.ponder.gearshift.text_2": "UNLOCALIZED: When powered by Redstone, it reverses the transmission", + + "create.ponder.hand_crank.header": "UNLOCALIZED: Generating Rotational Force using Hand Cranks", + "create.ponder.hand_crank.text_1": "UNLOCALIZED: Hand Cranks can be used by players to apply rotational force manually", + "create.ponder.hand_crank.text_2": "UNLOCALIZED: Hold Right-Click to rotate it Counter-Clockwise", + "create.ponder.hand_crank.text_3": "UNLOCALIZED: Its conveyed speed is relatively high", + "create.ponder.hand_crank.text_4": "UNLOCALIZED: Sneak and Hold Right-Click to rotate it Clockwise", + + "create.ponder.large_cogwheel.header": "UNLOCALIZED: Relaying rotational force using Large Cogwheels", + "create.ponder.large_cogwheel.text_1": "UNLOCALIZED: Large cogwheels can connect to each other at right angles", + "create.ponder.large_cogwheel.text_2": "UNLOCALIZED: It will help relaying conveyed speed to other axes of rotation", + + "create.ponder.portable_storage_interface.header": "UNLOCALIZED: Contraption Storage Exchange", + "create.ponder.portable_storage_interface.text_1": "UNLOCALIZED: Inventories on moving contraptions cannot be accessed by players.", + "create.ponder.portable_storage_interface.text_2": "UNLOCALIZED: This component can interact with storage without the need to stop the contraption.", + "create.ponder.portable_storage_interface.text_3": "UNLOCALIZED: Place a second one with a gap of 1 or 2 blocks inbetween", + "create.ponder.portable_storage_interface.text_4": "UNLOCALIZED: Whenever they pass by each other, they will engage in a connection", + "create.ponder.portable_storage_interface.text_5": "UNLOCALIZED: While engaged, the stationary interface will represent ALL inventories on the contraption", + "create.ponder.portable_storage_interface.text_6": "UNLOCALIZED: Items can now be inserted...", + "create.ponder.portable_storage_interface.text_7": "UNLOCALIZED: ...or extracted from the contraption", + "create.ponder.portable_storage_interface.text_8": "UNLOCALIZED: After no items have been exchanged for a while, the contraption will continue on its way", + + "create.ponder.portable_storage_interface_redstone.header": "UNLOCALIZED: Redstone Control", + "create.ponder.portable_storage_interface_redstone.text_1": "UNLOCALIZED: Redstone power will prevent the stationary interface from engaging", + + "create.ponder.shaft.header": "UNLOCALIZED: Relaying rotational force using Shafts", + "create.ponder.shaft.text_1": "UNLOCALIZED: Shafts will relay rotation in a straight line.", + + "create.ponder.shaft_casing.header": "UNLOCALIZED: Encasing Shafts", + "create.ponder.shaft_casing.text_1": "UNLOCALIZED: Brass or Andesite Casing can be used to decorate Shafts", + + "create.ponder.valve_handle.header": "UNLOCALIZED: Generating Rotational Force using Valve Handles", + "create.ponder.valve_handle.text_1": "UNLOCALIZED: Valve Handles can be used by players to apply rotational force manually", + "create.ponder.valve_handle.text_2": "UNLOCALIZED: Hold Right-Click to rotate it Counter-Clockwise", + "create.ponder.valve_handle.text_3": "UNLOCALIZED: Its conveyed speed is slow and precise", + "create.ponder.valve_handle.text_4": "UNLOCALIZED: Sneak and Hold Right-Click to rotate it Clockwise", + "create.ponder.valve_handle.text_5": "UNLOCALIZED: Valve handles can be dyed for aesthetic purposes", + + "create.ponder.water_wheel.header": "UNLOCALIZED: Generating Rotational Force using Water Wheels", + "create.ponder.water_wheel.text_1": "UNLOCALIZED: Water Wheels draw force from adjacent Water Currents", + "create.ponder.water_wheel.text_2": "UNLOCALIZED: The more faces are powered, the faster the Water Wheel will rotate", + "create.ponder.water_wheel.text_3": "UNLOCALIZED: The Wheels' blades should be oriented against the flow", + "create.ponder.water_wheel.text_4": "UNLOCALIZED: Facing the opposite way, they will not be as effective", + "_": "Thank you for translating Create!" } \ No newline at end of file diff --git a/src/generated/resources/assets/create/lang/unfinished/es_es.json b/src/generated/resources/assets/create/lang/unfinished/es_es.json index 7614ce83f..4df84e931 100644 --- a/src/generated/resources/assets/create/lang/unfinished/es_es.json +++ b/src/generated/resources/assets/create/lang/unfinished/es_es.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 8", + "_": "Missing Localizations: 186", "_": "->------------------------] Game Elements [------------------------<-", @@ -162,7 +162,7 @@ "block.create.gabbro_cobblestone_stairs": "Escaleras de adoquínes de gabro", "block.create.gabbro_cobblestone_wall": "Pared de adoquínes de gabro", "block.create.gabbro_pillar": "Pilar de gabro", - "block.create.gantry_pinion": "Piñón de grúa", + "block.create.gantry_carriage": "UNLOCALIZED: Gantry Carriage", "block.create.gantry_shaft": "Eje de grúa", "block.create.gearbox": "Caja de transmisión", "block.create.gearshift": "Caja de cambios", @@ -1809,6 +1809,221 @@ "create.tooltip.randomWipDescription7": "Este quizás no es para ti. ¿Qué tal ese?", "create.tooltip.randomWipDescription8": "Úsalo y arrepiéntete de tu decisión inmediatamente", + + "_": "->------------------------] Ponder Content [------------------------<-", + + "create.ponder.hold_to_ponder": "UNLOCALIZED: Hold [%1$s] to Ponder", + "create.ponder.subject": "UNLOCALIZED: Subject of this scene", + "create.ponder.pondering": "UNLOCALIZED: Pondering about...", + "create.ponder.identify_mode": "UNLOCALIZED: Identify mode active.\nUnpause with [%1$s]", + "create.ponder.associated": "UNLOCALIZED: Associated Entries", + "create.ponder.shared.movement_anchors": "UNLOCALIZED: With the help of Chassis or Super Glue, larger structures can be moved.", + "create.ponder.shared.rpm32": "UNLOCALIZED: 32 RPM", + "create.ponder.shared.sneak_and": "UNLOCALIZED: Sneak +", + "create.ponder.shared.rpm8": "UNLOCALIZED: 8 RPM", + "create.ponder.shared.ctrl_and": "UNLOCALIZED: Ctrl +", + "create.ponder.shared.rpm16_source": "UNLOCALIZED: Source: 16 RPM", + "create.ponder.shared.rpm16": "UNLOCALIZED: 16 RPM", + "create.ponder.tag.kinetic_sources": "UNLOCALIZED: Kinetic Sources", + "create.ponder.tag.kinetic_sources.description": "UNLOCALIZED: Components which generate Rotational Force", + "create.ponder.tag.contraption_actor": "UNLOCALIZED: Contraption Actors", + "create.ponder.tag.contraption_actor.description": "UNLOCALIZED: Components which expose special behaviour when attached to a moving contraption", + "create.ponder.tag.arm_targets": "UNLOCALIZED: Targets for Mechanical Arms", + "create.ponder.tag.arm_targets.description": "UNLOCALIZED: Components which can be selected as inputs or outputs to the Mechanical Arm", + "create.ponder.tag.logistics": "UNLOCALIZED: Item Transportation", + "create.ponder.tag.logistics.description": "UNLOCALIZED: Components which help moving items around", + "create.ponder.tag.movement_anchor": "UNLOCALIZED: Movement Anchors", + "create.ponder.tag.movement_anchor.description": "UNLOCALIZED: Components which allow the creation of moving contraptions, animating an attached structure in a variety of ways", + "create.ponder.tag.decoration": "UNLOCALIZED: Aesthetics", + "create.ponder.tag.decoration.description": "UNLOCALIZED: Components used mostly for decorative purposes", + "create.ponder.tag.kinetic_appliances": "UNLOCALIZED: Kinetic Appliances", + "create.ponder.tag.kinetic_appliances.description": "UNLOCALIZED: Components which make use of Rotational Force", + "create.ponder.tag.redstone": "UNLOCALIZED: Logic Components", + "create.ponder.tag.redstone.description": "UNLOCALIZED: Components which help with redstone engineering", + "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", + "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", + "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", + "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", + "create.ponder.tag.fluids": "UNLOCALIZED: Fluid Manipulators", + "create.ponder.tag.fluids.description": "UNLOCALIZED: Components which help relaying and making use of Fluids", + + "create.ponder.belt_casing.header": "UNLOCALIZED: Encasing Belts", + "create.ponder.belt_casing.text_1": "UNLOCALIZED: Brass or Andesite Casing can be used to decorate Mechanical Belts", + "create.ponder.belt_casing.text_2": "UNLOCALIZED: A wrench can be used to remove the casing", + + "create.ponder.belt_connector.header": "UNLOCALIZED: Using Mechanical Belts", + "create.ponder.belt_connector.text_1": "UNLOCALIZED: Right-Clicking two shafts with a belt item will connect them together", + "create.ponder.belt_connector.text_2": "UNLOCALIZED: Accidental selections can be canceled with Right-Click while Sneaking", + "create.ponder.belt_connector.text_3": "UNLOCALIZED: Additional Shafts can be added throughout the Belt", + "create.ponder.belt_connector.text_4": "UNLOCALIZED: Shafts connected via Belts will rotate with Identical Speed and Direction", + "create.ponder.belt_connector.text_5": "UNLOCALIZED: Added shafts can be removed using the wrench", + "create.ponder.belt_connector.text_6": "UNLOCALIZED: Mechanical Belts can be dyed for aesthetic purposes", + + "create.ponder.belt_directions.header": "UNLOCALIZED: Valid Orientations for Mechanical Belts", + "create.ponder.belt_directions.text_1": "UNLOCALIZED: Belts cannot connect in arbitrary directions", + "create.ponder.belt_directions.text_2": "UNLOCALIZED: 1. They can connect horizontally", + "create.ponder.belt_directions.text_3": "UNLOCALIZED: 2. They can connect diagonally", + "create.ponder.belt_directions.text_4": "UNLOCALIZED: 3. They can connect vertically", + "create.ponder.belt_directions.text_5": "UNLOCALIZED: 4. And they can connect vertical shafts horizontally", + "create.ponder.belt_directions.text_6": "UNLOCALIZED: These are all possible directions.\nBelts can span any Length between 2 and 20 blocks", + + "create.ponder.belt_transport.header": "UNLOCALIZED: Using Mechanical Belts for Logistics", + "create.ponder.belt_transport.text_1": "UNLOCALIZED: Moving belts will transport Items and other Entities", + "create.ponder.belt_transport.text_2": "UNLOCALIZED: Right-Click with an empty hand to take items off a belt", + + "create.ponder.brass_funnel.header": "UNLOCALIZED: The Brass Funnel", + "create.ponder.brass_funnel.text_1": "UNLOCALIZED: Andesite Funnels can only ever extract single items.", + "create.ponder.brass_funnel.text_2": "UNLOCALIZED: Brass Funnels can extract up to a full stack.", + "create.ponder.brass_funnel.text_3": "UNLOCALIZED: Scrolling on the filter slot allows for precise control over the extracted stack size.", + "create.ponder.brass_funnel.text_4": "UNLOCALIZED: Using items on the filter slot will restrict the funnel to only transfer matching stacks.", + + "create.ponder.chain_drive.header": "UNLOCALIZED: Relaying rotational force with Chain Drives", + "create.ponder.chain_drive.text_1": "UNLOCALIZED: Chain Drives relay rotation to each other in a row", + "create.ponder.chain_drive.text_2": "UNLOCALIZED: All shafts connected like this will rotate in the same direction", + "create.ponder.chain_drive.text_3": "UNLOCALIZED: Any part of the row can be rotated by 90 degrees", + + "create.ponder.chain_gearshift.header": "UNLOCALIZED: Controlling rotational speed with Chain Gearshifts", + "create.ponder.chain_gearshift.text_1": "UNLOCALIZED: Unpowered Chain Gearshifts behave exacly like Chain Drives", + "create.ponder.chain_gearshift.text_2": "UNLOCALIZED: When Powered, the speed transmitted to other Chain Drives in the row is doubled", + "create.ponder.chain_gearshift.text_3": "UNLOCALIZED: Whenever the Powered Gearshift is not at the source, its speed will be halved instead", + "create.ponder.chain_gearshift.text_4": "UNLOCALIZED: In both cases, Chain Drives in the row always run at 2x the speed of the Powered Gearshift", + "create.ponder.chain_gearshift.text_5": "UNLOCALIZED: Using analog signals, the ratio can be adjusted more precisely between 1 and 2", + "create.ponder.chain_gearshift.text_6": "UNLOCALIZED: 12 RPM", + + "create.ponder.clutch.header": "UNLOCALIZED: Controlling rotational force using a Clutch", + "create.ponder.clutch.text_1": "UNLOCALIZED: Clutches will relay rotation in a straight line", + "create.ponder.clutch.text_2": "UNLOCALIZED: When powered by Redstone, it breaks the connection", + + "create.ponder.cog_speedup.header": "UNLOCALIZED: Gearshifting with Cogs", + "create.ponder.cog_speedup.text_1": "UNLOCALIZED: Large and Small cogs can be connected diagonally", + "create.ponder.cog_speedup.text_2": "UNLOCALIZED: Shifting from large to small cogs, the conveyed speed will be doubled", + "create.ponder.cog_speedup.text_3": "UNLOCALIZED: Shifting the opposite way, the conveyed speed will be halved", + + "create.ponder.cogwheel.header": "UNLOCALIZED: Relaying rotational force using Cogwheels", + "create.ponder.cogwheel.text_1": "UNLOCALIZED: Cogwheels will relay rotation to other adjacent cogwheels", + "create.ponder.cogwheel.text_2": "UNLOCALIZED: Neighbouring shafts connected like this will rotate in opposite directions", + + "create.ponder.creative_motor.header": "UNLOCALIZED: Generating Rotational Force using Creative Motors", + "create.ponder.creative_motor.text_1": "UNLOCALIZED: Creative motors are a compact and configurable source of Rotational Force", + "create.ponder.creative_motor.text_2": "UNLOCALIZED: Scrolling on the back panel changes the RPM of the motors' rotational output", + + "create.ponder.fan_direction.header": "UNLOCALIZED: Air flow of Encased Fans", + "create.ponder.fan_direction.text_1": "UNLOCALIZED: Encased Fans use Rotational Force to create an Air Current", + "create.ponder.fan_direction.text_2": "UNLOCALIZED: Strength and Direction of Flow depends on the Rotational Input", + + "create.ponder.fan_processing.header": "UNLOCALIZED: Processing Items using Encased Fans", + "create.ponder.fan_processing.text_1": "UNLOCALIZED: When passing through lava, the Air Flow becomes Heated", + "create.ponder.fan_processing.text_2": "UNLOCALIZED: Items caught in the area will be smelted", + "create.ponder.fan_processing.text_3": "UNLOCALIZED: Food items thrown here would be incinerated", + "create.ponder.fan_processing.text_4": "UNLOCALIZED: Instead, a setup for Smoking using Fire should be used for them", + "create.ponder.fan_processing.text_5": "UNLOCALIZED: Air Flows passing through water create a Washing Setup", + "create.ponder.fan_processing.text_6": "UNLOCALIZED: Some interesting new processing can be done with it", + "create.ponder.fan_processing.text_7": "UNLOCALIZED: The Speed of the Fan does NOT affect the processing speed, only its range", + "create.ponder.fan_processing.text_8": "UNLOCALIZED: Fan Processing can also be applied to Items on Depots and Belts", + + "create.ponder.fan_source.header": "UNLOCALIZED: Generating Rotational Force using Encased Fans", + "create.ponder.fan_source.text_1": "UNLOCALIZED: Fans facing down into a source of heat can provide Rotational Force", + "create.ponder.fan_source.text_2": "UNLOCALIZED: When given a Redstone Signal, the Fans will start providing power", + + "create.ponder.funnel_compat.header": "UNLOCALIZED: Funnel compatibility", + "create.ponder.funnel_compat.text_1": "UNLOCALIZED: Funnels should also interact nicely with a handful of other components.", + "create.ponder.funnel_compat.text_2": "UNLOCALIZED: Vertical Saws", + "create.ponder.funnel_compat.text_3": "UNLOCALIZED: Depots", + "create.ponder.funnel_compat.text_4": "UNLOCALIZED: Item Drains", + + "create.ponder.funnel_direction.header": "UNLOCALIZED: Direction of Transfer", + "create.ponder.funnel_direction.text_1": "UNLOCALIZED: Placed normally, it pulls items from the inventory.", + "create.ponder.funnel_direction.text_2": "UNLOCALIZED: Placed while sneaking, it puts items into the inventory.", + "create.ponder.funnel_direction.text_3": "UNLOCALIZED: Using a wrench, the funnel can be flipped after placement.", + "create.ponder.funnel_direction.text_4": "UNLOCALIZED: Same rules will apply for most orientations.", + "create.ponder.funnel_direction.text_5": "UNLOCALIZED: Funnels on belts will extract/insert depending on its movement direction.", + + "create.ponder.funnel_intro.header": "UNLOCALIZED: Using funnels", + "create.ponder.funnel_intro.text_1": "UNLOCALIZED: Funnels are ideal for transferring items from and to inventories.", + + "create.ponder.funnel_redstone.header": "UNLOCALIZED: Redstone control", + "create.ponder.funnel_redstone.text_1": "UNLOCALIZED: Redstone power will prevent any funnel from acting.", + + "create.ponder.funnel_transfer.header": "UNLOCALIZED: Direct transfer", + "create.ponder.funnel_transfer.text_1": "UNLOCALIZED: Funnels cannot ever transfer between closed inventories directly.", + "create.ponder.funnel_transfer.text_2": "UNLOCALIZED: Chutes or Smart chutes might be more suitable for such purposes.", + "create.ponder.funnel_transfer.text_3": "UNLOCALIZED: Same applies for horizontal movement.\nA mechanical belt should help here.", + + "create.ponder.gantry_carriage.header": "UNLOCALIZED: Using Gantry Carriages", + "create.ponder.gantry_carriage.text_1": "UNLOCALIZED: Gantry Carriages can mount to and slide along a Gantry Shaft.", + "create.ponder.gantry_carriage.text_2": "UNLOCALIZED: Gantry setups can move attached Blocks.", + + "create.ponder.gantry_cascaded.header": "UNLOCALIZED: Cascaded Gantries", + "create.ponder.gantry_cascaded.text_1": "UNLOCALIZED: Gantry shafts attach to a carriage without the need of super glue", + "create.ponder.gantry_cascaded.text_2": "UNLOCALIZED: Same applies for carriages on moved Gantry Shafts", + "create.ponder.gantry_cascaded.text_3": "UNLOCALIZED: Thus, a gantry system can be cascaded to cover multiple axes of movement", + + "create.ponder.gantry_direction.header": "UNLOCALIZED: Gantry Movement Direction", + "create.ponder.gantry_direction.text_1": "UNLOCALIZED: Gantry Shafts can have opposite orientations", + "create.ponder.gantry_direction.text_2": "UNLOCALIZED: The movement direction of carriages depend on their shafts' orientation", + "create.ponder.gantry_direction.text_3": "UNLOCALIZED: ...as well as the rotation direction of the shaft", + "create.ponder.gantry_direction.text_4": "UNLOCALIZED: Same rules apply for the propagated rotation", + + "create.ponder.gantry_redstone.header": "UNLOCALIZED: Gantry Power Propagation", + "create.ponder.gantry_redstone.text_1": "UNLOCALIZED: Redstone-powered gantry shafts stop moving their carriages", + "create.ponder.gantry_redstone.text_2": "UNLOCALIZED: Instead, its rotational force is relayed to the carriages' output shaft", + + "create.ponder.gantry_shaft.header": "UNLOCALIZED: Using Gantry Shafts", + "create.ponder.gantry_shaft.text_1": "UNLOCALIZED: Gantry Shafts form the basis of a gantry setup. Attached Carriages will move along them.", + "create.ponder.gantry_shaft.text_2": "UNLOCALIZED: Gantry setups can move attached Blocks.", + + "create.ponder.gearbox.header": "UNLOCALIZED: Relaying rotational force using Gearboxes", + "create.ponder.gearbox.text_1": "UNLOCALIZED: Jumping between axes of rotation can get bulky quickly", + "create.ponder.gearbox.text_2": "UNLOCALIZED: A gearbox is the more compact equivalent of this setup", + "create.ponder.gearbox.text_3": "UNLOCALIZED: Shafts around corners rotate in mirrored directions", + "create.ponder.gearbox.text_4": "UNLOCALIZED: Straight connections will be reversed", + + "create.ponder.gearshift.header": "UNLOCALIZED: Controlling rotational force using a Gearshift", + "create.ponder.gearshift.text_1": "UNLOCALIZED: Gearshifts will relay rotation in a straight line", + "create.ponder.gearshift.text_2": "UNLOCALIZED: When powered by Redstone, it reverses the transmission", + + "create.ponder.hand_crank.header": "UNLOCALIZED: Generating Rotational Force using Hand Cranks", + "create.ponder.hand_crank.text_1": "UNLOCALIZED: Hand Cranks can be used by players to apply rotational force manually", + "create.ponder.hand_crank.text_2": "UNLOCALIZED: Hold Right-Click to rotate it Counter-Clockwise", + "create.ponder.hand_crank.text_3": "UNLOCALIZED: Its conveyed speed is relatively high", + "create.ponder.hand_crank.text_4": "UNLOCALIZED: Sneak and Hold Right-Click to rotate it Clockwise", + + "create.ponder.large_cogwheel.header": "UNLOCALIZED: Relaying rotational force using Large Cogwheels", + "create.ponder.large_cogwheel.text_1": "UNLOCALIZED: Large cogwheels can connect to each other at right angles", + "create.ponder.large_cogwheel.text_2": "UNLOCALIZED: It will help relaying conveyed speed to other axes of rotation", + + "create.ponder.portable_storage_interface.header": "UNLOCALIZED: Contraption Storage Exchange", + "create.ponder.portable_storage_interface.text_1": "UNLOCALIZED: Inventories on moving contraptions cannot be accessed by players.", + "create.ponder.portable_storage_interface.text_2": "UNLOCALIZED: This component can interact with storage without the need to stop the contraption.", + "create.ponder.portable_storage_interface.text_3": "UNLOCALIZED: Place a second one with a gap of 1 or 2 blocks inbetween", + "create.ponder.portable_storage_interface.text_4": "UNLOCALIZED: Whenever they pass by each other, they will engage in a connection", + "create.ponder.portable_storage_interface.text_5": "UNLOCALIZED: While engaged, the stationary interface will represent ALL inventories on the contraption", + "create.ponder.portable_storage_interface.text_6": "UNLOCALIZED: Items can now be inserted...", + "create.ponder.portable_storage_interface.text_7": "UNLOCALIZED: ...or extracted from the contraption", + "create.ponder.portable_storage_interface.text_8": "UNLOCALIZED: After no items have been exchanged for a while, the contraption will continue on its way", + + "create.ponder.portable_storage_interface_redstone.header": "UNLOCALIZED: Redstone Control", + "create.ponder.portable_storage_interface_redstone.text_1": "UNLOCALIZED: Redstone power will prevent the stationary interface from engaging", + + "create.ponder.shaft.header": "UNLOCALIZED: Relaying rotational force using Shafts", + "create.ponder.shaft.text_1": "UNLOCALIZED: Shafts will relay rotation in a straight line.", + + "create.ponder.shaft_casing.header": "UNLOCALIZED: Encasing Shafts", + "create.ponder.shaft_casing.text_1": "UNLOCALIZED: Brass or Andesite Casing can be used to decorate Shafts", + + "create.ponder.valve_handle.header": "UNLOCALIZED: Generating Rotational Force using Valve Handles", + "create.ponder.valve_handle.text_1": "UNLOCALIZED: Valve Handles can be used by players to apply rotational force manually", + "create.ponder.valve_handle.text_2": "UNLOCALIZED: Hold Right-Click to rotate it Counter-Clockwise", + "create.ponder.valve_handle.text_3": "UNLOCALIZED: Its conveyed speed is slow and precise", + "create.ponder.valve_handle.text_4": "UNLOCALIZED: Sneak and Hold Right-Click to rotate it Clockwise", + "create.ponder.valve_handle.text_5": "UNLOCALIZED: Valve handles can be dyed for aesthetic purposes", + + "create.ponder.water_wheel.header": "UNLOCALIZED: Generating Rotational Force using Water Wheels", + "create.ponder.water_wheel.text_1": "UNLOCALIZED: Water Wheels draw force from adjacent Water Currents", + "create.ponder.water_wheel.text_2": "UNLOCALIZED: The more faces are powered, the faster the Water Wheel will rotate", + "create.ponder.water_wheel.text_3": "UNLOCALIZED: The Wheels' blades should be oriented against the flow", + "create.ponder.water_wheel.text_4": "UNLOCALIZED: Facing the opposite way, they will not be as effective", + "_": "Thank you for translating Create!" } \ No newline at end of file diff --git a/src/generated/resources/assets/create/lang/unfinished/es_mx.json b/src/generated/resources/assets/create/lang/unfinished/es_mx.json index e3db6b4ac..0b112ec5a 100644 --- a/src/generated/resources/assets/create/lang/unfinished/es_mx.json +++ b/src/generated/resources/assets/create/lang/unfinished/es_mx.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 908", + "_": "Missing Localizations: 1085", "_": "->------------------------] Game Elements [------------------------<-", @@ -162,7 +162,7 @@ "block.create.gabbro_cobblestone_stairs": "Escaleras de Piedra Labrada de Gabro", "block.create.gabbro_cobblestone_wall": "Pared de Piedra Labrada de Gabro", "block.create.gabbro_pillar": "Pilar de Gabro", - "block.create.gantry_pinion": "UNLOCALIZED: Gantry Pinion", + "block.create.gantry_carriage": "UNLOCALIZED: Gantry Carriage", "block.create.gantry_shaft": "UNLOCALIZED: Gantry Shaft", "block.create.gearbox": "Transmisión", "block.create.gearshift": "Cambio de Marcha", @@ -1809,6 +1809,221 @@ "create.tooltip.randomWipDescription7": "UNLOCALIZED: This one maybe isn't for you. What about that one?", "create.tooltip.randomWipDescription8": "UNLOCALIZED: Use it and regret your decision immediately.", + + "_": "->------------------------] Ponder Content [------------------------<-", + + "create.ponder.hold_to_ponder": "UNLOCALIZED: Hold [%1$s] to Ponder", + "create.ponder.subject": "UNLOCALIZED: Subject of this scene", + "create.ponder.pondering": "UNLOCALIZED: Pondering about...", + "create.ponder.identify_mode": "UNLOCALIZED: Identify mode active.\nUnpause with [%1$s]", + "create.ponder.associated": "UNLOCALIZED: Associated Entries", + "create.ponder.shared.movement_anchors": "UNLOCALIZED: With the help of Chassis or Super Glue, larger structures can be moved.", + "create.ponder.shared.rpm32": "UNLOCALIZED: 32 RPM", + "create.ponder.shared.sneak_and": "UNLOCALIZED: Sneak +", + "create.ponder.shared.rpm8": "UNLOCALIZED: 8 RPM", + "create.ponder.shared.ctrl_and": "UNLOCALIZED: Ctrl +", + "create.ponder.shared.rpm16_source": "UNLOCALIZED: Source: 16 RPM", + "create.ponder.shared.rpm16": "UNLOCALIZED: 16 RPM", + "create.ponder.tag.kinetic_sources": "UNLOCALIZED: Kinetic Sources", + "create.ponder.tag.kinetic_sources.description": "UNLOCALIZED: Components which generate Rotational Force", + "create.ponder.tag.contraption_actor": "UNLOCALIZED: Contraption Actors", + "create.ponder.tag.contraption_actor.description": "UNLOCALIZED: Components which expose special behaviour when attached to a moving contraption", + "create.ponder.tag.arm_targets": "UNLOCALIZED: Targets for Mechanical Arms", + "create.ponder.tag.arm_targets.description": "UNLOCALIZED: Components which can be selected as inputs or outputs to the Mechanical Arm", + "create.ponder.tag.logistics": "UNLOCALIZED: Item Transportation", + "create.ponder.tag.logistics.description": "UNLOCALIZED: Components which help moving items around", + "create.ponder.tag.movement_anchor": "UNLOCALIZED: Movement Anchors", + "create.ponder.tag.movement_anchor.description": "UNLOCALIZED: Components which allow the creation of moving contraptions, animating an attached structure in a variety of ways", + "create.ponder.tag.decoration": "UNLOCALIZED: Aesthetics", + "create.ponder.tag.decoration.description": "UNLOCALIZED: Components used mostly for decorative purposes", + "create.ponder.tag.kinetic_appliances": "UNLOCALIZED: Kinetic Appliances", + "create.ponder.tag.kinetic_appliances.description": "UNLOCALIZED: Components which make use of Rotational Force", + "create.ponder.tag.redstone": "UNLOCALIZED: Logic Components", + "create.ponder.tag.redstone.description": "UNLOCALIZED: Components which help with redstone engineering", + "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", + "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", + "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", + "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", + "create.ponder.tag.fluids": "UNLOCALIZED: Fluid Manipulators", + "create.ponder.tag.fluids.description": "UNLOCALIZED: Components which help relaying and making use of Fluids", + + "create.ponder.belt_casing.header": "UNLOCALIZED: Encasing Belts", + "create.ponder.belt_casing.text_1": "UNLOCALIZED: Brass or Andesite Casing can be used to decorate Mechanical Belts", + "create.ponder.belt_casing.text_2": "UNLOCALIZED: A wrench can be used to remove the casing", + + "create.ponder.belt_connector.header": "UNLOCALIZED: Using Mechanical Belts", + "create.ponder.belt_connector.text_1": "UNLOCALIZED: Right-Clicking two shafts with a belt item will connect them together", + "create.ponder.belt_connector.text_2": "UNLOCALIZED: Accidental selections can be canceled with Right-Click while Sneaking", + "create.ponder.belt_connector.text_3": "UNLOCALIZED: Additional Shafts can be added throughout the Belt", + "create.ponder.belt_connector.text_4": "UNLOCALIZED: Shafts connected via Belts will rotate with Identical Speed and Direction", + "create.ponder.belt_connector.text_5": "UNLOCALIZED: Added shafts can be removed using the wrench", + "create.ponder.belt_connector.text_6": "UNLOCALIZED: Mechanical Belts can be dyed for aesthetic purposes", + + "create.ponder.belt_directions.header": "UNLOCALIZED: Valid Orientations for Mechanical Belts", + "create.ponder.belt_directions.text_1": "UNLOCALIZED: Belts cannot connect in arbitrary directions", + "create.ponder.belt_directions.text_2": "UNLOCALIZED: 1. They can connect horizontally", + "create.ponder.belt_directions.text_3": "UNLOCALIZED: 2. They can connect diagonally", + "create.ponder.belt_directions.text_4": "UNLOCALIZED: 3. They can connect vertically", + "create.ponder.belt_directions.text_5": "UNLOCALIZED: 4. And they can connect vertical shafts horizontally", + "create.ponder.belt_directions.text_6": "UNLOCALIZED: These are all possible directions.\nBelts can span any Length between 2 and 20 blocks", + + "create.ponder.belt_transport.header": "UNLOCALIZED: Using Mechanical Belts for Logistics", + "create.ponder.belt_transport.text_1": "UNLOCALIZED: Moving belts will transport Items and other Entities", + "create.ponder.belt_transport.text_2": "UNLOCALIZED: Right-Click with an empty hand to take items off a belt", + + "create.ponder.brass_funnel.header": "UNLOCALIZED: The Brass Funnel", + "create.ponder.brass_funnel.text_1": "UNLOCALIZED: Andesite Funnels can only ever extract single items.", + "create.ponder.brass_funnel.text_2": "UNLOCALIZED: Brass Funnels can extract up to a full stack.", + "create.ponder.brass_funnel.text_3": "UNLOCALIZED: Scrolling on the filter slot allows for precise control over the extracted stack size.", + "create.ponder.brass_funnel.text_4": "UNLOCALIZED: Using items on the filter slot will restrict the funnel to only transfer matching stacks.", + + "create.ponder.chain_drive.header": "UNLOCALIZED: Relaying rotational force with Chain Drives", + "create.ponder.chain_drive.text_1": "UNLOCALIZED: Chain Drives relay rotation to each other in a row", + "create.ponder.chain_drive.text_2": "UNLOCALIZED: All shafts connected like this will rotate in the same direction", + "create.ponder.chain_drive.text_3": "UNLOCALIZED: Any part of the row can be rotated by 90 degrees", + + "create.ponder.chain_gearshift.header": "UNLOCALIZED: Controlling rotational speed with Chain Gearshifts", + "create.ponder.chain_gearshift.text_1": "UNLOCALIZED: Unpowered Chain Gearshifts behave exacly like Chain Drives", + "create.ponder.chain_gearshift.text_2": "UNLOCALIZED: When Powered, the speed transmitted to other Chain Drives in the row is doubled", + "create.ponder.chain_gearshift.text_3": "UNLOCALIZED: Whenever the Powered Gearshift is not at the source, its speed will be halved instead", + "create.ponder.chain_gearshift.text_4": "UNLOCALIZED: In both cases, Chain Drives in the row always run at 2x the speed of the Powered Gearshift", + "create.ponder.chain_gearshift.text_5": "UNLOCALIZED: Using analog signals, the ratio can be adjusted more precisely between 1 and 2", + "create.ponder.chain_gearshift.text_6": "UNLOCALIZED: 12 RPM", + + "create.ponder.clutch.header": "UNLOCALIZED: Controlling rotational force using a Clutch", + "create.ponder.clutch.text_1": "UNLOCALIZED: Clutches will relay rotation in a straight line", + "create.ponder.clutch.text_2": "UNLOCALIZED: When powered by Redstone, it breaks the connection", + + "create.ponder.cog_speedup.header": "UNLOCALIZED: Gearshifting with Cogs", + "create.ponder.cog_speedup.text_1": "UNLOCALIZED: Large and Small cogs can be connected diagonally", + "create.ponder.cog_speedup.text_2": "UNLOCALIZED: Shifting from large to small cogs, the conveyed speed will be doubled", + "create.ponder.cog_speedup.text_3": "UNLOCALIZED: Shifting the opposite way, the conveyed speed will be halved", + + "create.ponder.cogwheel.header": "UNLOCALIZED: Relaying rotational force using Cogwheels", + "create.ponder.cogwheel.text_1": "UNLOCALIZED: Cogwheels will relay rotation to other adjacent cogwheels", + "create.ponder.cogwheel.text_2": "UNLOCALIZED: Neighbouring shafts connected like this will rotate in opposite directions", + + "create.ponder.creative_motor.header": "UNLOCALIZED: Generating Rotational Force using Creative Motors", + "create.ponder.creative_motor.text_1": "UNLOCALIZED: Creative motors are a compact and configurable source of Rotational Force", + "create.ponder.creative_motor.text_2": "UNLOCALIZED: Scrolling on the back panel changes the RPM of the motors' rotational output", + + "create.ponder.fan_direction.header": "UNLOCALIZED: Air flow of Encased Fans", + "create.ponder.fan_direction.text_1": "UNLOCALIZED: Encased Fans use Rotational Force to create an Air Current", + "create.ponder.fan_direction.text_2": "UNLOCALIZED: Strength and Direction of Flow depends on the Rotational Input", + + "create.ponder.fan_processing.header": "UNLOCALIZED: Processing Items using Encased Fans", + "create.ponder.fan_processing.text_1": "UNLOCALIZED: When passing through lava, the Air Flow becomes Heated", + "create.ponder.fan_processing.text_2": "UNLOCALIZED: Items caught in the area will be smelted", + "create.ponder.fan_processing.text_3": "UNLOCALIZED: Food items thrown here would be incinerated", + "create.ponder.fan_processing.text_4": "UNLOCALIZED: Instead, a setup for Smoking using Fire should be used for them", + "create.ponder.fan_processing.text_5": "UNLOCALIZED: Air Flows passing through water create a Washing Setup", + "create.ponder.fan_processing.text_6": "UNLOCALIZED: Some interesting new processing can be done with it", + "create.ponder.fan_processing.text_7": "UNLOCALIZED: The Speed of the Fan does NOT affect the processing speed, only its range", + "create.ponder.fan_processing.text_8": "UNLOCALIZED: Fan Processing can also be applied to Items on Depots and Belts", + + "create.ponder.fan_source.header": "UNLOCALIZED: Generating Rotational Force using Encased Fans", + "create.ponder.fan_source.text_1": "UNLOCALIZED: Fans facing down into a source of heat can provide Rotational Force", + "create.ponder.fan_source.text_2": "UNLOCALIZED: When given a Redstone Signal, the Fans will start providing power", + + "create.ponder.funnel_compat.header": "UNLOCALIZED: Funnel compatibility", + "create.ponder.funnel_compat.text_1": "UNLOCALIZED: Funnels should also interact nicely with a handful of other components.", + "create.ponder.funnel_compat.text_2": "UNLOCALIZED: Vertical Saws", + "create.ponder.funnel_compat.text_3": "UNLOCALIZED: Depots", + "create.ponder.funnel_compat.text_4": "UNLOCALIZED: Item Drains", + + "create.ponder.funnel_direction.header": "UNLOCALIZED: Direction of Transfer", + "create.ponder.funnel_direction.text_1": "UNLOCALIZED: Placed normally, it pulls items from the inventory.", + "create.ponder.funnel_direction.text_2": "UNLOCALIZED: Placed while sneaking, it puts items into the inventory.", + "create.ponder.funnel_direction.text_3": "UNLOCALIZED: Using a wrench, the funnel can be flipped after placement.", + "create.ponder.funnel_direction.text_4": "UNLOCALIZED: Same rules will apply for most orientations.", + "create.ponder.funnel_direction.text_5": "UNLOCALIZED: Funnels on belts will extract/insert depending on its movement direction.", + + "create.ponder.funnel_intro.header": "UNLOCALIZED: Using funnels", + "create.ponder.funnel_intro.text_1": "UNLOCALIZED: Funnels are ideal for transferring items from and to inventories.", + + "create.ponder.funnel_redstone.header": "UNLOCALIZED: Redstone control", + "create.ponder.funnel_redstone.text_1": "UNLOCALIZED: Redstone power will prevent any funnel from acting.", + + "create.ponder.funnel_transfer.header": "UNLOCALIZED: Direct transfer", + "create.ponder.funnel_transfer.text_1": "UNLOCALIZED: Funnels cannot ever transfer between closed inventories directly.", + "create.ponder.funnel_transfer.text_2": "UNLOCALIZED: Chutes or Smart chutes might be more suitable for such purposes.", + "create.ponder.funnel_transfer.text_3": "UNLOCALIZED: Same applies for horizontal movement.\nA mechanical belt should help here.", + + "create.ponder.gantry_carriage.header": "UNLOCALIZED: Using Gantry Carriages", + "create.ponder.gantry_carriage.text_1": "UNLOCALIZED: Gantry Carriages can mount to and slide along a Gantry Shaft.", + "create.ponder.gantry_carriage.text_2": "UNLOCALIZED: Gantry setups can move attached Blocks.", + + "create.ponder.gantry_cascaded.header": "UNLOCALIZED: Cascaded Gantries", + "create.ponder.gantry_cascaded.text_1": "UNLOCALIZED: Gantry shafts attach to a carriage without the need of super glue", + "create.ponder.gantry_cascaded.text_2": "UNLOCALIZED: Same applies for carriages on moved Gantry Shafts", + "create.ponder.gantry_cascaded.text_3": "UNLOCALIZED: Thus, a gantry system can be cascaded to cover multiple axes of movement", + + "create.ponder.gantry_direction.header": "UNLOCALIZED: Gantry Movement Direction", + "create.ponder.gantry_direction.text_1": "UNLOCALIZED: Gantry Shafts can have opposite orientations", + "create.ponder.gantry_direction.text_2": "UNLOCALIZED: The movement direction of carriages depend on their shafts' orientation", + "create.ponder.gantry_direction.text_3": "UNLOCALIZED: ...as well as the rotation direction of the shaft", + "create.ponder.gantry_direction.text_4": "UNLOCALIZED: Same rules apply for the propagated rotation", + + "create.ponder.gantry_redstone.header": "UNLOCALIZED: Gantry Power Propagation", + "create.ponder.gantry_redstone.text_1": "UNLOCALIZED: Redstone-powered gantry shafts stop moving their carriages", + "create.ponder.gantry_redstone.text_2": "UNLOCALIZED: Instead, its rotational force is relayed to the carriages' output shaft", + + "create.ponder.gantry_shaft.header": "UNLOCALIZED: Using Gantry Shafts", + "create.ponder.gantry_shaft.text_1": "UNLOCALIZED: Gantry Shafts form the basis of a gantry setup. Attached Carriages will move along them.", + "create.ponder.gantry_shaft.text_2": "UNLOCALIZED: Gantry setups can move attached Blocks.", + + "create.ponder.gearbox.header": "UNLOCALIZED: Relaying rotational force using Gearboxes", + "create.ponder.gearbox.text_1": "UNLOCALIZED: Jumping between axes of rotation can get bulky quickly", + "create.ponder.gearbox.text_2": "UNLOCALIZED: A gearbox is the more compact equivalent of this setup", + "create.ponder.gearbox.text_3": "UNLOCALIZED: Shafts around corners rotate in mirrored directions", + "create.ponder.gearbox.text_4": "UNLOCALIZED: Straight connections will be reversed", + + "create.ponder.gearshift.header": "UNLOCALIZED: Controlling rotational force using a Gearshift", + "create.ponder.gearshift.text_1": "UNLOCALIZED: Gearshifts will relay rotation in a straight line", + "create.ponder.gearshift.text_2": "UNLOCALIZED: When powered by Redstone, it reverses the transmission", + + "create.ponder.hand_crank.header": "UNLOCALIZED: Generating Rotational Force using Hand Cranks", + "create.ponder.hand_crank.text_1": "UNLOCALIZED: Hand Cranks can be used by players to apply rotational force manually", + "create.ponder.hand_crank.text_2": "UNLOCALIZED: Hold Right-Click to rotate it Counter-Clockwise", + "create.ponder.hand_crank.text_3": "UNLOCALIZED: Its conveyed speed is relatively high", + "create.ponder.hand_crank.text_4": "UNLOCALIZED: Sneak and Hold Right-Click to rotate it Clockwise", + + "create.ponder.large_cogwheel.header": "UNLOCALIZED: Relaying rotational force using Large Cogwheels", + "create.ponder.large_cogwheel.text_1": "UNLOCALIZED: Large cogwheels can connect to each other at right angles", + "create.ponder.large_cogwheel.text_2": "UNLOCALIZED: It will help relaying conveyed speed to other axes of rotation", + + "create.ponder.portable_storage_interface.header": "UNLOCALIZED: Contraption Storage Exchange", + "create.ponder.portable_storage_interface.text_1": "UNLOCALIZED: Inventories on moving contraptions cannot be accessed by players.", + "create.ponder.portable_storage_interface.text_2": "UNLOCALIZED: This component can interact with storage without the need to stop the contraption.", + "create.ponder.portable_storage_interface.text_3": "UNLOCALIZED: Place a second one with a gap of 1 or 2 blocks inbetween", + "create.ponder.portable_storage_interface.text_4": "UNLOCALIZED: Whenever they pass by each other, they will engage in a connection", + "create.ponder.portable_storage_interface.text_5": "UNLOCALIZED: While engaged, the stationary interface will represent ALL inventories on the contraption", + "create.ponder.portable_storage_interface.text_6": "UNLOCALIZED: Items can now be inserted...", + "create.ponder.portable_storage_interface.text_7": "UNLOCALIZED: ...or extracted from the contraption", + "create.ponder.portable_storage_interface.text_8": "UNLOCALIZED: After no items have been exchanged for a while, the contraption will continue on its way", + + "create.ponder.portable_storage_interface_redstone.header": "UNLOCALIZED: Redstone Control", + "create.ponder.portable_storage_interface_redstone.text_1": "UNLOCALIZED: Redstone power will prevent the stationary interface from engaging", + + "create.ponder.shaft.header": "UNLOCALIZED: Relaying rotational force using Shafts", + "create.ponder.shaft.text_1": "UNLOCALIZED: Shafts will relay rotation in a straight line.", + + "create.ponder.shaft_casing.header": "UNLOCALIZED: Encasing Shafts", + "create.ponder.shaft_casing.text_1": "UNLOCALIZED: Brass or Andesite Casing can be used to decorate Shafts", + + "create.ponder.valve_handle.header": "UNLOCALIZED: Generating Rotational Force using Valve Handles", + "create.ponder.valve_handle.text_1": "UNLOCALIZED: Valve Handles can be used by players to apply rotational force manually", + "create.ponder.valve_handle.text_2": "UNLOCALIZED: Hold Right-Click to rotate it Counter-Clockwise", + "create.ponder.valve_handle.text_3": "UNLOCALIZED: Its conveyed speed is slow and precise", + "create.ponder.valve_handle.text_4": "UNLOCALIZED: Sneak and Hold Right-Click to rotate it Clockwise", + "create.ponder.valve_handle.text_5": "UNLOCALIZED: Valve handles can be dyed for aesthetic purposes", + + "create.ponder.water_wheel.header": "UNLOCALIZED: Generating Rotational Force using Water Wheels", + "create.ponder.water_wheel.text_1": "UNLOCALIZED: Water Wheels draw force from adjacent Water Currents", + "create.ponder.water_wheel.text_2": "UNLOCALIZED: The more faces are powered, the faster the Water Wheel will rotate", + "create.ponder.water_wheel.text_3": "UNLOCALIZED: The Wheels' blades should be oriented against the flow", + "create.ponder.water_wheel.text_4": "UNLOCALIZED: Facing the opposite way, they will not be as effective", + "_": "Thank you for translating Create!" } \ No newline at end of file diff --git a/src/generated/resources/assets/create/lang/unfinished/fr_fr.json b/src/generated/resources/assets/create/lang/unfinished/fr_fr.json index d51c8cd12..eae6e162c 100644 --- a/src/generated/resources/assets/create/lang/unfinished/fr_fr.json +++ b/src/generated/resources/assets/create/lang/unfinished/fr_fr.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 690", + "_": "Missing Localizations: 867", "_": "->------------------------] Game Elements [------------------------<-", @@ -162,7 +162,7 @@ "block.create.gabbro_cobblestone_stairs": "UNLOCALIZED: Gabbro Cobblestone Stairs", "block.create.gabbro_cobblestone_wall": "UNLOCALIZED: Gabbro Cobblestone Wall", "block.create.gabbro_pillar": "UNLOCALIZED: Gabbro Pillar", - "block.create.gantry_pinion": "UNLOCALIZED: Gantry Pinion", + "block.create.gantry_carriage": "UNLOCALIZED: Gantry Carriage", "block.create.gantry_shaft": "UNLOCALIZED: Gantry Shaft", "block.create.gearbox": "Boîte à roue dentée", "block.create.gearshift": "Décaleur de rotation", @@ -1809,6 +1809,221 @@ "create.tooltip.randomWipDescription7": "Celui-ci n'est peut-être pas pour vous. Que dire de celui-là?", "create.tooltip.randomWipDescription8": "Utilisez-le et regrettez immédiatement votre décision.", + + "_": "->------------------------] Ponder Content [------------------------<-", + + "create.ponder.hold_to_ponder": "UNLOCALIZED: Hold [%1$s] to Ponder", + "create.ponder.subject": "UNLOCALIZED: Subject of this scene", + "create.ponder.pondering": "UNLOCALIZED: Pondering about...", + "create.ponder.identify_mode": "UNLOCALIZED: Identify mode active.\nUnpause with [%1$s]", + "create.ponder.associated": "UNLOCALIZED: Associated Entries", + "create.ponder.shared.movement_anchors": "UNLOCALIZED: With the help of Chassis or Super Glue, larger structures can be moved.", + "create.ponder.shared.rpm32": "UNLOCALIZED: 32 RPM", + "create.ponder.shared.sneak_and": "UNLOCALIZED: Sneak +", + "create.ponder.shared.rpm8": "UNLOCALIZED: 8 RPM", + "create.ponder.shared.ctrl_and": "UNLOCALIZED: Ctrl +", + "create.ponder.shared.rpm16_source": "UNLOCALIZED: Source: 16 RPM", + "create.ponder.shared.rpm16": "UNLOCALIZED: 16 RPM", + "create.ponder.tag.kinetic_sources": "UNLOCALIZED: Kinetic Sources", + "create.ponder.tag.kinetic_sources.description": "UNLOCALIZED: Components which generate Rotational Force", + "create.ponder.tag.contraption_actor": "UNLOCALIZED: Contraption Actors", + "create.ponder.tag.contraption_actor.description": "UNLOCALIZED: Components which expose special behaviour when attached to a moving contraption", + "create.ponder.tag.arm_targets": "UNLOCALIZED: Targets for Mechanical Arms", + "create.ponder.tag.arm_targets.description": "UNLOCALIZED: Components which can be selected as inputs or outputs to the Mechanical Arm", + "create.ponder.tag.logistics": "UNLOCALIZED: Item Transportation", + "create.ponder.tag.logistics.description": "UNLOCALIZED: Components which help moving items around", + "create.ponder.tag.movement_anchor": "UNLOCALIZED: Movement Anchors", + "create.ponder.tag.movement_anchor.description": "UNLOCALIZED: Components which allow the creation of moving contraptions, animating an attached structure in a variety of ways", + "create.ponder.tag.decoration": "UNLOCALIZED: Aesthetics", + "create.ponder.tag.decoration.description": "UNLOCALIZED: Components used mostly for decorative purposes", + "create.ponder.tag.kinetic_appliances": "UNLOCALIZED: Kinetic Appliances", + "create.ponder.tag.kinetic_appliances.description": "UNLOCALIZED: Components which make use of Rotational Force", + "create.ponder.tag.redstone": "UNLOCALIZED: Logic Components", + "create.ponder.tag.redstone.description": "UNLOCALIZED: Components which help with redstone engineering", + "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", + "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", + "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", + "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", + "create.ponder.tag.fluids": "UNLOCALIZED: Fluid Manipulators", + "create.ponder.tag.fluids.description": "UNLOCALIZED: Components which help relaying and making use of Fluids", + + "create.ponder.belt_casing.header": "UNLOCALIZED: Encasing Belts", + "create.ponder.belt_casing.text_1": "UNLOCALIZED: Brass or Andesite Casing can be used to decorate Mechanical Belts", + "create.ponder.belt_casing.text_2": "UNLOCALIZED: A wrench can be used to remove the casing", + + "create.ponder.belt_connector.header": "UNLOCALIZED: Using Mechanical Belts", + "create.ponder.belt_connector.text_1": "UNLOCALIZED: Right-Clicking two shafts with a belt item will connect them together", + "create.ponder.belt_connector.text_2": "UNLOCALIZED: Accidental selections can be canceled with Right-Click while Sneaking", + "create.ponder.belt_connector.text_3": "UNLOCALIZED: Additional Shafts can be added throughout the Belt", + "create.ponder.belt_connector.text_4": "UNLOCALIZED: Shafts connected via Belts will rotate with Identical Speed and Direction", + "create.ponder.belt_connector.text_5": "UNLOCALIZED: Added shafts can be removed using the wrench", + "create.ponder.belt_connector.text_6": "UNLOCALIZED: Mechanical Belts can be dyed for aesthetic purposes", + + "create.ponder.belt_directions.header": "UNLOCALIZED: Valid Orientations for Mechanical Belts", + "create.ponder.belt_directions.text_1": "UNLOCALIZED: Belts cannot connect in arbitrary directions", + "create.ponder.belt_directions.text_2": "UNLOCALIZED: 1. They can connect horizontally", + "create.ponder.belt_directions.text_3": "UNLOCALIZED: 2. They can connect diagonally", + "create.ponder.belt_directions.text_4": "UNLOCALIZED: 3. They can connect vertically", + "create.ponder.belt_directions.text_5": "UNLOCALIZED: 4. And they can connect vertical shafts horizontally", + "create.ponder.belt_directions.text_6": "UNLOCALIZED: These are all possible directions.\nBelts can span any Length between 2 and 20 blocks", + + "create.ponder.belt_transport.header": "UNLOCALIZED: Using Mechanical Belts for Logistics", + "create.ponder.belt_transport.text_1": "UNLOCALIZED: Moving belts will transport Items and other Entities", + "create.ponder.belt_transport.text_2": "UNLOCALIZED: Right-Click with an empty hand to take items off a belt", + + "create.ponder.brass_funnel.header": "UNLOCALIZED: The Brass Funnel", + "create.ponder.brass_funnel.text_1": "UNLOCALIZED: Andesite Funnels can only ever extract single items.", + "create.ponder.brass_funnel.text_2": "UNLOCALIZED: Brass Funnels can extract up to a full stack.", + "create.ponder.brass_funnel.text_3": "UNLOCALIZED: Scrolling on the filter slot allows for precise control over the extracted stack size.", + "create.ponder.brass_funnel.text_4": "UNLOCALIZED: Using items on the filter slot will restrict the funnel to only transfer matching stacks.", + + "create.ponder.chain_drive.header": "UNLOCALIZED: Relaying rotational force with Chain Drives", + "create.ponder.chain_drive.text_1": "UNLOCALIZED: Chain Drives relay rotation to each other in a row", + "create.ponder.chain_drive.text_2": "UNLOCALIZED: All shafts connected like this will rotate in the same direction", + "create.ponder.chain_drive.text_3": "UNLOCALIZED: Any part of the row can be rotated by 90 degrees", + + "create.ponder.chain_gearshift.header": "UNLOCALIZED: Controlling rotational speed with Chain Gearshifts", + "create.ponder.chain_gearshift.text_1": "UNLOCALIZED: Unpowered Chain Gearshifts behave exacly like Chain Drives", + "create.ponder.chain_gearshift.text_2": "UNLOCALIZED: When Powered, the speed transmitted to other Chain Drives in the row is doubled", + "create.ponder.chain_gearshift.text_3": "UNLOCALIZED: Whenever the Powered Gearshift is not at the source, its speed will be halved instead", + "create.ponder.chain_gearshift.text_4": "UNLOCALIZED: In both cases, Chain Drives in the row always run at 2x the speed of the Powered Gearshift", + "create.ponder.chain_gearshift.text_5": "UNLOCALIZED: Using analog signals, the ratio can be adjusted more precisely between 1 and 2", + "create.ponder.chain_gearshift.text_6": "UNLOCALIZED: 12 RPM", + + "create.ponder.clutch.header": "UNLOCALIZED: Controlling rotational force using a Clutch", + "create.ponder.clutch.text_1": "UNLOCALIZED: Clutches will relay rotation in a straight line", + "create.ponder.clutch.text_2": "UNLOCALIZED: When powered by Redstone, it breaks the connection", + + "create.ponder.cog_speedup.header": "UNLOCALIZED: Gearshifting with Cogs", + "create.ponder.cog_speedup.text_1": "UNLOCALIZED: Large and Small cogs can be connected diagonally", + "create.ponder.cog_speedup.text_2": "UNLOCALIZED: Shifting from large to small cogs, the conveyed speed will be doubled", + "create.ponder.cog_speedup.text_3": "UNLOCALIZED: Shifting the opposite way, the conveyed speed will be halved", + + "create.ponder.cogwheel.header": "UNLOCALIZED: Relaying rotational force using Cogwheels", + "create.ponder.cogwheel.text_1": "UNLOCALIZED: Cogwheels will relay rotation to other adjacent cogwheels", + "create.ponder.cogwheel.text_2": "UNLOCALIZED: Neighbouring shafts connected like this will rotate in opposite directions", + + "create.ponder.creative_motor.header": "UNLOCALIZED: Generating Rotational Force using Creative Motors", + "create.ponder.creative_motor.text_1": "UNLOCALIZED: Creative motors are a compact and configurable source of Rotational Force", + "create.ponder.creative_motor.text_2": "UNLOCALIZED: Scrolling on the back panel changes the RPM of the motors' rotational output", + + "create.ponder.fan_direction.header": "UNLOCALIZED: Air flow of Encased Fans", + "create.ponder.fan_direction.text_1": "UNLOCALIZED: Encased Fans use Rotational Force to create an Air Current", + "create.ponder.fan_direction.text_2": "UNLOCALIZED: Strength and Direction of Flow depends on the Rotational Input", + + "create.ponder.fan_processing.header": "UNLOCALIZED: Processing Items using Encased Fans", + "create.ponder.fan_processing.text_1": "UNLOCALIZED: When passing through lava, the Air Flow becomes Heated", + "create.ponder.fan_processing.text_2": "UNLOCALIZED: Items caught in the area will be smelted", + "create.ponder.fan_processing.text_3": "UNLOCALIZED: Food items thrown here would be incinerated", + "create.ponder.fan_processing.text_4": "UNLOCALIZED: Instead, a setup for Smoking using Fire should be used for them", + "create.ponder.fan_processing.text_5": "UNLOCALIZED: Air Flows passing through water create a Washing Setup", + "create.ponder.fan_processing.text_6": "UNLOCALIZED: Some interesting new processing can be done with it", + "create.ponder.fan_processing.text_7": "UNLOCALIZED: The Speed of the Fan does NOT affect the processing speed, only its range", + "create.ponder.fan_processing.text_8": "UNLOCALIZED: Fan Processing can also be applied to Items on Depots and Belts", + + "create.ponder.fan_source.header": "UNLOCALIZED: Generating Rotational Force using Encased Fans", + "create.ponder.fan_source.text_1": "UNLOCALIZED: Fans facing down into a source of heat can provide Rotational Force", + "create.ponder.fan_source.text_2": "UNLOCALIZED: When given a Redstone Signal, the Fans will start providing power", + + "create.ponder.funnel_compat.header": "UNLOCALIZED: Funnel compatibility", + "create.ponder.funnel_compat.text_1": "UNLOCALIZED: Funnels should also interact nicely with a handful of other components.", + "create.ponder.funnel_compat.text_2": "UNLOCALIZED: Vertical Saws", + "create.ponder.funnel_compat.text_3": "UNLOCALIZED: Depots", + "create.ponder.funnel_compat.text_4": "UNLOCALIZED: Item Drains", + + "create.ponder.funnel_direction.header": "UNLOCALIZED: Direction of Transfer", + "create.ponder.funnel_direction.text_1": "UNLOCALIZED: Placed normally, it pulls items from the inventory.", + "create.ponder.funnel_direction.text_2": "UNLOCALIZED: Placed while sneaking, it puts items into the inventory.", + "create.ponder.funnel_direction.text_3": "UNLOCALIZED: Using a wrench, the funnel can be flipped after placement.", + "create.ponder.funnel_direction.text_4": "UNLOCALIZED: Same rules will apply for most orientations.", + "create.ponder.funnel_direction.text_5": "UNLOCALIZED: Funnels on belts will extract/insert depending on its movement direction.", + + "create.ponder.funnel_intro.header": "UNLOCALIZED: Using funnels", + "create.ponder.funnel_intro.text_1": "UNLOCALIZED: Funnels are ideal for transferring items from and to inventories.", + + "create.ponder.funnel_redstone.header": "UNLOCALIZED: Redstone control", + "create.ponder.funnel_redstone.text_1": "UNLOCALIZED: Redstone power will prevent any funnel from acting.", + + "create.ponder.funnel_transfer.header": "UNLOCALIZED: Direct transfer", + "create.ponder.funnel_transfer.text_1": "UNLOCALIZED: Funnels cannot ever transfer between closed inventories directly.", + "create.ponder.funnel_transfer.text_2": "UNLOCALIZED: Chutes or Smart chutes might be more suitable for such purposes.", + "create.ponder.funnel_transfer.text_3": "UNLOCALIZED: Same applies for horizontal movement.\nA mechanical belt should help here.", + + "create.ponder.gantry_carriage.header": "UNLOCALIZED: Using Gantry Carriages", + "create.ponder.gantry_carriage.text_1": "UNLOCALIZED: Gantry Carriages can mount to and slide along a Gantry Shaft.", + "create.ponder.gantry_carriage.text_2": "UNLOCALIZED: Gantry setups can move attached Blocks.", + + "create.ponder.gantry_cascaded.header": "UNLOCALIZED: Cascaded Gantries", + "create.ponder.gantry_cascaded.text_1": "UNLOCALIZED: Gantry shafts attach to a carriage without the need of super glue", + "create.ponder.gantry_cascaded.text_2": "UNLOCALIZED: Same applies for carriages on moved Gantry Shafts", + "create.ponder.gantry_cascaded.text_3": "UNLOCALIZED: Thus, a gantry system can be cascaded to cover multiple axes of movement", + + "create.ponder.gantry_direction.header": "UNLOCALIZED: Gantry Movement Direction", + "create.ponder.gantry_direction.text_1": "UNLOCALIZED: Gantry Shafts can have opposite orientations", + "create.ponder.gantry_direction.text_2": "UNLOCALIZED: The movement direction of carriages depend on their shafts' orientation", + "create.ponder.gantry_direction.text_3": "UNLOCALIZED: ...as well as the rotation direction of the shaft", + "create.ponder.gantry_direction.text_4": "UNLOCALIZED: Same rules apply for the propagated rotation", + + "create.ponder.gantry_redstone.header": "UNLOCALIZED: Gantry Power Propagation", + "create.ponder.gantry_redstone.text_1": "UNLOCALIZED: Redstone-powered gantry shafts stop moving their carriages", + "create.ponder.gantry_redstone.text_2": "UNLOCALIZED: Instead, its rotational force is relayed to the carriages' output shaft", + + "create.ponder.gantry_shaft.header": "UNLOCALIZED: Using Gantry Shafts", + "create.ponder.gantry_shaft.text_1": "UNLOCALIZED: Gantry Shafts form the basis of a gantry setup. Attached Carriages will move along them.", + "create.ponder.gantry_shaft.text_2": "UNLOCALIZED: Gantry setups can move attached Blocks.", + + "create.ponder.gearbox.header": "UNLOCALIZED: Relaying rotational force using Gearboxes", + "create.ponder.gearbox.text_1": "UNLOCALIZED: Jumping between axes of rotation can get bulky quickly", + "create.ponder.gearbox.text_2": "UNLOCALIZED: A gearbox is the more compact equivalent of this setup", + "create.ponder.gearbox.text_3": "UNLOCALIZED: Shafts around corners rotate in mirrored directions", + "create.ponder.gearbox.text_4": "UNLOCALIZED: Straight connections will be reversed", + + "create.ponder.gearshift.header": "UNLOCALIZED: Controlling rotational force using a Gearshift", + "create.ponder.gearshift.text_1": "UNLOCALIZED: Gearshifts will relay rotation in a straight line", + "create.ponder.gearshift.text_2": "UNLOCALIZED: When powered by Redstone, it reverses the transmission", + + "create.ponder.hand_crank.header": "UNLOCALIZED: Generating Rotational Force using Hand Cranks", + "create.ponder.hand_crank.text_1": "UNLOCALIZED: Hand Cranks can be used by players to apply rotational force manually", + "create.ponder.hand_crank.text_2": "UNLOCALIZED: Hold Right-Click to rotate it Counter-Clockwise", + "create.ponder.hand_crank.text_3": "UNLOCALIZED: Its conveyed speed is relatively high", + "create.ponder.hand_crank.text_4": "UNLOCALIZED: Sneak and Hold Right-Click to rotate it Clockwise", + + "create.ponder.large_cogwheel.header": "UNLOCALIZED: Relaying rotational force using Large Cogwheels", + "create.ponder.large_cogwheel.text_1": "UNLOCALIZED: Large cogwheels can connect to each other at right angles", + "create.ponder.large_cogwheel.text_2": "UNLOCALIZED: It will help relaying conveyed speed to other axes of rotation", + + "create.ponder.portable_storage_interface.header": "UNLOCALIZED: Contraption Storage Exchange", + "create.ponder.portable_storage_interface.text_1": "UNLOCALIZED: Inventories on moving contraptions cannot be accessed by players.", + "create.ponder.portable_storage_interface.text_2": "UNLOCALIZED: This component can interact with storage without the need to stop the contraption.", + "create.ponder.portable_storage_interface.text_3": "UNLOCALIZED: Place a second one with a gap of 1 or 2 blocks inbetween", + "create.ponder.portable_storage_interface.text_4": "UNLOCALIZED: Whenever they pass by each other, they will engage in a connection", + "create.ponder.portable_storage_interface.text_5": "UNLOCALIZED: While engaged, the stationary interface will represent ALL inventories on the contraption", + "create.ponder.portable_storage_interface.text_6": "UNLOCALIZED: Items can now be inserted...", + "create.ponder.portable_storage_interface.text_7": "UNLOCALIZED: ...or extracted from the contraption", + "create.ponder.portable_storage_interface.text_8": "UNLOCALIZED: After no items have been exchanged for a while, the contraption will continue on its way", + + "create.ponder.portable_storage_interface_redstone.header": "UNLOCALIZED: Redstone Control", + "create.ponder.portable_storage_interface_redstone.text_1": "UNLOCALIZED: Redstone power will prevent the stationary interface from engaging", + + "create.ponder.shaft.header": "UNLOCALIZED: Relaying rotational force using Shafts", + "create.ponder.shaft.text_1": "UNLOCALIZED: Shafts will relay rotation in a straight line.", + + "create.ponder.shaft_casing.header": "UNLOCALIZED: Encasing Shafts", + "create.ponder.shaft_casing.text_1": "UNLOCALIZED: Brass or Andesite Casing can be used to decorate Shafts", + + "create.ponder.valve_handle.header": "UNLOCALIZED: Generating Rotational Force using Valve Handles", + "create.ponder.valve_handle.text_1": "UNLOCALIZED: Valve Handles can be used by players to apply rotational force manually", + "create.ponder.valve_handle.text_2": "UNLOCALIZED: Hold Right-Click to rotate it Counter-Clockwise", + "create.ponder.valve_handle.text_3": "UNLOCALIZED: Its conveyed speed is slow and precise", + "create.ponder.valve_handle.text_4": "UNLOCALIZED: Sneak and Hold Right-Click to rotate it Clockwise", + "create.ponder.valve_handle.text_5": "UNLOCALIZED: Valve handles can be dyed for aesthetic purposes", + + "create.ponder.water_wheel.header": "UNLOCALIZED: Generating Rotational Force using Water Wheels", + "create.ponder.water_wheel.text_1": "UNLOCALIZED: Water Wheels draw force from adjacent Water Currents", + "create.ponder.water_wheel.text_2": "UNLOCALIZED: The more faces are powered, the faster the Water Wheel will rotate", + "create.ponder.water_wheel.text_3": "UNLOCALIZED: The Wheels' blades should be oriented against the flow", + "create.ponder.water_wheel.text_4": "UNLOCALIZED: Facing the opposite way, they will not be as effective", + "_": "Thank you for translating Create!" } \ No newline at end of file diff --git a/src/generated/resources/assets/create/lang/unfinished/it_it.json b/src/generated/resources/assets/create/lang/unfinished/it_it.json index e93e4ea9d..c2eefe3dc 100644 --- a/src/generated/resources/assets/create/lang/unfinished/it_it.json +++ b/src/generated/resources/assets/create/lang/unfinished/it_it.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 25", + "_": "Missing Localizations: 203", "_": "->------------------------] Game Elements [------------------------<-", @@ -162,7 +162,7 @@ "block.create.gabbro_cobblestone_stairs": "Scalini di pietrisco di gabbro", "block.create.gabbro_cobblestone_wall": "Muretto di pietrisco di gabbro", "block.create.gabbro_pillar": "Pilastro di gabbro", - "block.create.gantry_pinion": "Pignone a portale", + "block.create.gantry_carriage": "UNLOCALIZED: Gantry Carriage", "block.create.gantry_shaft": "Albero a portale", "block.create.gearbox": "Riduttore", "block.create.gearshift": "Cambio", @@ -1809,6 +1809,221 @@ "create.tooltip.randomWipDescription7": "Questo forse non fa per te. Che ne dici di quello?", "create.tooltip.randomWipDescription8": "Usalo e rimpiangi immediatamente la tua decisione.", + + "_": "->------------------------] Ponder Content [------------------------<-", + + "create.ponder.hold_to_ponder": "UNLOCALIZED: Hold [%1$s] to Ponder", + "create.ponder.subject": "UNLOCALIZED: Subject of this scene", + "create.ponder.pondering": "UNLOCALIZED: Pondering about...", + "create.ponder.identify_mode": "UNLOCALIZED: Identify mode active.\nUnpause with [%1$s]", + "create.ponder.associated": "UNLOCALIZED: Associated Entries", + "create.ponder.shared.movement_anchors": "UNLOCALIZED: With the help of Chassis or Super Glue, larger structures can be moved.", + "create.ponder.shared.rpm32": "UNLOCALIZED: 32 RPM", + "create.ponder.shared.sneak_and": "UNLOCALIZED: Sneak +", + "create.ponder.shared.rpm8": "UNLOCALIZED: 8 RPM", + "create.ponder.shared.ctrl_and": "UNLOCALIZED: Ctrl +", + "create.ponder.shared.rpm16_source": "UNLOCALIZED: Source: 16 RPM", + "create.ponder.shared.rpm16": "UNLOCALIZED: 16 RPM", + "create.ponder.tag.kinetic_sources": "UNLOCALIZED: Kinetic Sources", + "create.ponder.tag.kinetic_sources.description": "UNLOCALIZED: Components which generate Rotational Force", + "create.ponder.tag.contraption_actor": "UNLOCALIZED: Contraption Actors", + "create.ponder.tag.contraption_actor.description": "UNLOCALIZED: Components which expose special behaviour when attached to a moving contraption", + "create.ponder.tag.arm_targets": "UNLOCALIZED: Targets for Mechanical Arms", + "create.ponder.tag.arm_targets.description": "UNLOCALIZED: Components which can be selected as inputs or outputs to the Mechanical Arm", + "create.ponder.tag.logistics": "UNLOCALIZED: Item Transportation", + "create.ponder.tag.logistics.description": "UNLOCALIZED: Components which help moving items around", + "create.ponder.tag.movement_anchor": "UNLOCALIZED: Movement Anchors", + "create.ponder.tag.movement_anchor.description": "UNLOCALIZED: Components which allow the creation of moving contraptions, animating an attached structure in a variety of ways", + "create.ponder.tag.decoration": "UNLOCALIZED: Aesthetics", + "create.ponder.tag.decoration.description": "UNLOCALIZED: Components used mostly for decorative purposes", + "create.ponder.tag.kinetic_appliances": "UNLOCALIZED: Kinetic Appliances", + "create.ponder.tag.kinetic_appliances.description": "UNLOCALIZED: Components which make use of Rotational Force", + "create.ponder.tag.redstone": "UNLOCALIZED: Logic Components", + "create.ponder.tag.redstone.description": "UNLOCALIZED: Components which help with redstone engineering", + "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", + "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", + "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", + "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", + "create.ponder.tag.fluids": "UNLOCALIZED: Fluid Manipulators", + "create.ponder.tag.fluids.description": "UNLOCALIZED: Components which help relaying and making use of Fluids", + + "create.ponder.belt_casing.header": "UNLOCALIZED: Encasing Belts", + "create.ponder.belt_casing.text_1": "UNLOCALIZED: Brass or Andesite Casing can be used to decorate Mechanical Belts", + "create.ponder.belt_casing.text_2": "UNLOCALIZED: A wrench can be used to remove the casing", + + "create.ponder.belt_connector.header": "UNLOCALIZED: Using Mechanical Belts", + "create.ponder.belt_connector.text_1": "UNLOCALIZED: Right-Clicking two shafts with a belt item will connect them together", + "create.ponder.belt_connector.text_2": "UNLOCALIZED: Accidental selections can be canceled with Right-Click while Sneaking", + "create.ponder.belt_connector.text_3": "UNLOCALIZED: Additional Shafts can be added throughout the Belt", + "create.ponder.belt_connector.text_4": "UNLOCALIZED: Shafts connected via Belts will rotate with Identical Speed and Direction", + "create.ponder.belt_connector.text_5": "UNLOCALIZED: Added shafts can be removed using the wrench", + "create.ponder.belt_connector.text_6": "UNLOCALIZED: Mechanical Belts can be dyed for aesthetic purposes", + + "create.ponder.belt_directions.header": "UNLOCALIZED: Valid Orientations for Mechanical Belts", + "create.ponder.belt_directions.text_1": "UNLOCALIZED: Belts cannot connect in arbitrary directions", + "create.ponder.belt_directions.text_2": "UNLOCALIZED: 1. They can connect horizontally", + "create.ponder.belt_directions.text_3": "UNLOCALIZED: 2. They can connect diagonally", + "create.ponder.belt_directions.text_4": "UNLOCALIZED: 3. They can connect vertically", + "create.ponder.belt_directions.text_5": "UNLOCALIZED: 4. And they can connect vertical shafts horizontally", + "create.ponder.belt_directions.text_6": "UNLOCALIZED: These are all possible directions.\nBelts can span any Length between 2 and 20 blocks", + + "create.ponder.belt_transport.header": "UNLOCALIZED: Using Mechanical Belts for Logistics", + "create.ponder.belt_transport.text_1": "UNLOCALIZED: Moving belts will transport Items and other Entities", + "create.ponder.belt_transport.text_2": "UNLOCALIZED: Right-Click with an empty hand to take items off a belt", + + "create.ponder.brass_funnel.header": "UNLOCALIZED: The Brass Funnel", + "create.ponder.brass_funnel.text_1": "UNLOCALIZED: Andesite Funnels can only ever extract single items.", + "create.ponder.brass_funnel.text_2": "UNLOCALIZED: Brass Funnels can extract up to a full stack.", + "create.ponder.brass_funnel.text_3": "UNLOCALIZED: Scrolling on the filter slot allows for precise control over the extracted stack size.", + "create.ponder.brass_funnel.text_4": "UNLOCALIZED: Using items on the filter slot will restrict the funnel to only transfer matching stacks.", + + "create.ponder.chain_drive.header": "UNLOCALIZED: Relaying rotational force with Chain Drives", + "create.ponder.chain_drive.text_1": "UNLOCALIZED: Chain Drives relay rotation to each other in a row", + "create.ponder.chain_drive.text_2": "UNLOCALIZED: All shafts connected like this will rotate in the same direction", + "create.ponder.chain_drive.text_3": "UNLOCALIZED: Any part of the row can be rotated by 90 degrees", + + "create.ponder.chain_gearshift.header": "UNLOCALIZED: Controlling rotational speed with Chain Gearshifts", + "create.ponder.chain_gearshift.text_1": "UNLOCALIZED: Unpowered Chain Gearshifts behave exacly like Chain Drives", + "create.ponder.chain_gearshift.text_2": "UNLOCALIZED: When Powered, the speed transmitted to other Chain Drives in the row is doubled", + "create.ponder.chain_gearshift.text_3": "UNLOCALIZED: Whenever the Powered Gearshift is not at the source, its speed will be halved instead", + "create.ponder.chain_gearshift.text_4": "UNLOCALIZED: In both cases, Chain Drives in the row always run at 2x the speed of the Powered Gearshift", + "create.ponder.chain_gearshift.text_5": "UNLOCALIZED: Using analog signals, the ratio can be adjusted more precisely between 1 and 2", + "create.ponder.chain_gearshift.text_6": "UNLOCALIZED: 12 RPM", + + "create.ponder.clutch.header": "UNLOCALIZED: Controlling rotational force using a Clutch", + "create.ponder.clutch.text_1": "UNLOCALIZED: Clutches will relay rotation in a straight line", + "create.ponder.clutch.text_2": "UNLOCALIZED: When powered by Redstone, it breaks the connection", + + "create.ponder.cog_speedup.header": "UNLOCALIZED: Gearshifting with Cogs", + "create.ponder.cog_speedup.text_1": "UNLOCALIZED: Large and Small cogs can be connected diagonally", + "create.ponder.cog_speedup.text_2": "UNLOCALIZED: Shifting from large to small cogs, the conveyed speed will be doubled", + "create.ponder.cog_speedup.text_3": "UNLOCALIZED: Shifting the opposite way, the conveyed speed will be halved", + + "create.ponder.cogwheel.header": "UNLOCALIZED: Relaying rotational force using Cogwheels", + "create.ponder.cogwheel.text_1": "UNLOCALIZED: Cogwheels will relay rotation to other adjacent cogwheels", + "create.ponder.cogwheel.text_2": "UNLOCALIZED: Neighbouring shafts connected like this will rotate in opposite directions", + + "create.ponder.creative_motor.header": "UNLOCALIZED: Generating Rotational Force using Creative Motors", + "create.ponder.creative_motor.text_1": "UNLOCALIZED: Creative motors are a compact and configurable source of Rotational Force", + "create.ponder.creative_motor.text_2": "UNLOCALIZED: Scrolling on the back panel changes the RPM of the motors' rotational output", + + "create.ponder.fan_direction.header": "UNLOCALIZED: Air flow of Encased Fans", + "create.ponder.fan_direction.text_1": "UNLOCALIZED: Encased Fans use Rotational Force to create an Air Current", + "create.ponder.fan_direction.text_2": "UNLOCALIZED: Strength and Direction of Flow depends on the Rotational Input", + + "create.ponder.fan_processing.header": "UNLOCALIZED: Processing Items using Encased Fans", + "create.ponder.fan_processing.text_1": "UNLOCALIZED: When passing through lava, the Air Flow becomes Heated", + "create.ponder.fan_processing.text_2": "UNLOCALIZED: Items caught in the area will be smelted", + "create.ponder.fan_processing.text_3": "UNLOCALIZED: Food items thrown here would be incinerated", + "create.ponder.fan_processing.text_4": "UNLOCALIZED: Instead, a setup for Smoking using Fire should be used for them", + "create.ponder.fan_processing.text_5": "UNLOCALIZED: Air Flows passing through water create a Washing Setup", + "create.ponder.fan_processing.text_6": "UNLOCALIZED: Some interesting new processing can be done with it", + "create.ponder.fan_processing.text_7": "UNLOCALIZED: The Speed of the Fan does NOT affect the processing speed, only its range", + "create.ponder.fan_processing.text_8": "UNLOCALIZED: Fan Processing can also be applied to Items on Depots and Belts", + + "create.ponder.fan_source.header": "UNLOCALIZED: Generating Rotational Force using Encased Fans", + "create.ponder.fan_source.text_1": "UNLOCALIZED: Fans facing down into a source of heat can provide Rotational Force", + "create.ponder.fan_source.text_2": "UNLOCALIZED: When given a Redstone Signal, the Fans will start providing power", + + "create.ponder.funnel_compat.header": "UNLOCALIZED: Funnel compatibility", + "create.ponder.funnel_compat.text_1": "UNLOCALIZED: Funnels should also interact nicely with a handful of other components.", + "create.ponder.funnel_compat.text_2": "UNLOCALIZED: Vertical Saws", + "create.ponder.funnel_compat.text_3": "UNLOCALIZED: Depots", + "create.ponder.funnel_compat.text_4": "UNLOCALIZED: Item Drains", + + "create.ponder.funnel_direction.header": "UNLOCALIZED: Direction of Transfer", + "create.ponder.funnel_direction.text_1": "UNLOCALIZED: Placed normally, it pulls items from the inventory.", + "create.ponder.funnel_direction.text_2": "UNLOCALIZED: Placed while sneaking, it puts items into the inventory.", + "create.ponder.funnel_direction.text_3": "UNLOCALIZED: Using a wrench, the funnel can be flipped after placement.", + "create.ponder.funnel_direction.text_4": "UNLOCALIZED: Same rules will apply for most orientations.", + "create.ponder.funnel_direction.text_5": "UNLOCALIZED: Funnels on belts will extract/insert depending on its movement direction.", + + "create.ponder.funnel_intro.header": "UNLOCALIZED: Using funnels", + "create.ponder.funnel_intro.text_1": "UNLOCALIZED: Funnels are ideal for transferring items from and to inventories.", + + "create.ponder.funnel_redstone.header": "UNLOCALIZED: Redstone control", + "create.ponder.funnel_redstone.text_1": "UNLOCALIZED: Redstone power will prevent any funnel from acting.", + + "create.ponder.funnel_transfer.header": "UNLOCALIZED: Direct transfer", + "create.ponder.funnel_transfer.text_1": "UNLOCALIZED: Funnels cannot ever transfer between closed inventories directly.", + "create.ponder.funnel_transfer.text_2": "UNLOCALIZED: Chutes or Smart chutes might be more suitable for such purposes.", + "create.ponder.funnel_transfer.text_3": "UNLOCALIZED: Same applies for horizontal movement.\nA mechanical belt should help here.", + + "create.ponder.gantry_carriage.header": "UNLOCALIZED: Using Gantry Carriages", + "create.ponder.gantry_carriage.text_1": "UNLOCALIZED: Gantry Carriages can mount to and slide along a Gantry Shaft.", + "create.ponder.gantry_carriage.text_2": "UNLOCALIZED: Gantry setups can move attached Blocks.", + + "create.ponder.gantry_cascaded.header": "UNLOCALIZED: Cascaded Gantries", + "create.ponder.gantry_cascaded.text_1": "UNLOCALIZED: Gantry shafts attach to a carriage without the need of super glue", + "create.ponder.gantry_cascaded.text_2": "UNLOCALIZED: Same applies for carriages on moved Gantry Shafts", + "create.ponder.gantry_cascaded.text_3": "UNLOCALIZED: Thus, a gantry system can be cascaded to cover multiple axes of movement", + + "create.ponder.gantry_direction.header": "UNLOCALIZED: Gantry Movement Direction", + "create.ponder.gantry_direction.text_1": "UNLOCALIZED: Gantry Shafts can have opposite orientations", + "create.ponder.gantry_direction.text_2": "UNLOCALIZED: The movement direction of carriages depend on their shafts' orientation", + "create.ponder.gantry_direction.text_3": "UNLOCALIZED: ...as well as the rotation direction of the shaft", + "create.ponder.gantry_direction.text_4": "UNLOCALIZED: Same rules apply for the propagated rotation", + + "create.ponder.gantry_redstone.header": "UNLOCALIZED: Gantry Power Propagation", + "create.ponder.gantry_redstone.text_1": "UNLOCALIZED: Redstone-powered gantry shafts stop moving their carriages", + "create.ponder.gantry_redstone.text_2": "UNLOCALIZED: Instead, its rotational force is relayed to the carriages' output shaft", + + "create.ponder.gantry_shaft.header": "UNLOCALIZED: Using Gantry Shafts", + "create.ponder.gantry_shaft.text_1": "UNLOCALIZED: Gantry Shafts form the basis of a gantry setup. Attached Carriages will move along them.", + "create.ponder.gantry_shaft.text_2": "UNLOCALIZED: Gantry setups can move attached Blocks.", + + "create.ponder.gearbox.header": "UNLOCALIZED: Relaying rotational force using Gearboxes", + "create.ponder.gearbox.text_1": "UNLOCALIZED: Jumping between axes of rotation can get bulky quickly", + "create.ponder.gearbox.text_2": "UNLOCALIZED: A gearbox is the more compact equivalent of this setup", + "create.ponder.gearbox.text_3": "UNLOCALIZED: Shafts around corners rotate in mirrored directions", + "create.ponder.gearbox.text_4": "UNLOCALIZED: Straight connections will be reversed", + + "create.ponder.gearshift.header": "UNLOCALIZED: Controlling rotational force using a Gearshift", + "create.ponder.gearshift.text_1": "UNLOCALIZED: Gearshifts will relay rotation in a straight line", + "create.ponder.gearshift.text_2": "UNLOCALIZED: When powered by Redstone, it reverses the transmission", + + "create.ponder.hand_crank.header": "UNLOCALIZED: Generating Rotational Force using Hand Cranks", + "create.ponder.hand_crank.text_1": "UNLOCALIZED: Hand Cranks can be used by players to apply rotational force manually", + "create.ponder.hand_crank.text_2": "UNLOCALIZED: Hold Right-Click to rotate it Counter-Clockwise", + "create.ponder.hand_crank.text_3": "UNLOCALIZED: Its conveyed speed is relatively high", + "create.ponder.hand_crank.text_4": "UNLOCALIZED: Sneak and Hold Right-Click to rotate it Clockwise", + + "create.ponder.large_cogwheel.header": "UNLOCALIZED: Relaying rotational force using Large Cogwheels", + "create.ponder.large_cogwheel.text_1": "UNLOCALIZED: Large cogwheels can connect to each other at right angles", + "create.ponder.large_cogwheel.text_2": "UNLOCALIZED: It will help relaying conveyed speed to other axes of rotation", + + "create.ponder.portable_storage_interface.header": "UNLOCALIZED: Contraption Storage Exchange", + "create.ponder.portable_storage_interface.text_1": "UNLOCALIZED: Inventories on moving contraptions cannot be accessed by players.", + "create.ponder.portable_storage_interface.text_2": "UNLOCALIZED: This component can interact with storage without the need to stop the contraption.", + "create.ponder.portable_storage_interface.text_3": "UNLOCALIZED: Place a second one with a gap of 1 or 2 blocks inbetween", + "create.ponder.portable_storage_interface.text_4": "UNLOCALIZED: Whenever they pass by each other, they will engage in a connection", + "create.ponder.portable_storage_interface.text_5": "UNLOCALIZED: While engaged, the stationary interface will represent ALL inventories on the contraption", + "create.ponder.portable_storage_interface.text_6": "UNLOCALIZED: Items can now be inserted...", + "create.ponder.portable_storage_interface.text_7": "UNLOCALIZED: ...or extracted from the contraption", + "create.ponder.portable_storage_interface.text_8": "UNLOCALIZED: After no items have been exchanged for a while, the contraption will continue on its way", + + "create.ponder.portable_storage_interface_redstone.header": "UNLOCALIZED: Redstone Control", + "create.ponder.portable_storage_interface_redstone.text_1": "UNLOCALIZED: Redstone power will prevent the stationary interface from engaging", + + "create.ponder.shaft.header": "UNLOCALIZED: Relaying rotational force using Shafts", + "create.ponder.shaft.text_1": "UNLOCALIZED: Shafts will relay rotation in a straight line.", + + "create.ponder.shaft_casing.header": "UNLOCALIZED: Encasing Shafts", + "create.ponder.shaft_casing.text_1": "UNLOCALIZED: Brass or Andesite Casing can be used to decorate Shafts", + + "create.ponder.valve_handle.header": "UNLOCALIZED: Generating Rotational Force using Valve Handles", + "create.ponder.valve_handle.text_1": "UNLOCALIZED: Valve Handles can be used by players to apply rotational force manually", + "create.ponder.valve_handle.text_2": "UNLOCALIZED: Hold Right-Click to rotate it Counter-Clockwise", + "create.ponder.valve_handle.text_3": "UNLOCALIZED: Its conveyed speed is slow and precise", + "create.ponder.valve_handle.text_4": "UNLOCALIZED: Sneak and Hold Right-Click to rotate it Clockwise", + "create.ponder.valve_handle.text_5": "UNLOCALIZED: Valve handles can be dyed for aesthetic purposes", + + "create.ponder.water_wheel.header": "UNLOCALIZED: Generating Rotational Force using Water Wheels", + "create.ponder.water_wheel.text_1": "UNLOCALIZED: Water Wheels draw force from adjacent Water Currents", + "create.ponder.water_wheel.text_2": "UNLOCALIZED: The more faces are powered, the faster the Water Wheel will rotate", + "create.ponder.water_wheel.text_3": "UNLOCALIZED: The Wheels' blades should be oriented against the flow", + "create.ponder.water_wheel.text_4": "UNLOCALIZED: Facing the opposite way, they will not be as effective", + "_": "Thank you for translating Create!" } \ No newline at end of file diff --git a/src/generated/resources/assets/create/lang/unfinished/ja_jp.json b/src/generated/resources/assets/create/lang/unfinished/ja_jp.json index 5121afc38..da469281b 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ja_jp.json +++ b/src/generated/resources/assets/create/lang/unfinished/ja_jp.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 32", + "_": "Missing Localizations: 210", "_": "->------------------------] Game Elements [------------------------<-", @@ -162,7 +162,7 @@ "block.create.gabbro_cobblestone_stairs": "斑れい岩の丸石の階段", "block.create.gabbro_cobblestone_wall": "斑れい岩の丸石の壁", "block.create.gabbro_pillar": "斑れい岩の柱", - "block.create.gantry_pinion": "ガントリーピニオン", + "block.create.gantry_carriage": "UNLOCALIZED: Gantry Carriage", "block.create.gantry_shaft": "ガントリーシャフト", "block.create.gearbox": "ギアボックス", "block.create.gearshift": "ギアシフト", @@ -1809,6 +1809,221 @@ "create.tooltip.randomWipDescription7": "これは君に向いていないかもしれない。あれはどう??", "create.tooltip.randomWipDescription8": "それを使ったことをすぐ後悔する。", + + "_": "->------------------------] Ponder Content [------------------------<-", + + "create.ponder.hold_to_ponder": "UNLOCALIZED: Hold [%1$s] to Ponder", + "create.ponder.subject": "UNLOCALIZED: Subject of this scene", + "create.ponder.pondering": "UNLOCALIZED: Pondering about...", + "create.ponder.identify_mode": "UNLOCALIZED: Identify mode active.\nUnpause with [%1$s]", + "create.ponder.associated": "UNLOCALIZED: Associated Entries", + "create.ponder.shared.movement_anchors": "UNLOCALIZED: With the help of Chassis or Super Glue, larger structures can be moved.", + "create.ponder.shared.rpm32": "UNLOCALIZED: 32 RPM", + "create.ponder.shared.sneak_and": "UNLOCALIZED: Sneak +", + "create.ponder.shared.rpm8": "UNLOCALIZED: 8 RPM", + "create.ponder.shared.ctrl_and": "UNLOCALIZED: Ctrl +", + "create.ponder.shared.rpm16_source": "UNLOCALIZED: Source: 16 RPM", + "create.ponder.shared.rpm16": "UNLOCALIZED: 16 RPM", + "create.ponder.tag.kinetic_sources": "UNLOCALIZED: Kinetic Sources", + "create.ponder.tag.kinetic_sources.description": "UNLOCALIZED: Components which generate Rotational Force", + "create.ponder.tag.contraption_actor": "UNLOCALIZED: Contraption Actors", + "create.ponder.tag.contraption_actor.description": "UNLOCALIZED: Components which expose special behaviour when attached to a moving contraption", + "create.ponder.tag.arm_targets": "UNLOCALIZED: Targets for Mechanical Arms", + "create.ponder.tag.arm_targets.description": "UNLOCALIZED: Components which can be selected as inputs or outputs to the Mechanical Arm", + "create.ponder.tag.logistics": "UNLOCALIZED: Item Transportation", + "create.ponder.tag.logistics.description": "UNLOCALIZED: Components which help moving items around", + "create.ponder.tag.movement_anchor": "UNLOCALIZED: Movement Anchors", + "create.ponder.tag.movement_anchor.description": "UNLOCALIZED: Components which allow the creation of moving contraptions, animating an attached structure in a variety of ways", + "create.ponder.tag.decoration": "UNLOCALIZED: Aesthetics", + "create.ponder.tag.decoration.description": "UNLOCALIZED: Components used mostly for decorative purposes", + "create.ponder.tag.kinetic_appliances": "UNLOCALIZED: Kinetic Appliances", + "create.ponder.tag.kinetic_appliances.description": "UNLOCALIZED: Components which make use of Rotational Force", + "create.ponder.tag.redstone": "UNLOCALIZED: Logic Components", + "create.ponder.tag.redstone.description": "UNLOCALIZED: Components which help with redstone engineering", + "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", + "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", + "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", + "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", + "create.ponder.tag.fluids": "UNLOCALIZED: Fluid Manipulators", + "create.ponder.tag.fluids.description": "UNLOCALIZED: Components which help relaying and making use of Fluids", + + "create.ponder.belt_casing.header": "UNLOCALIZED: Encasing Belts", + "create.ponder.belt_casing.text_1": "UNLOCALIZED: Brass or Andesite Casing can be used to decorate Mechanical Belts", + "create.ponder.belt_casing.text_2": "UNLOCALIZED: A wrench can be used to remove the casing", + + "create.ponder.belt_connector.header": "UNLOCALIZED: Using Mechanical Belts", + "create.ponder.belt_connector.text_1": "UNLOCALIZED: Right-Clicking two shafts with a belt item will connect them together", + "create.ponder.belt_connector.text_2": "UNLOCALIZED: Accidental selections can be canceled with Right-Click while Sneaking", + "create.ponder.belt_connector.text_3": "UNLOCALIZED: Additional Shafts can be added throughout the Belt", + "create.ponder.belt_connector.text_4": "UNLOCALIZED: Shafts connected via Belts will rotate with Identical Speed and Direction", + "create.ponder.belt_connector.text_5": "UNLOCALIZED: Added shafts can be removed using the wrench", + "create.ponder.belt_connector.text_6": "UNLOCALIZED: Mechanical Belts can be dyed for aesthetic purposes", + + "create.ponder.belt_directions.header": "UNLOCALIZED: Valid Orientations for Mechanical Belts", + "create.ponder.belt_directions.text_1": "UNLOCALIZED: Belts cannot connect in arbitrary directions", + "create.ponder.belt_directions.text_2": "UNLOCALIZED: 1. They can connect horizontally", + "create.ponder.belt_directions.text_3": "UNLOCALIZED: 2. They can connect diagonally", + "create.ponder.belt_directions.text_4": "UNLOCALIZED: 3. They can connect vertically", + "create.ponder.belt_directions.text_5": "UNLOCALIZED: 4. And they can connect vertical shafts horizontally", + "create.ponder.belt_directions.text_6": "UNLOCALIZED: These are all possible directions.\nBelts can span any Length between 2 and 20 blocks", + + "create.ponder.belt_transport.header": "UNLOCALIZED: Using Mechanical Belts for Logistics", + "create.ponder.belt_transport.text_1": "UNLOCALIZED: Moving belts will transport Items and other Entities", + "create.ponder.belt_transport.text_2": "UNLOCALIZED: Right-Click with an empty hand to take items off a belt", + + "create.ponder.brass_funnel.header": "UNLOCALIZED: The Brass Funnel", + "create.ponder.brass_funnel.text_1": "UNLOCALIZED: Andesite Funnels can only ever extract single items.", + "create.ponder.brass_funnel.text_2": "UNLOCALIZED: Brass Funnels can extract up to a full stack.", + "create.ponder.brass_funnel.text_3": "UNLOCALIZED: Scrolling on the filter slot allows for precise control over the extracted stack size.", + "create.ponder.brass_funnel.text_4": "UNLOCALIZED: Using items on the filter slot will restrict the funnel to only transfer matching stacks.", + + "create.ponder.chain_drive.header": "UNLOCALIZED: Relaying rotational force with Chain Drives", + "create.ponder.chain_drive.text_1": "UNLOCALIZED: Chain Drives relay rotation to each other in a row", + "create.ponder.chain_drive.text_2": "UNLOCALIZED: All shafts connected like this will rotate in the same direction", + "create.ponder.chain_drive.text_3": "UNLOCALIZED: Any part of the row can be rotated by 90 degrees", + + "create.ponder.chain_gearshift.header": "UNLOCALIZED: Controlling rotational speed with Chain Gearshifts", + "create.ponder.chain_gearshift.text_1": "UNLOCALIZED: Unpowered Chain Gearshifts behave exacly like Chain Drives", + "create.ponder.chain_gearshift.text_2": "UNLOCALIZED: When Powered, the speed transmitted to other Chain Drives in the row is doubled", + "create.ponder.chain_gearshift.text_3": "UNLOCALIZED: Whenever the Powered Gearshift is not at the source, its speed will be halved instead", + "create.ponder.chain_gearshift.text_4": "UNLOCALIZED: In both cases, Chain Drives in the row always run at 2x the speed of the Powered Gearshift", + "create.ponder.chain_gearshift.text_5": "UNLOCALIZED: Using analog signals, the ratio can be adjusted more precisely between 1 and 2", + "create.ponder.chain_gearshift.text_6": "UNLOCALIZED: 12 RPM", + + "create.ponder.clutch.header": "UNLOCALIZED: Controlling rotational force using a Clutch", + "create.ponder.clutch.text_1": "UNLOCALIZED: Clutches will relay rotation in a straight line", + "create.ponder.clutch.text_2": "UNLOCALIZED: When powered by Redstone, it breaks the connection", + + "create.ponder.cog_speedup.header": "UNLOCALIZED: Gearshifting with Cogs", + "create.ponder.cog_speedup.text_1": "UNLOCALIZED: Large and Small cogs can be connected diagonally", + "create.ponder.cog_speedup.text_2": "UNLOCALIZED: Shifting from large to small cogs, the conveyed speed will be doubled", + "create.ponder.cog_speedup.text_3": "UNLOCALIZED: Shifting the opposite way, the conveyed speed will be halved", + + "create.ponder.cogwheel.header": "UNLOCALIZED: Relaying rotational force using Cogwheels", + "create.ponder.cogwheel.text_1": "UNLOCALIZED: Cogwheels will relay rotation to other adjacent cogwheels", + "create.ponder.cogwheel.text_2": "UNLOCALIZED: Neighbouring shafts connected like this will rotate in opposite directions", + + "create.ponder.creative_motor.header": "UNLOCALIZED: Generating Rotational Force using Creative Motors", + "create.ponder.creative_motor.text_1": "UNLOCALIZED: Creative motors are a compact and configurable source of Rotational Force", + "create.ponder.creative_motor.text_2": "UNLOCALIZED: Scrolling on the back panel changes the RPM of the motors' rotational output", + + "create.ponder.fan_direction.header": "UNLOCALIZED: Air flow of Encased Fans", + "create.ponder.fan_direction.text_1": "UNLOCALIZED: Encased Fans use Rotational Force to create an Air Current", + "create.ponder.fan_direction.text_2": "UNLOCALIZED: Strength and Direction of Flow depends on the Rotational Input", + + "create.ponder.fan_processing.header": "UNLOCALIZED: Processing Items using Encased Fans", + "create.ponder.fan_processing.text_1": "UNLOCALIZED: When passing through lava, the Air Flow becomes Heated", + "create.ponder.fan_processing.text_2": "UNLOCALIZED: Items caught in the area will be smelted", + "create.ponder.fan_processing.text_3": "UNLOCALIZED: Food items thrown here would be incinerated", + "create.ponder.fan_processing.text_4": "UNLOCALIZED: Instead, a setup for Smoking using Fire should be used for them", + "create.ponder.fan_processing.text_5": "UNLOCALIZED: Air Flows passing through water create a Washing Setup", + "create.ponder.fan_processing.text_6": "UNLOCALIZED: Some interesting new processing can be done with it", + "create.ponder.fan_processing.text_7": "UNLOCALIZED: The Speed of the Fan does NOT affect the processing speed, only its range", + "create.ponder.fan_processing.text_8": "UNLOCALIZED: Fan Processing can also be applied to Items on Depots and Belts", + + "create.ponder.fan_source.header": "UNLOCALIZED: Generating Rotational Force using Encased Fans", + "create.ponder.fan_source.text_1": "UNLOCALIZED: Fans facing down into a source of heat can provide Rotational Force", + "create.ponder.fan_source.text_2": "UNLOCALIZED: When given a Redstone Signal, the Fans will start providing power", + + "create.ponder.funnel_compat.header": "UNLOCALIZED: Funnel compatibility", + "create.ponder.funnel_compat.text_1": "UNLOCALIZED: Funnels should also interact nicely with a handful of other components.", + "create.ponder.funnel_compat.text_2": "UNLOCALIZED: Vertical Saws", + "create.ponder.funnel_compat.text_3": "UNLOCALIZED: Depots", + "create.ponder.funnel_compat.text_4": "UNLOCALIZED: Item Drains", + + "create.ponder.funnel_direction.header": "UNLOCALIZED: Direction of Transfer", + "create.ponder.funnel_direction.text_1": "UNLOCALIZED: Placed normally, it pulls items from the inventory.", + "create.ponder.funnel_direction.text_2": "UNLOCALIZED: Placed while sneaking, it puts items into the inventory.", + "create.ponder.funnel_direction.text_3": "UNLOCALIZED: Using a wrench, the funnel can be flipped after placement.", + "create.ponder.funnel_direction.text_4": "UNLOCALIZED: Same rules will apply for most orientations.", + "create.ponder.funnel_direction.text_5": "UNLOCALIZED: Funnels on belts will extract/insert depending on its movement direction.", + + "create.ponder.funnel_intro.header": "UNLOCALIZED: Using funnels", + "create.ponder.funnel_intro.text_1": "UNLOCALIZED: Funnels are ideal for transferring items from and to inventories.", + + "create.ponder.funnel_redstone.header": "UNLOCALIZED: Redstone control", + "create.ponder.funnel_redstone.text_1": "UNLOCALIZED: Redstone power will prevent any funnel from acting.", + + "create.ponder.funnel_transfer.header": "UNLOCALIZED: Direct transfer", + "create.ponder.funnel_transfer.text_1": "UNLOCALIZED: Funnels cannot ever transfer between closed inventories directly.", + "create.ponder.funnel_transfer.text_2": "UNLOCALIZED: Chutes or Smart chutes might be more suitable for such purposes.", + "create.ponder.funnel_transfer.text_3": "UNLOCALIZED: Same applies for horizontal movement.\nA mechanical belt should help here.", + + "create.ponder.gantry_carriage.header": "UNLOCALIZED: Using Gantry Carriages", + "create.ponder.gantry_carriage.text_1": "UNLOCALIZED: Gantry Carriages can mount to and slide along a Gantry Shaft.", + "create.ponder.gantry_carriage.text_2": "UNLOCALIZED: Gantry setups can move attached Blocks.", + + "create.ponder.gantry_cascaded.header": "UNLOCALIZED: Cascaded Gantries", + "create.ponder.gantry_cascaded.text_1": "UNLOCALIZED: Gantry shafts attach to a carriage without the need of super glue", + "create.ponder.gantry_cascaded.text_2": "UNLOCALIZED: Same applies for carriages on moved Gantry Shafts", + "create.ponder.gantry_cascaded.text_3": "UNLOCALIZED: Thus, a gantry system can be cascaded to cover multiple axes of movement", + + "create.ponder.gantry_direction.header": "UNLOCALIZED: Gantry Movement Direction", + "create.ponder.gantry_direction.text_1": "UNLOCALIZED: Gantry Shafts can have opposite orientations", + "create.ponder.gantry_direction.text_2": "UNLOCALIZED: The movement direction of carriages depend on their shafts' orientation", + "create.ponder.gantry_direction.text_3": "UNLOCALIZED: ...as well as the rotation direction of the shaft", + "create.ponder.gantry_direction.text_4": "UNLOCALIZED: Same rules apply for the propagated rotation", + + "create.ponder.gantry_redstone.header": "UNLOCALIZED: Gantry Power Propagation", + "create.ponder.gantry_redstone.text_1": "UNLOCALIZED: Redstone-powered gantry shafts stop moving their carriages", + "create.ponder.gantry_redstone.text_2": "UNLOCALIZED: Instead, its rotational force is relayed to the carriages' output shaft", + + "create.ponder.gantry_shaft.header": "UNLOCALIZED: Using Gantry Shafts", + "create.ponder.gantry_shaft.text_1": "UNLOCALIZED: Gantry Shafts form the basis of a gantry setup. Attached Carriages will move along them.", + "create.ponder.gantry_shaft.text_2": "UNLOCALIZED: Gantry setups can move attached Blocks.", + + "create.ponder.gearbox.header": "UNLOCALIZED: Relaying rotational force using Gearboxes", + "create.ponder.gearbox.text_1": "UNLOCALIZED: Jumping between axes of rotation can get bulky quickly", + "create.ponder.gearbox.text_2": "UNLOCALIZED: A gearbox is the more compact equivalent of this setup", + "create.ponder.gearbox.text_3": "UNLOCALIZED: Shafts around corners rotate in mirrored directions", + "create.ponder.gearbox.text_4": "UNLOCALIZED: Straight connections will be reversed", + + "create.ponder.gearshift.header": "UNLOCALIZED: Controlling rotational force using a Gearshift", + "create.ponder.gearshift.text_1": "UNLOCALIZED: Gearshifts will relay rotation in a straight line", + "create.ponder.gearshift.text_2": "UNLOCALIZED: When powered by Redstone, it reverses the transmission", + + "create.ponder.hand_crank.header": "UNLOCALIZED: Generating Rotational Force using Hand Cranks", + "create.ponder.hand_crank.text_1": "UNLOCALIZED: Hand Cranks can be used by players to apply rotational force manually", + "create.ponder.hand_crank.text_2": "UNLOCALIZED: Hold Right-Click to rotate it Counter-Clockwise", + "create.ponder.hand_crank.text_3": "UNLOCALIZED: Its conveyed speed is relatively high", + "create.ponder.hand_crank.text_4": "UNLOCALIZED: Sneak and Hold Right-Click to rotate it Clockwise", + + "create.ponder.large_cogwheel.header": "UNLOCALIZED: Relaying rotational force using Large Cogwheels", + "create.ponder.large_cogwheel.text_1": "UNLOCALIZED: Large cogwheels can connect to each other at right angles", + "create.ponder.large_cogwheel.text_2": "UNLOCALIZED: It will help relaying conveyed speed to other axes of rotation", + + "create.ponder.portable_storage_interface.header": "UNLOCALIZED: Contraption Storage Exchange", + "create.ponder.portable_storage_interface.text_1": "UNLOCALIZED: Inventories on moving contraptions cannot be accessed by players.", + "create.ponder.portable_storage_interface.text_2": "UNLOCALIZED: This component can interact with storage without the need to stop the contraption.", + "create.ponder.portable_storage_interface.text_3": "UNLOCALIZED: Place a second one with a gap of 1 or 2 blocks inbetween", + "create.ponder.portable_storage_interface.text_4": "UNLOCALIZED: Whenever they pass by each other, they will engage in a connection", + "create.ponder.portable_storage_interface.text_5": "UNLOCALIZED: While engaged, the stationary interface will represent ALL inventories on the contraption", + "create.ponder.portable_storage_interface.text_6": "UNLOCALIZED: Items can now be inserted...", + "create.ponder.portable_storage_interface.text_7": "UNLOCALIZED: ...or extracted from the contraption", + "create.ponder.portable_storage_interface.text_8": "UNLOCALIZED: After no items have been exchanged for a while, the contraption will continue on its way", + + "create.ponder.portable_storage_interface_redstone.header": "UNLOCALIZED: Redstone Control", + "create.ponder.portable_storage_interface_redstone.text_1": "UNLOCALIZED: Redstone power will prevent the stationary interface from engaging", + + "create.ponder.shaft.header": "UNLOCALIZED: Relaying rotational force using Shafts", + "create.ponder.shaft.text_1": "UNLOCALIZED: Shafts will relay rotation in a straight line.", + + "create.ponder.shaft_casing.header": "UNLOCALIZED: Encasing Shafts", + "create.ponder.shaft_casing.text_1": "UNLOCALIZED: Brass or Andesite Casing can be used to decorate Shafts", + + "create.ponder.valve_handle.header": "UNLOCALIZED: Generating Rotational Force using Valve Handles", + "create.ponder.valve_handle.text_1": "UNLOCALIZED: Valve Handles can be used by players to apply rotational force manually", + "create.ponder.valve_handle.text_2": "UNLOCALIZED: Hold Right-Click to rotate it Counter-Clockwise", + "create.ponder.valve_handle.text_3": "UNLOCALIZED: Its conveyed speed is slow and precise", + "create.ponder.valve_handle.text_4": "UNLOCALIZED: Sneak and Hold Right-Click to rotate it Clockwise", + "create.ponder.valve_handle.text_5": "UNLOCALIZED: Valve handles can be dyed for aesthetic purposes", + + "create.ponder.water_wheel.header": "UNLOCALIZED: Generating Rotational Force using Water Wheels", + "create.ponder.water_wheel.text_1": "UNLOCALIZED: Water Wheels draw force from adjacent Water Currents", + "create.ponder.water_wheel.text_2": "UNLOCALIZED: The more faces are powered, the faster the Water Wheel will rotate", + "create.ponder.water_wheel.text_3": "UNLOCALIZED: The Wheels' blades should be oriented against the flow", + "create.ponder.water_wheel.text_4": "UNLOCALIZED: Facing the opposite way, they will not be as effective", + "_": "Thank you for translating Create!" } \ No newline at end of file diff --git a/src/generated/resources/assets/create/lang/unfinished/ko_kr.json b/src/generated/resources/assets/create/lang/unfinished/ko_kr.json index d0794775c..137d78e83 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ko_kr.json +++ b/src/generated/resources/assets/create/lang/unfinished/ko_kr.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 79", + "_": "Missing Localizations: 256", "_": "->------------------------] Game Elements [------------------------<-", @@ -162,7 +162,7 @@ "block.create.gabbro_cobblestone_stairs": "반려암 조약돌 계단", "block.create.gabbro_cobblestone_wall": "반려암 조약돌 담장", "block.create.gabbro_pillar": "반려암 기둥", - "block.create.gantry_pinion": "UNLOCALIZED: Gantry Pinion", + "block.create.gantry_carriage": "UNLOCALIZED: Gantry Carriage", "block.create.gantry_shaft": "UNLOCALIZED: Gantry Shaft", "block.create.gearbox": "기어박스", "block.create.gearshift": "기어쉬프트", @@ -1809,6 +1809,221 @@ "create.tooltip.randomWipDescription7": "This one maybe isn't for you. What about that one?", "create.tooltip.randomWipDescription8": "Use it and regret your decision immediately.", + + "_": "->------------------------] Ponder Content [------------------------<-", + + "create.ponder.hold_to_ponder": "UNLOCALIZED: Hold [%1$s] to Ponder", + "create.ponder.subject": "UNLOCALIZED: Subject of this scene", + "create.ponder.pondering": "UNLOCALIZED: Pondering about...", + "create.ponder.identify_mode": "UNLOCALIZED: Identify mode active.\nUnpause with [%1$s]", + "create.ponder.associated": "UNLOCALIZED: Associated Entries", + "create.ponder.shared.movement_anchors": "UNLOCALIZED: With the help of Chassis or Super Glue, larger structures can be moved.", + "create.ponder.shared.rpm32": "UNLOCALIZED: 32 RPM", + "create.ponder.shared.sneak_and": "UNLOCALIZED: Sneak +", + "create.ponder.shared.rpm8": "UNLOCALIZED: 8 RPM", + "create.ponder.shared.ctrl_and": "UNLOCALIZED: Ctrl +", + "create.ponder.shared.rpm16_source": "UNLOCALIZED: Source: 16 RPM", + "create.ponder.shared.rpm16": "UNLOCALIZED: 16 RPM", + "create.ponder.tag.kinetic_sources": "UNLOCALIZED: Kinetic Sources", + "create.ponder.tag.kinetic_sources.description": "UNLOCALIZED: Components which generate Rotational Force", + "create.ponder.tag.contraption_actor": "UNLOCALIZED: Contraption Actors", + "create.ponder.tag.contraption_actor.description": "UNLOCALIZED: Components which expose special behaviour when attached to a moving contraption", + "create.ponder.tag.arm_targets": "UNLOCALIZED: Targets for Mechanical Arms", + "create.ponder.tag.arm_targets.description": "UNLOCALIZED: Components which can be selected as inputs or outputs to the Mechanical Arm", + "create.ponder.tag.logistics": "UNLOCALIZED: Item Transportation", + "create.ponder.tag.logistics.description": "UNLOCALIZED: Components which help moving items around", + "create.ponder.tag.movement_anchor": "UNLOCALIZED: Movement Anchors", + "create.ponder.tag.movement_anchor.description": "UNLOCALIZED: Components which allow the creation of moving contraptions, animating an attached structure in a variety of ways", + "create.ponder.tag.decoration": "UNLOCALIZED: Aesthetics", + "create.ponder.tag.decoration.description": "UNLOCALIZED: Components used mostly for decorative purposes", + "create.ponder.tag.kinetic_appliances": "UNLOCALIZED: Kinetic Appliances", + "create.ponder.tag.kinetic_appliances.description": "UNLOCALIZED: Components which make use of Rotational Force", + "create.ponder.tag.redstone": "UNLOCALIZED: Logic Components", + "create.ponder.tag.redstone.description": "UNLOCALIZED: Components which help with redstone engineering", + "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", + "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", + "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", + "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", + "create.ponder.tag.fluids": "UNLOCALIZED: Fluid Manipulators", + "create.ponder.tag.fluids.description": "UNLOCALIZED: Components which help relaying and making use of Fluids", + + "create.ponder.belt_casing.header": "UNLOCALIZED: Encasing Belts", + "create.ponder.belt_casing.text_1": "UNLOCALIZED: Brass or Andesite Casing can be used to decorate Mechanical Belts", + "create.ponder.belt_casing.text_2": "UNLOCALIZED: A wrench can be used to remove the casing", + + "create.ponder.belt_connector.header": "UNLOCALIZED: Using Mechanical Belts", + "create.ponder.belt_connector.text_1": "UNLOCALIZED: Right-Clicking two shafts with a belt item will connect them together", + "create.ponder.belt_connector.text_2": "UNLOCALIZED: Accidental selections can be canceled with Right-Click while Sneaking", + "create.ponder.belt_connector.text_3": "UNLOCALIZED: Additional Shafts can be added throughout the Belt", + "create.ponder.belt_connector.text_4": "UNLOCALIZED: Shafts connected via Belts will rotate with Identical Speed and Direction", + "create.ponder.belt_connector.text_5": "UNLOCALIZED: Added shafts can be removed using the wrench", + "create.ponder.belt_connector.text_6": "UNLOCALIZED: Mechanical Belts can be dyed for aesthetic purposes", + + "create.ponder.belt_directions.header": "UNLOCALIZED: Valid Orientations for Mechanical Belts", + "create.ponder.belt_directions.text_1": "UNLOCALIZED: Belts cannot connect in arbitrary directions", + "create.ponder.belt_directions.text_2": "UNLOCALIZED: 1. They can connect horizontally", + "create.ponder.belt_directions.text_3": "UNLOCALIZED: 2. They can connect diagonally", + "create.ponder.belt_directions.text_4": "UNLOCALIZED: 3. They can connect vertically", + "create.ponder.belt_directions.text_5": "UNLOCALIZED: 4. And they can connect vertical shafts horizontally", + "create.ponder.belt_directions.text_6": "UNLOCALIZED: These are all possible directions.\nBelts can span any Length between 2 and 20 blocks", + + "create.ponder.belt_transport.header": "UNLOCALIZED: Using Mechanical Belts for Logistics", + "create.ponder.belt_transport.text_1": "UNLOCALIZED: Moving belts will transport Items and other Entities", + "create.ponder.belt_transport.text_2": "UNLOCALIZED: Right-Click with an empty hand to take items off a belt", + + "create.ponder.brass_funnel.header": "UNLOCALIZED: The Brass Funnel", + "create.ponder.brass_funnel.text_1": "UNLOCALIZED: Andesite Funnels can only ever extract single items.", + "create.ponder.brass_funnel.text_2": "UNLOCALIZED: Brass Funnels can extract up to a full stack.", + "create.ponder.brass_funnel.text_3": "UNLOCALIZED: Scrolling on the filter slot allows for precise control over the extracted stack size.", + "create.ponder.brass_funnel.text_4": "UNLOCALIZED: Using items on the filter slot will restrict the funnel to only transfer matching stacks.", + + "create.ponder.chain_drive.header": "UNLOCALIZED: Relaying rotational force with Chain Drives", + "create.ponder.chain_drive.text_1": "UNLOCALIZED: Chain Drives relay rotation to each other in a row", + "create.ponder.chain_drive.text_2": "UNLOCALIZED: All shafts connected like this will rotate in the same direction", + "create.ponder.chain_drive.text_3": "UNLOCALIZED: Any part of the row can be rotated by 90 degrees", + + "create.ponder.chain_gearshift.header": "UNLOCALIZED: Controlling rotational speed with Chain Gearshifts", + "create.ponder.chain_gearshift.text_1": "UNLOCALIZED: Unpowered Chain Gearshifts behave exacly like Chain Drives", + "create.ponder.chain_gearshift.text_2": "UNLOCALIZED: When Powered, the speed transmitted to other Chain Drives in the row is doubled", + "create.ponder.chain_gearshift.text_3": "UNLOCALIZED: Whenever the Powered Gearshift is not at the source, its speed will be halved instead", + "create.ponder.chain_gearshift.text_4": "UNLOCALIZED: In both cases, Chain Drives in the row always run at 2x the speed of the Powered Gearshift", + "create.ponder.chain_gearshift.text_5": "UNLOCALIZED: Using analog signals, the ratio can be adjusted more precisely between 1 and 2", + "create.ponder.chain_gearshift.text_6": "UNLOCALIZED: 12 RPM", + + "create.ponder.clutch.header": "UNLOCALIZED: Controlling rotational force using a Clutch", + "create.ponder.clutch.text_1": "UNLOCALIZED: Clutches will relay rotation in a straight line", + "create.ponder.clutch.text_2": "UNLOCALIZED: When powered by Redstone, it breaks the connection", + + "create.ponder.cog_speedup.header": "UNLOCALIZED: Gearshifting with Cogs", + "create.ponder.cog_speedup.text_1": "UNLOCALIZED: Large and Small cogs can be connected diagonally", + "create.ponder.cog_speedup.text_2": "UNLOCALIZED: Shifting from large to small cogs, the conveyed speed will be doubled", + "create.ponder.cog_speedup.text_3": "UNLOCALIZED: Shifting the opposite way, the conveyed speed will be halved", + + "create.ponder.cogwheel.header": "UNLOCALIZED: Relaying rotational force using Cogwheels", + "create.ponder.cogwheel.text_1": "UNLOCALIZED: Cogwheels will relay rotation to other adjacent cogwheels", + "create.ponder.cogwheel.text_2": "UNLOCALIZED: Neighbouring shafts connected like this will rotate in opposite directions", + + "create.ponder.creative_motor.header": "UNLOCALIZED: Generating Rotational Force using Creative Motors", + "create.ponder.creative_motor.text_1": "UNLOCALIZED: Creative motors are a compact and configurable source of Rotational Force", + "create.ponder.creative_motor.text_2": "UNLOCALIZED: Scrolling on the back panel changes the RPM of the motors' rotational output", + + "create.ponder.fan_direction.header": "UNLOCALIZED: Air flow of Encased Fans", + "create.ponder.fan_direction.text_1": "UNLOCALIZED: Encased Fans use Rotational Force to create an Air Current", + "create.ponder.fan_direction.text_2": "UNLOCALIZED: Strength and Direction of Flow depends on the Rotational Input", + + "create.ponder.fan_processing.header": "UNLOCALIZED: Processing Items using Encased Fans", + "create.ponder.fan_processing.text_1": "UNLOCALIZED: When passing through lava, the Air Flow becomes Heated", + "create.ponder.fan_processing.text_2": "UNLOCALIZED: Items caught in the area will be smelted", + "create.ponder.fan_processing.text_3": "UNLOCALIZED: Food items thrown here would be incinerated", + "create.ponder.fan_processing.text_4": "UNLOCALIZED: Instead, a setup for Smoking using Fire should be used for them", + "create.ponder.fan_processing.text_5": "UNLOCALIZED: Air Flows passing through water create a Washing Setup", + "create.ponder.fan_processing.text_6": "UNLOCALIZED: Some interesting new processing can be done with it", + "create.ponder.fan_processing.text_7": "UNLOCALIZED: The Speed of the Fan does NOT affect the processing speed, only its range", + "create.ponder.fan_processing.text_8": "UNLOCALIZED: Fan Processing can also be applied to Items on Depots and Belts", + + "create.ponder.fan_source.header": "UNLOCALIZED: Generating Rotational Force using Encased Fans", + "create.ponder.fan_source.text_1": "UNLOCALIZED: Fans facing down into a source of heat can provide Rotational Force", + "create.ponder.fan_source.text_2": "UNLOCALIZED: When given a Redstone Signal, the Fans will start providing power", + + "create.ponder.funnel_compat.header": "UNLOCALIZED: Funnel compatibility", + "create.ponder.funnel_compat.text_1": "UNLOCALIZED: Funnels should also interact nicely with a handful of other components.", + "create.ponder.funnel_compat.text_2": "UNLOCALIZED: Vertical Saws", + "create.ponder.funnel_compat.text_3": "UNLOCALIZED: Depots", + "create.ponder.funnel_compat.text_4": "UNLOCALIZED: Item Drains", + + "create.ponder.funnel_direction.header": "UNLOCALIZED: Direction of Transfer", + "create.ponder.funnel_direction.text_1": "UNLOCALIZED: Placed normally, it pulls items from the inventory.", + "create.ponder.funnel_direction.text_2": "UNLOCALIZED: Placed while sneaking, it puts items into the inventory.", + "create.ponder.funnel_direction.text_3": "UNLOCALIZED: Using a wrench, the funnel can be flipped after placement.", + "create.ponder.funnel_direction.text_4": "UNLOCALIZED: Same rules will apply for most orientations.", + "create.ponder.funnel_direction.text_5": "UNLOCALIZED: Funnels on belts will extract/insert depending on its movement direction.", + + "create.ponder.funnel_intro.header": "UNLOCALIZED: Using funnels", + "create.ponder.funnel_intro.text_1": "UNLOCALIZED: Funnels are ideal for transferring items from and to inventories.", + + "create.ponder.funnel_redstone.header": "UNLOCALIZED: Redstone control", + "create.ponder.funnel_redstone.text_1": "UNLOCALIZED: Redstone power will prevent any funnel from acting.", + + "create.ponder.funnel_transfer.header": "UNLOCALIZED: Direct transfer", + "create.ponder.funnel_transfer.text_1": "UNLOCALIZED: Funnels cannot ever transfer between closed inventories directly.", + "create.ponder.funnel_transfer.text_2": "UNLOCALIZED: Chutes or Smart chutes might be more suitable for such purposes.", + "create.ponder.funnel_transfer.text_3": "UNLOCALIZED: Same applies for horizontal movement.\nA mechanical belt should help here.", + + "create.ponder.gantry_carriage.header": "UNLOCALIZED: Using Gantry Carriages", + "create.ponder.gantry_carriage.text_1": "UNLOCALIZED: Gantry Carriages can mount to and slide along a Gantry Shaft.", + "create.ponder.gantry_carriage.text_2": "UNLOCALIZED: Gantry setups can move attached Blocks.", + + "create.ponder.gantry_cascaded.header": "UNLOCALIZED: Cascaded Gantries", + "create.ponder.gantry_cascaded.text_1": "UNLOCALIZED: Gantry shafts attach to a carriage without the need of super glue", + "create.ponder.gantry_cascaded.text_2": "UNLOCALIZED: Same applies for carriages on moved Gantry Shafts", + "create.ponder.gantry_cascaded.text_3": "UNLOCALIZED: Thus, a gantry system can be cascaded to cover multiple axes of movement", + + "create.ponder.gantry_direction.header": "UNLOCALIZED: Gantry Movement Direction", + "create.ponder.gantry_direction.text_1": "UNLOCALIZED: Gantry Shafts can have opposite orientations", + "create.ponder.gantry_direction.text_2": "UNLOCALIZED: The movement direction of carriages depend on their shafts' orientation", + "create.ponder.gantry_direction.text_3": "UNLOCALIZED: ...as well as the rotation direction of the shaft", + "create.ponder.gantry_direction.text_4": "UNLOCALIZED: Same rules apply for the propagated rotation", + + "create.ponder.gantry_redstone.header": "UNLOCALIZED: Gantry Power Propagation", + "create.ponder.gantry_redstone.text_1": "UNLOCALIZED: Redstone-powered gantry shafts stop moving their carriages", + "create.ponder.gantry_redstone.text_2": "UNLOCALIZED: Instead, its rotational force is relayed to the carriages' output shaft", + + "create.ponder.gantry_shaft.header": "UNLOCALIZED: Using Gantry Shafts", + "create.ponder.gantry_shaft.text_1": "UNLOCALIZED: Gantry Shafts form the basis of a gantry setup. Attached Carriages will move along them.", + "create.ponder.gantry_shaft.text_2": "UNLOCALIZED: Gantry setups can move attached Blocks.", + + "create.ponder.gearbox.header": "UNLOCALIZED: Relaying rotational force using Gearboxes", + "create.ponder.gearbox.text_1": "UNLOCALIZED: Jumping between axes of rotation can get bulky quickly", + "create.ponder.gearbox.text_2": "UNLOCALIZED: A gearbox is the more compact equivalent of this setup", + "create.ponder.gearbox.text_3": "UNLOCALIZED: Shafts around corners rotate in mirrored directions", + "create.ponder.gearbox.text_4": "UNLOCALIZED: Straight connections will be reversed", + + "create.ponder.gearshift.header": "UNLOCALIZED: Controlling rotational force using a Gearshift", + "create.ponder.gearshift.text_1": "UNLOCALIZED: Gearshifts will relay rotation in a straight line", + "create.ponder.gearshift.text_2": "UNLOCALIZED: When powered by Redstone, it reverses the transmission", + + "create.ponder.hand_crank.header": "UNLOCALIZED: Generating Rotational Force using Hand Cranks", + "create.ponder.hand_crank.text_1": "UNLOCALIZED: Hand Cranks can be used by players to apply rotational force manually", + "create.ponder.hand_crank.text_2": "UNLOCALIZED: Hold Right-Click to rotate it Counter-Clockwise", + "create.ponder.hand_crank.text_3": "UNLOCALIZED: Its conveyed speed is relatively high", + "create.ponder.hand_crank.text_4": "UNLOCALIZED: Sneak and Hold Right-Click to rotate it Clockwise", + + "create.ponder.large_cogwheel.header": "UNLOCALIZED: Relaying rotational force using Large Cogwheels", + "create.ponder.large_cogwheel.text_1": "UNLOCALIZED: Large cogwheels can connect to each other at right angles", + "create.ponder.large_cogwheel.text_2": "UNLOCALIZED: It will help relaying conveyed speed to other axes of rotation", + + "create.ponder.portable_storage_interface.header": "UNLOCALIZED: Contraption Storage Exchange", + "create.ponder.portable_storage_interface.text_1": "UNLOCALIZED: Inventories on moving contraptions cannot be accessed by players.", + "create.ponder.portable_storage_interface.text_2": "UNLOCALIZED: This component can interact with storage without the need to stop the contraption.", + "create.ponder.portable_storage_interface.text_3": "UNLOCALIZED: Place a second one with a gap of 1 or 2 blocks inbetween", + "create.ponder.portable_storage_interface.text_4": "UNLOCALIZED: Whenever they pass by each other, they will engage in a connection", + "create.ponder.portable_storage_interface.text_5": "UNLOCALIZED: While engaged, the stationary interface will represent ALL inventories on the contraption", + "create.ponder.portable_storage_interface.text_6": "UNLOCALIZED: Items can now be inserted...", + "create.ponder.portable_storage_interface.text_7": "UNLOCALIZED: ...or extracted from the contraption", + "create.ponder.portable_storage_interface.text_8": "UNLOCALIZED: After no items have been exchanged for a while, the contraption will continue on its way", + + "create.ponder.portable_storage_interface_redstone.header": "UNLOCALIZED: Redstone Control", + "create.ponder.portable_storage_interface_redstone.text_1": "UNLOCALIZED: Redstone power will prevent the stationary interface from engaging", + + "create.ponder.shaft.header": "UNLOCALIZED: Relaying rotational force using Shafts", + "create.ponder.shaft.text_1": "UNLOCALIZED: Shafts will relay rotation in a straight line.", + + "create.ponder.shaft_casing.header": "UNLOCALIZED: Encasing Shafts", + "create.ponder.shaft_casing.text_1": "UNLOCALIZED: Brass or Andesite Casing can be used to decorate Shafts", + + "create.ponder.valve_handle.header": "UNLOCALIZED: Generating Rotational Force using Valve Handles", + "create.ponder.valve_handle.text_1": "UNLOCALIZED: Valve Handles can be used by players to apply rotational force manually", + "create.ponder.valve_handle.text_2": "UNLOCALIZED: Hold Right-Click to rotate it Counter-Clockwise", + "create.ponder.valve_handle.text_3": "UNLOCALIZED: Its conveyed speed is slow and precise", + "create.ponder.valve_handle.text_4": "UNLOCALIZED: Sneak and Hold Right-Click to rotate it Clockwise", + "create.ponder.valve_handle.text_5": "UNLOCALIZED: Valve handles can be dyed for aesthetic purposes", + + "create.ponder.water_wheel.header": "UNLOCALIZED: Generating Rotational Force using Water Wheels", + "create.ponder.water_wheel.text_1": "UNLOCALIZED: Water Wheels draw force from adjacent Water Currents", + "create.ponder.water_wheel.text_2": "UNLOCALIZED: The more faces are powered, the faster the Water Wheel will rotate", + "create.ponder.water_wheel.text_3": "UNLOCALIZED: The Wheels' blades should be oriented against the flow", + "create.ponder.water_wheel.text_4": "UNLOCALIZED: Facing the opposite way, they will not be as effective", + "_": "Thank you for translating Create!" } \ No newline at end of file diff --git a/src/generated/resources/assets/create/lang/unfinished/nl_nl.json b/src/generated/resources/assets/create/lang/unfinished/nl_nl.json index 209100c76..7f9b5a584 100644 --- a/src/generated/resources/assets/create/lang/unfinished/nl_nl.json +++ b/src/generated/resources/assets/create/lang/unfinished/nl_nl.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 1177", + "_": "Missing Localizations: 1354", "_": "->------------------------] Game Elements [------------------------<-", @@ -162,7 +162,7 @@ "block.create.gabbro_cobblestone_stairs": "UNLOCALIZED: Gabbro Cobblestone Stairs", "block.create.gabbro_cobblestone_wall": "UNLOCALIZED: Gabbro Cobblestone Wall", "block.create.gabbro_pillar": "UNLOCALIZED: Gabbro Pillar", - "block.create.gantry_pinion": "UNLOCALIZED: Gantry Pinion", + "block.create.gantry_carriage": "UNLOCALIZED: Gantry Carriage", "block.create.gantry_shaft": "UNLOCALIZED: Gantry Shaft", "block.create.gearbox": "Versnellingsbak", "block.create.gearshift": "Versnellingspook", @@ -1809,6 +1809,221 @@ "create.tooltip.randomWipDescription7": "Deze is misschien niet geschikt voor jou.", "create.tooltip.randomWipDescription8": "Gebruikt het en je zal meteen spijt hebben.", + + "_": "->------------------------] Ponder Content [------------------------<-", + + "create.ponder.hold_to_ponder": "UNLOCALIZED: Hold [%1$s] to Ponder", + "create.ponder.subject": "UNLOCALIZED: Subject of this scene", + "create.ponder.pondering": "UNLOCALIZED: Pondering about...", + "create.ponder.identify_mode": "UNLOCALIZED: Identify mode active.\nUnpause with [%1$s]", + "create.ponder.associated": "UNLOCALIZED: Associated Entries", + "create.ponder.shared.movement_anchors": "UNLOCALIZED: With the help of Chassis or Super Glue, larger structures can be moved.", + "create.ponder.shared.rpm32": "UNLOCALIZED: 32 RPM", + "create.ponder.shared.sneak_and": "UNLOCALIZED: Sneak +", + "create.ponder.shared.rpm8": "UNLOCALIZED: 8 RPM", + "create.ponder.shared.ctrl_and": "UNLOCALIZED: Ctrl +", + "create.ponder.shared.rpm16_source": "UNLOCALIZED: Source: 16 RPM", + "create.ponder.shared.rpm16": "UNLOCALIZED: 16 RPM", + "create.ponder.tag.kinetic_sources": "UNLOCALIZED: Kinetic Sources", + "create.ponder.tag.kinetic_sources.description": "UNLOCALIZED: Components which generate Rotational Force", + "create.ponder.tag.contraption_actor": "UNLOCALIZED: Contraption Actors", + "create.ponder.tag.contraption_actor.description": "UNLOCALIZED: Components which expose special behaviour when attached to a moving contraption", + "create.ponder.tag.arm_targets": "UNLOCALIZED: Targets for Mechanical Arms", + "create.ponder.tag.arm_targets.description": "UNLOCALIZED: Components which can be selected as inputs or outputs to the Mechanical Arm", + "create.ponder.tag.logistics": "UNLOCALIZED: Item Transportation", + "create.ponder.tag.logistics.description": "UNLOCALIZED: Components which help moving items around", + "create.ponder.tag.movement_anchor": "UNLOCALIZED: Movement Anchors", + "create.ponder.tag.movement_anchor.description": "UNLOCALIZED: Components which allow the creation of moving contraptions, animating an attached structure in a variety of ways", + "create.ponder.tag.decoration": "UNLOCALIZED: Aesthetics", + "create.ponder.tag.decoration.description": "UNLOCALIZED: Components used mostly for decorative purposes", + "create.ponder.tag.kinetic_appliances": "UNLOCALIZED: Kinetic Appliances", + "create.ponder.tag.kinetic_appliances.description": "UNLOCALIZED: Components which make use of Rotational Force", + "create.ponder.tag.redstone": "UNLOCALIZED: Logic Components", + "create.ponder.tag.redstone.description": "UNLOCALIZED: Components which help with redstone engineering", + "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", + "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", + "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", + "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", + "create.ponder.tag.fluids": "UNLOCALIZED: Fluid Manipulators", + "create.ponder.tag.fluids.description": "UNLOCALIZED: Components which help relaying and making use of Fluids", + + "create.ponder.belt_casing.header": "UNLOCALIZED: Encasing Belts", + "create.ponder.belt_casing.text_1": "UNLOCALIZED: Brass or Andesite Casing can be used to decorate Mechanical Belts", + "create.ponder.belt_casing.text_2": "UNLOCALIZED: A wrench can be used to remove the casing", + + "create.ponder.belt_connector.header": "UNLOCALIZED: Using Mechanical Belts", + "create.ponder.belt_connector.text_1": "UNLOCALIZED: Right-Clicking two shafts with a belt item will connect them together", + "create.ponder.belt_connector.text_2": "UNLOCALIZED: Accidental selections can be canceled with Right-Click while Sneaking", + "create.ponder.belt_connector.text_3": "UNLOCALIZED: Additional Shafts can be added throughout the Belt", + "create.ponder.belt_connector.text_4": "UNLOCALIZED: Shafts connected via Belts will rotate with Identical Speed and Direction", + "create.ponder.belt_connector.text_5": "UNLOCALIZED: Added shafts can be removed using the wrench", + "create.ponder.belt_connector.text_6": "UNLOCALIZED: Mechanical Belts can be dyed for aesthetic purposes", + + "create.ponder.belt_directions.header": "UNLOCALIZED: Valid Orientations for Mechanical Belts", + "create.ponder.belt_directions.text_1": "UNLOCALIZED: Belts cannot connect in arbitrary directions", + "create.ponder.belt_directions.text_2": "UNLOCALIZED: 1. They can connect horizontally", + "create.ponder.belt_directions.text_3": "UNLOCALIZED: 2. They can connect diagonally", + "create.ponder.belt_directions.text_4": "UNLOCALIZED: 3. They can connect vertically", + "create.ponder.belt_directions.text_5": "UNLOCALIZED: 4. And they can connect vertical shafts horizontally", + "create.ponder.belt_directions.text_6": "UNLOCALIZED: These are all possible directions.\nBelts can span any Length between 2 and 20 blocks", + + "create.ponder.belt_transport.header": "UNLOCALIZED: Using Mechanical Belts for Logistics", + "create.ponder.belt_transport.text_1": "UNLOCALIZED: Moving belts will transport Items and other Entities", + "create.ponder.belt_transport.text_2": "UNLOCALIZED: Right-Click with an empty hand to take items off a belt", + + "create.ponder.brass_funnel.header": "UNLOCALIZED: The Brass Funnel", + "create.ponder.brass_funnel.text_1": "UNLOCALIZED: Andesite Funnels can only ever extract single items.", + "create.ponder.brass_funnel.text_2": "UNLOCALIZED: Brass Funnels can extract up to a full stack.", + "create.ponder.brass_funnel.text_3": "UNLOCALIZED: Scrolling on the filter slot allows for precise control over the extracted stack size.", + "create.ponder.brass_funnel.text_4": "UNLOCALIZED: Using items on the filter slot will restrict the funnel to only transfer matching stacks.", + + "create.ponder.chain_drive.header": "UNLOCALIZED: Relaying rotational force with Chain Drives", + "create.ponder.chain_drive.text_1": "UNLOCALIZED: Chain Drives relay rotation to each other in a row", + "create.ponder.chain_drive.text_2": "UNLOCALIZED: All shafts connected like this will rotate in the same direction", + "create.ponder.chain_drive.text_3": "UNLOCALIZED: Any part of the row can be rotated by 90 degrees", + + "create.ponder.chain_gearshift.header": "UNLOCALIZED: Controlling rotational speed with Chain Gearshifts", + "create.ponder.chain_gearshift.text_1": "UNLOCALIZED: Unpowered Chain Gearshifts behave exacly like Chain Drives", + "create.ponder.chain_gearshift.text_2": "UNLOCALIZED: When Powered, the speed transmitted to other Chain Drives in the row is doubled", + "create.ponder.chain_gearshift.text_3": "UNLOCALIZED: Whenever the Powered Gearshift is not at the source, its speed will be halved instead", + "create.ponder.chain_gearshift.text_4": "UNLOCALIZED: In both cases, Chain Drives in the row always run at 2x the speed of the Powered Gearshift", + "create.ponder.chain_gearshift.text_5": "UNLOCALIZED: Using analog signals, the ratio can be adjusted more precisely between 1 and 2", + "create.ponder.chain_gearshift.text_6": "UNLOCALIZED: 12 RPM", + + "create.ponder.clutch.header": "UNLOCALIZED: Controlling rotational force using a Clutch", + "create.ponder.clutch.text_1": "UNLOCALIZED: Clutches will relay rotation in a straight line", + "create.ponder.clutch.text_2": "UNLOCALIZED: When powered by Redstone, it breaks the connection", + + "create.ponder.cog_speedup.header": "UNLOCALIZED: Gearshifting with Cogs", + "create.ponder.cog_speedup.text_1": "UNLOCALIZED: Large and Small cogs can be connected diagonally", + "create.ponder.cog_speedup.text_2": "UNLOCALIZED: Shifting from large to small cogs, the conveyed speed will be doubled", + "create.ponder.cog_speedup.text_3": "UNLOCALIZED: Shifting the opposite way, the conveyed speed will be halved", + + "create.ponder.cogwheel.header": "UNLOCALIZED: Relaying rotational force using Cogwheels", + "create.ponder.cogwheel.text_1": "UNLOCALIZED: Cogwheels will relay rotation to other adjacent cogwheels", + "create.ponder.cogwheel.text_2": "UNLOCALIZED: Neighbouring shafts connected like this will rotate in opposite directions", + + "create.ponder.creative_motor.header": "UNLOCALIZED: Generating Rotational Force using Creative Motors", + "create.ponder.creative_motor.text_1": "UNLOCALIZED: Creative motors are a compact and configurable source of Rotational Force", + "create.ponder.creative_motor.text_2": "UNLOCALIZED: Scrolling on the back panel changes the RPM of the motors' rotational output", + + "create.ponder.fan_direction.header": "UNLOCALIZED: Air flow of Encased Fans", + "create.ponder.fan_direction.text_1": "UNLOCALIZED: Encased Fans use Rotational Force to create an Air Current", + "create.ponder.fan_direction.text_2": "UNLOCALIZED: Strength and Direction of Flow depends on the Rotational Input", + + "create.ponder.fan_processing.header": "UNLOCALIZED: Processing Items using Encased Fans", + "create.ponder.fan_processing.text_1": "UNLOCALIZED: When passing through lava, the Air Flow becomes Heated", + "create.ponder.fan_processing.text_2": "UNLOCALIZED: Items caught in the area will be smelted", + "create.ponder.fan_processing.text_3": "UNLOCALIZED: Food items thrown here would be incinerated", + "create.ponder.fan_processing.text_4": "UNLOCALIZED: Instead, a setup for Smoking using Fire should be used for them", + "create.ponder.fan_processing.text_5": "UNLOCALIZED: Air Flows passing through water create a Washing Setup", + "create.ponder.fan_processing.text_6": "UNLOCALIZED: Some interesting new processing can be done with it", + "create.ponder.fan_processing.text_7": "UNLOCALIZED: The Speed of the Fan does NOT affect the processing speed, only its range", + "create.ponder.fan_processing.text_8": "UNLOCALIZED: Fan Processing can also be applied to Items on Depots and Belts", + + "create.ponder.fan_source.header": "UNLOCALIZED: Generating Rotational Force using Encased Fans", + "create.ponder.fan_source.text_1": "UNLOCALIZED: Fans facing down into a source of heat can provide Rotational Force", + "create.ponder.fan_source.text_2": "UNLOCALIZED: When given a Redstone Signal, the Fans will start providing power", + + "create.ponder.funnel_compat.header": "UNLOCALIZED: Funnel compatibility", + "create.ponder.funnel_compat.text_1": "UNLOCALIZED: Funnels should also interact nicely with a handful of other components.", + "create.ponder.funnel_compat.text_2": "UNLOCALIZED: Vertical Saws", + "create.ponder.funnel_compat.text_3": "UNLOCALIZED: Depots", + "create.ponder.funnel_compat.text_4": "UNLOCALIZED: Item Drains", + + "create.ponder.funnel_direction.header": "UNLOCALIZED: Direction of Transfer", + "create.ponder.funnel_direction.text_1": "UNLOCALIZED: Placed normally, it pulls items from the inventory.", + "create.ponder.funnel_direction.text_2": "UNLOCALIZED: Placed while sneaking, it puts items into the inventory.", + "create.ponder.funnel_direction.text_3": "UNLOCALIZED: Using a wrench, the funnel can be flipped after placement.", + "create.ponder.funnel_direction.text_4": "UNLOCALIZED: Same rules will apply for most orientations.", + "create.ponder.funnel_direction.text_5": "UNLOCALIZED: Funnels on belts will extract/insert depending on its movement direction.", + + "create.ponder.funnel_intro.header": "UNLOCALIZED: Using funnels", + "create.ponder.funnel_intro.text_1": "UNLOCALIZED: Funnels are ideal for transferring items from and to inventories.", + + "create.ponder.funnel_redstone.header": "UNLOCALIZED: Redstone control", + "create.ponder.funnel_redstone.text_1": "UNLOCALIZED: Redstone power will prevent any funnel from acting.", + + "create.ponder.funnel_transfer.header": "UNLOCALIZED: Direct transfer", + "create.ponder.funnel_transfer.text_1": "UNLOCALIZED: Funnels cannot ever transfer between closed inventories directly.", + "create.ponder.funnel_transfer.text_2": "UNLOCALIZED: Chutes or Smart chutes might be more suitable for such purposes.", + "create.ponder.funnel_transfer.text_3": "UNLOCALIZED: Same applies for horizontal movement.\nA mechanical belt should help here.", + + "create.ponder.gantry_carriage.header": "UNLOCALIZED: Using Gantry Carriages", + "create.ponder.gantry_carriage.text_1": "UNLOCALIZED: Gantry Carriages can mount to and slide along a Gantry Shaft.", + "create.ponder.gantry_carriage.text_2": "UNLOCALIZED: Gantry setups can move attached Blocks.", + + "create.ponder.gantry_cascaded.header": "UNLOCALIZED: Cascaded Gantries", + "create.ponder.gantry_cascaded.text_1": "UNLOCALIZED: Gantry shafts attach to a carriage without the need of super glue", + "create.ponder.gantry_cascaded.text_2": "UNLOCALIZED: Same applies for carriages on moved Gantry Shafts", + "create.ponder.gantry_cascaded.text_3": "UNLOCALIZED: Thus, a gantry system can be cascaded to cover multiple axes of movement", + + "create.ponder.gantry_direction.header": "UNLOCALIZED: Gantry Movement Direction", + "create.ponder.gantry_direction.text_1": "UNLOCALIZED: Gantry Shafts can have opposite orientations", + "create.ponder.gantry_direction.text_2": "UNLOCALIZED: The movement direction of carriages depend on their shafts' orientation", + "create.ponder.gantry_direction.text_3": "UNLOCALIZED: ...as well as the rotation direction of the shaft", + "create.ponder.gantry_direction.text_4": "UNLOCALIZED: Same rules apply for the propagated rotation", + + "create.ponder.gantry_redstone.header": "UNLOCALIZED: Gantry Power Propagation", + "create.ponder.gantry_redstone.text_1": "UNLOCALIZED: Redstone-powered gantry shafts stop moving their carriages", + "create.ponder.gantry_redstone.text_2": "UNLOCALIZED: Instead, its rotational force is relayed to the carriages' output shaft", + + "create.ponder.gantry_shaft.header": "UNLOCALIZED: Using Gantry Shafts", + "create.ponder.gantry_shaft.text_1": "UNLOCALIZED: Gantry Shafts form the basis of a gantry setup. Attached Carriages will move along them.", + "create.ponder.gantry_shaft.text_2": "UNLOCALIZED: Gantry setups can move attached Blocks.", + + "create.ponder.gearbox.header": "UNLOCALIZED: Relaying rotational force using Gearboxes", + "create.ponder.gearbox.text_1": "UNLOCALIZED: Jumping between axes of rotation can get bulky quickly", + "create.ponder.gearbox.text_2": "UNLOCALIZED: A gearbox is the more compact equivalent of this setup", + "create.ponder.gearbox.text_3": "UNLOCALIZED: Shafts around corners rotate in mirrored directions", + "create.ponder.gearbox.text_4": "UNLOCALIZED: Straight connections will be reversed", + + "create.ponder.gearshift.header": "UNLOCALIZED: Controlling rotational force using a Gearshift", + "create.ponder.gearshift.text_1": "UNLOCALIZED: Gearshifts will relay rotation in a straight line", + "create.ponder.gearshift.text_2": "UNLOCALIZED: When powered by Redstone, it reverses the transmission", + + "create.ponder.hand_crank.header": "UNLOCALIZED: Generating Rotational Force using Hand Cranks", + "create.ponder.hand_crank.text_1": "UNLOCALIZED: Hand Cranks can be used by players to apply rotational force manually", + "create.ponder.hand_crank.text_2": "UNLOCALIZED: Hold Right-Click to rotate it Counter-Clockwise", + "create.ponder.hand_crank.text_3": "UNLOCALIZED: Its conveyed speed is relatively high", + "create.ponder.hand_crank.text_4": "UNLOCALIZED: Sneak and Hold Right-Click to rotate it Clockwise", + + "create.ponder.large_cogwheel.header": "UNLOCALIZED: Relaying rotational force using Large Cogwheels", + "create.ponder.large_cogwheel.text_1": "UNLOCALIZED: Large cogwheels can connect to each other at right angles", + "create.ponder.large_cogwheel.text_2": "UNLOCALIZED: It will help relaying conveyed speed to other axes of rotation", + + "create.ponder.portable_storage_interface.header": "UNLOCALIZED: Contraption Storage Exchange", + "create.ponder.portable_storage_interface.text_1": "UNLOCALIZED: Inventories on moving contraptions cannot be accessed by players.", + "create.ponder.portable_storage_interface.text_2": "UNLOCALIZED: This component can interact with storage without the need to stop the contraption.", + "create.ponder.portable_storage_interface.text_3": "UNLOCALIZED: Place a second one with a gap of 1 or 2 blocks inbetween", + "create.ponder.portable_storage_interface.text_4": "UNLOCALIZED: Whenever they pass by each other, they will engage in a connection", + "create.ponder.portable_storage_interface.text_5": "UNLOCALIZED: While engaged, the stationary interface will represent ALL inventories on the contraption", + "create.ponder.portable_storage_interface.text_6": "UNLOCALIZED: Items can now be inserted...", + "create.ponder.portable_storage_interface.text_7": "UNLOCALIZED: ...or extracted from the contraption", + "create.ponder.portable_storage_interface.text_8": "UNLOCALIZED: After no items have been exchanged for a while, the contraption will continue on its way", + + "create.ponder.portable_storage_interface_redstone.header": "UNLOCALIZED: Redstone Control", + "create.ponder.portable_storage_interface_redstone.text_1": "UNLOCALIZED: Redstone power will prevent the stationary interface from engaging", + + "create.ponder.shaft.header": "UNLOCALIZED: Relaying rotational force using Shafts", + "create.ponder.shaft.text_1": "UNLOCALIZED: Shafts will relay rotation in a straight line.", + + "create.ponder.shaft_casing.header": "UNLOCALIZED: Encasing Shafts", + "create.ponder.shaft_casing.text_1": "UNLOCALIZED: Brass or Andesite Casing can be used to decorate Shafts", + + "create.ponder.valve_handle.header": "UNLOCALIZED: Generating Rotational Force using Valve Handles", + "create.ponder.valve_handle.text_1": "UNLOCALIZED: Valve Handles can be used by players to apply rotational force manually", + "create.ponder.valve_handle.text_2": "UNLOCALIZED: Hold Right-Click to rotate it Counter-Clockwise", + "create.ponder.valve_handle.text_3": "UNLOCALIZED: Its conveyed speed is slow and precise", + "create.ponder.valve_handle.text_4": "UNLOCALIZED: Sneak and Hold Right-Click to rotate it Clockwise", + "create.ponder.valve_handle.text_5": "UNLOCALIZED: Valve handles can be dyed for aesthetic purposes", + + "create.ponder.water_wheel.header": "UNLOCALIZED: Generating Rotational Force using Water Wheels", + "create.ponder.water_wheel.text_1": "UNLOCALIZED: Water Wheels draw force from adjacent Water Currents", + "create.ponder.water_wheel.text_2": "UNLOCALIZED: The more faces are powered, the faster the Water Wheel will rotate", + "create.ponder.water_wheel.text_3": "UNLOCALIZED: The Wheels' blades should be oriented against the flow", + "create.ponder.water_wheel.text_4": "UNLOCALIZED: Facing the opposite way, they will not be as effective", + "_": "Thank you for translating Create!" } \ No newline at end of file diff --git a/src/generated/resources/assets/create/lang/unfinished/pt_br.json b/src/generated/resources/assets/create/lang/unfinished/pt_br.json index 9da0705cc..a6d4d4d11 100644 --- a/src/generated/resources/assets/create/lang/unfinished/pt_br.json +++ b/src/generated/resources/assets/create/lang/unfinished/pt_br.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 1243", + "_": "Missing Localizations: 1420", "_": "->------------------------] Game Elements [------------------------<-", @@ -162,7 +162,7 @@ "block.create.gabbro_cobblestone_stairs": "UNLOCALIZED: Gabbro Cobblestone Stairs", "block.create.gabbro_cobblestone_wall": "UNLOCALIZED: Gabbro Cobblestone Wall", "block.create.gabbro_pillar": "UNLOCALIZED: Gabbro Pillar", - "block.create.gantry_pinion": "UNLOCALIZED: Gantry Pinion", + "block.create.gantry_carriage": "UNLOCALIZED: Gantry Carriage", "block.create.gantry_shaft": "UNLOCALIZED: Gantry Shaft", "block.create.gearbox": "Caixa de Transmissão", "block.create.gearshift": "Câmbio", @@ -1809,6 +1809,221 @@ "create.tooltip.randomWipDescription7": "UNLOCALIZED: This one maybe isn't for you. What about that one?", "create.tooltip.randomWipDescription8": "UNLOCALIZED: Use it and regret your decision immediately.", + + "_": "->------------------------] Ponder Content [------------------------<-", + + "create.ponder.hold_to_ponder": "UNLOCALIZED: Hold [%1$s] to Ponder", + "create.ponder.subject": "UNLOCALIZED: Subject of this scene", + "create.ponder.pondering": "UNLOCALIZED: Pondering about...", + "create.ponder.identify_mode": "UNLOCALIZED: Identify mode active.\nUnpause with [%1$s]", + "create.ponder.associated": "UNLOCALIZED: Associated Entries", + "create.ponder.shared.movement_anchors": "UNLOCALIZED: With the help of Chassis or Super Glue, larger structures can be moved.", + "create.ponder.shared.rpm32": "UNLOCALIZED: 32 RPM", + "create.ponder.shared.sneak_and": "UNLOCALIZED: Sneak +", + "create.ponder.shared.rpm8": "UNLOCALIZED: 8 RPM", + "create.ponder.shared.ctrl_and": "UNLOCALIZED: Ctrl +", + "create.ponder.shared.rpm16_source": "UNLOCALIZED: Source: 16 RPM", + "create.ponder.shared.rpm16": "UNLOCALIZED: 16 RPM", + "create.ponder.tag.kinetic_sources": "UNLOCALIZED: Kinetic Sources", + "create.ponder.tag.kinetic_sources.description": "UNLOCALIZED: Components which generate Rotational Force", + "create.ponder.tag.contraption_actor": "UNLOCALIZED: Contraption Actors", + "create.ponder.tag.contraption_actor.description": "UNLOCALIZED: Components which expose special behaviour when attached to a moving contraption", + "create.ponder.tag.arm_targets": "UNLOCALIZED: Targets for Mechanical Arms", + "create.ponder.tag.arm_targets.description": "UNLOCALIZED: Components which can be selected as inputs or outputs to the Mechanical Arm", + "create.ponder.tag.logistics": "UNLOCALIZED: Item Transportation", + "create.ponder.tag.logistics.description": "UNLOCALIZED: Components which help moving items around", + "create.ponder.tag.movement_anchor": "UNLOCALIZED: Movement Anchors", + "create.ponder.tag.movement_anchor.description": "UNLOCALIZED: Components which allow the creation of moving contraptions, animating an attached structure in a variety of ways", + "create.ponder.tag.decoration": "UNLOCALIZED: Aesthetics", + "create.ponder.tag.decoration.description": "UNLOCALIZED: Components used mostly for decorative purposes", + "create.ponder.tag.kinetic_appliances": "UNLOCALIZED: Kinetic Appliances", + "create.ponder.tag.kinetic_appliances.description": "UNLOCALIZED: Components which make use of Rotational Force", + "create.ponder.tag.redstone": "UNLOCALIZED: Logic Components", + "create.ponder.tag.redstone.description": "UNLOCALIZED: Components which help with redstone engineering", + "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", + "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", + "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", + "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", + "create.ponder.tag.fluids": "UNLOCALIZED: Fluid Manipulators", + "create.ponder.tag.fluids.description": "UNLOCALIZED: Components which help relaying and making use of Fluids", + + "create.ponder.belt_casing.header": "UNLOCALIZED: Encasing Belts", + "create.ponder.belt_casing.text_1": "UNLOCALIZED: Brass or Andesite Casing can be used to decorate Mechanical Belts", + "create.ponder.belt_casing.text_2": "UNLOCALIZED: A wrench can be used to remove the casing", + + "create.ponder.belt_connector.header": "UNLOCALIZED: Using Mechanical Belts", + "create.ponder.belt_connector.text_1": "UNLOCALIZED: Right-Clicking two shafts with a belt item will connect them together", + "create.ponder.belt_connector.text_2": "UNLOCALIZED: Accidental selections can be canceled with Right-Click while Sneaking", + "create.ponder.belt_connector.text_3": "UNLOCALIZED: Additional Shafts can be added throughout the Belt", + "create.ponder.belt_connector.text_4": "UNLOCALIZED: Shafts connected via Belts will rotate with Identical Speed and Direction", + "create.ponder.belt_connector.text_5": "UNLOCALIZED: Added shafts can be removed using the wrench", + "create.ponder.belt_connector.text_6": "UNLOCALIZED: Mechanical Belts can be dyed for aesthetic purposes", + + "create.ponder.belt_directions.header": "UNLOCALIZED: Valid Orientations for Mechanical Belts", + "create.ponder.belt_directions.text_1": "UNLOCALIZED: Belts cannot connect in arbitrary directions", + "create.ponder.belt_directions.text_2": "UNLOCALIZED: 1. They can connect horizontally", + "create.ponder.belt_directions.text_3": "UNLOCALIZED: 2. They can connect diagonally", + "create.ponder.belt_directions.text_4": "UNLOCALIZED: 3. They can connect vertically", + "create.ponder.belt_directions.text_5": "UNLOCALIZED: 4. And they can connect vertical shafts horizontally", + "create.ponder.belt_directions.text_6": "UNLOCALIZED: These are all possible directions.\nBelts can span any Length between 2 and 20 blocks", + + "create.ponder.belt_transport.header": "UNLOCALIZED: Using Mechanical Belts for Logistics", + "create.ponder.belt_transport.text_1": "UNLOCALIZED: Moving belts will transport Items and other Entities", + "create.ponder.belt_transport.text_2": "UNLOCALIZED: Right-Click with an empty hand to take items off a belt", + + "create.ponder.brass_funnel.header": "UNLOCALIZED: The Brass Funnel", + "create.ponder.brass_funnel.text_1": "UNLOCALIZED: Andesite Funnels can only ever extract single items.", + "create.ponder.brass_funnel.text_2": "UNLOCALIZED: Brass Funnels can extract up to a full stack.", + "create.ponder.brass_funnel.text_3": "UNLOCALIZED: Scrolling on the filter slot allows for precise control over the extracted stack size.", + "create.ponder.brass_funnel.text_4": "UNLOCALIZED: Using items on the filter slot will restrict the funnel to only transfer matching stacks.", + + "create.ponder.chain_drive.header": "UNLOCALIZED: Relaying rotational force with Chain Drives", + "create.ponder.chain_drive.text_1": "UNLOCALIZED: Chain Drives relay rotation to each other in a row", + "create.ponder.chain_drive.text_2": "UNLOCALIZED: All shafts connected like this will rotate in the same direction", + "create.ponder.chain_drive.text_3": "UNLOCALIZED: Any part of the row can be rotated by 90 degrees", + + "create.ponder.chain_gearshift.header": "UNLOCALIZED: Controlling rotational speed with Chain Gearshifts", + "create.ponder.chain_gearshift.text_1": "UNLOCALIZED: Unpowered Chain Gearshifts behave exacly like Chain Drives", + "create.ponder.chain_gearshift.text_2": "UNLOCALIZED: When Powered, the speed transmitted to other Chain Drives in the row is doubled", + "create.ponder.chain_gearshift.text_3": "UNLOCALIZED: Whenever the Powered Gearshift is not at the source, its speed will be halved instead", + "create.ponder.chain_gearshift.text_4": "UNLOCALIZED: In both cases, Chain Drives in the row always run at 2x the speed of the Powered Gearshift", + "create.ponder.chain_gearshift.text_5": "UNLOCALIZED: Using analog signals, the ratio can be adjusted more precisely between 1 and 2", + "create.ponder.chain_gearshift.text_6": "UNLOCALIZED: 12 RPM", + + "create.ponder.clutch.header": "UNLOCALIZED: Controlling rotational force using a Clutch", + "create.ponder.clutch.text_1": "UNLOCALIZED: Clutches will relay rotation in a straight line", + "create.ponder.clutch.text_2": "UNLOCALIZED: When powered by Redstone, it breaks the connection", + + "create.ponder.cog_speedup.header": "UNLOCALIZED: Gearshifting with Cogs", + "create.ponder.cog_speedup.text_1": "UNLOCALIZED: Large and Small cogs can be connected diagonally", + "create.ponder.cog_speedup.text_2": "UNLOCALIZED: Shifting from large to small cogs, the conveyed speed will be doubled", + "create.ponder.cog_speedup.text_3": "UNLOCALIZED: Shifting the opposite way, the conveyed speed will be halved", + + "create.ponder.cogwheel.header": "UNLOCALIZED: Relaying rotational force using Cogwheels", + "create.ponder.cogwheel.text_1": "UNLOCALIZED: Cogwheels will relay rotation to other adjacent cogwheels", + "create.ponder.cogwheel.text_2": "UNLOCALIZED: Neighbouring shafts connected like this will rotate in opposite directions", + + "create.ponder.creative_motor.header": "UNLOCALIZED: Generating Rotational Force using Creative Motors", + "create.ponder.creative_motor.text_1": "UNLOCALIZED: Creative motors are a compact and configurable source of Rotational Force", + "create.ponder.creative_motor.text_2": "UNLOCALIZED: Scrolling on the back panel changes the RPM of the motors' rotational output", + + "create.ponder.fan_direction.header": "UNLOCALIZED: Air flow of Encased Fans", + "create.ponder.fan_direction.text_1": "UNLOCALIZED: Encased Fans use Rotational Force to create an Air Current", + "create.ponder.fan_direction.text_2": "UNLOCALIZED: Strength and Direction of Flow depends on the Rotational Input", + + "create.ponder.fan_processing.header": "UNLOCALIZED: Processing Items using Encased Fans", + "create.ponder.fan_processing.text_1": "UNLOCALIZED: When passing through lava, the Air Flow becomes Heated", + "create.ponder.fan_processing.text_2": "UNLOCALIZED: Items caught in the area will be smelted", + "create.ponder.fan_processing.text_3": "UNLOCALIZED: Food items thrown here would be incinerated", + "create.ponder.fan_processing.text_4": "UNLOCALIZED: Instead, a setup for Smoking using Fire should be used for them", + "create.ponder.fan_processing.text_5": "UNLOCALIZED: Air Flows passing through water create a Washing Setup", + "create.ponder.fan_processing.text_6": "UNLOCALIZED: Some interesting new processing can be done with it", + "create.ponder.fan_processing.text_7": "UNLOCALIZED: The Speed of the Fan does NOT affect the processing speed, only its range", + "create.ponder.fan_processing.text_8": "UNLOCALIZED: Fan Processing can also be applied to Items on Depots and Belts", + + "create.ponder.fan_source.header": "UNLOCALIZED: Generating Rotational Force using Encased Fans", + "create.ponder.fan_source.text_1": "UNLOCALIZED: Fans facing down into a source of heat can provide Rotational Force", + "create.ponder.fan_source.text_2": "UNLOCALIZED: When given a Redstone Signal, the Fans will start providing power", + + "create.ponder.funnel_compat.header": "UNLOCALIZED: Funnel compatibility", + "create.ponder.funnel_compat.text_1": "UNLOCALIZED: Funnels should also interact nicely with a handful of other components.", + "create.ponder.funnel_compat.text_2": "UNLOCALIZED: Vertical Saws", + "create.ponder.funnel_compat.text_3": "UNLOCALIZED: Depots", + "create.ponder.funnel_compat.text_4": "UNLOCALIZED: Item Drains", + + "create.ponder.funnel_direction.header": "UNLOCALIZED: Direction of Transfer", + "create.ponder.funnel_direction.text_1": "UNLOCALIZED: Placed normally, it pulls items from the inventory.", + "create.ponder.funnel_direction.text_2": "UNLOCALIZED: Placed while sneaking, it puts items into the inventory.", + "create.ponder.funnel_direction.text_3": "UNLOCALIZED: Using a wrench, the funnel can be flipped after placement.", + "create.ponder.funnel_direction.text_4": "UNLOCALIZED: Same rules will apply for most orientations.", + "create.ponder.funnel_direction.text_5": "UNLOCALIZED: Funnels on belts will extract/insert depending on its movement direction.", + + "create.ponder.funnel_intro.header": "UNLOCALIZED: Using funnels", + "create.ponder.funnel_intro.text_1": "UNLOCALIZED: Funnels are ideal for transferring items from and to inventories.", + + "create.ponder.funnel_redstone.header": "UNLOCALIZED: Redstone control", + "create.ponder.funnel_redstone.text_1": "UNLOCALIZED: Redstone power will prevent any funnel from acting.", + + "create.ponder.funnel_transfer.header": "UNLOCALIZED: Direct transfer", + "create.ponder.funnel_transfer.text_1": "UNLOCALIZED: Funnels cannot ever transfer between closed inventories directly.", + "create.ponder.funnel_transfer.text_2": "UNLOCALIZED: Chutes or Smart chutes might be more suitable for such purposes.", + "create.ponder.funnel_transfer.text_3": "UNLOCALIZED: Same applies for horizontal movement.\nA mechanical belt should help here.", + + "create.ponder.gantry_carriage.header": "UNLOCALIZED: Using Gantry Carriages", + "create.ponder.gantry_carriage.text_1": "UNLOCALIZED: Gantry Carriages can mount to and slide along a Gantry Shaft.", + "create.ponder.gantry_carriage.text_2": "UNLOCALIZED: Gantry setups can move attached Blocks.", + + "create.ponder.gantry_cascaded.header": "UNLOCALIZED: Cascaded Gantries", + "create.ponder.gantry_cascaded.text_1": "UNLOCALIZED: Gantry shafts attach to a carriage without the need of super glue", + "create.ponder.gantry_cascaded.text_2": "UNLOCALIZED: Same applies for carriages on moved Gantry Shafts", + "create.ponder.gantry_cascaded.text_3": "UNLOCALIZED: Thus, a gantry system can be cascaded to cover multiple axes of movement", + + "create.ponder.gantry_direction.header": "UNLOCALIZED: Gantry Movement Direction", + "create.ponder.gantry_direction.text_1": "UNLOCALIZED: Gantry Shafts can have opposite orientations", + "create.ponder.gantry_direction.text_2": "UNLOCALIZED: The movement direction of carriages depend on their shafts' orientation", + "create.ponder.gantry_direction.text_3": "UNLOCALIZED: ...as well as the rotation direction of the shaft", + "create.ponder.gantry_direction.text_4": "UNLOCALIZED: Same rules apply for the propagated rotation", + + "create.ponder.gantry_redstone.header": "UNLOCALIZED: Gantry Power Propagation", + "create.ponder.gantry_redstone.text_1": "UNLOCALIZED: Redstone-powered gantry shafts stop moving their carriages", + "create.ponder.gantry_redstone.text_2": "UNLOCALIZED: Instead, its rotational force is relayed to the carriages' output shaft", + + "create.ponder.gantry_shaft.header": "UNLOCALIZED: Using Gantry Shafts", + "create.ponder.gantry_shaft.text_1": "UNLOCALIZED: Gantry Shafts form the basis of a gantry setup. Attached Carriages will move along them.", + "create.ponder.gantry_shaft.text_2": "UNLOCALIZED: Gantry setups can move attached Blocks.", + + "create.ponder.gearbox.header": "UNLOCALIZED: Relaying rotational force using Gearboxes", + "create.ponder.gearbox.text_1": "UNLOCALIZED: Jumping between axes of rotation can get bulky quickly", + "create.ponder.gearbox.text_2": "UNLOCALIZED: A gearbox is the more compact equivalent of this setup", + "create.ponder.gearbox.text_3": "UNLOCALIZED: Shafts around corners rotate in mirrored directions", + "create.ponder.gearbox.text_4": "UNLOCALIZED: Straight connections will be reversed", + + "create.ponder.gearshift.header": "UNLOCALIZED: Controlling rotational force using a Gearshift", + "create.ponder.gearshift.text_1": "UNLOCALIZED: Gearshifts will relay rotation in a straight line", + "create.ponder.gearshift.text_2": "UNLOCALIZED: When powered by Redstone, it reverses the transmission", + + "create.ponder.hand_crank.header": "UNLOCALIZED: Generating Rotational Force using Hand Cranks", + "create.ponder.hand_crank.text_1": "UNLOCALIZED: Hand Cranks can be used by players to apply rotational force manually", + "create.ponder.hand_crank.text_2": "UNLOCALIZED: Hold Right-Click to rotate it Counter-Clockwise", + "create.ponder.hand_crank.text_3": "UNLOCALIZED: Its conveyed speed is relatively high", + "create.ponder.hand_crank.text_4": "UNLOCALIZED: Sneak and Hold Right-Click to rotate it Clockwise", + + "create.ponder.large_cogwheel.header": "UNLOCALIZED: Relaying rotational force using Large Cogwheels", + "create.ponder.large_cogwheel.text_1": "UNLOCALIZED: Large cogwheels can connect to each other at right angles", + "create.ponder.large_cogwheel.text_2": "UNLOCALIZED: It will help relaying conveyed speed to other axes of rotation", + + "create.ponder.portable_storage_interface.header": "UNLOCALIZED: Contraption Storage Exchange", + "create.ponder.portable_storage_interface.text_1": "UNLOCALIZED: Inventories on moving contraptions cannot be accessed by players.", + "create.ponder.portable_storage_interface.text_2": "UNLOCALIZED: This component can interact with storage without the need to stop the contraption.", + "create.ponder.portable_storage_interface.text_3": "UNLOCALIZED: Place a second one with a gap of 1 or 2 blocks inbetween", + "create.ponder.portable_storage_interface.text_4": "UNLOCALIZED: Whenever they pass by each other, they will engage in a connection", + "create.ponder.portable_storage_interface.text_5": "UNLOCALIZED: While engaged, the stationary interface will represent ALL inventories on the contraption", + "create.ponder.portable_storage_interface.text_6": "UNLOCALIZED: Items can now be inserted...", + "create.ponder.portable_storage_interface.text_7": "UNLOCALIZED: ...or extracted from the contraption", + "create.ponder.portable_storage_interface.text_8": "UNLOCALIZED: After no items have been exchanged for a while, the contraption will continue on its way", + + "create.ponder.portable_storage_interface_redstone.header": "UNLOCALIZED: Redstone Control", + "create.ponder.portable_storage_interface_redstone.text_1": "UNLOCALIZED: Redstone power will prevent the stationary interface from engaging", + + "create.ponder.shaft.header": "UNLOCALIZED: Relaying rotational force using Shafts", + "create.ponder.shaft.text_1": "UNLOCALIZED: Shafts will relay rotation in a straight line.", + + "create.ponder.shaft_casing.header": "UNLOCALIZED: Encasing Shafts", + "create.ponder.shaft_casing.text_1": "UNLOCALIZED: Brass or Andesite Casing can be used to decorate Shafts", + + "create.ponder.valve_handle.header": "UNLOCALIZED: Generating Rotational Force using Valve Handles", + "create.ponder.valve_handle.text_1": "UNLOCALIZED: Valve Handles can be used by players to apply rotational force manually", + "create.ponder.valve_handle.text_2": "UNLOCALIZED: Hold Right-Click to rotate it Counter-Clockwise", + "create.ponder.valve_handle.text_3": "UNLOCALIZED: Its conveyed speed is slow and precise", + "create.ponder.valve_handle.text_4": "UNLOCALIZED: Sneak and Hold Right-Click to rotate it Clockwise", + "create.ponder.valve_handle.text_5": "UNLOCALIZED: Valve handles can be dyed for aesthetic purposes", + + "create.ponder.water_wheel.header": "UNLOCALIZED: Generating Rotational Force using Water Wheels", + "create.ponder.water_wheel.text_1": "UNLOCALIZED: Water Wheels draw force from adjacent Water Currents", + "create.ponder.water_wheel.text_2": "UNLOCALIZED: The more faces are powered, the faster the Water Wheel will rotate", + "create.ponder.water_wheel.text_3": "UNLOCALIZED: The Wheels' blades should be oriented against the flow", + "create.ponder.water_wheel.text_4": "UNLOCALIZED: Facing the opposite way, they will not be as effective", + "_": "Thank you for translating Create!" } \ No newline at end of file diff --git a/src/generated/resources/assets/create/lang/unfinished/ru_ru.json b/src/generated/resources/assets/create/lang/unfinished/ru_ru.json index 424e226e1..04fdb8e05 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ru_ru.json +++ b/src/generated/resources/assets/create/lang/unfinished/ru_ru.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 29", + "_": "Missing Localizations: 206", "_": "->------------------------] Game Elements [------------------------<-", @@ -162,7 +162,7 @@ "block.create.gabbro_cobblestone_stairs": "Ступени из габбро-булыжника", "block.create.gabbro_cobblestone_wall": "Стена из габбро-булыжника", "block.create.gabbro_pillar": "Габбро колонна", - "block.create.gantry_pinion": "UNLOCALIZED: Gantry Pinion", + "block.create.gantry_carriage": "UNLOCALIZED: Gantry Carriage", "block.create.gantry_shaft": "UNLOCALIZED: Gantry Shaft", "block.create.gearbox": "Коробка передач", "block.create.gearshift": "Реверсивный механизм", @@ -1809,6 +1809,221 @@ "create.tooltip.randomWipDescription7": "Этот, возможно, но не для тебя. Как насчет этого?", "create.tooltip.randomWipDescription8": "Используя его, вы немедленно пожалеете о своем решении.", + + "_": "->------------------------] Ponder Content [------------------------<-", + + "create.ponder.hold_to_ponder": "UNLOCALIZED: Hold [%1$s] to Ponder", + "create.ponder.subject": "UNLOCALIZED: Subject of this scene", + "create.ponder.pondering": "UNLOCALIZED: Pondering about...", + "create.ponder.identify_mode": "UNLOCALIZED: Identify mode active.\nUnpause with [%1$s]", + "create.ponder.associated": "UNLOCALIZED: Associated Entries", + "create.ponder.shared.movement_anchors": "UNLOCALIZED: With the help of Chassis or Super Glue, larger structures can be moved.", + "create.ponder.shared.rpm32": "UNLOCALIZED: 32 RPM", + "create.ponder.shared.sneak_and": "UNLOCALIZED: Sneak +", + "create.ponder.shared.rpm8": "UNLOCALIZED: 8 RPM", + "create.ponder.shared.ctrl_and": "UNLOCALIZED: Ctrl +", + "create.ponder.shared.rpm16_source": "UNLOCALIZED: Source: 16 RPM", + "create.ponder.shared.rpm16": "UNLOCALIZED: 16 RPM", + "create.ponder.tag.kinetic_sources": "UNLOCALIZED: Kinetic Sources", + "create.ponder.tag.kinetic_sources.description": "UNLOCALIZED: Components which generate Rotational Force", + "create.ponder.tag.contraption_actor": "UNLOCALIZED: Contraption Actors", + "create.ponder.tag.contraption_actor.description": "UNLOCALIZED: Components which expose special behaviour when attached to a moving contraption", + "create.ponder.tag.arm_targets": "UNLOCALIZED: Targets for Mechanical Arms", + "create.ponder.tag.arm_targets.description": "UNLOCALIZED: Components which can be selected as inputs or outputs to the Mechanical Arm", + "create.ponder.tag.logistics": "UNLOCALIZED: Item Transportation", + "create.ponder.tag.logistics.description": "UNLOCALIZED: Components which help moving items around", + "create.ponder.tag.movement_anchor": "UNLOCALIZED: Movement Anchors", + "create.ponder.tag.movement_anchor.description": "UNLOCALIZED: Components which allow the creation of moving contraptions, animating an attached structure in a variety of ways", + "create.ponder.tag.decoration": "UNLOCALIZED: Aesthetics", + "create.ponder.tag.decoration.description": "UNLOCALIZED: Components used mostly for decorative purposes", + "create.ponder.tag.kinetic_appliances": "UNLOCALIZED: Kinetic Appliances", + "create.ponder.tag.kinetic_appliances.description": "UNLOCALIZED: Components which make use of Rotational Force", + "create.ponder.tag.redstone": "UNLOCALIZED: Logic Components", + "create.ponder.tag.redstone.description": "UNLOCALIZED: Components which help with redstone engineering", + "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", + "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", + "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", + "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", + "create.ponder.tag.fluids": "UNLOCALIZED: Fluid Manipulators", + "create.ponder.tag.fluids.description": "UNLOCALIZED: Components which help relaying and making use of Fluids", + + "create.ponder.belt_casing.header": "UNLOCALIZED: Encasing Belts", + "create.ponder.belt_casing.text_1": "UNLOCALIZED: Brass or Andesite Casing can be used to decorate Mechanical Belts", + "create.ponder.belt_casing.text_2": "UNLOCALIZED: A wrench can be used to remove the casing", + + "create.ponder.belt_connector.header": "UNLOCALIZED: Using Mechanical Belts", + "create.ponder.belt_connector.text_1": "UNLOCALIZED: Right-Clicking two shafts with a belt item will connect them together", + "create.ponder.belt_connector.text_2": "UNLOCALIZED: Accidental selections can be canceled with Right-Click while Sneaking", + "create.ponder.belt_connector.text_3": "UNLOCALIZED: Additional Shafts can be added throughout the Belt", + "create.ponder.belt_connector.text_4": "UNLOCALIZED: Shafts connected via Belts will rotate with Identical Speed and Direction", + "create.ponder.belt_connector.text_5": "UNLOCALIZED: Added shafts can be removed using the wrench", + "create.ponder.belt_connector.text_6": "UNLOCALIZED: Mechanical Belts can be dyed for aesthetic purposes", + + "create.ponder.belt_directions.header": "UNLOCALIZED: Valid Orientations for Mechanical Belts", + "create.ponder.belt_directions.text_1": "UNLOCALIZED: Belts cannot connect in arbitrary directions", + "create.ponder.belt_directions.text_2": "UNLOCALIZED: 1. They can connect horizontally", + "create.ponder.belt_directions.text_3": "UNLOCALIZED: 2. They can connect diagonally", + "create.ponder.belt_directions.text_4": "UNLOCALIZED: 3. They can connect vertically", + "create.ponder.belt_directions.text_5": "UNLOCALIZED: 4. And they can connect vertical shafts horizontally", + "create.ponder.belt_directions.text_6": "UNLOCALIZED: These are all possible directions.\nBelts can span any Length between 2 and 20 blocks", + + "create.ponder.belt_transport.header": "UNLOCALIZED: Using Mechanical Belts for Logistics", + "create.ponder.belt_transport.text_1": "UNLOCALIZED: Moving belts will transport Items and other Entities", + "create.ponder.belt_transport.text_2": "UNLOCALIZED: Right-Click with an empty hand to take items off a belt", + + "create.ponder.brass_funnel.header": "UNLOCALIZED: The Brass Funnel", + "create.ponder.brass_funnel.text_1": "UNLOCALIZED: Andesite Funnels can only ever extract single items.", + "create.ponder.brass_funnel.text_2": "UNLOCALIZED: Brass Funnels can extract up to a full stack.", + "create.ponder.brass_funnel.text_3": "UNLOCALIZED: Scrolling on the filter slot allows for precise control over the extracted stack size.", + "create.ponder.brass_funnel.text_4": "UNLOCALIZED: Using items on the filter slot will restrict the funnel to only transfer matching stacks.", + + "create.ponder.chain_drive.header": "UNLOCALIZED: Relaying rotational force with Chain Drives", + "create.ponder.chain_drive.text_1": "UNLOCALIZED: Chain Drives relay rotation to each other in a row", + "create.ponder.chain_drive.text_2": "UNLOCALIZED: All shafts connected like this will rotate in the same direction", + "create.ponder.chain_drive.text_3": "UNLOCALIZED: Any part of the row can be rotated by 90 degrees", + + "create.ponder.chain_gearshift.header": "UNLOCALIZED: Controlling rotational speed with Chain Gearshifts", + "create.ponder.chain_gearshift.text_1": "UNLOCALIZED: Unpowered Chain Gearshifts behave exacly like Chain Drives", + "create.ponder.chain_gearshift.text_2": "UNLOCALIZED: When Powered, the speed transmitted to other Chain Drives in the row is doubled", + "create.ponder.chain_gearshift.text_3": "UNLOCALIZED: Whenever the Powered Gearshift is not at the source, its speed will be halved instead", + "create.ponder.chain_gearshift.text_4": "UNLOCALIZED: In both cases, Chain Drives in the row always run at 2x the speed of the Powered Gearshift", + "create.ponder.chain_gearshift.text_5": "UNLOCALIZED: Using analog signals, the ratio can be adjusted more precisely between 1 and 2", + "create.ponder.chain_gearshift.text_6": "UNLOCALIZED: 12 RPM", + + "create.ponder.clutch.header": "UNLOCALIZED: Controlling rotational force using a Clutch", + "create.ponder.clutch.text_1": "UNLOCALIZED: Clutches will relay rotation in a straight line", + "create.ponder.clutch.text_2": "UNLOCALIZED: When powered by Redstone, it breaks the connection", + + "create.ponder.cog_speedup.header": "UNLOCALIZED: Gearshifting with Cogs", + "create.ponder.cog_speedup.text_1": "UNLOCALIZED: Large and Small cogs can be connected diagonally", + "create.ponder.cog_speedup.text_2": "UNLOCALIZED: Shifting from large to small cogs, the conveyed speed will be doubled", + "create.ponder.cog_speedup.text_3": "UNLOCALIZED: Shifting the opposite way, the conveyed speed will be halved", + + "create.ponder.cogwheel.header": "UNLOCALIZED: Relaying rotational force using Cogwheels", + "create.ponder.cogwheel.text_1": "UNLOCALIZED: Cogwheels will relay rotation to other adjacent cogwheels", + "create.ponder.cogwheel.text_2": "UNLOCALIZED: Neighbouring shafts connected like this will rotate in opposite directions", + + "create.ponder.creative_motor.header": "UNLOCALIZED: Generating Rotational Force using Creative Motors", + "create.ponder.creative_motor.text_1": "UNLOCALIZED: Creative motors are a compact and configurable source of Rotational Force", + "create.ponder.creative_motor.text_2": "UNLOCALIZED: Scrolling on the back panel changes the RPM of the motors' rotational output", + + "create.ponder.fan_direction.header": "UNLOCALIZED: Air flow of Encased Fans", + "create.ponder.fan_direction.text_1": "UNLOCALIZED: Encased Fans use Rotational Force to create an Air Current", + "create.ponder.fan_direction.text_2": "UNLOCALIZED: Strength and Direction of Flow depends on the Rotational Input", + + "create.ponder.fan_processing.header": "UNLOCALIZED: Processing Items using Encased Fans", + "create.ponder.fan_processing.text_1": "UNLOCALIZED: When passing through lava, the Air Flow becomes Heated", + "create.ponder.fan_processing.text_2": "UNLOCALIZED: Items caught in the area will be smelted", + "create.ponder.fan_processing.text_3": "UNLOCALIZED: Food items thrown here would be incinerated", + "create.ponder.fan_processing.text_4": "UNLOCALIZED: Instead, a setup for Smoking using Fire should be used for them", + "create.ponder.fan_processing.text_5": "UNLOCALIZED: Air Flows passing through water create a Washing Setup", + "create.ponder.fan_processing.text_6": "UNLOCALIZED: Some interesting new processing can be done with it", + "create.ponder.fan_processing.text_7": "UNLOCALIZED: The Speed of the Fan does NOT affect the processing speed, only its range", + "create.ponder.fan_processing.text_8": "UNLOCALIZED: Fan Processing can also be applied to Items on Depots and Belts", + + "create.ponder.fan_source.header": "UNLOCALIZED: Generating Rotational Force using Encased Fans", + "create.ponder.fan_source.text_1": "UNLOCALIZED: Fans facing down into a source of heat can provide Rotational Force", + "create.ponder.fan_source.text_2": "UNLOCALIZED: When given a Redstone Signal, the Fans will start providing power", + + "create.ponder.funnel_compat.header": "UNLOCALIZED: Funnel compatibility", + "create.ponder.funnel_compat.text_1": "UNLOCALIZED: Funnels should also interact nicely with a handful of other components.", + "create.ponder.funnel_compat.text_2": "UNLOCALIZED: Vertical Saws", + "create.ponder.funnel_compat.text_3": "UNLOCALIZED: Depots", + "create.ponder.funnel_compat.text_4": "UNLOCALIZED: Item Drains", + + "create.ponder.funnel_direction.header": "UNLOCALIZED: Direction of Transfer", + "create.ponder.funnel_direction.text_1": "UNLOCALIZED: Placed normally, it pulls items from the inventory.", + "create.ponder.funnel_direction.text_2": "UNLOCALIZED: Placed while sneaking, it puts items into the inventory.", + "create.ponder.funnel_direction.text_3": "UNLOCALIZED: Using a wrench, the funnel can be flipped after placement.", + "create.ponder.funnel_direction.text_4": "UNLOCALIZED: Same rules will apply for most orientations.", + "create.ponder.funnel_direction.text_5": "UNLOCALIZED: Funnels on belts will extract/insert depending on its movement direction.", + + "create.ponder.funnel_intro.header": "UNLOCALIZED: Using funnels", + "create.ponder.funnel_intro.text_1": "UNLOCALIZED: Funnels are ideal for transferring items from and to inventories.", + + "create.ponder.funnel_redstone.header": "UNLOCALIZED: Redstone control", + "create.ponder.funnel_redstone.text_1": "UNLOCALIZED: Redstone power will prevent any funnel from acting.", + + "create.ponder.funnel_transfer.header": "UNLOCALIZED: Direct transfer", + "create.ponder.funnel_transfer.text_1": "UNLOCALIZED: Funnels cannot ever transfer between closed inventories directly.", + "create.ponder.funnel_transfer.text_2": "UNLOCALIZED: Chutes or Smart chutes might be more suitable for such purposes.", + "create.ponder.funnel_transfer.text_3": "UNLOCALIZED: Same applies for horizontal movement.\nA mechanical belt should help here.", + + "create.ponder.gantry_carriage.header": "UNLOCALIZED: Using Gantry Carriages", + "create.ponder.gantry_carriage.text_1": "UNLOCALIZED: Gantry Carriages can mount to and slide along a Gantry Shaft.", + "create.ponder.gantry_carriage.text_2": "UNLOCALIZED: Gantry setups can move attached Blocks.", + + "create.ponder.gantry_cascaded.header": "UNLOCALIZED: Cascaded Gantries", + "create.ponder.gantry_cascaded.text_1": "UNLOCALIZED: Gantry shafts attach to a carriage without the need of super glue", + "create.ponder.gantry_cascaded.text_2": "UNLOCALIZED: Same applies for carriages on moved Gantry Shafts", + "create.ponder.gantry_cascaded.text_3": "UNLOCALIZED: Thus, a gantry system can be cascaded to cover multiple axes of movement", + + "create.ponder.gantry_direction.header": "UNLOCALIZED: Gantry Movement Direction", + "create.ponder.gantry_direction.text_1": "UNLOCALIZED: Gantry Shafts can have opposite orientations", + "create.ponder.gantry_direction.text_2": "UNLOCALIZED: The movement direction of carriages depend on their shafts' orientation", + "create.ponder.gantry_direction.text_3": "UNLOCALIZED: ...as well as the rotation direction of the shaft", + "create.ponder.gantry_direction.text_4": "UNLOCALIZED: Same rules apply for the propagated rotation", + + "create.ponder.gantry_redstone.header": "UNLOCALIZED: Gantry Power Propagation", + "create.ponder.gantry_redstone.text_1": "UNLOCALIZED: Redstone-powered gantry shafts stop moving their carriages", + "create.ponder.gantry_redstone.text_2": "UNLOCALIZED: Instead, its rotational force is relayed to the carriages' output shaft", + + "create.ponder.gantry_shaft.header": "UNLOCALIZED: Using Gantry Shafts", + "create.ponder.gantry_shaft.text_1": "UNLOCALIZED: Gantry Shafts form the basis of a gantry setup. Attached Carriages will move along them.", + "create.ponder.gantry_shaft.text_2": "UNLOCALIZED: Gantry setups can move attached Blocks.", + + "create.ponder.gearbox.header": "UNLOCALIZED: Relaying rotational force using Gearboxes", + "create.ponder.gearbox.text_1": "UNLOCALIZED: Jumping between axes of rotation can get bulky quickly", + "create.ponder.gearbox.text_2": "UNLOCALIZED: A gearbox is the more compact equivalent of this setup", + "create.ponder.gearbox.text_3": "UNLOCALIZED: Shafts around corners rotate in mirrored directions", + "create.ponder.gearbox.text_4": "UNLOCALIZED: Straight connections will be reversed", + + "create.ponder.gearshift.header": "UNLOCALIZED: Controlling rotational force using a Gearshift", + "create.ponder.gearshift.text_1": "UNLOCALIZED: Gearshifts will relay rotation in a straight line", + "create.ponder.gearshift.text_2": "UNLOCALIZED: When powered by Redstone, it reverses the transmission", + + "create.ponder.hand_crank.header": "UNLOCALIZED: Generating Rotational Force using Hand Cranks", + "create.ponder.hand_crank.text_1": "UNLOCALIZED: Hand Cranks can be used by players to apply rotational force manually", + "create.ponder.hand_crank.text_2": "UNLOCALIZED: Hold Right-Click to rotate it Counter-Clockwise", + "create.ponder.hand_crank.text_3": "UNLOCALIZED: Its conveyed speed is relatively high", + "create.ponder.hand_crank.text_4": "UNLOCALIZED: Sneak and Hold Right-Click to rotate it Clockwise", + + "create.ponder.large_cogwheel.header": "UNLOCALIZED: Relaying rotational force using Large Cogwheels", + "create.ponder.large_cogwheel.text_1": "UNLOCALIZED: Large cogwheels can connect to each other at right angles", + "create.ponder.large_cogwheel.text_2": "UNLOCALIZED: It will help relaying conveyed speed to other axes of rotation", + + "create.ponder.portable_storage_interface.header": "UNLOCALIZED: Contraption Storage Exchange", + "create.ponder.portable_storage_interface.text_1": "UNLOCALIZED: Inventories on moving contraptions cannot be accessed by players.", + "create.ponder.portable_storage_interface.text_2": "UNLOCALIZED: This component can interact with storage without the need to stop the contraption.", + "create.ponder.portable_storage_interface.text_3": "UNLOCALIZED: Place a second one with a gap of 1 or 2 blocks inbetween", + "create.ponder.portable_storage_interface.text_4": "UNLOCALIZED: Whenever they pass by each other, they will engage in a connection", + "create.ponder.portable_storage_interface.text_5": "UNLOCALIZED: While engaged, the stationary interface will represent ALL inventories on the contraption", + "create.ponder.portable_storage_interface.text_6": "UNLOCALIZED: Items can now be inserted...", + "create.ponder.portable_storage_interface.text_7": "UNLOCALIZED: ...or extracted from the contraption", + "create.ponder.portable_storage_interface.text_8": "UNLOCALIZED: After no items have been exchanged for a while, the contraption will continue on its way", + + "create.ponder.portable_storage_interface_redstone.header": "UNLOCALIZED: Redstone Control", + "create.ponder.portable_storage_interface_redstone.text_1": "UNLOCALIZED: Redstone power will prevent the stationary interface from engaging", + + "create.ponder.shaft.header": "UNLOCALIZED: Relaying rotational force using Shafts", + "create.ponder.shaft.text_1": "UNLOCALIZED: Shafts will relay rotation in a straight line.", + + "create.ponder.shaft_casing.header": "UNLOCALIZED: Encasing Shafts", + "create.ponder.shaft_casing.text_1": "UNLOCALIZED: Brass or Andesite Casing can be used to decorate Shafts", + + "create.ponder.valve_handle.header": "UNLOCALIZED: Generating Rotational Force using Valve Handles", + "create.ponder.valve_handle.text_1": "UNLOCALIZED: Valve Handles can be used by players to apply rotational force manually", + "create.ponder.valve_handle.text_2": "UNLOCALIZED: Hold Right-Click to rotate it Counter-Clockwise", + "create.ponder.valve_handle.text_3": "UNLOCALIZED: Its conveyed speed is slow and precise", + "create.ponder.valve_handle.text_4": "UNLOCALIZED: Sneak and Hold Right-Click to rotate it Clockwise", + "create.ponder.valve_handle.text_5": "UNLOCALIZED: Valve handles can be dyed for aesthetic purposes", + + "create.ponder.water_wheel.header": "UNLOCALIZED: Generating Rotational Force using Water Wheels", + "create.ponder.water_wheel.text_1": "UNLOCALIZED: Water Wheels draw force from adjacent Water Currents", + "create.ponder.water_wheel.text_2": "UNLOCALIZED: The more faces are powered, the faster the Water Wheel will rotate", + "create.ponder.water_wheel.text_3": "UNLOCALIZED: The Wheels' blades should be oriented against the flow", + "create.ponder.water_wheel.text_4": "UNLOCALIZED: Facing the opposite way, they will not be as effective", + "_": "Thank you for translating Create!" } \ No newline at end of file diff --git a/src/generated/resources/assets/create/lang/unfinished/zh_cn.json b/src/generated/resources/assets/create/lang/unfinished/zh_cn.json index e384ec585..2d472fd71 100644 --- a/src/generated/resources/assets/create/lang/unfinished/zh_cn.json +++ b/src/generated/resources/assets/create/lang/unfinished/zh_cn.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 27", + "_": "Missing Localizations: 204", "_": "->------------------------] Game Elements [------------------------<-", @@ -162,7 +162,7 @@ "block.create.gabbro_cobblestone_stairs": "辉长岩圆石楼梯", "block.create.gabbro_cobblestone_wall": "辉长岩圆石墙", "block.create.gabbro_pillar": "竖纹辉长岩", - "block.create.gantry_pinion": "UNLOCALIZED: Gantry Pinion", + "block.create.gantry_carriage": "UNLOCALIZED: Gantry Carriage", "block.create.gantry_shaft": "UNLOCALIZED: Gantry Shaft", "block.create.gearbox": "十字齿轮箱", "block.create.gearshift": "反转齿轮箱", @@ -1809,6 +1809,221 @@ "create.tooltip.randomWipDescription7": "这玩意不是给你用的,换个吧", "create.tooltip.randomWipDescription8": "试试就逝世。", + + "_": "->------------------------] Ponder Content [------------------------<-", + + "create.ponder.hold_to_ponder": "UNLOCALIZED: Hold [%1$s] to Ponder", + "create.ponder.subject": "UNLOCALIZED: Subject of this scene", + "create.ponder.pondering": "UNLOCALIZED: Pondering about...", + "create.ponder.identify_mode": "UNLOCALIZED: Identify mode active.\nUnpause with [%1$s]", + "create.ponder.associated": "UNLOCALIZED: Associated Entries", + "create.ponder.shared.movement_anchors": "UNLOCALIZED: With the help of Chassis or Super Glue, larger structures can be moved.", + "create.ponder.shared.rpm32": "UNLOCALIZED: 32 RPM", + "create.ponder.shared.sneak_and": "UNLOCALIZED: Sneak +", + "create.ponder.shared.rpm8": "UNLOCALIZED: 8 RPM", + "create.ponder.shared.ctrl_and": "UNLOCALIZED: Ctrl +", + "create.ponder.shared.rpm16_source": "UNLOCALIZED: Source: 16 RPM", + "create.ponder.shared.rpm16": "UNLOCALIZED: 16 RPM", + "create.ponder.tag.kinetic_sources": "UNLOCALIZED: Kinetic Sources", + "create.ponder.tag.kinetic_sources.description": "UNLOCALIZED: Components which generate Rotational Force", + "create.ponder.tag.contraption_actor": "UNLOCALIZED: Contraption Actors", + "create.ponder.tag.contraption_actor.description": "UNLOCALIZED: Components which expose special behaviour when attached to a moving contraption", + "create.ponder.tag.arm_targets": "UNLOCALIZED: Targets for Mechanical Arms", + "create.ponder.tag.arm_targets.description": "UNLOCALIZED: Components which can be selected as inputs or outputs to the Mechanical Arm", + "create.ponder.tag.logistics": "UNLOCALIZED: Item Transportation", + "create.ponder.tag.logistics.description": "UNLOCALIZED: Components which help moving items around", + "create.ponder.tag.movement_anchor": "UNLOCALIZED: Movement Anchors", + "create.ponder.tag.movement_anchor.description": "UNLOCALIZED: Components which allow the creation of moving contraptions, animating an attached structure in a variety of ways", + "create.ponder.tag.decoration": "UNLOCALIZED: Aesthetics", + "create.ponder.tag.decoration.description": "UNLOCALIZED: Components used mostly for decorative purposes", + "create.ponder.tag.kinetic_appliances": "UNLOCALIZED: Kinetic Appliances", + "create.ponder.tag.kinetic_appliances.description": "UNLOCALIZED: Components which make use of Rotational Force", + "create.ponder.tag.redstone": "UNLOCALIZED: Logic Components", + "create.ponder.tag.redstone.description": "UNLOCALIZED: Components which help with redstone engineering", + "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", + "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", + "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", + "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", + "create.ponder.tag.fluids": "UNLOCALIZED: Fluid Manipulators", + "create.ponder.tag.fluids.description": "UNLOCALIZED: Components which help relaying and making use of Fluids", + + "create.ponder.belt_casing.header": "UNLOCALIZED: Encasing Belts", + "create.ponder.belt_casing.text_1": "UNLOCALIZED: Brass or Andesite Casing can be used to decorate Mechanical Belts", + "create.ponder.belt_casing.text_2": "UNLOCALIZED: A wrench can be used to remove the casing", + + "create.ponder.belt_connector.header": "UNLOCALIZED: Using Mechanical Belts", + "create.ponder.belt_connector.text_1": "UNLOCALIZED: Right-Clicking two shafts with a belt item will connect them together", + "create.ponder.belt_connector.text_2": "UNLOCALIZED: Accidental selections can be canceled with Right-Click while Sneaking", + "create.ponder.belt_connector.text_3": "UNLOCALIZED: Additional Shafts can be added throughout the Belt", + "create.ponder.belt_connector.text_4": "UNLOCALIZED: Shafts connected via Belts will rotate with Identical Speed and Direction", + "create.ponder.belt_connector.text_5": "UNLOCALIZED: Added shafts can be removed using the wrench", + "create.ponder.belt_connector.text_6": "UNLOCALIZED: Mechanical Belts can be dyed for aesthetic purposes", + + "create.ponder.belt_directions.header": "UNLOCALIZED: Valid Orientations for Mechanical Belts", + "create.ponder.belt_directions.text_1": "UNLOCALIZED: Belts cannot connect in arbitrary directions", + "create.ponder.belt_directions.text_2": "UNLOCALIZED: 1. They can connect horizontally", + "create.ponder.belt_directions.text_3": "UNLOCALIZED: 2. They can connect diagonally", + "create.ponder.belt_directions.text_4": "UNLOCALIZED: 3. They can connect vertically", + "create.ponder.belt_directions.text_5": "UNLOCALIZED: 4. And they can connect vertical shafts horizontally", + "create.ponder.belt_directions.text_6": "UNLOCALIZED: These are all possible directions.\nBelts can span any Length between 2 and 20 blocks", + + "create.ponder.belt_transport.header": "UNLOCALIZED: Using Mechanical Belts for Logistics", + "create.ponder.belt_transport.text_1": "UNLOCALIZED: Moving belts will transport Items and other Entities", + "create.ponder.belt_transport.text_2": "UNLOCALIZED: Right-Click with an empty hand to take items off a belt", + + "create.ponder.brass_funnel.header": "UNLOCALIZED: The Brass Funnel", + "create.ponder.brass_funnel.text_1": "UNLOCALIZED: Andesite Funnels can only ever extract single items.", + "create.ponder.brass_funnel.text_2": "UNLOCALIZED: Brass Funnels can extract up to a full stack.", + "create.ponder.brass_funnel.text_3": "UNLOCALIZED: Scrolling on the filter slot allows for precise control over the extracted stack size.", + "create.ponder.brass_funnel.text_4": "UNLOCALIZED: Using items on the filter slot will restrict the funnel to only transfer matching stacks.", + + "create.ponder.chain_drive.header": "UNLOCALIZED: Relaying rotational force with Chain Drives", + "create.ponder.chain_drive.text_1": "UNLOCALIZED: Chain Drives relay rotation to each other in a row", + "create.ponder.chain_drive.text_2": "UNLOCALIZED: All shafts connected like this will rotate in the same direction", + "create.ponder.chain_drive.text_3": "UNLOCALIZED: Any part of the row can be rotated by 90 degrees", + + "create.ponder.chain_gearshift.header": "UNLOCALIZED: Controlling rotational speed with Chain Gearshifts", + "create.ponder.chain_gearshift.text_1": "UNLOCALIZED: Unpowered Chain Gearshifts behave exacly like Chain Drives", + "create.ponder.chain_gearshift.text_2": "UNLOCALIZED: When Powered, the speed transmitted to other Chain Drives in the row is doubled", + "create.ponder.chain_gearshift.text_3": "UNLOCALIZED: Whenever the Powered Gearshift is not at the source, its speed will be halved instead", + "create.ponder.chain_gearshift.text_4": "UNLOCALIZED: In both cases, Chain Drives in the row always run at 2x the speed of the Powered Gearshift", + "create.ponder.chain_gearshift.text_5": "UNLOCALIZED: Using analog signals, the ratio can be adjusted more precisely between 1 and 2", + "create.ponder.chain_gearshift.text_6": "UNLOCALIZED: 12 RPM", + + "create.ponder.clutch.header": "UNLOCALIZED: Controlling rotational force using a Clutch", + "create.ponder.clutch.text_1": "UNLOCALIZED: Clutches will relay rotation in a straight line", + "create.ponder.clutch.text_2": "UNLOCALIZED: When powered by Redstone, it breaks the connection", + + "create.ponder.cog_speedup.header": "UNLOCALIZED: Gearshifting with Cogs", + "create.ponder.cog_speedup.text_1": "UNLOCALIZED: Large and Small cogs can be connected diagonally", + "create.ponder.cog_speedup.text_2": "UNLOCALIZED: Shifting from large to small cogs, the conveyed speed will be doubled", + "create.ponder.cog_speedup.text_3": "UNLOCALIZED: Shifting the opposite way, the conveyed speed will be halved", + + "create.ponder.cogwheel.header": "UNLOCALIZED: Relaying rotational force using Cogwheels", + "create.ponder.cogwheel.text_1": "UNLOCALIZED: Cogwheels will relay rotation to other adjacent cogwheels", + "create.ponder.cogwheel.text_2": "UNLOCALIZED: Neighbouring shafts connected like this will rotate in opposite directions", + + "create.ponder.creative_motor.header": "UNLOCALIZED: Generating Rotational Force using Creative Motors", + "create.ponder.creative_motor.text_1": "UNLOCALIZED: Creative motors are a compact and configurable source of Rotational Force", + "create.ponder.creative_motor.text_2": "UNLOCALIZED: Scrolling on the back panel changes the RPM of the motors' rotational output", + + "create.ponder.fan_direction.header": "UNLOCALIZED: Air flow of Encased Fans", + "create.ponder.fan_direction.text_1": "UNLOCALIZED: Encased Fans use Rotational Force to create an Air Current", + "create.ponder.fan_direction.text_2": "UNLOCALIZED: Strength and Direction of Flow depends on the Rotational Input", + + "create.ponder.fan_processing.header": "UNLOCALIZED: Processing Items using Encased Fans", + "create.ponder.fan_processing.text_1": "UNLOCALIZED: When passing through lava, the Air Flow becomes Heated", + "create.ponder.fan_processing.text_2": "UNLOCALIZED: Items caught in the area will be smelted", + "create.ponder.fan_processing.text_3": "UNLOCALIZED: Food items thrown here would be incinerated", + "create.ponder.fan_processing.text_4": "UNLOCALIZED: Instead, a setup for Smoking using Fire should be used for them", + "create.ponder.fan_processing.text_5": "UNLOCALIZED: Air Flows passing through water create a Washing Setup", + "create.ponder.fan_processing.text_6": "UNLOCALIZED: Some interesting new processing can be done with it", + "create.ponder.fan_processing.text_7": "UNLOCALIZED: The Speed of the Fan does NOT affect the processing speed, only its range", + "create.ponder.fan_processing.text_8": "UNLOCALIZED: Fan Processing can also be applied to Items on Depots and Belts", + + "create.ponder.fan_source.header": "UNLOCALIZED: Generating Rotational Force using Encased Fans", + "create.ponder.fan_source.text_1": "UNLOCALIZED: Fans facing down into a source of heat can provide Rotational Force", + "create.ponder.fan_source.text_2": "UNLOCALIZED: When given a Redstone Signal, the Fans will start providing power", + + "create.ponder.funnel_compat.header": "UNLOCALIZED: Funnel compatibility", + "create.ponder.funnel_compat.text_1": "UNLOCALIZED: Funnels should also interact nicely with a handful of other components.", + "create.ponder.funnel_compat.text_2": "UNLOCALIZED: Vertical Saws", + "create.ponder.funnel_compat.text_3": "UNLOCALIZED: Depots", + "create.ponder.funnel_compat.text_4": "UNLOCALIZED: Item Drains", + + "create.ponder.funnel_direction.header": "UNLOCALIZED: Direction of Transfer", + "create.ponder.funnel_direction.text_1": "UNLOCALIZED: Placed normally, it pulls items from the inventory.", + "create.ponder.funnel_direction.text_2": "UNLOCALIZED: Placed while sneaking, it puts items into the inventory.", + "create.ponder.funnel_direction.text_3": "UNLOCALIZED: Using a wrench, the funnel can be flipped after placement.", + "create.ponder.funnel_direction.text_4": "UNLOCALIZED: Same rules will apply for most orientations.", + "create.ponder.funnel_direction.text_5": "UNLOCALIZED: Funnels on belts will extract/insert depending on its movement direction.", + + "create.ponder.funnel_intro.header": "UNLOCALIZED: Using funnels", + "create.ponder.funnel_intro.text_1": "UNLOCALIZED: Funnels are ideal for transferring items from and to inventories.", + + "create.ponder.funnel_redstone.header": "UNLOCALIZED: Redstone control", + "create.ponder.funnel_redstone.text_1": "UNLOCALIZED: Redstone power will prevent any funnel from acting.", + + "create.ponder.funnel_transfer.header": "UNLOCALIZED: Direct transfer", + "create.ponder.funnel_transfer.text_1": "UNLOCALIZED: Funnels cannot ever transfer between closed inventories directly.", + "create.ponder.funnel_transfer.text_2": "UNLOCALIZED: Chutes or Smart chutes might be more suitable for such purposes.", + "create.ponder.funnel_transfer.text_3": "UNLOCALIZED: Same applies for horizontal movement.\nA mechanical belt should help here.", + + "create.ponder.gantry_carriage.header": "UNLOCALIZED: Using Gantry Carriages", + "create.ponder.gantry_carriage.text_1": "UNLOCALIZED: Gantry Carriages can mount to and slide along a Gantry Shaft.", + "create.ponder.gantry_carriage.text_2": "UNLOCALIZED: Gantry setups can move attached Blocks.", + + "create.ponder.gantry_cascaded.header": "UNLOCALIZED: Cascaded Gantries", + "create.ponder.gantry_cascaded.text_1": "UNLOCALIZED: Gantry shafts attach to a carriage without the need of super glue", + "create.ponder.gantry_cascaded.text_2": "UNLOCALIZED: Same applies for carriages on moved Gantry Shafts", + "create.ponder.gantry_cascaded.text_3": "UNLOCALIZED: Thus, a gantry system can be cascaded to cover multiple axes of movement", + + "create.ponder.gantry_direction.header": "UNLOCALIZED: Gantry Movement Direction", + "create.ponder.gantry_direction.text_1": "UNLOCALIZED: Gantry Shafts can have opposite orientations", + "create.ponder.gantry_direction.text_2": "UNLOCALIZED: The movement direction of carriages depend on their shafts' orientation", + "create.ponder.gantry_direction.text_3": "UNLOCALIZED: ...as well as the rotation direction of the shaft", + "create.ponder.gantry_direction.text_4": "UNLOCALIZED: Same rules apply for the propagated rotation", + + "create.ponder.gantry_redstone.header": "UNLOCALIZED: Gantry Power Propagation", + "create.ponder.gantry_redstone.text_1": "UNLOCALIZED: Redstone-powered gantry shafts stop moving their carriages", + "create.ponder.gantry_redstone.text_2": "UNLOCALIZED: Instead, its rotational force is relayed to the carriages' output shaft", + + "create.ponder.gantry_shaft.header": "UNLOCALIZED: Using Gantry Shafts", + "create.ponder.gantry_shaft.text_1": "UNLOCALIZED: Gantry Shafts form the basis of a gantry setup. Attached Carriages will move along them.", + "create.ponder.gantry_shaft.text_2": "UNLOCALIZED: Gantry setups can move attached Blocks.", + + "create.ponder.gearbox.header": "UNLOCALIZED: Relaying rotational force using Gearboxes", + "create.ponder.gearbox.text_1": "UNLOCALIZED: Jumping between axes of rotation can get bulky quickly", + "create.ponder.gearbox.text_2": "UNLOCALIZED: A gearbox is the more compact equivalent of this setup", + "create.ponder.gearbox.text_3": "UNLOCALIZED: Shafts around corners rotate in mirrored directions", + "create.ponder.gearbox.text_4": "UNLOCALIZED: Straight connections will be reversed", + + "create.ponder.gearshift.header": "UNLOCALIZED: Controlling rotational force using a Gearshift", + "create.ponder.gearshift.text_1": "UNLOCALIZED: Gearshifts will relay rotation in a straight line", + "create.ponder.gearshift.text_2": "UNLOCALIZED: When powered by Redstone, it reverses the transmission", + + "create.ponder.hand_crank.header": "UNLOCALIZED: Generating Rotational Force using Hand Cranks", + "create.ponder.hand_crank.text_1": "UNLOCALIZED: Hand Cranks can be used by players to apply rotational force manually", + "create.ponder.hand_crank.text_2": "UNLOCALIZED: Hold Right-Click to rotate it Counter-Clockwise", + "create.ponder.hand_crank.text_3": "UNLOCALIZED: Its conveyed speed is relatively high", + "create.ponder.hand_crank.text_4": "UNLOCALIZED: Sneak and Hold Right-Click to rotate it Clockwise", + + "create.ponder.large_cogwheel.header": "UNLOCALIZED: Relaying rotational force using Large Cogwheels", + "create.ponder.large_cogwheel.text_1": "UNLOCALIZED: Large cogwheels can connect to each other at right angles", + "create.ponder.large_cogwheel.text_2": "UNLOCALIZED: It will help relaying conveyed speed to other axes of rotation", + + "create.ponder.portable_storage_interface.header": "UNLOCALIZED: Contraption Storage Exchange", + "create.ponder.portable_storage_interface.text_1": "UNLOCALIZED: Inventories on moving contraptions cannot be accessed by players.", + "create.ponder.portable_storage_interface.text_2": "UNLOCALIZED: This component can interact with storage without the need to stop the contraption.", + "create.ponder.portable_storage_interface.text_3": "UNLOCALIZED: Place a second one with a gap of 1 or 2 blocks inbetween", + "create.ponder.portable_storage_interface.text_4": "UNLOCALIZED: Whenever they pass by each other, they will engage in a connection", + "create.ponder.portable_storage_interface.text_5": "UNLOCALIZED: While engaged, the stationary interface will represent ALL inventories on the contraption", + "create.ponder.portable_storage_interface.text_6": "UNLOCALIZED: Items can now be inserted...", + "create.ponder.portable_storage_interface.text_7": "UNLOCALIZED: ...or extracted from the contraption", + "create.ponder.portable_storage_interface.text_8": "UNLOCALIZED: After no items have been exchanged for a while, the contraption will continue on its way", + + "create.ponder.portable_storage_interface_redstone.header": "UNLOCALIZED: Redstone Control", + "create.ponder.portable_storage_interface_redstone.text_1": "UNLOCALIZED: Redstone power will prevent the stationary interface from engaging", + + "create.ponder.shaft.header": "UNLOCALIZED: Relaying rotational force using Shafts", + "create.ponder.shaft.text_1": "UNLOCALIZED: Shafts will relay rotation in a straight line.", + + "create.ponder.shaft_casing.header": "UNLOCALIZED: Encasing Shafts", + "create.ponder.shaft_casing.text_1": "UNLOCALIZED: Brass or Andesite Casing can be used to decorate Shafts", + + "create.ponder.valve_handle.header": "UNLOCALIZED: Generating Rotational Force using Valve Handles", + "create.ponder.valve_handle.text_1": "UNLOCALIZED: Valve Handles can be used by players to apply rotational force manually", + "create.ponder.valve_handle.text_2": "UNLOCALIZED: Hold Right-Click to rotate it Counter-Clockwise", + "create.ponder.valve_handle.text_3": "UNLOCALIZED: Its conveyed speed is slow and precise", + "create.ponder.valve_handle.text_4": "UNLOCALIZED: Sneak and Hold Right-Click to rotate it Clockwise", + "create.ponder.valve_handle.text_5": "UNLOCALIZED: Valve handles can be dyed for aesthetic purposes", + + "create.ponder.water_wheel.header": "UNLOCALIZED: Generating Rotational Force using Water Wheels", + "create.ponder.water_wheel.text_1": "UNLOCALIZED: Water Wheels draw force from adjacent Water Currents", + "create.ponder.water_wheel.text_2": "UNLOCALIZED: The more faces are powered, the faster the Water Wheel will rotate", + "create.ponder.water_wheel.text_3": "UNLOCALIZED: The Wheels' blades should be oriented against the flow", + "create.ponder.water_wheel.text_4": "UNLOCALIZED: Facing the opposite way, they will not be as effective", + "_": "Thank you for translating Create!" } \ No newline at end of file diff --git a/src/generated/resources/assets/create/lang/unfinished/zh_tw.json b/src/generated/resources/assets/create/lang/unfinished/zh_tw.json index 9e55235fa..f18894ed3 100644 --- a/src/generated/resources/assets/create/lang/unfinished/zh_tw.json +++ b/src/generated/resources/assets/create/lang/unfinished/zh_tw.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 32", + "_": "Missing Localizations: 209", "_": "->------------------------] Game Elements [------------------------<-", @@ -162,7 +162,7 @@ "block.create.gabbro_cobblestone_stairs": "碎輝長岩樓梯", "block.create.gabbro_cobblestone_wall": "碎輝長岩牆", "block.create.gabbro_pillar": "豎紋輝長岩", - "block.create.gantry_pinion": "UNLOCALIZED: Gantry Pinion", + "block.create.gantry_carriage": "UNLOCALIZED: Gantry Carriage", "block.create.gantry_shaft": "UNLOCALIZED: Gantry Shaft", "block.create.gearbox": "齒輪箱", "block.create.gearshift": "變速箱", @@ -1809,6 +1809,221 @@ "create.tooltip.randomWipDescription7": "這東西不是給你用的,再找找吧!", "create.tooltip.randomWipDescription8": "用了就死定了。", + + "_": "->------------------------] Ponder Content [------------------------<-", + + "create.ponder.hold_to_ponder": "UNLOCALIZED: Hold [%1$s] to Ponder", + "create.ponder.subject": "UNLOCALIZED: Subject of this scene", + "create.ponder.pondering": "UNLOCALIZED: Pondering about...", + "create.ponder.identify_mode": "UNLOCALIZED: Identify mode active.\nUnpause with [%1$s]", + "create.ponder.associated": "UNLOCALIZED: Associated Entries", + "create.ponder.shared.movement_anchors": "UNLOCALIZED: With the help of Chassis or Super Glue, larger structures can be moved.", + "create.ponder.shared.rpm32": "UNLOCALIZED: 32 RPM", + "create.ponder.shared.sneak_and": "UNLOCALIZED: Sneak +", + "create.ponder.shared.rpm8": "UNLOCALIZED: 8 RPM", + "create.ponder.shared.ctrl_and": "UNLOCALIZED: Ctrl +", + "create.ponder.shared.rpm16_source": "UNLOCALIZED: Source: 16 RPM", + "create.ponder.shared.rpm16": "UNLOCALIZED: 16 RPM", + "create.ponder.tag.kinetic_sources": "UNLOCALIZED: Kinetic Sources", + "create.ponder.tag.kinetic_sources.description": "UNLOCALIZED: Components which generate Rotational Force", + "create.ponder.tag.contraption_actor": "UNLOCALIZED: Contraption Actors", + "create.ponder.tag.contraption_actor.description": "UNLOCALIZED: Components which expose special behaviour when attached to a moving contraption", + "create.ponder.tag.arm_targets": "UNLOCALIZED: Targets for Mechanical Arms", + "create.ponder.tag.arm_targets.description": "UNLOCALIZED: Components which can be selected as inputs or outputs to the Mechanical Arm", + "create.ponder.tag.logistics": "UNLOCALIZED: Item Transportation", + "create.ponder.tag.logistics.description": "UNLOCALIZED: Components which help moving items around", + "create.ponder.tag.movement_anchor": "UNLOCALIZED: Movement Anchors", + "create.ponder.tag.movement_anchor.description": "UNLOCALIZED: Components which allow the creation of moving contraptions, animating an attached structure in a variety of ways", + "create.ponder.tag.decoration": "UNLOCALIZED: Aesthetics", + "create.ponder.tag.decoration.description": "UNLOCALIZED: Components used mostly for decorative purposes", + "create.ponder.tag.kinetic_appliances": "UNLOCALIZED: Kinetic Appliances", + "create.ponder.tag.kinetic_appliances.description": "UNLOCALIZED: Components which make use of Rotational Force", + "create.ponder.tag.redstone": "UNLOCALIZED: Logic Components", + "create.ponder.tag.redstone.description": "UNLOCALIZED: Components which help with redstone engineering", + "create.ponder.tag.creative": "UNLOCALIZED: Creative Mode", + "create.ponder.tag.creative.description": "UNLOCALIZED: Components not usually available for Survival Mode", + "create.ponder.tag.kinetic_relays": "UNLOCALIZED: Kinetic Blocks", + "create.ponder.tag.kinetic_relays.description": "UNLOCALIZED: Components which help relaying Rotational Force elsewhere", + "create.ponder.tag.fluids": "UNLOCALIZED: Fluid Manipulators", + "create.ponder.tag.fluids.description": "UNLOCALIZED: Components which help relaying and making use of Fluids", + + "create.ponder.belt_casing.header": "UNLOCALIZED: Encasing Belts", + "create.ponder.belt_casing.text_1": "UNLOCALIZED: Brass or Andesite Casing can be used to decorate Mechanical Belts", + "create.ponder.belt_casing.text_2": "UNLOCALIZED: A wrench can be used to remove the casing", + + "create.ponder.belt_connector.header": "UNLOCALIZED: Using Mechanical Belts", + "create.ponder.belt_connector.text_1": "UNLOCALIZED: Right-Clicking two shafts with a belt item will connect them together", + "create.ponder.belt_connector.text_2": "UNLOCALIZED: Accidental selections can be canceled with Right-Click while Sneaking", + "create.ponder.belt_connector.text_3": "UNLOCALIZED: Additional Shafts can be added throughout the Belt", + "create.ponder.belt_connector.text_4": "UNLOCALIZED: Shafts connected via Belts will rotate with Identical Speed and Direction", + "create.ponder.belt_connector.text_5": "UNLOCALIZED: Added shafts can be removed using the wrench", + "create.ponder.belt_connector.text_6": "UNLOCALIZED: Mechanical Belts can be dyed for aesthetic purposes", + + "create.ponder.belt_directions.header": "UNLOCALIZED: Valid Orientations for Mechanical Belts", + "create.ponder.belt_directions.text_1": "UNLOCALIZED: Belts cannot connect in arbitrary directions", + "create.ponder.belt_directions.text_2": "UNLOCALIZED: 1. They can connect horizontally", + "create.ponder.belt_directions.text_3": "UNLOCALIZED: 2. They can connect diagonally", + "create.ponder.belt_directions.text_4": "UNLOCALIZED: 3. They can connect vertically", + "create.ponder.belt_directions.text_5": "UNLOCALIZED: 4. And they can connect vertical shafts horizontally", + "create.ponder.belt_directions.text_6": "UNLOCALIZED: These are all possible directions.\nBelts can span any Length between 2 and 20 blocks", + + "create.ponder.belt_transport.header": "UNLOCALIZED: Using Mechanical Belts for Logistics", + "create.ponder.belt_transport.text_1": "UNLOCALIZED: Moving belts will transport Items and other Entities", + "create.ponder.belt_transport.text_2": "UNLOCALIZED: Right-Click with an empty hand to take items off a belt", + + "create.ponder.brass_funnel.header": "UNLOCALIZED: The Brass Funnel", + "create.ponder.brass_funnel.text_1": "UNLOCALIZED: Andesite Funnels can only ever extract single items.", + "create.ponder.brass_funnel.text_2": "UNLOCALIZED: Brass Funnels can extract up to a full stack.", + "create.ponder.brass_funnel.text_3": "UNLOCALIZED: Scrolling on the filter slot allows for precise control over the extracted stack size.", + "create.ponder.brass_funnel.text_4": "UNLOCALIZED: Using items on the filter slot will restrict the funnel to only transfer matching stacks.", + + "create.ponder.chain_drive.header": "UNLOCALIZED: Relaying rotational force with Chain Drives", + "create.ponder.chain_drive.text_1": "UNLOCALIZED: Chain Drives relay rotation to each other in a row", + "create.ponder.chain_drive.text_2": "UNLOCALIZED: All shafts connected like this will rotate in the same direction", + "create.ponder.chain_drive.text_3": "UNLOCALIZED: Any part of the row can be rotated by 90 degrees", + + "create.ponder.chain_gearshift.header": "UNLOCALIZED: Controlling rotational speed with Chain Gearshifts", + "create.ponder.chain_gearshift.text_1": "UNLOCALIZED: Unpowered Chain Gearshifts behave exacly like Chain Drives", + "create.ponder.chain_gearshift.text_2": "UNLOCALIZED: When Powered, the speed transmitted to other Chain Drives in the row is doubled", + "create.ponder.chain_gearshift.text_3": "UNLOCALIZED: Whenever the Powered Gearshift is not at the source, its speed will be halved instead", + "create.ponder.chain_gearshift.text_4": "UNLOCALIZED: In both cases, Chain Drives in the row always run at 2x the speed of the Powered Gearshift", + "create.ponder.chain_gearshift.text_5": "UNLOCALIZED: Using analog signals, the ratio can be adjusted more precisely between 1 and 2", + "create.ponder.chain_gearshift.text_6": "UNLOCALIZED: 12 RPM", + + "create.ponder.clutch.header": "UNLOCALIZED: Controlling rotational force using a Clutch", + "create.ponder.clutch.text_1": "UNLOCALIZED: Clutches will relay rotation in a straight line", + "create.ponder.clutch.text_2": "UNLOCALIZED: When powered by Redstone, it breaks the connection", + + "create.ponder.cog_speedup.header": "UNLOCALIZED: Gearshifting with Cogs", + "create.ponder.cog_speedup.text_1": "UNLOCALIZED: Large and Small cogs can be connected diagonally", + "create.ponder.cog_speedup.text_2": "UNLOCALIZED: Shifting from large to small cogs, the conveyed speed will be doubled", + "create.ponder.cog_speedup.text_3": "UNLOCALIZED: Shifting the opposite way, the conveyed speed will be halved", + + "create.ponder.cogwheel.header": "UNLOCALIZED: Relaying rotational force using Cogwheels", + "create.ponder.cogwheel.text_1": "UNLOCALIZED: Cogwheels will relay rotation to other adjacent cogwheels", + "create.ponder.cogwheel.text_2": "UNLOCALIZED: Neighbouring shafts connected like this will rotate in opposite directions", + + "create.ponder.creative_motor.header": "UNLOCALIZED: Generating Rotational Force using Creative Motors", + "create.ponder.creative_motor.text_1": "UNLOCALIZED: Creative motors are a compact and configurable source of Rotational Force", + "create.ponder.creative_motor.text_2": "UNLOCALIZED: Scrolling on the back panel changes the RPM of the motors' rotational output", + + "create.ponder.fan_direction.header": "UNLOCALIZED: Air flow of Encased Fans", + "create.ponder.fan_direction.text_1": "UNLOCALIZED: Encased Fans use Rotational Force to create an Air Current", + "create.ponder.fan_direction.text_2": "UNLOCALIZED: Strength and Direction of Flow depends on the Rotational Input", + + "create.ponder.fan_processing.header": "UNLOCALIZED: Processing Items using Encased Fans", + "create.ponder.fan_processing.text_1": "UNLOCALIZED: When passing through lava, the Air Flow becomes Heated", + "create.ponder.fan_processing.text_2": "UNLOCALIZED: Items caught in the area will be smelted", + "create.ponder.fan_processing.text_3": "UNLOCALIZED: Food items thrown here would be incinerated", + "create.ponder.fan_processing.text_4": "UNLOCALIZED: Instead, a setup for Smoking using Fire should be used for them", + "create.ponder.fan_processing.text_5": "UNLOCALIZED: Air Flows passing through water create a Washing Setup", + "create.ponder.fan_processing.text_6": "UNLOCALIZED: Some interesting new processing can be done with it", + "create.ponder.fan_processing.text_7": "UNLOCALIZED: The Speed of the Fan does NOT affect the processing speed, only its range", + "create.ponder.fan_processing.text_8": "UNLOCALIZED: Fan Processing can also be applied to Items on Depots and Belts", + + "create.ponder.fan_source.header": "UNLOCALIZED: Generating Rotational Force using Encased Fans", + "create.ponder.fan_source.text_1": "UNLOCALIZED: Fans facing down into a source of heat can provide Rotational Force", + "create.ponder.fan_source.text_2": "UNLOCALIZED: When given a Redstone Signal, the Fans will start providing power", + + "create.ponder.funnel_compat.header": "UNLOCALIZED: Funnel compatibility", + "create.ponder.funnel_compat.text_1": "UNLOCALIZED: Funnels should also interact nicely with a handful of other components.", + "create.ponder.funnel_compat.text_2": "UNLOCALIZED: Vertical Saws", + "create.ponder.funnel_compat.text_3": "UNLOCALIZED: Depots", + "create.ponder.funnel_compat.text_4": "UNLOCALIZED: Item Drains", + + "create.ponder.funnel_direction.header": "UNLOCALIZED: Direction of Transfer", + "create.ponder.funnel_direction.text_1": "UNLOCALIZED: Placed normally, it pulls items from the inventory.", + "create.ponder.funnel_direction.text_2": "UNLOCALIZED: Placed while sneaking, it puts items into the inventory.", + "create.ponder.funnel_direction.text_3": "UNLOCALIZED: Using a wrench, the funnel can be flipped after placement.", + "create.ponder.funnel_direction.text_4": "UNLOCALIZED: Same rules will apply for most orientations.", + "create.ponder.funnel_direction.text_5": "UNLOCALIZED: Funnels on belts will extract/insert depending on its movement direction.", + + "create.ponder.funnel_intro.header": "UNLOCALIZED: Using funnels", + "create.ponder.funnel_intro.text_1": "UNLOCALIZED: Funnels are ideal for transferring items from and to inventories.", + + "create.ponder.funnel_redstone.header": "UNLOCALIZED: Redstone control", + "create.ponder.funnel_redstone.text_1": "UNLOCALIZED: Redstone power will prevent any funnel from acting.", + + "create.ponder.funnel_transfer.header": "UNLOCALIZED: Direct transfer", + "create.ponder.funnel_transfer.text_1": "UNLOCALIZED: Funnels cannot ever transfer between closed inventories directly.", + "create.ponder.funnel_transfer.text_2": "UNLOCALIZED: Chutes or Smart chutes might be more suitable for such purposes.", + "create.ponder.funnel_transfer.text_3": "UNLOCALIZED: Same applies for horizontal movement.\nA mechanical belt should help here.", + + "create.ponder.gantry_carriage.header": "UNLOCALIZED: Using Gantry Carriages", + "create.ponder.gantry_carriage.text_1": "UNLOCALIZED: Gantry Carriages can mount to and slide along a Gantry Shaft.", + "create.ponder.gantry_carriage.text_2": "UNLOCALIZED: Gantry setups can move attached Blocks.", + + "create.ponder.gantry_cascaded.header": "UNLOCALIZED: Cascaded Gantries", + "create.ponder.gantry_cascaded.text_1": "UNLOCALIZED: Gantry shafts attach to a carriage without the need of super glue", + "create.ponder.gantry_cascaded.text_2": "UNLOCALIZED: Same applies for carriages on moved Gantry Shafts", + "create.ponder.gantry_cascaded.text_3": "UNLOCALIZED: Thus, a gantry system can be cascaded to cover multiple axes of movement", + + "create.ponder.gantry_direction.header": "UNLOCALIZED: Gantry Movement Direction", + "create.ponder.gantry_direction.text_1": "UNLOCALIZED: Gantry Shafts can have opposite orientations", + "create.ponder.gantry_direction.text_2": "UNLOCALIZED: The movement direction of carriages depend on their shafts' orientation", + "create.ponder.gantry_direction.text_3": "UNLOCALIZED: ...as well as the rotation direction of the shaft", + "create.ponder.gantry_direction.text_4": "UNLOCALIZED: Same rules apply for the propagated rotation", + + "create.ponder.gantry_redstone.header": "UNLOCALIZED: Gantry Power Propagation", + "create.ponder.gantry_redstone.text_1": "UNLOCALIZED: Redstone-powered gantry shafts stop moving their carriages", + "create.ponder.gantry_redstone.text_2": "UNLOCALIZED: Instead, its rotational force is relayed to the carriages' output shaft", + + "create.ponder.gantry_shaft.header": "UNLOCALIZED: Using Gantry Shafts", + "create.ponder.gantry_shaft.text_1": "UNLOCALIZED: Gantry Shafts form the basis of a gantry setup. Attached Carriages will move along them.", + "create.ponder.gantry_shaft.text_2": "UNLOCALIZED: Gantry setups can move attached Blocks.", + + "create.ponder.gearbox.header": "UNLOCALIZED: Relaying rotational force using Gearboxes", + "create.ponder.gearbox.text_1": "UNLOCALIZED: Jumping between axes of rotation can get bulky quickly", + "create.ponder.gearbox.text_2": "UNLOCALIZED: A gearbox is the more compact equivalent of this setup", + "create.ponder.gearbox.text_3": "UNLOCALIZED: Shafts around corners rotate in mirrored directions", + "create.ponder.gearbox.text_4": "UNLOCALIZED: Straight connections will be reversed", + + "create.ponder.gearshift.header": "UNLOCALIZED: Controlling rotational force using a Gearshift", + "create.ponder.gearshift.text_1": "UNLOCALIZED: Gearshifts will relay rotation in a straight line", + "create.ponder.gearshift.text_2": "UNLOCALIZED: When powered by Redstone, it reverses the transmission", + + "create.ponder.hand_crank.header": "UNLOCALIZED: Generating Rotational Force using Hand Cranks", + "create.ponder.hand_crank.text_1": "UNLOCALIZED: Hand Cranks can be used by players to apply rotational force manually", + "create.ponder.hand_crank.text_2": "UNLOCALIZED: Hold Right-Click to rotate it Counter-Clockwise", + "create.ponder.hand_crank.text_3": "UNLOCALIZED: Its conveyed speed is relatively high", + "create.ponder.hand_crank.text_4": "UNLOCALIZED: Sneak and Hold Right-Click to rotate it Clockwise", + + "create.ponder.large_cogwheel.header": "UNLOCALIZED: Relaying rotational force using Large Cogwheels", + "create.ponder.large_cogwheel.text_1": "UNLOCALIZED: Large cogwheels can connect to each other at right angles", + "create.ponder.large_cogwheel.text_2": "UNLOCALIZED: It will help relaying conveyed speed to other axes of rotation", + + "create.ponder.portable_storage_interface.header": "UNLOCALIZED: Contraption Storage Exchange", + "create.ponder.portable_storage_interface.text_1": "UNLOCALIZED: Inventories on moving contraptions cannot be accessed by players.", + "create.ponder.portable_storage_interface.text_2": "UNLOCALIZED: This component can interact with storage without the need to stop the contraption.", + "create.ponder.portable_storage_interface.text_3": "UNLOCALIZED: Place a second one with a gap of 1 or 2 blocks inbetween", + "create.ponder.portable_storage_interface.text_4": "UNLOCALIZED: Whenever they pass by each other, they will engage in a connection", + "create.ponder.portable_storage_interface.text_5": "UNLOCALIZED: While engaged, the stationary interface will represent ALL inventories on the contraption", + "create.ponder.portable_storage_interface.text_6": "UNLOCALIZED: Items can now be inserted...", + "create.ponder.portable_storage_interface.text_7": "UNLOCALIZED: ...or extracted from the contraption", + "create.ponder.portable_storage_interface.text_8": "UNLOCALIZED: After no items have been exchanged for a while, the contraption will continue on its way", + + "create.ponder.portable_storage_interface_redstone.header": "UNLOCALIZED: Redstone Control", + "create.ponder.portable_storage_interface_redstone.text_1": "UNLOCALIZED: Redstone power will prevent the stationary interface from engaging", + + "create.ponder.shaft.header": "UNLOCALIZED: Relaying rotational force using Shafts", + "create.ponder.shaft.text_1": "UNLOCALIZED: Shafts will relay rotation in a straight line.", + + "create.ponder.shaft_casing.header": "UNLOCALIZED: Encasing Shafts", + "create.ponder.shaft_casing.text_1": "UNLOCALIZED: Brass or Andesite Casing can be used to decorate Shafts", + + "create.ponder.valve_handle.header": "UNLOCALIZED: Generating Rotational Force using Valve Handles", + "create.ponder.valve_handle.text_1": "UNLOCALIZED: Valve Handles can be used by players to apply rotational force manually", + "create.ponder.valve_handle.text_2": "UNLOCALIZED: Hold Right-Click to rotate it Counter-Clockwise", + "create.ponder.valve_handle.text_3": "UNLOCALIZED: Its conveyed speed is slow and precise", + "create.ponder.valve_handle.text_4": "UNLOCALIZED: Sneak and Hold Right-Click to rotate it Clockwise", + "create.ponder.valve_handle.text_5": "UNLOCALIZED: Valve handles can be dyed for aesthetic purposes", + + "create.ponder.water_wheel.header": "UNLOCALIZED: Generating Rotational Force using Water Wheels", + "create.ponder.water_wheel.text_1": "UNLOCALIZED: Water Wheels draw force from adjacent Water Currents", + "create.ponder.water_wheel.text_2": "UNLOCALIZED: The more faces are powered, the faster the Water Wheel will rotate", + "create.ponder.water_wheel.text_3": "UNLOCALIZED: The Wheels' blades should be oriented against the flow", + "create.ponder.water_wheel.text_4": "UNLOCALIZED: Facing the opposite way, they will not be as effective", + "_": "Thank you for translating Create!" } \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/block/andesite_funnel_vertical_pull.json b/src/generated/resources/assets/create/models/block/andesite_funnel_vertical_filterless_pull.json similarity index 86% rename from src/generated/resources/assets/create/models/block/andesite_funnel_vertical_pull.json rename to src/generated/resources/assets/create/models/block/andesite_funnel_vertical_filterless_pull.json index 02736f668..a05b1954a 100644 --- a/src/generated/resources/assets/create/models/block/andesite_funnel_vertical_pull.json +++ b/src/generated/resources/assets/create/models/block/andesite_funnel_vertical_filterless_pull.json @@ -1,5 +1,5 @@ { - "parent": "create:block/funnel/block_vertical", + "parent": "create:block/funnel/block_vertical_filterless", "textures": { "particle": "create:block/andesite_casing", "7": "create:block/andesite_funnel_plating", diff --git a/src/generated/resources/assets/create/models/block/andesite_funnel_vertical_pull_powered.json b/src/generated/resources/assets/create/models/block/andesite_funnel_vertical_filterless_pull_powered.json similarity index 86% rename from src/generated/resources/assets/create/models/block/andesite_funnel_vertical_pull_powered.json rename to src/generated/resources/assets/create/models/block/andesite_funnel_vertical_filterless_pull_powered.json index 7752f5d86..979f71145 100644 --- a/src/generated/resources/assets/create/models/block/andesite_funnel_vertical_pull_powered.json +++ b/src/generated/resources/assets/create/models/block/andesite_funnel_vertical_filterless_pull_powered.json @@ -1,5 +1,5 @@ { - "parent": "create:block/funnel/block_vertical", + "parent": "create:block/funnel/block_vertical_filterless", "textures": { "particle": "create:block/andesite_casing", "7": "create:block/andesite_funnel_plating", diff --git a/src/generated/resources/assets/create/models/block/andesite_funnel_vertical_push.json b/src/generated/resources/assets/create/models/block/andesite_funnel_vertical_filterless_push.json similarity index 86% rename from src/generated/resources/assets/create/models/block/andesite_funnel_vertical_push.json rename to src/generated/resources/assets/create/models/block/andesite_funnel_vertical_filterless_push.json index acbd75ff3..ef3fe4431 100644 --- a/src/generated/resources/assets/create/models/block/andesite_funnel_vertical_push.json +++ b/src/generated/resources/assets/create/models/block/andesite_funnel_vertical_filterless_push.json @@ -1,5 +1,5 @@ { - "parent": "create:block/funnel/block_vertical", + "parent": "create:block/funnel/block_vertical_filterless", "textures": { "particle": "create:block/andesite_casing", "7": "create:block/andesite_funnel_plating", diff --git a/src/generated/resources/assets/create/models/block/andesite_funnel_vertical_push_powered.json b/src/generated/resources/assets/create/models/block/andesite_funnel_vertical_filterless_push_powered.json similarity index 86% rename from src/generated/resources/assets/create/models/block/andesite_funnel_vertical_push_powered.json rename to src/generated/resources/assets/create/models/block/andesite_funnel_vertical_filterless_push_powered.json index 6bbc397da..4afdf8a20 100644 --- a/src/generated/resources/assets/create/models/block/andesite_funnel_vertical_push_powered.json +++ b/src/generated/resources/assets/create/models/block/andesite_funnel_vertical_filterless_push_powered.json @@ -1,5 +1,5 @@ { - "parent": "create:block/funnel/block_vertical", + "parent": "create:block/funnel/block_vertical_filterless", "textures": { "particle": "create:block/andesite_casing", "7": "create:block/andesite_funnel_plating", diff --git a/src/generated/resources/assets/create/models/item/gantry_carriage.json b/src/generated/resources/assets/create/models/item/gantry_carriage.json new file mode 100644 index 000000000..7421b9883 --- /dev/null +++ b/src/generated/resources/assets/create/models/item/gantry_carriage.json @@ -0,0 +1,3 @@ +{ + "parent": "create:block/gantry_carriage/item" +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/item/gantry_pinion.json b/src/generated/resources/assets/create/models/item/gantry_pinion.json deleted file mode 100644 index 55924eb15..000000000 --- a/src/generated/resources/assets/create/models/item/gantry_pinion.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "create:block/gantry_pinion/item" -} \ No newline at end of file diff --git a/src/generated/resources/data/create/advancements/aesthetics.json b/src/generated/resources/data/create/advancements/aesthetics.json index 59a86f429..d723cbe38 100644 --- a/src/generated/resources/data/create/advancements/aesthetics.json +++ b/src/generated/resources/data/create/advancements/aesthetics.json @@ -28,8 +28,8 @@ "trigger": "create:bracket_apply", "conditions": { "accepted_entries": [ - "create:large_cogwheel", - "create:cogwheel" + "create:cogwheel", + "create:large_cogwheel" ] } }, diff --git a/src/generated/resources/data/create/advancements/recipes/create.base/crafting/kinetics/gantry_pinion.json b/src/generated/resources/data/create/advancements/recipes/create.base/crafting/kinetics/gantry_carriage.json similarity index 81% rename from src/generated/resources/data/create/advancements/recipes/create.base/crafting/kinetics/gantry_pinion.json rename to src/generated/resources/data/create/advancements/recipes/create.base/crafting/kinetics/gantry_carriage.json index b0d383da3..736ef1b67 100644 --- a/src/generated/resources/data/create/advancements/recipes/create.base/crafting/kinetics/gantry_pinion.json +++ b/src/generated/resources/data/create/advancements/recipes/create.base/crafting/kinetics/gantry_carriage.json @@ -2,7 +2,7 @@ "parent": "minecraft:recipes/root", "rewards": { "recipes": [ - "create:crafting/kinetics/gantry_pinion" + "create:crafting/kinetics/gantry_carriage" ] }, "criteria": { @@ -19,7 +19,7 @@ "has_the_recipe": { "trigger": "minecraft:recipe_unlocked", "conditions": { - "recipe": "create:crafting/kinetics/gantry_pinion" + "recipe": "create:crafting/kinetics/gantry_carriage" } } }, diff --git a/src/generated/resources/data/create/loot_tables/blocks/gantry_pinion.json b/src/generated/resources/data/create/loot_tables/blocks/gantry_carriage.json similarity index 86% rename from src/generated/resources/data/create/loot_tables/blocks/gantry_pinion.json rename to src/generated/resources/data/create/loot_tables/blocks/gantry_carriage.json index 9631215af..cf1d1630a 100644 --- a/src/generated/resources/data/create/loot_tables/blocks/gantry_pinion.json +++ b/src/generated/resources/data/create/loot_tables/blocks/gantry_carriage.json @@ -6,7 +6,7 @@ "entries": [ { "type": "minecraft:item", - "name": "create:gantry_pinion" + "name": "create:gantry_carriage" } ], "conditions": [ diff --git a/src/generated/resources/data/create/recipes/crafting/kinetics/gantry_pinion.json b/src/generated/resources/data/create/recipes/crafting/kinetics/gantry_carriage.json similarity index 89% rename from src/generated/resources/data/create/recipes/crafting/kinetics/gantry_pinion.json rename to src/generated/resources/data/create/recipes/crafting/kinetics/gantry_carriage.json index 9bb723b76..e4bccc262 100644 --- a/src/generated/resources/data/create/recipes/crafting/kinetics/gantry_pinion.json +++ b/src/generated/resources/data/create/recipes/crafting/kinetics/gantry_carriage.json @@ -20,6 +20,6 @@ } }, "result": { - "item": "create:gantry_pinion" + "item": "create:gantry_carriage" } } \ No newline at end of file diff --git a/src/main/java/com/simibubi/create/AllBlockPartials.java b/src/main/java/com/simibubi/create/AllBlockPartials.java index 727ecf78f..dcef481c9 100644 --- a/src/main/java/com/simibubi/create/AllBlockPartials.java +++ b/src/main/java/com/simibubi/create/AllBlockPartials.java @@ -77,7 +77,7 @@ public class AllBlockPartials { CUCKOO_RIGHT_DOOR = get("cuckoo_clock/right_door"), CUCKOO_PIG = get("cuckoo_clock/pig"), CUCKOO_CREEPER = get("cuckoo_clock/creeper"), - GANTRY_COGS = get("gantry_pinion/wheels"), + GANTRY_COGS = get("gantry_carriage/wheels"), ROPE_COIL = get("rope_pulley/rope_coil"), ROPE_HALF = get("rope_pulley/rope_half"), diff --git a/src/main/java/com/simibubi/create/AllBlocks.java b/src/main/java/com/simibubi/create/AllBlocks.java index ac22dda0c..444f80625 100644 --- a/src/main/java/com/simibubi/create/AllBlocks.java +++ b/src/main/java/com/simibubi/create/AllBlocks.java @@ -55,7 +55,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.cha import com.simibubi.create.content.contraptions.components.structureMovement.chassis.LinearChassisBlock.ChassisCTBehaviour; import com.simibubi.create.content.contraptions.components.structureMovement.chassis.RadialChassisBlock; import com.simibubi.create.content.contraptions.components.structureMovement.chassis.StickerBlock; -import com.simibubi.create.content.contraptions.components.structureMovement.gantry.GantryPinionBlock; +import com.simibubi.create.content.contraptions.components.structureMovement.gantry.GantryCarriageBlock; import com.simibubi.create.content.contraptions.components.structureMovement.mounted.CartAssemblerBlock; import com.simibubi.create.content.contraptions.components.structureMovement.mounted.CartAssemblerBlock.MinecartAnchorBlock; import com.simibubi.create.content.contraptions.components.structureMovement.mounted.CartAssemblerBlockItem; @@ -693,8 +693,8 @@ public class AllBlocks { .getName() + "/head")))) .register(); - public static final BlockEntry GANTRY_PINION = - REGISTRATE.block("gantry_pinion", GantryPinionBlock::new) + public static final BlockEntry GANTRY_CARRIAGE = + REGISTRATE.block("gantry_carriage", GantryCarriageBlock::new) .initialProperties(SharedProperties::stone) .properties(Block.Properties::nonOpaque) .blockstate(BlockStateGen.directionalAxisBlockProvider()) @@ -1093,7 +1093,7 @@ public class AllBlocks { .initialProperties(SharedProperties::stone) .tag(AllBlockTags.SAFE_NBT.tag) .onRegister(addMovementBehaviour(FunnelMovementBehaviour.andesite())) - .blockstate(new FunnelGenerator("andesite")::generate) + .blockstate(new FunnelGenerator("andesite", false)::generate) .item(FunnelItem::new) .model(FunnelGenerator.itemModel("andesite")) .build() @@ -1112,7 +1112,7 @@ public class AllBlocks { .initialProperties(SharedProperties::softMetal) .tag(AllBlockTags.SAFE_NBT.tag) .onRegister(addMovementBehaviour(FunnelMovementBehaviour.brass())) - .blockstate(new FunnelGenerator("brass")::generate) + .blockstate(new FunnelGenerator("brass", true)::generate) .item(FunnelItem::new) .model(FunnelGenerator.itemModel("brass")) .build() diff --git a/src/main/java/com/simibubi/create/AllShapes.java b/src/main/java/com/simibubi/create/AllShapes.java index e7442c5b8..7c102139e 100644 --- a/src/main/java/com/simibubi/create/AllShapes.java +++ b/src/main/java/com/simibubi/create/AllShapes.java @@ -187,10 +187,10 @@ public class AllShapes { TANK_TOP_BOTTOM = shape(TANK_BOTTOM_LID).add(TANK_TOP_LID) .add(TANK) .build(), - FUNNEL_FLOOR = shape(2, -2, 2, 14, 8, 14).add(1, 2, 1, 15, 8, 15) + FUNNEL_FLOOR = shape(2, -2, 2, 14, 8, 14).add(1, 1, 1, 15, 8, 15) .add(0, 4, 0, 16, 10, 16) .build(), - FUNNEL_CEILING = shape(2, 8, 2, 14, 18, 14).add(1, 8, 1, 15, 14, 15) + FUNNEL_CEILING = shape(2, 8, 2, 14, 18, 14).add(1, 8, 1, 15, 15, 15) .add(0, 6, 0, 16, 12, 16) .build(), DEPOT = shape(CASING_11PX.get(Direction.UP)).add(1, 11, 1, 15, 13, 15) diff --git a/src/main/java/com/simibubi/create/AllTileEntities.java b/src/main/java/com/simibubi/create/AllTileEntities.java index b194f3204..0220a6c85 100644 --- a/src/main/java/com/simibubi/create/AllTileEntities.java +++ b/src/main/java/com/simibubi/create/AllTileEntities.java @@ -54,9 +54,9 @@ import com.simibubi.create.content.contraptions.components.structureMovement.cha import com.simibubi.create.content.contraptions.components.structureMovement.chassis.StickerInstance; import com.simibubi.create.content.contraptions.components.structureMovement.chassis.StickerRenderer; import com.simibubi.create.content.contraptions.components.structureMovement.chassis.StickerTileEntity; -import com.simibubi.create.content.contraptions.components.structureMovement.gantry.GantryPinionInstance; -import com.simibubi.create.content.contraptions.components.structureMovement.gantry.GantryPinionRenderer; -import com.simibubi.create.content.contraptions.components.structureMovement.gantry.GantryPinionTileEntity; +import com.simibubi.create.content.contraptions.components.structureMovement.gantry.GantryCarriageRenderer; +import com.simibubi.create.content.contraptions.components.structureMovement.gantry.GantryCarriageTileEntity; +import com.simibubi.create.content.contraptions.components.structureMovement.gantry.GantryCarriageInstance; import com.simibubi.create.content.contraptions.components.structureMovement.mounted.CartAssemblerTileEntity; import com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonRenderer; import com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonTileEntity; @@ -248,11 +248,11 @@ public class AllTileEntities { .onRegister(SingleRotatingInstance::register) .register(); - public static final TileEntityEntry GANTRY_PINION = Create.registrate() - .tileEntity("gantry_pinion", GantryPinionTileEntity::new) - .validBlocks(AllBlocks.GANTRY_PINION) - .renderer(() -> GantryPinionRenderer::new) - .onRegister(GantryPinionInstance::register) + public static final TileEntityEntry GANTRY_PINION = Create.registrate() + .tileEntity("gantry_pinion", GantryCarriageTileEntity::new) + .validBlocks(AllBlocks.GANTRY_CARRIAGE) + .renderer(() -> GantryCarriageRenderer::new) + .onRegister(GantryCarriageInstance::register) .register(); public static final TileEntityEntry MECHANICAL_PUMP = Create.registrate() diff --git a/src/main/java/com/simibubi/create/CreateClient.java b/src/main/java/com/simibubi/create/CreateClient.java index e698cfe85..c411a9e26 100644 --- a/src/main/java/com/simibubi/create/CreateClient.java +++ b/src/main/java/com/simibubi/create/CreateClient.java @@ -1,10 +1,5 @@ package com.simibubi.create; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.function.Function; - import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher; import com.simibubi.create.content.contraptions.relays.encased.CasingConnectivity; @@ -14,15 +9,17 @@ import com.simibubi.create.content.schematics.client.SchematicHandler; import com.simibubi.create.foundation.ResourceReloadHandler; import com.simibubi.create.foundation.block.render.CustomBlockModels; import com.simibubi.create.foundation.block.render.SpriteShifter; +import com.simibubi.create.foundation.gui.UIRenderHelper; import com.simibubi.create.foundation.item.CustomItemModels; import com.simibubi.create.foundation.item.CustomRenderedItems; +import com.simibubi.create.foundation.ponder.content.PonderIndex; +import com.simibubi.create.foundation.ponder.elements.WorldSectionElement; import com.simibubi.create.foundation.render.KineticRenderer; import com.simibubi.create.foundation.render.SuperByteBufferCache; import com.simibubi.create.foundation.render.backend.Backend; import com.simibubi.create.foundation.render.backend.OptifineHandler; import com.simibubi.create.foundation.utility.ghost.GhostBlocks; import com.simibubi.create.foundation.utility.outliner.Outliner; - import net.minecraft.block.Block; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.BlockModelShapes; @@ -40,6 +37,11 @@ import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + public class CreateClient { public static ClientSchematicLoader schematicSender; @@ -77,6 +79,7 @@ public class CreateClient { bufferCache = new SuperByteBufferCache(); bufferCache.registerCompartment(KineticTileEntityRenderer.KINETIC_TILE); bufferCache.registerCompartment(ContraptionRenderDispatcher.CONTRAPTION, 20); + bufferCache.registerCompartment(WorldSectionElement.DOC_WORLD_SECTION, 20); ghostBlocks = new GhostBlocks(); @@ -86,6 +89,10 @@ public class CreateClient { AllEntityTypes.registerRenderers(); getColorHandler().init(); AllFluids.assignRenderLayers(); + PonderIndex.register(); + PonderIndex.registerTags(); + + UIRenderHelper.init(); IResourceManager resourceManager = Minecraft.getInstance() .getResourceManager(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntity.java index c12fa785a..dd59c1a1c 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntity.java @@ -15,7 +15,6 @@ import com.simibubi.create.content.contraptions.base.IRotate.SpeedLevel; import com.simibubi.create.content.contraptions.base.IRotate.StressImpact; import com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation; import com.simibubi.create.content.contraptions.goggles.IHaveHoveringInformation; -import com.simibubi.create.foundation.advancement.AllTriggers; import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.item.TooltipHelper; import com.simibubi.create.foundation.render.backend.FastRenderDispatcher; @@ -73,7 +72,7 @@ public abstract class KineticTileEntity extends SmartTileEntity @Override public void initialize() { - if (hasNetwork()) { + if (hasNetwork() && !world.isRemote) { KineticNetwork network = getOrCreateNetwork(); if (!network.initialized) network.initFromTE(capacity, stress, networkSize); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceTileEntity.java index d304af537..9ea1408a7 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceTileEntity.java @@ -55,8 +55,9 @@ public abstract class PortableStorageInterfaceTileEntity extends SmartTileEntity public void tick() { super.tick(); boolean wasConnected = isConnected(); + int timeUnit = getTransferTimeout() / 2; - if (transferTimer > 0) { + if (transferTimer > 0 && (!isVirtual() || transferTimer != timeUnit)) { transferTimer--; if (transferTimer == 0 || powered) stopTransferring(); @@ -67,7 +68,6 @@ public abstract class PortableStorageInterfaceTileEntity extends SmartTileEntity markDirty(); float progress = 0; - int timeUnit = getTransferTimeout() / 2; if (isConnected) progress = 1; else if (transferTimer >= timeUnit * 3) @@ -106,12 +106,13 @@ public abstract class PortableStorageInterfaceTileEntity extends SmartTileEntity powered = isBlockPowered; sendData(); } - + public boolean isPowered() { return powered; } protected AxisAlignedBB cachedBoundingBox; + @Override @OnlyIn(Dist.CLIENT) public AxisAlignedBB getRenderBoundingBox() { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanTileEntity.java index 132f9f65d..eb5bc626c 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanTileEntity.java @@ -171,7 +171,9 @@ public class EncasedFanTileEntity extends GeneratingKineticTileEntity implements public void tick() { super.tick(); - if (!world.isRemote && airCurrentUpdateCooldown-- <= 0) { + boolean server = !world.isRemote || isVirtual(); + + if (server && airCurrentUpdateCooldown-- <= 0) { airCurrentUpdateCooldown = AllConfigs.SERVER.kinetics.fanBlockCheckRate.get(); updateAirFlow = true; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawTileEntity.java index 8652591db..bcb39ea99 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawTileEntity.java @@ -129,7 +129,7 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity { if (inventory.remainingTime > 0) spawnParticles(inventory.getStackInSlot(0)); - if (world.isRemote) + if (world.isRemote && !isVirtual()) return; if (inventory.remainingTime < 20 && !inventory.appliedRecipe) { @@ -317,7 +317,7 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity { return; if (inventory.isEmpty()) return; - if (world.isRemote) + if (world.isRemote && !isVirtual()) return; List> recipes = getRecipes(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java index 44fb1523c..5ee4c3bb0 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java @@ -34,7 +34,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.bea import com.simibubi.create.content.contraptions.components.structureMovement.chassis.AbstractChassisBlock; import com.simibubi.create.content.contraptions.components.structureMovement.chassis.ChassisTileEntity; import com.simibubi.create.content.contraptions.components.structureMovement.chassis.StickerBlock; -import com.simibubi.create.content.contraptions.components.structureMovement.gantry.GantryPinionBlock; +import com.simibubi.create.content.contraptions.components.structureMovement.gantry.GantryCarriageBlock; import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity; import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueHandler; import com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock; @@ -293,7 +293,7 @@ public abstract class Contraption { if (AllBlocks.BELT.has(state)) moveBelt(pos, frontier, visited, state); - if (AllBlocks.GANTRY_PINION.has(state)) + if (AllBlocks.GANTRY_CARRIAGE.has(state)) moveGantryPinion(world, pos, frontier, visited, state); if (AllBlocks.GANTRY_SHAFT.has(state)) @@ -435,7 +435,7 @@ public abstract class Contraption { protected void moveGantryPinion(World world, BlockPos pos, Queue frontier, Set visited, BlockState state) { - BlockPos offset = pos.offset(state.get(GantryPinionBlock.FACING)); + BlockPos offset = pos.offset(state.get(GantryCarriageBlock.FACING)); if (!visited.contains(offset)) frontier.add(offset); Axis rotationAxis = ((IRotate) state.getBlock()).getRotationAxis(state); @@ -459,7 +459,7 @@ public abstract class Contraption { if (d.getAxis() == facing.getAxis() && AllBlocks.GANTRY_SHAFT.has(offsetState) && offsetState.get(GantryShaftBlock.FACING) == facing) frontier.add(offset); - else if (AllBlocks.GANTRY_PINION.has(offsetState) && offsetState.get(GantryPinionBlock.FACING) == d) + else if (AllBlocks.GANTRY_CARRIAGE.has(offsetState) && offsetState.get(GantryCarriageBlock.FACING) == d) frontier.add(offset); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/MechanicalBearingTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/MechanicalBearingTileEntity.java index 42460217a..e92e9ff22 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/MechanicalBearingTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/MechanicalBearingTileEntity.java @@ -25,7 +25,8 @@ import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; -public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity implements IBearingTileEntity, IDisplayAssemblyExceptions { +public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity + implements IBearingTileEntity, IDisplayAssemblyExceptions { protected ScrollOptionBehaviour movementMode; protected ControlledContraptionEntity movedContraption; @@ -35,6 +36,8 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp protected float clientAngleDiff; protected AssemblyException lastException; + private float prevAngle; + public MechanicalBearingTileEntity(TileEntityType type) { super(type); setLazyTickRate(3); @@ -87,6 +90,8 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp @Override public float getInterpolatedAngle(float partialTicks) { + if (isVirtual()) + return MathHelper.lerp(partialTicks + .5f, prevAngle, angle); if (movedContraption == null || movedContraption.isStalled() || !running) partialTicks = 0; return MathHelper.lerp(partialTicks, angle, angle + getAngularSpeed()); @@ -145,7 +150,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp AllTriggers.triggerForNearbyPlayers(AllTriggers.WINDMILL, world, pos, 5); if (contraption.getSailBlocks() >= 16 * 8) AllTriggers.triggerForNearbyPlayers(AllTriggers.MAXED_WINDMILL, world, pos, 5); - + contraption.removeBlocksFromWorld(world, BlockPos.ZERO); movedContraption = ControlledContraptionEntity.create(world, this, contraption); BlockPos anchor = pos.offset(direction); @@ -179,6 +184,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp public void tick() { super.tick(); + prevAngle = angle; if (world.isRemote) clientAngleDiff /= 2; @@ -291,7 +297,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp BlockState state = getBlockState(); if (!(state.getBlock() instanceof BearingBlock)) return false; - + BlockState attachedState = world.getBlockState(pos.offset(state.get(BearingBlock.FACING))); if (attachedState.getMaterial() .isReplaceable()) @@ -304,4 +310,9 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp public boolean shouldRenderAsTE() { return true; } + + public void setAngle(float forcedAngle) { + angle = forcedAngle; + } + } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryPinionBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageBlock.java similarity index 91% rename from src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryPinionBlock.java rename to src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageBlock.java index 85c41d0af..744c803fc 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryPinionBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageBlock.java @@ -24,9 +24,9 @@ import net.minecraft.world.IWorld; import net.minecraft.world.IWorldReader; import net.minecraft.world.World; -public class GantryPinionBlock extends DirectionalAxisKineticBlock implements ITE { +public class GantryCarriageBlock extends DirectionalAxisKineticBlock implements ITE { - public GantryPinionBlock(Properties properties) { + public GantryCarriageBlock(Properties properties) { super(properties); } @@ -41,7 +41,7 @@ public class GantryPinionBlock extends DirectionalAxisKineticBlock implements IT @Override public void updateNeighbors(BlockState stateIn, IWorld worldIn, BlockPos pos, int flags) { super.updateNeighbors(stateIn, worldIn, pos, flags); - withTileEntityDo(worldIn, pos, GantryPinionTileEntity::checkValidGantryShaft); + withTileEntityDo(worldIn, pos, GantryCarriageTileEntity::checkValidGantryShaft); } @Override @@ -113,7 +113,7 @@ public class GantryPinionBlock extends DirectionalAxisKineticBlock implements IT } public static Axis getValidGantryShaftAxis(BlockState state) { - if (!(state.getBlock() instanceof GantryPinionBlock)) + if (!(state.getBlock() instanceof GantryCarriageBlock)) return Axis.Y; IRotate block = (IRotate) state.getBlock(); Axis rotationAxis = block.getRotationAxis(state); @@ -135,8 +135,8 @@ public class GantryPinionBlock extends DirectionalAxisKineticBlock implements IT } @Override - public Class getTileEntityClass() { - return GantryPinionTileEntity.class; + public Class getTileEntityClass() { + return GantryCarriageTileEntity.class; } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryPinionInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageInstance.java similarity index 88% rename from src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryPinionInstance.java rename to src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageInstance.java index adb7cc56f..3a94fccb8 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryPinionInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageInstance.java @@ -14,7 +14,6 @@ import com.simibubi.create.foundation.render.backend.instancing.impl.TransformDa import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.MatrixStacker; -import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.Vector3f; import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; @@ -23,15 +22,15 @@ import net.minecraft.world.LightType; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.fml.DistExecutor; -public class GantryPinionInstance extends ShaftInstance implements ITickableInstance { +public class GantryCarriageInstance extends ShaftInstance implements ITickableInstance { public static void register(TileEntityType type) { DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> - InstancedTileRenderRegistry.instance.register(type, GantryPinionInstance::new)); + InstancedTileRenderRegistry.instance.register(type, GantryCarriageInstance::new)); } private InstanceKey gantryCogs; - public GantryPinionInstance(InstancedTileRenderer dispatcher, KineticTileEntity tile) { + public GantryCarriageInstance(InstancedTileRenderer dispatcher, KineticTileEntity tile) { super(dispatcher, tile); } @@ -49,13 +48,13 @@ public class GantryPinionInstance extends ShaftInstance implements ITickableInst @Override public void tick() { lastState = world.getBlockState(pos); - Direction facing = lastState.get(GantryPinionBlock.FACING); - Boolean alongFirst = lastState.get(GantryPinionBlock.AXIS_ALONG_FIRST_COORDINATE); + Direction facing = lastState.get(GantryCarriageBlock.FACING); + Boolean alongFirst = lastState.get(GantryCarriageBlock.AXIS_ALONG_FIRST_COORDINATE); Direction.Axis rotationAxis = KineticTileEntityRenderer.getRotationAxisOf(tile); BlockPos visualPos = facing.getAxisDirection() == Direction.AxisDirection.POSITIVE ? tile.getPos() : tile.getPos() .offset(facing.getOpposite()); - float angleForTe = GantryPinionRenderer.getAngleForTe(tile, visualPos, rotationAxis); + float angleForTe = GantryCarriageRenderer.getAngleForTe(tile, visualPos, rotationAxis); Direction.Axis gantryAxis = Direction.Axis.X; for (Direction.Axis axis : Iterate.axes) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryPinionRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageRenderer.java similarity index 91% rename from src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryPinionRenderer.java rename to src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageRenderer.java index b92e2aa8b..0010a4755 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryPinionRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageRenderer.java @@ -21,9 +21,9 @@ import net.minecraft.util.Direction.Axis; import net.minecraft.util.Direction.AxisDirection; import net.minecraft.util.math.BlockPos; -public class GantryPinionRenderer extends KineticTileEntityRenderer { +public class GantryCarriageRenderer extends KineticTileEntityRenderer { - public GantryPinionRenderer(TileEntityRendererDispatcher dispatcher) { + public GantryCarriageRenderer(TileEntityRendererDispatcher dispatcher) { super(dispatcher); } @@ -35,8 +35,8 @@ public class GantryPinionRenderer extends KineticTileEntityRenderer { if (FastRenderDispatcher.available(te.getWorld())) return; BlockState state = te.getBlockState(); - Direction facing = state.get(GantryPinionBlock.FACING); - Boolean alongFirst = state.get(GantryPinionBlock.AXIS_ALONG_FIRST_COORDINATE); + Direction facing = state.get(GantryCarriageBlock.FACING); + Boolean alongFirst = state.get(GantryCarriageBlock.AXIS_ALONG_FIRST_COORDINATE); Axis rotationAxis = getRotationAxisOf(te); BlockPos visualPos = facing.getAxisDirection() == AxisDirection.POSITIVE ? te.getPos() : te.getPos() diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryPinionTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageTileEntity.java similarity index 91% rename from src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryPinionTileEntity.java rename to src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageTileEntity.java index 582b7d749..a3d59c9fd 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryPinionTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageTileEntity.java @@ -18,12 +18,12 @@ import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; -public class GantryPinionTileEntity extends KineticTileEntity implements IDisplayAssemblyExceptions { +public class GantryCarriageTileEntity extends KineticTileEntity implements IDisplayAssemblyExceptions { boolean assembleNextTick; protected AssemblyException lastException; - public GantryPinionTileEntity(TileEntityType typeIn) { + public GantryCarriageTileEntity(TileEntityType typeIn) { super(typeIn); } @@ -61,7 +61,7 @@ public class GantryPinionTileEntity extends KineticTileEntity implements IDispla private void tryAssemble() { BlockState blockState = getBlockState(); - if (!(blockState.getBlock() instanceof GantryPinionBlock)) + if (!(blockState.getBlock() instanceof GantryCarriageBlock)) return; Direction direction = blockState.get(FACING); @@ -129,9 +129,9 @@ public class GantryPinionTileEntity extends KineticTileEntity implements IDispla return defaultModifier; Direction direction = Direction.getFacingFromVector(diff.getX(), diff.getY(), diff.getZ()); - if (stateFrom.get(GantryPinionBlock.FACING) != direction.getOpposite()) + if (stateFrom.get(GantryCarriageBlock.FACING) != direction.getOpposite()) return defaultModifier; - return getGantryPinionModifier(stateTo.get(GantryShaftBlock.FACING), stateFrom.get(GantryPinionBlock.FACING)); + return getGantryPinionModifier(stateTo.get(GantryShaftBlock.FACING), stateFrom.get(GantryCarriageBlock.FACING)); } public static float getGantryPinionModifier(Direction shaft, Direction pinionDirection) { @@ -152,9 +152,9 @@ public class GantryPinionTileEntity extends KineticTileEntity implements IDispla private boolean shouldAssemble() { BlockState blockState = getBlockState(); - if (!(blockState.getBlock() instanceof GantryPinionBlock)) + if (!(blockState.getBlock() instanceof GantryCarriageBlock)) return false; - Direction facing = blockState.get(GantryPinionBlock.FACING) + Direction facing = blockState.get(GantryCarriageBlock.FACING) .getOpposite(); BlockState shaftState = world.getBlockState(pos.offset(facing)); if (!(shaftState.getBlock() instanceof GantryShaftBlock)) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryContraption.java index 0db74075e..df6366c73 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryContraption.java @@ -60,7 +60,7 @@ public class GantryContraption extends TranslatingContraption { @Override protected boolean shouldUpdateAfterMovement(BlockInfo info) { - return super.shouldUpdateAfterMovement(info) && !AllBlocks.GANTRY_PINION.has(info.state); + return super.shouldUpdateAfterMovement(info) && !AllBlocks.GANTRY_CARRIAGE.has(info.state); } @Override diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/ItemDrainTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/ItemDrainTileEntity.java index 6206ad9e8..39f9bc7a1 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/ItemDrainTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/ItemDrainTileEntity.java @@ -98,10 +98,12 @@ public class ItemDrainTileEntity extends SmartTileEntity implements IHaveGoggleI return; } + boolean onClient = world.isRemote && !isVirtual(); + if (processingTicks > 0) { heldItem.prevBeltPosition = .5f; boolean wasAtBeginning = processingTicks == FILLING_TIME; - if (!world.isRemote || processingTicks < FILLING_TIME) + if (!onClient || processingTicks < FILLING_TIME) processingTicks--; if (!continueProcessing()) { processingTicks = 0; @@ -120,7 +122,7 @@ public class ItemDrainTileEntity extends SmartTileEntity implements IHaveGoggleI if (heldItem.beltPosition > 1) { heldItem.beltPosition = 1; - if (world.isRemote) + if (onClient) return; Direction side = heldItem.insertedFrom; @@ -186,7 +188,7 @@ public class ItemDrainTileEntity extends SmartTileEntity implements IHaveGoggleI if (!EmptyingByBasin.canItemBeEmptied(world, heldItem.stack)) return; heldItem.beltPosition = .5f; - if (world.isRemote) + if (onClient) return; processingTicks = FILLING_TIME; sendData(); @@ -195,7 +197,7 @@ public class ItemDrainTileEntity extends SmartTileEntity implements IHaveGoggleI } protected boolean continueProcessing() { - if (world.isRemote) + if (world.isRemote && !isVirtual()) return true; if (processingTicks < 5) return true; diff --git a/src/main/java/com/simibubi/create/content/contraptions/particle/RotationIndicatorParticle.java b/src/main/java/com/simibubi/create/content/contraptions/particle/RotationIndicatorParticle.java index dd314bfe6..f9b754484 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/particle/RotationIndicatorParticle.java +++ b/src/main/java/com/simibubi/create/content/contraptions/particle/RotationIndicatorParticle.java @@ -29,7 +29,7 @@ public class RotationIndicatorParticle extends SimpleAnimatedParticle { protected boolean isVisible; private RotationIndicatorParticle(World world, double x, double y, double z, int color, float radius1, - float radius2, float speed, Axis axis, int lifeSpan, boolean isVisible, IAnimatedSprite sprite) { + float radius2, float speed, Axis axis, int lifeSpan, boolean isVisible, IAnimatedSprite sprite) { super(world, x, y, z, sprite, 0); this.motionX = 0; this.motionY = 0; @@ -58,7 +58,7 @@ public class RotationIndicatorParticle extends SimpleAnimatedParticle { super.tick(); radius += (radius2 - radius) * .1f; } - + @Override public void buildGeometry(IVertexBuilder buffer, ActiveRenderInfo renderInfo, float partialTicks) { if (!isVisible) @@ -69,7 +69,10 @@ public class RotationIndicatorParticle extends SimpleAnimatedParticle { public void move(double x, double y, double z) { float time = AnimationTickHolder.getTicks(); float angle = (float) ((time * speed) % 360) - (speed / 2 * age * (((float) age) / maxAge)); - Vec3d position = VecHelper.rotate(this.offset.scale(radius), angle, axis).add(origin); + if (speed < 0 && axis.isVertical()) + angle += 180; + Vec3d position = VecHelper.rotate(this.offset.scale(radius), angle, axis) + .add(origin); posX = position.x; posY = position.y; posZ = position.z; @@ -83,11 +86,12 @@ public class RotationIndicatorParticle extends SimpleAnimatedParticle { } public Particle makeParticle(RotationIndicatorParticleData data, World worldIn, double x, double y, double z, - double xSpeed, double ySpeed, double zSpeed) { - ClientPlayerEntity player = Minecraft.getInstance().player; - boolean visible = player != null && GogglesItem.canSeeParticles(player); + double xSpeed, double ySpeed, double zSpeed) { + Minecraft mc = Minecraft.getInstance(); + ClientPlayerEntity player = mc.player; + boolean visible = worldIn != mc.world || player != null && GogglesItem.canSeeParticles(player); return new RotationIndicatorParticle(worldIn, x, y, z, data.color, data.radius1, data.radius2, data.speed, - data.getAxis(), data.lifeSpan, visible, this.spriteSet); + data.getAxis(), data.lifeSpan, visible, this.spriteSet); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/GantryShaftBlock.java b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/GantryShaftBlock.java index db9ae172b..645905b59 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/GantryShaftBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/GantryShaftBlock.java @@ -259,6 +259,16 @@ public class GantryShaftBlock extends DirectionalKineticBlock { return super.areStatesKineticallyEquivalent(oldState, newState) && oldState.get(POWERED) == newState.get(POWERED); } + + @Override + public float getParticleTargetRadius() { + return .35f; + } + + @Override + public float getParticleInitialRadius() { + return .25f; + } public static class PlacementHelper extends PoleHelper { diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/GantryShaftTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/GantryShaftTileEntity.java index 338123dc8..dbdeeb073 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/GantryShaftTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/GantryShaftTileEntity.java @@ -2,8 +2,8 @@ package com.simibubi.create.content.contraptions.relays.advanced; import com.simibubi.create.AllBlocks; import com.simibubi.create.content.contraptions.base.KineticTileEntity; -import com.simibubi.create.content.contraptions.components.structureMovement.gantry.GantryPinionBlock; -import com.simibubi.create.content.contraptions.components.structureMovement.gantry.GantryPinionTileEntity; +import com.simibubi.create.content.contraptions.components.structureMovement.gantry.GantryCarriageBlock; +import com.simibubi.create.content.contraptions.components.structureMovement.gantry.GantryCarriageTileEntity; import com.simibubi.create.foundation.utility.Iterate; import net.minecraft.block.BlockState; @@ -31,13 +31,13 @@ public class GantryShaftTileEntity extends KineticTileEntity { continue; BlockPos offset = pos.offset(d); BlockState pinionState = world.getBlockState(offset); - if (!AllBlocks.GANTRY_PINION.has(pinionState)) + if (!AllBlocks.GANTRY_CARRIAGE.has(pinionState)) continue; - if (pinionState.get(GantryPinionBlock.FACING) != d) + if (pinionState.get(GantryCarriageBlock.FACING) != d) continue; TileEntity tileEntity = world.getTileEntity(offset); - if (tileEntity instanceof GantryPinionTileEntity) - ((GantryPinionTileEntity) tileEntity).queueAssembly(); + if (tileEntity instanceof GantryCarriageTileEntity) + ((GantryCarriageTileEntity) tileEntity).queueAssembly(); } } @@ -52,24 +52,24 @@ public class GantryShaftTileEntity extends KineticTileEntity { return defaultModifier; if (!stateFrom.get(GantryShaftBlock.POWERED)) return defaultModifier; - if (!AllBlocks.GANTRY_PINION.has(stateTo)) + if (!AllBlocks.GANTRY_CARRIAGE.has(stateTo)) return defaultModifier; Direction direction = Direction.getFacingFromVector(diff.getX(), diff.getY(), diff.getZ()); - if (stateTo.get(GantryPinionBlock.FACING) != direction) + if (stateTo.get(GantryCarriageBlock.FACING) != direction) return defaultModifier; - return GantryPinionTileEntity.getGantryPinionModifier(stateFrom.get(GantryShaftBlock.FACING), - stateTo.get(GantryPinionBlock.FACING)); + return GantryCarriageTileEntity.getGantryPinionModifier(stateFrom.get(GantryShaftBlock.FACING), + stateTo.get(GantryCarriageBlock.FACING)); } @Override public boolean isCustomConnection(KineticTileEntity other, BlockState state, BlockState otherState) { - if (!AllBlocks.GANTRY_PINION.has(otherState)) + if (!AllBlocks.GANTRY_CARRIAGE.has(otherState)) return false; final BlockPos diff = other.getPos() .subtract(pos); Direction direction = Direction.getFacingFromVector(diff.getX(), diff.getY(), diff.getZ()); - return otherState.get(GantryPinionBlock.FACING) == direction; + return otherState.get(GantryCarriageBlock.FACING) == direction; } public boolean canAssembleOn() { diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/transport/BeltInventory.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/transport/BeltInventory.java index 8b4dcbde9..1dbd82087 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/transport/BeltInventory.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/transport/BeltInventory.java @@ -82,7 +82,7 @@ public class BeltInventory { .get(BeltBlock.SLOPE) == BeltSlope.HORIZONTAL; float spacing = 1; World world = belt.getWorld(); - boolean onClient = world.isRemote; + boolean onClient = world.isRemote && !belt.isVirtual(); // resolve ending only when items will reach it this tick Ending ending = Ending.UNRESOLVED; @@ -105,7 +105,7 @@ public class BeltInventory { movement *= ServerSpeedProvider.get(); // Don't move if held by processing (client) - if (onClient && currentItem.locked) + if (world.isRemote && currentItem.locked) continue; // Don't move if other items are waiting in front @@ -436,5 +436,5 @@ public class BeltInventory { public List getTransportedItems() { return items; } - + } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/ShaftBlock.java b/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/ShaftBlock.java index 3b0bb2e8d..16dfa60c3 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/ShaftBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/ShaftBlock.java @@ -45,12 +45,12 @@ public class ShaftBlock extends AbstractShaftBlock { @Override public float getParticleTargetRadius() { - return .25f; + return .35f; } @Override public float getParticleInitialRadius() { - return 0f; + return .125f; } @Override diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/AdjustablePulleyTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/AdjustablePulleyTileEntity.java index 80d831b84..e243e50c4 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/AdjustablePulleyTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/AdjustablePulleyTileEntity.java @@ -49,6 +49,8 @@ public class AdjustablePulleyTileEntity extends KineticTileEntity { @Override public void tick() { super.tick(); + if (world.isRemote) + return; if (signalChanged) { signalChanged = false; analogSignalChanged(world.getRedstonePowerFromNeighbors(pos)); diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/gauge/SpeedGaugeTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/relays/gauge/SpeedGaugeTileEntity.java index 373387ab7..e3cc2c1b5 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/gauge/SpeedGaugeTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/gauge/SpeedGaugeTileEntity.java @@ -13,7 +13,7 @@ import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.math.MathHelper; import net.minecraft.util.text.TextFormatting; -public class SpeedGaugeTileEntity extends GaugeTileEntity{ +public class SpeedGaugeTileEntity extends GaugeTileEntity { public SpeedGaugeTileEntity(TileEntityType type) { super(type); @@ -23,28 +23,37 @@ public class SpeedGaugeTileEntity extends GaugeTileEntity{ public void onSpeedChanged(float prevSpeed) { super.onSpeedChanged(prevSpeed); float speed = Math.abs(getSpeed()); - float medium = AllConfigs.SERVER.kinetics.mediumSpeed.get().floatValue(); - float fast = AllConfigs.SERVER.kinetics.fastSpeed.get().floatValue(); - float max = AllConfigs.SERVER.kinetics.maxRotationSpeed.get().floatValue(); - color = ColorHelper.mixColors(SpeedLevel.of(speed).getColor(), 0xffffff, .25f); + color = speed == 0 ? 0x333333 + : ColorHelper.mixColors(SpeedLevel.of(speed) + .getColor(), 0xffffff, .25f); if (speed == 69) - AllTriggers.triggerForNearbyPlayers(AllTriggers.SPEED_READ, world, pos, 6, - GogglesItem::canSeeParticles); - if (speed == 0) { - dialTarget = 0; - color = 0x333333; - } else if (speed < medium) { - dialTarget = MathHelper.lerp(speed / medium, 0, .45f); - } else if (speed < fast) { - dialTarget = MathHelper.lerp((speed - medium) / (fast - medium), .45f, .75f); - } else { - dialTarget = MathHelper.lerp((speed - fast) / (max - fast), .75f, 1.125f); - } - + AllTriggers.triggerForNearbyPlayers(AllTriggers.SPEED_READ, world, pos, 6, GogglesItem::canSeeParticles); + + dialTarget = getDialTarget(speed); markDirty(); } + public static float getDialTarget(float speed) { + speed = Math.abs(speed); + float medium = AllConfigs.SERVER.kinetics.mediumSpeed.get() + .floatValue(); + float fast = AllConfigs.SERVER.kinetics.fastSpeed.get() + .floatValue(); + float max = AllConfigs.SERVER.kinetics.maxRotationSpeed.get() + .floatValue(); + float target = 0; + if (speed == 0) + target = 0; + else if (speed < medium) + target = MathHelper.lerp(speed / medium, 0, .45f); + else if (speed < fast) + target = MathHelper.lerp((speed - medium) / (fast - medium), .45f, .75f); + else + target = MathHelper.lerp((speed - fast) / (max - fast), .75f, 1.125f); + return target; + } + @Override public boolean addToGoggleTooltip(List tooltip, boolean isPlayerSneaking) { super.addToGoggleTooltip(tooltip, isPlayerSneaking); diff --git a/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelGenerator.java b/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelGenerator.java index 5c5fc8bd1..b41d3384f 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelGenerator.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelGenerator.java @@ -19,9 +19,11 @@ public class FunnelGenerator extends SpecialBlockStateGen { private String type; private ResourceLocation particleTexture; + private boolean hasFilter; - public FunnelGenerator(String type) { + public FunnelGenerator(String type, boolean hasFilter) { this.type = type; + this.hasFilter = hasFilter; this.particleTexture = Create.asResource("block/" + type + "_casing"); } @@ -44,7 +46,7 @@ public class FunnelGenerator extends SpecialBlockStateGen { Direction facing = s.get(FunnelBlock.FACING); boolean horizontal = facing.getAxis() .isHorizontal(); - String parent = horizontal ? "horizontal" : "vertical"; + String parent = horizontal ? "horizontal" : hasFilter ? "vertical" : "vertical_filterless"; BlockModelBuilder model = p.models() .withExistingParent("block/" + type + "_funnel_" + parent + extracting + powered, diff --git a/src/main/java/com/simibubi/create/content/schematics/SchematicWorld.java b/src/main/java/com/simibubi/create/content/schematics/SchematicWorld.java index e414c36e6..06abab70c 100644 --- a/src/main/java/com/simibubi/create/content/schematics/SchematicWorld.java +++ b/src/main/java/com/simibubi/create/content/schematics/SchematicWorld.java @@ -34,11 +34,12 @@ import net.minecraft.world.biome.Biomes; public class SchematicWorld extends WrappedWorld { - private Map blocks; - private Map tileEntities; - private List renderedTileEntities; - private List entities; - private MutableBoundingBox bounds; + protected Map blocks; + protected Map tileEntities; + protected List renderedTileEntities; + protected List entities; + protected MutableBoundingBox bounds; + public BlockPos anchor; public boolean renderMode; @@ -179,6 +180,18 @@ public class SchematicWorld extends WrappedWorld { pos = pos.subtract(anchor); bounds.expandTo(new MutableBoundingBox(pos, pos)); blocks.put(pos, arg1); + if (tileEntities.containsKey(pos)) { + TileEntity tileEntity = tileEntities.get(pos); + if (!tileEntity.getType().isValidBlock(arg1.getBlock())) { + tileEntities.remove(pos); + renderedTileEntities.remove(tileEntity); + } + } + + TileEntity tileEntity = getTileEntity(pos); + if (tileEntity != null) + tileEntities.put(pos, tileEntity); + return true; } diff --git a/src/main/java/com/simibubi/create/content/schematics/client/SchematicRenderer.java b/src/main/java/com/simibubi/create/content/schematics/client/SchematicRenderer.java index c7c346182..e5ff4732c 100644 --- a/src/main/java/com/simibubi/create/content/schematics/client/SchematicRenderer.java +++ b/src/main/java/com/simibubi/create/content/schematics/client/SchematicRenderer.java @@ -23,6 +23,7 @@ import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderTypeLookup; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.BlockPos; import net.minecraftforge.client.ForgeHooksClient; import net.minecraftforge.client.model.data.EmptyModelData; @@ -110,8 +111,12 @@ public class SchematicRenderer { BufferBuilder bufferBuilder = buffers.get(blockRenderLayer); if (startedBufferBuilders.add(blockRenderLayer)) bufferBuilder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK); + + TileEntity tileEntity = blockAccess.getTileEntity(localPos); + if (blockRendererDispatcher.renderModel(state, pos, blockAccess, ms, bufferBuilder, true, - minecraft.world.rand, EmptyModelData.INSTANCE)) { + minecraft.world.rand, + tileEntity != null ? tileEntity.getModelData() : EmptyModelData.INSTANCE)) { usedBlockRenderLayers.add(blockRenderLayer); } blockstates.add(state); diff --git a/src/main/java/com/simibubi/create/content/schematics/client/tools/DeployTool.java b/src/main/java/com/simibubi/create/content/schematics/client/tools/DeployTool.java index ea5de6a18..6dba9fb9e 100644 --- a/src/main/java/com/simibubi/create/content/schematics/client/tools/DeployTool.java +++ b/src/main/java/com/simibubi/create/content/schematics/client/tools/DeployTool.java @@ -67,7 +67,7 @@ public class DeployTool extends PlacementToolBase { .translateBack(origin); AABBOutline outline = schematicHandler.getOutline(); - outline.render(ms, buffer); + outline.render(ms, buffer, pt); outline.getParams() .clearTextures(); ms.pop(); diff --git a/src/main/java/com/simibubi/create/content/schematics/client/tools/FlipTool.java b/src/main/java/com/simibubi/create/content/schematics/client/tools/FlipTool.java index 32eb4c7fd..28f06d271 100644 --- a/src/main/java/com/simibubi/create/content/schematics/client/tools/FlipTool.java +++ b/src/main/java/com/simibubi/create/content/schematics/client/tools/FlipTool.java @@ -3,6 +3,7 @@ package com.simibubi.create.content.schematics.client.tools; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllSpecialTextures; import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer; +import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.outliner.AABBOutline; import net.minecraft.util.Direction; @@ -74,7 +75,7 @@ public class FlipTool extends PlacementToolBase { .disableNormals() .colored(0xdddddd) .withFaceTextures(tex, tex); - outline.render(ms, buffer); + outline.render(ms, buffer, AnimationTickHolder.getPartialTicks()); super.renderOnSchematic(ms, buffer); } diff --git a/src/main/java/com/simibubi/create/content/schematics/client/tools/RotateTool.java b/src/main/java/com/simibubi/create/content/schematics/client/tools/RotateTool.java index 8c34beb39..e0c0eecc6 100644 --- a/src/main/java/com/simibubi/create/content/schematics/client/tools/RotateTool.java +++ b/src/main/java/com/simibubi/create/content/schematics/client/tools/RotateTool.java @@ -2,6 +2,7 @@ package com.simibubi.create.content.schematics.client.tools; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer; +import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.outliner.LineOutline; import net.minecraft.util.math.AxisAlignedBB; @@ -35,7 +36,7 @@ public class RotateTool extends PlacementToolBase { .colored(0xdddddd) .lineWidth(1 / 16f); line.set(start, end) - .render(ms, buffer); + .render(ms, buffer, AnimationTickHolder.getPartialTicks()); super.renderOnSchematic(ms, buffer); } diff --git a/src/main/java/com/simibubi/create/content/schematics/client/tools/SchematicToolBase.java b/src/main/java/com/simibubi/create/content/schematics/client/tools/SchematicToolBase.java index 6a7863831..ae07bed15 100644 --- a/src/main/java/com/simibubi/create/content/schematics/client/tools/SchematicToolBase.java +++ b/src/main/java/com/simibubi/create/content/schematics/client/tools/SchematicToolBase.java @@ -143,7 +143,7 @@ public abstract class SchematicToolBase implements ISchematicTool { .colored(0x6886c5) .withFaceTexture(AllSpecialTextures.CHECKERED) .lineWidth(1 / 16f); - outline.render(ms, buffer); + outline.render(ms, buffer, AnimationTickHolder.getPartialTicks()); outline.getParams() .clearTextures(); ms.pop(); diff --git a/src/main/java/com/simibubi/create/events/ClientEvents.java b/src/main/java/com/simibubi/create/events/ClientEvents.java index 7aeca6f3b..fbb370c09 100644 --- a/src/main/java/com/simibubi/create/events/ClientEvents.java +++ b/src/main/java/com/simibubi/create/events/ClientEvents.java @@ -1,8 +1,5 @@ package com.simibubi.create.events; -import java.util.ArrayList; -import java.util.List; - import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.systems.RenderSystem; import com.simibubi.create.AllFluids; @@ -25,10 +22,10 @@ import com.simibubi.create.content.curiosities.zapper.blockzapper.BlockzapperRen import com.simibubi.create.content.curiosities.zapper.terrainzapper.WorldshaperRenderHandler; import com.simibubi.create.content.logistics.block.mechanicalArm.ArmInteractionPointHandler; import com.simibubi.create.foundation.config.AllConfigs; -import com.simibubi.create.foundation.gui.ScreenOpener; import com.simibubi.create.foundation.item.TooltipHelper; import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.networking.LeftClickPacket; +import com.simibubi.create.foundation.ponder.PonderTooltipHandler; import com.simibubi.create.foundation.render.backend.FastRenderDispatcher; import com.simibubi.create.foundation.render.backend.RenderWork; import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer; @@ -39,7 +36,6 @@ import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollVal import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.ServerSpeedProvider; import com.simibubi.create.foundation.utility.placement.PlacementHelpers; - import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.ActiveRenderInfo; import net.minecraft.client.renderer.IRenderTypeBuffer; @@ -56,6 +52,7 @@ import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.client.event.EntityViewRenderEvent; import net.minecraftforge.client.event.RenderGameOverlayEvent; import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType; +import net.minecraftforge.client.event.RenderTooltipEvent; import net.minecraftforge.client.event.RenderWorldLastEvent; import net.minecraftforge.event.TickEvent.ClientTickEvent; import net.minecraftforge.event.TickEvent.Phase; @@ -66,6 +63,9 @@ import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod.EventBusSubscriber; +import java.util.ArrayList; +import java.util.List; + @EventBusSubscriber(value = Dist.CLIENT) public class ClientEvents { @@ -92,7 +92,8 @@ public class ClientEvents { CapabilityMinecartController.tick(world); CouplingPhysics.tick(world); - ScreenOpener.tick(); + PonderTooltipHandler.tick(); + //ScreenOpener.tick(); ServerSpeedProvider.clientTick(); BeltConnectorHandler.tick(); FilteringRenderer.tick(); @@ -136,6 +137,7 @@ public class ClientEvents { @SubscribeEvent public static void onRenderWorld(RenderWorldLastEvent event) { Vec3d cameraPos = Minecraft.getInstance().gameRenderer.getActiveRenderInfo().getProjectedView(); + float pt = AnimationTickHolder.getPartialTicks(); MatrixStack ms = event.getMatrixStack(); ms.push(); @@ -146,9 +148,8 @@ public class ClientEvents { CreateClient.schematicHandler.render(ms, buffer); CreateClient.ghostBlocks.renderAll(ms, buffer); - CreateClient.outliner.renderOutlines(ms, buffer); + CreateClient.outliner.renderOutlines(ms, buffer, pt); // LightVolumeDebugger.render(ms, buffer); -// CollisionDebugger.render(ms, buffer); buffer.draw(); RenderSystem.enableCull(); @@ -172,6 +173,11 @@ public class ClientEvents { CreateClient.schematicHandler.renderOverlay(ms, buffer, light, overlay); } + @SubscribeEvent + public static void getItemTooltipColor(RenderTooltipEvent.Color event) { + PonderTooltipHandler.handleTooltipColor(event); + } + @SubscribeEvent public static void addToItemTooltip(ItemTooltipEvent event) { if (!AllConfigs.CLIENT.tooltips.get()) @@ -193,7 +199,8 @@ public class ClientEvents { .addInformation(toolTip); itemTooltip.addAll(0, toolTip); } - + + PonderTooltipHandler.addToTooltip(event.getToolTip(), stack); } @SubscribeEvent diff --git a/src/main/java/com/simibubi/create/foundation/collision/CollisionDebugger.java b/src/main/java/com/simibubi/create/foundation/collision/CollisionDebugger.java deleted file mode 100644 index 0f697c166..000000000 --- a/src/main/java/com/simibubi/create/foundation/collision/CollisionDebugger.java +++ /dev/null @@ -1,114 +0,0 @@ -package com.simibubi.create.foundation.collision; - -import com.mojang.blaze3d.matrix.MatrixStack; -import com.simibubi.create.AllSpecialTextures; -import com.simibubi.create.CreateClient; -import com.simibubi.create.foundation.collision.ContinuousOBBCollider.ContinuousSeparationManifold; -import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer; -import com.simibubi.create.foundation.utility.AngleHelper; -import com.simibubi.create.foundation.utility.MatrixStacker; -import com.simibubi.create.foundation.utility.outliner.AABBOutline; - -import net.minecraft.client.Minecraft; -import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.BlockRayTraceResult; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.math.RayTraceResult.Type; -import net.minecraft.util.math.Vec3d; - -public class CollisionDebugger { - - public static AxisAlignedBB AABB = new AxisAlignedBB(BlockPos.ZERO.up(10)); - public static OrientedBB OBB = new OrientedBB(new AxisAlignedBB(BlockPos.ZERO)); - public static Vec3d motion = Vec3d.ZERO; - static ContinuousSeparationManifold seperation; - static double angle = 0; - static AABBOutline outline; - - public static void onScroll(double delta) { - angle += delta; - angle = (int) angle; - OBB.setRotation(new Matrix3d().asZRotation(AngleHelper.rad(angle))); - } - - public static void render(MatrixStack ms, SuperRenderTypeBuffer buffer) { - ms.push(); - outline = new AABBOutline(OBB.getAsAxisAlignedBB()); - outline.getParams() - .withFaceTexture(seperation == null ? AllSpecialTextures.CHECKERED : null) - .colored(0xffffff); - if (seperation != null) - outline.getParams() - .lineWidth(1 / 64f) - .colored(0xff6544); - MatrixStacker.of(ms) - .translate(OBB.center); - ms.peek() - .getModel() - .multiply(OBB.rotation.getAsMatrix4f()); - MatrixStacker.of(ms) - .translateBack(OBB.center); - outline.render(ms, buffer); - ms.pop(); - -// ms.push(); -// if (motion.length() != 0 && (seperation == null || seperation.getTimeOfImpact() != 1)) { -// outline.getParams() -// .colored(0x6544ff) -// .lineWidth(1 / 32f); -// MatrixStacker.of(ms) -// .translate(seperation != null ? seperation.getAllowedMotion(motion) : motion) -// .translate(OBB.center); -// ms.peek() -// .getModel() -// .multiply(OBB.rotation.getAsMatrix4f()); -// MatrixStacker.of(ms) -// .translateBack(OBB.center); -// outline.render(ms, buffer); -// } -// ms.pop(); - - ms.push(); - if (seperation != null) { - Vec3d asSeparationVec = seperation.asSeparationVec(.5f); - if (asSeparationVec != null) { - outline.getParams() - .colored(0x65ff44) - .lineWidth(1 / 32f); - MatrixStacker.of(ms) - .translate(asSeparationVec) - .translate(OBB.center); - ms.peek() - .getModel() - .multiply(OBB.rotation.getAsMatrix4f()); - MatrixStacker.of(ms) - .translateBack(OBB.center); - outline.render(ms, buffer); - } - } - ms.pop(); - } - - public static void tick() { - AABB = new AxisAlignedBB(BlockPos.ZERO.up(60)).offset(.5, 0, .5); - motion = Vec3d.ZERO; - RayTraceResult mouse = Minecraft.getInstance().objectMouseOver; - if (mouse != null && mouse.getType() == Type.BLOCK) { - BlockRayTraceResult hit = (BlockRayTraceResult) mouse; - OBB.setCenter(hit.getHitVec()); - seperation = OBB.intersect(AABB, motion); - } - CreateClient.outliner.showAABB(AABB, AABB) - .withFaceTexture(seperation == null ? AllSpecialTextures.CHECKERED : null); - } - - static void showDebugLine(Vec3d relativeStart, Vec3d relativeEnd, int color, String id, int offset) { - Vec3d center = CollisionDebugger.AABB.getCenter() - .add(0, 1 + offset / 16f, 0); - CreateClient.outliner.showLine(id + OBBCollider.checkCount, center.add(relativeStart), center.add(relativeEnd)) - .colored(color) - .lineWidth(1 / 32f); - } - -} diff --git a/src/main/java/com/simibubi/create/foundation/collision/OBBCollider.java b/src/main/java/com/simibubi/create/foundation/collision/OBBCollider.java index daf13ab6b..ece63976a 100644 --- a/src/main/java/com/simibubi/create/foundation/collision/OBBCollider.java +++ b/src/main/java/com/simibubi/create/foundation/collision/OBBCollider.java @@ -1,6 +1,5 @@ package com.simibubi.create.foundation.collision; -import static com.simibubi.create.foundation.collision.CollisionDebugger.showDebugLine; import static java.lang.Math.abs; import static java.lang.Math.signum; @@ -60,7 +59,6 @@ public class OBBCollider { if (diff > 0) return true; -// boolean isBestSeperation = distance != 0 && -(diff) <= abs(bestSeparation.getValue()); boolean isBestSeperation = checkCount == 2; // Debug specific separations if (isBestSeperation) { @@ -68,17 +66,6 @@ public class OBBCollider { double value = sTL * abs(diff); mf.axis = axis.normalize(); mf.separation = value; - - // Visualize values - if (CollisionDebugger.AABB != null) { - Vec3d normalizedAxis = axis.normalize(); - showDebugLine(Vec3d.ZERO, normalizedAxis.scale(TL), 0xbb00bb, "tl", 4); - showDebugLine(Vec3d.ZERO, normalizedAxis.scale(sTL * rA), 0xff4444, "ra", 3); - showDebugLine(normalizedAxis.scale(sTL * (distance - rB)), normalizedAxis.scale(TL), 0x4444ff, "rb", 2); - showDebugLine(normalizedAxis.scale(sTL * (distance - rB)), - normalizedAxis.scale(sTL * (distance - rB) + value), 0xff9966, "separation", 1); - System.out.println("TL:" + TL + ", rA: " + rA + ", rB: " + rB); - } } return false; diff --git a/src/main/java/com/simibubi/create/foundation/command/AllCommands.java b/src/main/java/com/simibubi/create/foundation/command/AllCommands.java index 2f9471abb..b45ee6143 100644 --- a/src/main/java/com/simibubi/create/foundation/command/AllCommands.java +++ b/src/main/java/com/simibubi/create/foundation/command/AllCommands.java @@ -1,16 +1,17 @@ package com.simibubi.create.foundation.command; +import java.util.Collections; +import java.util.function.Predicate; + import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.tree.CommandNode; import com.mojang.brigadier.tree.LiteralCommandNode; + import net.minecraft.command.CommandSource; import net.minecraft.command.Commands; import net.minecraft.entity.player.PlayerEntity; -import java.util.Collections; -import java.util.function.Predicate; - public class AllCommands { public static Predicate sourceIsPlayer = (cs) -> cs.getEntity() instanceof PlayerEntity; @@ -29,6 +30,7 @@ public class AllCommands { .then(HighlightCommand.register()) .then(CouplingCommand.register()) .then(CloneCommand.register()) + .then(PonderCommand.register()) //utility .then(util) diff --git a/src/main/java/com/simibubi/create/foundation/command/ConfigureConfigPacket.java b/src/main/java/com/simibubi/create/foundation/command/ConfigureConfigPacket.java index 692933155..bb54b2db4 100644 --- a/src/main/java/com/simibubi/create/foundation/command/ConfigureConfigPacket.java +++ b/src/main/java/com/simibubi/create/foundation/command/ConfigureConfigPacket.java @@ -4,6 +4,7 @@ import com.simibubi.create.content.contraptions.goggles.GoggleConfigScreen; import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.gui.ScreenOpener; import com.simibubi.create.foundation.networking.SimplePacketBase; +import com.simibubi.create.foundation.ponder.content.PonderIndexScreen; import com.simibubi.create.foundation.render.backend.FastRenderDispatcher; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.player.ClientPlayerEntity; @@ -65,6 +66,7 @@ public class ConfigureConfigPacket extends SimplePacketBase { fixLighting(() -> Actions::experimentalLighting), overlayReset(() -> Actions::overlayReset), experimentalRendering(() -> Actions::experimentalRendering), + ponderIndex(() -> Actions::ponderIndex), ; @@ -130,6 +132,11 @@ public class ConfigureConfigPacket extends SimplePacketBase { Minecraft.getInstance().worldRenderer.loadRenderers(); } + @OnlyIn(Dist.CLIENT) + private static void ponderIndex(String value) { + ScreenOpener.transitionTo(new PonderIndexScreen()); + } + private static ITextComponent boolToText(boolean b) { return b ? new StringTextComponent("enabled").applyTextStyle(TextFormatting.DARK_GREEN) diff --git a/src/main/java/com/simibubi/create/foundation/command/PonderCommand.java b/src/main/java/com/simibubi/create/foundation/command/PonderCommand.java new file mode 100644 index 000000000..b69b5664b --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/command/PonderCommand.java @@ -0,0 +1,25 @@ +package com.simibubi.create.foundation.command; + +import com.mojang.brigadier.builder.ArgumentBuilder; +import com.simibubi.create.foundation.networking.AllPackets; +import net.minecraft.command.CommandSource; +import net.minecraft.command.Commands; +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraftforge.fml.network.PacketDistributor; + +public class PonderCommand { + + static ArgumentBuilder register() { + return Commands.literal("ponder") + .requires(cs -> cs.hasPermissionLevel(0)) + .executes(ctx -> { + ServerPlayerEntity player = ctx.getSource().asPlayer(); + + AllPackets.channel.send( + PacketDistributor.PLAYER.with(() -> player), + new ConfigureConfigPacket(ConfigureConfigPacket.Actions.ponderIndex.name(), "")); + + return 1; + }); + } +} diff --git a/src/main/java/com/simibubi/create/foundation/data/AllLangPartials.java b/src/main/java/com/simibubi/create/foundation/data/AllLangPartials.java index 34dcfeb86..6c71f4d97 100644 --- a/src/main/java/com/simibubi/create/foundation/data/AllLangPartials.java +++ b/src/main/java/com/simibubi/create/foundation/data/AllLangPartials.java @@ -1,21 +1,49 @@ package com.simibubi.create.foundation.data; +import com.google.common.base.Supplier; +import com.google.gson.JsonElement; +import com.simibubi.create.Create; +import com.simibubi.create.foundation.ponder.PonderRegistry; +import com.simibubi.create.foundation.utility.FilesHelper; +import com.simibubi.create.foundation.utility.Lang; + public enum AllLangPartials { - + ADVANCEMENTS("Advancements"), MESSAGES("UI & Messages"), TOOLTIPS("Item Descriptions"), - + PONDER("Ponder Content", PonderRegistry::provideLangEntries), + ; - + private String display; + private Supplier provider; private AllLangPartials(String display) { this.display = display; + this.provider = this::fromResource; + } + + private AllLangPartials(String display, Supplier customProvider) { + this.display = display; + this.provider = customProvider; } public String getDisplay() { return display; } + public JsonElement provide() { + return provider.get(); + } + + private JsonElement fromResource() { + String fileName = Lang.asId(name()); + String filepath = "assets/" + Create.ID + "/lang/default/" + fileName + ".json"; + JsonElement element = FilesHelper.loadJsonResource(filepath); + if (element == null) + throw new IllegalStateException(String.format("Could not find default lang file: %s", filepath)); + return element; + } + } diff --git a/src/main/java/com/simibubi/create/foundation/data/LangMerger.java b/src/main/java/com/simibubi/create/foundation/data/LangMerger.java index d51631052..a4426a706 100644 --- a/src/main/java/com/simibubi/create/foundation/data/LangMerger.java +++ b/src/main/java/com/simibubi/create/foundation/data/LangMerger.java @@ -23,8 +23,8 @@ import com.google.gson.GsonBuilder; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.simibubi.create.Create; +import com.simibubi.create.foundation.ponder.PonderScene; import com.simibubi.create.foundation.utility.FilesHelper; -import com.simibubi.create.foundation.utility.Lang; import net.minecraft.data.DataGenerator; import net.minecraft.data.DirectoryCache; @@ -45,12 +45,28 @@ public class LangMerger implements IDataProvider { private Map> allLocalizedEntries; private Map missingTranslationTally; + private List langIgnore; + public LangMerger(DataGenerator gen) { this.gen = gen; this.mergedLangData = new ArrayList<>(); + this.langIgnore = new ArrayList<>(); this.allLocalizedEntries = new HashMap<>(); this.populatedLangData = new HashMap<>(); this.missingTranslationTally = new HashMap<>(); + populateLangIgnore(); + } + + private void populateLangIgnore() { + // Key prefixes added here will NOT be transferred to lang templates + langIgnore.add("create.ponder.debug_"); // Ponder debug scene text + } + + private boolean shouldIgnore(String key) { + for (String string : langIgnore) + if (key.startsWith(string)) + return true; + return false; } @Override @@ -128,6 +144,8 @@ public class LangMerger implements IDataProvider { .stream() .forEachOrdered(entry -> { String key = entry.getKey(); + if (shouldIgnore(key)) + return; String value = entry.getValue() .getAsString(); if (!previousKey.getValue() @@ -158,9 +176,11 @@ public class LangMerger implements IDataProvider { } protected boolean shouldAddLineBreak(String key, String previousKey) { - // Always put tooltips in their own paragraphs + // Always put tooltips and ponder scenes in their own paragraphs if (key.endsWith(".tooltip")) return true; + if (key.startsWith("create.ponder") && key.endsWith(PonderScene.TITLE_KEY)) + return true; key = key.replaceFirst("\\.", ""); previousKey = previousKey.replaceFirst("\\.", ""); @@ -201,14 +221,9 @@ public class LangMerger implements IDataProvider { } private void collectEntries() { - for (AllLangPartials partial : AllLangPartials.values()) { - String fileName = Lang.asId(partial.name()); - String filepath = "assets/" + Create.ID + "/lang/default/" + fileName + ".json"; - JsonElement element = FilesHelper.loadJsonResource(filepath); - if (element == null) - throw new IllegalStateException(String.format("Could not find default lang file: %s", filepath)); - addAll(partial.getDisplay(), element.getAsJsonObject()); - } + for (AllLangPartials partial : AllLangPartials.values()) + addAll(partial.getDisplay(), partial.provide() + .getAsJsonObject()); } private void save(DirectoryCache cache, List dataIn, int missingKeys, Path target, String message) diff --git a/src/main/java/com/simibubi/create/foundation/data/recipe/StandardRecipeGen.java b/src/main/java/com/simibubi/create/foundation/data/recipe/StandardRecipeGen.java index 6227918e6..abe18a5b6 100644 --- a/src/main/java/com/simibubi/create/foundation/data/recipe/StandardRecipeGen.java +++ b/src/main/java/com/simibubi/create/foundation/data/recipe/StandardRecipeGen.java @@ -317,8 +317,8 @@ public class StandardRecipeGen extends CreateRecipeProvider { .patternLine("P") .patternLine("A") .patternLine("P")), - - GANTRY_PINION = create(AllBlocks.GANTRY_PINION).unlockedBy(I::andesiteCasing) + + GANTRY_PINION = create(AllBlocks.GANTRY_CARRIAGE).unlockedBy(I::andesiteCasing) .viaShaped(b -> b.key('B', ItemTags.PLANKS) .key('S', I.cog()) .key('C', I.andesiteCasing()) diff --git a/src/main/java/com/simibubi/create/foundation/gui/AbstractSimiContainerScreen.java b/src/main/java/com/simibubi/create/foundation/gui/AbstractSimiContainerScreen.java index 5ed72ec0e..106379330 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/AbstractSimiContainerScreen.java +++ b/src/main/java/com/simibubi/create/foundation/gui/AbstractSimiContainerScreen.java @@ -9,6 +9,7 @@ import javax.annotation.Nullable; import com.mojang.blaze3d.systems.RenderSystem; import com.simibubi.create.foundation.gui.widgets.AbstractSimiWidget; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.screen.inventory.ContainerScreen; import net.minecraft.client.gui.widget.Widget; @@ -41,6 +42,8 @@ public abstract class AbstractSimiContainerScreen extends C @Override public void render(int mouseX, int mouseY, float partialTicks) { + partialTicks = Minecraft.getInstance() + .getRenderPartialTicks(); renderBackground(); renderWindow(mouseX, mouseY, partialTicks); diff --git a/src/main/java/com/simibubi/create/foundation/gui/AbstractSimiScreen.java b/src/main/java/com/simibubi/create/foundation/gui/AbstractSimiScreen.java index 1ec2a4129..874bfeba7 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/AbstractSimiScreen.java +++ b/src/main/java/com/simibubi/create/foundation/gui/AbstractSimiScreen.java @@ -2,9 +2,18 @@ package com.simibubi.create.foundation.gui; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; +import org.apache.commons.lang3.mutable.MutableBoolean; +import org.apache.commons.lang3.mutable.MutableInt; +import org.lwjgl.glfw.GLFW; + +import com.mojang.blaze3d.systems.RenderSystem; import com.simibubi.create.foundation.gui.widgets.AbstractSimiWidget; +import com.simibubi.create.foundation.utility.LerpedFloat; +import net.minecraft.client.MainWindow; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.widget.Widget; import net.minecraft.util.text.StringTextComponent; @@ -16,11 +25,19 @@ public abstract class AbstractSimiScreen extends Screen { protected int sWidth, sHeight; protected int guiLeft, guiTop; + protected int depthPointX, depthPointY; protected List widgets; + public final LerpedFloat transition = LerpedFloat.linear() + .startWithValue(0) + .chase(0, .1f, LerpedFloat.Chaser.LINEAR); protected AbstractSimiScreen() { super(new StringTextComponent("")); widgets = new ArrayList<>(); + MainWindow window = Minecraft.getInstance() + .getWindow(); + depthPointX = window.getScaledWidth() / 2; + depthPointY = window.getScaledHeight() / 2; } protected void setWindowSize(int width, int height) { @@ -30,33 +47,108 @@ public abstract class AbstractSimiScreen extends Screen { guiTop = (this.height - sHeight) / 2; } + @Override + public void tick() { + super.tick(); + transition.tickChaser(); + } + @Override public void render(int mouseX, int mouseY, float partialTicks) { - renderBackground(); + partialTicks = partialTicks == 10 ? 0 + : Minecraft.getInstance() + .getRenderPartialTicks(); + + RenderSystem.pushMatrix(); + + renderTransition(mouseX, mouseY, partialTicks); + renderWindow(mouseX, mouseY, partialTicks); for (Widget widget : widgets) widget.render(mouseX, mouseY, partialTicks); + renderWindowForeground(mouseX, mouseY, partialTicks); for (Widget widget : widgets) widget.renderToolTip(mouseX, mouseY); + + RenderSystem.popMatrix(); + + renderBreadcrumbs(mouseX, mouseY, partialTicks); + } + + private void renderTransition(int mouseX, int mouseY, float partialTicks) { + if (transition.getChaseTarget() == 0) { + renderBackground(); + return; + } + + renderBackground(); + + Screen lastScreen = ScreenOpener.getPreviouslyRenderedScreen(); + float transitionValue = transition.getValue(partialTicks); + double scale = 1 + 0.5 * transitionValue; + + // draw last screen into buffer + if (lastScreen != null && lastScreen != this) { + RenderSystem.pushMatrix();// 1 + UIRenderHelper.framebuffer.framebufferClear(Minecraft.IS_RUNNING_ON_MAC); + UIRenderHelper.prepFramebufferSize(); + RenderSystem.pushMatrix();// 2 + RenderSystem.translated(0, 0, -1000); + UIRenderHelper.framebuffer.bindFramebuffer(true); + lastScreen.render(mouseX, mouseY, 10); + RenderSystem.popMatrix();// 2 + + // use the buffer texture + Minecraft.getInstance() + .getFramebuffer() + .bindFramebuffer(true); + + MainWindow window = Minecraft.getInstance() + .getWindow(); + int dpx = window.getScaledWidth() / 2; + int dpy = window.getScaledHeight() / 2; + if (lastScreen instanceof AbstractSimiScreen) { + dpx = ((AbstractSimiScreen) lastScreen).depthPointX; + dpy = ((AbstractSimiScreen) lastScreen).depthPointY; + } + + // transitionV is 1/-1 when the older screen is hidden + // transitionV is 0 when the older screen is still fully visible + RenderSystem.translated(dpx, dpy, 0); + RenderSystem.scaled(scale, scale, 1); + RenderSystem.translated(-dpx, -dpy, 0); + UIRenderHelper.drawFramebuffer(1f - Math.abs(transitionValue)); + RenderSystem.popMatrix();// 1 + } + + // modify current screen as well + scale = transitionValue > 0 ? 1 - 0.5 * (1 - transitionValue) : 1 + .5 * (1 + transitionValue); + RenderSystem.translated(depthPointX, depthPointY, 0); + RenderSystem.scaled(scale, scale, 1); + RenderSystem.translated(-depthPointX, -depthPointY, 0); } @Override public boolean mouseClicked(double x, double y, int button) { boolean result = false; - for (Widget widget : widgets) { + for (Widget widget : widgets) if (widget.mouseClicked(x, y, button)) result = true; - } return result; } @Override public boolean keyPressed(int code, int p_keyPressed_2_, int p_keyPressed_3_) { - for (Widget widget : widgets) { + for (Widget widget : widgets) if (widget.keyPressed(code, p_keyPressed_2_, p_keyPressed_3_)) return true; + + if (code == GLFW.GLFW_KEY_BACKSPACE) { + ScreenOpener.openPreviousScreen(this); + return true; } + return super.keyPressed(code, p_keyPressed_2_, p_keyPressed_3_); } @@ -79,7 +171,7 @@ public abstract class AbstractSimiScreen extends Screen { } return super.mouseScrolled(mouseX, mouseY, delta); } - + @Override public boolean mouseReleased(double x, double y, int button) { boolean result = false; @@ -95,6 +187,12 @@ public abstract class AbstractSimiScreen extends Screen { return true; } + @Override + public void onClose() { + ScreenOpener.clearStack(); + super.onClose(); + } + @Override public boolean isPauseScreen() { return false; @@ -102,15 +200,84 @@ public abstract class AbstractSimiScreen extends Screen { protected abstract void renderWindow(int mouseX, int mouseY, float partialTicks); + protected void renderBreadcrumbs(int mouseX, int mouseY, float partialTicks) { + List history = ScreenOpener.getScreenHistory(); + if (history.isEmpty()) + return; + + history.add(0, Minecraft.getInstance().currentScreen); + int spacing = 20; + + List names = history.stream() + .map(AbstractSimiScreen::screenTitle) + .collect(Collectors.toList()); + + int bWidth = names.stream() + .mapToInt(s -> font.getStringWidth(s) + spacing) + .sum(); + + MutableInt x = new MutableInt(width - bWidth); + MutableInt y = new MutableInt(height - 18); + MutableBoolean first = new MutableBoolean(true); + + if (x.getValue() < 25) + x.setValue(25); + + RenderSystem.pushMatrix(); + RenderSystem.translated(0, 0, 600); + names.forEach(s -> { + int sWidth = font.getStringWidth(s); + // UIRenderHelper.breadcrumbArrow(x.getValue(), y.getValue(), sWidth + spacing, + // 14, spacing/2, 0xbbababab, 0x22ababab); + UIRenderHelper.breadcrumbArrow(x.getValue(), y.getValue(), sWidth + spacing, 14, spacing / 2, 0xdd101010, + 0x44101010); + drawString(font, s, x.getValue() + 5, y.getValue() + 3, first.getValue() ? 0xffeeffee : 0xffddeeff); + first.setFalse(); + + x.add(sWidth + spacing); + }); + RenderSystem.popMatrix(); + } + + private static String screenTitle(Screen screen) { + if (screen instanceof AbstractSimiScreen) + return ((AbstractSimiScreen) screen).getBreadcrumbTitle(); + + return screen.getClass() + .getSimpleName(); + } + + protected String getBreadcrumbTitle() { + return this.getClass() + .getSimpleName(); + } + protected void renderWindowForeground(int mouseX, int mouseY, float partialTicks) { for (Widget widget : widgets) { if (!widget.isHovered()) continue; - - if (widget instanceof AbstractSimiWidget && !((AbstractSimiWidget) widget).getToolTip().isEmpty()) { + + if (widget instanceof AbstractSimiWidget && !((AbstractSimiWidget) widget).getToolTip() + .isEmpty()) { renderTooltip(((AbstractSimiWidget) widget).getToolTip(), mouseX, mouseY); } } } + public void centerScalingOn(int x, int y) { + depthPointX = x; + depthPointY = y; + } + + public void centerScalingOnMouse() { + MainWindow w = minecraft.getWindow(); + double mouseX = minecraft.mouseHelper.getMouseX() * w.getScaledWidth() / w.getWidth(); + double mouseY = minecraft.mouseHelper.getMouseY() * w.getScaledHeight() / w.getHeight(); + centerScalingOn((int) mouseX, (int) mouseY); + } + + public boolean isEquivalentTo(AbstractSimiScreen other) { + return false; + } + } diff --git a/src/main/java/com/simibubi/create/foundation/gui/AllGuiTextures.java b/src/main/java/com/simibubi/create/foundation/gui/AllGuiTextures.java index f74b305d4..b69069be6 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/AllGuiTextures.java +++ b/src/main/java/com/simibubi/create/foundation/gui/AllGuiTextures.java @@ -1,15 +1,13 @@ package com.simibubi.create.foundation.gui; import com.simibubi.create.Create; - import net.minecraft.client.Minecraft; import net.minecraft.client.gui.AbstractGui; -import net.minecraft.client.gui.screen.Screen; import net.minecraft.util.ResourceLocation; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; -public enum AllGuiTextures { +public enum AllGuiTextures implements IScreenRenderable { // Inventories PLAYER_INVENTORY("player_inventory.png", 176, 108), @@ -79,6 +77,9 @@ public enum AllGuiTextures { INDICATOR_GREEN("widgets.png", 36, 18, 18, 6), INDICATOR_YELLOW("widgets.png", 54, 18, 18, 6), INDICATOR_RED("widgets.png", 72, 18, 18, 6), + + SPEECH_TOOLTIP("widgets.png", 0, 24, 8, 8), + SPEECH_TOOLTIP_HIGHLIGHT("widgets.png", 8, 24, 8, 8), // PlacementIndicator PLACEMENT_INDICATOR_SHEET("placement_indicator.png", 0, 0, 16, 256); @@ -114,16 +115,10 @@ public enum AllGuiTextures { .bindTexture(location); } + @Override @OnlyIn(Dist.CLIENT) public void draw(AbstractGui screen, int x, int y) { bind(); screen.blit(x, y, startX, startY, width, height); } - - @OnlyIn(Dist.CLIENT) - public void draw(int x, int y) { - draw(new Screen(null) { - }, x, y); - } - } diff --git a/src/main/java/com/simibubi/create/foundation/gui/AllIcons.java b/src/main/java/com/simibubi/create/foundation/gui/AllIcons.java index c1279fce0..17806fb70 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/AllIcons.java +++ b/src/main/java/com/simibubi/create/foundation/gui/AllIcons.java @@ -5,10 +5,8 @@ import com.mojang.blaze3d.matrix.MatrixStack.Entry; import com.mojang.blaze3d.vertex.IVertexBuilder; import com.simibubi.create.Create; import com.simibubi.create.foundation.utility.ColorHelper; - import net.minecraft.client.Minecraft; import net.minecraft.client.gui.AbstractGui; -import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.RenderType; import net.minecraft.util.ResourceLocation; @@ -16,7 +14,7 @@ import net.minecraft.util.math.Vec3d; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; -public class AllIcons { +public class AllIcons implements IScreenRenderable { public static final ResourceLocation ICON_ATLAS = Create.asResource("textures/gui/icons.png"); private static int x = 0, y = -1; @@ -70,7 +68,10 @@ public class AllIcons { I_REPLACE = next(), I_CLEAR = next(), I_OVERLAY = next(), - I_FLATTEN = next(); + I_FLATTEN = next(), + I_LMB = next(), + I_SCROLL = next(), + I_RMB = next(); public static final AllIcons I_TOOL_DEPLOY = newRow(), @@ -115,7 +116,13 @@ public class AllIcons { I_FOLLOW_DIAGONAL = next(), I_FOLLOW_MATERIAL = next(), - I_SCHEMATIC = newRow(); + I_SCHEMATIC = newRow(), + + I_MTD_LEFT = newRow(), + I_MTD_CLOSE = next(), + I_MTD_RIGHT = next(), + I_MTD_SCAN = next(), + I_MTD_REPLAY = next(); public AllIcons(int x, int y) { iconX = x * 16; @@ -137,18 +144,13 @@ public class AllIcons { .bindTexture(ICON_ATLAS); } + @Override @OnlyIn(Dist.CLIENT) public void draw(AbstractGui screen, int x, int y) { bind(); screen.blit(x, y, iconX, iconY, 16, 16); } - @OnlyIn(Dist.CLIENT) - public void draw(int x, int y) { - draw(new Screen(null) { - }, x, y); - } - @OnlyIn(Dist.CLIENT) public void draw(MatrixStack ms, IRenderTypeBuffer buffer, int color) { IVertexBuilder builder = buffer.getBuffer(RenderType.getTextSeeThrough(ICON_ATLAS)); diff --git a/src/main/java/com/simibubi/create/foundation/gui/IScreenRenderable.java b/src/main/java/com/simibubi/create/foundation/gui/IScreenRenderable.java new file mode 100644 index 000000000..d4e16c6aa --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/gui/IScreenRenderable.java @@ -0,0 +1,18 @@ +package com.simibubi.create.foundation.gui; + +import net.minecraft.client.gui.AbstractGui; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.util.text.StringTextComponent; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; + +public interface IScreenRenderable { + + @OnlyIn(Dist.CLIENT) + void draw(AbstractGui screen, int x, int y); + + @OnlyIn(Dist.CLIENT) + default void draw(int x, int y) { + draw(new Screen(new StringTextComponent("")) {}, x, y); + } +} diff --git a/src/main/java/com/simibubi/create/foundation/gui/ScreenOpener.java b/src/main/java/com/simibubi/create/foundation/gui/ScreenOpener.java index bef5042de..82f736791 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/ScreenOpener.java +++ b/src/main/java/com/simibubi/create/foundation/gui/ScreenOpener.java @@ -1,29 +1,91 @@ package com.simibubi.create.foundation.gui; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Deque; +import java.util.List; + +import javax.annotation.Nullable; + +import com.simibubi.create.foundation.utility.LerpedFloat; + import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screen.Screen; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; -import net.minecraftforge.fml.DistExecutor; public class ScreenOpener { - @OnlyIn(Dist.CLIENT) - private static Screen openedGuiNextTick; + private static final Deque backStack = new ArrayDeque<>(); + private static Screen backSteppedFrom = null; - public static void tick() { - DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> { - if (openedGuiNextTick != null) { - Minecraft.getInstance().displayGuiScreen(openedGuiNextTick); - openedGuiNextTick = null; - } - }); + public static void open(Screen screen) { + open(Minecraft.getInstance().currentScreen, screen); } - public static void open(Screen gui) { - DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> { - openedGuiNextTick = gui; - }); + public static void open(@Nullable Screen current, Screen toOpen) { + backSteppedFrom = null; + if (current != null) { + if (backStack.size() >= 15) // don't go deeper than 15 steps + backStack.pollLast(); + + backStack.push(current); + } else + backStack.clear(); + + openScreen(toOpen); + } + + public static void openPreviousScreen(Screen current) { + if (backStack.isEmpty()) + return; + backSteppedFrom = current; + Screen previousScreen = backStack.pop(); + if (previousScreen instanceof AbstractSimiScreen) + ((AbstractSimiScreen) previousScreen).transition.startWithValue(-0.1) + .chase(-1, .4f, LerpedFloat.Chaser.EXP); + openScreen(previousScreen); + } + + // transitions are only supported in simiScreens atm. they take care of all the + // rendering for it + public static void transitionTo(AbstractSimiScreen screen) { + if (tryBackTracking(screen)) + return; + screen.transition.startWithValue(0.1) + .chase(1, .4f, LerpedFloat.Chaser.EXP); + open(screen); + } + + private static boolean tryBackTracking(AbstractSimiScreen screen) { + List screenHistory = getScreenHistory(); + if (screenHistory.isEmpty()) + return false; + Screen previouslyRenderedScreen = screenHistory.get(0); + if (!(previouslyRenderedScreen instanceof AbstractSimiScreen)) + return false; + if (!screen.isEquivalentTo((AbstractSimiScreen) previouslyRenderedScreen)) + return false; + + openPreviousScreen(Minecraft.getInstance().currentScreen); + return true; + } + + public static void clearStack() { + backStack.clear(); + } + + public static List getScreenHistory() { + return new ArrayList<>(backStack); + } + + @Nullable + public static Screen getPreviouslyRenderedScreen() { + return backSteppedFrom != null ? backSteppedFrom : backStack.peek(); + } + + private static void openScreen(Screen screen) { + Minecraft.getInstance() + .enqueue(() -> Minecraft.getInstance() + .displayGuiScreen(screen)); } } diff --git a/src/main/java/com/simibubi/create/foundation/gui/UIRenderHelper.java b/src/main/java/com/simibubi/create/foundation/gui/UIRenderHelper.java new file mode 100644 index 000000000..f6db492b5 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/gui/UIRenderHelper.java @@ -0,0 +1,179 @@ +package com.simibubi.create.foundation.gui; + +import org.lwjgl.opengl.GL11; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.simibubi.create.foundation.utility.ColorHelper; + +import net.minecraft.client.MainWindow; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.client.shader.Framebuffer; +import net.minecraftforge.fml.client.gui.GuiUtils; + +public class UIRenderHelper { + + public static Framebuffer framebuffer; + + public static void init() { + RenderSystem.recordRenderCall(() -> { + MainWindow mainWindow = Minecraft.getInstance().getWindow(); + framebuffer = new Framebuffer(mainWindow.getFramebufferWidth(), mainWindow.getFramebufferHeight(), true, Minecraft.IS_RUNNING_ON_MAC); + framebuffer.setFramebufferColor(0, 0, 0, 0); +// framebuffer.deleteFramebuffer(); + }); + } + + public static void prepFramebufferSize() { + MainWindow window = Minecraft.getInstance().getWindow(); + if (framebuffer.framebufferWidth != window.getFramebufferWidth() || framebuffer.framebufferHeight != window.getFramebufferHeight()) { + framebuffer.func_216491_a(window.getFramebufferWidth(), window.getFramebufferHeight(), Minecraft.IS_RUNNING_ON_MAC); + } + } + + public static void drawFramebuffer(float alpha) { + MainWindow window = Minecraft.getInstance() + .getWindow(); + + float vx = (float) window.getScaledWidth(); + float vy = (float) window.getScaledHeight(); + float tx = (float) framebuffer.framebufferWidth / (float) framebuffer.framebufferTextureWidth; + float ty = (float) framebuffer.framebufferHeight / (float) framebuffer.framebufferTextureHeight; + + RenderSystem.enableTexture(); + RenderSystem.enableBlend(); + RenderSystem.disableLighting(); + RenderSystem.disableAlphaTest(); + RenderSystem.defaultBlendFunc(); + RenderSystem.enableDepthTest(); + + framebuffer.bindFramebufferTexture(); + + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder bufferbuilder = tessellator.getBuffer(); + bufferbuilder.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR_TEXTURE); + + bufferbuilder.vertex(0, vy, 0).color(1, 1, 1, alpha).texture(0,0).endVertex(); + bufferbuilder.vertex(vx, vy, 0).color(1, 1, 1, alpha).texture(tx,0).endVertex(); + bufferbuilder.vertex(vx, 0, 0).color(1, 1, 1, alpha).texture(tx, ty).endVertex(); + bufferbuilder.vertex(0, 0, 0).color(1, 1, 1, alpha).texture(0, ty).endVertex(); + + tessellator.draw(); + framebuffer.unbindFramebufferTexture(); + RenderSystem.disableBlend(); + RenderSystem.enableAlphaTest(); + } + + //angle in degrees; 0° -> fading to the right + //x and y specify the middle point of the starting edge + //width is the total width of the streak + public static void streak(float angle, int x, int y, int width, int length, int color) { + int a1 = 0xa0 << 24; + int a2 = 0x80 << 24; + int a3 = 0x10 << 24; + int a4 = 0x00 << 24; + + color = color & 0x00FFFFFF; + int c1 = a1 | color; + int c2 = a2 | color; + int c3 = a3 | color; + int c4 = a4 | color; + + RenderSystem.pushMatrix(); + RenderSystem.translated(x, y, 0); + RenderSystem.rotatef(angle - 90, 0, 0, 1); + + streak(width/2, length, c1, c2, c3, c4); + + RenderSystem.popMatrix(); + } + + private static void streak(int width, int height, int c1, int c2, int c3, int c4) { + double split1 = .5; + double split2 = .75; + GuiUtils.drawGradientRect(0, -width, 0, width, (int) (split1 * height), c1, c2); + GuiUtils.drawGradientRect(0, -width, (int) (split1 * height), width, (int) (split2 * height), c2, c3); + GuiUtils.drawGradientRect(0, -width, (int) (split2 * height), width, height, c3, c4); + } + + //draws a wide chevron-style breadcrumb arrow pointing left + public static void breadcrumbArrow(int x, int y, int width, int height, int indent, int startColor, int endColor) { + RenderSystem.pushMatrix(); + RenderSystem.translated(x - indent, y, 0); + + breadcrumbArrow(width, height, indent, startColor, endColor); + + RenderSystem.popMatrix(); + } + + private static void breadcrumbArrow(int width, int height, int indent, int c1, int c2) { + + /* + * 0,0 x1,y1 ********************* x4,y4 ***** x7,y7 + * **** **** + * **** **** + * x0,y0 x2,y2 x5,y5 + * **** **** + * **** **** + * x3,y3 ********************* x6,y6 ***** x8,y8 + * + * */ + + double x0 = 0, y0 = height / 2d; + double x1 = indent, y1 = 0; + double x2 = indent, y2 = height / 2d; + double x3 = indent, y3 = height; + double x4 = width, y4 = 0; + double x5 = width, y5 = height / 2d; + double x6 = width, y6 = height; + double x7 = indent + width, y7 = 0; + double x8 = indent + width, y8 = height; + + int fc1 = ColorHelper.mixAlphaColors(c1, c2, 0); + int fc2 = ColorHelper.mixAlphaColors(c1, c2, (indent)/(width + 2f * indent)); + int fc3 = ColorHelper.mixAlphaColors(c1, c2, (indent + width)/(width + 2f * indent)); + int fc4 = ColorHelper.mixAlphaColors(c1, c2, 1); + + RenderSystem.disableTexture(); + RenderSystem.enableBlend(); + RenderSystem.disableAlphaTest(); + RenderSystem.defaultBlendFunc(); + RenderSystem.shadeModel(GL11.GL_SMOOTH); + + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder bufferbuilder = tessellator.getBuffer(); + bufferbuilder.begin(GL11.GL_TRIANGLES, DefaultVertexFormats.POSITION_COLOR); + + bufferbuilder.vertex(x0, y0, 0).color(fc1 >> 16 & 0xFF, fc1 >> 8 & 0xFF, fc1 & 0xFF, fc1 >> 24 & 0xFF).endVertex(); + bufferbuilder.vertex(x1, y1, 0).color(fc2 >> 16 & 0xFF, fc2 >> 8 & 0xFF, fc2 & 0xFF, fc2 >> 24 & 0xFF).endVertex(); + bufferbuilder.vertex(x2, y2, 0).color(fc2 >> 16 & 0xFF, fc2 >> 8 & 0xFF, fc2 & 0xFF, fc2 >> 24 & 0xFF).endVertex(); + + bufferbuilder.vertex(x0, y0, 0).color(fc1 >> 16 & 0xFF, fc1 >> 8 & 0xFF, fc1 & 0xFF, fc1 >> 24 & 0xFF).endVertex(); + bufferbuilder.vertex(x2, y2, 0).color(fc2 >> 16 & 0xFF, fc2 >> 8 & 0xFF, fc2 & 0xFF, fc2 >> 24 & 0xFF).endVertex(); + bufferbuilder.vertex(x3, y3, 0).color(fc2 >> 16 & 0xFF, fc2 >> 8 & 0xFF, fc2 & 0xFF, fc2 >> 24 & 0xFF).endVertex(); + + bufferbuilder.vertex(x3, y3, 0).color(fc2 >> 16 & 0xFF, fc2 >> 8 & 0xFF, fc2 & 0xFF, fc2 >> 24 & 0xFF).endVertex(); + bufferbuilder.vertex(x1, y1, 0).color(fc2 >> 16 & 0xFF, fc2 >> 8 & 0xFF, fc2 & 0xFF, fc2 >> 24 & 0xFF).endVertex(); + bufferbuilder.vertex(x4, y4, 0).color(fc3 >> 16 & 0xFF, fc3 >> 8 & 0xFF, fc3 & 0xFF, fc3 >> 24 & 0xFF).endVertex(); + + bufferbuilder.vertex(x3, y3, 0).color(fc2 >> 16 & 0xFF, fc2 >> 8 & 0xFF, fc2 & 0xFF, fc2 >> 24 & 0xFF).endVertex(); + bufferbuilder.vertex(x4, y4, 0).color(fc3 >> 16 & 0xFF, fc3 >> 8 & 0xFF, fc3 & 0xFF, fc3 >> 24 & 0xFF).endVertex(); + bufferbuilder.vertex(x6, y6, 0).color(fc3 >> 16 & 0xFF, fc3 >> 8 & 0xFF, fc3 & 0xFF, fc3 >> 24 & 0xFF).endVertex(); + + bufferbuilder.vertex(x5, y5, 0).color(fc3 >> 16 & 0xFF, fc3 >> 8 & 0xFF, fc3 & 0xFF, fc3 >> 24 & 0xFF).endVertex(); + bufferbuilder.vertex(x4, y4, 0).color(fc3 >> 16 & 0xFF, fc3 >> 8 & 0xFF, fc3 & 0xFF, fc3 >> 24 & 0xFF).endVertex(); + bufferbuilder.vertex(x7, y7, 0).color(fc4 >> 16 & 0xFF, fc4 >> 8 & 0xFF, fc4 & 0xFF, fc4 >> 24 & 0xFF).endVertex(); + + bufferbuilder.vertex(x6, y6, 0).color(fc3 >> 16 & 0xFF, fc3 >> 8 & 0xFF, fc3 & 0xFF, fc3 >> 24 & 0xFF).endVertex(); + bufferbuilder.vertex(x5, y5, 0).color(fc3 >> 16 & 0xFF, fc3 >> 8 & 0xFF, fc3 & 0xFF, fc3 >> 24 & 0xFF).endVertex(); + bufferbuilder.vertex(x8, y8, 0).color(fc4 >> 16 & 0xFF, fc4 >> 8 & 0xFF, fc4 & 0xFF, fc4 >> 24 & 0xFF).endVertex(); + + tessellator.draw(); + RenderSystem.shadeModel(GL11.GL_FLAT); + RenderSystem.disableBlend(); + RenderSystem.enableAlphaTest(); + RenderSystem.enableTexture(); + } +} diff --git a/src/main/java/com/simibubi/create/foundation/mixin/RenderHooksMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/RenderHooksMixin.java index d44d476b0..89310489c 100644 --- a/src/main/java/com/simibubi/create/foundation/mixin/RenderHooksMixin.java +++ b/src/main/java/com/simibubi/create/foundation/mixin/RenderHooksMixin.java @@ -45,7 +45,7 @@ public class RenderHooksMixin { GL20.glUseProgram(0); } - @Inject(at = @At(value = "INVOKE", target = "updateChunks(J)V"), method = "render") + @Inject(at = @At(value = "INVOKE", target = "net.minecraft.client.renderer.WorldRenderer.updateChunks(J)V"), method = "render") private void setupFrame(MatrixStack p_228426_1_, float p_228426_2_, long p_228426_3_, boolean p_228426_5_, ActiveRenderInfo info, GameRenderer p_228426_7_, LightTexture p_228426_8_, Matrix4f p_228426_9_, CallbackInfo ci) { Vec3d cameraPos = info.getProjectedView(); double camX = cameraPos.getX(); diff --git a/src/main/java/com/simibubi/create/foundation/ponder/ElementLink.java b/src/main/java/com/simibubi/create/foundation/ponder/ElementLink.java new file mode 100644 index 000000000..cc336981c --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/ElementLink.java @@ -0,0 +1,27 @@ +package com.simibubi.create.foundation.ponder; + +import java.util.UUID; + +public class ElementLink { + + private Class elementClass; + private UUID id; + + public ElementLink(Class elementClass) { + this(elementClass, UUID.randomUUID()); + } + + public ElementLink(Class elementClass, UUID id) { + this.elementClass = elementClass; + this.id = id; + } + + public UUID getId() { + return id; + } + + public T cast(PonderElement e) { + return elementClass.cast(e); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/PonderElement.java b/src/main/java/com/simibubi/create/foundation/ponder/PonderElement.java new file mode 100644 index 000000000..9c482406e --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/PonderElement.java @@ -0,0 +1,19 @@ +package com.simibubi.create.foundation.ponder; + +public class PonderElement { + + boolean visible = true; + + public void tick(PonderScene scene) {} + + public void reset(PonderScene scene) {} + + public boolean isVisible() { + return visible; + } + + public void setVisible(boolean visible) { + this.visible = visible; + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/PonderInstruction.java b/src/main/java/com/simibubi/create/foundation/ponder/PonderInstruction.java new file mode 100644 index 000000000..1cee38f86 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/PonderInstruction.java @@ -0,0 +1,43 @@ +package com.simibubi.create.foundation.ponder; + +import java.util.function.Consumer; + +public abstract class PonderInstruction { + + public boolean isBlocking() { + return false; + } + + public void reset(PonderScene scene) {} + + public abstract boolean isComplete(); + + public void onScheduled(PonderScene scene) {} + + public abstract void tick(PonderScene scene); + + public static PonderInstruction simple(Consumer callback) { + return new Simple(callback); + } + + private static class Simple extends PonderInstruction { + + private Consumer callback; + + public Simple(Consumer callback) { + this.callback = callback; + } + + @Override + public boolean isComplete() { + return true; + } + + @Override + public void tick(PonderScene scene) { + callback.accept(scene); + } + + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/PonderLocalization.java b/src/main/java/com/simibubi/create/foundation/ponder/PonderLocalization.java new file mode 100644 index 000000000..b6e7eae6c --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/PonderLocalization.java @@ -0,0 +1,117 @@ +package com.simibubi.create.foundation.ponder; + +import java.util.HashMap; +import java.util.Map; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.simibubi.create.Create; +import com.simibubi.create.foundation.ponder.content.PonderIndex; +import com.simibubi.create.foundation.ponder.content.PonderTagScreen; +import com.simibubi.create.foundation.utility.Couple; +import com.simibubi.create.foundation.utility.Lang; + +public class PonderLocalization { + + static Map shared = new HashMap<>(); + static Map> tag = new HashMap<>(); + static Map> specific = new HashMap<>(); + + // + + public static void registerTag(String key, String enUS, String description) { + tag.put(key, Couple.create(enUS, description)); + } + + public static void registerShared(String key, String enUS) { + shared.put(key, enUS); + } + + public static void registerSpecific(String sceneId, String key, String enUS) { + specific.computeIfAbsent(sceneId, $ -> new HashMap<>()) + .put(key, enUS); + } + + // + + public static String getShared(String key) { + if (PonderIndex.EDITOR_MODE) + return shared.containsKey(key) ? shared.get(key) : ("unregistered shared entry:" + key); + return Lang.translate(langKeyForShared(key)); + } + + public static String getSpecific(String sceneId, String k) { + if (PonderIndex.EDITOR_MODE) + return specific.get(sceneId) + .get(k); + return Lang.translate(langKeyForSpecific(sceneId, k)); + } + + public static String getTag(String key) { + if (PonderIndex.EDITOR_MODE) + return tag.containsKey(key) ? tag.get(key) + .getFirst() : ("unregistered tag entry:" + key); + return Lang.translate(langKeyForTag(key)); + } + + public static String getTagDescription(String key) { + if (PonderIndex.EDITOR_MODE) + return tag.containsKey(key) ? tag.get(key) + .getSecond() : ("unregistered tag entry:" + key); + return Lang.translate(langKeyForTagDescription(key)); + } + + // + + public static final String LANG_PREFIX = "ponder."; + + public static JsonElement record() { + JsonObject object = new JsonObject(); + + addGeneral(object, PonderTooltipHandler.HOLD_TO_PONDER, "Hold [%1$s] to Ponder"); + addGeneral(object, PonderTooltipHandler.SUBJECT, "Subject of this scene"); + addGeneral(object, PonderUI.PONDERING, "Pondering about..."); + addGeneral(object, PonderUI.IDENTIFY_MODE, "Identify mode active.\nUnpause with [%1$s]"); + addGeneral(object, PonderTagScreen.ASSOCIATED, "Associated Entries"); + + shared.forEach((k, v) -> object.addProperty(Create.ID + "." + langKeyForShared(k), v)); + tag.forEach((k, v) -> { + object.addProperty(Create.ID + "." + langKeyForTag(k), v.getFirst()); + object.addProperty(Create.ID + "." + langKeyForTagDescription(k), v.getSecond()); + }); + + specific.entrySet() + .stream() + .sorted(Map.Entry.comparingByKey()) + .forEach(entry -> { + entry.getValue() + .entrySet() + .stream() + .sorted(Map.Entry.comparingByKey()) + .forEach(subEntry -> object.addProperty(Create.ID + "." + langKeyForSpecific(entry.getKey(), subEntry.getKey()), + subEntry.getValue())); + }); + return object; + } + + private static void addGeneral(JsonObject json, String key, String enUS) { + json.addProperty(Create.ID + "." + key, enUS); + } + + protected static String langKeyForSpecific(String sceneId, String k) { + return LANG_PREFIX + sceneId + "." + k; + } + + protected static String langKeyForShared(String k) { + return LANG_PREFIX + "shared." + k; + } + + protected static String langKeyForTag(String k) { + return LANG_PREFIX + "tag." + k; + } + + protected static String langKeyForTagDescription(String k) { + return LANG_PREFIX + "tag." + k + ".description"; + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/PonderRegistry.java b/src/main/java/com/simibubi/create/foundation/ponder/PonderRegistry.java new file mode 100644 index 000000000..74f7e7ec5 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/PonderRegistry.java @@ -0,0 +1,178 @@ +package com.simibubi.create.foundation.ponder; + +import java.io.BufferedInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; +import java.util.zip.GZIPInputStream; + +import com.google.gson.JsonElement; +import com.simibubi.create.Create; +import com.simibubi.create.foundation.ponder.PonderStoryBoardEntry.PonderStoryBoard; +import com.simibubi.create.foundation.ponder.content.PonderChapter; +import com.simibubi.create.foundation.ponder.content.PonderChapterRegistry; +import com.simibubi.create.foundation.ponder.content.PonderIndex; +import com.simibubi.create.foundation.ponder.content.PonderTag; +import com.simibubi.create.foundation.ponder.content.PonderTagRegistry; +import com.simibubi.create.foundation.ponder.content.SharedText; +import com.tterrag.registrate.util.entry.ItemProviderEntry; + +import net.minecraft.client.Minecraft; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.nbt.CompressedStreamTools; +import net.minecraft.nbt.NBTSizeTracker; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.gen.feature.template.PlacementSettings; +import net.minecraft.world.gen.feature.template.Template; + +public class PonderRegistry { + + public static final PonderTagRegistry tags = new PonderTagRegistry(); + public static final PonderChapterRegistry chapters = new PonderChapterRegistry(); + public static Map> all = new HashMap<>(); + + public static PonderSceneBuilder addStoryBoard(ItemProviderEntry component, String schematic, PonderStoryBoard storyBoard) { + ResourceLocation id = component.getId(); + PonderStoryBoardEntry entry = new PonderStoryBoardEntry(storyBoard, schematic, id); + PonderSceneBuilder builder = new PonderSceneBuilder(entry); + all.computeIfAbsent(id, _$ -> new ArrayList<>()).add(entry); + return builder; + } + + public static PonderSceneBuilder addStoryBoard(PonderChapter chapter, ResourceLocation component, String schematic, PonderStoryBoard storyBoard) { + if (component == null) + component = new ResourceLocation("minecraft", "stick"); + + PonderStoryBoardEntry entry = new PonderStoryBoardEntry(storyBoard, schematic, component); + PonderSceneBuilder builder = new PonderSceneBuilder(entry); + chapters.addStoriesToChapter(chapter, entry); + return builder; + } + + public static MultiSceneBuilder forComponents(ItemProviderEntry... components) { + return new MultiSceneBuilder(Arrays.asList(components)); + } + + public static List compile(ResourceLocation id) { + return compile(all.get(id)); + } + + public static List compile(PonderChapter chapter) { + return compile(chapters.getStories(chapter)); + } + + public static List compile(List entries) { + if (PonderIndex.EDITOR_MODE) { + PonderLocalization.shared.clear(); + SharedText.gatherText(); + } + + List scenes = new ArrayList<>(); + + for (int i = 0; i < entries.size(); i++) { + PonderStoryBoardEntry sb = entries.get(i); + Template activeTemplate = loadSchematic(sb.getSchematicName()); + PonderWorld world = new PonderWorld(BlockPos.ZERO, Minecraft.getInstance().world); + activeTemplate.addBlocksToWorld(world, BlockPos.ZERO, new PlacementSettings()); + world.createBackup(); + PonderScene scene = compileScene(i, sb, world); + scene.begin(); + scenes.add(scene); + } + + return scenes; + } + + public static PonderScene compileScene(int i, PonderStoryBoardEntry sb, PonderWorld world) { + PonderScene scene = new PonderScene(world, sb.getComponent(), sb.getTags()); + SceneBuilder builder = scene.builder(); + sb.getBoard().program(builder, scene.getSceneBuildingUtil()); + return scene; + } + + public static Template loadSchematic(String path) { + Template t = new Template(); + String filepath = "ponder/" + path + ".nbt"; + InputStream resourceAsStream = Create.class.getClassLoader() + .getResourceAsStream(filepath); + if (resourceAsStream == null) + throw new IllegalStateException("Could not find ponder schematic: " + filepath); + try (DataInputStream stream = + new DataInputStream(new BufferedInputStream(new GZIPInputStream(resourceAsStream)))) { + CompoundNBT nbt = CompressedStreamTools.read(stream, new NBTSizeTracker(0x20000000L)); + t.read(nbt); + } catch (IOException e) { + Create.logger.warn("Failed to read ponder schematic", e); + } + return t; + } + + public static JsonElement provideLangEntries() { + PonderIndex.register(); + PonderTag.register(); + SharedText.gatherText(); + all.forEach((id, list) -> { + for (int i = 0; i < list.size(); i++) + compileScene(i, list.get(i), null); + }); + return PonderLocalization.record(); + } + + public static class MultiSceneBuilder { + + private final Collection> components; + + MultiSceneBuilder(Collection> components) { + this.components = components; + } + + public MultiSceneBuilder addStoryBoard(String schematicPath, PonderStoryBoard storyBoard) { + return addStoryBoard(schematicPath, storyBoard, PonderSceneBuilder::highlightAllTags); + } + + public MultiSceneBuilder addStoryBoard(String schematicPath, PonderStoryBoard storyBoard, Consumer extras) { + components.forEach(c -> extras.accept(PonderRegistry.addStoryBoard(c, schematicPath, storyBoard))); + return this; + } + + } + + public static class PonderSceneBuilder { + + private final PonderStoryBoardEntry entry; + + PonderSceneBuilder(PonderStoryBoardEntry entry) { + this.entry = entry; + } + + public PonderSceneBuilder highlightAllTags() { + entry.getTags().add(PonderTag.Highlight.ALL); + return this; + } + + public PonderSceneBuilder highlightTags(PonderTag... tags) { + entry.getTags().addAll(Arrays.asList(tags)); + return this; + } + + public PonderSceneBuilder chapter(PonderChapter chapter) { + PonderRegistry.chapters.addStoriesToChapter(chapter, entry); + return this; + } + + public PonderSceneBuilder chapters(PonderChapter... chapters) { + for (PonderChapter c : chapters) + chapter(c); + return this; + } + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/PonderScene.java b/src/main/java/com/simibubi/create/foundation/ponder/PonderScene.java new file mode 100644 index 000000000..1eee89b34 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/PonderScene.java @@ -0,0 +1,462 @@ +package com.simibubi.create.foundation.ponder; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Supplier; + +import org.apache.commons.lang3.mutable.MutableDouble; +import org.apache.commons.lang3.mutable.MutableObject; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.foundation.ponder.content.PonderIndex; +import com.simibubi.create.foundation.ponder.content.PonderTag; +import com.simibubi.create.foundation.ponder.elements.PonderOverlayElement; +import com.simibubi.create.foundation.ponder.elements.PonderSceneElement; +import com.simibubi.create.foundation.ponder.elements.WorldSectionElement; +import com.simibubi.create.foundation.ponder.instructions.HideAllInstruction; +import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer; +import com.simibubi.create.foundation.utility.AnimationTickHolder; +import com.simibubi.create.foundation.utility.LerpedFloat; +import com.simibubi.create.foundation.utility.MatrixStacker; +import com.simibubi.create.foundation.utility.Pair; +import com.simibubi.create.foundation.utility.VecHelper; +import com.simibubi.create.foundation.utility.outliner.Outliner; + +import net.minecraft.block.BlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.ActiveRenderInfo; +import net.minecraft.client.renderer.Matrix4f; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.Vector4f; +import net.minecraft.entity.Entity; +import net.minecraft.entity.item.ArmorStandEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.util.Direction; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; +import net.minecraft.util.math.MutableBoundingBox; +import net.minecraft.util.math.Vec2f; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.Vec3i; + +public class PonderScene { + + public static final String TITLE_KEY = "header"; + + boolean finished; + int sceneIndex; + int textIndex; + String sceneId; + + List schedule, activeSchedule; + Map linkedElements; + Set elements; + List tags; + + PonderWorld world; + ResourceLocation component; + SceneTransform transform; + SceneRenderInfo info; + Outliner outliner; + String defaultTitle; + + Vec3d pointOfInterest; + Vec3d chasingPointOfInterest; + WorldSectionElement baseWorldSection; + Entity renderViewEntity; + + int offsetX; + int offsetZ; + int size; + + int totalTime; + int currentTime; + + public PonderScene(PonderWorld world, ResourceLocation component, Collection tags) { + pointOfInterest = Vec3d.ZERO; + textIndex = 1; + + this.world = world; + this.component = component; + + outliner = new Outliner(); + elements = new HashSet<>(); + linkedElements = new HashMap<>(); + this.tags = new ArrayList<>(tags); + schedule = new ArrayList<>(); + activeSchedule = new ArrayList<>(); + transform = new SceneTransform(); + size = getBounds().getXSize(); + info = new SceneRenderInfo(); + baseWorldSection = new WorldSectionElement(); + renderViewEntity = new ArmorStandEntity(world, 0, 0, 0); + + setPointOfInterest(new Vec3d(0, 4, 0)); + } + + public void deselect() { + forEach(WorldSectionElement.class, WorldSectionElement::resetSelectedBlock); + } + + public Pair rayTraceScene(Vec3d from, Vec3d to) { + MutableObject> nearestHit = new MutableObject<>(); + MutableDouble bestDistance = new MutableDouble(0); + + forEach(WorldSectionElement.class, wse -> { + wse.resetSelectedBlock(); + if (!wse.isVisible()) + return; + Pair rayTrace = wse.rayTrace(world, from, to); + if (rayTrace == null) + return; + double distanceTo = rayTrace.getFirst() + .distanceTo(from); + if (nearestHit.getValue() != null && distanceTo >= bestDistance.getValue()) + return; + + nearestHit.setValue(Pair.of(wse, rayTrace.getSecond())); + bestDistance.setValue(distanceTo); + }); + + if (nearestHit.getValue() == null) + return Pair.of(ItemStack.EMPTY, null); + + BlockPos selectedPos = nearestHit.getValue() + .getSecond(); + + BlockPos origin = new BlockPos(offsetX, 0, offsetZ); + if (!world.getBounds() + .isVecInside(selectedPos)) + return Pair.of(ItemStack.EMPTY, null); + if (new MutableBoundingBox(origin, origin.add(new Vec3i(size - 1, 0, size - 1))).isVecInside(selectedPos)) { + if (PonderIndex.EDITOR_MODE) + nearestHit.getValue() + .getFirst() + .selectBlock(selectedPos); + return Pair.of(ItemStack.EMPTY, selectedPos); + } + + nearestHit.getValue() + .getFirst() + .selectBlock(selectedPos); + BlockState blockState = world.getBlockState(selectedPos); + ItemStack pickBlock = blockState.getPickBlock( + new BlockRayTraceResult(VecHelper.getCenterOf(selectedPos), Direction.UP, selectedPos, true), world, + selectedPos, Minecraft.getInstance().player); + + return Pair.of(pickBlock, selectedPos); + } + + public String getTitle() { + return getString(TITLE_KEY); + } + + public String getString(String key) { + return PonderLocalization.getSpecific(sceneId, key); + } + + public void reset() { + currentTime = 0; + activeSchedule.clear(); + schedule.forEach(mdi -> mdi.reset(this)); + } + + public void begin() { + reset(); + forEach(pe -> pe.reset(this)); + + world.restore(); + elements.clear(); + linkedElements.clear(); + + transform = new SceneTransform(); + finished = false; + setPointOfInterest(new Vec3d(0, 4, 0)); + + baseWorldSection.setEmpty(); + baseWorldSection.forceApplyFade(1); + elements.add(baseWorldSection); + + totalTime = 0; + activeSchedule.addAll(schedule); + activeSchedule.forEach(i -> i.onScheduled(this)); + } + + public WorldSectionElement getBaseWorldSection() { + return baseWorldSection; + } + + public float getSceneProgress() { + return totalTime == 0 ? 0 : currentTime / (float) totalTime; + } + + public void fadeOut() { + reset(); + activeSchedule.add(new HideAllInstruction(10, null)); + } + + public void renderScene(SuperRenderTypeBuffer buffer, MatrixStack ms, float pt) { + ms.push(); + Minecraft mc = Minecraft.getInstance(); + Entity prevRVE = mc.renderViewEntity; + + mc.renderViewEntity = this.renderViewEntity; + forEachVisible(PonderSceneElement.class, e -> e.renderFirst(world, buffer, ms, pt)); + mc.renderViewEntity = prevRVE; + + for (RenderType type : RenderType.getBlockLayers()) + forEachVisible(PonderSceneElement.class, e -> e.renderLayer(world, buffer, type, ms, pt)); + forEachVisible(PonderSceneElement.class, e -> e.renderLast(world, buffer, ms, pt)); + info.set(transform.xRotation.getValue(pt), transform.yRotation.getValue(pt)); + world.renderEntities(ms, buffer, info, pt); + world.renderParticles(ms, buffer, info, pt); + outliner.renderOutlines(ms, buffer, pt); + ms.pop(); + } + + public void renderOverlay(PonderUI screen, MatrixStack ms, float partialTicks) { + ms.push(); + forEachVisible(PonderOverlayElement.class, e -> e.render(this, screen, ms, partialTicks)); + ms.pop(); + } + + public void setPointOfInterest(Vec3d poi) { + if (chasingPointOfInterest == null) + pointOfInterest = poi; + chasingPointOfInterest = poi; + } + + public Vec3d getPointOfInterest() { + return pointOfInterest; + } + + public void tick() { + if (chasingPointOfInterest != null) + pointOfInterest = VecHelper.lerp(.25f, pointOfInterest, chasingPointOfInterest); + + outliner.tickOutlines(); + world.tick(); + transform.tick(); + forEach(e -> e.tick(this)); + + if (currentTime < totalTime) + currentTime++; + + for (Iterator iterator = activeSchedule.iterator(); iterator.hasNext();) { + PonderInstruction instruction = iterator.next(); + instruction.tick(this); + if (instruction.isComplete()) { + iterator.remove(); + continue; + } + if (instruction.isBlocking()) + break; + } + + if (activeSchedule.isEmpty()) + finished = true; + } + + public void addToSceneTime(int time) { + totalTime += time; + } + + public void addElement(PonderElement e) { + elements.add(e); + } + + public void linkElement(E e, ElementLink link) { + linkedElements.put(link.getId(), e); + } + + public E resolve(ElementLink link) { + return link.cast(linkedElements.get(link.getId())); + } + + public void runWith(ElementLink link, Consumer callback) { + callback.accept(resolve(link)); + } + + public F applyTo(ElementLink link, Function function) { + return function.apply(resolve(link)); + } + + public PonderWorld getWorld() { + return world; + } + + public Set getElements() { + return elements; + } + + public void forEach(Consumer function) { + for (PonderElement elemtent : elements) + function.accept(elemtent); + } + + public void forEachWorldEntity(Class type, Consumer function) { + for (Entity element : world.getEntities()) + if (type.isInstance(element)) + function.accept(type.cast(element)); + } + + public void forEach(Class type, Consumer function) { + for (PonderElement element : elements) + if (type.isInstance(element)) + function.accept(type.cast(element)); + } + + public void forEachVisible(Class type, Consumer function) { + for (PonderElement element : elements) + if (type.isInstance(element) && element.isVisible()) + function.accept(type.cast(element)); + } + + public MutableBoundingBox getBounds() { + return world == null ? new MutableBoundingBox() : world.getBounds(); + } + + public Supplier registerText(String defaultText) { + final String key = "text_" + textIndex; + PonderLocalization.registerSpecific(sceneId, key, defaultText); + Supplier supplier = () -> PonderLocalization.getSpecific(sceneId, key); + textIndex++; + return supplier; + } + + public SceneBuilder builder() { + return new SceneBuilder(this); + } + + public SceneBuildingUtil getSceneBuildingUtil() { + return new SceneBuildingUtil(getBounds()); + } + + public SceneTransform getTransform() { + return transform; + } + + public class SceneTransform { + + public LerpedFloat xRotation, yRotation; + + // Screen params + int width, height; + double offset; + Matrix4f cachedMat; + + public SceneTransform() { + xRotation = LerpedFloat.angular() + .startWithValue(-35); + yRotation = LerpedFloat.angular() + .startWithValue(55 + 90); + } + + public void tick() { + xRotation.tickChaser(); + yRotation.tickChaser(); + } + + public void updateScreenParams(int width, int height, double offset) { + this.width = width; + this.height = height; + this.offset = offset; + cachedMat = null; + } + + public MatrixStack apply(MatrixStack ms) { + return apply(ms, AnimationTickHolder.getPartialTicks()); + } + + public MatrixStack apply(MatrixStack ms, float pt) { + ms.translate(width / 2, height / 2, 200); + + MatrixStacker.of(ms) + .rotateX(-35) + .rotateY(55); + ms.translate(offset, 0, 0); + MatrixStacker.of(ms) + .rotateY(-55) + .rotateX(35); + + MatrixStacker.of(ms) + .rotateX(xRotation.getValue(pt)) + .rotateY(yRotation.getValue(pt)); + ms.scale(30, -30, 30); + ms.translate((size + offsetX) / -2f, -1f, (size + offsetZ) / -2f); + + return ms; + } + + public void updateSceneRVE() { + Vec3d v = screenToScene(width / 2, height / 2, 500); + renderViewEntity.setPosition(v.x, v.y, v.z); + } + + public Vec3d screenToScene(double x, double y, int depth) { + refreshMatrix(); + float pt = AnimationTickHolder.getPartialTicks(); + Vec3d vec = new Vec3d(x, y, depth); + + vec = vec.subtract(width / 2, height / 2, 200); + vec = VecHelper.rotate(vec, 35, Axis.X); + vec = VecHelper.rotate(vec, -55, Axis.Y); + vec = vec.subtract(offset, 0, 0); + vec = VecHelper.rotate(vec, 55, Axis.Y); + vec = VecHelper.rotate(vec, -35, Axis.X); + vec = VecHelper.rotate(vec, -xRotation.getValue(pt), Axis.X); + vec = VecHelper.rotate(vec, -yRotation.getValue(pt), Axis.Y); + vec = vec.mul(1f / 30, 1f / -30, 1f / 30); + vec = vec.subtract((size + offsetX) / -2f, -1f, (size + offsetZ) / -2f); + + return vec; + } + + public Vec2f sceneToScreen(Vec3d vec) { + refreshMatrix(); + Vector4f vec4 = new Vector4f((float) vec.x, (float) vec.y, (float) vec.z, 1); + vec4.transform(cachedMat); + return new Vec2f(vec4.getX(), vec4.getY()); + } + + protected void refreshMatrix() { + if (cachedMat != null) + return; + cachedMat = apply(new MatrixStack()).peek() + .getModel(); + } + + } + + public class SceneRenderInfo extends ActiveRenderInfo { + + public void set(float xRotation, float yRotation) { + setDirection(yRotation, xRotation); + } + + } + + public Outliner getOutliner() { + return outliner; + } + + public boolean isFinished() { + return finished; + } + + public void setFinished(boolean finished) { + this.finished = finished; + } + +} \ No newline at end of file diff --git a/src/main/java/com/simibubi/create/foundation/ponder/PonderStoryBoardEntry.java b/src/main/java/com/simibubi/create/foundation/ponder/PonderStoryBoardEntry.java new file mode 100644 index 000000000..7de4ccf5e --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/PonderStoryBoardEntry.java @@ -0,0 +1,43 @@ +package com.simibubi.create.foundation.ponder; + +import com.simibubi.create.foundation.ponder.content.PonderTag; +import net.minecraft.util.ResourceLocation; + +import java.util.ArrayList; +import java.util.List; + +public class PonderStoryBoardEntry { + + private final String schematicName; + private final PonderStoryBoard board; + private final List tags; + private final ResourceLocation component; + + public PonderStoryBoardEntry(PonderStoryBoard board, String schematicName, ResourceLocation component) { + this.board = board; + this.schematicName = schematicName; + this.tags = new ArrayList<>(); + this.component = component; + } + + public interface PonderStoryBoard { + void program(SceneBuilder scene, SceneBuildingUtil util); + } + + public String getSchematicName() { + return schematicName; + } + + public PonderStoryBoard getBoard() { + return board; + } + + public List getTags() { + return tags; + } + + public ResourceLocation getComponent() { + return component; + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/PonderTooltipHandler.java b/src/main/java/com/simibubi/create/foundation/ponder/PonderTooltipHandler.java new file mode 100644 index 000000000..87c56e7f0 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/PonderTooltipHandler.java @@ -0,0 +1,162 @@ +package com.simibubi.create.foundation.ponder; + +import java.util.List; + +import com.google.common.base.Strings; +import com.simibubi.create.foundation.gui.AbstractSimiScreen; +import com.simibubi.create.foundation.gui.ScreenOpener; +import com.simibubi.create.foundation.ponder.content.PonderIndexScreen; +import com.simibubi.create.foundation.ponder.content.PonderTagScreen; +import com.simibubi.create.foundation.utility.AnimationTickHolder; +import com.simibubi.create.foundation.utility.ColorHelper; +import com.simibubi.create.foundation.utility.Lang; +import com.simibubi.create.foundation.utility.LerpedFloat; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.inventory.ContainerScreen; +import net.minecraft.client.settings.KeyBinding; +import net.minecraft.client.util.InputMappings; +import net.minecraft.inventory.container.Slot; +import net.minecraft.item.ItemStack; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.StringTextComponent; +import net.minecraft.util.text.TextFormatting; +import net.minecraftforge.client.event.RenderTooltipEvent; + +public class PonderTooltipHandler { + + static LerpedFloat holdWProgress = LerpedFloat.linear() + .startWithValue(0); + static ItemStack lastHoveredStack = ItemStack.EMPTY; + static boolean subject = false; + + public static final String HOLD_TO_PONDER = PonderLocalization.LANG_PREFIX + "hold_to_ponder"; + public static final String SUBJECT = PonderLocalization.LANG_PREFIX + "subject"; + + public static void tick() { + Minecraft instance = Minecraft.getInstance(); + Screen currentScreen = instance.currentScreen; + ItemStack stack = ItemStack.EMPTY; + ItemStack prevStack = lastHoveredStack; + lastHoveredStack = ItemStack.EMPTY; + subject = false; + + if (currentScreen instanceof ContainerScreen) { + ContainerScreen cs = (ContainerScreen) currentScreen; + Slot slotUnderMouse = cs.getSlotUnderMouse(); + if (slotUnderMouse == null || !slotUnderMouse.getHasStack()) + return; + stack = slotUnderMouse.getStack(); + } else if (currentScreen instanceof PonderUI) { + PonderUI ponderUI = (PonderUI) currentScreen; + stack = ponderUI.getHoveredTooltipItem(); + if (stack.isItemEqual(ponderUI.getSubject())) + subject = true; + } else if (currentScreen instanceof PonderTagScreen) { + PonderTagScreen tagScreen = (PonderTagScreen) currentScreen; + stack = tagScreen.getHoveredTooltipItem(); + } else if (currentScreen instanceof PonderIndexScreen) { + PonderIndexScreen indexScreen = (PonderIndexScreen) currentScreen; + stack = indexScreen.getHoveredTooltipItem(); + } else + return; + + if (stack.isEmpty()) + return; + if (!PonderRegistry.all.containsKey(stack.getItem() + .getRegistryName())) + return; + + if (prevStack.isEmpty() || !prevStack.isItemEqual(stack)) + holdWProgress.startWithValue(0); + + float value = holdWProgress.getValue(); + int keyCode = ponderKeybind().getKey() + .getKeyCode(); + long window = instance.getWindow() + .getHandle(); + + if (!subject && InputMappings.isKeyDown(window, keyCode)) { + if (value >= 1) { + if (currentScreen instanceof AbstractSimiScreen) + ((AbstractSimiScreen) currentScreen).centerScalingOnMouse(); + + ScreenOpener.transitionTo(PonderUI.of(stack)); + holdWProgress.startWithValue(0); + return; + } + holdWProgress.setValue(Math.min(1, value + Math.max(.25f, value) * .25f)); + } else + holdWProgress.setValue(Math.max(0, value - .05f)); + + lastHoveredStack = stack; + } + + public static void addToTooltip(List toolTip, ItemStack stack) { + float renderPartialTicks = AnimationTickHolder.getPartialTicks(); + if (lastHoveredStack != stack) + return; + if (subject) { + toolTip.set(1, Lang.createTranslationTextComponent(SUBJECT) + .applyTextStyle(TextFormatting.GREEN)); + return; + } + toolTip.set(1, makeProgressBar(Math.min(1, holdWProgress.getValue(renderPartialTicks) * 8 / 7f))); + } + + public static void handleTooltipColor(RenderTooltipEvent.Color event) { + if (lastHoveredStack != event.getStack()) + return; + if (holdWProgress.getValue() == 0) + return; + float renderPartialTicks = Minecraft.getInstance() + .getRenderPartialTicks(); + int start = event.getOriginalBorderStart(); + int end = event.getOriginalBorderEnd(); + float progress = Math.min(1, holdWProgress.getValue(renderPartialTicks) * 8 / 7f); + + start = getSmoothColorForProgress(progress); + end = getSmoothColorForProgress((progress)); + + event.setBorderStart(start | 0xa0000000); + event.setBorderEnd(end | 0xa0000000); + } + + private static int getSmoothColorForProgress(float progress) { + if (progress < .5f) + return ColorHelper.mixColors(0x5000FF, 5592575, progress * 2); + return ColorHelper.mixColors(5592575, 0xffffff, (progress - .5f) * 2); + } + + private static ITextComponent makeProgressBar(float progress) { + String holdW = Lang + .createTranslationTextComponent(HOLD_TO_PONDER, new StringTextComponent(ponderKeybind().getKeyBinding() + .getLocalizedName()).applyTextStyle(TextFormatting.WHITE)) + .applyTextStyle(TextFormatting.GRAY) + .getFormattedText(); + + FontRenderer fontRenderer = Minecraft.getInstance().fontRenderer; + float charWidth = fontRenderer.getStringWidth("|"); + float tipWidth = fontRenderer.getStringWidth(holdW); + + int total = (int) (tipWidth / charWidth); + int current = (int) (progress * total); + + if (progress > 0) { + String bars = ""; + bars += TextFormatting.WHITE + Strings.repeat("|", current); + if (progress < 1) + bars += TextFormatting.GRAY + Strings.repeat("|", total - current); + return new StringTextComponent(bars); + } + + return new StringTextComponent(holdW); + } + + protected static KeyBinding ponderKeybind() { + return Minecraft.getInstance().gameSettings.keyBindForward; + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/PonderUI.java b/src/main/java/com/simibubi/create/foundation/ponder/PonderUI.java new file mode 100644 index 000000000..1e5b8bca9 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/PonderUI.java @@ -0,0 +1,746 @@ +package com.simibubi.create.foundation.ponder; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.IntStream; + +import org.apache.commons.lang3.mutable.MutableBoolean; +import org.lwjgl.opengl.GL11; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.systems.RenderSystem; +import com.simibubi.create.foundation.gui.AbstractSimiScreen; +import com.simibubi.create.foundation.gui.AllGuiTextures; +import com.simibubi.create.foundation.gui.AllIcons; +import com.simibubi.create.foundation.gui.GuiGameElement; +import com.simibubi.create.foundation.gui.ScreenOpener; +import com.simibubi.create.foundation.gui.UIRenderHelper; +import com.simibubi.create.foundation.ponder.PonderScene.SceneTransform; +import com.simibubi.create.foundation.ponder.content.DebugScenes; +import com.simibubi.create.foundation.ponder.content.PonderChapter; +import com.simibubi.create.foundation.ponder.content.PonderIndex; +import com.simibubi.create.foundation.ponder.content.PonderTag; +import com.simibubi.create.foundation.ponder.content.PonderTagScreen; +import com.simibubi.create.foundation.ponder.ui.PonderButton; +import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer; +import com.simibubi.create.foundation.utility.AnimationTickHolder; +import com.simibubi.create.foundation.utility.ColorHelper; +import com.simibubi.create.foundation.utility.Iterate; +import com.simibubi.create.foundation.utility.Lang; +import com.simibubi.create.foundation.utility.LerpedFloat; +import com.simibubi.create.foundation.utility.LerpedFloat.Chaser; +import com.simibubi.create.foundation.utility.Pair; +import com.simibubi.create.foundation.utility.Pointing; + +import net.minecraft.client.ClipboardHelper; +import net.minecraft.client.GameSettings; +import net.minecraft.client.MainWindow; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.settings.KeyBinding; +import net.minecraft.item.ItemStack; +import net.minecraft.util.Direction; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.MutableBoundingBox; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.text.StringTextComponent; +import net.minecraft.util.text.TextFormatting; +import net.minecraft.world.gen.feature.template.PlacementSettings; +import net.minecraft.world.gen.feature.template.Template; +import net.minecraftforge.fml.client.gui.GuiUtils; +import net.minecraftforge.registries.ForgeRegistries; + +public class PonderUI extends AbstractSimiScreen { + + public static final String PONDERING = PonderLocalization.LANG_PREFIX + "pondering"; + public static final String IDENTIFY_MODE = PonderLocalization.LANG_PREFIX + "identify_mode"; + public static final String IN_CHAPTER = PonderLocalization.LANG_PREFIX + "in_chapter"; + + private List scenes; + private List tags; + private List tagButtons; + private List tagFades; + private LerpedFloat fadeIn; + private LerpedFloat sceneProgress; + ItemStack stack; + PonderChapter chapter = null; + + private boolean identifyMode; + private ItemStack hoveredTooltipItem; + private BlockPos hoveredBlockPos; + + private ClipboardHelper clipboardHelper; + private BlockPos copiedBlockPos; + + private LerpedFloat lazyIndex; + private int index = 0; + + private PonderButton left, right, scan, chap; + + public static PonderUI of(ItemStack item) { + return new PonderUI(PonderRegistry.compile(item.getItem() + .getRegistryName())); + } + + public static PonderUI of(PonderChapter chapter) { + PonderUI ui = new PonderUI(PonderRegistry.compile(chapter)); + ui.chapter = chapter; + return ui; + } + + public PonderUI(List scenes) { + ResourceLocation component = scenes.get(0).component; + if (ForgeRegistries.ITEMS.containsKey(component)) + stack = new ItemStack(ForgeRegistries.ITEMS.getValue(component)); + else + stack = new ItemStack(ForgeRegistries.BLOCKS.getValue(component)); + + tags = new ArrayList<>(PonderRegistry.tags.getTags(component)); + this.scenes = scenes; + if (scenes.isEmpty()) { + List l = Collections.singletonList(new PonderStoryBoardEntry(DebugScenes::empty, + "debug/scene_1", new ResourceLocation("minecraft", "stick"))); + scenes.addAll(PonderRegistry.compile(l)); + } + lazyIndex = LerpedFloat.linear() + .startWithValue(index); + sceneProgress = LerpedFloat.linear() + .startWithValue(0); + fadeIn = LerpedFloat.linear() + .startWithValue(0) + .chase(1, .1f, Chaser.EXP); + clipboardHelper = new ClipboardHelper(); + } + + @Override + protected void init() { + super.init(); + widgets.clear(); + + tagButtons = new ArrayList<>(); + tagFades = new ArrayList<>(); + + tags.forEach(t -> { + int i = tagButtons.size(); + int x = 31; + int y = 71 + i * 30; + PonderButton b = new PonderButton(x, y, (mouseX, mouseY) -> { + centerScalingOn(mouseX, mouseY); + ScreenOpener.transitionTo(new PonderTagScreen(t)); + }).showing(t); + + widgets.add(b); + tagButtons.add(b); + + LerpedFloat chase = LerpedFloat.linear() + .startWithValue(0) + .chase(0, .05f, Chaser.exp(.1)); + tagFades.add(chase); + + }); + + if (chapter != null) { + widgets.add(chap = new PonderButton(width - 31 - 24, 31, () -> { + }).showing(chapter)); + } + + GameSettings bindings = minecraft.gameSettings; + int spacing = 8; + int bX = (width - 20) / 2 - (70 + 2 * spacing); + int bY = height - 20 - 31; + + widgets.add(scan = new PonderButton(bX, bY, () -> { + identifyMode = !identifyMode; + if (!identifyMode) + scenes.get(index) + .deselect(); + }).showing(AllIcons.I_MTD_SCAN) + .shortcut(bindings.keyBindDrop) + .fade(0, -1)); + + bX += 50 + spacing; + widgets.add(left = new PonderButton(bX, bY, () -> this.scroll(false)).showing(AllIcons.I_MTD_LEFT) + .shortcut(bindings.keyBindLeft) + .fade(0, -1)); + + bX += 20 + spacing; + widgets.add(new PonderButton(bX, bY, this::onClose).showing(AllIcons.I_MTD_CLOSE) + .shortcut(bindings.keyBindInventory) + .fade(0, -1)); + + bX += 20 + spacing; + widgets.add(right = new PonderButton(bX, bY, () -> this.scroll(true)).showing(AllIcons.I_MTD_RIGHT) + .shortcut(bindings.keyBindRight) + .fade(0, -1)); + + bX += 50 + spacing; + widgets.add(new PonderButton(bX, bY, this::replay).showing(AllIcons.I_MTD_REPLAY) + .shortcut(bindings.keyBindBack) + .fade(0, -1)); + + } + + @Override + public void tick() { + super.tick(); + PonderScene activeScene = scenes.get(index); + if (!identifyMode) + activeScene.tick(); + sceneProgress.chase(activeScene.getSceneProgress(), .5f, Chaser.EXP); + lazyIndex.tickChaser(); + fadeIn.tickChaser(); + sceneProgress.tickChaser(); + + if (!identifyMode) { + float lazyIndexValue = lazyIndex.getValue(); + if (Math.abs(lazyIndexValue - index) > 1 / 512f) + scenes.get(lazyIndexValue < index ? index - 1 : index + 1) + .tick(); + } + + updateIdentifiedItem(activeScene); + } + + public void updateIdentifiedItem(PonderScene activeScene) { + hoveredTooltipItem = ItemStack.EMPTY; + hoveredBlockPos = null; + if (!identifyMode) + return; + + MainWindow w = minecraft.getWindow(); + double mouseX = minecraft.mouseHelper.getMouseX() * w.getScaledWidth() / w.getWidth(); + double mouseY = minecraft.mouseHelper.getMouseY() * w.getScaledHeight() / w.getHeight(); + SceneTransform t = activeScene.getTransform(); + Vec3d vec1 = t.screenToScene(mouseX, mouseY, 1000); + Vec3d vec2 = t.screenToScene(mouseX, mouseY, -100); + Pair pair = activeScene.rayTraceScene(vec1, vec2); + hoveredTooltipItem = pair.getFirst(); + hoveredBlockPos = pair.getSecond(); + } + + @Override + public boolean mouseScrolled(double mouseX, double mouseY, double delta) { + if (scroll(delta > 0)) + return true; + return super.mouseScrolled(mouseX, mouseY, delta); + } + + protected void replay() { + identifyMode = false; + PonderScene scene = scenes.get(index); + + if (hasShiftDown()) { + List list = PonderRegistry.all.get(scene.component); + PonderStoryBoardEntry sb = list.get(index); + Template activeTemplate = PonderRegistry.loadSchematic(sb.getSchematicName()); + PonderWorld world = new PonderWorld(BlockPos.ZERO, Minecraft.getInstance().world); + activeTemplate.addBlocksToWorld(world, BlockPos.ZERO, new PlacementSettings()); + world.createBackup(); + scene = PonderRegistry.compileScene(index, sb, world); + scene.begin(); + scenes.set(index, scene); + } + + scene.begin(); + } + + protected boolean scroll(boolean forward) { + int prevIndex = index; + index = forward ? index + 1 : index - 1; + index = MathHelper.clamp(index, 0, scenes.size() - 1); + if (prevIndex != index) {// && Math.abs(index - lazyIndex.getValue()) < 1.5f) { + scenes.get(prevIndex) + .fadeOut(); + scenes.get(index) + .begin(); + lazyIndex.chase(index, 1 / 4f, Chaser.EXP); + identifyMode = false; + return true; + } else + index = prevIndex; + return false; + } + + @Override + protected void renderWindow(int mouseX, int mouseY, float partialTicks) { + RenderSystem.enableBlend(); + renderVisibleScenes(mouseX, mouseY, identifyMode ? 0 : partialTicks); + renderWidgets(mouseX, mouseY, identifyMode ? 0 : partialTicks); + } + + protected void renderVisibleScenes(int mouseX, int mouseY, float partialTicks) { + renderScene(mouseX, mouseY, index, partialTicks); + float lazyIndexValue = lazyIndex.getValue(partialTicks); + if (Math.abs(lazyIndexValue - index) > 1 / 512f) + renderScene(mouseX, mouseY, lazyIndexValue < index ? index - 1 : index + 1, partialTicks); + } + + protected void renderScene(int mouseX, int mouseY, int i, float partialTicks) { + SuperRenderTypeBuffer buffer = SuperRenderTypeBuffer.getInstance(); + PonderScene story = scenes.get(i); + MatrixStack ms = new MatrixStack(); + double value = lazyIndex.getValue(AnimationTickHolder.getPartialTicks()); + double diff = i - value; + double slide = MathHelper.lerp(diff * diff, 200, 600) * diff; + + RenderSystem.enableAlphaTest(); + RenderSystem.enableBlend(); + RenderSystem.enableDepthTest(); + + ms.push(); + story.transform.updateScreenParams(width, height, slide); + story.transform.apply(ms, partialTicks); + story.transform.updateSceneRVE(); + story.renderScene(buffer, ms, partialTicks); + buffer.draw(); + + // coords for debug + if (PonderIndex.EDITOR_MODE) { + MutableBoundingBox bounds = story.getBounds(); + + RenderSystem.pushMatrix(); + RenderSystem.multMatrix(ms.peek() + .getModel()); + + RenderSystem.scaled(-1 / 16d, -1 / 16d, 1 / 16d); + RenderSystem.translated(1, -8, -1 / 64f); + + // X AXIS + RenderSystem.pushMatrix(); + RenderSystem.translated(4, -3, 0); + for (int x = 0; x <= bounds.getXSize(); x++) { + RenderSystem.translated(-16, 0, 0); + font.drawString(x == bounds.getXSize() ? "x" : "" + x, 0, 0, 0xFFFFFFFF); + } + RenderSystem.popMatrix(); + + // Z AXIS + RenderSystem.pushMatrix(); + RenderSystem.scaled(-1, 1, 1); + RenderSystem.translated(0, -3, -4); + RenderSystem.rotatef(-90, 0, 1, 0); + RenderSystem.translated(-8, -2, 2 / 64f); + for (int z = 0; z <= bounds.getZSize(); z++) { + RenderSystem.translated(16, 0, 0); + font.drawString(z == bounds.getZSize() ? "z" : "" + z, 0, 0, 0xFFFFFFFF); + } + RenderSystem.popMatrix(); + + // DIRECTIONS + RenderSystem.pushMatrix(); + RenderSystem.translated(bounds.getXSize() * -8, 0, bounds.getZSize() * 8); + RenderSystem.rotatef(-90, 0, 1, 0); + for (Direction d : Iterate.horizontalDirections) { + RenderSystem.rotatef(90, 0, 1, 0); + RenderSystem.pushMatrix(); + RenderSystem.translated(0, 0, bounds.getZSize() * 16); + RenderSystem.rotatef(-90, 1, 0, 0); + font.drawString(d.name() + .substring(0, 1), 0, 0, 0x66FFFFFF); + font.drawString("|", 2, 10, 0x44FFFFFF); + font.drawString(".", 2, 14, 0x22FFFFFF); + RenderSystem.popMatrix(); + } + RenderSystem.popMatrix(); + + buffer.draw(); + RenderSystem.popMatrix(); + } + + ms.pop(); + } + + protected void renderWidgets(int mouseX, int mouseY, float partialTicks) { + float fade = fadeIn.getValue(partialTicks); + float lazyIndexValue = lazyIndex.getValue(partialTicks); + float indexDiff = Math.abs(lazyIndexValue - index); + PonderScene activeScene = scenes.get(index); + int textColor = 0xeeeeee; + + { + // Chapter title + RenderSystem.pushMatrix(); + RenderSystem.translated(0, 0, 800); + int x = 31 + 20 + 8; + int y = 31; + + String title = activeScene.getTitle(); + int wordWrappedHeight = font.getWordWrappedHeight(title, left.x); + + int streakHeight = 35 - 9 + wordWrappedHeight; + UIRenderHelper.streak(0, x - 4, y - 12 + streakHeight / 2, streakHeight, (int) (150 * fade), 0x101010); + UIRenderHelper.streak(180, x - 4, y - 12 + streakHeight / 2, streakHeight, (int) (30 * fade), 0x101010); + renderBox(21, 21, 30, 30, false); + + GuiGameElement.of(stack) + .at(x - 39, y - 11) + .scale(2) + .render(); + + drawString(font, Lang.translate(PONDERING), x, y - 6, 0xffa3a3a3); + y += 8; + x += 0; + // RenderSystem.translated(0, 3 * (indexDiff), 0); + RenderSystem.translated(x, y, 0); + RenderSystem.rotatef(indexDiff * -75, 1, 0, 0); + RenderSystem.translated(0, 0, 5); + font.drawSplitString(title, 0, 0, left.x, ColorHelper.applyAlpha(textColor, 1 - indexDiff)); + RenderSystem.popMatrix(); + + if (chapter != null) { + RenderSystem.pushMatrix(); + + RenderSystem.translated(chap.x - 4 - 4, chap.y, 0); + UIRenderHelper.streak(180, 4, 10, 26, (int) (150 * fade), 0x101010); + + drawRightAlignedString(font, Lang.translate(IN_CHAPTER), 0, 0, 0xffa3a3a3); + drawRightAlignedString(font, + Lang.translate(PonderLocalization.LANG_PREFIX + "chapter." + chapter.getId()), 0, 12, 0xffeeeeee); + + RenderSystem.popMatrix(); + } + } + + if (identifyMode) { + RenderSystem.pushMatrix(); + RenderSystem.translated(mouseX, mouseY, 100); + if (hoveredTooltipItem.isEmpty()) { + String tooltip = Lang + .createTranslationTextComponent(IDENTIFY_MODE, + new StringTextComponent(minecraft.gameSettings.keyBindDrop.getKeyBinding() + .getLocalizedName()).applyTextStyle(TextFormatting.WHITE)) + .applyTextStyle(TextFormatting.GRAY) + .getFormattedText(); + renderTooltip(font.listFormattedStringToWidth(tooltip, width / 3), 0, 0); + } else + renderTooltip(hoveredTooltipItem, 0, 0); + if (hoveredBlockPos != null && PonderIndex.EDITOR_MODE) { + RenderSystem.translated(0, -15, 0); + boolean copied = copiedBlockPos != null && hoveredBlockPos.equals(copiedBlockPos); + String coords = new StringTextComponent( + hoveredBlockPos.getX() + ", " + hoveredBlockPos.getY() + ", " + hoveredBlockPos.getZ()) + .applyTextStyles(copied ? TextFormatting.GREEN : TextFormatting.GOLD) + .getFormattedText(); + renderTooltip(coords, 0, 0); + } + RenderSystem.popMatrix(); + + scan.flash(); + } else { + scan.dim(); + } + + { + // Scene overlay + RenderSystem.pushMatrix(); + RenderSystem.translated(0, 0, 100); + renderOverlay(index, partialTicks); + if (indexDiff > 1 / 512f) + renderOverlay(lazyIndexValue < index ? index - 1 : index + 1, partialTicks); + RenderSystem.popMatrix(); + } + + // Widgets + widgets.forEach(w -> { + if (w instanceof PonderButton) { + PonderButton mtdButton = (PonderButton) w; + mtdButton.fade(fade); + } + }); + + if (index == 0 || index == 1 && lazyIndexValue < index) + left.fade(lazyIndexValue); + if (index == scenes.size() - 1 || index == scenes.size() - 2 && lazyIndexValue > index) + right.fade(scenes.size() - lazyIndexValue - 1); + + boolean finished = activeScene.isFinished(); + if (finished) + right.flash(); + else + right.dim(); + + { + int x = (width / 2) - 110; + int y = right.y + right.getHeight() + 4; + int w = width - 2 * x; + renderBox(x, y, w, 1, false); + RenderSystem.pushMatrix(); + RenderSystem.translated(x - 2, y - 2, 0); + RenderSystem.scaled((w + 4) * sceneProgress.getValue(partialTicks), 1, 1); + GuiUtils.drawGradientRect(200, 0, 3, 1, 4, 0x60ffeedd, 0x60ffeedd); + RenderSystem.popMatrix(); + } + + // Tags + List sceneTags = activeScene.tags; + boolean highlightAll = sceneTags.contains(PonderTag.Highlight.ALL); + double s = Minecraft.getInstance() + .getWindow() + .getGuiScaleFactor(); + IntStream.range(0, tagButtons.size()) + .forEach(i -> { + RenderSystem.pushMatrix(); + LerpedFloat chase = tagFades.get(i); + PonderButton button = tagButtons.get(i); + if (button.isMouseOver(mouseX, mouseY)) { + chase.updateChaseTarget(1); + } else + chase.updateChaseTarget(0); + + chase.tickChaser(); + + if (highlightAll || sceneTags.contains(this.tags.get(i))) + button.flash(); + else + button.dim(); + + int x = button.x + button.getWidth() + 4; + int y = button.y - 2; + RenderSystem.translated(x, y + 5 * (1 - fade), 800); + + float fadedWidth = 200 * chase.getValue(partialTicks); + UIRenderHelper.streak(0, 0, 12, 26, (int) fadedWidth, 0x101010); + + GL11.glScissor((int) (x * s), 0, (int) (fadedWidth * s), (int) (height * s)); + GL11.glEnable(GL11.GL_SCISSOR_TEST); + + String tagName = this.tags.get(i) + .getTitle(); + drawString(tagName, 3, 8, 0xffeedd); + + GL11.glDisable(GL11.GL_SCISSOR_TEST); + + RenderSystem.popMatrix(); + }); + } + + protected void lowerButtonGroup(int index, int mouseX, int mouseY, float fade, AllIcons icon, KeyBinding key) { + int bWidth = 20; + int bHeight = 20; + int bX = (width - bWidth) / 2 + (index - 1) * (bWidth + 8); + int bY = height - bHeight - 31; + + RenderSystem.pushMatrix(); + if (fade < fadeIn.getChaseTarget()) + RenderSystem.translated(0, (1 - fade) * 5, 0); + boolean hovered = isMouseOver(mouseX, mouseY, bX, bY, bWidth, bHeight); + renderBox(bX, bY, bWidth, bHeight, hovered); + icon.draw(bX + 2, bY + 2); + drawCenteredString(font, key.getLocalizedName(), bX + bWidth / 2 + 8, bY + bHeight - 6, 0xff606060); + RenderSystem.popMatrix(); + } + + private void renderOverlay(int i, float partialTicks) { + if (identifyMode) + return; + RenderSystem.pushMatrix(); + PonderScene story = scenes.get(i); + MatrixStack ms = new MatrixStack(); + story.renderOverlay(this, ms, partialTicks); + RenderSystem.popMatrix(); + } + + @Override + public boolean mouseClicked(double x, double y, int button) { + MutableBoolean handled = new MutableBoolean(false); + widgets.forEach(w -> { + if (handled.booleanValue()) + return; + if (!w.isMouseOver(x, y)) + return; + if (w instanceof PonderButton) { + PonderButton mtdButton = (PonderButton) w; + mtdButton.runCallback(x, y); + handled.setTrue(); + return; + } + }); + + if (handled.booleanValue()) + return true; + + if (identifyMode && hoveredBlockPos != null && PonderIndex.EDITOR_MODE) { + long handle = minecraft.getWindow() + .getHandle(); + if (copiedBlockPos != null && button == 1) { + clipboardHelper.setClipboardString(handle, + "util.select.fromTo(" + copiedBlockPos.getX() + ", " + copiedBlockPos.getY() + ", " + + copiedBlockPos.getZ() + ", " + hoveredBlockPos.getX() + ", " + hoveredBlockPos.getY() + ", " + + hoveredBlockPos.getZ() + ")"); + copiedBlockPos = hoveredBlockPos; + return true; + } + + clipboardHelper.setClipboardString(handle, "util.grid.at(" + hoveredBlockPos.getX() + ", " + + hoveredBlockPos.getY() + ", " + hoveredBlockPos.getZ() + ")"); + copiedBlockPos = hoveredBlockPos; + return true; + } + + return super.mouseClicked(x, y, button); + } + + @Override + public boolean keyPressed(int code, int p_keyPressed_2_, int p_keyPressed_3_) { + GameSettings settings = Minecraft.getInstance().gameSettings; + int sCode = settings.keyBindBack.getKey() + .getKeyCode(); + int aCode = settings.keyBindLeft.getKey() + .getKeyCode(); + int dCode = settings.keyBindRight.getKey() + .getKeyCode(); + int qCode = settings.keyBindDrop.getKey() + .getKeyCode(); + + if (code == sCode) { + replay(); + return true; + } + + if (code == aCode) { + scroll(false); + return true; + } + + if (code == dCode) { + scroll(true); + return true; + } + + if (code == qCode) { + identifyMode = !identifyMode; + if (!identifyMode) + scenes.get(index) + .deselect(); + return true; + } + + return super.keyPressed(code, p_keyPressed_2_, p_keyPressed_3_); + } + + @Override + protected String getBreadcrumbTitle() { + if (chapter != null) + return Lang.translate(PonderLocalization.LANG_PREFIX + "chapter." + chapter.getId()); + + return stack.getItem() + .getName() + .getFormattedText(); + } + + public FontRenderer getFontRenderer() { + return font; + } + + protected boolean isMouseOver(double mouseX, double mouseY, int x, int y, int w, int h) { + boolean hovered = !(mouseX < x || mouseX > x + w); + hovered &= !(mouseY < y || mouseY > y + h); + return hovered; + } + + public void drawString(String s, int x, int y, int color) { + drawString(font, s, x, y, color); + } + + public static void renderBox(int x, int y, int w, int h, boolean highlighted) { + renderBox(x, y, w, h, 0xff000000, highlighted ? 0xf0ffeedd : 0x40ffeedd, highlighted ? 0x60ffeedd : 0x20ffeedd); + } + + public static void renderSpeechBox(int x, int y, int w, int h, boolean highlighted, Pointing pointing, + boolean returnWithLocalTransform) { + if (!returnWithLocalTransform) + RenderSystem.pushMatrix(); + + int boxX = x; + int boxY = y; + int divotX = x; + int divotY = y; + int divotRotation = 0; + int divotSize = 8; + int distance = 1; + int divotRadius = divotSize / 2; + + switch (pointing) { + default: + case DOWN: + divotRotation = 0; + boxX -= w / 2; + boxY -= h + divotSize + 1 + distance; + divotX -= divotRadius; + divotY -= divotSize + distance; + break; + case LEFT: + divotRotation = 90; + boxX += divotSize + 1 + distance; + boxY -= h / 2; + divotX += distance; + divotY -= divotRadius; + break; + case RIGHT: + divotRotation = 270; + boxX -= w + divotSize + 1 + distance; + boxY -= h / 2; + divotX -= divotSize + distance; + divotY -= divotRadius; + break; + case UP: + divotRotation = 180; + boxX -= w / 2; + boxY += divotSize + 1 + distance; + divotX -= divotRadius; + divotY += distance; + break; + } + + renderBox(boxX, boxY, w, h, highlighted); + + RenderSystem.pushMatrix(); + AllGuiTextures toRender = highlighted ? AllGuiTextures.SPEECH_TOOLTIP_HIGHLIGHT : AllGuiTextures.SPEECH_TOOLTIP; + RenderSystem.translated(divotX + divotRadius, divotY + divotRadius, 10); + RenderSystem.rotatef(divotRotation, 0, 0, 1); + RenderSystem.translated(-divotRadius, -divotRadius, 0); + toRender.draw(0, 0); + RenderSystem.popMatrix(); + + if (returnWithLocalTransform) { + RenderSystem.translated(boxX, boxY, 0); + return; + } + + RenderSystem.popMatrix(); + + } + + public static void renderBox(int x, int y, int w, int h, int backgroundColor, int borderColorStart, + int borderColorEnd) { + int z = 100; + GuiUtils.drawGradientRect(z, x - 3, y - 4, x + w + 3, y - 3, backgroundColor, backgroundColor); + GuiUtils.drawGradientRect(z, x - 3, y + h + 3, x + w + 3, y + h + 4, backgroundColor, backgroundColor); + GuiUtils.drawGradientRect(z, x - 3, y - 3, x + w + 3, y + h + 3, backgroundColor, backgroundColor); + GuiUtils.drawGradientRect(z, x - 4, y - 3, x - 3, y + h + 3, backgroundColor, backgroundColor); + GuiUtils.drawGradientRect(z, x + w + 3, y - 3, x + w + 4, y + h + 3, backgroundColor, backgroundColor); + GuiUtils.drawGradientRect(z, x - 3, y - 3 + 1, x - 3 + 1, y + h + 3 - 1, borderColorStart, borderColorEnd); + GuiUtils.drawGradientRect(z, x + w + 2, y - 3 + 1, x + w + 3, y + h + 3 - 1, borderColorStart, borderColorEnd); + GuiUtils.drawGradientRect(z, x - 3, y - 3, x + w + 3, y - 3 + 1, borderColorStart, borderColorStart); + GuiUtils.drawGradientRect(z, x - 3, y + h + 2, x + w + 3, y + h + 3, borderColorEnd, borderColorEnd); + } + + public ItemStack getHoveredTooltipItem() { + return hoveredTooltipItem; + } + + public ItemStack getSubject() { + return stack; + } + + @Override + public boolean isEquivalentTo(AbstractSimiScreen other) { + if (other instanceof PonderUI) + return stack.isItemEqual(((PonderUI) other).stack); + return super.isEquivalentTo(other); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/PonderWorld.java b/src/main/java/com/simibubi/create/foundation/ponder/PonderWorld.java new file mode 100644 index 000000000..1b75b6571 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/PonderWorld.java @@ -0,0 +1,252 @@ +package com.simibubi.create.foundation.ponder; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.annotation.Nullable; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.content.contraptions.relays.belt.BeltBlock; +import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity; +import com.simibubi.create.content.schematics.SchematicWorld; +import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer; +import com.simibubi.create.foundation.tileEntity.SmartTileEntity; + +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.client.Minecraft; +import net.minecraft.client.particle.IParticleFactory; +import net.minecraft.client.particle.Particle; +import net.minecraft.client.particle.ParticleManager; +import net.minecraft.client.renderer.ActiveRenderInfo; +import net.minecraft.client.renderer.IRenderTypeBuffer; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.entity.EntityRendererManager; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.inventory.container.PlayerContainer; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.particles.BlockParticleData; +import net.minecraft.particles.IParticleData; +import net.minecraft.particles.ParticleTypes; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.shapes.VoxelShape; +import net.minecraft.world.IBlockReader; +import net.minecraft.world.LightType; +import net.minecraft.world.World; +import net.minecraftforge.registries.ForgeRegistries; + +public class PonderWorld extends SchematicWorld { + + protected Map originalBlocks; + protected Map originalTileEntities; + protected List originalEntities; + protected PonderWorldParticles particles; + + int overrideLight; + Selection mask; + + public PonderWorld(BlockPos anchor, World original) { + super(anchor, original); + originalBlocks = new HashMap<>(); + originalTileEntities = new HashMap<>(); + originalEntities = new ArrayList<>(); + particles = new PonderWorldParticles(this); + } + + public void createBackup() { + originalBlocks.clear(); + originalTileEntities.clear(); + blocks.forEach((k, v) -> originalBlocks.put(k, v)); + tileEntities.forEach((k, v) -> originalTileEntities.put(k, TileEntity.create(v.write(new CompoundNBT())))); + entities.forEach(e -> EntityType.loadEntityUnchecked(e.serializeNBT(), this) + .ifPresent(originalEntities::add)); + } + + public void restore() { + entities.clear(); + blocks.clear(); + tileEntities.clear(); + renderedTileEntities.clear(); + originalBlocks.forEach((k, v) -> blocks.put(k, v)); + originalTileEntities.forEach((k, v) -> { + TileEntity te = TileEntity.create(v.write(new CompoundNBT())); + te.setLocation(this, te.getPos()); + tileEntities.put(k, te); + renderedTileEntities.add(te); + }); + originalEntities.forEach(e -> EntityType.loadEntityUnchecked(e.serializeNBT(), this) + .ifPresent(entities::add)); + particles.clearEffects(); + fixVirtualTileEntities(); + } + + public void pushFakeLight(int light) { + this.overrideLight = light; + } + + public void popLight() { + this.overrideLight = -1; + } + + @Override + public int getLightLevel(LightType p_226658_1_, BlockPos p_226658_2_) { + return overrideLight == -1 ? 15 : overrideLight; + } + + public void setMask(Selection mask) { + this.mask = mask; + } + + public void clearMask() { + this.mask = null; + } + + @Override + public BlockState getBlockState(BlockPos globalPos) { + if (mask != null && !mask.test(globalPos.subtract(anchor))) + return Blocks.AIR.getDefaultState(); + return super.getBlockState(globalPos); + } + + @Override // For particle collision + public IBlockReader getExistingChunk(int p_225522_1_, int p_225522_2_) { + return this; + } + + public void renderEntities(MatrixStack ms, SuperRenderTypeBuffer buffer, ActiveRenderInfo ari, float pt) { + Vec3d vec3d = ari.getProjectedView(); + double d0 = vec3d.getX(); + double d1 = vec3d.getY(); + double d2 = vec3d.getZ(); + + for (Entity entity : entities) { + if (entity.ticksExisted == 0) { + entity.lastTickPosX = entity.getX(); + entity.lastTickPosY = entity.getY(); + entity.lastTickPosZ = entity.getZ(); + } + renderEntity(entity, d0, d1, d2, pt, ms, buffer); + } + + buffer.draw(RenderType.getEntitySolid(PlayerContainer.BLOCK_ATLAS_TEXTURE)); + buffer.draw(RenderType.getEntityCutout(PlayerContainer.BLOCK_ATLAS_TEXTURE)); + buffer.draw(RenderType.getEntityCutoutNoCull(PlayerContainer.BLOCK_ATLAS_TEXTURE)); + buffer.draw(RenderType.getEntitySmoothCutout(PlayerContainer.BLOCK_ATLAS_TEXTURE)); + } + + private void renderEntity(Entity entity, double x, double y, double z, float pt, MatrixStack ms, + IRenderTypeBuffer buffer) { + double d0 = MathHelper.lerp((double) pt, entity.lastTickPosX, entity.getX()); + double d1 = MathHelper.lerp((double) pt, entity.lastTickPosY, entity.getY()); + double d2 = MathHelper.lerp((double) pt, entity.lastTickPosZ, entity.getZ()); + float f = MathHelper.lerp(pt, entity.prevRotationYaw, entity.rotationYaw); + EntityRendererManager renderManager = Minecraft.getInstance() + .getRenderManager(); + int light = renderManager.getRenderer(entity) + .getLight(entity, pt); + renderManager.render(entity, d0 - x, d1 - y, d2 - z, f, pt, ms, buffer, light); + } + + public void renderParticles(MatrixStack ms, IRenderTypeBuffer buffer, ActiveRenderInfo ari, float pt) { + particles.renderParticles(ms, buffer, ari, pt); + } + + public void tick() { + particles.tick(); + + for (Iterator iterator = entities.iterator(); iterator.hasNext();) { + Entity entity = iterator.next(); + + entity.ticksExisted++; + entity.lastTickPosX = entity.getX(); + entity.lastTickPosY = entity.getY(); + entity.lastTickPosZ = entity.getZ(); + entity.tick(); + + if (!entity.isAlive()) + iterator.remove(); + } + } + + @Override + public void addParticle(IParticleData data, double x, double y, double z, double mx, double my, double mz) { + addParticle(makeParticle(data, x, y, z, mx, my, mz)); + } + + @Nullable + @SuppressWarnings("unchecked") + private Particle makeParticle(T data, double x, double y, double z, double mx, double my, + double mz) { + ParticleManager particleManager = Minecraft.getInstance().particles; + ResourceLocation key = ForgeRegistries.PARTICLE_TYPES.getKey(data.getType()); + IParticleFactory iparticlefactory = (IParticleFactory) particleManager.factories.get(key); + return iparticlefactory == null ? null : iparticlefactory.makeParticle(data, this, x, y, z, mx, my, mz); + } + + public void addParticle(Particle p) { + if (p != null) + particles.addParticle(p); + } + + public void fixVirtualTileEntities() { + for (TileEntity tileEntity : tileEntities.values()) { + if (!(tileEntity instanceof SmartTileEntity)) + continue; + SmartTileEntity smartTileEntity = (SmartTileEntity) tileEntity; + smartTileEntity.markVirtual(); + + if (!(smartTileEntity instanceof BeltTileEntity)) + continue; + BeltTileEntity beltTileEntity = (BeltTileEntity) smartTileEntity; + if (!beltTileEntity.isController()) + continue; + BlockPos controllerPos = tileEntity.getPos(); + for (BlockPos blockPos : BeltBlock.getBeltChain(this, controllerPos)) { + TileEntity tileEntity2 = getTileEntity(blockPos); + if (!(tileEntity2 instanceof BeltTileEntity)) + continue; + BeltTileEntity belt2 = (BeltTileEntity) tileEntity2; + belt2.setController(controllerPos); + } + } + } + + public void addBlockDestroyEffects(BlockPos pos, BlockState state) { + VoxelShape voxelshape = state.getShape(this, pos); + if (voxelshape.isEmpty()) + return; + + AxisAlignedBB bb = voxelshape.getBoundingBox(); + double d1 = Math.min(1.0D, bb.maxX - bb.minX); + double d2 = Math.min(1.0D, bb.maxY - bb.minY); + double d3 = Math.min(1.0D, bb.maxZ - bb.minZ); + int i = Math.max(2, MathHelper.ceil(d1 / 0.25D)); + int j = Math.max(2, MathHelper.ceil(d2 / 0.25D)); + int k = Math.max(2, MathHelper.ceil(d3 / 0.25D)); + + for (int l = 0; l < i; ++l) { + for (int i1 = 0; i1 < j; ++i1) { + for (int j1 = 0; j1 < k; ++j1) { + double d4 = (l + 0.5D) / i; + double d5 = (i1 + 0.5D) / j; + double d6 = (j1 + 0.5D) / k; + double d7 = d4 * d1 + bb.minX; + double d8 = d5 * d2 + bb.minY; + double d9 = d6 * d3 + bb.minZ; + addParticle(new BlockParticleData(ParticleTypes.BLOCK, state), pos.getX() + d7, pos.getY() + d8, + pos.getZ() + d9, d4 - 0.5D, d5 - 0.5D, d6 - 0.5D); + } + } + } + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/PonderWorldParticles.java b/src/main/java/com/simibubi/create/foundation/ponder/PonderWorldParticles.java new file mode 100644 index 000000000..1f121ba1e --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/PonderWorldParticles.java @@ -0,0 +1,108 @@ +package com.simibubi.create.foundation.ponder; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; +import java.util.Queue; + +import com.google.common.collect.EvictingQueue; +import com.google.common.collect.Maps; +import com.google.common.collect.Queues; +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.systems.RenderSystem; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.particle.IParticleRenderType; +import net.minecraft.client.particle.Particle; +import net.minecraft.client.renderer.ActiveRenderInfo; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.IRenderTypeBuffer; +import net.minecraft.client.renderer.LightTexture; +import net.minecraft.client.renderer.Tessellator; + +public class PonderWorldParticles { + + private final Map> byType = Maps.newIdentityHashMap(); + private final Queue queue = Queues.newArrayDeque(); + + PonderWorld world; + + public PonderWorldParticles(PonderWorld world) { + this.world = world; + } + + public void addParticle(Particle p) { + this.queue.add(p); + } + + public void tick() { + this.byType.forEach((p_228347_1_, p_228347_2_) -> this.tickParticleList(p_228347_2_)); + + Particle particle; + if (queue.isEmpty()) + return; + while ((particle = this.queue.poll()) != null) + this.byType.computeIfAbsent(particle.getRenderType(), $ -> EvictingQueue.create(16384)) + .add(particle); + } + + private void tickParticleList(Collection p_187240_1_) { + if (p_187240_1_.isEmpty()) + return; + + Iterator iterator = p_187240_1_.iterator(); + while (iterator.hasNext()) { + Particle particle = iterator.next(); + particle.tick(); + if (!particle.isAlive()) + iterator.remove(); + } + } + + public void renderParticles(MatrixStack ms, IRenderTypeBuffer buffer, ActiveRenderInfo p_228345_4_, float p_228345_5_) { + Minecraft mc = Minecraft.getInstance(); + LightTexture p_228345_3_ = mc.gameRenderer.getLightmapTextureManager(); + + p_228345_3_.enableLightmap(); + Runnable enable = () -> { + RenderSystem.enableAlphaTest(); + RenderSystem.defaultAlphaFunc(); + RenderSystem.enableDepthTest(); + RenderSystem.enableFog(); + }; + RenderSystem.pushMatrix(); + RenderSystem.multMatrix(ms.peek() + .getModel()); + + for (IParticleRenderType iparticlerendertype : this.byType.keySet()) { // Forge: allow custom + // IParticleRenderType's + if (iparticlerendertype == IParticleRenderType.NO_RENDER) + continue; + enable.run(); // Forge: MC-168672 Make sure all render types have the correct GL state. + Iterable iterable = this.byType.get(iparticlerendertype); + if (iterable != null) { + RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F); + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder bufferbuilder = tessellator.getBuffer(); + iparticlerendertype.beginRender(bufferbuilder, mc.textureManager); + + for (Particle particle : iterable) + particle.buildGeometry(bufferbuilder, p_228345_4_, p_228345_5_); + + iparticlerendertype.finishRender(tessellator); + } + } + + RenderSystem.popMatrix(); + RenderSystem.depthMask(true); + RenderSystem.disableBlend(); + RenderSystem.defaultAlphaFunc(); + p_228345_3_.disableLightmap(); + RenderSystem.disableFog(); + } + + public void clearEffects() { + this.byType.clear(); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/SceneBuilder.java b/src/main/java/com/simibubi/create/foundation/ponder/SceneBuilder.java new file mode 100644 index 000000000..fe208b5ff --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/SceneBuilder.java @@ -0,0 +1,657 @@ +package com.simibubi.create.foundation.ponder; + +import java.util.Optional; +import java.util.UUID; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.UnaryOperator; + +import com.simibubi.create.content.contraptions.base.IRotate.SpeedLevel; +import com.simibubi.create.content.contraptions.base.KineticBlock; +import com.simibubi.create.content.contraptions.base.KineticTileEntity; +import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueItem; +import com.simibubi.create.content.contraptions.particle.RotationIndicatorParticleData; +import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity; +import com.simibubi.create.content.contraptions.relays.gauge.SpeedGaugeTileEntity; +import com.simibubi.create.content.logistics.block.funnel.FunnelTileEntity; +import com.simibubi.create.foundation.ponder.content.PonderPalette; +import com.simibubi.create.foundation.ponder.elements.BeltItemElement; +import com.simibubi.create.foundation.ponder.elements.EntityElement; +import com.simibubi.create.foundation.ponder.elements.InputWindowElement; +import com.simibubi.create.foundation.ponder.elements.ParrotElement; +import com.simibubi.create.foundation.ponder.elements.TextWindowElement; +import com.simibubi.create.foundation.ponder.elements.WorldSectionElement; +import com.simibubi.create.foundation.ponder.instructions.AnimateParrotInstruction; +import com.simibubi.create.foundation.ponder.instructions.AnimateTileEntityInstruction; +import com.simibubi.create.foundation.ponder.instructions.AnimateWorldSectionInstruction; +import com.simibubi.create.foundation.ponder.instructions.ChaseAABBInstruction; +import com.simibubi.create.foundation.ponder.instructions.CreateParrotInstruction; +import com.simibubi.create.foundation.ponder.instructions.DelayInstruction; +import com.simibubi.create.foundation.ponder.instructions.DisplayWorldSectionInstruction; +import com.simibubi.create.foundation.ponder.instructions.EmitParticlesInstruction; +import com.simibubi.create.foundation.ponder.instructions.EmitParticlesInstruction.Emitter; +import com.simibubi.create.foundation.ponder.instructions.FadeOutOfSceneInstruction; +import com.simibubi.create.foundation.ponder.instructions.LineInstruction; +import com.simibubi.create.foundation.ponder.instructions.MarkAsFinishedInstruction; +import com.simibubi.create.foundation.ponder.instructions.MovePoiInstruction; +import com.simibubi.create.foundation.ponder.instructions.OutlineSelectionInstruction; +import com.simibubi.create.foundation.ponder.instructions.ReplaceBlocksInstruction; +import com.simibubi.create.foundation.ponder.instructions.RotateSceneInstruction; +import com.simibubi.create.foundation.ponder.instructions.ShowInputInstruction; +import com.simibubi.create.foundation.ponder.instructions.TextInstruction; +import com.simibubi.create.foundation.ponder.instructions.TileEntityDataInstruction; +import com.simibubi.create.foundation.tileEntity.SmartTileEntity; +import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour; +import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour; +import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour.TransportedResult; +import com.simibubi.create.foundation.utility.ColorHelper; +import com.simibubi.create.foundation.utility.VecHelper; + +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.entity.Entity; +import net.minecraft.entity.item.ItemEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.particles.RedstoneParticleData; +import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.Direction; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.Vec3i; +import net.minecraft.world.World; + +/** + * Enqueue instructions to the schedule via this object's methods. + */ +public class SceneBuilder { + + /** + * Ponder's toolkit for showing information on top of the scene world, such as + * highlighted bounding boxes, texts, icons and keybindings. + */ + public final OverlayInstructions overlay; + + /** + * Instructions for manipulating the schematic and its currently visible areas. + * Allows to show, hide and modify blocks as the scene plays out. + */ + public final WorldInstructions world; + + /** + * Additional tools for debugging ponder and bypassing the facade + */ + public final DebugInstructions debug; + + /** + * Special effects to embellish and communicate with + */ + public final EffectInstructions effects; + + /** + * Random other instructions that might come in handy + */ + public final SpecialInstructions special; + + private final PonderScene scene; + + public SceneBuilder(PonderScene ponderScene) { + scene = ponderScene; + overlay = new OverlayInstructions(); + special = new SpecialInstructions(); + world = new WorldInstructions(); + debug = new DebugInstructions(); + effects = new EffectInstructions(); + } + + // General + + /** + * Assign a unique translation key, as well as the standard english translation + * for this scene's title using this method, anywhere inside the program + * function. + * + * @param sceneId + * @param title + */ + public void title(String sceneId, String title) { + scene.sceneId = sceneId; + PonderLocalization.registerSpecific(sceneId, PonderScene.TITLE_KEY, title); + } + + /** + * Communicates to the ponder UI which parts of the schematic make up the base + * horizontally. Use of this is encouraged whenever there are components outside + * the the base plate.
+ * As a result, showBasePlate() will only show the configured size, and the + * scene's scaling inside the UI will be consistent with its base size. + * + * @param xOffset Block spaces between the base plate and the schematic + * boundary on the Western side. + * @param zOffset Block spaces between the base plate and the schematic + * boundary on the Northern side. + * @param basePlateSize Length in blocks of the base plate itself. Ponder + * assumes it to be square + */ + public void configureBasePlate(int xOffset, int zOffset, int basePlateSize) { + scene.offsetX = xOffset; + scene.offsetZ = zOffset; + scene.size = basePlateSize; + } + + /** + * Fade the layer of blocks into the scene ponder assumes to be the base plate + * of the schematic's structure. Makes for a nice opener + */ + public void showBasePlate() { + world.showSection(scene.getSceneBuildingUtil().select.cuboid(new BlockPos(scene.offsetX, 0, scene.offsetZ), + new Vec3i(scene.size, 0, scene.size)), Direction.UP); + } + + /** + * Before running the upcoming instructions, wait for a duration to let previous + * actions play out.
+ * Idle does not stall any animations, only schedules a time gap between + * instructions. + * + * @param ticks Duration to wait for + */ + public void idle(int ticks) { + addInstruction(new DelayInstruction(ticks)); + } + + /** + * Before running the upcoming instructions, wait for a duration to let previous + * actions play out.
+ * Idle does not stall any animations, only schedules a time gap between + * instructions. + * + * @param seconds Duration to wait for + */ + public void idleSeconds(int seconds) { + idle(seconds * 20); + } + + /** + * Once the scene reaches this instruction in the timeline, mark it as + * "finished". This happens automatically when the end of a storyboard is + * reached, but can be desirable to do earlier, in order to bypass the wait for + * any residual text windows to time out.
+ * So far this event only affects the "next scene" button in the UI to flash. + */ + public void markAsFinished() { + addInstruction(new MarkAsFinishedInstruction()); + } + + /** + * Pans the scene's camera view around the vertical axis by the given amount + * + * @param degrees + */ + public void rotateCameraY(float degrees) { + addInstruction(new RotateSceneInstruction(0, degrees, true)); + } + + public class EffectInstructions { + + public void emitParticles(Vec3d location, Emitter emitter, float amountPerCycle, int cycles) { + addInstruction(new EmitParticlesInstruction(location, emitter, amountPerCycle, cycles)); + } + + public void superGlue(BlockPos pos, Direction side, boolean fullBlock) { + addInstruction(scene -> SuperGlueItem.spawnParticles(scene.world, pos, side, fullBlock)); + } + + private void rotationIndicator(BlockPos pos, boolean direction) { + addInstruction(scene -> { + BlockState blockState = scene.world.getBlockState(pos); + TileEntity tileEntity = scene.world.getTileEntity(pos); + + if (!(blockState.getBlock() instanceof KineticBlock)) + return; + if (!(tileEntity instanceof KineticTileEntity)) + return; + + KineticTileEntity kte = (KineticTileEntity) tileEntity; + KineticBlock kb = (KineticBlock) blockState.getBlock(); + Axis rotationAxis = kb.getRotationAxis(blockState); + + float speed = kte.getTheoreticalSpeed(); + SpeedLevel speedLevel = SpeedLevel.of(speed); + int color = direction ? speed > 0 ? 0xeb5e0b : 0x1687a7 : speedLevel.getColor(); + int particleSpeed = speedLevel.getParticleSpeed(); + particleSpeed *= Math.signum(speed); + + Vec3d location = VecHelper.getCenterOf(pos); + RotationIndicatorParticleData particleData = new RotationIndicatorParticleData(color, particleSpeed, + kb.getParticleInitialRadius(), kb.getParticleTargetRadius(), 20, rotationAxis.name() + .charAt(0)); + + for (int i = 0; i < 20; i++) + scene.world.addParticle(particleData, location.x, location.y, location.z, 0, 0, 0); + }); + } + + public void rotationSpeedIndicator(BlockPos pos) { + rotationIndicator(pos, false); + } + + public void rotationDirectionIndicator(BlockPos pos) { + rotationIndicator(pos, true); + } + + public void indicateRedstone(BlockPos pos) { + createRedstoneParticles(pos, 0xFF0000, 10); + } + + public void indicateSuccess(BlockPos pos) { + createRedstoneParticles(pos, 0x80FFaa, 10); + } + + public void createRedstoneParticles(BlockPos pos, int color, int amount) { + Vec3d rgb = ColorHelper.getRGB(color); + addInstruction(new EmitParticlesInstruction(VecHelper.getCenterOf(pos), Emitter.withinBlockSpace( + new RedstoneParticleData((float) rgb.x, (float) rgb.y, (float) rgb.z, 1), Vec3d.ZERO), amount, 2)); + } + + } + + public class OverlayInstructions { + + public TextWindowElement.Builder showText(int duration) { + TextWindowElement textWindowElement = new TextWindowElement(); + addInstruction(new TextInstruction(textWindowElement, duration)); + return textWindowElement.new Builder(scene); + } + + public TextWindowElement.Builder showSelectionWithText(Selection selection, int duration) { + TextWindowElement textWindowElement = new TextWindowElement(); + addInstruction(new TextInstruction(textWindowElement, duration, selection)); + return textWindowElement.new Builder(scene).pointAt(selection.getCenter()); + } + + public void showControls(InputWindowElement element, int duration) { + addInstruction(new ShowInputInstruction(element.clone(), duration)); + } + + public void chaseBoundingBoxOutline(PonderPalette color, Object slot, AxisAlignedBB boundingBox, int duration) { + addInstruction(new ChaseAABBInstruction(color, slot, boundingBox, duration)); + } + + public void showLine(PonderPalette color, Vec3d start, Vec3d end, int duration) { + addInstruction(new LineInstruction(color, start, end, duration)); + } + + public void showOutline(PonderPalette color, Object slot, Selection selection, int duration) { + addInstruction(new OutlineSelectionInstruction(color, slot, selection, duration)); + } + + } + + public class SpecialInstructions { + + public ElementLink birbOnTurntable(BlockPos pos) { + ElementLink link = new ElementLink<>(ParrotElement.class); + ParrotElement parrot = ParrotElement.spinOnComponent(VecHelper.getCenterOf(pos), pos); + addInstruction(new CreateParrotInstruction(10, Direction.DOWN, parrot)); + addInstruction(scene -> scene.linkElement(parrot, link)); + return link; + } + + public ElementLink birbOnSpinnyShaft(BlockPos pos) { + ElementLink link = new ElementLink<>(ParrotElement.class); + ParrotElement parrot = ParrotElement.spinOnComponent(VecHelper.getCenterOf(pos) + .add(0, 0.5, 0), pos); + addInstruction(new CreateParrotInstruction(10, Direction.DOWN, parrot)); + addInstruction(scene -> scene.linkElement(parrot, link)); + return link; + } + + public ElementLink birbLookingAtPOI(Vec3d location) { + ElementLink link = new ElementLink<>(ParrotElement.class); + ParrotElement parrot = ParrotElement.lookAtPOI(location); + addInstruction(new CreateParrotInstruction(10, Direction.DOWN, parrot)); + addInstruction(scene -> scene.linkElement(parrot, link)); + return link; + } + + public ElementLink flappyBirb(Vec3d location) { + ElementLink link = new ElementLink<>(ParrotElement.class); + ParrotElement parrot = ParrotElement.flappy(location); + addInstruction(new CreateParrotInstruction(10, Direction.DOWN, parrot)); + addInstruction(scene -> scene.linkElement(parrot, link)); + return link; + } + + public ElementLink birbPartying(Vec3d location) { + ElementLink link = new ElementLink<>(ParrotElement.class); + ParrotElement parrot = ParrotElement.dance(location); + addInstruction(new CreateParrotInstruction(10, Direction.DOWN, parrot)); + addInstruction(scene -> scene.linkElement(parrot, link)); + return link; + } + + public void movePointOfInterest(Vec3d location) { + addInstruction(new MovePoiInstruction(location)); + } + + public void movePointOfInterest(BlockPos location) { + movePointOfInterest(VecHelper.getCenterOf(location)); + } + + public void rotateParrot(ElementLink link, double xRotation, double yRotation, double zRotation, + int duration) { + addInstruction(AnimateParrotInstruction.rotate(link, new Vec3d(xRotation, yRotation, zRotation), duration)); + } + + public void moveParrot(ElementLink link, Vec3d offset, int duration) { + addInstruction(AnimateParrotInstruction.move(link, offset, duration)); + } + + } + + public class WorldInstructions { + + public void showSection(Selection selection, Direction fadeInDirection) { + addInstruction(new DisplayWorldSectionInstruction(15, fadeInDirection, selection, + Optional.of(scene::getBaseWorldSection))); + } + + public void showSectionAndMerge(Selection selection, Direction fadeInDirection, + ElementLink link) { + addInstruction(new DisplayWorldSectionInstruction(15, fadeInDirection, selection, + Optional.of(() -> scene.resolve(link)))); + } + + public ElementLink showIndependentSection(Selection selection, Direction fadeInDirection) { + DisplayWorldSectionInstruction instruction = + new DisplayWorldSectionInstruction(15, fadeInDirection, selection, Optional.empty()); + addInstruction(instruction); + return instruction.createLink(scene); + } + + public void hideSection(Selection selection, Direction fadeOutDirection) { + WorldSectionElement worldSectionElement = new WorldSectionElement(selection); + ElementLink elementLink = new ElementLink<>(WorldSectionElement.class); + + addInstruction(scene -> { + scene.getBaseWorldSection() + .erase(selection); + scene.linkElement(worldSectionElement, elementLink); + scene.addElement(worldSectionElement); + worldSectionElement.queueRedraw(); + }); + + hideIndependentSection(elementLink, fadeOutDirection); + } + + public void hideIndependentSection(ElementLink link, Direction fadeOutDirection) { + addInstruction(new FadeOutOfSceneInstruction<>(15, fadeOutDirection, link)); + } + + public ElementLink makeSectionIndependent(Selection selection) { + WorldSectionElement worldSectionElement = new WorldSectionElement(selection); + ElementLink elementLink = new ElementLink<>(WorldSectionElement.class); + + addInstruction(scene -> { + scene.getBaseWorldSection() + .erase(selection); + scene.linkElement(worldSectionElement, elementLink); + scene.addElement(worldSectionElement); + worldSectionElement.queueRedraw(); + worldSectionElement.resetAnimatedTransform(); + worldSectionElement.setVisible(true); + worldSectionElement.forceApplyFade(1); + }); + + return elementLink; + } + + public void rotateSection(ElementLink link, double xRotation, double yRotation, + double zRotation, int duration) { + addInstruction( + AnimateWorldSectionInstruction.rotate(link, new Vec3d(xRotation, yRotation, zRotation), duration)); + } + + public void configureCenterOfRotation(ElementLink link, Vec3d anchor) { + addInstruction(scene -> scene.resolve(link) + .setCenterOfRotation(anchor)); + } + + public void moveSection(ElementLink link, Vec3d offset, int duration) { + addInstruction(AnimateWorldSectionInstruction.move(link, offset, duration)); + } + + public void rotateBearing(BlockPos pos, float angle, int duration) { + addInstruction(AnimateTileEntityInstruction.bearing(pos, angle, duration)); + } + + public void movePulley(BlockPos pos, float distance, int duration) { + addInstruction(AnimateTileEntityInstruction.pulley(pos, distance, duration)); + } + + public void setBlocks(Selection selection, BlockState state, boolean spawnParticles) { + addInstruction(new ReplaceBlocksInstruction(selection, $ -> state, true, spawnParticles)); + } + + public void destroyBlock(BlockPos pos) { + setBlock(pos, Blocks.AIR.getDefaultState(), true); + } + + public void setBlock(BlockPos pos, BlockState state, boolean spawnParticles) { + setBlocks(scene.getSceneBuildingUtil().select.position(pos), state, spawnParticles); + } + + public void replaceBlocks(Selection selection, BlockState state, boolean spawnParticles) { + modifyBlocks(selection, $ -> state, spawnParticles); + } + + public void modifyBlock(BlockPos pos, UnaryOperator stateFunc, boolean spawnParticles) { + modifyBlocks(scene.getSceneBuildingUtil().select.position(pos), stateFunc, spawnParticles); + } + + public void modifyBlocks(Selection selection, UnaryOperator stateFunc, boolean spawnParticles) { + addInstruction(new ReplaceBlocksInstruction(selection, stateFunc, false, spawnParticles)); + } + + public void toggleRedstonePower(Selection selection) { + modifyBlocks(selection, s -> { + if (s.has(BlockStateProperties.POWER_0_15)) + s = s.with(BlockStateProperties.POWER_0_15, s.get(BlockStateProperties.POWER_0_15) == 0 ? 15 : 0); + if (s.has(BlockStateProperties.POWERED)) + s = s.cycle(BlockStateProperties.POWERED); + return s; + }, false); + } + + public void modifyEntities(Class entityClass, Consumer entityCallBack) { + addInstruction(scene -> scene.forEachWorldEntity(entityClass, entityCallBack)); + } + + public void modifyEntitiesInside(Class entityClass, Selection area, + Consumer entityCallBack) { + addInstruction(scene -> scene.forEachWorldEntity(entityClass, e -> { + if (area.test(e.getPosition())) + entityCallBack.accept(e); + })); + } + + public void modifyEntity(ElementLink link, Consumer entityCallBack) { + addInstruction(scene -> { + EntityElement resolve = scene.resolve(link); + if (resolve != null) + resolve.ifPresent(entityCallBack::accept); + }); + } + + public ElementLink createEntity(Function factory) { + ElementLink link = new ElementLink<>(EntityElement.class, UUID.randomUUID()); + addInstruction(scene -> { + PonderWorld world = scene.getWorld(); + Entity entity = factory.apply(world); + EntityElement handle = new EntityElement(entity); + scene.addElement(handle); + scene.linkElement(handle, link); + world.addEntity(entity); + }); + return link; + } + + public ElementLink createItemEntity(Vec3d location, Vec3d motion, ItemStack stack) { + return createEntity(world -> { + ItemEntity itemEntity = new ItemEntity(world, location.x, location.y, location.z, stack); + itemEntity.setMotion(motion); + return itemEntity; + }); + } + + public void createItemOnBeltLike(BlockPos location, Direction insertionSide, ItemStack stack) { + addInstruction(scene -> { + PonderWorld world = scene.getWorld(); + TileEntity tileEntity = world.getTileEntity(location); + if (!(tileEntity instanceof SmartTileEntity)) + return; + SmartTileEntity beltTileEntity = (SmartTileEntity) tileEntity; + DirectBeltInputBehaviour behaviour = beltTileEntity.getBehaviour(DirectBeltInputBehaviour.TYPE); + if (behaviour == null) + return; + behaviour.handleInsertion(stack, insertionSide.getOpposite(), false); + }); + flapFunnels(scene.getSceneBuildingUtil().select.position(location.up()), true); + } + + public ElementLink createItemOnBelt(BlockPos beltLocation, Direction insertionSide, + ItemStack stack) { + ElementLink link = new ElementLink<>(BeltItemElement.class); + addInstruction(scene -> { + PonderWorld world = scene.getWorld(); + TileEntity tileEntity = world.getTileEntity(beltLocation); + if (!(tileEntity instanceof BeltTileEntity)) + return; + + BeltTileEntity beltTileEntity = (BeltTileEntity) tileEntity; + DirectBeltInputBehaviour behaviour = beltTileEntity.getBehaviour(DirectBeltInputBehaviour.TYPE); + behaviour.handleInsertion(stack, insertionSide.getOpposite(), false); + + BeltTileEntity controllerTE = beltTileEntity.getControllerTE(); + if (controllerTE != null) + controllerTE.tick(); + + TransportedItemStackHandlerBehaviour transporter = + beltTileEntity.getBehaviour(TransportedItemStackHandlerBehaviour.TYPE); + transporter.handleProcessingOnAllItems(tis -> { + BeltItemElement tracker = new BeltItemElement(tis); + scene.addElement(tracker); + scene.linkElement(tracker, link); + return TransportedResult.doNothing(); + }); + + }); + flapFunnels(scene.getSceneBuildingUtil().select.position(beltLocation.up()), true); + return link; + } + + public void removeItemsFromBelt(BlockPos beltLocation) { + addInstruction(scene -> { + PonderWorld world = scene.getWorld(); + TileEntity tileEntity = world.getTileEntity(beltLocation); + if (!(tileEntity instanceof BeltTileEntity)) + return; + BeltTileEntity beltTileEntity = (BeltTileEntity) tileEntity; + TransportedItemStackHandlerBehaviour transporter = + beltTileEntity.getBehaviour(TransportedItemStackHandlerBehaviour.TYPE); + transporter.handleProcessingOnAllItems(tis -> TransportedResult.removeItem()); + }); + } + + public void stallBeltItem(ElementLink link, boolean stalled) { + addInstruction(scene -> { + BeltItemElement resolve = scene.resolve(link); + if (resolve != null) + resolve.ifPresent(tis -> tis.locked = stalled); + }); + } + + public void changeBeltItemTo(ElementLink link, ItemStack newStack) { + addInstruction(scene -> { + BeltItemElement resolve = scene.resolve(link); + if (resolve != null) + resolve.ifPresent(tis -> tis.stack = newStack); + }); + } + + public void setKineticSpeed(Selection selection, float speed) { + modifyKineticSpeed(selection, f -> speed); + } + + public void multiplyKineticSpeed(Selection selection, float modifier) { + modifyKineticSpeed(selection, f -> f * modifier); + } + + public void modifyKineticSpeed(Selection selection, UnaryOperator speedFunc) { + modifyTileNBT(selection, SpeedGaugeTileEntity.class, nbt -> { + float newSpeed = speedFunc.apply(nbt.getFloat("Speed")); + nbt.putFloat("Value", SpeedGaugeTileEntity.getDialTarget(newSpeed)); + }); + modifyTileNBT(selection, KineticTileEntity.class, nbt -> { + nbt.putFloat("Speed", speedFunc.apply(nbt.getFloat("Speed"))); + }); + } + + public void setFilterData(Selection selection, Class teType, ItemStack filter) { + modifyTileNBT(selection, teType, nbt -> { + nbt.put("Filter", filter.serializeNBT()); + }); + } + + public void modifyTileNBT(Selection selection, Class teType, + Consumer consumer) { + modifyTileNBT(selection, teType, consumer, false); + } + + public void modifyTileNBT(Selection selection, Class teType, + Consumer consumer, boolean reDrawBlocks) { + addInstruction(new TileEntityDataInstruction(selection, teType, nbt -> { + consumer.accept(nbt); + return nbt; + }, reDrawBlocks)); + } + + public void flapFunnels(Selection selection, boolean outward) { + addInstruction(new TileEntityDataInstruction(selection, FunnelTileEntity.class, nbt -> { + nbt.putInt("Flap", outward ? -1 : 1); + return nbt; + }, false)); + } + + } + + public class DebugInstructions { + + public void debugSchematic() { + addInstruction( + scene -> scene.addElement(new WorldSectionElement(scene.getSceneBuildingUtil().select.everywhere()))); + } + + public void addInstructionInstance(PonderInstruction instruction) { + addInstruction(instruction); + } + + public void enqueueCallback(Consumer callback) { + addInstruction(callback); + } + + } + + private void addInstruction(PonderInstruction instruction) { + scene.schedule.add(instruction); + } + + private void addInstruction(Consumer callback) { + scene.schedule.add(PonderInstruction.simple(callback)); + } + +} \ No newline at end of file diff --git a/src/main/java/com/simibubi/create/foundation/ponder/SceneBuildingUtil.java b/src/main/java/com/simibubi/create/foundation/ponder/SceneBuildingUtil.java new file mode 100644 index 000000000..58e7ebd0e --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/SceneBuildingUtil.java @@ -0,0 +1,118 @@ +package com.simibubi.create.foundation.ponder; + +import com.simibubi.create.foundation.utility.VecHelper; + +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MutableBoundingBox; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.Vec3i; + +/** + * Helpful shortcuts for marking boundaries, points or sections inside the scene + */ +public class SceneBuildingUtil { + + public final SelectionUtil select; + public final VectorUtil vector; + public final PositionUtil grid; + + private final MutableBoundingBox sceneBounds; + + SceneBuildingUtil(MutableBoundingBox sceneBounds) { + this.sceneBounds = sceneBounds; + this.select = new SelectionUtil(); + this.vector = new VectorUtil(); + this.grid = new PositionUtil(); + } + + public class PositionUtil { + + public BlockPos at(int x, int y, int z) { + return new BlockPos(x, y, z); + } + + public BlockPos zero() { + return at(0, 0, 0); + } + + } + + public class VectorUtil { + + public Vec3d centerOf(int x, int y, int z) { + return centerOf(grid.at(x, y, z)); + } + + public Vec3d centerOf(BlockPos pos) { + return VecHelper.getCenterOf(pos); + } + + public Vec3d topOf(int x, int y, int z) { + return blockSurface(grid.at(x, y, z), Direction.UP); + } + + public Vec3d topOf(BlockPos pos) { + return blockSurface(pos, Direction.UP); + } + + public Vec3d blockSurface(BlockPos pos, Direction face) { + return blockSurface(pos, face, 0); + } + + public Vec3d blockSurface(BlockPos pos, Direction face, float margin) { + return centerOf(pos).add(new Vec3d(face.getDirectionVec()).scale(.5f + margin)); + } + + public Vec3d of(double x, double y, double z) { + return new Vec3d(x, y, z); + } + + } + + public class SelectionUtil { + + public Selection everywhere() { + return Selection.of(sceneBounds); + } + + public Selection position(int x, int y, int z) { + return position(grid.at(x, y, z)); + } + + public Selection position(BlockPos pos) { + return cuboid(pos, BlockPos.ZERO); + } + + public Selection fromTo(int x, int y, int z, int x2, int y2, int z2) { + return fromTo(new BlockPos(x, y, z), new BlockPos(x2, y2, z2)); + } + + public Selection fromTo(BlockPos pos1, BlockPos pos2) { + return cuboid(pos1, pos2.subtract(pos1)); + } + + public Selection column(int x, int z) { + return cuboid(new BlockPos(x, 1, z), new Vec3i(0, sceneBounds.getYSize(), 0)); + } + + public Selection layer(int y) { + return layers(y, 1); + } + + public Selection layersFrom(int y) { + return layers(y, sceneBounds.getYSize() - y); + } + + public Selection layers(int y, int height) { + return cuboid(new BlockPos(0, y, 0), new Vec3i(sceneBounds.getXSize(), + Math.min(sceneBounds.getYSize() - y, height) - 1, sceneBounds.getZSize())); + } + + public Selection cuboid(BlockPos origin, Vec3i size) { + return Selection.of(new MutableBoundingBox(origin, origin.add(size))); + } + + } + +} \ No newline at end of file diff --git a/src/main/java/com/simibubi/create/foundation/ponder/Selection.java b/src/main/java/com/simibubi/create/foundation/ponder/Selection.java new file mode 100644 index 000000000..589a9834f --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/Selection.java @@ -0,0 +1,155 @@ +package com.simibubi.create.foundation.ponder; + +import java.util.HashSet; +import java.util.Set; +import java.util.function.Consumer; +import java.util.function.Predicate; + +import com.simibubi.create.foundation.utility.outliner.Outline.OutlineParams; +import com.simibubi.create.foundation.utility.outliner.Outliner; + +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MutableBoundingBox; +import net.minecraft.util.math.Vec3d; + +public abstract class Selection implements Predicate { + + public static Selection of(MutableBoundingBox bb) { + return new Simple(bb); + } + + public abstract Selection add(Selection other); + + public abstract Selection substract(Selection other); + + public abstract Selection copy(); + + public abstract Vec3d getCenter(); + + public abstract void forEach(Consumer callback); + + public abstract OutlineParams makeOutline(Outliner outliner, Object slot); + + public OutlineParams makeOutline(Outliner outliner) { + return makeOutline(outliner, this); + } + + private static class Compound extends Selection { + + Set posSet; + Vec3d center; + + public Compound(Simple initial) { + posSet = new HashSet<>(); + add(initial); + } + + private Compound(Set template) { + posSet = new HashSet<>(template); + } + + @Override + public boolean test(BlockPos t) { + return posSet.contains(t); + } + + @Override + public Selection add(Selection other) { + other.forEach(p -> posSet.add(p.toImmutable())); + center = null; + return this; + } + + @Override + public Selection substract(Selection other) { + other.forEach(p -> posSet.remove(p.toImmutable())); + center = null; + return this; + } + + @Override + public void forEach(Consumer callback) { + posSet.forEach(callback); + } + + @Override + public OutlineParams makeOutline(Outliner outliner, Object slot) { + return outliner.showCluster(slot, posSet); + } + + @Override + public Vec3d getCenter() { + return center == null ? center = evalCenter() : center; + } + + private Vec3d evalCenter() { + Vec3d center = Vec3d.ZERO; + if (posSet.isEmpty()) + return center; + for (BlockPos blockPos : posSet) + center = center.add(new Vec3d(blockPos)); + center = center.scale(1f / posSet.size()); + return center.add(new Vec3d(.5, .5, .5)); + } + + @Override + public Selection copy() { + return new Compound(posSet); + } + + } + + private static class Simple extends Selection { + + private MutableBoundingBox bb; + private AxisAlignedBB aabb; + + public Simple(MutableBoundingBox bb) { + this.bb = bb; + this.aabb = getAABB(); + } + + @Override + public boolean test(BlockPos t) { + return bb.isVecInside(t); + } + + @Override + public Selection add(Selection other) { + return new Compound(this).add(other); + } + + @Override + public Selection substract(Selection other) { + return new Compound(this).substract(other); + } + + @Override + public void forEach(Consumer callback) { + BlockPos.func_229383_a_(bb) + .forEach(callback); + } + + @Override + public Vec3d getCenter() { + return aabb.getCenter(); + } + + @Override + public OutlineParams makeOutline(Outliner outliner, Object slot) { + return outliner.showAABB(slot, aabb); + } + + private AxisAlignedBB getAABB() { + return new AxisAlignedBB(bb.minX, bb.minY, bb.minZ, bb.maxX + 1, bb.maxY + 1, bb.maxZ + 1); + } + + @Override + public Selection copy() { + return new Simple(new MutableBoundingBox(bb)); + } + + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/BeltScenes.java b/src/main/java/com/simibubi/create/foundation/ponder/content/BeltScenes.java new file mode 100644 index 000000000..09c5ff47b --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/BeltScenes.java @@ -0,0 +1,459 @@ +package com.simibubi.create.foundation.ponder.content; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllItems; +import com.simibubi.create.content.contraptions.relays.belt.BeltBlock; +import com.simibubi.create.content.contraptions.relays.belt.BeltPart; +import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity; +import com.simibubi.create.content.contraptions.relays.elementary.ShaftBlock; +import com.simibubi.create.foundation.ponder.ElementLink; +import com.simibubi.create.foundation.ponder.SceneBuilder; +import com.simibubi.create.foundation.ponder.SceneBuildingUtil; +import com.simibubi.create.foundation.ponder.Selection; +import com.simibubi.create.foundation.ponder.elements.EntityElement; +import com.simibubi.create.foundation.ponder.elements.InputWindowElement; +import com.simibubi.create.foundation.ponder.elements.ParrotElement; +import com.simibubi.create.foundation.ponder.elements.WorldSectionElement; +import com.simibubi.create.foundation.utility.NBTHelper; +import com.simibubi.create.foundation.utility.Pointing; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.item.ItemEntity; +import net.minecraft.item.DyeColor; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.util.Direction; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; + +public class BeltScenes { + + public static void beltConnector(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("belt_connector", "Using Mechanical Belts"); + scene.configureBasePlate(0, 0, 5); + scene.showBasePlate(); + scene.idle(5); + + scene.world.showSection(util.select.fromTo(4, 1, 3, 4, 1, 5), Direction.DOWN); + ElementLink shafts = + scene.world.showIndependentSection(util.select.fromTo(0, 1, 3, 4, 1, 3), Direction.DOWN); + scene.world.moveSection(shafts, util.vector.of(0, 0, -1), 0); + scene.world.setKineticSpeed(util.select.position(0, 1, 3), 0); + scene.idle(20); + + BlockPos backEnd = util.grid.at(4, 1, 2); + BlockPos frontEnd = util.grid.at(0, 1, 2); + ItemStack beltItem = AllItems.BELT_CONNECTOR.asStack(); + Vec3d backEndCenter = util.vector.centerOf(backEnd); + AxisAlignedBB connectBB = new AxisAlignedBB(backEndCenter, backEndCenter); + AxisAlignedBB shaftBB = AllBlocks.SHAFT.getDefaultState() + .with(ShaftBlock.AXIS, Axis.Z) + .getShape(null, null) + .getBoundingBox(); + + scene.overlay.showControls(new InputWindowElement(util.vector.topOf(backEnd), Pointing.DOWN).rightClick() + .withItem(beltItem), 57); + scene.idle(7); + + scene.overlay.chaseBoundingBoxOutline(PonderPalette.GREEN, backEnd, shaftBB.offset(backEnd), 42); + scene.overlay.chaseBoundingBoxOutline(PonderPalette.BLACK, backEndCenter, connectBB, 50); + scene.idle(20); + + scene.overlay.showControls(new InputWindowElement(util.vector.topOf(frontEnd), Pointing.DOWN).rightClick() + .withItem(beltItem), 37); + scene.idle(7); + + scene.overlay.chaseBoundingBoxOutline(PonderPalette.GREEN, frontEnd, shaftBB.offset(frontEnd), 17); + scene.overlay.chaseBoundingBoxOutline(PonderPalette.BLACK, backEndCenter, connectBB.expand(-4, 0, 0), 20); + scene.idle(20); + + scene.world.moveSection(shafts, util.vector.of(0, -2, 0), 0); + scene.world.showSection(util.select.fromTo(0, 1, 2, 4, 1, 2), Direction.SOUTH); + scene.idle(20); + + scene.overlay.showText(80) + .text("Right-Clicking two shafts with a belt item will connect them together") + .placeNearTarget() + .pointAt(util.vector.topOf(2, 1, 2)); + scene.idle(90); + + Vec3d falseSelection = util.vector.topOf(backEnd.south(1)); + scene.overlay.showControls(new InputWindowElement(falseSelection, Pointing.DOWN).rightClick() + .withItem(beltItem), 37); + scene.idle(7); + scene.overlay.chaseBoundingBoxOutline(PonderPalette.RED, backEnd, shaftBB.offset(backEnd.south(1)), 50); + + scene.overlay.showText(80) + .colored(PonderPalette.RED) + .text("Accidental selections can be canceled with Right-Click while Sneaking") + .placeNearTarget() + .pointAt(util.vector.centerOf(backEnd.south(1))); + scene.idle(43); + + scene.overlay.showControls(new InputWindowElement(falseSelection, Pointing.DOWN).rightClick() + .withItem(beltItem) + .whileSneaking(), 20); + scene.idle(60); + + BlockPos shaftLocation = frontEnd.east(); + scene.overlay.showControls(new InputWindowElement(util.vector.topOf(shaftLocation), Pointing.DOWN).rightClick() + .withItem(AllBlocks.SHAFT.asStack()), 50); + scene.idle(7); + scene.world.modifyBlock(shaftLocation, s -> s.with(BeltBlock.PART, BeltPart.PULLEY), true); + scene.idle(10); + + scene.overlay.showText(43) + .text("Additional Shafts can be added throughout the Belt") + .placeNearTarget() + .pointAt(util.vector.blockSurface(shaftLocation, Direction.NORTH)); + scene.idle(50); + + Selection attachedShafts = util.select.fromTo(0, 1, 1, 1, 1, 1); + scene.world.showSection(attachedShafts, Direction.SOUTH); + scene.world.setKineticSpeed(attachedShafts, 32); + scene.idle(10); + scene.effects.rotationDirectionIndicator(util.grid.at(0, 1, 1)); + scene.effects.rotationDirectionIndicator(util.grid.at(1, 1, 1)); + scene.idle(20); + + scene.overlay.showText(50) + .text("Shafts connected via Belts will rotate with Identical Speed and Direction") + .placeNearTarget() + .pointAt(util.vector.blockSurface(util.grid.at(0, 1, 1), Direction.NORTH)); + scene.idle(60); + + scene.world.hideSection(attachedShafts, Direction.NORTH); + scene.idle(20); + + scene.overlay.showControls(new InputWindowElement(util.vector.topOf(shaftLocation), Pointing.DOWN).rightClick() + .withWrench(), 50); + scene.idle(7); + scene.world.modifyBlock(shaftLocation, s -> s.with(BeltBlock.PART, BeltPart.MIDDLE), true); + scene.idle(10); + scene.overlay.showText(50) + .text("Added shafts can be removed using the wrench") + .placeNearTarget() + .pointAt(util.vector.blockSurface(shaftLocation, Direction.NORTH)); + scene.idle(70); + + scene.overlay + .showControls(new InputWindowElement(util.vector.topOf(shaftLocation.east()), Pointing.DOWN).rightClick() + .withItem(new ItemStack(Items.BLUE_DYE)), 50); + scene.idle(7); + scene.world.modifyTileNBT(util.select.fromTo(0, 1, 2, 4, 1, 2), BeltTileEntity.class, + nbt -> NBTHelper.writeEnum(nbt, "Dye", DyeColor.BLUE)); + scene.idle(20); + scene.overlay.showText(80) + .colored(PonderPalette.BLUE) + .text("Mechanical Belts can be dyed for aesthetic purposes") + .placeNearTarget() + .pointAt(util.vector.topOf(shaftLocation.east())); + } + + public static void directions(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("belt_directions", "Valid Orientations for Mechanical Belts"); + scene.configureBasePlate(0, 0, 5); + scene.showBasePlate(); + scene.idle(5); + + ElementLink leftShaft = + scene.world.showIndependentSection(util.select.position(4, 1, 0), Direction.DOWN); + ElementLink rightShaft = + scene.world.showIndependentSection(util.select.position(0, 1, 0), Direction.DOWN); + + scene.world.moveSection(leftShaft, util.vector.of(0, 0, 2), 0); + scene.world.moveSection(rightShaft, util.vector.of(0, 0, 2), 0); + scene.idle(1); + scene.world.moveSection(leftShaft, util.vector.of(-1, 0, 0), 10); + scene.world.moveSection(rightShaft, util.vector.of(1, 1, 0), 10); + + scene.idle(20); + + Vec3d from = util.vector.centerOf(3, 1, 2); + Vec3d to = util.vector.centerOf(1, 2, 2); + + scene.overlay.showLine(PonderPalette.RED, from, to, 70); + scene.idle(10); + scene.overlay.showLine(PonderPalette.GREEN, to.add(-1, -1, 0), from, 60); + scene.overlay.showLine(PonderPalette.GREEN, from.add(0, 3, 0), from, 60); + + scene.idle(20); + scene.overlay.showText(60) + .colored(PonderPalette.RED) + .placeNearTarget() + .pointAt(to) + .text("Belts cannot connect in arbitrary directions"); + scene.idle(70); + + from = util.vector.centerOf(4, 1, 2); + to = util.vector.centerOf(0, 1, 2); + + scene.world.moveSection(leftShaft, util.vector.of(1, 0, 0), 10); + scene.world.moveSection(rightShaft, util.vector.of(-1, -1, 0), 10); + scene.idle(10); + scene.overlay.showLine(PonderPalette.GREEN, from, to, 40); + scene.idle(10); + scene.overlay.showText(40) + .colored(PonderPalette.GREEN) + .placeNearTarget() + .pointAt(to) + .text("1. They can connect horizontally"); + + scene.idle(20); + Selection firstBelt = util.select.fromTo(4, 1, 1, 0, 1, 1); + ElementLink belt = scene.world.showIndependentSection(firstBelt, Direction.SOUTH); + scene.world.moveSection(belt, util.vector.of(0, 0, 1), 0); + scene.idle(20); + scene.world.hideIndependentSection(belt, Direction.SOUTH); + scene.idle(15); + + from = util.vector.centerOf(3, 3, 2); + to = util.vector.centerOf(1, 1, 2); + + scene.world.moveSection(leftShaft, util.vector.of(-1, 2, 0), 10); + scene.world.moveSection(rightShaft, util.vector.of(1, 0, 0), 10); + scene.idle(10); + scene.world.rotateSection(leftShaft, 0, 0, 25, 5); + scene.world.rotateSection(rightShaft, 0, 0, 25, 5); + scene.overlay.showLine(PonderPalette.GREEN, from, to, 40); + scene.idle(10); + scene.overlay.showText(40) + .colored(PonderPalette.GREEN) + .placeNearTarget() + .pointAt(to) + .text("2. They can connect diagonally"); + + scene.idle(20); + Selection secondBelt = util.select.fromTo(3, 3, 2, 1, 1, 2); + belt = scene.world.showIndependentSection(secondBelt, Direction.SOUTH); + scene.idle(20); + scene.world.hideIndependentSection(belt, Direction.SOUTH); + scene.idle(15); + + from = util.vector.centerOf(2, 4, 2); + to = util.vector.centerOf(2, 1, 2); + + scene.world.moveSection(leftShaft, util.vector.of(-1, 1, 0), 10); + scene.world.moveSection(rightShaft, util.vector.of(1, 0, 0), 10); + scene.idle(10); + scene.world.rotateSection(rightShaft, 0, 0, -25, 5); + scene.overlay.showLine(PonderPalette.GREEN, from, to, 40); + scene.idle(10); + scene.overlay.showText(40) + .colored(PonderPalette.GREEN) + .placeNearTarget() + .pointAt(to) + .text("3. They can connect vertically"); + + scene.idle(20); + Selection thirdBelt = util.select.fromTo(2, 1, 3, 2, 4, 3); + belt = scene.world.showIndependentSection(thirdBelt, Direction.SOUTH); + scene.world.moveSection(belt, util.vector.of(0, 0, -1), 0); + scene.idle(20); + scene.world.hideIndependentSection(belt, Direction.SOUTH); + scene.idle(15); + + from = util.vector.centerOf(4, 1, 2); + to = util.vector.centerOf(0, 1, 2); + + scene.world.moveSection(leftShaft, util.vector.of(2, -3, 0), 10); + scene.world.moveSection(rightShaft, util.vector.of(-2, 0, 0), 10); + scene.idle(10); + scene.world.rotateSection(rightShaft, 90, 0, -25, 5); + scene.world.rotateSection(leftShaft, 90, 0, -50, 5); + scene.overlay.showLine(PonderPalette.GREEN, from, to, 60); + scene.idle(10); + scene.overlay.showText(60) + .colored(PonderPalette.GREEN) + .placeNearTarget() + .pointAt(to) + .text("4. And they can connect vertical shafts horizontally"); + + scene.idle(20); + Selection fourthBelt = util.select.fromTo(4, 1, 4, 0, 1, 4); + belt = scene.world.showIndependentSection(fourthBelt, Direction.DOWN); + scene.world.moveSection(belt, util.vector.of(0, 1 / 512f, -2), 0); + scene.idle(40); + scene.world.hideIndependentSection(belt, Direction.UP); + scene.idle(15); + scene.world.hideIndependentSection(leftShaft, Direction.UP); + scene.world.hideIndependentSection(rightShaft, Direction.UP); + scene.idle(15); + + scene.world.showSection(firstBelt, Direction.DOWN); + scene.idle(5); + scene.world.showSection(secondBelt, Direction.DOWN); + scene.idle(5); + scene.world.showSection(thirdBelt, Direction.DOWN); + scene.idle(5); + scene.world.showSection(fourthBelt, Direction.DOWN); + scene.idle(10); + + scene.overlay.showText(160) + .text("These are all possible directions.\nBelts can span any Length between 2 and 20 blocks"); + scene.markAsFinished(); + } + + public static void transport(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("belt_transport", "Using Mechanical Belts for Logistics"); + scene.configureBasePlate(0, 0, 5); + scene.world.modifyKineticSpeed(util.select.everywhere(), f -> -.6f * f); + scene.showBasePlate(); + scene.idle(5); + scene.world.showSection(util.select.fromTo(1, 1, 3, 2, 1, 5), Direction.DOWN); + scene.idle(20); + scene.world.showSection(util.select.fromTo(2, 1, 2, 4, 3, 2), Direction.SOUTH); + scene.idle(5); + scene.world.showSection(util.select.fromTo(1, 1, 2, 0, 1, 2), Direction.SOUTH); + scene.idle(10); + scene.special.movePointOfInterest(util.grid.at(2, 2, 0)); + + ItemStack stack = AllBlocks.COPPER_BLOCK.asStack(); + ElementLink item = + scene.world.createItemEntity(util.vector.centerOf(0, 4, 2), util.vector.of(0, 0, 0), stack); + scene.idle(13); + scene.world.modifyEntity(item, Entity::remove); + BlockPos beltEnd = util.grid.at(0, 1, 2); + scene.world.createItemOnBelt(beltEnd, Direction.DOWN, stack); + + scene.idle(20); + + ElementLink parrot = scene.special.birbLookingAtPOI(util.vector.topOf(0, 1, 2) + .add(0, -3 / 16f, 0)); + scene.special.moveParrot(parrot, util.vector.of(1.78, 0, 0), 40); + scene.special.movePointOfInterest(util.grid.at(1, 1, 3)); + + scene.overlay.showText(60) + .placeNearTarget() + .pointAt(util.vector.topOf(beltEnd)) + .text("Moving belts will transport Items and other Entities"); + + scene.idle(20); + item = scene.world.createItemEntity(util.vector.centerOf(0, 4, 2), util.vector.of(0, 0, 0), stack); + scene.special.movePointOfInterest(util.grid.at(0, 3, 2)); + scene.idle(10); + scene.special.movePointOfInterest(beltEnd); + scene.idle(3); + scene.world.modifyEntity(item, Entity::remove); + scene.world.createItemOnBelt(beltEnd, Direction.DOWN, stack); + scene.idle(8); + + scene.special.movePointOfInterest(util.grid.at(3, 2, 1)); + scene.special.moveParrot(parrot, util.vector.of(2.1, 2.1, 0), 60); + scene.idle(20); + scene.special.movePointOfInterest(util.grid.at(5, 5, 2)); + scene.idle(30); + scene.special.movePointOfInterest(util.grid.at(2, 1, 5)); + scene.idle(10); + scene.special.moveParrot(parrot, util.vector.of(.23, 0, 0), 5); + scene.idle(5); + scene.world.setKineticSpeed(util.select.everywhere(), 0f); + scene.idle(10); + scene.world.modifyEntities(ItemEntity.class, Entity::remove); + scene.special.movePointOfInterest(util.grid.at(2, 5, 4)); + + Vec3d topOf = util.vector.topOf(util.grid.at(3, 2, 2)) + .add(-0.1, 0.3, 0); + scene.overlay.showControls(new InputWindowElement(topOf, Pointing.DOWN).rightClick(), 60); + scene.idle(10); + scene.overlay.showText(60) + .placeNearTarget() + .pointAt(topOf.subtract(0, 0.1, 0)) + .text("Right-Click with an empty hand to take items off a belt"); + scene.idle(20); + scene.world.removeItemsFromBelt(util.grid.at(3, 2, 2)); + scene.effects.indicateSuccess(util.grid.at(3, 2, 2)); + scene.idle(20); + + scene.special.movePointOfInterest(util.grid.at(2, 1, 5)); + } + + public static void beltsCanBeEncased(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("belt_casing", "Encasing Belts"); + scene.configureBasePlate(0, 0, 5); + scene.showBasePlate(); + scene.idle(5); + scene.world.showSection(util.select.layersFrom(1), Direction.DOWN); + scene.idle(20); + + ItemStack brassCasingItem = AllBlocks.BRASS_CASING.asStack(); + ItemStack andesiteCasingItem = AllBlocks.ANDESITE_CASING.asStack(); + + BlockPos beltPos = util.grid.at(3, 1, 0); + BlockPos beltPos2 = util.grid.at(0, 2, 3); + BlockPos beltPos3 = util.grid.at(1, 4, 4); + + scene.overlay.showControls(new InputWindowElement(util.vector.topOf(beltPos), Pointing.DOWN).rightClick() + .withItem(brassCasingItem), 20); + scene.idle(7); + scene.world.modifyBlock(beltPos, s -> s.with(BeltBlock.CASING, true), true); + scene.idle(20); + + scene.overlay.showControls(new InputWindowElement(util.vector.topOf(beltPos2), Pointing.DOWN).rightClick() + .withItem(andesiteCasingItem), 20); + scene.idle(7); + scene.world.modifyBlock(beltPos2, s -> s.with(BeltBlock.CASING, true), true); + scene.world.modifyTileNBT(util.select.position(beltPos2), BeltTileEntity.class, nbt -> { + NBTHelper.writeEnum(nbt, "Casing", BeltTileEntity.CasingType.ANDESITE); + }); + scene.idle(20); + + scene.overlay.showControls( + new InputWindowElement(util.vector.blockSurface(beltPos3, Direction.EAST), Pointing.RIGHT).rightClick() + .withItem(brassCasingItem), + 20); + scene.idle(7); + scene.world.modifyBlock(beltPos3, s -> s.with(BeltBlock.CASING, true), true); + scene.idle(20); + + scene.overlay.showText(80) + .text("Brass or Andesite Casing can be used to decorate Mechanical Belts") + .pointAt(util.vector.centerOf(beltPos2)); + + scene.idle(40); + + List brassBelts = new ArrayList<>(); + List andesiteBelts = new ArrayList<>(); + + for (int z = 1; z <= 3; z++) + brassBelts.add(beltPos.south(z)); + for (int x = 1; x <= 3; x++) + brassBelts.add(beltPos3.east(x) + .down(x)); + for (int x = 1; x <= 3; x++) + andesiteBelts.add(beltPos2.east(x)); + + Collections.shuffle(andesiteBelts); + Collections.shuffle(brassBelts); + + for (BlockPos pos : andesiteBelts) { + scene.idle(4); + scene.world.modifyBlock(pos, s -> s.with(BeltBlock.CASING, true), true); + scene.world.modifyTileNBT(util.select.position(pos), BeltTileEntity.class, nbt -> { + NBTHelper.writeEnum(nbt, "Casing", BeltTileEntity.CasingType.ANDESITE); + }); + } + for (BlockPos pos : brassBelts) { + scene.idle(4); + scene.world.modifyBlock(pos, s -> s.with(BeltBlock.CASING, true), true); + } + scene.idle(30); + + scene.overlay + .showControls(new InputWindowElement(util.vector.topOf(beltPos.south()), Pointing.DOWN).rightClick() + .withWrench(), 40); + scene.idle(7); + scene.world.modifyBlock(beltPos.south(), s -> s.with(BeltBlock.CASING, false), true); + scene.overlay.showText(80) + .text("A wrench can be used to remove the casing") + .placeNearTarget() + .pointAt(util.vector.blockSurface(beltPos.south(), Direction.WEST)); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/ChainDriveScenes.java b/src/main/java/com/simibubi/create/foundation/ponder/content/ChainDriveScenes.java new file mode 100644 index 000000000..841646d57 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/ChainDriveScenes.java @@ -0,0 +1,259 @@ +package com.simibubi.create.foundation.ponder.content; + +import com.simibubi.create.content.contraptions.relays.encased.EncasedBeltBlock; +import com.simibubi.create.content.logistics.block.redstone.AnalogLeverTileEntity; +import com.simibubi.create.foundation.ponder.ElementLink; +import com.simibubi.create.foundation.ponder.SceneBuilder; +import com.simibubi.create.foundation.ponder.SceneBuildingUtil; +import com.simibubi.create.foundation.ponder.Selection; +import com.simibubi.create.foundation.ponder.elements.InputWindowElement; +import com.simibubi.create.foundation.ponder.elements.TextWindowElement.Builder; +import com.simibubi.create.foundation.ponder.elements.WorldSectionElement; +import com.simibubi.create.foundation.utility.Pointing; + +import net.minecraft.block.RedstoneWireBlock; +import net.minecraft.util.Direction; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; + +public class ChainDriveScenes { + + public static void chainDriveAsRelay(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("chain_drive", "Relaying rotational force with Chain Drives"); + scene.configureBasePlate(0, 0, 5); + scene.world.showSection(util.select.layer(0), Direction.UP); + BlockPos gaugePos = util.grid.at(0, 1, 3); + Selection gauge = util.select.position(gaugePos); + scene.world.showSection(gauge, Direction.UP); + scene.world.setKineticSpeed(gauge, 0); + + scene.idle(5); + scene.world.showSection(util.select.fromTo(5, 1, 2, 4, 1, 2), Direction.DOWN); + scene.idle(10); + + for (int i = 0; i < 3; i++) { + scene.idle(5); + scene.world.showSection(util.select.position(3, 1, 2 - i), Direction.DOWN); + if (i != 0) + scene.world.showSection(util.select.position(3, 1, 2 + i), Direction.DOWN); + } + + scene.idle(10); + scene.world.showSection(util.select.position(gaugePos.east(2)), Direction.DOWN); + scene.idle(5); + scene.world.showSection(util.select.position(gaugePos.east()), Direction.DOWN); + scene.idle(5); + + scene.world.setKineticSpeed(gauge, 64); + scene.effects.indicateSuccess(gaugePos); + scene.idle(20); + scene.overlay.showText(60) + .text("Chain Drives relay rotation to each other in a row") + .placeNearTarget() + .pointAt(util.vector.blockSurface(util.grid.at(3, 1, 4), Direction.WEST)); + scene.idle(60); + + Selection shafts = util.select.fromTo(2, 1, 0, 2, 1, 1); + BlockPos rotatedECD = util.grid.at(3, 1, 0); + Selection verticalShaft = util.select.fromTo(rotatedECD.up(), rotatedECD.up(2)); + + scene.world.showSection(shafts, Direction.EAST); + scene.idle(10); + scene.effects.rotationDirectionIndicator(util.grid.at(2, 1, 0)); + scene.effects.rotationDirectionIndicator(util.grid.at(2, 1, 1)); + scene.idle(20); + scene.overlay.showText(60) + .text("All shafts connected like this will rotate in the same direction") + .placeNearTarget() + .pointAt(util.vector.blockSurface(util.grid.at(2, 1, 1), Direction.WEST)); + scene.idle(50); + scene.world.hideSection(shafts, Direction.WEST); + scene.idle(25); + + scene.overlay.showControls(new InputWindowElement(util.vector.topOf(rotatedECD), Pointing.DOWN).rightClick() + .withWrench(), 30); + scene.idle(7); + scene.world.modifyBlock(rotatedECD, s -> s.with(EncasedBeltBlock.AXIS, Axis.Y), true); + scene.idle(40); + + scene.world.showSection(verticalShaft, Direction.DOWN); + scene.idle(10); + + scene.effects.rotationDirectionIndicator(util.grid.at(3, 3, 0)); + scene.idle(10); + scene.overlay.showText(60) + .text("Any part of the row can be rotated by 90 degrees") + .placeNearTarget() + .pointAt(util.vector.centerOf(3, 2, 0)); + + scene.markAsFinished(); + } + + public static void adjustableChainGearshift(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("chain_gearshift", "Controlling rotational speed with Chain Gearshifts"); + scene.configureBasePlate(0, 0, 7); + scene.world.showSection(util.select.layer(0), Direction.UP); + + BlockPos leverPos = util.grid.at(3, 1, 0); + BlockPos eastDrive = util.grid.at(3, 1, 2); + + BlockPos eastGauge = eastDrive.up(3); + BlockPos middleGauge = eastGauge.west() + .down(); + BlockPos westGauge = eastGauge.west(2) + .down(2); + + ElementLink lever = + scene.world.showIndependentSection(util.select.fromTo(leverPos, leverPos.south()), Direction.UP); + + scene.idle(5); + scene.world.showSection(util.select.fromTo(4, 1, 3, 4, 2, 3), Direction.DOWN); + scene.idle(10); + scene.world.showSection(util.select.fromTo(eastDrive, eastDrive.west(2)) + .add(util.select.position(eastDrive.up())), Direction.DOWN); + scene.idle(10); + + scene.overlay.showText(60) + .text("Unpowered Chain Gearshifts behave exacly like Chain Drives") + .placeNearTarget() + .pointAt(util.vector.blockSurface(eastDrive, Direction.NORTH)); + scene.idle(60); + + scene.world.showSection(util.select.fromTo(eastGauge, eastGauge.down()), Direction.DOWN); + scene.idle(5); + scene.world.showSection(util.select.fromTo(middleGauge, middleGauge.down()), Direction.DOWN); + scene.idle(5); + scene.world.showSection(util.select.position(westGauge), Direction.DOWN); + scene.idle(5); + + for (BlockPos gauge : new BlockPos[] { eastGauge, middleGauge, westGauge }) { + scene.idle(5); + scene.overlay.showText(50) + .sharedText(gauge == eastGauge ? "rpm16_source" : "rpm16") + .colored(PonderPalette.MEDIUM) + .placeNearTarget() + .pointAt(util.vector.blockSurface(gauge, Direction.NORTH)); + } + + scene.idle(60); + + scene.world.toggleRedstonePower(util.select.fromTo(leverPos, leverPos.south(2))); + scene.effects.indicateRedstone(leverPos); + scene.world.modifyKineticSpeed(util.select.fromTo(westGauge.down(), middleGauge), f -> 2 * f); + + scene.idle(10); + + AxisAlignedBB bb = new AxisAlignedBB(eastDrive); + scene.overlay.chaseBoundingBoxOutline(PonderPalette.MEDIUM, eastDrive, bb, 160); + scene.overlay.chaseBoundingBoxOutline(PonderPalette.FAST, eastDrive.west(), bb.offset(-2, 0, 0) + .expand(15 / 16f, 0, 0), 160); + scene.idle(20); + + scene.overlay.showText(80) + .text("When Powered, the speed transmitted to other Chain Drives in the row is doubled") + .placeNearTarget() + .colored(PonderPalette.FAST) + .pointAt(util.vector.blockSurface(eastDrive.west(2), Direction.WEST)); + scene.idle(80); + + for (BlockPos gauge : new BlockPos[] { eastGauge, middleGauge, westGauge }) { + scene.idle(5); + scene.overlay.showText(70) + .sharedText(gauge == eastGauge ? "rpm16_source" : "rpm32") + .colored(gauge == eastGauge ? PonderPalette.MEDIUM : PonderPalette.FAST) + .placeNearTarget() + .pointAt(util.vector.blockSurface(gauge, Direction.NORTH)); + } + + scene.idle(80); + + scene.world.hideSection(util.select.fromTo(eastDrive, eastDrive.west(2)), Direction.SOUTH); + scene.idle(15); + scene.world.toggleRedstonePower(util.select.fromTo(leverPos, leverPos.south(2))); + Selection newDriveSelect = util.select.fromTo(eastDrive.south(2), eastDrive.south(2) + .west(2)); + ElementLink drives = scene.world.showIndependentSection(newDriveSelect, Direction.NORTH); + scene.world.modifyKineticSpeed(util.select.fromTo(westGauge.down(), middleGauge), f -> .5f * f); + scene.world.setKineticSpeed(newDriveSelect, -32); + scene.world.moveSection(drives, util.vector.of(0, 0, -2), 0); + scene.world.moveSection(lever, util.vector.of(-2, 0, 0), 10); + + scene.idle(40); + + scene.world.toggleRedstonePower(util.select.fromTo(leverPos, leverPos.south(1))); + scene.world.toggleRedstonePower(util.select.position(1, 1, 4)); + BlockPos analogPos = leverPos.west(2); + scene.effects.indicateRedstone(analogPos); + scene.world.modifyKineticSpeed(util.select.position(westGauge), f -> .5f * f); + + scene.idle(10); + + bb = new AxisAlignedBB(eastDrive); + scene.overlay.chaseBoundingBoxOutline(PonderPalette.MEDIUM, eastDrive, bb.expand(-15 / 16f, 0, 0), 160); + scene.overlay.chaseBoundingBoxOutline(PonderPalette.SLOW, eastDrive.west(), bb.offset(-2, 0, 0), 160); + scene.idle(20); + + scene.overlay.showText(80) + .text("Whenever the Powered Gearshift is not at the source, its speed will be halved instead") + .placeNearTarget() + .colored(PonderPalette.SLOW) + .pointAt(util.vector.blockSurface(eastDrive.west(2), Direction.WEST)); + scene.idle(80); + + for (BlockPos gauge : new BlockPos[] { eastGauge, middleGauge, westGauge }) { + scene.idle(5); + scene.overlay.showText(180) + .sharedText(gauge == westGauge ? "rpm8" : gauge == eastGauge ? "rpm16_source" : "rpm16") + .colored(gauge == westGauge ? PonderPalette.SLOW : PonderPalette.MEDIUM) + .placeNearTarget() + .pointAt(util.vector.blockSurface(gauge, Direction.NORTH)); + } + + scene.idle(80); + + scene.overlay.showText(100) + .text("In both cases, Chain Drives in the row always run at 2x the speed of the Powered Gearshift") + .placeNearTarget() + .pointAt(util.vector.blockSurface(eastDrive.west(2), Direction.WEST)); + scene.idle(100); + + scene.world.toggleRedstonePower(util.select.fromTo(leverPos, leverPos.south(2))); + scene.world.toggleRedstonePower(util.select.position(1, 1, 4)); + scene.world.modifyKineticSpeed(util.select.position(westGauge), f -> 2f * f); + scene.world.hideIndependentSection(lever, Direction.UP); + scene.idle(15); + + scene.world.showSection(util.select.fromTo(analogPos, analogPos.south()), Direction.DOWN); + + scene.idle(15); + scene.world.modifyTileNBT(util.select.position(analogPos), AnalogLeverTileEntity.class, nbt -> { + nbt.putInt("State", 8); + }); + scene.world.modifyBlock(analogPos.south(), s -> s.with(RedstoneWireBlock.POWER, 8), false); + scene.world.toggleRedstonePower(util.select.position(1, 1, 4)); + scene.world.modifyKineticSpeed(util.select.position(westGauge), f -> .75f * f); + scene.effects.indicateRedstone(analogPos); + + scene.idle(20); + + scene.overlay.showText(100) + .text("Using analog signals, the ratio can be adjusted more precisely between 1 and 2") + .placeNearTarget() + .pointAt(util.vector.blockSurface(eastDrive.west(2), Direction.WEST)); + scene.idle(40); + + for (BlockPos gauge : new BlockPos[] { eastGauge, middleGauge, westGauge }) { + scene.idle(5); + Builder builder = scene.overlay.showText(180) + .colored(gauge == westGauge ? PonderPalette.SLOW : PonderPalette.MEDIUM) + .placeNearTarget() + .pointAt(util.vector.blockSurface(gauge, Direction.NORTH)); + if (gauge == westGauge) + builder.text("12 RPM"); + else + builder.sharedText(gauge == eastGauge ? "rpm16_source" : "rpm16"); + } + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/DebugScenes.java b/src/main/java/com/simibubi/create/foundation/ponder/content/DebugScenes.java new file mode 100644 index 000000000..da89236c3 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/DebugScenes.java @@ -0,0 +1,436 @@ +package com.simibubi.create.foundation.ponder.content; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllItems; +import com.simibubi.create.content.contraptions.base.IRotate.SpeedLevel; +import com.simibubi.create.content.contraptions.particle.RotationIndicatorParticleData; +import com.simibubi.create.foundation.ponder.ElementLink; +import com.simibubi.create.foundation.ponder.PonderRegistry; +import com.simibubi.create.foundation.ponder.PonderStoryBoardEntry.PonderStoryBoard; +import com.simibubi.create.foundation.ponder.SceneBuilder; +import com.simibubi.create.foundation.ponder.SceneBuildingUtil; +import com.simibubi.create.foundation.ponder.Selection; +import com.simibubi.create.foundation.ponder.elements.BeltItemElement; +import com.simibubi.create.foundation.ponder.elements.InputWindowElement; +import com.simibubi.create.foundation.ponder.elements.WorldSectionElement; +import com.simibubi.create.foundation.ponder.instructions.EmitParticlesInstruction.Emitter; +import com.simibubi.create.foundation.utility.Pointing; +import com.tterrag.registrate.util.entry.ItemEntry; + +import net.minecraft.block.Blocks; +import net.minecraft.entity.Entity; +import net.minecraft.entity.item.ItemEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.particles.ParticleTypes; +import net.minecraft.util.Direction; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; + +public class DebugScenes { + + private static int index; + + public static void registerAll() { + index = 1; + add(DebugScenes::coordinateScene); + add(DebugScenes::blocksScene); + add(DebugScenes::fluidsScene); + add(DebugScenes::offScreenScene); + add(DebugScenes::particleScene); + add(DebugScenes::controlsScene); + add(DebugScenes::birbScene); + add(DebugScenes::sectionsScene); + add(DebugScenes::itemScene); + } + + private static void add(PonderStoryBoard sb) { + ItemEntry item = AllItems.BRASS_HAND; + String schematicPath = "debug/scene_" + index; + PonderRegistry.addStoryBoard(item, schematicPath, sb) + .highlightAllTags() + .chapter(PonderChapter.of("debug")); + index++; + } + + public static void empty(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("debug_empty", "Missing Content"); + scene.showBasePlate(); + scene.idle(5); + } + + public static void coordinateScene(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("debug_coords", "Coordinate Space"); + scene.showBasePlate(); + scene.idle(10); + scene.world.showSection(util.select.layersFrom(1), Direction.DOWN); + + Selection xAxis = util.select.fromTo(2, 1, 1, 4, 1, 1); + Selection yAxis = util.select.fromTo(1, 2, 1, 1, 4, 1); + Selection zAxis = util.select.fromTo(1, 1, 2, 1, 1, 4); + + scene.idle(10); + scene.overlay.showSelectionWithText(xAxis, 20) + .colored(PonderPalette.RED) + .text("Das X axis"); + scene.idle(20); + scene.overlay.showSelectionWithText(yAxis, 20) + .colored(PonderPalette.GREEN) + .text("Das Y axis"); + scene.idle(20); + scene.overlay.showSelectionWithText(zAxis, 20) + .colored(PonderPalette.BLUE) + .text("Das Z axis"); + scene.idle(10); + } + + public static void blocksScene(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("debug_blocks", "Changing Blocks"); + scene.showBasePlate(); + scene.idle(10); + scene.world.showSection(util.select.layersFrom(1), Direction.DOWN); + scene.idle(10); + scene.overlay.showText(1000) + .independent(10) + .text("Blocks can be modified"); + scene.idle(20); + scene.world.replaceBlocks(util.select.fromTo(1, 1, 3, 2, 2, 4), + AllBlocks.REFINED_RADIANCE_CASING.getDefaultState(), true); + scene.idle(10); + scene.world.replaceBlocks(util.select.position(3, 1, 1), Blocks.GOLD_BLOCK.getDefaultState(), true); + scene.rotateCameraY(180); + scene.markAsFinished(); + } + + public static void fluidsScene(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("debug_fluids", "Showing Fluids"); + scene.showBasePlate(); + scene.idle(10); + Vec3d parrotPos = util.vector.topOf(1, 0, 1); + scene.special.birbLookingAtPOI(parrotPos); + scene.world.showSection(util.select.layersFrom(1), Direction.DOWN); + scene.overlay.showText(1000) + .text("Fluid rendering test.") + .pointAt(new Vec3d(1, 2.5, 4.5)); + scene.markAsFinished(); + + Object outlineSlot = new Object(); + + Vec3d vec1 = util.vector.topOf(1, 0, 0); + Vec3d vec2 = util.vector.topOf(0, 0, 1); + AxisAlignedBB boundingBox1 = new AxisAlignedBB(vec1, vec1).expand(0, 2.5, 0) + .grow(.15, 0, .15); + AxisAlignedBB boundingBox2 = new AxisAlignedBB(vec2, vec2).expand(0, .125, 0) + .grow(.45, 0, .45); + Vec3d poi1 = boundingBox1.getCenter(); + Vec3d poi2 = boundingBox2.getCenter(); + + for (int i = 0; i < 10; i++) { + scene.overlay.chaseBoundingBoxOutline(PonderPalette.RED, outlineSlot, + i % 2 == 0 ? boundingBox1 : boundingBox2, 15); + scene.idle(3); + scene.special.movePointOfInterest(i % 2 == 0 ? poi1 : poi2); + scene.idle(12); + } + + scene.idle(12); + scene.special.movePointOfInterest(util.grid.at(-4, 5, 4)); + scene.overlay.showText(40) + .colored(PonderPalette.RED) + .text("wut?") + .pointAt(parrotPos.add(-.25f, 0.25f, .25f)); + + } + + public static void offScreenScene(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("debug_baseplate", "Out of bounds / configureBasePlate"); + scene.configureBasePlate(1, 0, 6); + scene.showBasePlate(); + + Selection out1 = util.select.fromTo(7, 0, 0, 8, 0, 5); + Selection out2 = util.select.fromTo(0, 0, 0, 0, 0, 5); + Selection blocksExceptBasePlate = util.select.layersFrom(1) + .add(out1) + .add(out2); + + scene.idle(10); + scene.world.showSection(blocksExceptBasePlate, Direction.DOWN); + scene.idle(10); + + scene.overlay.showSelectionWithText(out1, 100) + .colored(PonderPalette.BLACK) + .text("Blocks outside of the base plate do not affect scaling"); + scene.overlay.showSelectionWithText(out2, 100) + .colored(PonderPalette.BLACK) + .text("configureBasePlate() makes sure of that."); + scene.markAsFinished(); + } + + public static void particleScene(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("debug_particles", "Emitting particles"); + scene.showBasePlate(); + scene.idle(10); + scene.world.showSection(util.select.layersFrom(1), Direction.DOWN); + scene.idle(10); + + Vec3d emitterPos = util.vector.of(2.5, 2.25, 2.5); + Emitter emitter = Emitter.simple(ParticleTypes.LAVA, util.vector.of(0, .1, 0)); + Emitter rotation = + Emitter.simple(new RotationIndicatorParticleData(SpeedLevel.MEDIUM.getColor(), 12, 1, 1, 20, 'Y'), + util.vector.of(0, .1, 0)); + + scene.overlay.showText(20) + .text("Incoming...") + .pointAt(emitterPos); + scene.idle(30); + scene.effects.emitParticles(emitterPos, emitter, 1, 60); + scene.effects.emitParticles(emitterPos, rotation, 20, 1); + scene.idle(30); + scene.rotateCameraY(180); + } + + public static void controlsScene(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("debug_controls", "Basic player interaction"); + scene.showBasePlate(); + scene.idle(10); + scene.world.showSection(util.select.layer(1), Direction.DOWN); + scene.idle(4); + scene.world.showSection(util.select.layer(2), Direction.DOWN); + scene.idle(4); + scene.world.showSection(util.select.layer(3), Direction.DOWN); + scene.idle(10); + + BlockPos shaftPos = util.grid.at(3, 1, 1); + Selection shaftSelection = util.select.position(shaftPos); + scene.overlay.showControls(new InputWindowElement(util.vector.topOf(shaftPos), Pointing.DOWN).rightClick() + .whileSneaking() + .withWrench(), 40); + scene.idle(20); + scene.world.replaceBlocks(shaftSelection, AllBlocks.SHAFT.getDefaultState(), true); + + scene.idle(20); + scene.world.hideSection(shaftSelection, Direction.UP); + + scene.idle(20); + + scene.overlay.showControls(new InputWindowElement(util.vector.of(1, 4.5, 3.5), Pointing.LEFT).rightClick() + .withItem(new ItemStack(Blocks.POLISHED_ANDESITE)), 20); + scene.world.showSection(util.select.layer(4), Direction.DOWN); + + scene.idle(40); + + BlockPos chassis = util.grid.at(1, 1, 3); + Vec3d chassisSurface = util.vector.blockSurface(chassis, Direction.NORTH); + + Object chassisValueBoxHighlight = new Object(); + Object chassisEffectHighlight = new Object(); + + AxisAlignedBB point = new AxisAlignedBB(chassisSurface, chassisSurface); + AxisAlignedBB expanded = point.grow(1 / 4f, 1 / 4f, 1 / 16f); + + Selection singleBlock = util.select.position(1, 2, 3); + Selection twoBlocks = util.select.fromTo(1, 2, 3, 1, 3, 3); + Selection threeBlocks = util.select.fromTo(1, 2, 3, 1, 4, 3); + + Selection singleRow = util.select.fromTo(1, 2, 3, 3, 2, 3); + Selection twoRows = util.select.fromTo(1, 2, 3, 3, 3, 3); + Selection threeRows = twoRows.copy() + .add(threeBlocks); + + scene.overlay.chaseBoundingBoxOutline(PonderPalette.GREEN, chassisValueBoxHighlight, point, 1); + scene.idle(1); + scene.overlay.chaseBoundingBoxOutline(PonderPalette.GREEN, chassisValueBoxHighlight, expanded, 120); + scene.overlay.showControls(new InputWindowElement(chassisSurface, Pointing.UP).scroll() + .withWrench(), 40); + + PonderPalette white = PonderPalette.WHITE; + scene.overlay.showOutline(white, chassisEffectHighlight, singleBlock, 10); + scene.idle(10); + scene.overlay.showOutline(white, chassisEffectHighlight, twoBlocks, 10); + scene.idle(10); + scene.overlay.showOutline(white, chassisEffectHighlight, threeBlocks, 10); + scene.idle(10); + scene.overlay.showOutline(white, chassisEffectHighlight, twoBlocks, 10); + scene.idle(10); + scene.overlay.showOutline(white, chassisEffectHighlight, singleBlock, 10); + scene.idle(10); + + scene.idle(30); + scene.overlay.showControls(new InputWindowElement(chassisSurface, Pointing.UP).whileCTRL() + .scroll() + .withWrench(), 40); + + scene.overlay.showOutline(white, chassisEffectHighlight, singleRow, 10); + scene.idle(10); + scene.overlay.showOutline(white, chassisEffectHighlight, twoRows, 10); + scene.idle(10); + scene.overlay.showOutline(white, chassisEffectHighlight, threeRows, 10); + scene.idle(10); + scene.overlay.showOutline(white, chassisEffectHighlight, twoRows, 10); + scene.idle(10); + scene.overlay.showOutline(white, chassisEffectHighlight, singleRow, 10); + scene.idle(10); + + scene.markAsFinished(); + } + + public static void birbScene(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("debug_birbs", "Birbs"); + scene.showBasePlate(); + scene.idle(10); + scene.world.showSection(util.select.layersFrom(1), Direction.DOWN); + scene.idle(10); + + BlockPos pos = new BlockPos(1, 2, 3); + scene.special.birbOnSpinnyShaft(pos); + scene.overlay.showText(100) + .colored(PonderPalette.GREEN) + .text("More birbs = More interesting") + .pointAt(util.vector.topOf(pos)); + + scene.idle(10); + scene.special.birbPartying(util.vector.topOf(0, 1, 2)); + scene.idle(10); + + scene.special.birbLookingAtPOI(util.vector.centerOf(3, 1, 3) + .add(0, 0.25f, 0)); + scene.idle(20); + + BlockPos poi1 = util.grid.at(4, 1, 0); + BlockPos poi2 = util.grid.at(0, 1, 4); + + scene.world.setBlock(poi1, Blocks.GOLD_BLOCK.getDefaultState(), true); + scene.special.movePointOfInterest(poi1); + scene.idle(20); + + scene.world.setBlock(poi2, Blocks.GOLD_BLOCK.getDefaultState(), true); + scene.special.movePointOfInterest(poi2); + scene.overlay.showText(20) + .text("Point of Interest") + .pointAt(util.vector.centerOf(poi2)); + scene.idle(20); + + scene.world.destroyBlock(poi1); + scene.special.movePointOfInterest(poi1); + scene.idle(20); + + scene.world.destroyBlock(poi2); + scene.special.movePointOfInterest(poi2); + } + + public static void sectionsScene(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("debug_sections", "Sections"); + scene.showBasePlate(); + scene.idle(10); + scene.rotateCameraY(95); + + BlockPos mergePos = util.grid.at(1, 1, 1); + BlockPos independentPos = util.grid.at(3, 1, 1); + Selection toMerge = util.select.position(mergePos); + Selection independent = util.select.position(independentPos); + Selection start = util.select.layersFrom(1) + .substract(toMerge) + .substract(independent); + + scene.world.showSection(start, Direction.DOWN); + scene.idle(20); + + scene.world.showSection(toMerge, Direction.DOWN); + ElementLink link = scene.world.showIndependentSection(independent, Direction.DOWN); + + scene.idle(20); + + scene.overlay.showText(40) + .colored(PonderPalette.GREEN) + .text("This Section got merged to base.") + .pointAt(util.vector.topOf(mergePos)); + scene.idle(10); + scene.overlay.showText(40) + .colored(PonderPalette.RED) + .text("This Section renders independently.") + .pointAt(util.vector.topOf(independentPos)); + + scene.idle(40); + + scene.world.hideIndependentSection(link, Direction.DOWN); + scene.world.hideSection(util.select.fromTo(mergePos, util.grid.at(1, 1, 4)), Direction.DOWN); + + scene.idle(20); + + Selection hiddenReplaceArea = util.select.fromTo(2, 1, 2, 4, 1, 4) + .substract(util.select.position(4, 1, 3)) + .substract(util.select.position(2, 1, 3)); + + scene.world.hideSection(hiddenReplaceArea, Direction.UP); + scene.idle(20); + scene.world.setBlocks(hiddenReplaceArea, AllBlocks.REFINED_RADIANCE_CASING.getDefaultState(), false); + scene.world.showSection(hiddenReplaceArea, Direction.DOWN); + scene.idle(20); + scene.overlay.showSelectionWithText(hiddenReplaceArea, 30) + .colored(PonderPalette.BLUE) + .text("Seamless substitution of blocks"); + + scene.idle(40); + + ElementLink helicopter = scene.world.makeSectionIndependent(hiddenReplaceArea); + scene.world.rotateSection(helicopter, 50, 5 * 360, 0, 60); + scene.world.moveSection(helicopter, util.vector.of(0, 4, 5), 50); + scene.overlay.showText(30) + .colored(PonderPalette.BLUE) + .text("Up, up and away.") + .independent(30); + + scene.idle(40); + scene.world.hideIndependentSection(helicopter, Direction.UP); + + } + + public static void itemScene(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("debug_items", "Manipulating Items"); + scene.configureBasePlate(0, 0, 6); + scene.world.showSection(util.select.layer(0), Direction.UP); + scene.idle(10); + scene.world.showSection(util.select.layersFrom(1), Direction.DOWN); + + ItemStack brassItem = AllItems.BRASS_INGOT.asStack(); + ItemStack copperItem = AllItems.COPPER_INGOT.asStack(); + + for (int z = 4; z >= 2; z--) { + scene.world.createItemEntity(util.vector.centerOf(0, 4, z), Vec3d.ZERO, brassItem.copy()); + scene.idle(10); + } + + BlockPos beltPos = util.grid.at(2, 1, 3); + ElementLink itemOnBelt = + scene.world.createItemOnBelt(beltPos, Direction.EAST, copperItem.copy()); + + scene.idle(10); + scene.world.stallBeltItem(itemOnBelt, true); + scene.idle(5); + scene.overlay.showText(40) + .colored(PonderPalette.FAST) + .text("Belt Items can only be force-stalled on the belt they were created on.") + .pointAt(util.vector.topOf(2, 1, 2)); + scene.idle(45); + scene.world.stallBeltItem(itemOnBelt, false); + scene.idle(20); + + scene.world.modifyEntities(ItemEntity.class, entity -> { + if (copperItem.isItemEqual(entity.getItem())) + entity.setNoGravity(true); + }); + + scene.idle(20); + + scene.world.modifyEntities(ItemEntity.class, entity -> { + if (brassItem.isItemEqual(entity.getItem())) + entity.setMotion(util.vector.of(-.15f, .5f, 0)); + }); + + scene.idle(27); + + scene.world.modifyEntities(ItemEntity.class, Entity::remove); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/FanScenes.java b/src/main/java/com/simibubi/create/foundation/ponder/content/FanScenes.java new file mode 100644 index 000000000..8d52c8113 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/FanScenes.java @@ -0,0 +1,297 @@ +package com.simibubi.create.foundation.ponder.content; + +import com.simibubi.create.AllItems; +import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack; +import com.simibubi.create.content.logistics.block.depot.DepotTileEntity; +import com.simibubi.create.foundation.ponder.ElementLink; +import com.simibubi.create.foundation.ponder.SceneBuilder; +import com.simibubi.create.foundation.ponder.SceneBuildingUtil; +import com.simibubi.create.foundation.ponder.Selection; +import com.simibubi.create.foundation.ponder.elements.BeltItemElement; +import com.simibubi.create.foundation.ponder.elements.EntityElement; +import com.simibubi.create.foundation.ponder.elements.InputWindowElement; +import com.simibubi.create.foundation.ponder.elements.ParrotElement; +import com.simibubi.create.foundation.ponder.elements.WorldSectionElement; +import com.simibubi.create.foundation.ponder.instructions.EmitParticlesInstruction.Emitter; +import com.simibubi.create.foundation.utility.Pointing; + +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.entity.Entity; +import net.minecraft.entity.item.ItemEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.particles.ParticleTypes; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; + +public class FanScenes { + + public static void direction(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("fan_direction", "Air flow of Encased Fans"); + scene.configureBasePlate(0, 1, 5); + scene.world.showSection(util.select.layer(0), Direction.UP); +// scene.world.modifyKineticSpeed(util.select.everywhere(), f -> -f); + scene.idle(5); + scene.world.showSection(util.select.fromTo(3, 1, 0, 3, 1, 5) + .add(util.select.position(3, 2, 4)), Direction.DOWN); + scene.world.showSection(util.select.fromTo(2, 1, 5, 1, 1, 5), Direction.DOWN); + scene.idle(10); + + BlockPos fanPos = util.grid.at(1, 1, 4); + scene.world.showSection(util.select.position(fanPos), Direction.SOUTH); + + scene.idle(40); + scene.effects.rotationDirectionIndicator(fanPos.south()); + + ElementLink flappyBirb = scene.special.flappyBirb(util.vector.topOf(1, 0, 3)); + scene.idle(2); + scene.special.rotateParrot(flappyBirb, 0, 235, 0, 30); + scene.special.moveParrot(flappyBirb, util.vector.of(0, 0, -2.5), 30); + scene.idle(20); + + scene.overlay.showText(80) + .text("Encased Fans use Rotational Force to create an Air Current") + .placeNearTarget() + .pointAt(util.vector.topOf(fanPos)); + scene.idle(90); + + BlockPos leverPos = util.grid.at(3, 2, 4); + Selection reverse = util.select.fromTo(3, 1, 5, 1, 1, 4); + scene.world.toggleRedstonePower(util.select.fromTo(leverPos, leverPos.down())); + scene.effects.indicateRedstone(leverPos); + scene.world.modifyKineticSpeed(reverse, f -> -f); + scene.effects.rotationDirectionIndicator(fanPos.south()); + scene.special.rotateParrot(flappyBirb, 0, 215 * 2, 0, 30); + scene.special.moveParrot(flappyBirb, util.vector.of(0, 0, 2.5), 30); + scene.idle(31); + + scene.overlay.showText(60) + .text("Strength and Direction of Flow depends on the Rotational Input") + .placeNearTarget() + .pointAt(util.vector.topOf(fanPos)); + scene.markAsFinished(); + scene.idle(70); + + scene.world.toggleRedstonePower(util.select.fromTo(leverPos, leverPos.down())); + scene.effects.indicateRedstone(leverPos); + scene.world.modifyKineticSpeed(reverse, f -> -f); + scene.world.modifyKineticSpeed(util.select.everywhere(), f -> 4 * f); + scene.effects.rotationSpeedIndicator(fanPos.south()); + scene.special.rotateParrot(flappyBirb, 0, 245 * 4, 0, 30); + scene.special.moveParrot(flappyBirb, util.vector.of(0, 0, -20), 30); + + } + + public static void processing(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("fan_processing", "Processing Items using Encased Fans"); + scene.configureBasePlate(1, 0, 5); + scene.world.showSection(util.select.layer(0) + .substract(util.select.position(0, 0, 4)), Direction.UP); + scene.idle(5); + scene.world.showSection(util.select.fromTo(6, 1, 2, 5, 1, 2) + .add(util.select.position(1, 1, 2)), Direction.DOWN); + scene.idle(25); + + BlockPos blockPos = util.grid.at(4, 1, 2); + + // blasting start + + ElementLink blockInFront = + scene.world.showIndependentSection(util.select.position(3, 1, 0), Direction.SOUTH); + scene.world.moveSection(blockInFront, util.vector.of(1, 0, 2), 0); + scene.world.setBlock(blockPos, Blocks.LAVA.getDefaultState(), false); + scene.idle(10); + + scene.overlay.showSelectionWithText(util.select.fromTo(blockPos, blockPos.west(2)), 80) + .colored(PonderPalette.RED) + .text("When passing through lava, the Air Flow becomes Heated"); + scene.idle(80); + + ItemStack stack = new ItemStack(Items.GOLD_ORE); + ItemStack smelted = new ItemStack(Items.GOLD_INGOT); + + ElementLink entityLink = scene.world.createItemEntity(util.vector.centerOf(blockPos.west(2) + .up(2)), util.vector.of(0, 0.1, 0), stack); + scene.idle(15); + scene.world.modifyEntity(entityLink, e -> e.setMotion(-0.2f, 0, 0)); + Vec3d itemVec = util.vector.blockSurface(util.grid.at(1, 1, 2), Direction.EAST) + .add(0.1, 0, 0); + scene.overlay.showControls(new InputWindowElement(itemVec, Pointing.DOWN).withItem(stack), 20); + scene.idle(20); + scene.effects.emitParticles(itemVec.add(0, 0.2f, 0), Emitter.simple(ParticleTypes.LARGE_SMOKE, Vec3d.ZERO), 1, + 60); + + scene.overlay.showText(80) + .colored(PonderPalette.WHITE) + .pointAt(itemVec) + .placeNearTarget() + .text("Items caught in the area will be smelted"); + + scene.idle(60); + scene.world.modifyEntities(ItemEntity.class, ie -> ie.setItem(smelted)); + scene.idle(40); + scene.overlay.showControls(new InputWindowElement(itemVec, Pointing.DOWN).withItem(smelted), 20); + scene.idle(20); + scene.world.modifyEntities(ItemEntity.class, Entity::remove); + scene.idle(20); + + scene.overlay.showText(80) + .colored(PonderPalette.RED) + .pointAt(itemVec) + .placeNearTarget() + .text("Food items thrown here would be incinerated"); + scene.idle(40); + + // smoking start + + BlockState campfire = Blocks.FIRE.getDefaultState(); + scene.world.hideIndependentSection(blockInFront, Direction.NORTH); + scene.idle(15); + scene.world.setBlock(util.grid.at(3, 1, 0), campfire, false); + scene.world.setBlock(blockPos, campfire, true); + blockInFront = scene.world.showIndependentSection(util.select.position(3, 1, 0), Direction.NORTH); + scene.world.moveSection(blockInFront, util.vector.of(1, 0, 2), 0); + scene.idle(50); + + scene.overlay.showSelectionWithText(util.select.fromTo(blockPos, blockPos.west(2)), 60) + .colored(PonderPalette.BLACK) + .text("Instead, a setup for Smoking using Fire should be used for them"); + scene.idle(80); + + // washing start + + BlockState water = Blocks.WATER.getDefaultState(); + scene.world.hideIndependentSection(blockInFront, Direction.NORTH); + scene.idle(15); + scene.world.setBlock(util.grid.at(3, 1, 0), water, false); + scene.world.setBlock(blockPos, water, true); + blockInFront = scene.world.showIndependentSection(util.select.position(3, 1, 0), Direction.NORTH); + scene.world.moveSection(blockInFront, util.vector.of(1, 0, 2), 0); + scene.idle(20); + + scene.overlay.showSelectionWithText(util.select.fromTo(blockPos, blockPos.west(2)), 60) + .colored(PonderPalette.MEDIUM) + .text("Air Flows passing through water create a Washing Setup"); + scene.idle(70); + + stack = AllItems.CRUSHED_GOLD.asStack(); + ItemStack washed = new ItemStack(Items.GOLD_NUGGET, 16); + + entityLink = scene.world.createItemEntity(util.vector.centerOf(blockPos.west(2) + .up(2)), util.vector.of(0, 0.1, 0), stack); + scene.idle(15); + scene.world.modifyEntity(entityLink, e -> e.setMotion(-0.2f, 0, 0)); + scene.overlay.showControls(new InputWindowElement(itemVec, Pointing.DOWN).withItem(stack), 20); + scene.idle(20); + scene.effects.emitParticles(itemVec.add(0, 0.2f, 0), Emitter.simple(ParticleTypes.SPIT, Vec3d.ZERO), 1, 60); + + scene.overlay.showText(50) + .colored(PonderPalette.WHITE) + .pointAt(itemVec) + .placeNearTarget() + .text("Some interesting new processing can be done with it"); + + scene.idle(60); + scene.world.modifyEntities(ItemEntity.class, ie -> ie.setItem(washed)); + scene.overlay.showControls(new InputWindowElement(itemVec, Pointing.DOWN).withItem(washed), 20); + scene.idle(20); + scene.world.modifyEntities(ItemEntity.class, Entity::remove); + scene.idle(20); + + scene.overlay.showText(100) + .colored(PonderPalette.RED) + .pointAt(util.vector.topOf(blockPos.east())) + .placeNearTarget() + .text("The Speed of the Fan does NOT affect the processing speed, only its range"); + scene.world.destroyBlock(util.grid.at(1, 1, 2)); + scene.idle(110); + + ElementLink cogs = scene.world.makeSectionIndependent(util.select.fromTo(6, 1, 2, 6, 0, 3) + .add(util.select.fromTo(4, 0, 2, 5, 0, 2))); + scene.world.modifyKineticSpeed(util.select.position(5, 2, 2), f -> f / 3f); + scene.world.moveSection(cogs, util.vector.of(0, 1, 0), 15); + scene.world.moveSection(blockInFront, util.vector.of(0, 1, 0), 15); + scene.world.destroyBlock(blockPos.east()); + scene.world.showSection(util.select.position(blockPos.east() + .up()), Direction.DOWN); + scene.world.setBlock(blockPos.up(), Blocks.WATER.getDefaultState(), false); + + ItemStack sand = new ItemStack(Items.SAND); + ItemStack clay = new ItemStack(Items.CLAY_BALL); + + scene.idle(20); + BlockPos depos = util.grid.at(3, 4, 2); + ElementLink depot = + scene.world.showIndependentSection(util.select.position(depos), Direction.DOWN); + scene.world.moveSection(depot, util.vector.of(-1, -3, 0), 0); + scene.world.createItemOnBeltLike(depos, Direction.NORTH, sand); + scene.idle(10); + Vec3d depotTop = util.vector.topOf(2, 1, 2) + .add(0, 0.25, 0); + scene.effects.emitParticles(depotTop, Emitter.simple(ParticleTypes.SPIT, Vec3d.ZERO), .5f, 30); + scene.idle(30); + scene.world.modifyTileNBT(util.select.position(depos), DepotTileEntity.class, + nbt -> nbt.put("HeldItem", new TransportedItemStack(clay).serializeNBT())); + scene.effects.emitParticles(depotTop, Emitter.simple(ParticleTypes.SPIT, Vec3d.ZERO), .5f, 30); + scene.overlay.showText(90) + .pointAt(depotTop) + .text("Fan Processing can also be applied to Items on Depots and Belts"); + + scene.idle(100); + scene.world.moveSection(depot, util.vector.of(-1, 0, 0), 15); + scene.idle(15); + ElementLink largeCog = + scene.world.showIndependentSection(util.select.position(1, 2, 4), Direction.UP); + ElementLink belt = + scene.world.showIndependentSection(util.select.fromTo(3, 3, 1, 1, 3, 3), Direction.DOWN); + scene.world.moveSection(largeCog, util.vector.of(-1, -2, 0), 0); + scene.world.moveSection(belt, util.vector.of(-1, -2, 0), 0); + ElementLink transported = + scene.world.createItemOnBelt(util.grid.at(3, 3, 3), Direction.SOUTH, sand); + scene.idle(60); + scene.effects.emitParticles(depotTop, Emitter.simple(ParticleTypes.SPIT, Vec3d.ZERO), .5f, 25); + scene.idle(25); + scene.world.changeBeltItemTo(transported, new ItemStack(Items.CLAY_BALL)); + scene.effects.emitParticles(depotTop, Emitter.simple(ParticleTypes.SPIT, Vec3d.ZERO), .5f, 25); + scene.idle(60); + + scene.world.setKineticSpeed(util.select.position(1, 2, 4) + .add(util.select.fromTo(3, 3, 1, 1, 3, 3)), 0); + + } + + public static void source(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("fan_source", "Generating Rotational Force using Encased Fans"); + scene.configureBasePlate(0, 0, 5); + scene.world.showSection(util.select.layer(0), Direction.UP); + scene.idle(5); + scene.world.showSection(util.select.layer(1), Direction.DOWN); + scene.idle(10); + scene.world.showSection(util.select.layersFrom(2), Direction.DOWN); + scene.idle(10); + BlockPos rightFan = util.grid.at(1, 2, 2); + scene.overlay.showText(80) + .text("Fans facing down into a source of heat can provide Rotational Force") + .placeNearTarget() + .pointAt(util.vector.blockSurface(rightFan, Direction.WEST)); + scene.idle(80); + + for (BlockPos pos : new BlockPos[] { rightFan, util.grid.at(3, 2, 2) }) { + scene.idle(10); + scene.world.toggleRedstonePower(util.select.position(pos.north())); + scene.effects.indicateRedstone(pos.north()); + scene.world.setKineticSpeed(util.select.fromTo(pos, pos.up()), 4); + scene.effects.rotationSpeedIndicator(pos.up()); + } + + scene.overlay.showText(90) + .text("When given a Redstone Signal, the Fans will start providing power") + .colored(PonderPalette.RED) + .placeNearTarget() + .pointAt(util.vector.blockSurface(rightFan, Direction.WEST)); + scene.markAsFinished(); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/FunnelScenes.java b/src/main/java/com/simibubi/create/foundation/ponder/content/FunnelScenes.java new file mode 100644 index 000000000..f6fee510c --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/FunnelScenes.java @@ -0,0 +1,509 @@ +package com.simibubi.create.foundation.ponder.content; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllItems; +import com.simibubi.create.content.logistics.block.funnel.BeltFunnelBlock; +import com.simibubi.create.content.logistics.block.funnel.FunnelBlock; +import com.simibubi.create.content.logistics.block.funnel.FunnelTileEntity; +import com.simibubi.create.foundation.ponder.ElementLink; +import com.simibubi.create.foundation.ponder.SceneBuilder; +import com.simibubi.create.foundation.ponder.SceneBuildingUtil; +import com.simibubi.create.foundation.ponder.Selection; +import com.simibubi.create.foundation.ponder.elements.EntityElement; +import com.simibubi.create.foundation.ponder.elements.InputWindowElement; +import com.simibubi.create.foundation.ponder.elements.WorldSectionElement; +import com.simibubi.create.foundation.utility.Pointing; + +import net.minecraft.block.Blocks; +import net.minecraft.block.LeverBlock; +import net.minecraft.block.RedstoneWireBlock; +import net.minecraft.entity.Entity; +import net.minecraft.entity.item.ItemEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.util.Direction; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraftforge.items.ItemHandlerHelper; + +public class FunnelScenes { + + public static void intro(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("funnel_intro", "Using funnels"); + scene.configureBasePlate(0, 1, 5); + scene.world.showSection(util.select.layer(0), Direction.UP); + scene.world.modifyKineticSpeed(util.select.everywhere(), f -> f / 2f); + + scene.idle(10); + + Selection verticalFunnel = util.select.fromTo(2, -1, 4, 2, 4, 4) + .add(util.select.fromTo(1, 1, 4, 1, 4, 4)); + Selection beltFunnels = util.select.fromTo(1, 2, 2, 3, 2, 2); + Selection beltFunnelEnv = util.select.fromTo(0, 1, 0, 5, 2, 2) + .substract(beltFunnels); + + scene.world.showSection(beltFunnelEnv, Direction.DOWN); + + scene.idle(20); + scene.world.showSection(beltFunnels, Direction.DOWN); + + BlockPos entryBeltPos = util.grid.at(3, 1, 2); + BlockPos exitBeltPos = util.grid.at(1, 1, 2); + ItemStack itemStack = AllBlocks.BRASS_BLOCK.asStack(); + Selection exitFunnel = util.select.position(exitBeltPos.up()); + + for (int i = 0; i < 8; i++) { + scene.idle(8); + scene.world.removeItemsFromBelt(exitBeltPos); + scene.world.flapFunnels(exitFunnel, false); + if (i == 2) + scene.rotateCameraY(70); + if (i < 6) + scene.world.createItemOnBelt(entryBeltPos, Direction.EAST, itemStack); + } + + scene.rotateCameraY(-70); + scene.idle(10); + + Selection outputFunnel = util.select.position(1, 2, 4); + scene.world.setBlocks(outputFunnel, Blocks.AIR.getDefaultState(), false); + scene.world.setBlocks(util.select.fromTo(2, -1, 4, 2, 0, 4), AllBlocks.ANDESITE_CASING.getDefaultState(), true); + ElementLink independentSection = + scene.world.showIndependentSection(verticalFunnel, Direction.UP); + + Vec3d topItemSpawn = util.vector.centerOf(2, 6, 4); + Vec3d sideItemSpawn = util.vector.centerOf(1, 3, 4) + .add(0.15f, -0.45f, 0); + ElementLink lastItemEntity = null; + + for (int i = 0; i < 4; i++) { + if (lastItemEntity != null) + scene.world.modifyEntity(lastItemEntity, Entity::remove); + if (i < 3) + lastItemEntity = scene.world.createItemEntity(topItemSpawn, util.vector.of(0, -0.4, 0), itemStack); + scene.idle(8); + } + + scene.world.moveSection(independentSection, util.vector.of(0, 1, 0), 15); + scene.idle(10); + scene.world.setBlocks(outputFunnel, AllBlocks.ANDESITE_FUNNEL.getDefaultState() + .with(FunnelBlock.FACING, Direction.WEST) + .with(FunnelBlock.EXTRACTING, true), false); + + for (int i = 0; i < 3; i++) { + scene.idle(8); + scene.world.flapFunnels(outputFunnel, false); + scene.world.createItemEntity(sideItemSpawn, util.vector.of(-.05, 0, 0), itemStack); + } + + scene.idle(8); + scene.overlay.showText(360) + .text("Funnels are ideal for transferring items from and to inventories.") + .independent(); + scene.markAsFinished(); + } + + public static void directionality(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("funnel_direction", "Direction of Transfer"); + scene.configureBasePlate(0, 0, 5); + scene.world.showSection(util.select.layer(0), Direction.UP); + scene.world.modifyKineticSpeed(util.select.everywhere(), f -> f / 2f); + scene.world.setBlocks(util.select.position(3, 1, 1), AllBlocks.ANDESITE_CASING.getDefaultState(), false); + + BlockPos topFunnel = util.grid.at(3, 3, 2); + Selection topFunnelSelection = util.select.position(topFunnel); + Selection firstShow = util.select.fromTo(3, 1, 2, 3, 2, 2); + scene.idle(5); + + scene.world.showSection(firstShow, Direction.DOWN); + scene.idle(15); + + ItemStack itemStack = AllBlocks.BRASS_BLOCK.asStack(); + Vec3d topCenter = util.vector.centerOf(topFunnel); + Vec3d topSide = util.vector.blockSurface(topFunnel, Direction.EAST); + + InputWindowElement controlsSneak = new InputWindowElement(topCenter, Pointing.DOWN).rightClick() + .whileSneaking(); + + // Placing funnels without sneak + scene.world.showSection(topFunnelSelection, Direction.DOWN); + scene.overlay.showText(80) + .text("Placed normally, it pulls items from the inventory.") + .pointAt(topCenter) + .placeNearTarget(); + scene.idle(45); + + ElementLink itemLink = + scene.world.createItemEntity(topCenter, util.vector.of(0, 4 / 16f, 0), itemStack); + scene.idle(40); + + scene.world.modifyEntity(itemLink, Entity::remove); + scene.world.hideSection(topFunnelSelection, Direction.UP); + scene.idle(20); + + // Placing funnels with sneak + scene.world.modifyBlock(topFunnel, s -> s.with(FunnelBlock.EXTRACTING, false), false); + scene.idle(5); + + scene.world.showSection(topFunnelSelection, Direction.DOWN); + scene.overlay.showControls(controlsSneak, 35); + scene.overlay.showText(80) + .text("Placed while sneaking, it puts items into the inventory.") + .pointAt(topCenter) + .placeNearTarget(); + scene.idle(45); + + itemLink = scene.world.createItemEntity(topCenter.add(0, 3, 0), util.vector.of(0, -0.2, 0), itemStack); + scene.idle(10); + + scene.world.modifyEntity(itemLink, Entity::remove); + scene.idle(45); + + // Wrench interaction + InputWindowElement wrenchControls = new InputWindowElement(topSide, Pointing.RIGHT).rightClick() + .withWrench(); + scene.overlay.showControls(wrenchControls, 40); + scene.idle(10); + scene.world.modifyBlock(topFunnel, s -> s.cycle(FunnelBlock.EXTRACTING), true); + scene.idle(10); + scene.overlay.showText(80) + .text("Using a wrench, the funnel can be flipped after placement.") + .pointAt(topCenter) + .placeNearTarget(); + + itemLink = scene.world.createItemEntity(topCenter, util.vector.of(0, 4 / 16f, 0), itemStack); + scene.idle(30); + + scene.overlay.showControls(wrenchControls, 40); + scene.idle(10); + scene.world.modifyBlock(topFunnel, s -> s.cycle(FunnelBlock.EXTRACTING), true); + scene.idle(10); + scene.world.modifyEntity(itemLink, Entity::remove); + + scene.idle(20); + + // Side funnel + BlockPos sideFunnel = util.grid.at(3, 2, 1); + Selection sideFunnelSelection = util.select.fromTo(sideFunnel.down(), sideFunnel); + Vec3d sideCenter = util.vector.centerOf(sideFunnel); + + scene.world.modifyBlock(sideFunnel, s -> s.cycle(FunnelBlock.EXTRACTING), false); + scene.world.showSection(sideFunnelSelection, Direction.DOWN); + scene.overlay.showText(70) + .text("Same rules will apply for most orientations.") + .pointAt(sideCenter) + .placeNearTarget(); + + scene.idle(20); + + scene.world.flapFunnels(sideFunnelSelection, true); + itemLink = scene.world.createItemEntity(sideCenter.subtract(0, .45, 0), util.vector.of(0, 0, -0.1), itemStack); + scene.idle(60); + scene.world.hideSection(sideFunnelSelection, Direction.UP); + scene.world.hideSection(topFunnelSelection, Direction.UP); + scene.world.modifyEntity(itemLink, Entity::remove); + scene.idle(20); + + // Belt funnel + Selection beltFunnelSetup = util.select.fromTo(0, 1, 0, 2, 2, 5); + Selection gearshiftAndLever = util.select.fromTo(1, 1, 4, 1, 2, 4); + Selection gearshiftedKinetics = util.select.fromTo(1, 1, 2, 2, 1, 4); + Vec3d topOfBeltFunnel = util.vector.topOf(2, 2, 2); + BlockPos beltPos = util.grid.at(2, 1, 2); + BlockPos cogPos = util.grid.at(1, 1, 3); + + scene.world.showSection(beltFunnelSetup, Direction.DOWN); + scene.overlay.showText(140) + .text("Funnels on belts will extract/insert depending on its movement direction.") + .pointAt(topOfBeltFunnel); + + scene.idle(15); + + for (int i = 0; i < 2; i++) { + scene.world.createItemOnBelt(beltPos, Direction.EAST, itemStack); + scene.effects.rotationDirectionIndicator(cogPos); + scene.idle(50); + + scene.world.modifyBlocks(gearshiftAndLever, s -> s.cycle(BlockStateProperties.POWERED), false); + scene.world.modifyKineticSpeed(gearshiftedKinetics, f -> -f); + scene.effects.indicateRedstone(util.grid.at(1, 2, 4)); + scene.effects.rotationDirectionIndicator(cogPos); + scene.idle(35); + + scene.world.removeItemsFromBelt(beltPos); + scene.world.flapFunnels(beltFunnelSetup, false); + + if (i == 0) { + scene.idle(50); + scene.world.modifyBlocks(gearshiftAndLever, s -> s.cycle(BlockStateProperties.POWERED), false); + scene.world.modifyKineticSpeed(gearshiftedKinetics, f -> -f); + scene.effects.indicateRedstone(util.grid.at(1, 2, 4)); + } + } + } + + public static void compat(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("funnel_compat", "Funnel compatibility"); + scene.configureBasePlate(0, 0, 5); + + BlockPos sawFunnel = util.grid.at(4, 2, 1); + BlockPos depotFunnel = util.grid.at(2, 2, 2); + BlockPos drainFunnel = util.grid.at(0, 2, 3); + + scene.world.showSection(util.select.layer(0), Direction.UP); + Selection firstShow = util.select.layer(1) + .add(util.select.position(sawFunnel.south())) + .add(util.select.position(depotFunnel.south())) + .add(util.select.position(drainFunnel.south())); + scene.idle(5); + + scene.world.showSection(firstShow, Direction.DOWN); + + scene.idle(8); + scene.overlay.showText(360) + .text("Funnels should also interact nicely with a handful of other components.") + .independent(0); + scene.idle(40); + + scene.world.showSection(util.select.position(sawFunnel), Direction.DOWN); + scene.overlay.showText(40) + .text("Vertical Saws") + .colored(PonderPalette.BLUE) + .placeNearTarget() + .pointAt(util.vector.centerOf(sawFunnel.down())); + scene.idle(8); + scene.world.createItemOnBeltLike(sawFunnel.down(), Direction.SOUTH, new ItemStack(Blocks.OAK_LOG)); + scene.idle(40); + + scene.world.showSection(util.select.position(depotFunnel), Direction.DOWN); + scene.overlay.showText(40) + .text("Depots") + .colored(PonderPalette.BLUE) + .placeNearTarget() + .pointAt(util.vector.centerOf(depotFunnel.down())); + scene.idle(8); + scene.world.createItemOnBeltLike(depotFunnel.down(), Direction.SOUTH, new ItemStack(Items.GOLDEN_PICKAXE)); + scene.idle(40); + + scene.world.showSection(util.select.position(drainFunnel), Direction.DOWN); + scene.overlay.showText(40) + .text("Item Drains") + .colored(PonderPalette.BLUE) + .placeNearTarget() + .pointAt(util.vector.centerOf(drainFunnel.down())); + scene.idle(8); + scene.world.createItemOnBeltLike(drainFunnel.down(), Direction.SOUTH, new ItemStack(Items.WATER_BUCKET)); + scene.idle(40); + + scene.markAsFinished(); + } + + public static void redstone(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("funnel_redstone", "Redstone control"); + scene.configureBasePlate(0, 0, 5); + scene.world.showSection(util.select.layer(0), Direction.UP); + scene.idle(5); + scene.world.showSection(util.select.layersFrom(1), Direction.DOWN); + + ItemStack itemStack = AllBlocks.BRASS_BLOCK.asStack(); + Vec3d topItemSpawn = util.vector.centerOf(3, 6, 2); + ElementLink lastItemEntity = null; + + BlockPos lever = util.grid.at(1, 2, 2); + BlockPos redstone = util.grid.at(2, 2, 2); + BlockPos funnel = util.grid.at(3, 2, 2); + + AxisAlignedBB redstoneBB = new AxisAlignedBB(funnel).grow(-1 / 16f, -6 / 16f, -1 / 16f) + .offset(0, -5 / 16f, 0); + + for (int i = 0; i < 4; i++) { + if (lastItemEntity != null) + scene.world.modifyEntity(lastItemEntity, Entity::remove); + lastItemEntity = scene.world.createItemEntity(topItemSpawn, util.vector.of(0, -0.2, 0), itemStack); + scene.idle(8); + + if (i == 3) { + scene.world.modifyBlock(lever, s -> s.cycle(LeverBlock.POWERED), false); + scene.world.modifyBlock(redstone, s -> s.with(RedstoneWireBlock.POWER, 15), false); + scene.world.modifyBlock(funnel, s -> s.cycle(FunnelBlock.POWERED), false); + scene.effects.indicateRedstone(lever); + scene.idle(4); + scene.overlay.chaseBoundingBoxOutline(PonderPalette.RED, funnel, redstoneBB, 80); + scene.overlay.showText(80) + .colored(PonderPalette.RED) + .text("Redstone power will prevent any funnel from acting.") + .pointAt(util.vector.blockSurface(funnel, Direction.DOWN)); + } else { + scene.idle(4); + } + } + + } + + public static void brass(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("brass_funnel", "The Brass Funnel"); + scene.configureBasePlate(0, 0, 5); + scene.world.showSection(util.select.layer(0), Direction.UP); + scene.idle(5); + + BlockPos firstDepot = util.grid.at(3, 1, 1); + BlockPos secondDepot = util.grid.at(1, 1, 1); + Selection depots = util.select.fromTo(firstDepot, secondDepot); + Selection beltAndStuff = util.select.fromTo(0, 1, 2, 4, 1, 2) + .add(util.select.fromTo(0, 1, 3, 0, 2, 5)); + Selection withoutBelt = util.select.layersFrom(1) + .substract(beltAndStuff) + .substract(depots); + + scene.world.showSection(withoutBelt, Direction.DOWN); + ElementLink independentSection = + scene.world.showIndependentSection(depots, Direction.DOWN); + scene.world.moveSection(independentSection, util.vector.of(0, 0, 1), 0); + + BlockPos andesiteFunnel = util.grid.at(3, 2, 2); + BlockPos brassFunnel = util.grid.at(1, 2, 2); + ItemStack itemStack = AllItems.BRASS_INGOT.asStack(); + scene.idle(10); + + scene.overlay.showText(60) + .text("Andesite Funnels can only ever extract single items.") + .pointAt(util.vector.topOf(andesiteFunnel)) + .placeNearTarget(); + scene.idle(10); + scene.world.createItemOnBeltLike(andesiteFunnel.down() + .north(), Direction.SOUTH, itemStack); + scene.world.flapFunnels(util.select.position(andesiteFunnel), true); + scene.idle(60); + + scene.overlay.showText(60) + .text("Brass Funnels can extract up to a full stack.") + .pointAt(util.vector.topOf(brassFunnel)) + .placeNearTarget(); + scene.idle(10); + scene.world.createItemOnBeltLike(brassFunnel.down() + .north(), Direction.SOUTH, ItemHandlerHelper.copyStackWithSize(itemStack, 64)); + scene.world.flapFunnels(util.select.position(brassFunnel), true); + scene.idle(60); + + AxisAlignedBB filterSlot = new AxisAlignedBB(brassFunnel).grow(-.35, -.35, -.35) + .offset(0, 0.2, 0); + scene.overlay.chaseBoundingBoxOutline(PonderPalette.WHITE, filterSlot, filterSlot, 80); + scene.overlay.showControls(new InputWindowElement(util.vector.topOf(brassFunnel), Pointing.DOWN).scroll(), 60); + scene.idle(10); + scene.overlay.showText(80) + .text("Scrolling on the filter slot allows for precise control over the extracted stack size.") + .pointAt(filterSlot.getCenter()) + .placeNearTarget(); + scene.idle(90); + + // belt + scene.world.hideIndependentSection(independentSection, Direction.NORTH); + scene.world.hideSection(util.select.position(brassFunnel), Direction.UP); + scene.idle(20); + + scene.world.modifyBlock(brassFunnel, s -> s.cycle(BeltFunnelBlock.SHAPE), false); + scene.world.showSection(util.select.position(brassFunnel), Direction.DOWN); + scene.world.showSection(beltAndStuff, Direction.SOUTH); + scene.idle(10); + + ItemStack dirt = new ItemStack(Items.DIRT); + ItemStack gravel = new ItemStack(Items.GRAVEL); + ItemStack emerald = new ItemStack(Items.EMERALD); + + for (int i = 0; i < 14; i++) { + + if (i < 12) + scene.world.createItemOnBelt(andesiteFunnel.down(), Direction.SOUTH, + i % 3 == 0 ? dirt : i % 3 == 1 ? gravel : emerald); + scene.idle(10); + + if (i > 0 && (i < 3 || i % 3 == 0)) { + scene.world.removeItemsFromBelt(brassFunnel.down()); + scene.world.flapFunnels(util.select.position(brassFunnel), false); + } + + scene.world.modifyEntities(ItemEntity.class, e -> { + if (e.getY() < 1) + e.remove(); + }); + + if (i == 2) { + scene.overlay.chaseBoundingBoxOutline(PonderPalette.WHITE, filterSlot, filterSlot, 80); + scene.overlay + .showControls(new InputWindowElement(util.vector.topOf(brassFunnel), Pointing.DOWN).rightClick() + .withItem(emerald), 60); + scene.idle(10); + scene.overlay.showText(80) + .text("Using items on the filter slot will restrict the funnel to only transfer matching stacks.") + .pointAt(filterSlot.getCenter()) + .placeNearTarget(); + scene.world.setFilterData(util.select.position(brassFunnel), FunnelTileEntity.class, emerald); + } else + scene.idle(10); + + if (i == 8) + scene.markAsFinished(); + } + } + + public static void transposer(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("funnel_transfer", "Direct transfer"); + scene.configureBasePlate(0, 0, 5); + scene.world.showSection(util.select.layer(0), Direction.UP); + scene.idle(5); + + BlockPos funnelPos = util.grid.at(2, 2, 2); + Selection funnelSelect = util.select.position(funnelPos); + + ElementLink rightChest = + scene.world.showIndependentSection(util.select.position(0, 2, 2), Direction.DOWN); + ElementLink leftChest = + scene.world.showIndependentSection(util.select.position(4, 2, 2), Direction.DOWN); + scene.world.moveSection(rightChest, util.vector.of(2, 1, 0), 0); + scene.world.moveSection(leftChest, util.vector.of(-2, -1, 0), 0); + scene.idle(5); + + scene.world.showSection(funnelSelect, Direction.DOWN); + scene.idle(20); + + scene.overlay.showSelectionWithText(funnelSelect, 40) + .colored(PonderPalette.RED) + .text("Funnels cannot ever transfer between closed inventories directly.") + .placeNearTarget(); + scene.idle(50); + + scene.world.hideSection(funnelSelect, Direction.SOUTH); + scene.idle(20); + + scene.world.setBlocks(funnelSelect, AllBlocks.CHUTE.getDefaultState(), false); + scene.world.showSection(funnelSelect, Direction.NORTH); + scene.idle(10); + + scene.overlay.showText(40) + .colored(PonderPalette.GREEN) + .text("Chutes or Smart chutes might be more suitable for such purposes.") + .pointAt(util.vector.centerOf(funnelPos)) + .placeNearTarget(); + scene.idle(50); + + scene.world.hideSection(funnelSelect, Direction.UP); + scene.world.hideIndependentSection(leftChest, Direction.UP); + scene.world.hideIndependentSection(rightChest, Direction.UP); + scene.idle(20); + + Selection belt = util.select.layer(1); + scene.world.setBlocks(funnelSelect, Blocks.AIR.getDefaultState(), false); + scene.world.showSection(belt, Direction.DOWN); + scene.world.showSection(util.select.fromTo(0, 2, 2, 4, 2, 2), Direction.DOWN); + scene.overlay.showText(120) + .colored(PonderPalette.GREEN) + .text("Same applies for horizontal movement.\nA mechanical belt should help here.") + .pointAt(util.vector.topOf(1, 2, 2)) + .placeNearTarget(); + + scene.markAsFinished(); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/GantryScenes.java b/src/main/java/com/simibubi/create/foundation/ponder/content/GantryScenes.java new file mode 100644 index 000000000..152d7c781 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/GantryScenes.java @@ -0,0 +1,295 @@ +package com.simibubi.create.foundation.ponder.content; + +import com.simibubi.create.foundation.ponder.ElementLink; +import com.simibubi.create.foundation.ponder.SceneBuilder; +import com.simibubi.create.foundation.ponder.SceneBuildingUtil; +import com.simibubi.create.foundation.ponder.Selection; +import com.simibubi.create.foundation.ponder.elements.WorldSectionElement; +import com.simibubi.create.foundation.utility.Iterate; + +import net.minecraft.block.RedstoneWireBlock; +import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; + +public class GantryScenes { + + public static void introForPinion(SceneBuilder scene, SceneBuildingUtil util) { + intro(scene, util, true); + } + + public static void introForShaft(SceneBuilder scene, SceneBuildingUtil util) { + intro(scene, util, false); + } + + private static void intro(SceneBuilder scene, SceneBuildingUtil util, boolean pinion) { + String id = "gantry_" + (pinion ? "carriage" : "shaft"); + String title = "Using Gantry " + (pinion ? "Carriages" : "Shafts"); + scene.title(id, title); + + scene.world.modifyKineticSpeed(util.select.everywhere(), f -> -2 * f); + scene.configureBasePlate(0, 0, 5); + scene.world.showSection(util.select.layer(0), Direction.UP); + scene.idle(10); + scene.world.showSection(util.select.layer(1), Direction.DOWN); + scene.idle(10); + ElementLink gantry = + scene.world.showIndependentSection(util.select.layer(2), Direction.DOWN); + scene.idle(10); + + BlockPos centralShaft = util.grid.at(2, 1, 2); + + scene.world.moveSection(gantry, util.vector.of(-4, 0, 0), 60); + + String text = pinion ? "Gantry Carriages can mount to and slide along a Gantry Shaft." + : "Gantry Shafts form the basis of a gantry setup. Attached Carriages will move along them."; + + scene.overlay.showText(80) + .text(text) + .pointAt(util.vector.centerOf(centralShaft)); + scene.idle(80); + + scene.world.hideIndependentSection(gantry, Direction.UP); + scene.idle(10); + gantry = scene.world.showIndependentSection(util.select.layer(2), Direction.DOWN); + Vec3d gantryTop = util.vector.topOf(4, 2, 2); + scene.world.modifyKineticSpeed(util.select.everywhere(), f -> 0f); + scene.overlay.showText(40) + .text("Gantry setups can move attached Blocks.") + .pointAt(gantryTop) + .placeNearTarget(); + scene.idle(30); + + Selection planks = util.select.position(5, 3, 1); + + scene.world.showSectionAndMerge(util.select.layersFrom(3) + .substract(planks), Direction.DOWN, gantry); + scene.idle(10); + scene.world.showSectionAndMerge(planks, Direction.SOUTH, gantry); + scene.idle(10); + scene.effects.superGlue(util.grid.at(5, 3, 1), Direction.SOUTH, true); + + scene.idle(20); + scene.overlay.showText(80) + .sharedText("movement_anchors") + .pointAt(gantryTop) + .placeNearTarget(); + scene.idle(80); + + scene.world.modifyKineticSpeed(util.select.layer(0), f -> 32f); + scene.world.modifyKineticSpeed(util.select.layer(1), f -> -64f); + + scene.world.moveSection(gantry, util.vector.of(-4, 0, 0), 60); + scene.idle(20); + scene.markAsFinished(); + } + + public static void redstone(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("gantry_redstone", "Gantry Power Propagation"); + scene.world.modifyKineticSpeed(util.select.everywhere(), f -> -f); + + Selection leverRedstone = util.select.fromTo(3, 1, 0, 3, 1, 1); + Selection shaft = util.select.fromTo(0, 1, 2, 4, 1, 2); + Selection shaftAndCog = util.select.fromTo(0, 1, 2, 5, 1, 2); + + scene.configureBasePlate(0, 0, 5); + scene.world.showSection(util.select.layer(0) + .add(leverRedstone), Direction.UP); + + scene.idle(10); + scene.world.showSection(shaftAndCog, Direction.DOWN); + scene.idle(10); + + BlockPos gantryPos = util.grid.at(4, 2, 2); + ElementLink gantry = + scene.world.showIndependentSection(util.select.position(gantryPos), Direction.DOWN); + scene.idle(15); + scene.world.moveSection(gantry, util.vector.of(-3, 0, 0), 40); + scene.idle(40); + + scene.world.toggleRedstonePower(shaft); + scene.world.toggleRedstonePower(util.select.position(3, 1, 0)); + scene.world.toggleRedstonePower(util.select.position(3, 1, 1)); + scene.effects.indicateRedstone(util.grid.at(3, 1, 0)); + scene.world.modifyKineticSpeed(util.select.position(gantryPos), f -> 32f); + scene.idle(40); + + BlockPos cogPos = util.grid.at(1, 2, 1); + scene.overlay.showText(60) + .colored(PonderPalette.RED) + .pointAt(util.vector.centerOf(cogPos.down() + .south())) + .text("Redstone-powered gantry shafts stop moving their carriages") + .placeNearTarget(); + scene.idle(70); + + Selection cogSelection = util.select.position(cogPos); + scene.world.showSection(cogSelection, Direction.SOUTH); + scene.world.modifyKineticSpeed(cogSelection, f -> 32f); + scene.overlay.showText(180) + .colored(PonderPalette.GREEN) + .pointAt(util.vector.blockSurface(cogPos, Direction.NORTH)) + .text("Instead, its rotational force is relayed to the carriages' output shaft") + .placeNearTarget(); + scene.idle(10); + + scene.effects.rotationSpeedIndicator(cogPos); + scene.markAsFinished(); + } + + public static void direction(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("gantry_direction", "Gantry Movement Direction"); + scene.configureBasePlate(0, 0, 5); + scene.world.modifyKineticSpeed(util.select.everywhere(), f -> -f); + scene.world.showSection(util.select.layer(0), Direction.UP); + scene.idle(10); + + Selection shaftAndGearshiftAndLever = util.select.fromTo(0, 1, 2, 5, 2, 2); + Selection shafts = util.select.fromTo(0, 1, 2, 3, 1, 2); + + scene.world.showSection(shaftAndGearshiftAndLever, Direction.DOWN); + scene.overlay.showText(60) + .text("Gantry Shafts can have opposite orientations") + .pointAt(util.vector.of(2, 1.5, 2.5)) + .placeNearTarget(); + scene.idle(60); + + ElementLink gantry1 = + scene.world.showIndependentSection(util.select.position(0, 1, 3), Direction.NORTH); + ElementLink gantry2 = + scene.world.showIndependentSection(util.select.position(3, 1, 3), Direction.NORTH); + scene.idle(10); + + scene.world.moveSection(gantry1, util.vector.of(1, 0, 0), 20); + scene.world.moveSection(gantry2, util.vector.of(-1, 0, 0), 20); + + scene.overlay.showText(80) + .text("The movement direction of carriages depend on their shafts' orientation") + .pointAt(util.vector.topOf(1, 1, 3)) + .placeNearTarget(); + scene.idle(80); + + BlockPos lastShaft = util.grid.at(0, 1, 2); + boolean flip = true; + + for (int i = 0; i < 3; i++) { + scene.world.modifyBlocks(util.select.fromTo(4, 1, 2, 4, 2, 2), s -> s.cycle(BlockStateProperties.POWERED), + false); + scene.effects.indicateRedstone(util.grid.at(4, 2, 2)); + scene.world.moveSection(gantry1, util.vector.of(flip ? -1 : 1, 0, 0), 20); + scene.world.moveSection(gantry2, util.vector.of(flip ? 1 : -1, 0, 0), 20); + scene.world.modifyKineticSpeed(shafts, f -> -f); + scene.effects.rotationDirectionIndicator(lastShaft.east(flip ? 1 : 0)); + scene.idle(20); + + if (i == 0) { + scene.overlay.showText(80) + .text("...as well as the rotation direction of the shaft") + .pointAt(util.vector.blockSurface(lastShaft, Direction.WEST)) + .placeNearTarget(); + } + + scene.idle(30); + flip = !flip; + } + + Selection kinetics = util.select.fromTo(0, 2, 3, 3, 3, 3); + Selection gears1 = util.select.fromTo(0, 1, 3, 0, 3, 3); + Selection gears2 = util.select.fromTo(3, 1, 3, 3, 3, 3); + + scene.world.showSection(kinetics, Direction.DOWN); + scene.world.showSection(util.select.fromTo(0, 1, 0, 4, 1, 1), Direction.SOUTH); + scene.idle(20); + + BlockPos leverPos = util.grid.at(4, 1, 0); + scene.world.modifyBlocks(util.select.fromTo(1, 1, 0, 3, 1, 1), + s -> s.has(RedstoneWireBlock.POWER) ? s.with(RedstoneWireBlock.POWER, 15) : s, false); + scene.world.toggleRedstonePower(util.select.position(leverPos)); + scene.world.toggleRedstonePower(shafts); + scene.effects.indicateRedstone(leverPos); + scene.world.modifyKineticSpeed(gears1, f -> -32f); + scene.world.modifyKineticSpeed(gears2, f -> 32f); + + scene.idle(20); + scene.overlay.showText(120) + .text("Same rules apply for the propagated rotation") + .pointAt(util.vector.topOf(0, 3, 3)) + .placeNearTarget(); + scene.idle(20); + + for (boolean flip2 : Iterate.trueAndFalse) { + scene.effects.rotationDirectionIndicator(util.grid.at(0, 3, 3)); + scene.effects.rotationDirectionIndicator(util.grid.at(3, 3, 3)); + + scene.idle(60); + scene.world.modifyBlocks(util.select.fromTo(4, 1, 2, 4, 2, 2), s -> s.cycle(BlockStateProperties.POWERED), + false); + scene.effects.indicateRedstone(util.grid.at(4, 2, 2)); + scene.world.modifyKineticSpeed(gears1, f -> -f); + scene.world.modifyKineticSpeed(gears2, f -> -f); + + if (!flip2) { + scene.effects.rotationDirectionIndicator(util.grid.at(0, 3, 3)); + scene.effects.rotationDirectionIndicator(util.grid.at(3, 3, 3)); + scene.markAsFinished(); + } + } + + } + + public static void subgantry(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("gantry_cascaded", "Cascaded Gantries"); + scene.configureBasePlate(0, 0, 5); + scene.world.modifyKineticSpeed(util.select.everywhere(), f -> -2 * f); + scene.world.showSection(util.select.layer(0) + .add(util.select.column(5, 3)) + .add(util.select.fromTo(2, 1, 3, 4, 1, 3)), Direction.UP); + scene.idle(10); + + BlockPos gantryPos = util.grid.at(5, 1, 2); + BlockPos gantryPos2 = util.grid.at(3, 2, 2); + ElementLink gantry = + scene.world.showIndependentSection(util.select.position(gantryPos), Direction.SOUTH); + scene.idle(5); + + scene.world.showSectionAndMerge(util.select.fromTo(0, 1, 2, 4, 1, 2), Direction.EAST, gantry); + scene.idle(15); + + scene.world.moveSection(gantry, util.vector.of(0, 2, 0), 40); + scene.overlay.showText(60) + .text("Gantry shafts attach to a carriage without the need of super glue") + .independent(20); + scene.idle(40); + + scene.world.modifyKineticSpeed(util.select.everywhere(), f -> -f); + scene.world.moveSection(gantry, util.vector.of(0, -2, 0), 40); + scene.idle(40); + + ElementLink secondGantry = + scene.world.showIndependentSection(util.select.position(gantryPos2), Direction.DOWN); + scene.idle(15); + scene.overlay.showText(60) + .text("Same applies for carriages on moved Gantry Shafts") + .independent(20); + scene.idle(15); + + scene.world.moveSection(gantry, util.vector.of(0, 2, 0), 40); + scene.world.moveSection(secondGantry, util.vector.of(0, 2, 0), 40); + + scene.idle(40); + BlockPos leverPos = util.grid.at(2, 1, 3); + scene.world.toggleRedstonePower(util.select.position(leverPos)); + scene.world.toggleRedstonePower(util.select.fromTo(3, 1, 3, 4, 1, 3)); + scene.world.toggleRedstonePower(util.select.fromTo(5, 1, 3, 5, 4, 3)); + scene.world.modifyKineticSpeed(util.select.fromTo(0, 1, 2, 5, 1, 2), f -> -32f); + scene.effects.indicateRedstone(leverPos); + scene.world.moveSection(secondGantry, util.vector.of(-3, 0, 0), 60); + + scene.idle(20); + scene.overlay.showText(120) + .text("Thus, a gantry system can be cascaded to cover multiple axes of movement") + .independent(20); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/KineticsScenes.java b/src/main/java/com/simibubi/create/foundation/ponder/content/KineticsScenes.java new file mode 100644 index 000000000..28ff3e051 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/KineticsScenes.java @@ -0,0 +1,690 @@ +package com.simibubi.create.foundation.ponder.content; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.content.contraptions.components.crank.ValveHandleBlock; +import com.simibubi.create.content.contraptions.components.waterwheel.WaterWheelBlock; +import com.simibubi.create.content.contraptions.relays.elementary.CogWheelBlock; +import com.simibubi.create.content.contraptions.relays.elementary.ShaftBlock; +import com.simibubi.create.content.contraptions.relays.encased.EncasedShaftBlock; +import com.simibubi.create.foundation.ponder.ElementLink; +import com.simibubi.create.foundation.ponder.SceneBuilder; +import com.simibubi.create.foundation.ponder.SceneBuildingUtil; +import com.simibubi.create.foundation.ponder.Selection; +import com.simibubi.create.foundation.ponder.elements.InputWindowElement; +import com.simibubi.create.foundation.ponder.elements.WorldSectionElement; +import com.simibubi.create.foundation.utility.Pointing; +import com.tterrag.registrate.util.entry.BlockEntry; + +import net.minecraft.block.BlockState; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.util.Direction; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.Vec3i; + +public class KineticsScenes { + + public static void shaftAsRelay(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("shaft", "Relaying rotational force using Shafts"); + scene.configureBasePlate(0, 0, 5); + scene.world.showSection(util.select.layer(0), Direction.UP); + + BlockPos gaugePos = util.grid.at(0, 1, 2); + Selection gauge = util.select.position(gaugePos); + scene.world.showSection(gauge, Direction.UP); + scene.world.setKineticSpeed(gauge, 0); + + scene.idle(5); + scene.world.showSection(util.select.position(5, 1, 2), Direction.DOWN); + scene.idle(10); + + for (int i = 4; i >= 1; i--) { + if (i == 2) + scene.rotateCameraY(70); + scene.idle(5); + scene.world.showSection(util.select.position(i, 1, 2), Direction.DOWN); + } + + scene.world.setKineticSpeed(gauge, 64); + scene.effects.indicateSuccess(gaugePos); + scene.idle(10); + scene.overlay.showText(1000) + .text("Shafts will relay rotation in a straight line.") + .pointAt(util.vector.of(3, 1.5, 2.5)); + + scene.idle(20); + scene.markAsFinished(); + } + + public static void shaftsCanBeEncased(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("shaft_casing", "Encasing Shafts"); + scene.configureBasePlate(0, 0, 5); + scene.showBasePlate(); + + Selection shaft = util.select.cuboid(new BlockPos(0, 1, 2), new Vec3i(5, 0, 2)); + Selection andesite = util.select.position(3, 1, 2); + Selection brass = util.select.position(1, 1, 2); + + scene.world.showSection(shaft, Direction.DOWN); + scene.idle(20); + + BlockEntry andesiteEncased = AllBlocks.ANDESITE_ENCASED_SHAFT; + ItemStack andesiteCasingItem = AllBlocks.ANDESITE_CASING.asStack(); + + scene.overlay.showControls(new InputWindowElement(util.vector.topOf(3, 1, 2), Pointing.DOWN).rightClick() + .withItem(andesiteCasingItem), 60); + scene.idle(7); + scene.world.setBlocks(andesite, andesiteEncased.getDefaultState() + .with(EncasedShaftBlock.AXIS, Axis.X), true); + scene.world.setKineticSpeed(shaft, 32); + scene.idle(10); + + BlockEntry brassEncased = AllBlocks.BRASS_ENCASED_SHAFT; + ItemStack brassCasingItem = AllBlocks.BRASS_CASING.asStack(); + + scene.overlay.showControls(new InputWindowElement(util.vector.topOf(1, 0, 2), Pointing.UP).rightClick() + .withItem(brassCasingItem), 60); + scene.idle(7); + scene.world.setBlocks(brass, brassEncased.getDefaultState() + .with(EncasedShaftBlock.AXIS, Axis.X), true); + scene.world.setKineticSpeed(shaft, 32); + + scene.idle(10); + scene.overlay.showText(1000) + .text("Brass or Andesite Casing can be used to decorate Shafts") + .pointAt(util.vector.topOf(1, 1, 2)); + } + + public static void cogAsRelay(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("cogwheel", "Relaying rotational force using Cogwheels"); + scene.configureBasePlate(0, 0, 5); + BlockPos gauge = util.grid.at(4, 1, 1); + Selection gaugeSelect = util.select.position(gauge); + scene.world.showSection(util.select.layer(0), Direction.UP); + scene.world.showSection(gaugeSelect, Direction.UP); + scene.world.setKineticSpeed(gaugeSelect, 0); + scene.idle(5); + scene.world.showSection(util.select.fromTo(1, 1, 3, 1, 1, 5), Direction.DOWN); + scene.idle(10); + + for (int i = 1; i <= 4; i++) { + scene.idle(5); + if (i == 2) + scene.world.showSection(util.select.position(0, 1, 2), Direction.DOWN); + scene.world.showSection(util.select.position(i, 1, 2), Direction.DOWN); + } + + scene.world.setKineticSpeed(gaugeSelect, 64); + scene.effects.indicateSuccess(gauge); + scene.idle(10); + scene.overlay.showText(60) + .text("Cogwheels will relay rotation to other adjacent cogwheels") + .pointAt(util.vector.blockSurface(util.grid.at(0, 1, 2), Direction.EAST)); + + scene.idle(60); + scene.world.showSection(util.select.fromTo(1, 1, 1, 2, 1, 1), Direction.SOUTH); + scene.idle(10); + scene.effects.rotationDirectionIndicator(util.grid.at(1, 1, 1)); + scene.effects.rotationDirectionIndicator(util.grid.at(2, 1, 1)); + scene.idle(20); + scene.overlay.showText(100) + .text("Neighbouring shafts connected like this will rotate in opposite directions") + .placeNearTarget() + .pointAt(util.vector.blockSurface(util.grid.at(1, 1, 2), Direction.NORTH)); + + } + + public static void largeCogAsRelay(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("large_cogwheel", "Relaying rotational force using Large Cogwheels"); + scene.configureBasePlate(1, 1, 5); + scene.world.setBlock(util.grid.at(4, 2, 3), AllBlocks.LARGE_COGWHEEL.getDefaultState() + .with(CogWheelBlock.AXIS, Axis.X), false); + + scene.showBasePlate(); + scene.idle(5); + scene.world.showSection(util.select.layer(1), Direction.DOWN); + scene.idle(5); + scene.world.showSection(util.select.position(3, 2, 4), Direction.NORTH); + + for (int i = 3; i >= 1; i--) { + scene.idle(5); + if (i == 3) + scene.world.showSection(util.select.position(3, 2, 5), Direction.DOWN); + scene.world.showSection(util.select.position(3, 2, i), Direction.DOWN); + } + + scene.overlay.showText(70) + .text("Large cogwheels can connect to each other at right angles") + .placeNearTarget() + .pointAt(util.vector.centerOf(3, 1, 4)); + scene.idle(70); + scene.world.hideSection(util.select.fromTo(3, 2, 1, 3, 2, 5), Direction.SOUTH); + + scene.idle(15); + scene.world.modifyBlock(util.grid.at(3, 2, 3), s -> s.with(ShaftBlock.AXIS, Axis.X), false); + scene.world.setKineticSpeed(util.select.fromTo(1, 2, 3, 5, 2, 3), 16); + scene.world.showSection(util.select.position(4, 2, 3), Direction.WEST); + + for (int i = 3; i >= 1; i--) { + scene.idle(5); + if (i == 3) + scene.world.showSection(util.select.position(5, 2, 3), Direction.DOWN); + scene.world.showSection(util.select.position(i, 2, 3), Direction.DOWN); + } + + scene.idle(5); + scene.overlay.showText(90) + .text("It will help relaying conveyed speed to other axes of rotation") + .placeNearTarget() + .pointAt(util.vector.blockSurface(util.grid.at(1, 2, 3), Direction.WEST)); + scene.effects.rotationSpeedIndicator(util.grid.at(3, 1, 3)); + scene.effects.rotationSpeedIndicator(util.grid.at(4, 2, 3)); + + } + + public static void cogsSpeedUp(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("cog_speedup", "Gearshifting with Cogs"); + scene.configureBasePlate(0, 0, 5); + scene.world.showSection(util.select.layer(0), Direction.UP); + scene.idle(5); + scene.world.showSection(util.select.fromTo(5, 1, 2, 4, 1, 2), Direction.DOWN); + scene.idle(10); + + BlockPos lowerCog = util.grid.at(3, 1, 2); + BlockPos upperCog = util.grid.at(3, 2, 3); + BlockState largeCogState = AllBlocks.LARGE_COGWHEEL.getDefaultState() + .with(CogWheelBlock.AXIS, Axis.X); + BlockState smallCogState = AllBlocks.COGWHEEL.getDefaultState() + .with(CogWheelBlock.AXIS, Axis.X); + + scene.world.setBlock(lowerCog, largeCogState, false); + scene.world.setBlock(upperCog, smallCogState, false); + BlockPos upperShaftEnd = upperCog.west(3); + BlockPos lowerShaftEnd = lowerCog.west(3); + + scene.world.setKineticSpeed(util.select.fromTo(upperCog, upperShaftEnd), -64); + scene.world.showSection(util.select.fromTo(lowerCog, upperCog), Direction.EAST); + scene.overlay.showText(60) + .text("Large and Small cogs can be connected diagonally") + .placeNearTarget() + .pointAt(util.vector.blockSurface(upperCog, Direction.WEST)); + scene.idle(80); + + Selection gaugesSelect = util.select.fromTo(0, 1, 2, 2, 2, 3); + scene.world.showSection(gaugesSelect, Direction.DOWN); + scene.overlay.showText(60) + .text("Shifting from large to small cogs, the conveyed speed will be doubled") + .colored(PonderPalette.GREEN) + .placeNearTarget() + .pointAt(util.vector.blockSurface(util.grid.at(1, 2, 3), Direction.NORTH)); + scene.idle(10); + scene.effects.rotationSpeedIndicator(upperCog); + scene.idle(60); + + scene.overlay.showText(30) + .sharedText("rpm32") + .colored(PonderPalette.FAST) + .placeNearTarget() + .pointAt(util.vector.blockSurface(upperShaftEnd, Direction.WEST)); + scene.idle(5); + scene.overlay.showText(30) + .sharedText("rpm16") + .colored(PonderPalette.MEDIUM) + .placeNearTarget() + .pointAt(util.vector.blockSurface(lowerShaftEnd, Direction.WEST)); + scene.idle(45); + + scene.world.setKineticSpeed(util.select.fromTo(lowerCog, upperShaftEnd), 0); + ElementLink cogs = + scene.world.makeSectionIndependent(util.select.fromTo(lowerCog, upperCog)); + scene.world.moveSection(cogs, util.vector.of(0, 1, 0), 5); + scene.idle(5); + scene.world.rotateSection(cogs, 180, 0, 0, 10); + scene.idle(10); + scene.world.setBlock(lowerCog, smallCogState, false); + scene.world.setBlock(upperCog, largeCogState, false); + scene.world.rotateSection(cogs, 180, 0, 0, 0); + scene.world.moveSection(cogs, util.vector.of(0, -1, 0), 5); + scene.idle(5); + + scene.world.setKineticSpeed(util.select.fromTo(lowerCog, lowerShaftEnd), 32); + scene.world.setKineticSpeed(util.select.fromTo(upperCog, upperShaftEnd), -16); + + scene.overlay.showText(80) + .text("Shifting the opposite way, the conveyed speed will be halved") + .colored(PonderPalette.RED) + .placeNearTarget() + .pointAt(util.vector.blockSurface(util.grid.at(1, 2, 3), Direction.NORTH)); + scene.idle(10); + scene.effects.rotationSpeedIndicator(upperCog); + scene.idle(80); + + scene.overlay.showText(60) + .sharedText("rpm8") + .colored(PonderPalette.SLOW) + .placeNearTarget() + .pointAt(util.vector.blockSurface(upperShaftEnd, Direction.WEST)); + scene.idle(5); + scene.overlay.showText(60) + .sharedText("rpm16") + .colored(PonderPalette.MEDIUM) + .placeNearTarget() + .pointAt(util.vector.blockSurface(lowerShaftEnd, Direction.WEST)); + scene.idle(40); + } + + public static void gearbox(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("gearbox", "Relaying rotational force using Gearboxes"); + scene.configureBasePlate(1, 1, 5); + scene.world.showSection(util.select.layer(0), Direction.UP); + scene.world.showSection(util.select.fromTo(4, 1, 6, 3, 2, 5), Direction.UP); + scene.idle(10); + + BlockPos largeCogBack = util.grid.at(3, 2, 4); + BlockPos largeCogLeft = util.grid.at(4, 2, 3); + BlockPos largeCogFront = util.grid.at(3, 2, 2); + BlockPos largeCogRight = util.grid.at(2, 2, 3); + + scene.world.showSection(util.select.position(largeCogBack), Direction.SOUTH); + scene.idle(5); + scene.world.showSection(util.select.position(largeCogLeft), Direction.WEST); + scene.world.showSection(util.select.position(largeCogLeft.east()), Direction.WEST); + scene.world.showSection(util.select.position(largeCogRight), Direction.EAST); + scene.world.showSection(util.select.position(largeCogRight.west()), Direction.EAST); + scene.idle(5); + scene.world.showSection(util.select.position(largeCogFront), Direction.SOUTH); + scene.world.showSection(util.select.position(largeCogFront.north()), Direction.SOUTH); + + scene.idle(10); + + scene.overlay.showText(80) + .colored(PonderPalette.RED) + .pointAt(util.vector.blockSurface(largeCogRight.west(), Direction.WEST)) + .placeNearTarget() + .text("Jumping between axes of rotation can get bulky quickly"); + scene.idle(80); + Selection gearbox = util.select.position(3, 2, 3); + scene.world.hideSection(util.select.fromTo(4, 2, 2, 2, 2, 4) + .substract(gearbox), Direction.UP); + scene.idle(20); + + BlockState defaultState = AllBlocks.SHAFT.getDefaultState(); + BlockState cogState = AllBlocks.COGWHEEL.getDefaultState(); + scene.world.setBlock(largeCogBack, defaultState.with(CogWheelBlock.AXIS, Axis.Z), false); + scene.world.setBlock(largeCogFront, defaultState.with(CogWheelBlock.AXIS, Axis.Z), false); + scene.world.setBlock(largeCogRight, defaultState.with(CogWheelBlock.AXIS, Axis.X), false); + scene.world.setBlock(largeCogLeft, defaultState.with(CogWheelBlock.AXIS, Axis.X), false); + scene.world.showSection(util.select.fromTo(4, 2, 2, 2, 2, 4), Direction.DOWN); + + scene.idle(20); + scene.overlay.showText(80) + .colored(PonderPalette.GREEN) + .pointAt(util.vector.topOf(3, 2, 3)) + .placeNearTarget() + .text("A gearbox is the more compact equivalent of this setup"); + + scene.idle(90); + scene.world.setBlock(largeCogFront.north(), cogState.with(CogWheelBlock.AXIS, Axis.Z), true); + scene.world.setBlock(largeCogRight.west(), cogState.with(CogWheelBlock.AXIS, Axis.X), true); + scene.idle(10); + scene.effects.rotationDirectionIndicator(largeCogFront.north()); + scene.effects.rotationDirectionIndicator(largeCogRight.west()); + scene.idle(15); + scene.overlay.showText(60) + .pointAt(util.vector.of(3, 2.5, 3)) + .placeNearTarget() + .text("Shafts around corners rotate in mirrored directions"); + + scene.idle(70); + + scene.world.hideSection(util.select.fromTo(1, 2, 3, 2, 2, 3), Direction.WEST); + scene.world.hideSection(util.select.fromTo(4, 2, 3, 5, 2, 3), Direction.EAST); + scene.world.setBlock(largeCogBack.south(), cogState.with(CogWheelBlock.AXIS, Axis.Z), true); + scene.idle(10); + + scene.effects.rotationDirectionIndicator(largeCogFront.north()); + scene.effects.rotationDirectionIndicator(largeCogBack.south()); + scene.idle(15); + scene.overlay.showText(60) + .pointAt(util.vector.centerOf(3, 2, 5)) + .placeNearTarget() + .text("Straight connections will be reversed"); + + } + + public static void clutch(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("clutch", "Controlling rotational force using a Clutch"); + scene.configureBasePlate(0, 0, 5); + scene.world.showSection(util.select.layer(0), Direction.UP); + BlockPos leverPos = util.grid.at(3, 1, 0); + scene.world.showSection(util.select.fromTo(leverPos, leverPos.south()), Direction.UP); + + BlockPos gaugePos = util.grid.at(0, 1, 2); + Selection gauge = util.select.position(gaugePos); + scene.world.showSection(gauge, Direction.UP); + scene.world.setKineticSpeed(gauge, 0); + + scene.idle(5); + scene.world.showSection(util.select.position(5, 1, 2), Direction.DOWN); + scene.idle(10); + + for (int i = 4; i >= 1; i--) { + scene.idle(5); + scene.world.showSection(util.select.position(i, 1, 2), Direction.DOWN); + } + + BlockPos clutch = util.grid.at(3, 1, 2); + + scene.world.setKineticSpeed(gauge, 32); + scene.effects.indicateSuccess(gaugePos); + scene.idle(10); + scene.overlay.showText(50) + .text("Clutches will relay rotation in a straight line") + .placeNearTarget() + .pointAt(util.vector.topOf(clutch)); + + scene.idle(60); + scene.world.toggleRedstonePower(util.select.fromTo(leverPos, leverPos.south(2))); + scene.effects.indicateRedstone(leverPos); + scene.world.setKineticSpeed(util.select.fromTo(0, 1, 2, 2, 1, 2), 0); + scene.idle(10); + + scene.idle(10); + scene.overlay.showText(50) + .colored(PonderPalette.RED) + .text("When powered by Redstone, it breaks the connection") + .placeNearTarget() + .pointAt(util.vector.topOf(clutch)); + + scene.idle(70); + scene.world.toggleRedstonePower(util.select.fromTo(leverPos, leverPos.south(2))); + scene.effects.indicateRedstone(leverPos); + scene.world.setKineticSpeed(util.select.fromTo(0, 1, 2, 2, 1, 2), 32); + scene.effects.indicateSuccess(gaugePos); + } + + public static void gearshift(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("gearshift", "Controlling rotational force using a Gearshift"); + scene.configureBasePlate(0, 0, 5); + scene.world.showSection(util.select.layer(0), Direction.UP); + BlockPos leverPos = util.grid.at(3, 1, 0); + scene.world.showSection(util.select.fromTo(leverPos, leverPos.south()), Direction.UP); + + scene.idle(5); + scene.world.showSection(util.select.position(5, 1, 2), Direction.DOWN); + scene.idle(10); + + for (int i = 4; i >= 1; i--) { + scene.idle(5); + scene.world.showSection(util.select.position(i, 1, 2), Direction.DOWN); + } + + BlockPos gearshift = util.grid.at(3, 1, 2); + scene.idle(10); + scene.overlay.showText(50) + .placeNearTarget() + .text("Gearshifts will relay rotation in a straight line") + .pointAt(util.vector.topOf(gearshift)); + + scene.idle(60); + scene.world.toggleRedstonePower(util.select.fromTo(leverPos, leverPos.south(2))); + scene.effects.indicateRedstone(leverPos); + scene.world.modifyKineticSpeed(util.select.fromTo(0, 1, 2, 2, 2, 2), f -> -f); + scene.effects.rotationDirectionIndicator(gearshift.east(2)); + scene.effects.rotationDirectionIndicator(gearshift.west(2)); + scene.idle(30); + + scene.overlay.showText(50) + .colored(PonderPalette.RED) + .placeNearTarget() + .text("When powered by Redstone, it reverses the transmission") + .pointAt(util.vector.topOf(gearshift)); + + for (int i = 0; i < 3; i++) { + scene.idle(60); + scene.world.toggleRedstonePower(util.select.fromTo(leverPos, leverPos.south(2))); + scene.effects.indicateRedstone(leverPos); + scene.world.modifyKineticSpeed(util.select.fromTo(0, 1, 2, 2, 2, 2), f -> -f); + scene.effects.rotationDirectionIndicator(gearshift.east(2)); + scene.effects.rotationDirectionIndicator(gearshift.west(2)); + } + } + + public static void creativeMotor(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("creative_motor", "Generating Rotational Force using Creative Motors"); + scene.configureBasePlate(0, 0, 5); + scene.world.showSection(util.select.layer(0), Direction.UP); + + BlockPos motor = util.grid.at(3, 1, 2); + + for (int i = 0; i < 3; i++) { + scene.idle(5); + scene.world.showSection(util.select.position(1 + i, 1, 2), Direction.DOWN); + } + + scene.idle(10); + scene.effects.rotationSpeedIndicator(motor); + scene.overlay.showText(50) + .text("Creative motors are a compact and configurable source of Rotational Force") + .placeNearTarget() + .pointAt(util.vector.topOf(motor)); + scene.idle(50); + + scene.rotateCameraY(90); + scene.idle(20); + + Vec3d blockSurface = util.vector.blockSurface(motor, Direction.EAST); + AxisAlignedBB point = new AxisAlignedBB(blockSurface, blockSurface); + AxisAlignedBB expanded = point.grow(1 / 16f, 1 / 5f, 1 / 5f); + + scene.overlay.chaseBoundingBoxOutline(PonderPalette.WHITE, blockSurface, point, 1); + scene.idle(1); + scene.overlay.chaseBoundingBoxOutline(PonderPalette.WHITE, blockSurface, expanded, 60); + scene.overlay.showControls(new InputWindowElement(blockSurface, Pointing.DOWN).scroll(), 60); + scene.idle(20); + + scene.overlay.showText(50) + .text("Scrolling on the back panel changes the RPM of the motors' rotational output") + .placeNearTarget() + .pointAt(blockSurface); + scene.idle(10); + scene.world.modifyKineticSpeed(util.select.fromTo(1, 1, 2, 3, 1, 2), f -> 4 * f); + scene.idle(50); + + scene.effects.rotationSpeedIndicator(motor); + scene.rotateCameraY(-90); + } + + public static void waterWheel(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("water_wheel", "Generating Rotational Force using Water Wheels"); + scene.configureBasePlate(0, 0, 5); + scene.world.showSection(util.select.layer(0), Direction.UP); + scene.idle(5); + scene.world.showSection(util.select.fromTo(4, 1, 1, 4, 3, 3) + .add(util.select.fromTo(3, 1, 3, 3, 2, 3)), Direction.DOWN); + scene.world.setKineticSpeed(util.select.everywhere(), 0); + + BlockPos gaugePos = util.grid.at(0, 2, 2); + + for (int i = 0; i < 4; i++) { + scene.idle(5); + scene.world.showSection(util.select.fromTo(gaugePos.east(i) + .down(), gaugePos.east(i)), Direction.DOWN); + } + + scene.idle(10); + + for (int i = 0; i < 3; i++) { + scene.idle(5); + scene.world.showSection(util.select.position(3, 3, 3 - i), Direction.DOWN); + } + scene.world.setKineticSpeed(util.select.everywhere(), -12); + scene.effects.indicateSuccess(gaugePos); + for (int i = 0; i < 2; i++) { + scene.idle(5); + scene.world.showSection(util.select.position(3, 2 - i, 1), Direction.DOWN); + } + + BlockPos wheel = util.grid.at(3, 2, 2); + scene.effects.rotationSpeedIndicator(wheel); + scene.overlay.showText(50) + .text("Water Wheels draw force from adjacent Water Currents") + .placeNearTarget() + .pointAt(util.vector.topOf(wheel)); + scene.idle(50); + + AxisAlignedBB bb = new AxisAlignedBB(wheel).grow(.125f, 0, 0); + scene.overlay.chaseBoundingBoxOutline(PonderPalette.MEDIUM, new Object(), bb.offset(0, 1.2, 0) + .contract(0, .75, 0), 80); + scene.idle(5); + scene.overlay.chaseBoundingBoxOutline(PonderPalette.MEDIUM, new Object(), bb.offset(0, 0, 1.2) + .contract(0, 0, .75), 80); + scene.idle(5); + scene.overlay.chaseBoundingBoxOutline(PonderPalette.MEDIUM, new Object(), bb.offset(0, -1.2, 0) + .contract(0, -.75, 0), 80); + scene.idle(5); + scene.overlay.chaseBoundingBoxOutline(PonderPalette.MEDIUM, new Object(), bb.offset(0, 0, -1.2) + .contract(0, 0, -.75), 80); + scene.idle(5); + scene.overlay.showText(50) + .text("The more faces are powered, the faster the Water Wheel will rotate") + .colored(PonderPalette.MEDIUM) + .placeNearTarget() + .pointAt(util.vector.topOf(wheel)); + + scene.idle(80); + scene.rotateCameraY(-30); + scene.overlay.showText(70) + .text("The Wheels' blades should be oriented against the flow") + .placeNearTarget() + .pointAt(util.vector.topOf(wheel)); + scene.idle(80); + + ElementLink water = scene.world.makeSectionIndependent(util.select.fromTo(3, 1, 1, 3, 3, 1) + .add(util.select.fromTo(3, 3, 2, 3, 3, 3))); + ElementLink wheelElement = scene.world.makeSectionIndependent(util.select.position(wheel)); + + scene.world.setKineticSpeed(util.select.everywhere(), 0); + scene.world.moveSection(water, util.vector.of(0, 2, -2), 10); + scene.world.moveSection(wheelElement, util.vector.of(0, 1, -1), 10); + scene.idle(10); + scene.world.rotateSection(wheelElement, 0, 180, 0, 5); + scene.idle(10); + scene.world.modifyBlock(wheel, s -> s.with(WaterWheelBlock.HORIZONTAL_FACING, Direction.WEST), false); + scene.world.rotateSection(wheelElement, 0, -180, 0, 0); + scene.idle(1); + scene.world.moveSection(water, util.vector.of(0, -2, 2), 10); + scene.world.moveSection(wheelElement, util.vector.of(0, -1, 1), 10); + scene.idle(10); + scene.world.setKineticSpeed(util.select.everywhere(), -8); + + scene.overlay.showText(70) + .colored(PonderPalette.RED) + .text("Facing the opposite way, they will not be as effective") + .placeNearTarget() + .pointAt(util.vector.topOf(wheel)); + scene.idle(80); + + scene.world.setKineticSpeed(util.select.everywhere(), 0); + scene.world.moveSection(water, util.vector.of(0, 2, -2), 10); + scene.world.moveSection(wheelElement, util.vector.of(0, 1, -1), 10); + scene.idle(10); + scene.rotateCameraY(30); + scene.world.rotateSection(wheelElement, 0, 180, 0, 5); + scene.idle(10); + scene.world.modifyBlock(wheel, s -> s.with(WaterWheelBlock.HORIZONTAL_FACING, Direction.EAST), false); + scene.world.rotateSection(wheelElement, 0, -180, 0, 0); + scene.idle(1); + scene.world.moveSection(water, util.vector.of(0, -2, 2), 10); + scene.world.moveSection(wheelElement, util.vector.of(0, -1, 1), 10); + scene.idle(10); + scene.world.setKineticSpeed(util.select.everywhere(), -12); + scene.effects.indicateSuccess(gaugePos); + } + + public static void handCrank(SceneBuilder scene, SceneBuildingUtil util) { + manualSource(scene, util, true); + } + + public static void valveHandle(SceneBuilder scene, SceneBuildingUtil util) { + manualSource(scene, util, false); + scene.world.setKineticSpeed(util.select.everywhere(), 0); + scene.idle(20); + Vec3d centerOf = util.vector.centerOf(2, 2, 2); + scene.overlay.showControls(new InputWindowElement(centerOf, Pointing.DOWN).rightClick() + .withItem(new ItemStack(Items.BLUE_DYE)), 40); + scene.idle(7); + scene.world.modifyBlock(util.grid.at(2, 2, 2), s -> AllBlocks.DYED_VALVE_HANDLES[11].getDefaultState() + .with(ValveHandleBlock.FACING, Direction.UP), true); + scene.idle(10); + scene.overlay.showText(70) + .text("Valve handles can be dyed for aesthetic purposes") + .placeNearTarget() + .pointAt(centerOf); + } + + private static void manualSource(SceneBuilder scene, SceneBuildingUtil util, boolean handCrank) { + String name = handCrank ? "Hand Cranks" : "Valve Handles"; + scene.title(handCrank ? "hand_crank" : "valve_handle", "Generating Rotational Force using " + name); + scene.configureBasePlate(0, 0, 5); + scene.world.showSection(util.select.layer(0), Direction.UP); + scene.idle(5); + + BlockPos gaugePos = util.grid.at(1, 3, 3); + BlockPos handlePos = util.grid.at(2, 2, 2); + Selection handleSelect = util.select.position(handlePos); + + scene.world.showSection(util.select.layersFrom(1) + .substract(handleSelect), Direction.DOWN); + scene.idle(10); + scene.world.showSection(handleSelect, Direction.DOWN); + scene.idle(20); + + Vec3d centerOf = util.vector.centerOf(handlePos); + scene.overlay.showText(70) + .text(name + " can be used by players to apply rotational force manually") + .placeNearTarget() + .pointAt(centerOf); + scene.idle(80); + + scene.overlay.showControls(new InputWindowElement(centerOf, Pointing.DOWN).rightClick(), 40); + scene.idle(7); + scene.world.setKineticSpeed(util.select.everywhere(), handCrank ? 32 : 16); + scene.world.modifyKineticSpeed(util.select.column(1, 3), f -> f * -2); + scene.effects.rotationDirectionIndicator(handlePos); + scene.effects.indicateSuccess(gaugePos); + scene.idle(10); + scene.overlay.showText(50) + .text("Hold Right-Click to rotate it Counter-Clockwise") + .placeNearTarget() + .pointAt(centerOf); + scene.idle(70); + scene.overlay.showText(50) + .colored(handCrank ? PonderPalette.MEDIUM : PonderPalette.SLOW) + .text("Its conveyed speed is " + (handCrank ? "relatively high" : "slow and precise")) + .placeNearTarget() + .pointAt(centerOf); + scene.idle(70); + + scene.world.setKineticSpeed(util.select.everywhere(), 0); + scene.idle(10); + + scene.overlay.showControls(new InputWindowElement(centerOf, Pointing.DOWN).rightClick() + .whileSneaking(), 40); + scene.idle(7); + scene.world.setKineticSpeed(util.select.everywhere(), handCrank ? -32 : -16); + scene.world.modifyKineticSpeed(util.select.column(1, 3), f -> f * -2); + scene.effects.rotationDirectionIndicator(handlePos); + scene.effects.indicateSuccess(gaugePos); + scene.idle(10); + scene.overlay.showText(90) + .text("Sneak and Hold Right-Click to rotate it Clockwise") + .placeNearTarget() + .pointAt(centerOf); + scene.idle(90); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/MovementActorScenes.java b/src/main/java/com/simibubi/create/foundation/ponder/content/MovementActorScenes.java new file mode 100644 index 000000000..5203f0756 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/MovementActorScenes.java @@ -0,0 +1,189 @@ +package com.simibubi.create.foundation.ponder.content; + +import com.simibubi.create.AllItems; +import com.simibubi.create.content.contraptions.components.actors.PortableItemInterfaceTileEntity; +import com.simibubi.create.foundation.ponder.ElementLink; +import com.simibubi.create.foundation.ponder.SceneBuilder; +import com.simibubi.create.foundation.ponder.SceneBuildingUtil; +import com.simibubi.create.foundation.ponder.Selection; +import com.simibubi.create.foundation.ponder.elements.EntityElement; +import com.simibubi.create.foundation.ponder.elements.InputWindowElement; +import com.simibubi.create.foundation.ponder.elements.WorldSectionElement; +import com.simibubi.create.foundation.utility.Pointing; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.item.ItemEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; + +public class MovementActorScenes { + + public static void psiTransfer(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("portable_storage_interface", "Contraption Storage Exchange"); + scene.configureBasePlate(0, 0, 8); + scene.world.showSection(util.select.layer(0), Direction.UP); + scene.idle(5); + + BlockPos bearing = util.grid.at(5, 1, 2); + scene.world.showSection(util.select.position(bearing), Direction.DOWN); + scene.idle(5); + ElementLink contraption = + scene.world.showIndependentSection(util.select.fromTo(5, 2, 2, 6, 3, 2), Direction.DOWN); + scene.world.configureCenterOfRotation(contraption, util.vector.centerOf(bearing)); + scene.idle(10); + scene.world.rotateBearing(bearing, 360, 70); + scene.world.rotateSection(contraption, 0, 360, 0, 70); + scene.overlay.showText(60) + .pointAt(util.vector.topOf(bearing.up(2))) + .colored(PonderPalette.RED) + .placeNearTarget() + .text("Inventories on moving contraptions cannot be accessed by players."); + + scene.idle(70); + BlockPos psi = util.grid.at(4, 2, 2); + scene.world.showSectionAndMerge(util.select.position(psi), Direction.EAST, contraption); + scene.idle(13); + scene.effects.superGlue(psi, Direction.EAST, true); + + scene.overlay.showText(80) + .pointAt(util.vector.topOf(psi)) + .colored(PonderPalette.GREEN) + .placeNearTarget() + .text("This component can interact with storage without the need to stop the contraption."); + scene.idle(90); + + BlockPos psi2 = psi.west(2); + scene.world.showSection(util.select.position(psi2), Direction.DOWN); + scene.overlay.showSelectionWithText(util.select.position(psi.west()), 50) + .colored(PonderPalette.RED) + .placeNearTarget() + .text("Place a second one with a gap of 1 or 2 blocks inbetween"); + scene.idle(55); + + scene.world.rotateBearing(bearing, 360, 60); + scene.world.rotateSection(contraption, 0, 360, 0, 60); + scene.idle(20); + + scene.overlay.showText(40) + .placeNearTarget() + .pointAt(util.vector.of(3, 3, 2.5)) + .text("Whenever they pass by each other, they will engage in a connection"); + scene.idle(35); + + Selection both = util.select.fromTo(2, 2, 2, 4, 2, 2); + Class psiClass = PortableItemInterfaceTileEntity.class; + + scene.world.modifyTileNBT(both, psiClass, nbt -> { + nbt.putFloat("Distance", 1); + nbt.putFloat("Timer", 40); + }); + + scene.idle(20); + scene.overlay.showOutline(PonderPalette.GREEN, psi, util.select.fromTo(5, 3, 2, 6, 3, 2), 80); + scene.idle(10); + + scene.overlay.showSelectionWithText(util.select.position(psi2), 70) + .placeNearTarget() + .colored(PonderPalette.GREEN) + .text("While engaged, the stationary interface will represent ALL inventories on the contraption"); + + scene.idle(80); + + BlockPos hopper = util.grid.at(2, 3, 2); + scene.world.showSection(util.select.position(hopper), Direction.DOWN); + scene.overlay.showText(70) + .placeNearTarget() + .pointAt(util.vector.topOf(hopper)) + .text("Items can now be inserted..."); + + ItemStack itemStack = AllItems.COPPER_INGOT.asStack(); + Vec3d entitySpawn = util.vector.topOf(hopper.up(3)); + + ElementLink entity1 = + scene.world.createItemEntity(entitySpawn, util.vector.of(0, 0.2, 0), itemStack); + scene.idle(10); + ElementLink entity2 = + scene.world.createItemEntity(entitySpawn, util.vector.of(0, 0.2, 0), itemStack); + scene.idle(10); + scene.world.modifyEntity(entity1, Entity::remove); + scene.idle(10); + scene.world.modifyEntity(entity2, Entity::remove); + + scene.overlay + .showControls(new InputWindowElement(util.vector.topOf(6, 3, 2), Pointing.DOWN).withItem(itemStack), 40); + + scene.idle(30); + scene.world.hideSection(util.select.position(hopper), Direction.UP); + scene.idle(15); + + BlockPos beltPos = util.grid.at(1, 1, 2); + scene.world.showSection(util.select.fromTo(0, 1, 0, 1, 2, 6), Direction.DOWN); + scene.idle(10); + scene.world.createItemOnBelt(beltPos, Direction.EAST, itemStack.copy()); + scene.overlay.showText(40) + .placeNearTarget() + .pointAt(util.vector.topOf(beltPos.up())) + .text("...or extracted from the contraption"); + scene.idle(15); + scene.world.createItemOnBelt(beltPos, Direction.EAST, itemStack); + + scene.idle(20); + scene.world.modifyEntities(ItemEntity.class, Entity::remove); + scene.idle(15); + scene.world.modifyEntities(ItemEntity.class, Entity::remove); + + scene.overlay.showText(120) + .placeNearTarget() + .pointAt(util.vector.topOf(psi2)) + .text("After no items have been exchanged for a while, the contraption will continue on its way"); + scene.world.modifyTileNBT(both, psiClass, nbt -> nbt.putFloat("Timer", 9)); + + scene.idle(15); + scene.markAsFinished(); + scene.world.rotateBearing(bearing, 270, 120); + scene.world.rotateSection(contraption, 0, 270, 0, 120); + } + + public static void psiRedstone(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("portable_storage_interface_redstone", "Redstone Control"); + scene.configureBasePlate(0, 0, 6); + + Class psiClass = PortableItemInterfaceTileEntity.class; + Selection psis = util.select.fromTo(1, 1, 3, 1, 3, 3); + scene.world.modifyTileNBT(psis, psiClass, nbt -> { + nbt.putFloat("Distance", 1); + nbt.putFloat("Timer", 40); + }); + + scene.world.showSection(util.select.layer(0), Direction.UP); + scene.idle(5); + scene.world.showSection(util.select.layer(1), Direction.DOWN); + scene.idle(5); + + ElementLink contraption = + scene.world.showIndependentSection(util.select.layersFrom(2), Direction.DOWN); + BlockPos bearing = util.grid.at(3, 1, 3); + scene.world.configureCenterOfRotation(contraption, util.vector.topOf(bearing)); + scene.idle(20); + scene.world.modifyTileNBT(psis, psiClass, nbt -> nbt.putFloat("Timer", 9)); + scene.idle(20); + scene.world.rotateBearing(bearing, 360 * 3 + 270, 240 + 60); + scene.world.rotateSection(contraption, 0, 360 * 3 + 270, 0, 240 + 60); + scene.idle(20); + + scene.world.toggleRedstonePower(util.select.fromTo(1, 1, 1, 1, 1, 2)); + scene.effects.indicateRedstone(util.grid.at(1, 1, 1)); + + scene.idle(10); + + scene.overlay.showSelectionWithText(util.select.position(1, 1, 3), 120) + .colored(PonderPalette.RED) + .text("Redstone power will prevent the stationary interface from engaging"); + + scene.idle(20); + scene.markAsFinished(); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/PonderChapter.java b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderChapter.java new file mode 100644 index 000000000..a128c6bfb --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderChapter.java @@ -0,0 +1,52 @@ +package com.simibubi.create.foundation.ponder.content; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.simibubi.create.Create; +import com.simibubi.create.foundation.gui.IScreenRenderable; +import com.simibubi.create.foundation.ponder.PonderRegistry; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.AbstractGui; +import net.minecraft.util.ResourceLocation; + +import javax.annotation.Nonnull; + +public class PonderChapter implements IScreenRenderable { + + private final String id; + private final ResourceLocation icon; + + private PonderChapter(String id) { + this.id = id; + icon = new ResourceLocation(Create.ID, "textures/ponder/chapter/" + id + ".png"); + } + + @Override + public void draw(AbstractGui screen, int x, int y) { + RenderSystem.pushMatrix(); + Minecraft.getInstance().getTextureManager().bindTexture(icon); + RenderSystem.scaled(0.25, 0.25, 1); + //x and y offset, blit z offset, tex x and y, tex width and height, entire tex sheet width and height + AbstractGui.blit(x, y, 0, 0, 0, 64, 64, 64, 64); + RenderSystem.popMatrix(); + } + + @Nonnull + public static PonderChapter of(String id) { + PonderChapter chapter = PonderRegistry.chapters.getChapter(id); + if (chapter == null) { + chapter = PonderRegistry.chapters.addChapter(new PonderChapter(id)); + } + + return chapter; + } + + public PonderChapter addTagsToChapter(PonderTag... tags) { + for (PonderTag t : tags) + PonderRegistry.tags.add(t, this); + return this; + } + + public String getId() { + return id; + } +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/PonderChapterRegistry.java b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderChapterRegistry.java new file mode 100644 index 000000000..66da66763 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderChapterRegistry.java @@ -0,0 +1,49 @@ +package com.simibubi.create.foundation.ponder.content; + +import com.simibubi.create.foundation.ponder.PonderStoryBoardEntry; +import com.simibubi.create.foundation.utility.Pair; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.*; +import java.util.stream.Collectors; + +public class PonderChapterRegistry { + + private final Map>> chapters; + + public PonderChapterRegistry() { + chapters = new HashMap<>(); + } + + public void addStoriesToChapter(@Nonnull PonderChapter chapter, PonderStoryBoardEntry... entries) { + chapters.get(chapter.getId()).getSecond().addAll(Arrays.asList(entries)); + } + + PonderChapter addChapter(@Nonnull PonderChapter chapter) { + chapters.put(chapter.getId(), Pair.of(chapter, new ArrayList<>())); + return chapter; + } + + @Nullable + PonderChapter getChapter(String id) { + Pair> pair = chapters.get(id); + if (pair == null) + return null; + + return pair.getFirst(); + } + + public List getAllChapters() { + return chapters + .values() + .stream() + .map(Pair::getFirst) + .collect(Collectors.toList()); + } + + public List getStories(PonderChapter chapter) { + return chapters.get(chapter.getId()).getSecond(); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/PonderIndex.java b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderIndex.java new file mode 100644 index 000000000..63ad820b8 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderIndex.java @@ -0,0 +1,235 @@ +package com.simibubi.create.foundation.ponder.content; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllItems; +import com.simibubi.create.foundation.ponder.PonderRegistry; + +import net.minecraft.block.Blocks; + +public class PonderIndex { + + public static final boolean EDITOR_MODE = true; + + public static void register() { + // Register storyboards here + // (!) Added entries require re-launch + // (!) Modifications inside storyboard methods only require re-opening the ui + + PonderRegistry.forComponents(AllBlocks.SHAFT) + .addStoryBoard("shaft/relay", KineticsScenes::shaftAsRelay); + PonderRegistry.forComponents(AllBlocks.SHAFT, AllBlocks.ANDESITE_ENCASED_SHAFT, AllBlocks.BRASS_ENCASED_SHAFT) + .addStoryBoard("shaft/encasing", KineticsScenes::shaftsCanBeEncased); + + PonderRegistry.forComponents(AllBlocks.COGWHEEL) + .addStoryBoard("cog/small", KineticsScenes::cogAsRelay) + .addStoryBoard("cog/speedup", KineticsScenes::cogsSpeedUp); + PonderRegistry.forComponents(AllBlocks.LARGE_COGWHEEL) + .addStoryBoard("cog/speedup", KineticsScenes::cogsSpeedUp) + .addStoryBoard("cog/large", KineticsScenes::largeCogAsRelay); + PonderRegistry.forComponents(AllItems.BELT_CONNECTOR) + .addStoryBoard("belt/connect", BeltScenes::beltConnector) + .addStoryBoard("belt/directions", BeltScenes::directions) + .addStoryBoard("belt/transport", BeltScenes::transport) + .addStoryBoard("belt/encasing", BeltScenes::beltsCanBeEncased); + + PonderRegistry.forComponents(AllBlocks.ANDESITE_CASING, AllBlocks.BRASS_CASING) + .addStoryBoard("shaft/encasing", KineticsScenes::shaftsCanBeEncased) + .addStoryBoard("belt/encasing", BeltScenes::beltsCanBeEncased); + + PonderRegistry.forComponents(AllBlocks.GEARBOX, AllItems.VERTICAL_GEARBOX) + .addStoryBoard("gearbox", KineticsScenes::gearbox); + PonderRegistry.addStoryBoard(AllBlocks.CLUTCH, "clutch", KineticsScenes::clutch); + PonderRegistry.addStoryBoard(AllBlocks.GEARSHIFT, "gearshift", KineticsScenes::gearshift); + + PonderRegistry.forComponents(AllBlocks.ENCASED_FAN) + .addStoryBoard("fan/direction", FanScenes::direction) + .addStoryBoard("fan/processing", FanScenes::processing) + .addStoryBoard("fan/source", FanScenes::source); + + PonderRegistry.addStoryBoard(AllBlocks.CREATIVE_MOTOR, "creative_motor", KineticsScenes::creativeMotor); + PonderRegistry.addStoryBoard(AllBlocks.WATER_WHEEL, "water_wheel", KineticsScenes::waterWheel); + PonderRegistry.addStoryBoard(AllBlocks.HAND_CRANK, "hand_crank", KineticsScenes::handCrank); + PonderRegistry.addStoryBoard(AllBlocks.COPPER_VALVE_HANDLE, "valve_handle", KineticsScenes::valveHandle); + PonderRegistry.forComponents(AllBlocks.DYED_VALVE_HANDLES) + .addStoryBoard("valve_handle", KineticsScenes::valveHandle); + + PonderRegistry.addStoryBoard(AllBlocks.ENCASED_CHAIN_DRIVE, "chain_drive/relay", + ChainDriveScenes::chainDriveAsRelay); + PonderRegistry.forComponents(AllBlocks.ENCASED_CHAIN_DRIVE, AllBlocks.ADJUSTABLE_CHAIN_GEARSHIFT) + .addStoryBoard("chain_drive/gearshift", ChainDriveScenes::adjustableChainGearshift); + + // Funnels + PonderRegistry.addStoryBoard(AllBlocks.BRASS_FUNNEL, "funnels/brass", FunnelScenes::brass); + PonderRegistry.forComponents(AllBlocks.ANDESITE_FUNNEL, AllBlocks.BRASS_FUNNEL) + .addStoryBoard("funnels/intro", FunnelScenes::intro) + .addStoryBoard("funnels/direction", FunnelScenes::directionality) + .addStoryBoard("funnels/compat", FunnelScenes::compat) + .addStoryBoard("funnels/redstone", FunnelScenes::redstone) + .addStoryBoard("funnels/transposer", FunnelScenes::transposer); + PonderRegistry.addStoryBoard(AllBlocks.ANDESITE_FUNNEL, "funnels/brass", FunnelScenes::brass); + + // Gantries + PonderRegistry.addStoryBoard(AllBlocks.GANTRY_SHAFT, "gantry/intro", GantryScenes::introForShaft); + PonderRegistry.addStoryBoard(AllBlocks.GANTRY_CARRIAGE, "gantry/intro", GantryScenes::introForPinion); + PonderRegistry.forComponents(AllBlocks.GANTRY_SHAFT, AllBlocks.GANTRY_CARRIAGE) + .addStoryBoard("gantry/redstone", GantryScenes::redstone) + .addStoryBoard("gantry/direction", GantryScenes::direction) + .addStoryBoard("gantry/subgantry", GantryScenes::subgantry); + + // Movement Actors + PonderRegistry.forComponents(AllBlocks.PORTABLE_STORAGE_INTERFACE) + .addStoryBoard("portable_interface/transfer", MovementActorScenes::psiTransfer) + .addStoryBoard("portable_interface/redstone", MovementActorScenes::psiRedstone); + + // Debug scenes, can be found in game via the Brass Hand + if (EDITOR_MODE) + DebugScenes.registerAll(); + } + + public static void registerTags() { + // Add items to tags here + + PonderRegistry.tags.forTag(PonderTag.KINETIC_RELAYS) + .add(AllBlocks.SHAFT) + .add(AllBlocks.COGWHEEL) + .add(AllBlocks.LARGE_COGWHEEL) + .add(AllItems.BELT_CONNECTOR) + .add(AllBlocks.GEARBOX) + .add(AllBlocks.CLUTCH) + .add(AllBlocks.GEARSHIFT) + .add(AllBlocks.ENCASED_CHAIN_DRIVE) + .add(AllBlocks.ADJUSTABLE_CHAIN_GEARSHIFT) + .add(AllBlocks.SEQUENCED_GEARSHIFT) + .add(AllBlocks.ROTATION_SPEED_CONTROLLER); + + PonderRegistry.tags.forTag(PonderTag.KINETIC_SOURCES) + .add(AllBlocks.HAND_CRANK) + .add(AllBlocks.COPPER_VALVE_HANDLE) + .add(AllBlocks.WATER_WHEEL) + .add(AllBlocks.ENCASED_FAN) + .add(AllBlocks.WINDMILL_BEARING) + .add(AllBlocks.FURNACE_ENGINE) + .add(AllBlocks.FLYWHEEL) + .add(AllBlocks.CREATIVE_MOTOR); + + PonderRegistry.tags.forTag(PonderTag.KINETIC_APPLIANCES) + .add(AllBlocks.MILLSTONE) + .add(AllBlocks.TURNTABLE) + .add(AllBlocks.ENCASED_FAN) + .add(AllBlocks.CUCKOO_CLOCK) + .add(AllBlocks.MECHANICAL_PRESS) + .add(AllBlocks.MECHANICAL_MIXER) + .add(AllBlocks.MECHANICAL_CRAFTER) + .add(AllBlocks.MECHANICAL_DRILL) + .add(AllBlocks.MECHANICAL_SAW) + .add(AllBlocks.MECHANICAL_PUMP) + .add(AllBlocks.MECHANICAL_ARM) + .add(AllBlocks.MECHANICAL_PISTON) + .add(AllBlocks.ROPE_PULLEY) + .add(AllBlocks.MECHANICAL_BEARING) + .add(AllBlocks.GANTRY_SHAFT) + .add(AllBlocks.GANTRY_CARRIAGE) + .add(AllBlocks.CLOCKWORK_BEARING) + .add(AllBlocks.CRUSHING_WHEEL); + + PonderRegistry.tags.forTag(PonderTag.FLUIDS) + .add(AllBlocks.FLUID_PIPE) + .add(AllBlocks.MECHANICAL_PUMP) + .add(AllBlocks.FLUID_VALVE) + .add(AllBlocks.SMART_FLUID_PIPE) + .add(AllBlocks.HOSE_PULLEY) + .add(AllBlocks.ITEM_DRAIN) + .add(AllBlocks.SPOUT) + .add(AllBlocks.PORTABLE_FLUID_INTERFACE) + .add(AllBlocks.FLUID_TANK) + .add(AllBlocks.CREATIVE_FLUID_TANK); + + PonderRegistry.tags.forTag(PonderTag.ARM_TARGETS) + .add(AllItems.BELT_CONNECTOR) + .add(AllBlocks.CHUTE) + .add(AllBlocks.DEPOT) + .add(AllBlocks.BASIN) + .add(AllBlocks.ANDESITE_FUNNEL) + .add(AllBlocks.BRASS_FUNNEL) + .add(AllBlocks.MECHANICAL_CRAFTER) + .add(AllBlocks.MILLSTONE) + .add(AllBlocks.DEPLOYER) + .add(AllBlocks.MECHANICAL_SAW) + .add(Blocks.COMPOSTER) + .add(AllBlocks.BLAZE_BURNER) + .add(Blocks.JUKEBOX) + .add(AllBlocks.CRUSHING_WHEEL); + + PonderRegistry.tags.forTag(PonderTag.LOGISTICS) + .add(AllItems.BELT_CONNECTOR) + .add(AllItems.FILTER) + .add(AllItems.ATTRIBUTE_FILTER) + .add(AllBlocks.CHUTE) + .add(AllBlocks.SMART_CHUTE) + .add(AllBlocks.DEPOT) + .add(AllBlocks.MECHANICAL_ARM) + .add(AllBlocks.ANDESITE_FUNNEL) + .add(AllBlocks.BRASS_FUNNEL) + .add(AllBlocks.ANDESITE_TUNNEL) + .add(AllBlocks.BRASS_TUNNEL) + .add(AllBlocks.CONTENT_OBSERVER) + .add(AllBlocks.STOCKPILE_SWITCH) + .add(AllBlocks.ADJUSTABLE_CRATE) + .add(AllBlocks.CREATIVE_CRATE) + .add(AllBlocks.PORTABLE_STORAGE_INTERFACE); + + PonderRegistry.tags.forTag(PonderTag.DECORATION) + .add(AllBlocks.NIXIE_TUBE) + .add(AllBlocks.CUCKOO_CLOCK) + .add(AllBlocks.WOODEN_BRACKET) + .add(AllBlocks.METAL_BRACKET) + .add(AllBlocks.ANDESITE_CASING) + .add(AllBlocks.BRASS_CASING) + .add(AllBlocks.COPPER_CASING); + + PonderRegistry.tags.forTag(PonderTag.CREATIVE) + .add(AllBlocks.CREATIVE_CRATE) + .add(AllBlocks.CREATIVE_FLUID_TANK) + .add(AllBlocks.CREATIVE_MOTOR); + + PonderRegistry.tags.forTag(PonderTag.REDSTONE) + .add(AllBlocks.NIXIE_TUBE) + .add(AllBlocks.REDSTONE_CONTACT) + .add(AllBlocks.ANALOG_LEVER) + .add(AllBlocks.REDSTONE_LINK) + .add(AllBlocks.ADJUSTABLE_REPEATER) + .add(AllBlocks.PULSE_REPEATER) + .add(AllBlocks.ADJUSTABLE_PULSE_REPEATER) + .add(AllBlocks.POWERED_LATCH) + .add(AllBlocks.POWERED_TOGGLE_LATCH); + + PonderRegistry.tags.forTag(PonderTag.MOVEMENT_ANCHOR) + .add(AllBlocks.MECHANICAL_PISTON) + .add(AllBlocks.WINDMILL_BEARING) + .add(AllBlocks.MECHANICAL_BEARING) + .add(AllBlocks.CLOCKWORK_BEARING) + .add(AllBlocks.ROPE_PULLEY) + .add(AllBlocks.GANTRY_CARRIAGE) + .add(AllBlocks.CART_ASSEMBLER); + + PonderRegistry.tags.forTag(PonderTag.CONTRAPTION_ACTOR) + .add(AllBlocks.MECHANICAL_HARVESTER) + .add(AllBlocks.MECHANICAL_PLOUGH) + .add(AllBlocks.MECHANICAL_DRILL) + .add(AllBlocks.MECHANICAL_SAW) + .add(AllBlocks.DEPLOYER) + .add(AllBlocks.PORTABLE_STORAGE_INTERFACE) + .add(AllBlocks.PORTABLE_FLUID_INTERFACE) + .add(AllBlocks.MECHANICAL_BEARING) + .add(AllBlocks.ANDESITE_FUNNEL) + .add(AllBlocks.BRASS_FUNNEL) + .add(AllBlocks.SEATS[0]) + .add(AllBlocks.REDSTONE_CONTACT) + .add(AllBlocks.SAIL) + .add(Blocks.BELL) + .add(Blocks.DISPENSER) + .add(Blocks.DROPPER); + + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/PonderIndexScreen.java b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderIndexScreen.java new file mode 100644 index 000000000..a8176db77 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderIndexScreen.java @@ -0,0 +1,172 @@ +package com.simibubi.create.foundation.ponder.content; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.simibubi.create.foundation.gui.AbstractSimiScreen; +import com.simibubi.create.foundation.gui.ScreenOpener; +import com.simibubi.create.foundation.gui.UIRenderHelper; +import com.simibubi.create.foundation.ponder.PonderRegistry; +import com.simibubi.create.foundation.ponder.PonderUI; +import com.simibubi.create.foundation.ponder.ui.ChapterLabel; +import com.simibubi.create.foundation.ponder.ui.LayoutHelper; +import com.simibubi.create.foundation.ponder.ui.PonderButton; +import net.minecraft.block.Block; +import net.minecraft.client.MainWindow; +import net.minecraft.client.gui.widget.Widget; +import net.minecraft.client.renderer.Rectangle2d; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.MathHelper; +import net.minecraftforge.registries.ForgeRegistries; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +public class PonderIndexScreen extends AbstractSimiScreen { + + protected final List chapters; + private final double chapterXmult = 0.5; + private final double chapterYmult = 0.3; + protected Rectangle2d chapterArea; + + protected final List items; + private final double itemXmult = 0.5; + private final double itemYmult = 0.75; + protected Rectangle2d itemArea; + + private ItemStack hoveredItem = ItemStack.EMPTY; + + public PonderIndexScreen() { + chapters = new ArrayList<>(); + items = new ArrayList<>(); + } + + @Override + protected void init() { + super.init(); + + widgets.clear(); + + chapters.clear(); + chapters.addAll(PonderRegistry.chapters.getAllChapters()); + + LayoutHelper layout = LayoutHelper.centeredHorizontal( + chapters.size(), + MathHelper.clamp((int) Math.ceil(chapters.size() / 4f), 1, 4), + 200, + 38, + 16 + ); + chapterArea = layout.getArea(); + int chapterCenterX = (int) (width * chapterXmult); + int chapterCenterY = (int) (height * chapterYmult); + + //todo at some point pagination or horizontal scrolling may be needed for chapters/items + for (PonderChapter chapter : chapters) { + ChapterLabel label = new ChapterLabel(chapter, chapterCenterX + layout.getX(), + chapterCenterY + layout.getY(), (mouseX, mouseY) -> { + centerScalingOn(mouseX, mouseY); + ScreenOpener.transitionTo(PonderUI.of(chapter)); + }); + + widgets.add(label); + layout.next(); + } + + items.clear(); + PonderRegistry.all.keySet() + .stream() + .map(key -> { + Item item = ForgeRegistries.ITEMS.getValue(key); + if (item == null) { + Block b = ForgeRegistries.BLOCKS.getValue(key); + if (b != null) + item = b.asItem(); + } + return item; + }) + .filter(Objects::nonNull) + .forEach(items::add); + + layout = LayoutHelper.centeredHorizontal( + items.size(), + MathHelper.clamp((int) Math.ceil(items.size() / 11f), 1, 4), + 28, + 28, + 8 + ); + itemArea = layout.getArea(); + int itemCenterX = (int) (width * itemXmult); + int itemCenterY = (int) (height * itemYmult); + + for (Item item : items) { + PonderButton button = new PonderButton(itemCenterX + layout.getX() + 4, itemCenterY + layout.getY() + 4, (x, y) -> {}) + .showing(new ItemStack(item)); + + button.fade(1); + widgets.add(button); + layout.next(); + } + + + } + + @Override + public void tick() { + super.tick(); + + hoveredItem = ItemStack.EMPTY; + MainWindow w = minecraft.getWindow(); + double mouseX = minecraft.mouseHelper.getMouseX() * w.getScaledWidth() / w.getWidth(); + double mouseY = minecraft.mouseHelper.getMouseY() * w.getScaledHeight() / w.getHeight(); + for (Widget widget : widgets) { + if (widget instanceof PonderButton) + if (widget.isMouseOver(mouseX, mouseY)) { + hoveredItem = ((PonderButton) widget).getItem(); + } + } + } + + @Override + protected void renderWindow(int mouseX, int mouseY, float partialTicks) { + int x = (int) (width * chapterXmult); + int y = (int) (height * chapterYmult); + + RenderSystem.pushMatrix(); + RenderSystem.translated(x, y, 0); + + UIRenderHelper.streak(0, chapterArea.getX() - 10, chapterArea.getY() - 20, 20, 220, 0x101010); + drawString(font, "Topics to Ponder about", chapterArea.getX() - 5, chapterArea.getY() - 25, 0xffddeeff); + + RenderSystem.popMatrix(); + + + x = (int) (width * itemXmult); + y = (int) (height * itemYmult); + + RenderSystem.pushMatrix(); + RenderSystem.translated(x, y, 0); + + UIRenderHelper.streak(0, itemArea.getX() - 10, itemArea.getY() - 20, 20, 220, 0x101010); + drawString(font, "Items to inspect", itemArea.getX() - 5, itemArea.getY() - 25, 0xffddeeff); + + RenderSystem.popMatrix(); + } + + @Override + protected void renderWindowForeground(int mouseX, int mouseY, float partialTicks) { + if (hoveredItem.isEmpty()) + return; + + RenderSystem.pushMatrix(); + RenderSystem.translated(0, 0, 200); + + renderTooltip(hoveredItem, mouseX, mouseY); + + RenderSystem.popMatrix(); + } + + public ItemStack getHoveredTooltipItem() { + return hoveredItem; + } +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/PonderPalette.java b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderPalette.java new file mode 100644 index 000000000..ede4108ed --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderPalette.java @@ -0,0 +1,27 @@ +package com.simibubi.create.foundation.ponder.content; + +public enum PonderPalette { + + WHITE(0xFF_eeeeee), + BLACK(0xFF_221111), + + RED(0xFF_ff5d6c), + GREEN(0xFF_8cba51), + BLUE(0xFF_5f6caf), + + SLOW(0xFF_22ff22), + MEDIUM(0xFF_0084ff), + FAST(0xFF_ff55ff), + + ; + + private int color; + + private PonderPalette(int color) { + this.color = color; + } + + public int getColor() { + return color; + } +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/PonderTag.java b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderTag.java new file mode 100644 index 000000000..b0b7ba26c --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderTag.java @@ -0,0 +1,154 @@ +package com.simibubi.create.foundation.ponder.content; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.simibubi.create.AllBlocks; +import com.simibubi.create.foundation.gui.GuiGameElement; +import com.simibubi.create.foundation.gui.IScreenRenderable; +import com.simibubi.create.foundation.ponder.PonderLocalization; + +import net.minecraft.block.Blocks; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.AbstractGui; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.util.IItemProvider; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; + +public class PonderTag implements IScreenRenderable { + + // + + public static final PonderTag + + KINETIC_RELAYS = new PonderTag("kinetic_relays").item(AllBlocks.COGWHEEL.get(), true, false) + .defaultLang("Kinetic Blocks", "Components which help relaying Rotational Force elsewhere"), + + KINETIC_SOURCES = new PonderTag("kinetic_sources").item(AllBlocks.WATER_WHEEL.get(), true, false) + .defaultLang("Kinetic Sources", "Components which generate Rotational Force"), + + KINETIC_APPLIANCES = new PonderTag("kinetic_appliances").item(AllBlocks.MECHANICAL_PRESS.get(), true, false) + .defaultLang("Kinetic Appliances", "Components which make use of Rotational Force"), + + FLUIDS = new PonderTag("fluids").item(AllBlocks.FLUID_PIPE.get(), true, false) + .defaultLang("Fluid Manipulators", "Components which help relaying and making use of Fluids"), + + LOGISTICS = new PonderTag("logistics").item(Blocks.CHEST, true, false) + .defaultLang("Item Transportation", "Components which help moving items around"), + + REDSTONE = new PonderTag("redstone").item(Items.REDSTONE, true, false) + .defaultLang("Logic Components", "Components which help with redstone engineering"), + + DECORATION = new PonderTag("decoration").item(Items.ROSE_BUSH, true, false) + .defaultLang("Aesthetics", "Components used mostly for decorative purposes"), + + CREATIVE = new PonderTag("creative").item(AllBlocks.CREATIVE_CRATE.get(), true, false) + .defaultLang("Creative Mode", "Components not usually available for Survival Mode"), + + MOVEMENT_ANCHOR = new PonderTag("movement_anchor").item(AllBlocks.MECHANICAL_PISTON.get(), true, false) + .defaultLang("Movement Anchors", + "Components which allow the creation of moving contraptions, animating an attached structure in a variety of ways"), + + CONTRAPTION_ACTOR = new PonderTag("contraption_actor").item(AllBlocks.MECHANICAL_HARVESTER.get(), true, false) + .defaultLang("Contraption Actors", + "Components which expose special behaviour when attached to a moving contraption"), + +// FLUID_TRANSFER = new PonderTag("fluid_transfer").idAsIcon(), +// +// OPEN_INVENTORY = new PonderTag("open_inventory").item(AllBlocks.BASIN.get() +// .asItem()), +// +// REDSTONE_CONTROL = new PonderTag("redstone_control").item(Items.REDSTONE, true, false), +// +// ITEM_TRANSFER = new PonderTag("item_transfer").idAsIcon(), + + ARM_TARGETS = new PonderTag("arm_targets").item(AllBlocks.MECHANICAL_ARM.get()) + .defaultLang("Targets for Mechanical Arms", + "Components which can be selected as inputs or outputs to the Mechanical Arm"); + + public static class Highlight { + public static final PonderTag ALL = new PonderTag("_all"); + } + + // + + private final String id; + private ResourceLocation icon; + private ItemStack itemIcon = ItemStack.EMPTY; + private ItemStack mainItem = ItemStack.EMPTY; + + public String getTitle() { + return PonderLocalization.getTag(id); + } + + public String getDescription() { + return PonderLocalization.getTagDescription(id); + } + + // Builder + + public PonderTag(String id) { + this.id = id; + } + + public String getId() { + return id; + } + + public PonderTag defaultLang(String title, String description) { + PonderLocalization.registerTag(id, title, description); + return this; + } + + public ItemStack getMainItem() { + return mainItem; + } + + public PonderTag idAsIcon() { + return icon(id); + } + + public PonderTag icon(String location) { + this.icon = new ResourceLocation(com.simibubi.create.Create.ID, "textures/ponder/tag/" + location + ".png"); + return this; + } + + public PonderTag item(IItemProvider item) { + return this.item(item, true, true); + } + + public PonderTag item(IItemProvider item, boolean useAsIcon, boolean useAsMainItem) { + if (useAsIcon) + this.itemIcon = new ItemStack(item); + if (useAsMainItem) + this.mainItem = new ItemStack(item); + return this; + } + + @Override + @OnlyIn(Dist.CLIENT) + public void draw(AbstractGui screen, int x, int y) { + RenderSystem.pushMatrix(); + RenderSystem.translated(x, y, 0); + if (icon != null) { + Minecraft.getInstance() + .getTextureManager() + .bindTexture(icon); + RenderSystem.scaled(0.25, 0.25, 1); + // x and y offset, blit z offset, tex x and y, tex width and height, entire tex + // sheet width and height + AbstractGui.blit(0, 0, 0, 0, 0, 64, 64, 64, 64); + } else if (!itemIcon.isEmpty()) { + RenderSystem.translated(-4, -4, 0); + RenderSystem.scaled(1.5, 1.5, 1.5); + GuiGameElement.of(itemIcon) + .render(); + } + RenderSystem.popMatrix(); + } + + // Load class + public static void register() {} + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/PonderTagRegistry.java b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderTagRegistry.java new file mode 100644 index 000000000..9ff0a6763 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderTagRegistry.java @@ -0,0 +1,104 @@ +package com.simibubi.create.foundation.ponder.content; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.LinkedHashMultimap; +import com.google.common.collect.Multimap; +import com.simibubi.create.foundation.ponder.PonderRegistry; +import com.tterrag.registrate.util.entry.ItemProviderEntry; + +import net.minecraft.util.IItemProvider; +import net.minecraft.util.ResourceLocation; + +public class PonderTagRegistry { + + private final Multimap tags; + private final Multimap chapterTags; + + public PonderTagRegistry() { + tags = LinkedHashMultimap.create(); + chapterTags = LinkedHashMultimap.create(); + } + + public Set getTags(ResourceLocation item) { + return ImmutableSet.copyOf(tags.get(item)); + } + + public Set getTags(PonderChapter chapter) { + return ImmutableSet.copyOf(chapterTags.get(chapter)); + } + + public Set getItems(PonderTag tag) { + return tags.entries() + .stream() + .filter(e -> e.getValue() == tag) + .map(Map.Entry::getKey) + .collect(ImmutableSet.toImmutableSet()); + } + + public Set getChapters(PonderTag tag) { + return chapterTags.entries() + .stream() + .filter(e -> e.getValue() == tag) + .map(Map.Entry::getKey) + .collect(ImmutableSet.toImmutableSet()); + } + + public void add(PonderTag tag, ResourceLocation item) { + tags.put(item, tag); + } + + public void add(PonderTag tag, PonderChapter chapter) { + chapterTags.put(chapter, tag); + } + + public ItemBuilder forItems(ResourceLocation... items) { + return new ItemBuilder(items); + } + + public TagBuilder forTag(PonderTag tag) { + return new TagBuilder(tag); + } + + public static class ItemBuilder { + + private final Collection items; + + private ItemBuilder(ResourceLocation... items) { + this.items = Arrays.asList(items); + } + + public ItemBuilder add(PonderTag tag) { + items.forEach(i -> PonderRegistry.tags.add(tag, i)); + return this; + } + + } + + public static class TagBuilder { + + private final PonderTag tag; + + private TagBuilder(PonderTag tag) { + this.tag = tag; + } + + public TagBuilder add(ResourceLocation item) { + PonderRegistry.tags.add(tag, item); + return this; + } + + public TagBuilder add(IItemProvider item) { + return add(item.asItem() + .getRegistryName()); + } + + public TagBuilder add(ItemProviderEntry entry) { + return add(entry.get()); + } + } +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/PonderTagScreen.java b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderTagScreen.java new file mode 100644 index 000000000..822f0e59b --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderTagScreen.java @@ -0,0 +1,295 @@ +package com.simibubi.create.foundation.ponder.content; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import org.apache.commons.lang3.mutable.MutableBoolean; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.simibubi.create.foundation.gui.AbstractSimiScreen; +import com.simibubi.create.foundation.gui.ScreenOpener; +import com.simibubi.create.foundation.gui.UIRenderHelper; +import com.simibubi.create.foundation.ponder.PonderLocalization; +import com.simibubi.create.foundation.ponder.PonderRegistry; +import com.simibubi.create.foundation.ponder.PonderUI; +import com.simibubi.create.foundation.ponder.ui.ChapterLabel; +import com.simibubi.create.foundation.ponder.ui.LayoutHelper; +import com.simibubi.create.foundation.ponder.ui.PonderButton; +import com.simibubi.create.foundation.utility.Lang; + +import net.minecraft.block.Block; +import net.minecraft.client.MainWindow; +import net.minecraft.client.gui.widget.Widget; +import net.minecraft.client.renderer.Rectangle2d; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.MathHelper; +import net.minecraftforge.registries.ForgeRegistries; + +public class PonderTagScreen extends AbstractSimiScreen { + + public static final String ASSOCIATED = PonderLocalization.LANG_PREFIX + "associated"; + + protected final PonderTag tag; + protected final List items; + private final double itemXmult = 0.5; + protected Rectangle2d itemArea; + protected final List chapters; + private final double chapterXmult = 0.5; + private final double chapterYmult = 0.75; + protected Rectangle2d chapterArea; + private final double mainYmult = 0.15; + + private ItemStack hoveredItem = ItemStack.EMPTY; + + public PonderTagScreen(PonderTag tag) { + this.tag = tag; + items = new ArrayList<>(); + chapters = new ArrayList<>(); + } + + @Override + protected void init() { + super.init(); + widgets.clear(); + + // items + items.clear(); + PonderRegistry.tags.getItems(tag) + .stream() + .map(key -> { + Item item = ForgeRegistries.ITEMS.getValue(key); + if (item == null) { + Block b = ForgeRegistries.BLOCKS.getValue(key); + if (b != null) + item = b.asItem(); + } + return item; + }) + .filter(Objects::nonNull) + .forEach(items::add); + + int rowCount = MathHelper.clamp((int) Math.ceil(items.size() / 11d), 1, 3); + LayoutHelper layout = LayoutHelper.centeredHorizontal(items.size(), rowCount, 28, 28, 8); + itemArea = layout.getArea(); + int itemCenterX = (int) (width * itemXmult); + int itemCenterY = getItemsY(); + + for (Item i : items) { + PonderButton button = + new PonderButton(itemCenterX + layout.getX() + 4, itemCenterY + layout.getY() + 4, (mouseX, mouseY) -> { + if (!PonderRegistry.all.containsKey(i.getRegistryName())) + return; + centerScalingOn(mouseX, mouseY); + ScreenOpener.transitionTo(PonderUI.of(new ItemStack(i))); + }).showing(new ItemStack(i)); + + button.fade(1); + widgets.add(button); + layout.next(); + } + + if (!tag.getMainItem() + .isEmpty()) { + PonderButton button = + new PonderButton(itemCenterX - layout.getTotalWidth() / 2 - 42, itemCenterY - 10, (mouseX, mouseY) -> { + if (!PonderRegistry.all.containsKey(tag.getMainItem() + .getItem() + .getRegistryName())) + return; + centerScalingOn(mouseX, mouseY); + ScreenOpener.transitionTo(PonderUI.of(tag.getMainItem())); + }).showing(tag.getMainItem()); + + button.fade(1); +// button.flash(); + widgets.add(button); + } + + // chapters + chapters.clear(); + chapters.addAll(PonderRegistry.tags.getChapters(tag)); + + rowCount = MathHelper.clamp((int) Math.ceil(chapters.size() / 3f), 1, 3); + layout = LayoutHelper.centeredHorizontal(chapters.size(), rowCount, 200, 38, 16); + chapterArea = layout.getArea(); + int chapterCenterX = (int) (width * chapterXmult); + int chapterCenterY = (int) (height * chapterYmult); + + for (PonderChapter chapter : chapters) { + ChapterLabel label = new ChapterLabel(chapter, chapterCenterX + layout.getX(), + chapterCenterY + layout.getY(), (mouseX, mouseY) -> { + centerScalingOn(mouseX, mouseY); + ScreenOpener.transitionTo(PonderUI.of(chapter)); + }); + + widgets.add(label); + layout.next(); + } + + } + + @Override + public void tick() { + super.tick(); + + hoveredItem = ItemStack.EMPTY; + MainWindow w = minecraft.getWindow(); + double mouseX = minecraft.mouseHelper.getMouseX() * w.getScaledWidth() / w.getWidth(); + double mouseY = minecraft.mouseHelper.getMouseY() * w.getScaledHeight() / w.getHeight(); + for (Widget widget : widgets) { + if (widget instanceof PonderButton) + if (widget.isMouseOver(mouseX, mouseY)) { + hoveredItem = ((PonderButton) widget).getItem(); + } + } + } + + @Override + protected void renderWindow(int mouseX, int mouseY, float partialTicks) { + renderItems(mouseX, mouseY, partialTicks); + + renderChapters(mouseX, mouseY, partialTicks); + + RenderSystem.pushMatrix(); + RenderSystem.translated(width / 2 - 120, height * mainYmult - 40, 0); + + RenderSystem.pushMatrix(); + RenderSystem.translated(0, 0, 800); + int x = 31 + 20 + 8; + int y = 31; + + String title = tag.getTitle(); + + int streakHeight = 35; + UIRenderHelper.streak(0, x - 4, y - 12 + streakHeight / 2, streakHeight, (int) (240), 0x101010); + PonderUI.renderBox(21, 21, 30, 30, false); + + drawString(font, Lang.translate(PonderUI.PONDERING), x, y - 6, 0xffa3a3a3); + y += 8; + x += 0; + RenderSystem.translated(x, y, 0); + RenderSystem.translated(0, 0, 5); + font.drawString(title, 0, 0, 0xeeeeee); + RenderSystem.popMatrix(); + + RenderSystem.pushMatrix(); + RenderSystem.translated(23, 23, 0); + RenderSystem.scaled(1.66, 1.66, 1.66); + tag.draw(this, 0, 0); + RenderSystem.popMatrix(); + RenderSystem.popMatrix(); + + RenderSystem.pushMatrix(); + int w = (int) (width * .45); + x = (width - w) / 2; + y = getItemsY() - 10 + Math.max(itemArea.getHeight(), 48); + + String desc = tag.getDescription(); + int h = font.getWordWrappedHeight(desc, w); + + PonderUI.renderBox(x - 3, y - 3, w + 6, h + 6, false); + RenderSystem.translated(0, 0, 100); + font.drawSplitString(desc, x, y, w, 0xeeeeee); + RenderSystem.popMatrix(); + } + + protected void renderItems(int mouseX, int mouseY, float partialTicks) { + if (items.isEmpty()) + return; + + int x = (int) (width * itemXmult); + int y = getItemsY(); + + String relatedTitle = Lang.translate(ASSOCIATED); + int stringWidth = font.getStringWidth(relatedTitle); + + RenderSystem.pushMatrix(); + RenderSystem.translated(x, y, 0); + PonderUI.renderBox((sWidth - stringWidth) / 2 - 5, itemArea.getY() - 21, stringWidth + 10, 10, false); + RenderSystem.translated(0, 0, 200); + +// UIRenderHelper.streak(0, itemArea.getX() - 10, itemArea.getY() - 20, 20, 180, 0x101010); + drawCenteredString(font, relatedTitle, sWidth / 2, itemArea.getY() - 20, 0xeeeeee); + + UIRenderHelper.streak(0, 0, 0, itemArea.getHeight() + 10, itemArea.getWidth() / 2 + 75, 0x101010); + UIRenderHelper.streak(180, 0, 0, itemArea.getHeight() + 10, itemArea.getWidth() / 2 + 75, 0x101010); + + RenderSystem.popMatrix(); + + } + + public int getItemsY() { + return (int) (mainYmult * height + 85); + } + + protected void renderChapters(int mouseX, int mouseY, float partialTicks) { + if (chapters.isEmpty()) + return; + + int chapterX = (int) (width * chapterXmult); + int chapterY = (int) (height * chapterYmult); + + RenderSystem.pushMatrix(); + RenderSystem.translated(chapterX, chapterY, 0); + + UIRenderHelper.streak(0, chapterArea.getX() - 10, chapterArea.getY() - 20, 20, 220, 0x101010); + drawString(font, "More Topics to Ponder about", chapterArea.getX() - 5, chapterArea.getY() - 25, 0xffddeeff); + + RenderSystem.popMatrix(); + } + + @Override + protected void renderWindowForeground(int mouseX, int mouseY, float partialTicks) { + RenderSystem.pushMatrix(); + RenderSystem.disableRescaleNormal(); + RenderSystem.disableDepthTest(); + + RenderSystem.translated(0, 0, 200); + if (!hoveredItem.isEmpty()) { + renderTooltip(hoveredItem, mouseX, mouseY); + } + RenderSystem.enableDepthTest(); + RenderSystem.enableRescaleNormal(); + RenderSystem.popMatrix(); + } + + @Override + protected String getBreadcrumbTitle() { + return tag.getTitle(); + } + + public ItemStack getHoveredTooltipItem() { + return hoveredItem; + } + + @Override + public boolean mouseClicked(double x, double y, int button) { + MutableBoolean handled = new MutableBoolean(false); + widgets.forEach(w -> { + if (handled.booleanValue()) + return; + if (!w.isMouseOver(x, y)) + return; + if (w instanceof PonderButton) { + PonderButton mtdButton = (PonderButton) w; + mtdButton.runCallback(x, y); + handled.setTrue(); + return; + } + }); + + if (handled.booleanValue()) + return true; + return super.mouseClicked(x, y, button); + } + + @Override + public boolean isEquivalentTo(AbstractSimiScreen other) { + if (other instanceof PonderTagScreen) + return tag == ((PonderTagScreen) other).tag; + return super.isEquivalentTo(other); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/SharedText.java b/src/main/java/com/simibubi/create/foundation/ponder/content/SharedText.java new file mode 100644 index 000000000..c7e2ed679 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/SharedText.java @@ -0,0 +1,30 @@ +package com.simibubi.create.foundation.ponder.content; + +import com.simibubi.create.foundation.ponder.PonderLocalization; + +public class SharedText { + + public static void gatherText() { + // Add entries used across several ponder scenes (Safe for hotswap) + + add("sneak_and", "Sneak +"); + add("ctrl_and", "Ctrl +"); + + add("rpm8", "8 RPM"); + add("rpm16", "16 RPM"); + add("rpm16_source", "Source: 16 RPM"); + add("rpm32", "32 RPM"); + + add("movement_anchors", "With the help of Chassis or Super Glue, larger structures can be moved."); + + } + + public static String get(String key) { + return PonderLocalization.getShared(key); + } + + private static void add(String k, String v) { + PonderLocalization.registerShared(k, v); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/elements/AnimatedOverlayElement.java b/src/main/java/com/simibubi/create/foundation/ponder/elements/AnimatedOverlayElement.java new file mode 100644 index 000000000..ef2950bf0 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/elements/AnimatedOverlayElement.java @@ -0,0 +1,29 @@ +package com.simibubi.create.foundation.ponder.elements; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.foundation.ponder.PonderScene; +import com.simibubi.create.foundation.ponder.PonderUI; +import com.simibubi.create.foundation.utility.LerpedFloat; + +public abstract class AnimatedOverlayElement extends PonderOverlayElement { + + protected LerpedFloat fade; + + public AnimatedOverlayElement() { + fade = LerpedFloat.linear() + .startWithValue(0); + } + + public void setFade(float fade) { + this.fade.setValue(fade); + } + + @Override + public final void render(PonderScene scene, PonderUI screen, MatrixStack ms, float partialTicks) { + float currentFade = fade.getValue(partialTicks); + render(scene, screen, ms, partialTicks, currentFade); + } + + protected abstract void render(PonderScene scene, PonderUI screen, MatrixStack ms, float partialTicks, float fade); + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/elements/AnimatedSceneElement.java b/src/main/java/com/simibubi/create/foundation/ponder/elements/AnimatedSceneElement.java new file mode 100644 index 000000000..4c98c08aa --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/elements/AnimatedSceneElement.java @@ -0,0 +1,84 @@ +package com.simibubi.create.foundation.ponder.elements; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.foundation.ponder.PonderWorld; +import com.simibubi.create.foundation.utility.LerpedFloat; +import com.simibubi.create.foundation.utility.MatrixStacker; + +import net.minecraft.client.renderer.IRenderTypeBuffer; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; + +public abstract class AnimatedSceneElement extends PonderSceneElement { + + protected Vec3d fadeVec; + protected LerpedFloat fade; + + public AnimatedSceneElement() { + fade = LerpedFloat.linear() + .startWithValue(0); + } + + public void forceApplyFade(float fade) { + this.fade.startWithValue(fade); + } + + public void setFade(float fade) { + this.fade.setValue(fade); + } + + public void setFadeVec(Vec3d fadeVec) { + this.fadeVec = fadeVec; + } + + @Override + public final void renderFirst(PonderWorld world, IRenderTypeBuffer buffer, MatrixStack ms, float pt) { + ms.push(); + float currentFade = applyFade(ms, pt); + renderFirst(world, buffer, ms, currentFade, pt); + ms.pop(); + } + + @Override + public final void renderLayer(PonderWorld world, IRenderTypeBuffer buffer, RenderType type, MatrixStack ms, + float pt) { + ms.push(); + float currentFade = applyFade(ms, pt); + renderLayer(world, buffer, type, ms, currentFade, pt); + ms.pop(); + } + + @Override + public final void renderLast(PonderWorld world, IRenderTypeBuffer buffer, MatrixStack ms, float pt) { + ms.push(); + float currentFade = applyFade(ms, pt); + renderLast(world, buffer, ms, currentFade, pt); + ms.pop(); + } + + protected float applyFade(MatrixStack ms, float pt) { + float currentFade = fade.getValue(pt); + if (fadeVec != null) + MatrixStacker.of(ms) + .translate(fadeVec.scale(-1 + currentFade)); + return currentFade; + } + + protected void renderLayer(PonderWorld world, IRenderTypeBuffer buffer, RenderType type, MatrixStack ms, float fade, + float pt) {} + + protected void renderFirst(PonderWorld world, IRenderTypeBuffer buffer, MatrixStack ms, float fade, float pt) {} + + protected void renderLast(PonderWorld world, IRenderTypeBuffer buffer, MatrixStack ms, float fade, float pt) {} + + protected int lightCoordsFromFade(float fade) { + int light = 0xF000F0; + if (fade != 1) { + light = (int) (MathHelper.lerp(fade, 5, 0xF)); + light = light << 4 | light << 20; + } + return light; + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/elements/BeltItemElement.java b/src/main/java/com/simibubi/create/foundation/ponder/elements/BeltItemElement.java new file mode 100644 index 000000000..4935b3da4 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/elements/BeltItemElement.java @@ -0,0 +1,11 @@ +package com.simibubi.create.foundation.ponder.elements; + +import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack; + +public class BeltItemElement extends TrackedElement { + + public BeltItemElement(TransportedItemStack wrapped) { + super(wrapped); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/elements/EntityElement.java b/src/main/java/com/simibubi/create/foundation/ponder/elements/EntityElement.java new file mode 100644 index 000000000..556d300a4 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/elements/EntityElement.java @@ -0,0 +1,16 @@ +package com.simibubi.create.foundation.ponder.elements; + +import net.minecraft.entity.Entity; + +public class EntityElement extends TrackedElement { + + public EntityElement(Entity wrapped) { + super(wrapped); + } + + @Override + protected boolean isStillValid(Entity element) { + return element.isAlive(); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/elements/InputWindowElement.java b/src/main/java/com/simibubi/create/foundation/ponder/elements/InputWindowElement.java new file mode 100644 index 000000000..0932b7443 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/elements/InputWindowElement.java @@ -0,0 +1,141 @@ +package com.simibubi.create.foundation.ponder.elements; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.systems.RenderSystem; +import com.simibubi.create.AllItems; +import com.simibubi.create.foundation.gui.AllIcons; +import com.simibubi.create.foundation.gui.GuiGameElement; +import com.simibubi.create.foundation.ponder.PonderLocalization; +import com.simibubi.create.foundation.ponder.PonderScene; +import com.simibubi.create.foundation.ponder.PonderUI; +import com.simibubi.create.foundation.ponder.content.PonderPalette; +import com.simibubi.create.foundation.utility.ColorHelper; +import com.simibubi.create.foundation.utility.Pointing; + +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.Vec2f; +import net.minecraft.util.math.Vec3d; + +public class InputWindowElement extends AnimatedOverlayElement { + + private Pointing direction; + String key; + AllIcons icon; + ItemStack item = ItemStack.EMPTY; + private Vec3d sceneSpace; + + public InputWindowElement clone() { + InputWindowElement inputWindowElement = new InputWindowElement(sceneSpace, direction); + inputWindowElement.key = key; + inputWindowElement.icon = icon; + inputWindowElement.item = item.copy(); + return inputWindowElement; + } + + public InputWindowElement(Vec3d sceneSpace, Pointing direction) { + this.sceneSpace = sceneSpace; + this.direction = direction; + } + + public InputWindowElement withItem(ItemStack stack) { + item = stack; + return this; + } + + public InputWindowElement withWrench() { + item = AllItems.WRENCH.asStack(); + return this; + } + + public InputWindowElement scroll() { + icon = AllIcons.I_SCROLL; + return this; + } + + public InputWindowElement rightClick() { + icon = AllIcons.I_RMB; + return this; + } + + public InputWindowElement leftClick() { + icon = AllIcons.I_LMB; + return this; + } + + public InputWindowElement whileSneaking() { + key = "sneak_and"; + return this; + } + + public InputWindowElement whileCTRL() { + key = "ctrl_and"; + return this; + } + + @Override + protected void render(PonderScene scene, PonderUI screen, MatrixStack ms, float partialTicks, float fade) { + FontRenderer font = screen.getFontRenderer(); + int width = 0; + int height = 0; + + int xFade = direction == Pointing.RIGHT ? -1 : direction == Pointing.LEFT ? 1 : 0; + int yFade = direction == Pointing.DOWN ? -1 : direction == Pointing.UP ? 1 : 0; + xFade *= 10 * (1 - fade); + yFade *= 10 * (1 - fade); + + boolean hasItem = !item.isEmpty(); + boolean hasText = key != null; + boolean hasIcon = icon != null; + int keyWidth = 0; + String text = hasText ? PonderLocalization.getShared(key) : ""; + + if (fade < 1 / 16f) + return; + Vec2f sceneToScreen = scene.getTransform() + .sceneToScreen(sceneSpace); + + if (hasIcon) { + width += 24; + height = 24; + } + + if (hasText) { + keyWidth = font.getStringWidth(text); + width += keyWidth; + } + + if (hasItem) { + width += 24; + height = 24; + } + + RenderSystem.pushMatrix(); + RenderSystem.translated(sceneToScreen.x + xFade, sceneToScreen.y + yFade, 400); + + PonderUI.renderSpeechBox(0, 0, width, height, false, direction, true); + + if (hasText) + font.drawString(text, 2, (height - font.FONT_HEIGHT) / 2 + 2, + ColorHelper.applyAlpha(PonderPalette.WHITE.getColor(), fade)); + + if (hasIcon) { + RenderSystem.pushMatrix(); + RenderSystem.translated(keyWidth, 0, 0); + RenderSystem.scaled(1.5, 1.5, 1.5); + icon.draw(0, 0); + RenderSystem.popMatrix(); + } + + if (hasItem) { + GuiGameElement.of(item) + .at(keyWidth + (hasIcon ? 24 : 0), 0) + .scale(1.5) + .render(); + RenderSystem.disableDepthTest(); + } + + RenderSystem.popMatrix(); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/elements/OutlinerElement.java b/src/main/java/com/simibubi/create/foundation/ponder/elements/OutlinerElement.java new file mode 100644 index 000000000..44773221a --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/elements/OutlinerElement.java @@ -0,0 +1,35 @@ +package com.simibubi.create.foundation.ponder.elements; + +import java.util.function.Function; + +import com.simibubi.create.foundation.ponder.PonderScene; +import com.simibubi.create.foundation.utility.outliner.Outline.OutlineParams; +import com.simibubi.create.foundation.utility.outliner.Outliner; + +public class OutlinerElement extends AnimatedSceneElement { + + private Function outlinerCall; + private int overrideColor; + + public OutlinerElement(Function outlinerCall) { + this.outlinerCall = outlinerCall; + this.overrideColor = -1; + } + + @Override + public void tick(PonderScene scene) { + super.tick(scene); + if (fade.getValue() < 1/16f) + return; + if (fade.getValue(0) > fade.getValue(1)) + return; + OutlineParams params = outlinerCall.apply(scene.getOutliner()); + if (overrideColor != -1) + params.colored(overrideColor); + } + + public void setColor(int overrideColor) { + this.overrideColor = overrideColor; + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/elements/ParrotElement.java b/src/main/java/com/simibubi/create/foundation/ponder/elements/ParrotElement.java new file mode 100644 index 000000000..abcbfd691 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/elements/ParrotElement.java @@ -0,0 +1,225 @@ +package com.simibubi.create.foundation.ponder.elements; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.Create; +import com.simibubi.create.content.contraptions.base.KineticTileEntity; +import com.simibubi.create.foundation.ponder.PonderScene; +import com.simibubi.create.foundation.ponder.PonderWorld; +import com.simibubi.create.foundation.utility.AngleHelper; +import com.simibubi.create.foundation.utility.AnimationTickHolder; +import com.simibubi.create.foundation.utility.MatrixStacker; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.IRenderTypeBuffer; +import net.minecraft.client.renderer.entity.EntityRendererManager; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.passive.ParrotEntity; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; + +public class ParrotElement extends AnimatedSceneElement { + + private Vec3d location; + private ParrotEntity entity; + private ParrotPose pose; + + public static ParrotElement lookAtPOI(Vec3d location) { + ParrotElement parrotElement = new ParrotElement(location); + parrotElement.pose = parrotElement.new FacePointOfInterestPose(); + return parrotElement; + } + + public static ParrotElement spinOnComponent(Vec3d location, BlockPos componentPos) { + ParrotElement parrotElement = new ParrotElement(location); + parrotElement.pose = parrotElement.new SpinOnComponentPose(componentPos); + return parrotElement; + } + + public static ParrotElement dance(Vec3d location) { + ParrotElement parrotElement = new ParrotElement(location); + parrotElement.pose = parrotElement.new DancePose(); + return parrotElement; + } + + public static ParrotElement flappy(Vec3d location) { + ParrotElement parrotElement = new ParrotElement(location); + parrotElement.pose = parrotElement.new FlappyPose(); + return parrotElement; + } + + protected ParrotElement(Vec3d location) { + this.location = location; + } + + @Override + public void reset(PonderScene scene) { + super.reset(scene); + entity.setPos(0, 0, 0); + entity.prevPosX = 0; + entity.prevPosY = 0; + entity.prevPosZ = 0; + } + + @Override + public void tick(PonderScene scene) { + super.tick(scene); + if (entity == null) + return; + + entity.ticksExisted++; + entity.prevRotationYawHead = entity.rotationYawHead; + entity.oFlapSpeed = entity.flapSpeed; + entity.oFlap = entity.flap; + entity.onGround = true; + + pose.tick(scene); + + entity.prevPosX = entity.getX(); + entity.prevPosY = entity.getY(); + entity.prevPosZ = entity.getZ(); + entity.prevRotationYaw = entity.rotationYaw; + entity.prevRotationPitch = entity.rotationPitch; + } + + public void setPositionOffset(Vec3d position, boolean immediate) { + if (entity == null) + return; + entity.setPosition(position.x, position.y, position.z); + if (!immediate) + return; + entity.prevPosX = position.x; + entity.prevPosY = position.y; + entity.prevPosZ = position.z; + } + + public void setRotation(Vec3d eulers, boolean immediate) { + if (entity == null) + return; + entity.rotationPitch = (float) eulers.x; + entity.rotationYaw = (float) eulers.y; + if (!immediate) + return; + entity.prevRotationPitch = entity.rotationPitch; + entity.prevRotationYaw = entity.rotationYaw; + } + + public Vec3d getPositionOffset() { + return entity != null ? entity.getPositionVec() : Vec3d.ZERO; + } + + public Vec3d getRotation() { + return entity != null ? new Vec3d(entity.rotationPitch, entity.rotationYaw, 0) : Vec3d.ZERO; + } + + @Override + protected void renderLast(PonderWorld world, IRenderTypeBuffer buffer, MatrixStack ms, float fade, float pt) { + EntityRendererManager entityrenderermanager = Minecraft.getInstance() + .getRenderManager(); + + if (entity == null) + pose.create(world); + + ms.push(); + ms.translate(location.x, location.y, location.z); + ms.translate(MathHelper.lerp(pt, entity.prevPosX, entity.getX()), + MathHelper.lerp(pt, entity.prevPosY, entity.getY()), MathHelper.lerp(pt, entity.prevPosZ, entity.getZ())); + + MatrixStacker.of(ms) + .rotateY(AngleHelper.angleLerp(pt, entity.prevRotationYaw, entity.rotationYaw)); + + entityrenderermanager.render(entity, 0, 0, 0, 0, pt, ms, buffer, lightCoordsFromFade(fade)); + ms.pop(); + } + + abstract class ParrotPose { + + abstract void tick(PonderScene scene); + + void create(PonderWorld world) { + entity = new ParrotEntity(EntityType.PARROT, world); + int nextInt = Create.random.nextInt(5); + entity.setVariant(nextInt == 1 ? 0 : nextInt); // blue parrots are kinda hard to see + } + + } + + class DancePose extends ParrotPose { + + @Override + void create(PonderWorld world) { + super.create(world); + entity.setPartying(BlockPos.ZERO, true); + } + + @Override + void tick(PonderScene scene) { + entity.prevRotationYaw = entity.rotationYaw; + entity.rotationYaw -= 2; + } + + } + + class FlappyPose extends ParrotPose { + + @Override + void create(PonderWorld world) { + super.create(world); + } + + @Override + void tick(PonderScene scene) { + double length = entity.getPositionVec() + .subtract(entity.prevPosX, entity.prevPosY, entity.prevPosZ) + .length(); + entity.onGround = false; + double phase = Math.min(length * 15, 8); + float f = (float) ((AnimationTickHolder.getTicks() % 100) * phase); + entity.flapSpeed = MathHelper.sin(f) + 1; + if (length == 0) + entity.flapSpeed = 0; + } + + } + + class SpinOnComponentPose extends ParrotPose { + + private BlockPos componentPos; + + public SpinOnComponentPose(BlockPos componentPos) { + this.componentPos = componentPos; + } + + @Override + void tick(PonderScene scene) { + TileEntity tileEntity = scene.getWorld() + .getTileEntity(componentPos); + if (!(tileEntity instanceof KineticTileEntity)) + return; + float rpm = ((KineticTileEntity) tileEntity).getSpeed(); + entity.prevRotationYaw = entity.rotationYaw; + entity.rotationYaw += (rpm * .3f); + } + + } + + class FacePointOfInterestPose extends ParrotPose { + + @Override + void tick(PonderScene scene) { + Vec3d p_200602_2_ = scene.getPointOfInterest(); + Vec3d vec3d = location.add(entity.getEyePosition(0)); + double d0 = p_200602_2_.x - vec3d.x; + double d1 = p_200602_2_.y - vec3d.y; + double d2 = p_200602_2_.z - vec3d.z; + double d3 = (double) MathHelper.sqrt(d0 * d0 + d2 * d2); + entity.rotationPitch = + MathHelper.wrapDegrees((float) -(MathHelper.atan2(d1, d3) * (double) (180F / (float) Math.PI))); + entity.rotationYaw = + MathHelper.wrapDegrees((float) -(MathHelper.atan2(d2, d0) * (double) (180F / (float) Math.PI)) + 90); + } + + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/elements/PonderOverlayElement.java b/src/main/java/com/simibubi/create/foundation/ponder/elements/PonderOverlayElement.java new file mode 100644 index 000000000..89db05a60 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/elements/PonderOverlayElement.java @@ -0,0 +1,14 @@ +package com.simibubi.create.foundation.ponder.elements; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.foundation.ponder.PonderElement; +import com.simibubi.create.foundation.ponder.PonderScene; +import com.simibubi.create.foundation.ponder.PonderUI; + +public abstract class PonderOverlayElement extends PonderElement { + + public void tick(PonderScene scene) {} + + public abstract void render(PonderScene scene, PonderUI screen, MatrixStack ms, float partialTicks); + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/elements/PonderSceneElement.java b/src/main/java/com/simibubi/create/foundation/ponder/elements/PonderSceneElement.java new file mode 100644 index 000000000..dfa176d04 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/elements/PonderSceneElement.java @@ -0,0 +1,18 @@ +package com.simibubi.create.foundation.ponder.elements; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.foundation.ponder.PonderElement; +import com.simibubi.create.foundation.ponder.PonderWorld; + +import net.minecraft.client.renderer.IRenderTypeBuffer; +import net.minecraft.client.renderer.RenderType; + +public abstract class PonderSceneElement extends PonderElement { + + public abstract void renderFirst(PonderWorld world, IRenderTypeBuffer buffer, MatrixStack ms, float pt); + + public abstract void renderLayer(PonderWorld world, IRenderTypeBuffer buffer, RenderType type, MatrixStack ms, float pt); + + public abstract void renderLast(PonderWorld world, IRenderTypeBuffer buffer, MatrixStack ms, float pt); + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/elements/TextWindowElement.java b/src/main/java/com/simibubi/create/foundation/ponder/elements/TextWindowElement.java new file mode 100644 index 000000000..0afd83aee --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/elements/TextWindowElement.java @@ -0,0 +1,127 @@ +package com.simibubi.create.foundation.ponder.elements; + +import java.util.List; +import java.util.function.Supplier; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.systems.RenderSystem; +import com.simibubi.create.foundation.ponder.PonderLocalization; +import com.simibubi.create.foundation.ponder.PonderScene; +import com.simibubi.create.foundation.ponder.PonderUI; +import com.simibubi.create.foundation.ponder.content.PonderPalette; +import com.simibubi.create.foundation.utility.ColorHelper; + +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec2f; +import net.minecraft.util.math.Vec3d; +import net.minecraftforge.fml.client.gui.GuiUtils; + +public class TextWindowElement extends AnimatedOverlayElement { + + Supplier textGetter = () -> "(?) No text was provided"; + String bakedText; + + // from 0 to 200 + int y; + + Vec3d vec; + + boolean nearScene = false; + int color = PonderPalette.WHITE.getColor(); + + public class Builder { + + private PonderScene scene; + + public Builder(PonderScene scene) { + this.scene = scene; + } + + public Builder colored(PonderPalette color) { + TextWindowElement.this.color = color.getColor(); + return this; + } + + public Builder pointAt(Vec3d vec) { + TextWindowElement.this.vec = vec; + return this; + } + + public Builder independent(int y) { + TextWindowElement.this.y = y; + return this; + } + + public Builder independent() { + return independent(0); + } + + public Builder text(String defaultText) { + textGetter = scene.registerText(defaultText); + return this; + } + + public Builder sharedText(String key) { + textGetter = () -> PonderLocalization.getShared(key); + return this; + } + + public Builder placeNearTarget() { + TextWindowElement.this.nearScene = true; + return this; + } + + } + + @Override + protected void render(PonderScene scene, PonderUI screen, MatrixStack ms, float partialTicks, float fade) { + if (bakedText == null) + bakedText = textGetter.get(); + if (fade < 1 / 16f) + return; + Vec2f sceneToScreen = vec != null ? scene.getTransform() + .sceneToScreen(vec) : new Vec2f(0, (screen.height - 200) / 2 + y - 8); + + float yDiff = (screen.height / 2 - sceneToScreen.y - 10) / 100f; + int targetX = (int) (screen.width * MathHelper.lerp(yDiff * yDiff, 6f / 8, 5f / 8)); + + if (nearScene) + targetX = (int) Math.min(targetX, sceneToScreen.x + 50); + + int textWidth = Math.min(screen.width - targetX, 180); + + List list = screen.getFontRenderer() + .listFormattedStringToWidth(bakedText, textWidth); + int boxWidth = 0; + for (String string : list) + boxWidth = Math.max(boxWidth, screen.getFontRenderer() + .getStringWidth(string)); + int boxHeight = screen.getFontRenderer() + .getWordWrappedHeight(bakedText, textWidth); + + RenderSystem.pushMatrix(); + RenderSystem.translatef(0, sceneToScreen.y, 400); + + PonderUI.renderBox(targetX - 10, 3, boxWidth, boxHeight - 1, 0xaa000000, 0x30eebb00, 0x10eebb00); + + int brighterColor = ColorHelper.mixAlphaColors(color, 0xFFffffdd, 1 / 2f); + if (vec != null) { + RenderSystem.pushMatrix(); + RenderSystem.translatef(sceneToScreen.x, 0, 0); + double lineTarget = (targetX - sceneToScreen.x) * fade; + RenderSystem.scaled(lineTarget, 1, 1); + GuiUtils.drawGradientRect(-100, 0, 0, 1, 1, brighterColor, brighterColor); + GuiUtils.drawGradientRect(-100, 0, 1, 1, 2, 0xFF494949, 0xFF393939); + RenderSystem.popMatrix(); + } + + screen.getFontRenderer() + .drawSplitString(bakedText, targetX - 10, 3, textWidth, ColorHelper.applyAlpha(brighterColor, fade)); + RenderSystem.popMatrix(); + } + + public int getColor() { + return color; + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/elements/TrackedElement.java b/src/main/java/com/simibubi/create/foundation/ponder/elements/TrackedElement.java new file mode 100644 index 000000000..b7c2cd7f9 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/elements/TrackedElement.java @@ -0,0 +1,42 @@ +package com.simibubi.create.foundation.ponder.elements; + +import java.lang.ref.WeakReference; +import java.util.function.Consumer; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.foundation.ponder.PonderWorld; + +import net.minecraft.client.renderer.IRenderTypeBuffer; +import net.minecraft.client.renderer.RenderType; + +public abstract class TrackedElement extends PonderSceneElement { + + private WeakReference reference; + + public TrackedElement(T wrapped) { + this.reference = new WeakReference<>(wrapped); + } + + public void ifPresent(Consumer func) { + if (reference == null) + return; + T resolved = reference.get(); + if (resolved == null) + return; + func.accept(resolved); + } + + protected boolean isStillValid(T element) { + return true; + } + + @Override + public void renderFirst(PonderWorld world, IRenderTypeBuffer buffer, MatrixStack ms, float pt) {} + + @Override + public void renderLayer(PonderWorld world, IRenderTypeBuffer buffer, RenderType type, MatrixStack ms, float pt) {} + + @Override + public void renderLast(PonderWorld world, IRenderTypeBuffer buffer, MatrixStack ms, float pt) {} + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/elements/WorldSectionElement.java b/src/main/java/com/simibubi/create/foundation/ponder/elements/WorldSectionElement.java new file mode 100644 index 000000000..aa53b9f60 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/elements/WorldSectionElement.java @@ -0,0 +1,349 @@ +package com.simibubi.create.foundation.ponder.elements; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import org.lwjgl.opengl.GL11; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.systems.RenderSystem; +import com.simibubi.create.CreateClient; +import com.simibubi.create.foundation.ponder.PonderScene; +import com.simibubi.create.foundation.ponder.PonderWorld; +import com.simibubi.create.foundation.ponder.Selection; +import com.simibubi.create.foundation.render.Compartment; +import com.simibubi.create.foundation.render.SuperByteBuffer; +import com.simibubi.create.foundation.render.SuperByteBufferCache; +import com.simibubi.create.foundation.render.TileEntityRenderHelper; +import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer; +import com.simibubi.create.foundation.utility.AnimationTickHolder; +import com.simibubi.create.foundation.utility.MatrixStacker; +import com.simibubi.create.foundation.utility.Pair; +import com.simibubi.create.foundation.utility.VecHelper; + +import net.minecraft.block.BlockRenderType; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.BlockModelRenderer; +import net.minecraft.client.renderer.BlockRendererDispatcher; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.IRenderTypeBuffer; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.RenderTypeLookup; +import net.minecraft.client.renderer.WorldRenderer; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.fluid.IFluidState; +import net.minecraft.tileentity.ITickableTileEntity; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.RayTraceContext; +import net.minecraft.util.math.RayTraceContext.BlockMode; +import net.minecraft.util.math.RayTraceContext.FluidMode; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.shapes.ISelectionContext; +import net.minecraft.util.math.shapes.VoxelShape; +import net.minecraftforge.client.ForgeHooksClient; +import net.minecraftforge.client.model.data.EmptyModelData; + +public class WorldSectionElement extends AnimatedSceneElement { + + public static final Compartment> DOC_WORLD_SECTION = new Compartment<>(); + + List renderedTileEntities; + Selection section; + boolean redraw; + + Vec3d prevAnimatedOffset = Vec3d.ZERO; + Vec3d animatedOffset = Vec3d.ZERO; + Vec3d prevAnimatedRotation = Vec3d.ZERO; + Vec3d animatedRotation = Vec3d.ZERO; + Vec3d centerOfRotation = Vec3d.ZERO; + + BlockPos selectedBlock; + + public WorldSectionElement() {} + + public WorldSectionElement(Selection section) { + this.section = section.copy(); + centerOfRotation = section.getCenter(); + } + + public void mergeOnto(WorldSectionElement other) { + setVisible(false); + if (other.isEmpty()) + other.set(section); + else + other.add(section); + } + + public void set(Selection selection) { + applyNewSelection(selection.copy()); + } + + public void add(Selection toAdd) { + applyNewSelection(this.section.add(toAdd)); + } + + public void erase(Selection toErase) { + applyNewSelection(this.section.substract(toErase)); + } + + private void applyNewSelection(Selection selection) { + this.section = selection; + queueRedraw(); + } + + public void setCenterOfRotation(Vec3d center) { + centerOfRotation = center; + } + + @Override + public void reset(PonderScene scene) { + super.reset(scene); + resetAnimatedTransform(); + resetSelectedBlock(); + } + + public void selectBlock(BlockPos pos) { + selectedBlock = pos; + } + + public void resetSelectedBlock() { + selectedBlock = null; + } + + public void resetAnimatedTransform() { + prevAnimatedOffset = Vec3d.ZERO; + animatedOffset = Vec3d.ZERO; + prevAnimatedRotation = Vec3d.ZERO; + animatedRotation = Vec3d.ZERO; + } + + public void queueRedraw() { + redraw = true; + } + + public boolean isEmpty() { + return section == null; + } + + public void setEmpty() { + section = null; + } + + public void setAnimatedRotation(Vec3d eulerAngles, boolean force) { + this.animatedRotation = eulerAngles; + if (force) + prevAnimatedRotation = animatedRotation; + } + + public Vec3d getAnimatedRotation() { + return animatedRotation; + } + + public void setAnimatedOffset(Vec3d offset, boolean force) { + this.animatedOffset = offset; + if (force) + prevAnimatedOffset = animatedOffset; + } + + public Vec3d getAnimatedOffset() { + return animatedOffset; + } + + @Override + public boolean isVisible() { + return super.isVisible() && !isEmpty(); + } + + class WorldSectionRayTraceResult { + Vec3d actualHitVec; + BlockPos worldPos; + } + + public Pair rayTrace(PonderWorld world, Vec3d source, Vec3d target) { + world.setMask(this.section); + Vec3d transformedTarget = reverseTransformVec(target); + BlockRayTraceResult rayTraceBlocks = world.rayTraceBlocks(new RayTraceContext(reverseTransformVec(source), + transformedTarget, BlockMode.OUTLINE, FluidMode.NONE, null)); + world.clearMask(); + + if (rayTraceBlocks == null) + return null; + if (rayTraceBlocks.getHitVec() == null) + return null; + + double t = rayTraceBlocks.getHitVec() + .subtract(transformedTarget) + .lengthSquared() + / source.subtract(target) + .lengthSquared(); + Vec3d actualHit = VecHelper.lerp((float) t, target, source); + return Pair.of(actualHit, rayTraceBlocks.getPos()); + } + + private Vec3d reverseTransformVec(Vec3d in) { + float pt = AnimationTickHolder.getPartialTicks(); + in = in.subtract(VecHelper.lerp(pt, prevAnimatedOffset, animatedOffset)); + if (!animatedRotation.equals(Vec3d.ZERO) || !prevAnimatedRotation.equals(Vec3d.ZERO)) { + if (centerOfRotation == null) + centerOfRotation = section.getCenter(); + in = in.subtract(centerOfRotation); + in = VecHelper.rotate(in, -MathHelper.lerp(pt, prevAnimatedRotation.x, animatedRotation.x), Axis.X); + in = VecHelper.rotate(in, -MathHelper.lerp(pt, prevAnimatedRotation.z, animatedRotation.z), Axis.Z); + in = VecHelper.rotate(in, -MathHelper.lerp(pt, prevAnimatedRotation.y, animatedRotation.y), Axis.Y); + in = in.add(centerOfRotation); + } + return in; + } + + public void transformMS(MatrixStack ms, float pt) { + MatrixStacker.of(ms) + .translate(VecHelper.lerp(pt, prevAnimatedOffset, animatedOffset)); + if (!animatedRotation.equals(Vec3d.ZERO) || !prevAnimatedRotation.equals(Vec3d.ZERO)) { + if (centerOfRotation == null) + centerOfRotation = section.getCenter(); + MatrixStacker.of(ms) + .translate(centerOfRotation) + .rotateX(MathHelper.lerp(pt, prevAnimatedRotation.x, animatedRotation.x)) + .rotateZ(MathHelper.lerp(pt, prevAnimatedRotation.z, animatedRotation.z)) + .rotateY(MathHelper.lerp(pt, prevAnimatedRotation.y, animatedRotation.y)) + .translateBack(centerOfRotation); + } + } + + public void tick(PonderScene scene) { + prevAnimatedOffset = animatedOffset; + prevAnimatedRotation = animatedRotation; + if (!isVisible()) + return; + if (renderedTileEntities == null) + return; + renderedTileEntities.forEach(te -> { + if (te instanceof ITickableTileEntity) + ((ITickableTileEntity) te).tick(); + }); + } + + @Override + protected void renderLayer(PonderWorld world, IRenderTypeBuffer buffer, RenderType type, MatrixStack ms, float fade, + float pt) { + transformMS(ms, pt); + renderStructure(world, ms, buffer, type, fade); + } + + @Override + public void renderFirst(PonderWorld world, IRenderTypeBuffer buffer, MatrixStack ms, float fade, float pt) { + int light = -1; + if (fade != 1) + light = (int) (MathHelper.lerp(fade, 5, 14)); + if (redraw) + renderedTileEntities = null; + transformMS(ms, pt); + world.pushFakeLight(light); + renderTileEntities(world, ms, buffer, pt); + world.popLight(); + } + + protected void renderStructure(PonderWorld world, MatrixStack ms, IRenderTypeBuffer buffer, RenderType type, + float fade) { + SuperByteBufferCache bufferCache = CreateClient.bufferCache; + int code = hashCode() ^ world.hashCode(); + + Pair key = Pair.of(code, RenderType.getBlockLayers() + .indexOf(type)); + if (redraw) + bufferCache.invalidate(DOC_WORLD_SECTION, key); + SuperByteBuffer contraptionBuffer = + bufferCache.get(DOC_WORLD_SECTION, key, () -> buildStructureBuffer(world, type)); + if (contraptionBuffer.isEmpty()) + return; + + int light = lightCoordsFromFade(fade); + contraptionBuffer.light(light) + .renderInto(ms, buffer.getBuffer(type)); + } + + @Override + protected void renderLast(PonderWorld world, IRenderTypeBuffer buffer, MatrixStack ms, float fade, float pt) { + redraw = false; + if (selectedBlock == null) + return; + BlockState blockState = world.getBlockState(selectedBlock); + if (blockState.isAir(world, selectedBlock)) + return; + VoxelShape shape = + blockState.getShape(world, selectedBlock, ISelectionContext.forEntity(Minecraft.getInstance().player)); + if (shape.isEmpty()) + return; + + ms.push(); + transformMS(ms, pt); + RenderSystem.disableTexture(); + WorldRenderer.drawBox(ms, buffer.getBuffer(RenderType.getLines()), shape.getBoundingBox() + .offset(selectedBlock), 1, 1, 1, 1); + if (buffer instanceof SuperRenderTypeBuffer) + ((SuperRenderTypeBuffer) buffer).draw(RenderType.getLines()); + RenderSystem.enableTexture(); + ms.pop(); + } + + private void renderTileEntities(PonderWorld world, MatrixStack ms, IRenderTypeBuffer buffer, float pt) { + if (renderedTileEntities == null) { + renderedTileEntities = new ArrayList<>(); + section.forEach(pos -> { + TileEntity tileEntity = world.getTileEntity(pos); + if (tileEntity == null) + return; + renderedTileEntities.add(tileEntity); + tileEntity.updateContainingBlockInfo(); + }); + } else + renderedTileEntities.removeIf(te -> world.getTileEntity(te.getPos()) != te); + TileEntityRenderHelper.renderTileEntities(world, renderedTileEntities, ms, new MatrixStack(), buffer, pt); + } + + private SuperByteBuffer buildStructureBuffer(PonderWorld world, RenderType layer) { + ForgeHooksClient.setRenderLayer(layer); + MatrixStack ms = new MatrixStack(); + BlockRendererDispatcher dispatcher = Minecraft.getInstance() + .getBlockRendererDispatcher(); + BlockModelRenderer blockRenderer = dispatcher.getBlockModelRenderer(); + Random random = new Random(); + BufferBuilder builder = new BufferBuilder(DefaultVertexFormats.BLOCK.getIntegerSize()); + builder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK); + world.setMask(this.section); + + section.forEach(pos -> { + BlockState state = world.getBlockState(pos); + IFluidState ifluidstate = world.getFluidState(pos); + + ms.push(); + ms.translate(pos.getX(), pos.getY(), pos.getZ()); + + if (state.getRenderType() != BlockRenderType.ENTITYBLOCK_ANIMATED && state.getBlock() != Blocks.AIR + && RenderTypeLookup.canRenderInLayer(state, layer)) { + TileEntity tileEntity = world.getTileEntity(pos); + blockRenderer.renderModel(world, dispatcher.getModelForState(state), state, pos, ms, builder, true, + random, 42, OverlayTexture.DEFAULT_UV, + tileEntity != null ? tileEntity.getModelData() : EmptyModelData.INSTANCE); + } + + if (!ifluidstate.isEmpty() && RenderTypeLookup.canRenderInLayer(ifluidstate, layer)) + dispatcher.renderFluid(pos, world, builder, ifluidstate); + + ms.pop(); + }); + + world.clearMask(); + builder.finishDrawing(); + return new SuperByteBuffer(builder); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/instructions/AnimateElementInstruction.java b/src/main/java/com/simibubi/create/foundation/ponder/instructions/AnimateElementInstruction.java new file mode 100644 index 000000000..629f31085 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/instructions/AnimateElementInstruction.java @@ -0,0 +1,57 @@ +package com.simibubi.create.foundation.ponder.instructions; + +import java.util.function.BiConsumer; +import java.util.function.Function; + +import com.simibubi.create.foundation.ponder.ElementLink; +import com.simibubi.create.foundation.ponder.PonderScene; +import com.simibubi.create.foundation.ponder.elements.PonderSceneElement; + +import net.minecraft.util.math.Vec3d; + +public class AnimateElementInstruction extends TickingInstruction { + + protected Vec3d deltaPerTick; + protected Vec3d totalDelta; + protected Vec3d target; + protected ElementLink link; + protected T element; + + private BiConsumer setter; + private Function getter; + + protected AnimateElementInstruction(ElementLink link, Vec3d totalDelta, int ticks, + BiConsumer setter, Function getter) { + super(false, ticks); + this.link = link; + this.setter = setter; + this.getter = getter; + this.deltaPerTick = totalDelta.scale(1d / ticks); + this.totalDelta = totalDelta; + this.target = totalDelta; + } + + @Override + protected final void firstTick(PonderScene scene) { + super.firstTick(scene); + element = scene.resolve(link); + if (element == null) + return; + target = getter.apply(element) + .add(totalDelta); + } + + @Override + public void tick(PonderScene scene) { + super.tick(scene); + if (element == null) + return; + if (remainingTicks == 0) { + setter.accept(element, target); + return; + } + setter.accept(element, getter.apply(element) + .add(deltaPerTick)); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/instructions/AnimateParrotInstruction.java b/src/main/java/com/simibubi/create/foundation/ponder/instructions/AnimateParrotInstruction.java new file mode 100644 index 000000000..69f44417a --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/instructions/AnimateParrotInstruction.java @@ -0,0 +1,28 @@ +package com.simibubi.create.foundation.ponder.instructions; + +import java.util.function.BiConsumer; +import java.util.function.Function; + +import com.simibubi.create.foundation.ponder.ElementLink; +import com.simibubi.create.foundation.ponder.elements.ParrotElement; + +import net.minecraft.util.math.Vec3d; + +public class AnimateParrotInstruction extends AnimateElementInstruction { + + public static AnimateParrotInstruction rotate(ElementLink link, Vec3d rotation, int ticks) { + return new AnimateParrotInstruction(link, rotation, ticks, (wse, v) -> wse.setRotation(v, ticks == 0), + ParrotElement::getRotation); + } + + public static AnimateParrotInstruction move(ElementLink link, Vec3d offset, int ticks) { + return new AnimateParrotInstruction(link, offset, ticks, (wse, v) -> wse.setPositionOffset(v, ticks == 0), + ParrotElement::getPositionOffset); + } + + protected AnimateParrotInstruction(ElementLink link, Vec3d totalDelta, int ticks, + BiConsumer setter, Function getter) { + super(link, totalDelta, ticks, setter, getter); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/instructions/AnimateTileEntityInstruction.java b/src/main/java/com/simibubi/create/foundation/ponder/instructions/AnimateTileEntityInstruction.java new file mode 100644 index 000000000..99e1e8f2b --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/instructions/AnimateTileEntityInstruction.java @@ -0,0 +1,70 @@ +package com.simibubi.create.foundation.ponder.instructions; + +import java.util.Optional; +import java.util.function.BiConsumer; +import java.util.function.Function; + +import com.simibubi.create.content.contraptions.components.structureMovement.bearing.MechanicalBearingTileEntity; +import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyTileEntity; +import com.simibubi.create.foundation.ponder.PonderScene; +import com.simibubi.create.foundation.ponder.PonderWorld; + +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; + +public class AnimateTileEntityInstruction extends TickingInstruction { + + protected double deltaPerTick; + protected double totalDelta; + protected double target; + protected final BlockPos location; + + private BiConsumer setter; + private Function getter; + + public static AnimateTileEntityInstruction bearing(BlockPos location, float totalDelta, int ticks) { + return new AnimateTileEntityInstruction(location, totalDelta, ticks, + (w, f) -> castIfPresent(w, location, MechanicalBearingTileEntity.class).ifPresent(bte -> bte.setAngle(f)), + (w) -> castIfPresent(w, location, MechanicalBearingTileEntity.class).map(bte -> bte.getInterpolatedAngle(0)) + .orElse(0f)); + } + + public static AnimateTileEntityInstruction pulley(BlockPos location, float totalDelta, int ticks) { + return new AnimateTileEntityInstruction(location, totalDelta, ticks, + (w, f) -> castIfPresent(w, location, PulleyTileEntity.class).ifPresent(pulley -> pulley.offset = f), + (w) -> castIfPresent(w, location, PulleyTileEntity.class).map(pulley -> pulley.offset) + .orElse(0f)); + } + + protected AnimateTileEntityInstruction(BlockPos location, float totalDelta, int ticks, + BiConsumer setter, Function getter) { + super(false, ticks); + this.location = location; + this.setter = setter; + this.getter = getter; + this.deltaPerTick = totalDelta * (1d / ticks); + this.totalDelta = totalDelta; + this.target = totalDelta; + } + + @Override + protected final void firstTick(PonderScene scene) { + super.firstTick(scene); + target = getter.apply(scene.getWorld()) + totalDelta; + } + + @Override + public void tick(PonderScene scene) { + super.tick(scene); + PonderWorld world = scene.getWorld(); + setter.accept(world, (float) (remainingTicks == 0 ? target : getter.apply(world) + deltaPerTick)); + } + + private static Optional castIfPresent(PonderWorld world, BlockPos pos, Class teType) { + TileEntity tileEntity = world.getTileEntity(pos); + if (teType.isInstance(tileEntity)) + return Optional.of(teType.cast(tileEntity)); + return Optional.empty(); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/instructions/AnimateWorldSectionInstruction.java b/src/main/java/com/simibubi/create/foundation/ponder/instructions/AnimateWorldSectionInstruction.java new file mode 100644 index 000000000..c73f70dc4 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/instructions/AnimateWorldSectionInstruction.java @@ -0,0 +1,29 @@ +package com.simibubi.create.foundation.ponder.instructions; + +import java.util.function.BiConsumer; +import java.util.function.Function; + +import com.simibubi.create.foundation.ponder.ElementLink; +import com.simibubi.create.foundation.ponder.elements.WorldSectionElement; + +import net.minecraft.util.math.Vec3d; + +public class AnimateWorldSectionInstruction extends AnimateElementInstruction { + + public static AnimateWorldSectionInstruction rotate(ElementLink link, Vec3d rotation, + int ticks) { + return new AnimateWorldSectionInstruction(link, rotation, ticks, + (wse, v) -> wse.setAnimatedRotation(v, ticks == 0), WorldSectionElement::getAnimatedRotation); + } + + public static AnimateWorldSectionInstruction move(ElementLink link, Vec3d offset, int ticks) { + return new AnimateWorldSectionInstruction(link, offset, ticks, (wse, v) -> wse.setAnimatedOffset(v, ticks == 0), + WorldSectionElement::getAnimatedOffset); + } + + protected AnimateWorldSectionInstruction(ElementLink link, Vec3d totalDelta, int ticks, + BiConsumer setter, Function getter) { + super(link, totalDelta, ticks, setter, getter); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/instructions/ChaseAABBInstruction.java b/src/main/java/com/simibubi/create/foundation/ponder/instructions/ChaseAABBInstruction.java new file mode 100644 index 000000000..e0a19f30b --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/instructions/ChaseAABBInstruction.java @@ -0,0 +1,30 @@ +package com.simibubi.create.foundation.ponder.instructions; + +import com.simibubi.create.foundation.ponder.PonderScene; +import com.simibubi.create.foundation.ponder.content.PonderPalette; + +import net.minecraft.util.math.AxisAlignedBB; + +public class ChaseAABBInstruction extends TickingInstruction { + + private AxisAlignedBB bb; + private Object slot; + private PonderPalette color; + + public ChaseAABBInstruction(PonderPalette color, Object slot, AxisAlignedBB bb, int ticks) { + super(false, ticks); + this.color = color; + this.slot = slot; + this.bb = bb; + } + + @Override + public void tick(PonderScene scene) { + super.tick(scene); + scene.getOutliner() + .chaseAABB(slot, bb) + .lineWidth(1 / 16f) + .colored(color.getColor()); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/instructions/CreateParrotInstruction.java b/src/main/java/com/simibubi/create/foundation/ponder/instructions/CreateParrotInstruction.java new file mode 100644 index 000000000..56ada8ae2 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/instructions/CreateParrotInstruction.java @@ -0,0 +1,18 @@ +package com.simibubi.create.foundation.ponder.instructions; + +import com.simibubi.create.foundation.ponder.elements.ParrotElement; + +import net.minecraft.util.Direction; + +public class CreateParrotInstruction extends FadeIntoSceneInstruction { + + public CreateParrotInstruction(int fadeInTicks, Direction fadeInFrom, ParrotElement element) { + super(fadeInTicks, fadeInFrom, element); + } + + @Override + protected Class getElementClass() { + return ParrotElement.class; + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/instructions/DelayInstruction.java b/src/main/java/com/simibubi/create/foundation/ponder/instructions/DelayInstruction.java new file mode 100644 index 000000000..0965aa74b --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/instructions/DelayInstruction.java @@ -0,0 +1,9 @@ +package com.simibubi.create.foundation.ponder.instructions; + +public class DelayInstruction extends TickingInstruction { + + public DelayInstruction(int ticks) { + super(true, ticks); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/instructions/DisplayWorldSectionInstruction.java b/src/main/java/com/simibubi/create/foundation/ponder/instructions/DisplayWorldSectionInstruction.java new file mode 100644 index 000000000..e180ac92a --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/instructions/DisplayWorldSectionInstruction.java @@ -0,0 +1,44 @@ +package com.simibubi.create.foundation.ponder.instructions; + +import java.util.Optional; +import java.util.function.Supplier; + +import com.simibubi.create.foundation.ponder.PonderScene; +import com.simibubi.create.foundation.ponder.Selection; +import com.simibubi.create.foundation.ponder.elements.WorldSectionElement; + +import net.minecraft.util.Direction; + +public class DisplayWorldSectionInstruction extends FadeIntoSceneInstruction { + + private Selection initialSelection; + private Optional> mergeOnto; + + public DisplayWorldSectionInstruction(int fadeInTicks, Direction fadeInFrom, Selection selection, + Optional> mergeOnto) { + super(fadeInTicks, fadeInFrom, new WorldSectionElement(selection)); + initialSelection = selection; + this.mergeOnto = mergeOnto; + } + + @Override + protected void firstTick(PonderScene scene) { + super.firstTick(scene); + element.set(initialSelection); + element.setVisible(true); + } + + @Override + public void tick(PonderScene scene) { + super.tick(scene); + if (remainingTicks > 0) + return; + mergeOnto.ifPresent(c -> element.mergeOnto(c.get())); + } + + @Override + protected Class getElementClass() { + return WorldSectionElement.class; + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/instructions/EmitParticlesInstruction.java b/src/main/java/com/simibubi/create/foundation/ponder/instructions/EmitParticlesInstruction.java new file mode 100644 index 000000000..eb4a85f6c --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/instructions/EmitParticlesInstruction.java @@ -0,0 +1,56 @@ +package com.simibubi.create.foundation.ponder.instructions; + +import com.simibubi.create.Create; +import com.simibubi.create.foundation.ponder.PonderScene; +import com.simibubi.create.foundation.ponder.PonderWorld; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.particle.ParticleManager; +import net.minecraft.particles.IParticleData; +import net.minecraft.util.math.Vec3d; + +public class EmitParticlesInstruction extends TickingInstruction { + + private Vec3d anchor; + private Emitter emitter; + private float runsPerTick; + + @FunctionalInterface + public static interface Emitter { + + public static Emitter simple(T data, Vec3d motion) { + return (w, x, y, z) -> w.addParticle(data, x, y, z, motion.x, motion.y, motion.z); + } + + public static Emitter withinBlockSpace(T data, Vec3d motion) { + return (w, x, y, z) -> w.addParticle(data, Math.floor(x) + Create.random.nextFloat(), + Math.floor(y) + Create.random.nextFloat(), Math.floor(z) + Create.random.nextFloat(), motion.x, + motion.y, motion.z); + } + + static ParticleManager paticleManager() { + return Minecraft.getInstance().particles; + } + + public void create(PonderWorld world, double x, double y, double z); + + } + + public EmitParticlesInstruction(Vec3d anchor, Emitter emitter, float runsPerTick, int ticks) { + super(false, ticks); + this.anchor = anchor; + this.emitter = emitter; + this.runsPerTick = runsPerTick; + } + + @Override + public void tick(PonderScene scene) { + super.tick(scene); + int runs = (int) runsPerTick; + if (Create.random.nextFloat() < (runsPerTick - runs)) + runs++; + for (int i = 0; i < runs; i++) + emitter.create(scene.getWorld(), anchor.x, anchor.y, anchor.z); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/instructions/FadeInOutInstruction.java b/src/main/java/com/simibubi/create/foundation/ponder/instructions/FadeInOutInstruction.java new file mode 100644 index 000000000..a7f195ffe --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/instructions/FadeInOutInstruction.java @@ -0,0 +1,49 @@ +package com.simibubi.create.foundation.ponder.instructions; + +import com.simibubi.create.foundation.ponder.PonderScene; + +public abstract class FadeInOutInstruction extends TickingInstruction { + + protected static final int fadeTime = 5; + + public FadeInOutInstruction(int duration) { + super(false, duration + 2 * fadeTime); + } + + protected abstract void show(PonderScene scene); + + protected abstract void hide(PonderScene scene); + + protected abstract void applyFade(PonderScene scene, float fade); + + @Override + protected void firstTick(PonderScene scene) { + super.firstTick(scene); + show(scene); + applyFade(scene, 0); + } + + @Override + public void tick(PonderScene scene) { + super.tick(scene); + int elapsed = totalTicks - remainingTicks; + + if (elapsed < fadeTime) { + float fade = (elapsed / (float) fadeTime); + applyFade(scene, fade * fade); + + } else if (remainingTicks < fadeTime) { + float fade = (remainingTicks / (float) fadeTime); + applyFade(scene, fade * fade); + + } else + applyFade(scene, 1); + + if (remainingTicks == 0) { + applyFade(scene, 0); + hide(scene); + } + + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/instructions/FadeIntoSceneInstruction.java b/src/main/java/com/simibubi/create/foundation/ponder/instructions/FadeIntoSceneInstruction.java new file mode 100644 index 000000000..a45b1d967 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/instructions/FadeIntoSceneInstruction.java @@ -0,0 +1,49 @@ +package com.simibubi.create.foundation.ponder.instructions; + +import com.simibubi.create.foundation.ponder.ElementLink; +import com.simibubi.create.foundation.ponder.PonderScene; +import com.simibubi.create.foundation.ponder.elements.AnimatedSceneElement; + +import net.minecraft.util.Direction; +import net.minecraft.util.math.Vec3d; + +public abstract class FadeIntoSceneInstruction extends TickingInstruction { + + private Direction fadeInFrom; + protected T element; + private ElementLink elementLink; + + public FadeIntoSceneInstruction(int fadeInTicks, Direction fadeInFrom, T element) { + super(false, fadeInTicks); + this.fadeInFrom = fadeInFrom; + this.element = element; + } + + @Override + protected void firstTick(PonderScene scene) { + super.firstTick(scene); + scene.addElement(element); + element.setFade(0); + element.setFadeVec(new Vec3d(fadeInFrom.getDirectionVec()).scale(.5f)); + if (elementLink != null) + scene.linkElement(element, elementLink); + } + + @Override + public void tick(PonderScene scene) { + super.tick(scene); + float fade = (remainingTicks / (float) totalTicks); + element.setFade(1 - fade * fade); + if (remainingTicks == 0) + element.setFade(1); + } + + public ElementLink createLink(PonderScene scene) { + elementLink = new ElementLink<>(getElementClass()); + scene.linkElement(element, elementLink); + return elementLink; + } + + protected abstract Class getElementClass(); + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/instructions/FadeOutOfSceneInstruction.java b/src/main/java/com/simibubi/create/foundation/ponder/instructions/FadeOutOfSceneInstruction.java new file mode 100644 index 000000000..88545e101 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/instructions/FadeOutOfSceneInstruction.java @@ -0,0 +1,46 @@ +package com.simibubi.create.foundation.ponder.instructions; + +import com.simibubi.create.foundation.ponder.ElementLink; +import com.simibubi.create.foundation.ponder.PonderScene; +import com.simibubi.create.foundation.ponder.elements.AnimatedSceneElement; + +import net.minecraft.util.Direction; +import net.minecraft.util.math.Vec3d; + +public class FadeOutOfSceneInstruction extends TickingInstruction { + + private Direction fadeOutTo; + private ElementLink link; + private T element; + + public FadeOutOfSceneInstruction(int fadeOutTicks, Direction fadeOutTo, ElementLink link) { + super(false, fadeOutTicks); + this.fadeOutTo = fadeOutTo.getOpposite(); + this.link = link; + } + + @Override + protected void firstTick(PonderScene scene) { + super.firstTick(scene); + element = scene.resolve(link); + if (element == null) + return; + element.setVisible(true); + element.setFade(1); + element.setFadeVec(new Vec3d(fadeOutTo.getDirectionVec()).scale(.5f)); + } + + @Override + public void tick(PonderScene scene) { + super.tick(scene); + if (element == null) + return; + float fade = (remainingTicks / (float) totalTicks); + element.setFade(1 - (1 - fade) * (1 - fade)); + if (remainingTicks == 0) { + element.setVisible(false); + element.setFade(0); + } + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/instructions/HideAllInstruction.java b/src/main/java/com/simibubi/create/foundation/ponder/instructions/HideAllInstruction.java new file mode 100644 index 000000000..4849d2a64 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/instructions/HideAllInstruction.java @@ -0,0 +1,55 @@ +package com.simibubi.create.foundation.ponder.instructions; + +import com.simibubi.create.foundation.ponder.PonderScene; +import com.simibubi.create.foundation.ponder.elements.AnimatedOverlayElement; +import com.simibubi.create.foundation.ponder.elements.AnimatedSceneElement; + +import net.minecraft.util.Direction; +import net.minecraft.util.math.Vec3d; + +public class HideAllInstruction extends TickingInstruction { + + private Direction fadeOutTo; + + public HideAllInstruction(int fadeOutTicks, Direction fadeOutTo) { + super(false, fadeOutTicks); + this.fadeOutTo = fadeOutTo; + } + + @Override + protected void firstTick(PonderScene scene) { + super.firstTick(scene); + scene.getElements() + .forEach(element -> { + if (element instanceof AnimatedSceneElement) { + AnimatedSceneElement animatedSceneElement = (AnimatedSceneElement) element; + animatedSceneElement.setFade(1); + animatedSceneElement + .setFadeVec(fadeOutTo == null ? null : new Vec3d(fadeOutTo.getDirectionVec()).scale(.5f)); + } else if (element instanceof AnimatedOverlayElement) { + AnimatedOverlayElement animatedSceneElement = (AnimatedOverlayElement) element; + animatedSceneElement.setFade(1); + } else + element.setVisible(false); + }); + } + + @Override + public void tick(PonderScene scene) { + super.tick(scene); + float fade = (remainingTicks / (float) totalTicks); + + scene.forEach(AnimatedSceneElement.class, ase -> { + ase.setFade(fade * fade); + if (remainingTicks == 0) + ase.setFade(0); + }); + + scene.forEach(AnimatedOverlayElement.class, aoe -> { + aoe.setFade(fade * fade); + if (remainingTicks == 0) + aoe.setFade(0); + }); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/instructions/LineInstruction.java b/src/main/java/com/simibubi/create/foundation/ponder/instructions/LineInstruction.java new file mode 100644 index 000000000..2a18361b0 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/instructions/LineInstruction.java @@ -0,0 +1,30 @@ +package com.simibubi.create.foundation.ponder.instructions; + +import com.simibubi.create.foundation.ponder.PonderScene; +import com.simibubi.create.foundation.ponder.content.PonderPalette; + +import net.minecraft.util.math.Vec3d; + +public class LineInstruction extends TickingInstruction { + + private PonderPalette color; + private Vec3d start; + private Vec3d end; + + public LineInstruction(PonderPalette color, Vec3d start, Vec3d end, int ticks) { + super(false, ticks); + this.color = color; + this.start = start; + this.end = end; + } + + @Override + public void tick(PonderScene scene) { + super.tick(scene); + scene.getOutliner() + .showLine(start, start, end) + .lineWidth(1 / 16f) + .colored(color.getColor()); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/instructions/MarkAsFinishedInstruction.java b/src/main/java/com/simibubi/create/foundation/ponder/instructions/MarkAsFinishedInstruction.java new file mode 100644 index 000000000..a7f2e15b2 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/instructions/MarkAsFinishedInstruction.java @@ -0,0 +1,18 @@ +package com.simibubi.create.foundation.ponder.instructions; + +import com.simibubi.create.foundation.ponder.PonderInstruction; +import com.simibubi.create.foundation.ponder.PonderScene; + +public class MarkAsFinishedInstruction extends PonderInstruction { + + @Override + public boolean isComplete() { + return true; + } + + @Override + public void tick(PonderScene scene) { + scene.setFinished(true); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/instructions/MovePoiInstruction.java b/src/main/java/com/simibubi/create/foundation/ponder/instructions/MovePoiInstruction.java new file mode 100644 index 000000000..7209eda0f --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/instructions/MovePoiInstruction.java @@ -0,0 +1,26 @@ +package com.simibubi.create.foundation.ponder.instructions; + +import com.simibubi.create.foundation.ponder.PonderInstruction; +import com.simibubi.create.foundation.ponder.PonderScene; + +import net.minecraft.util.math.Vec3d; + +public class MovePoiInstruction extends PonderInstruction { + + private Vec3d poi; + + public MovePoiInstruction(Vec3d poi) { + this.poi = poi; + } + + @Override + public boolean isComplete() { + return true; + } + + @Override + public void tick(PonderScene scene) { + scene.setPointOfInterest(poi); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/instructions/OutlineSelectionInstruction.java b/src/main/java/com/simibubi/create/foundation/ponder/instructions/OutlineSelectionInstruction.java new file mode 100644 index 000000000..23207f9fc --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/instructions/OutlineSelectionInstruction.java @@ -0,0 +1,28 @@ +package com.simibubi.create.foundation.ponder.instructions; + +import com.simibubi.create.foundation.ponder.PonderScene; +import com.simibubi.create.foundation.ponder.Selection; +import com.simibubi.create.foundation.ponder.content.PonderPalette; + +public class OutlineSelectionInstruction extends TickingInstruction { + + private PonderPalette color; + private Object slot; + private Selection selection; + + public OutlineSelectionInstruction(PonderPalette color, Object slot, Selection selection, int ticks) { + super(false, ticks); + this.color = color; + this.slot = slot; + this.selection = selection; + } + + @Override + public void tick(PonderScene scene) { + super.tick(scene); + selection.makeOutline(scene.getOutliner(), slot) + .lineWidth(1 / 16f) + .colored(color.getColor()); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/instructions/ReplaceBlocksInstruction.java b/src/main/java/com/simibubi/create/foundation/ponder/instructions/ReplaceBlocksInstruction.java new file mode 100644 index 000000000..d71ad0919 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/instructions/ReplaceBlocksInstruction.java @@ -0,0 +1,47 @@ +package com.simibubi.create.foundation.ponder.instructions; + +import java.util.function.UnaryOperator; + +import com.simibubi.create.foundation.ponder.PonderScene; +import com.simibubi.create.foundation.ponder.PonderWorld; +import com.simibubi.create.foundation.ponder.Selection; + +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; + +public class ReplaceBlocksInstruction extends WorldModifyInstruction { + + private UnaryOperator stateToUse; + private boolean replaceAir; + private boolean spawnParticles; + + public ReplaceBlocksInstruction(Selection selection, UnaryOperator stateToUse, boolean replaceAir, + boolean spawnParticles) { + super(selection); + this.stateToUse = stateToUse; + this.replaceAir = replaceAir; + this.spawnParticles = spawnParticles; + } + + @Override + protected void runModification(Selection selection, PonderScene scene) { + PonderWorld world = scene.getWorld(); + selection.forEach(pos -> { + if (!world.getBounds() + .isVecInside(pos)) + return; + BlockState prevState = world.getBlockState(pos); + if (!replaceAir && prevState == Blocks.AIR.getDefaultState()) + return; + if (spawnParticles) + world.addBlockDestroyEffects(pos, prevState); + world.setBlockState(pos, stateToUse.apply(prevState)); + }); + } + + @Override + protected boolean needsRedraw() { + return true; + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/instructions/RotateSceneInstruction.java b/src/main/java/com/simibubi/create/foundation/ponder/instructions/RotateSceneInstruction.java new file mode 100644 index 000000000..04c49d793 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/instructions/RotateSceneInstruction.java @@ -0,0 +1,34 @@ +package com.simibubi.create.foundation.ponder.instructions; + +import com.simibubi.create.foundation.ponder.PonderInstruction; +import com.simibubi.create.foundation.ponder.PonderScene; +import com.simibubi.create.foundation.ponder.PonderScene.SceneTransform; +import com.simibubi.create.foundation.utility.LerpedFloat.Chaser; + +public class RotateSceneInstruction extends PonderInstruction { + + private float xRot; + private float yRot; + private boolean relative; + + public RotateSceneInstruction(float xRot, float yRot, boolean relative) { + this.xRot = xRot; + this.yRot = yRot; + this.relative = relative; + } + + @Override + public boolean isComplete() { + return true; + } + + @Override + public void tick(PonderScene scene) { + SceneTransform transform = scene.getTransform(); + float targetX = relative ? transform.xRotation.getChaseTarget() + xRot : xRot; + float targetY = relative ? transform.yRotation.getChaseTarget() + yRot : yRot; + transform.xRotation.chase(targetX, .1f, Chaser.EXP); + transform.yRotation.chase(targetY, .1f, Chaser.EXP); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/instructions/ShowInputInstruction.java b/src/main/java/com/simibubi/create/foundation/ponder/instructions/ShowInputInstruction.java new file mode 100644 index 000000000..4a1864478 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/instructions/ShowInputInstruction.java @@ -0,0 +1,31 @@ +package com.simibubi.create.foundation.ponder.instructions; + +import com.simibubi.create.foundation.ponder.PonderScene; +import com.simibubi.create.foundation.ponder.elements.InputWindowElement; + +public class ShowInputInstruction extends FadeInOutInstruction { + + private InputWindowElement element; + + public ShowInputInstruction(InputWindowElement element, int ticks) { + super(ticks); + this.element = element; + } + + @Override + protected void show(PonderScene scene) { + scene.addElement(element); + element.setVisible(true); + } + + @Override + protected void hide(PonderScene scene) { + element.setVisible(false); + } + + @Override + protected void applyFade(PonderScene scene, float fade) { + element.setFade(fade); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/instructions/TextInstruction.java b/src/main/java/com/simibubi/create/foundation/ponder/instructions/TextInstruction.java new file mode 100644 index 000000000..d0380cc81 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/instructions/TextInstruction.java @@ -0,0 +1,56 @@ +package com.simibubi.create.foundation.ponder.instructions; + +import com.simibubi.create.foundation.ponder.PonderScene; +import com.simibubi.create.foundation.ponder.Selection; +import com.simibubi.create.foundation.ponder.elements.OutlinerElement; +import com.simibubi.create.foundation.ponder.elements.TextWindowElement; + +public class TextInstruction extends FadeInOutInstruction { + + private TextWindowElement element; + private OutlinerElement outline; + + public TextInstruction(TextWindowElement element, int duration) { + super(duration); + this.element = element; + } + + public TextInstruction(TextWindowElement element, int duration, Selection selection) { + this(element, duration); + outline = new OutlinerElement(o -> selection.makeOutline(o) + .lineWidth(1 / 16f)); + } + + @Override + public void tick(PonderScene scene) { + super.tick(scene); + if (outline != null) + outline.setColor(element.getColor()); + } + + @Override + protected void show(PonderScene scene) { + scene.addElement(element); + element.setVisible(true); + if (outline != null) { + scene.addElement(outline); + outline.setFade(1); + outline.setVisible(true); + } + } + + @Override + protected void hide(PonderScene scene) { + element.setVisible(false); + if (outline != null) { + outline.setFade(0); + outline.setVisible(false); + } + } + + @Override + protected void applyFade(PonderScene scene, float fade) { + element.setFade(fade); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/instructions/TickingInstruction.java b/src/main/java/com/simibubi/create/foundation/ponder/instructions/TickingInstruction.java new file mode 100644 index 000000000..93f2b5a03 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/instructions/TickingInstruction.java @@ -0,0 +1,50 @@ +package com.simibubi.create.foundation.ponder.instructions; + +import com.simibubi.create.foundation.ponder.PonderInstruction; +import com.simibubi.create.foundation.ponder.PonderScene; + +public abstract class TickingInstruction extends PonderInstruction { + + private boolean blocking; + protected int totalTicks; + protected int remainingTicks; + + public TickingInstruction(boolean blocking, int ticks) { + this.blocking = blocking; + remainingTicks = totalTicks = ticks; + } + + @Override + public void reset(PonderScene scene) { + super.reset(scene); + remainingTicks = totalTicks; + } + + protected void firstTick(PonderScene scene) {} + + @Override + public void onScheduled(PonderScene scene) { + super.onScheduled(scene); + if (isBlocking()) + scene.addToSceneTime(totalTicks); + } + + @Override + public void tick(PonderScene scene) { + if (remainingTicks == totalTicks) + firstTick(scene); + if (remainingTicks > 0) + remainingTicks--; + } + + @Override + public boolean isComplete() { + return remainingTicks == 0; + } + + @Override + public boolean isBlocking() { + return blocking; + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/instructions/TileEntityDataInstruction.java b/src/main/java/com/simibubi/create/foundation/ponder/instructions/TileEntityDataInstruction.java new file mode 100644 index 000000000..d484bae49 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/instructions/TileEntityDataInstruction.java @@ -0,0 +1,49 @@ +package com.simibubi.create.foundation.ponder.instructions; + +import java.util.function.UnaryOperator; + +import com.simibubi.create.foundation.ponder.PonderScene; +import com.simibubi.create.foundation.ponder.PonderWorld; +import com.simibubi.create.foundation.ponder.Selection; +import com.simibubi.create.foundation.tileEntity.SyncedTileEntity; + +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.tileentity.TileEntity; + +public class TileEntityDataInstruction extends WorldModifyInstruction { + + private boolean redraw; + private UnaryOperator data; + private Class type; + + public TileEntityDataInstruction(Selection selection, Class type, + UnaryOperator data, boolean redraw) { + super(selection); + this.type = type; + this.data = data; + this.redraw = redraw; + } + + @Override + protected void runModification(Selection selection, PonderScene scene) { + PonderWorld world = scene.getWorld(); + selection.forEach(pos -> { + if (!world.getBounds() + .isVecInside(pos)) + return; + TileEntity tileEntity = world.getTileEntity(pos); + if (!type.isInstance(tileEntity)) + return; + CompoundNBT apply = data.apply(tileEntity.write(new CompoundNBT())); + tileEntity.read(apply); + if (tileEntity instanceof SyncedTileEntity) + ((SyncedTileEntity) tileEntity).readClientUpdate(apply); + }); + } + + @Override + protected boolean needsRedraw() { + return redraw; + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/instructions/WorldModifyInstruction.java b/src/main/java/com/simibubi/create/foundation/ponder/instructions/WorldModifyInstruction.java new file mode 100644 index 000000000..583514b67 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/instructions/WorldModifyInstruction.java @@ -0,0 +1,32 @@ +package com.simibubi.create.foundation.ponder.instructions; + +import com.simibubi.create.foundation.ponder.PonderInstruction; +import com.simibubi.create.foundation.ponder.PonderScene; +import com.simibubi.create.foundation.ponder.Selection; +import com.simibubi.create.foundation.ponder.elements.WorldSectionElement; + +public abstract class WorldModifyInstruction extends PonderInstruction { + + private Selection selection; + + public WorldModifyInstruction(Selection selection) { + this.selection = selection; + } + + @Override + public boolean isComplete() { + return true; + } + + @Override + public void tick(PonderScene scene) { + runModification(selection, scene); + if (needsRedraw()) + scene.forEach(WorldSectionElement.class, WorldSectionElement::queueRedraw); + } + + protected abstract void runModification(Selection selection, PonderScene scene); + + protected abstract boolean needsRedraw(); + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/ui/ChapterLabel.java b/src/main/java/com/simibubi/create/foundation/ponder/ui/ChapterLabel.java new file mode 100644 index 000000000..62f680df6 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/ui/ChapterLabel.java @@ -0,0 +1,44 @@ +package com.simibubi.create.foundation.ponder.ui; + +import java.util.function.BiConsumer; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.simibubi.create.foundation.gui.UIRenderHelper; +import com.simibubi.create.foundation.gui.widgets.AbstractSimiWidget; +import com.simibubi.create.foundation.ponder.content.PonderChapter; +import com.simibubi.create.foundation.utility.Lang; + +import net.minecraft.client.Minecraft; + +public class ChapterLabel extends AbstractSimiWidget { + + private final PonderChapter chapter; + private final PonderButton button; + + public ChapterLabel(PonderChapter chapter, int x, int y, BiConsumer onClick) { + super(x, y, 175, 38); + + this.button = new PonderButton(x + 4, y + 4, onClick, 30, 30).showing(chapter); + this.button.fade(1); + + this.chapter = chapter; + } + + @Override + public void render(int mouseX, int mouseY, float partialTicks) { + UIRenderHelper.streak(0, x, y + height / 2, height - 2, width, 0x101010); + drawString(Minecraft.getInstance().fontRenderer, Lang.translate("ponder.chapter." + chapter.getId()), x + 50, + y + 20, 0xffddeeff); + + button.renderButton(mouseX, mouseY, partialTicks); + super.render(mouseX, mouseY, partialTicks); + } + + @Override + public void onClick(double x, double y) { + if (!button.isMouseOver(x, y)) + return; + + button.runCallback(x, y); + } +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/ui/LayoutHelper.java b/src/main/java/com/simibubi/create/foundation/ponder/ui/LayoutHelper.java new file mode 100644 index 000000000..32ca1df1d --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/ui/LayoutHelper.java @@ -0,0 +1,118 @@ +package com.simibubi.create.foundation.ponder.ui; + +import net.minecraft.client.renderer.Rectangle2d; + +public interface LayoutHelper { + + static LayoutHelper centeredHorizontal(int itemCount, int rows, int width, int height, int spacing) { + return new CenteredHorizontalLayoutHelper(itemCount, rows, width, height, spacing); + } + + int getX(); + + int getY(); + + void next(); + + int getTotalWidth(); + + int getTotalHeight(); + + default Rectangle2d getArea() { + int lWidth = getTotalWidth(); + int lHeight = getTotalHeight(); + return new Rectangle2d(-lWidth / 2, -lHeight / 2, lWidth, lHeight); + } + + class CenteredHorizontalLayoutHelper implements LayoutHelper { + + int itemCount; + int rows; + int width; + int height; + int spacing; + + int currentColumn = 0; + int currentRow = 0; + int[] rowCounts; + int x = 0, y = 0; + + CenteredHorizontalLayoutHelper(int itemCount, int rows, int width, int height, int spacing) { + this.itemCount = itemCount; + this.rows = rows; + this.width = width; + this.height = height; + this.spacing = spacing; + + rowCounts = new int[rows]; + int itemsPerRow = itemCount / rows; + int itemDiff = itemCount - itemsPerRow * rows; + for (int i = 0; i < rows; i++) { + rowCounts[i] = itemsPerRow; + if (itemDiff > 0) { + rowCounts[i]++; + itemDiff--; + } + } + + init(); + } + + @Override + public int getX() { + return x; + } + + @Override + public int getY() { + return y; + } + + @Override + public void next() { + currentColumn++; + if (currentColumn >= rowCounts[currentRow]) { + // nextRow + if (++currentRow >= rows) { + x = 0; + y = 0; + return; + } + + currentColumn = 0; + prepareX(); + y += height + spacing; + return; + } + + x += width + spacing; + } + + private void init() { + prepareX(); + prepareY(); + } + + private void prepareX() { + int rowWidth = rowCounts[currentRow] * width + (rowCounts[currentRow] - 1) * spacing; + x = -(rowWidth / 2); + } + + private void prepareY() { + int totalHeight = rows * height + (rows > 1 ? ((rows - 1) * spacing) : 0); + y = -(totalHeight / 2); + } + + @Override + public int getTotalWidth() { + return rowCounts[0] * width + (rowCounts[0] - 1) * spacing; + } + + @Override + public int getTotalHeight() { + return rows * height + (rows > 1 ? ((rows - 1) * spacing) : 0); + } + + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/ui/PonderButton.java b/src/main/java/com/simibubi/create/foundation/ponder/ui/PonderButton.java new file mode 100644 index 000000000..1c007367e --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/ui/PonderButton.java @@ -0,0 +1,156 @@ +package com.simibubi.create.foundation.ponder.ui; + +import java.util.function.BiConsumer; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.simibubi.create.foundation.gui.GuiGameElement; +import com.simibubi.create.foundation.gui.IScreenRenderable; +import com.simibubi.create.foundation.gui.widgets.AbstractSimiWidget; +import com.simibubi.create.foundation.ponder.PonderUI; +import com.simibubi.create.foundation.utility.AnimationTickHolder; +import com.simibubi.create.foundation.utility.ColorHelper; +import com.simibubi.create.foundation.utility.LerpedFloat; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.settings.KeyBinding; +import net.minecraft.item.ItemStack; + +public class PonderButton extends AbstractSimiWidget { + + private IScreenRenderable icon; + private ItemStack item; + protected boolean pressed; + private BiConsumer onClick; + private int xFadeModifier; + private int yFadeModifier; + private float fade; + private KeyBinding shortcut; + private LerpedFloat flash; + + public static final int SIZE = 20; + + public PonderButton(int x, int y, BiConsumer onClick, int width, int height) { + super(x, y, width, height); + this.onClick = onClick; + flash = LerpedFloat.linear() + .startWithValue(0); + } + + public PonderButton(int x, int y, BiConsumer onClick) { + this(x, y, onClick, SIZE, SIZE); + } + + public PonderButton(int x, int y, Runnable onClick) { + this(x, y, ($, $$) -> onClick.run()); + } + + public PonderButton showing(IScreenRenderable icon) { + this.icon = icon; + return this; + } + + public PonderButton showing(ItemStack item) { + this.item = item; + return this; + } + + public PonderButton shortcut(KeyBinding key) { + this.shortcut = key; + return this; + } + + public PonderButton fade(int xModifier, int yModifier) { + this.xFadeModifier = xModifier; + this.yFadeModifier = yModifier; + return this; + } + + public void fade(float fade) { + this.fade = fade; + } + + public void flash() { + float value = flash.getValue(); + flash.setValue(value + (1 - value) * .2f); + } + + public void dim() { + float value = flash.getValue(); + flash.setValue(value * .5f); + } + + @Override + public void renderButton(int mouseX, int mouseY, float partialTicks) { + if (!visible) + return; + if (fade < .1f) + return; + + isHovered = mouseX >= x && mouseY >= y && mouseX < x + width && mouseY < y + height && fade > .75f; + + RenderSystem.pushMatrix(); + RenderSystem.disableDepthTest(); + if (fade < 1) + RenderSystem.translated((1 - fade) * -5 * xFadeModifier, (1 - fade) * -5 * yFadeModifier, 0); + + float flashValue = flash.getValue(partialTicks); + if (flashValue > .1f) + fade *= 3 * flashValue + ((Math.sin(AnimationTickHolder.getTicks() + partialTicks) / 6)) / 1f; + + int backgroundColor = ColorHelper.applyAlpha(0xdd000000, fade); + int borderColorStart = ColorHelper.applyAlpha(isHovered ? 0x70ffffff : 0x40aa9999, fade); + int borderColorEnd = ColorHelper.applyAlpha(isHovered ? 0x30ffffff : 0x20aa9999, fade); + + PonderUI.renderBox(x, y, width, height, backgroundColor, borderColorStart, borderColorEnd); + RenderSystem.translated(0, 0, 800); + + if (icon != null) { + RenderSystem.enableBlend(); + RenderSystem.color4f(1, 1, 1, fade); + RenderSystem.pushMatrix(); + RenderSystem.translated(x + 2, y + 2, 0); + RenderSystem.scaled((width - 4) / 16d, (height - 4) / 16d, 1); + icon.draw(this, 0, 0); + RenderSystem.popMatrix(); + } + if (item != null) { + RenderSystem.pushMatrix(); + RenderSystem.translated(0, 0, -800); + GuiGameElement.of(item) + .at(x - 2, y - 2) + .scale(1.5f) + .render(); + RenderSystem.popMatrix(); + } + if (shortcut != null) + drawCenteredString(Minecraft.getInstance().fontRenderer, shortcut.getLocalizedName(), x + width / 2 + 8, + y + height - 6, ColorHelper.applyAlpha(0xff606060, fade)); + + RenderSystem.popMatrix(); + } + + public void runCallback(double mouseX, double mouseY) { + onClick.accept((int) mouseX, (int) mouseY); + } + + @Override + public void onClick(double p_onClick_1_, double p_onClick_3_) { + super.onClick(p_onClick_1_, p_onClick_3_); + this.pressed = true; + } + + @Override + public void onRelease(double p_onRelease_1_, double p_onRelease_3_) { + super.onRelease(p_onRelease_1_, p_onRelease_3_); + this.pressed = false; + } + + public void setToolTip(String text) { + toolTip.clear(); + toolTip.add(text); + } + + public ItemStack getItem() { + return item; + } +} diff --git a/src/main/java/com/simibubi/create/foundation/render/SuperByteBufferCache.java b/src/main/java/com/simibubi/create/foundation/render/SuperByteBufferCache.java index ef25a5e2d..0ebf74157 100644 --- a/src/main/java/com/simibubi/create/foundation/render/SuperByteBufferCache.java +++ b/src/main/java/com/simibubi/create/foundation/render/SuperByteBufferCache.java @@ -78,6 +78,11 @@ public class SuperByteBufferCache { return null; } } + + public void invalidate(Compartment compartment, T key) { + Cache compartmentCache = this.cache.get(compartment); + compartmentCache.invalidate(key); + } public void registerCompartment(Compartment instance) { cache.put(instance, CacheBuilder.newBuilder() diff --git a/src/main/java/com/simibubi/create/foundation/render/TileEntityRenderHelper.java b/src/main/java/com/simibubi/create/foundation/render/TileEntityRenderHelper.java index 0b6e7ff62..95dcf7963 100644 --- a/src/main/java/com/simibubi/create/foundation/render/TileEntityRenderHelper.java +++ b/src/main/java/com/simibubi/create/foundation/render/TileEntityRenderHelper.java @@ -25,13 +25,23 @@ public class TileEntityRenderHelper { public static void renderTileEntities(World world, Iterable customRenderTEs, MatrixStack ms, MatrixStack localTransform, IRenderTypeBuffer buffer) { - renderTileEntities(world, null, customRenderTEs, ms, localTransform, buffer); } + + public static void renderTileEntities(World world, Iterable customRenderTEs, MatrixStack ms, + MatrixStack localTransform, IRenderTypeBuffer buffer, float pt) { + renderTileEntities(world, null, customRenderTEs, ms, localTransform, buffer, pt); + } - public static void renderTileEntities(World world, PlacementSimulationWorld renderWorld, Iterable customRenderTEs, MatrixStack ms, - MatrixStack localTransform, IRenderTypeBuffer buffer) { - float pt = AnimationTickHolder.getPartialTicks(); + public static void renderTileEntities(World world, PlacementSimulationWorld renderWorld, + Iterable customRenderTEs, MatrixStack ms, MatrixStack localTransform, IRenderTypeBuffer buffer) { + renderTileEntities(world, renderWorld, customRenderTEs, ms, localTransform, buffer, + AnimationTickHolder.getPartialTicks()); + } + + public static void renderTileEntities(World world, PlacementSimulationWorld renderWorld, + Iterable customRenderTEs, MatrixStack ms, MatrixStack localTransform, IRenderTypeBuffer buffer, + float pt) { Matrix4f matrix = localTransform.peek() .getModel(); diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/light/LightVolumeDebugger.java b/src/main/java/com/simibubi/create/foundation/render/backend/light/LightVolumeDebugger.java index 811987c5d..ca96b1b79 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/light/LightVolumeDebugger.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/light/LightVolumeDebugger.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher; import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer; +import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.Pair; import com.simibubi.create.foundation.utility.outliner.AABBOutline; @@ -29,6 +30,6 @@ public class LightVolumeDebugger { outline.getParams().colored(pair.getSecond()); return outline; }) - .forEach(outline -> outline.render(ms, buffer)); + .forEach(outline -> outline.render(ms, buffer, AnimationTickHolder.getPartialTicks())); } } diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/SmartTileEntity.java b/src/main/java/com/simibubi/create/foundation/tileEntity/SmartTileEntity.java index a40427a62..57d2c92b0 100644 --- a/src/main/java/com/simibubi/create/foundation/tileEntity/SmartTileEntity.java +++ b/src/main/java/com/simibubi/create/foundation/tileEntity/SmartTileEntity.java @@ -23,6 +23,9 @@ public abstract class SmartTileEntity extends SyncedTileEntity implements ITicka private int lazyTickRate; private int lazyTickCounter; + // Used for simulating this TE in a client-only setting + private boolean virtualMode; + public SmartTileEntity(TileEntityType tileEntityTypeIn) { super(tileEntityTypeIn); behaviours = new HashMap<>(); @@ -148,13 +151,21 @@ public abstract class SmartTileEntity extends SyncedTileEntity implements ITicka return (T) behaviours.get(type); return null; } - + protected boolean isItemHandlerCap(Capability cap) { return cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY; } - + protected boolean isFluidHandlerCap(Capability cap) { return cap == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY; } + + public void markVirtual() { + virtualMode = true; + } + + public boolean isVirtual() { + return virtualMode; + } } diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/ValueBox.java b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/ValueBox.java index 2dcf74527..5914501db 100644 --- a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/ValueBox.java +++ b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/ValueBox.java @@ -73,7 +73,7 @@ public class ValueBox extends ChasingAABBOutline { } @Override - public void render(MatrixStack ms, SuperRenderTypeBuffer buffer) { + public void render(MatrixStack ms, SuperRenderTypeBuffer buffer, float pt) { boolean hasTransform = transform != null; if (transform instanceof Sided && params.getHighlightedFace() != null) ((Sided) transform).fromSide(params.getHighlightedFace()); @@ -88,7 +88,7 @@ public class ValueBox extends ChasingAABBOutline { .getNormal() .copy(); params.colored(isPassive ? passiveColor : highlightColor); - super.render(ms, buffer); + super.render(ms, buffer, pt); float fontScale = hasTransform ? -transform.getFontScale() : -1 / 64f; ms.scale(fontScale, fontScale, fontScale); diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringHandler.java b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringHandler.java index b71159441..621cd3d2a 100644 --- a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringHandler.java +++ b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringHandler.java @@ -126,6 +126,8 @@ public class FilteringHandler { return false; if (!filtering.isCountVisible()) return false; + if (!filtering.isActive()) + return false; if (filtering.slotPositioning instanceof ValueBoxTransform.Sided) ((Sided) filtering.slotPositioning).fromSide(result.getFace()); if (!filtering.testHit(objectMouseOver.getHitVec())) diff --git a/src/main/java/com/simibubi/create/foundation/utility/ColorHelper.java b/src/main/java/com/simibubi/create/foundation/utility/ColorHelper.java index 7dfc7e24a..e1d369fbb 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/ColorHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/ColorHelper.java @@ -4,6 +4,7 @@ import java.util.UUID; import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; public class ColorHelper { @@ -30,6 +31,14 @@ public class ColorHelper { return 255 - progress; } + public static int applyAlpha(int color, float alpha) { + int prevAlphaChannel = (color >> 24) & 0xFF; + if (prevAlphaChannel > 0) + alpha *= prevAlphaChannel / 256f; + int alphaChannel = (int) (0xFF * MathHelper.clamp(alpha, 0, 1)); + return (color & 0xFFFFFF) | alphaChannel << 24; + } + public static int mixColors(int color1, int color2, float w) { int r1 = (color1 >> 16); int g1 = (color1 >> 8) & 0xFF; @@ -43,9 +52,25 @@ public class ColorHelper { return color; } + public static int mixAlphaColors(int color1, int color2, float w) { + int a1 = (color1 >> 24); + int r1 = (color1 >> 16) & 0xFF; + int g1 = (color1 >> 8) & 0xFF; + int b1 = color1 & 0xFF; + int a2 = (color2 >> 24); + int r2 = (color2 >> 16) & 0xFF; + int g2 = (color2 >> 8) & 0xFF; + int b2 = color2 & 0xFF; + + int color = ((int) (a1 + (a2 - a1) * w) << 24) + ((int) (r1 + (r2 - r1) * w) << 16) + + ((int) (g1 + (g2 - g1) * w) << 8) + (int) (b1 + (b2 - b1) * w); + + return color; + } + public static void glColor(int color) { color = mixColors(color, 0xFFFFFF, .5f); - int r = (color >> 16); + int r = (color >> 16) & 0xFF; int g = (color >> 8) & 0xFF; int b = color & 0xFF; @@ -57,7 +82,7 @@ public class ColorHelper { } public static Vec3d getRGB(int color) { - int r = (color >> 16); + int r = (color >> 16) & 0xFF; int g = (color >> 8) & 0xFF; int b = color & 0xFF; return new Vec3d(r, g, b).scale(1 / 256d); diff --git a/src/main/java/com/simibubi/create/foundation/utility/LerpedFloat.java b/src/main/java/com/simibubi/create/foundation/utility/LerpedFloat.java index 073f2fc07..4c7b4fec4 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/LerpedFloat.java +++ b/src/main/java/com/simibubi/create/foundation/utility/LerpedFloat.java @@ -46,6 +46,10 @@ public class LerpedFloat { return this; } + public void updateChaseTarget(float target) { + this.chaseTarget = target; + } + public boolean updateChaseSpeed(double speed) { float prevSpeed = this.chaseSpeed; this.chaseSpeed = (float) speed; diff --git a/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java b/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java index 1e620ec07..7610ea984 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java @@ -78,7 +78,7 @@ public class VecHelper { vec = vec.normalize(); return new Vec3d(1, 1, 1).subtract(Math.abs(vec.x), Math.abs(vec.y), Math.abs(vec.z)); } - + public static Vec3d axisAlingedPlaneOf(Direction face) { return axisAlingedPlaneOf(new Vec3d(face.getDirectionVec())); } @@ -124,6 +124,11 @@ public class VecHelper { .scale(maxLength) : vec; } + public static Vec3d lerp(float p, Vec3d from, Vec3d to) { + return from.add(to.subtract(from) + .scale(p)); + } + public static Vec3d clampComponentWise(Vec3d vec, float maxLength) { return new Vec3d(MathHelper.clamp(vec.x, -maxLength, maxLength), MathHelper.clamp(vec.y, -maxLength, maxLength), MathHelper.clamp(vec.z, -maxLength, maxLength)); diff --git a/src/main/java/com/simibubi/create/foundation/utility/outliner/AABBOutline.java b/src/main/java/com/simibubi/create/foundation/utility/outliner/AABBOutline.java index 55c0462fb..5efa0fe17 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/outliner/AABBOutline.java +++ b/src/main/java/com/simibubi/create/foundation/utility/outliner/AABBOutline.java @@ -22,7 +22,7 @@ public class AABBOutline extends Outline { } @Override - public void render(MatrixStack ms, SuperRenderTypeBuffer buffer) { + public void render(MatrixStack ms, SuperRenderTypeBuffer buffer, float pt) { renderBB(ms, buffer, bb); } diff --git a/src/main/java/com/simibubi/create/foundation/utility/outliner/BlockClusterOutline.java b/src/main/java/com/simibubi/create/foundation/utility/outliner/BlockClusterOutline.java index 06f7beb9f..c960eae5e 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/outliner/BlockClusterOutline.java +++ b/src/main/java/com/simibubi/create/foundation/utility/outliner/BlockClusterOutline.java @@ -30,7 +30,7 @@ public class BlockClusterOutline extends Outline { } @Override - public void render(MatrixStack ms, SuperRenderTypeBuffer buffer) { + public void render(MatrixStack ms, SuperRenderTypeBuffer buffer, float pt) { for (MergeEntry edge : cluster.visibleEdges) { Vec3d start = new Vec3d(edge.pos); Direction direction = Direction.getFacingFromAxis(AxisDirection.POSITIVE, edge.axis); diff --git a/src/main/java/com/simibubi/create/foundation/utility/outliner/ChasingAABBOutline.java b/src/main/java/com/simibubi/create/foundation/utility/outliner/ChasingAABBOutline.java index 6621b1a0e..d70ef3189 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/outliner/ChasingAABBOutline.java +++ b/src/main/java/com/simibubi/create/foundation/utility/outliner/ChasingAABBOutline.java @@ -2,7 +2,6 @@ package com.simibubi.create.foundation.utility.outliner; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer; -import com.simibubi.create.foundation.utility.AnimationTickHolder; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.MathHelper; @@ -29,8 +28,8 @@ public class ChasingAABBOutline extends AABBOutline { } @Override - public void render(MatrixStack ms, SuperRenderTypeBuffer buffer) { - renderBB(ms, buffer, interpolateBBs(prevBB, bb, AnimationTickHolder.getPartialTicks())); + public void render(MatrixStack ms, SuperRenderTypeBuffer buffer, float pt) { + renderBB(ms, buffer, interpolateBBs(prevBB, bb, pt)); } private static AxisAlignedBB interpolateBBs(AxisAlignedBB current, AxisAlignedBB target, float pt) { diff --git a/src/main/java/com/simibubi/create/foundation/utility/outliner/LineOutline.java b/src/main/java/com/simibubi/create/foundation/utility/outliner/LineOutline.java index 4a72da0da..66885d45b 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/outliner/LineOutline.java +++ b/src/main/java/com/simibubi/create/foundation/utility/outliner/LineOutline.java @@ -2,7 +2,6 @@ package com.simibubi.create.foundation.utility.outliner; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer; -import com.simibubi.create.foundation.utility.AnimationTickHolder; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; @@ -19,7 +18,7 @@ public class LineOutline extends Outline { } @Override - public void render(MatrixStack ms, SuperRenderTypeBuffer buffer) { + public void render(MatrixStack ms, SuperRenderTypeBuffer buffer, float pt) { renderCuboidLine(ms, buffer, start, end); } @@ -46,8 +45,7 @@ public class LineOutline extends Outline { } @Override - public void render(MatrixStack ms, SuperRenderTypeBuffer buffer) { - float pt = AnimationTickHolder.getPartialTicks(); + public void render(MatrixStack ms, SuperRenderTypeBuffer buffer, float pt) { float distanceToTarget = 1 - MathHelper.lerp(pt, prevProgress, progress); Vec3d start = end.add(this.start.subtract(end) .scale(distanceToTarget)); diff --git a/src/main/java/com/simibubi/create/foundation/utility/outliner/Outline.java b/src/main/java/com/simibubi/create/foundation/utility/outliner/Outline.java index c91099558..e5f90c3ca 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/outliner/Outline.java +++ b/src/main/java/com/simibubi/create/foundation/utility/outliner/Outline.java @@ -31,7 +31,7 @@ public abstract class Outline { params = new OutlineParams(); } - public abstract void render(MatrixStack ms, SuperRenderTypeBuffer buffer); + public abstract void render(MatrixStack ms, SuperRenderTypeBuffer buffer, float pt); public void renderCuboidLine(MatrixStack ms, SuperRenderTypeBuffer buffer, Vec3d start, Vec3d end) { Vec3d diff = end.subtract(start); diff --git a/src/main/java/com/simibubi/create/foundation/utility/outliner/Outliner.java b/src/main/java/com/simibubi/create/foundation/utility/outliner/Outliner.java index 3d0311265..25185c7d0 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/outliner/Outliner.java +++ b/src/main/java/com/simibubi/create/foundation/utility/outliner/Outliner.java @@ -10,7 +10,6 @@ import java.util.Set; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer; import com.simibubi.create.foundation.tileEntity.behaviour.ValueBox; -import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.outliner.LineOutline.EndChasingLineOutline; import com.simibubi.create.foundation.utility.outliner.Outline.OutlineParams; @@ -60,14 +59,14 @@ public class Outliner { public OutlineParams showAABB(Object slot, AxisAlignedBB bb, int ttl) { createAABBOutlineIfMissing(slot, bb); ChasingAABBOutline outline = getAndRefreshAABB(slot, ttl); - outline.prevBB = outline.targetBB = bb; + outline.prevBB = outline.targetBB = outline.bb = bb; return outline.getParams(); } public OutlineParams showAABB(Object slot, AxisAlignedBB bb) { createAABBOutlineIfMissing(slot, bb); ChasingAABBOutline outline = getAndRefreshAABB(slot); - outline.prevBB = outline.targetBB = bb; + outline.prevBB = outline.targetBB = outline.bb = bb; return outline.getParams(); } @@ -107,7 +106,7 @@ public class Outliner { // Utility private void createAABBOutlineIfMissing(Object slot, AxisAlignedBB bb) { - if (!outlines.containsKey(slot)) { + if (!outlines.containsKey(slot) || !(outlines.get(slot).outline instanceof AABBOutline)) { ChasingAABBOutline outline = new ChasingAABBOutline(bb); outlines.put(slot, new OutlineEntry(outline)); } @@ -146,7 +145,7 @@ public class Outliner { toClear.forEach(outlines::remove); } - public void renderOutlines(MatrixStack ms, SuperRenderTypeBuffer buffer) { + public void renderOutlines(MatrixStack ms, SuperRenderTypeBuffer buffer, float pt) { outlines.forEach((key, entry) -> { Outline outline = entry.getOutline(); outline.params.alpha = 1; @@ -156,13 +155,13 @@ public class Outliner { float fadeticks = OutlineEntry.fadeTicks; float lastAlpha = prevTicks >= 0 ? 1 : 1 + (prevTicks / fadeticks); float currentAlpha = 1 + (entry.ticksTillRemoval / fadeticks); - float alpha = MathHelper.lerp(AnimationTickHolder.getPartialTicks(), lastAlpha, currentAlpha); + float alpha = MathHelper.lerp(pt, lastAlpha, currentAlpha); outline.params.alpha = alpha * alpha * alpha; if (outline.params.alpha < 1 / 8f) return; } - outline.render(ms, buffer); + outline.render(ms, buffer, pt); }); } diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index 80912c491..75b9c48cb 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -25,6 +25,9 @@ public net.minecraft.tileentity.BeaconTileEntity field_174909_f # beamSegments public net.minecraft.world.server.ServerTickList field_205374_d # pendingTickListEntriesHashSet public net.minecraft.world.server.ServerTickList field_205375_e # pendingTickListEntriesTreeSet +# Particle Manager +public net.minecraft.client.particle.ParticleManager field_178932_g # factories + # Lightmap information for instanced rendering public net.minecraft.client.renderer.LightTexture field_205112_c #resourceLocation public net.minecraft.client.Minecraft field_193996_ah #renderPartialTicksPaused @@ -48,6 +51,7 @@ public net.minecraft.util.palette.IResizeCallback public net.minecraft.entity.Entity func_205011_p()V # updateAquatics +# For uploading matrices as vertex attributes. public net.minecraft.client.renderer.Matrix3f field_226097_a_ #a00 public net.minecraft.client.renderer.Matrix3f field_226098_b_ #a01 public net.minecraft.client.renderer.Matrix3f field_226099_c_ #a02 @@ -73,4 +77,4 @@ public net.minecraft.client.renderer.Matrix4f field_226586_l_ #a23 public net.minecraft.client.renderer.Matrix4f field_226587_m_ #a30 public net.minecraft.client.renderer.Matrix4f field_226588_n_ #a31 public net.minecraft.client.renderer.Matrix4f field_226589_o_ #a32 -public net.minecraft.client.renderer.Matrix4f field_226590_p_ #a33 \ No newline at end of file +public net.minecraft.client.renderer.Matrix4f field_226590_p_ #a33 diff --git a/src/main/resources/assets/create/models/block/funnel/block_vertical_filterless.json b/src/main/resources/assets/create/models/block/funnel/block_vertical_filterless.json new file mode 100644 index 000000000..ca31358f9 --- /dev/null +++ b/src/main/resources/assets/create/models/block/funnel/block_vertical_filterless.json @@ -0,0 +1,168 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "3": "create:block/brass_funnel_back", + "5": "create:block/brass_funnel_tall", + "7": "create:block/brass_funnel_plating", + "8": "create:block/brass_storage_block", + "9": "create:block/brass_funnel_slope", + "10": "create:block/funnel_closed", + "2_2": "create:block/brass_funnel_pull" + }, + "elements": [ + { + "name": "LeftWall", + "from": [0, 4, 0], + "to": [2, 10, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 2]}, + "faces": { + "north": {"uv": [14, 0, 16, 6], "texture": "#2_2"}, + "south": {"uv": [0, 0, 2, 6], "texture": "#2_2"}, + "west": {"uv": [0, 0, 16, 6], "texture": "#2_2"}, + "up": {"uv": [0, 0, 2, 16], "texture": "#8"}, + "down": {"uv": [0, 0, 16, 2], "rotation": 270, "texture": "#8"} + } + }, + { + "name": "LeftWall", + "from": [14, 4, 0], + "to": [16, 10, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 2]}, + "faces": { + "north": {"uv": [2, 0, 0, 6], "rotation": 180, "texture": "#2_2"}, + "east": {"uv": [0, 6, 16, 0], "rotation": 180, "texture": "#2_2"}, + "south": {"uv": [14, 0, 16, 6], "texture": "#2_2"}, + "up": {"uv": [14, 0, 16, 16], "texture": "#8"}, + "down": {"uv": [0, 14, 16, 16], "rotation": 270, "texture": "#8"} + } + }, + { + "name": "Top", + "from": [2, 4, 0], + "to": [14, 10, 2], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 2]}, + "faces": { + "north": {"uv": [2, 0, 14, 6], "texture": "#2_2"}, + "up": {"uv": [2, 0, 14, 2], "texture": "#8"}, + "down": {"uv": [0, 2, 2, 14], "rotation": 270, "texture": "#8"} + } + }, + { + "name": "Top", + "from": [2, 4, 14], + "to": [14, 10, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 18]}, + "faces": { + "south": {"uv": [14, 0, 2, 6], "texture": "#2_2"}, + "up": {"uv": [2, 16, 14, 14], "rotation": 180, "texture": "#8"}, + "down": {"uv": [14, 14, 16, 2], "rotation": 270, "texture": "#8"} + } + }, + { + "from": [1, 1, 1], + "to": [15, 4, 15], + "rotation": {"angle": 0, "axis": "y", "origin": [7, -6, 10]}, + "faces": { + "north": {"uv": [1, 0, 15, 3], "texture": "#5"}, + "east": {"uv": [1, 0, 15, 3], "texture": "#5"}, + "south": {"uv": [1, 0, 15, 3], "texture": "#5"}, + "west": {"uv": [1, 0, 15, 3], "texture": "#5"}, + "down": {"uv": [2, 2, 14, 14], "rotation": 270, "texture": "#8"} + } + }, + { + "from": [1, 5, 2], + "to": [2, 10, 14], + "rotation": {"angle": 22.5, "axis": "z", "origin": [2, 10, 8]}, + "faces": { + "east": {"uv": [2, 2, 14, 7], "texture": "#9"} + } + }, + { + "from": [14, 5, 2], + "to": [15, 10, 14], + "rotation": {"angle": -22.5, "axis": "z", "origin": [14, 10, 8]}, + "faces": { + "west": {"uv": [2, 2, 14, 7], "texture": "#9"} + } + }, + { + "from": [2, 5, 14], + "to": [14, 10, 15], + "rotation": {"angle": 22.5, "axis": "x", "origin": [8, 10, 14]}, + "faces": { + "north": {"uv": [2, 2, 14, 7], "texture": "#9"} + } + }, + { + "from": [2, 5, 1], + "to": [14, 10, 2], + "rotation": {"angle": -22.5, "axis": "x", "origin": [8, 10, 2]}, + "faces": { + "south": {"uv": [2, 2, 14, 7], "texture": "#9"} + } + }, + { + "from": [3, 5, 3], + "to": [13, 6, 13], + "rotation": {"angle": 0, "axis": "y", "origin": [11, 13, 11]}, + "faces": { + "up": {"uv": [3, 3, 13, 13], "texture": "#10"} + } + }, + { + "name": "Back", + "from": [1.95, -1.95, 1.95], + "to": [14.05, 2, 14.05], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 0.025, 8]}, + "faces": { + "north": {"uv": [2, 12, 14, 16], "texture": "#9"}, + "east": {"uv": [2, 12, 14, 16], "texture": "#9"}, + "south": {"uv": [2, 12, 14, 16], "texture": "#9"}, + "west": {"uv": [2, 12, 14, 16], "texture": "#9"}, + "down": {"uv": [6, 8, 12, 14], "rotation": 180, "texture": "#3"} + } + }, + { + "name": "Back", + "from": [2.1, 2, 2.05], + "to": [13.9, 4.1, 13.1], + "rotation": {"angle": 0, "axis": "y", "origin": [8, -6, 24.1]}, + "faces": { + "east": {"uv": [2.5, 1.5, 8, 0.5], "texture": "#5"}, + "west": {"uv": [2.5, 0.5, 8, 1.5], "rotation": 180, "texture": "#5"} + } + } + ], + "display": {}, + "groups": [ + { + "name": "block_retracted", + "origin": [8, 8, 8], + "children": [ + { + "name": "BeltFunnel", + "origin": [9, -4, 8], + "children": [ + { + "name": "FrontSection", + "origin": [9, -4, 8], + "children": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + }, + { + "name": "Base", + "origin": [9, -4, 8], + "children": [10, 11] + } + ] + } + ] + }, + { + "name": "Item Filter", + "origin": [8, 0, 8], + "children": [12, 13, 14, 15] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/gantry_pinion/horizontal.json b/src/main/resources/assets/create/models/block/gantry_carriage/horizontal.json similarity index 100% rename from src/main/resources/assets/create/models/block/gantry_pinion/horizontal.json rename to src/main/resources/assets/create/models/block/gantry_carriage/horizontal.json diff --git a/src/main/resources/assets/create/models/block/gantry_pinion/item.json b/src/main/resources/assets/create/models/block/gantry_carriage/item.json similarity index 100% rename from src/main/resources/assets/create/models/block/gantry_pinion/item.json rename to src/main/resources/assets/create/models/block/gantry_carriage/item.json diff --git a/src/main/resources/assets/create/models/block/gantry_pinion/vertical.json b/src/main/resources/assets/create/models/block/gantry_carriage/vertical.json similarity index 100% rename from src/main/resources/assets/create/models/block/gantry_pinion/vertical.json rename to src/main/resources/assets/create/models/block/gantry_carriage/vertical.json diff --git a/src/main/resources/assets/create/models/block/gantry_pinion/wheels.json b/src/main/resources/assets/create/models/block/gantry_carriage/wheels.json similarity index 100% rename from src/main/resources/assets/create/models/block/gantry_pinion/wheels.json rename to src/main/resources/assets/create/models/block/gantry_carriage/wheels.json diff --git a/src/main/resources/assets/create/textures/gui/icons.png b/src/main/resources/assets/create/textures/gui/icons.png index 499eccc38..000090faf 100644 Binary files a/src/main/resources/assets/create/textures/gui/icons.png and b/src/main/resources/assets/create/textures/gui/icons.png differ diff --git a/src/main/resources/assets/create/textures/gui/widgets.png b/src/main/resources/assets/create/textures/gui/widgets.png index 76be05990..22ec3d894 100644 Binary files a/src/main/resources/assets/create/textures/gui/widgets.png and b/src/main/resources/assets/create/textures/gui/widgets.png differ diff --git a/src/main/resources/assets/create/textures/ponder/chapter/basic_kinetics.png b/src/main/resources/assets/create/textures/ponder/chapter/basic_kinetics.png new file mode 100644 index 000000000..da70cc75a Binary files /dev/null and b/src/main/resources/assets/create/textures/ponder/chapter/basic_kinetics.png differ diff --git a/src/main/resources/assets/create/textures/ponder/tag/item_transfer.png b/src/main/resources/assets/create/textures/ponder/tag/item_transfer.png new file mode 100644 index 000000000..da70cc75a Binary files /dev/null and b/src/main/resources/assets/create/textures/ponder/tag/item_transfer.png differ diff --git a/src/main/resources/ponder/belt/connect.nbt b/src/main/resources/ponder/belt/connect.nbt new file mode 100644 index 000000000..b1009a9ce Binary files /dev/null and b/src/main/resources/ponder/belt/connect.nbt differ diff --git a/src/main/resources/ponder/belt/directions.nbt b/src/main/resources/ponder/belt/directions.nbt new file mode 100644 index 000000000..fde59d365 Binary files /dev/null and b/src/main/resources/ponder/belt/directions.nbt differ diff --git a/src/main/resources/ponder/belt/encasing.nbt b/src/main/resources/ponder/belt/encasing.nbt new file mode 100644 index 000000000..1ce0d762d Binary files /dev/null and b/src/main/resources/ponder/belt/encasing.nbt differ diff --git a/src/main/resources/ponder/belt/transport.nbt b/src/main/resources/ponder/belt/transport.nbt new file mode 100644 index 000000000..784df024a Binary files /dev/null and b/src/main/resources/ponder/belt/transport.nbt differ diff --git a/src/main/resources/ponder/chain_drive/gearshift.nbt b/src/main/resources/ponder/chain_drive/gearshift.nbt new file mode 100644 index 000000000..f9176ac82 Binary files /dev/null and b/src/main/resources/ponder/chain_drive/gearshift.nbt differ diff --git a/src/main/resources/ponder/chain_drive/relay.nbt b/src/main/resources/ponder/chain_drive/relay.nbt new file mode 100644 index 000000000..94eba9f2b Binary files /dev/null and b/src/main/resources/ponder/chain_drive/relay.nbt differ diff --git a/src/main/resources/ponder/clutch.nbt b/src/main/resources/ponder/clutch.nbt new file mode 100644 index 000000000..351af5afb Binary files /dev/null and b/src/main/resources/ponder/clutch.nbt differ diff --git a/src/main/resources/ponder/cog/large.nbt b/src/main/resources/ponder/cog/large.nbt new file mode 100644 index 000000000..3f55bd447 Binary files /dev/null and b/src/main/resources/ponder/cog/large.nbt differ diff --git a/src/main/resources/ponder/cog/small.nbt b/src/main/resources/ponder/cog/small.nbt new file mode 100644 index 000000000..90e235e2c Binary files /dev/null and b/src/main/resources/ponder/cog/small.nbt differ diff --git a/src/main/resources/ponder/cog/speedup.nbt b/src/main/resources/ponder/cog/speedup.nbt new file mode 100644 index 000000000..2a5687aee Binary files /dev/null and b/src/main/resources/ponder/cog/speedup.nbt differ diff --git a/src/main/resources/ponder/creative_motor.nbt b/src/main/resources/ponder/creative_motor.nbt new file mode 100644 index 000000000..58a94c9d1 Binary files /dev/null and b/src/main/resources/ponder/creative_motor.nbt differ diff --git a/src/main/resources/ponder/debug/scene_1.nbt b/src/main/resources/ponder/debug/scene_1.nbt new file mode 100644 index 000000000..2252fa1c3 Binary files /dev/null and b/src/main/resources/ponder/debug/scene_1.nbt differ diff --git a/src/main/resources/ponder/debug/scene_2.nbt b/src/main/resources/ponder/debug/scene_2.nbt new file mode 100644 index 000000000..16f82250c Binary files /dev/null and b/src/main/resources/ponder/debug/scene_2.nbt differ diff --git a/src/main/resources/ponder/debug/scene_3.nbt b/src/main/resources/ponder/debug/scene_3.nbt new file mode 100644 index 000000000..aedc65d0e Binary files /dev/null and b/src/main/resources/ponder/debug/scene_3.nbt differ diff --git a/src/main/resources/ponder/debug/scene_4.nbt b/src/main/resources/ponder/debug/scene_4.nbt new file mode 100644 index 000000000..589150451 Binary files /dev/null and b/src/main/resources/ponder/debug/scene_4.nbt differ diff --git a/src/main/resources/ponder/debug/scene_5.nbt b/src/main/resources/ponder/debug/scene_5.nbt new file mode 100644 index 000000000..be49148df Binary files /dev/null and b/src/main/resources/ponder/debug/scene_5.nbt differ diff --git a/src/main/resources/ponder/debug/scene_6.nbt b/src/main/resources/ponder/debug/scene_6.nbt new file mode 100644 index 000000000..6a7f63510 Binary files /dev/null and b/src/main/resources/ponder/debug/scene_6.nbt differ diff --git a/src/main/resources/ponder/debug/scene_7.nbt b/src/main/resources/ponder/debug/scene_7.nbt new file mode 100644 index 000000000..d0b4f88f6 Binary files /dev/null and b/src/main/resources/ponder/debug/scene_7.nbt differ diff --git a/src/main/resources/ponder/debug/scene_8.nbt b/src/main/resources/ponder/debug/scene_8.nbt new file mode 100644 index 000000000..eb2a7ac88 Binary files /dev/null and b/src/main/resources/ponder/debug/scene_8.nbt differ diff --git a/src/main/resources/ponder/debug/scene_9.nbt b/src/main/resources/ponder/debug/scene_9.nbt new file mode 100644 index 000000000..e981d81ed Binary files /dev/null and b/src/main/resources/ponder/debug/scene_9.nbt differ diff --git a/src/main/resources/ponder/fan/direction.nbt b/src/main/resources/ponder/fan/direction.nbt new file mode 100644 index 000000000..08e9d0236 Binary files /dev/null and b/src/main/resources/ponder/fan/direction.nbt differ diff --git a/src/main/resources/ponder/fan/processing.nbt b/src/main/resources/ponder/fan/processing.nbt new file mode 100644 index 000000000..00de4c3fe Binary files /dev/null and b/src/main/resources/ponder/fan/processing.nbt differ diff --git a/src/main/resources/ponder/fan/source.nbt b/src/main/resources/ponder/fan/source.nbt new file mode 100644 index 000000000..0c351c645 Binary files /dev/null and b/src/main/resources/ponder/fan/source.nbt differ diff --git a/src/main/resources/ponder/funnels/brass.nbt b/src/main/resources/ponder/funnels/brass.nbt new file mode 100644 index 000000000..f5dc748bc Binary files /dev/null and b/src/main/resources/ponder/funnels/brass.nbt differ diff --git a/src/main/resources/ponder/funnels/compat.nbt b/src/main/resources/ponder/funnels/compat.nbt new file mode 100644 index 000000000..73e10aa15 Binary files /dev/null and b/src/main/resources/ponder/funnels/compat.nbt differ diff --git a/src/main/resources/ponder/funnels/direction.nbt b/src/main/resources/ponder/funnels/direction.nbt new file mode 100644 index 000000000..b9f65898e Binary files /dev/null and b/src/main/resources/ponder/funnels/direction.nbt differ diff --git a/src/main/resources/ponder/funnels/intro.nbt b/src/main/resources/ponder/funnels/intro.nbt new file mode 100644 index 000000000..8f1f190f5 Binary files /dev/null and b/src/main/resources/ponder/funnels/intro.nbt differ diff --git a/src/main/resources/ponder/funnels/redstone.nbt b/src/main/resources/ponder/funnels/redstone.nbt new file mode 100644 index 000000000..f30d0417f Binary files /dev/null and b/src/main/resources/ponder/funnels/redstone.nbt differ diff --git a/src/main/resources/ponder/funnels/transposer.nbt b/src/main/resources/ponder/funnels/transposer.nbt new file mode 100644 index 000000000..fd13cd84c Binary files /dev/null and b/src/main/resources/ponder/funnels/transposer.nbt differ diff --git a/src/main/resources/ponder/gantry/direction.nbt b/src/main/resources/ponder/gantry/direction.nbt new file mode 100644 index 000000000..689314cd0 Binary files /dev/null and b/src/main/resources/ponder/gantry/direction.nbt differ diff --git a/src/main/resources/ponder/gantry/intro.nbt b/src/main/resources/ponder/gantry/intro.nbt new file mode 100644 index 000000000..20f0b8c2d Binary files /dev/null and b/src/main/resources/ponder/gantry/intro.nbt differ diff --git a/src/main/resources/ponder/gantry/redstone.nbt b/src/main/resources/ponder/gantry/redstone.nbt new file mode 100644 index 000000000..856d89863 Binary files /dev/null and b/src/main/resources/ponder/gantry/redstone.nbt differ diff --git a/src/main/resources/ponder/gantry/subgantry.nbt b/src/main/resources/ponder/gantry/subgantry.nbt new file mode 100644 index 000000000..09302c0a5 Binary files /dev/null and b/src/main/resources/ponder/gantry/subgantry.nbt differ diff --git a/src/main/resources/ponder/gearbox.nbt b/src/main/resources/ponder/gearbox.nbt new file mode 100644 index 000000000..39e5c6cd5 Binary files /dev/null and b/src/main/resources/ponder/gearbox.nbt differ diff --git a/src/main/resources/ponder/gearshift.nbt b/src/main/resources/ponder/gearshift.nbt new file mode 100644 index 000000000..957cec183 Binary files /dev/null and b/src/main/resources/ponder/gearshift.nbt differ diff --git a/src/main/resources/ponder/hand_crank.nbt b/src/main/resources/ponder/hand_crank.nbt new file mode 100644 index 000000000..2057ec700 Binary files /dev/null and b/src/main/resources/ponder/hand_crank.nbt differ diff --git a/src/main/resources/ponder/portable_interface/redstone.nbt b/src/main/resources/ponder/portable_interface/redstone.nbt new file mode 100644 index 000000000..799754288 Binary files /dev/null and b/src/main/resources/ponder/portable_interface/redstone.nbt differ diff --git a/src/main/resources/ponder/portable_interface/transfer.nbt b/src/main/resources/ponder/portable_interface/transfer.nbt new file mode 100644 index 000000000..a7d61c927 Binary files /dev/null and b/src/main/resources/ponder/portable_interface/transfer.nbt differ diff --git a/src/main/resources/ponder/shaft/encasing.nbt b/src/main/resources/ponder/shaft/encasing.nbt new file mode 100644 index 000000000..ab1fa5605 Binary files /dev/null and b/src/main/resources/ponder/shaft/encasing.nbt differ diff --git a/src/main/resources/ponder/shaft/relay.nbt b/src/main/resources/ponder/shaft/relay.nbt new file mode 100644 index 000000000..548effb1d Binary files /dev/null and b/src/main/resources/ponder/shaft/relay.nbt differ diff --git a/src/main/resources/ponder/valve_handle.nbt b/src/main/resources/ponder/valve_handle.nbt new file mode 100644 index 000000000..fe6af755d Binary files /dev/null and b/src/main/resources/ponder/valve_handle.nbt differ diff --git a/src/main/resources/ponder/water_wheel.nbt b/src/main/resources/ponder/water_wheel.nbt new file mode 100644 index 000000000..8c45937dd Binary files /dev/null and b/src/main/resources/ponder/water_wheel.nbt differ