From c0de8c4eb6e56f35463369a6fea502fde08c5545 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Fri, 19 Mar 2021 20:05:55 +0100 Subject: [PATCH 01/14] The grind continues - Scenes for Millstone, Crushing wheels, blaze burners, basin, mixer, press, speedometer and stressometer --- src/generated/resources/.cache/cache | 28 +- .../resources/assets/create/lang/en_us.json | 65 ++ .../assets/create/lang/unfinished/de_de.json | 67 +- .../assets/create/lang/unfinished/es_es.json | 67 +- .../assets/create/lang/unfinished/es_mx.json | 67 +- .../assets/create/lang/unfinished/fr_fr.json | 67 +- .../assets/create/lang/unfinished/it_it.json | 67 +- .../assets/create/lang/unfinished/ja_jp.json | 67 +- .../assets/create/lang/unfinished/ko_kr.json | 67 +- .../assets/create/lang/unfinished/nl_nl.json | 67 +- .../assets/create/lang/unfinished/pt_br.json | 67 +- .../assets/create/lang/unfinished/ru_ru.json | 67 +- .../assets/create/lang/unfinished/zh_cn.json | 67 +- .../assets/create/lang/unfinished/zh_tw.json | 67 +- .../data/create/advancements/aesthetics.json | 4 +- .../mixer/MechanicalMixerTileEntity.java | 2 +- .../press/MechanicalPressTileEntity.java | 5 +- .../burner/BlazeBurnerTileEntity.java | 10 +- .../create/foundation/ponder/PonderUI.java | 1 + .../create/foundation/ponder/PonderWorld.java | 12 +- .../foundation/ponder/SceneBuilder.java | 14 +- .../ponder/content/CartAssemblerScenes.java | 6 +- .../ponder/content/KineticsScenes.java | 97 ++ .../ponder/content/PonderIndex.java | 19 + .../ponder/content/ProcessingScenes.java | 895 ++++++++++++++++++ .../models/block/funnel/block_vertical.json | 5 +- .../funnel/block_vertical_filterless.json | 8 +- src/main/resources/ponder/basin.nbt | Bin 0 -> 1484 bytes src/main/resources/ponder/blaze_burner.nbt | Bin 0 -> 1047 bytes src/main/resources/ponder/crushing_wheel.nbt | Bin 0 -> 1271 bytes .../resources/ponder/empty_blaze_burner.nbt | Bin 0 -> 481 bytes src/main/resources/ponder/gauges.nbt | Bin 0 -> 656 bytes .../ponder/mechanical_mixer/mixing.nbt | Bin 0 -> 1142 bytes .../ponder/mechanical_press/compacting.nbt | Bin 0 -> 1179 bytes .../ponder/mechanical_press/pressing.nbt | Bin 0 -> 1042 bytes src/main/resources/ponder/millstone.nbt | Bin 0 -> 946 bytes 36 files changed, 1924 insertions(+), 51 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/ponder/content/ProcessingScenes.java create mode 100644 src/main/resources/ponder/basin.nbt create mode 100644 src/main/resources/ponder/blaze_burner.nbt create mode 100644 src/main/resources/ponder/crushing_wheel.nbt create mode 100644 src/main/resources/ponder/empty_blaze_burner.nbt create mode 100644 src/main/resources/ponder/gauges.nbt create mode 100644 src/main/resources/ponder/mechanical_mixer/mixing.nbt create mode 100644 src/main/resources/ponder/mechanical_press/compacting.nbt create mode 100644 src/main/resources/ponder/mechanical_press/pressing.nbt create mode 100644 src/main/resources/ponder/millstone.nbt diff --git a/src/generated/resources/.cache/cache b/src/generated/resources/.cache/cache index 4c93571f0..a7b18ba48 100644 --- a/src/generated/resources/.cache/cache +++ b/src/generated/resources/.cache/cache @@ -402,19 +402,19 @@ a3a11524cd3515fc01d905767b4b7ea782adaf03 assets/create/blockstates/yellow_seat.j 7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json 2b12f3cf99e498899207a8c4855210e7b5dc55cd assets/create/lang/en_ud.json -e371fd4fccf90c4ee6f2fbea91ea5d70e3d6c652 assets/create/lang/en_us.json -610a33e7074c3fb8e88370bed76549bfcfe0eddb assets/create/lang/unfinished/de_de.json -29339e0bf9743251639a2598d17f194cd406602c assets/create/lang/unfinished/es_es.json -e7138596de0babd4fc90a4b8ffb8fdea13088086 assets/create/lang/unfinished/es_mx.json -a95f57787534ae5d4920fe8e4825fe3012fdcd70 assets/create/lang/unfinished/fr_fr.json -7956b67df2d19a9f890f893c9d736516cc6e8629 assets/create/lang/unfinished/it_it.json -95394f8cc9d53397e030c46a9abef4fa4348e2ad assets/create/lang/unfinished/ja_jp.json -edcd5ffe8239f13cedbd63ab11c8334a38b90c90 assets/create/lang/unfinished/ko_kr.json -1749d2d020f02a2ccca4698d85bfdc4dcf849e3f assets/create/lang/unfinished/nl_nl.json -83c43209c295b3d3d85f7bebaa9a8ce7b79d47da assets/create/lang/unfinished/pt_br.json -a1a67295a2fe537080254fc8b353699d4d30989a assets/create/lang/unfinished/ru_ru.json -a525852b4f3aa0af52816e02e5cf4181de0c60c5 assets/create/lang/unfinished/zh_cn.json -51242fa9de9994103e9373e5c8dd6941438ec9a8 assets/create/lang/unfinished/zh_tw.json +cb22b256847375aa973491ca51858a704a3edf2c assets/create/lang/en_us.json +d2c8c43f990f7844f3dea35fd0a98ee7f4d40576 assets/create/lang/unfinished/de_de.json +69ce4c93ab2d6afd93352fd269be68f4c53ed963 assets/create/lang/unfinished/es_es.json +2a63880625f84655bee39fa5ff0e4d5f0933f8f9 assets/create/lang/unfinished/es_mx.json +a568c0d8943021d8f438d80692a62e7987b35c7d assets/create/lang/unfinished/fr_fr.json +b21c69ffdb9f09324bfb51fb843af000bf9c2c13 assets/create/lang/unfinished/it_it.json +230ab0c62a7e8b6a6e0c68b3081f06e0148e120a assets/create/lang/unfinished/ja_jp.json +c42a6c5d2ae9b97d4c79751cd7f60f70864f8c36 assets/create/lang/unfinished/ko_kr.json +b640c6137991b8e25139105a44d0d13b0b66ed18 assets/create/lang/unfinished/nl_nl.json +b9c2f45ac232045e6c1124d48017154504096dbd assets/create/lang/unfinished/pt_br.json +d69e5e26891d5ff7a1d93a1f5cc0bd775e1dfa08 assets/create/lang/unfinished/ru_ru.json +dbf513ee2276e1460adf3f3f50f336d104a74884 assets/create/lang/unfinished/zh_cn.json +40fd381d585db529a20f31adf001ecaf6dc77104 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 @@ -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 diff --git a/src/generated/resources/assets/create/lang/en_us.json b/src/generated/resources/assets/create/lang/en_us.json index 5b572a2a7..b3751d222 100644 --- a/src/generated/resources/assets/create/lang/en_us.json +++ b/src/generated/resources/assets/create/lang/en_us.json @@ -1873,6 +1873,17 @@ "create.ponder.analog_lever.text_2": "Right-click to increase its analog power output", "create.ponder.analog_lever.text_3": "Right-click while Sneaking to decrease the power output again", + "create.ponder.basin.header": "Processing Items in the Basin", + "create.ponder.basin.text_1": "A Basin can hold Items and Fluids for Processing", + "create.ponder.basin.text_2": "After a processing step, basins try to output below to the side of them", + "create.ponder.basin.text_3": "When a valid component is present, the Basin will show an output faucet", + "create.ponder.basin.text_4": "A number of options are applicable here", + "create.ponder.basin.text_5": "Outputs will be caught by the inventory below", + "create.ponder.basin.text_6": "Without output faucet, the Basin will retain items created in its processing", + "create.ponder.basin.text_7": "This can be useful if outputs should be re-used as ingredients", + "create.ponder.basin.text_8": "Desired outputs will then have to be extracted from the basin", + "create.ponder.basin.text_9": "A Filter might be necessary to avoid pulling out un-processed items", + "create.ponder.bearing_modes.header": "Movement Modes of the Mechanical Bearing", "create.ponder.bearing_modes.text_1": "When Stopped, the Bearing will place the structure at the nearest grid-aligned Angle", "create.ponder.bearing_modes.text_2": "It can be configured never to revert to solid blocks, or only near the angle it started at", @@ -1901,6 +1912,12 @@ "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.blaze_burner.header": "Feeding Blaze Burners", + "create.ponder.blaze_burner.text_1": "Blaze Burners can provide Heat to Items processed in a Basin", + "create.ponder.blaze_burner.text_2": "For this, the Blaze has to be fed with flammable items", + "create.ponder.blaze_burner.text_3": "With a Blaze Cake, the Burner can reach an even stronger level of heat", + "create.ponder.blaze_burner.text_4": "The feeding process can be automated using Deployers or Mechanical Arms", + "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.", @@ -1967,6 +1984,12 @@ "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.crushing_wheels.header": "Processing Items with Crushing Wheels", + "create.ponder.crushing_wheels.text_1": "A pair of Crushing Wheels can grind items very effectively", + "create.ponder.crushing_wheels.text_2": "Their Rotational Input has to make them spin into each other", + "create.ponder.crushing_wheels.text_3": "Items thrown or inserted into the top will get processed", + "create.ponder.crushing_wheels.text_4": "Items can be inserted and picked up through automated means as well", + "create.ponder.deployer.header": "Using the Deployer", "create.ponder.deployer.text_1": "Given Rotational Force, a Deployer can imitate player interactions", "create.ponder.deployer.text_10": "Right-click the front to give it an Item to use", @@ -1998,6 +2021,13 @@ "create.ponder.deployer_redstone.text_2": "Before stopping, the Deployer will finish any started cycles", "create.ponder.deployer_redstone.text_3": "Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.empty_blaze_burner.header": "Using Empty Blaze Burners", + "create.ponder.empty_blaze_burner.text_1": "Right-click a Blaze with the empty burner to capture it", + "create.ponder.empty_blaze_burner.text_2": "Alternatively, Blazes can be collected from their Spawners directly", + "create.ponder.empty_blaze_burner.text_3": "You now have an ideal heat source for various machines", + "create.ponder.empty_blaze_burner.text_4": "For Aesthetic purposes, Empty Blaze Burners can also be lit using Flint and Steel", + "create.ponder.empty_blaze_burner.text_5": "However, these are not suitable for industrial heating", + "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", @@ -2124,6 +2154,12 @@ "create.ponder.mechanical_harvester.text_1": "Whenever Harvesters are moved as part of an animated Contraption...", "create.ponder.mechanical_harvester.text_2": "They will harvest and reset any mature crops on their way", + "create.ponder.mechanical_mixer.header": "Processing Items with the Mechanical Mixer", + "create.ponder.mechanical_mixer.text_1": "With a Mixer and Basin, some Crafting Recipes can be automated", + "create.ponder.mechanical_mixer.text_2": "Available recipes include any Shapeless Crafting Recipe, plus a couple extra ones", + "create.ponder.mechanical_mixer.text_3": "Some of those recipes may require the heat of a Blaze Burner", + "create.ponder.mechanical_mixer.text_4": "The filter slot can be used in case two recipes are conflicting.", + "create.ponder.mechanical_piston.header": "Moving Structures using Mechanical Pistons", "create.ponder.mechanical_piston.text_1": "Mechanical Pistons can move blocks in front of them", "create.ponder.mechanical_piston.text_2": "Speed and direction of movement depend on the Rotational Input", @@ -2139,6 +2175,18 @@ "create.ponder.mechanical_plough.text_3": "Additionally, ploughs can create farmland", "create.ponder.mechanical_plough.text_4": "...they can also launch entities without hurting them", + "create.ponder.mechanical_press.header": "Processing Items with the Mechanical Press", + "create.ponder.mechanical_press.text_1": "The Mechanical Press can process items provided beneath it", + "create.ponder.mechanical_press.text_2": "The Input items can be dropped or placed on a Depot under the Press", + "create.ponder.mechanical_press.text_3": "When items are provided on a belt...", + "create.ponder.mechanical_press.text_4": "The Press will hold and process them automatically", + + "create.ponder.mechanical_press_compacting.header": "Compacting items with the Mechanical Press", + "create.ponder.mechanical_press_compacting.text_1": "Pressing items held in a Basin will cause them to be Compacted", + "create.ponder.mechanical_press_compacting.text_2": "Compacting includes any filled 2x2 or 3x3 Crafting Recipe, plus a couple extra ones", + "create.ponder.mechanical_press_compacting.text_3": "Some of those recipes may require the heat of a Blaze Burner", + "create.ponder.mechanical_press_compacting.text_4": "The filter slot can be used in case two recipes are conflicting.", + "create.ponder.mechanical_saw_breaker.header": "Cutting Trees with the Mechanical Saw", "create.ponder.mechanical_saw_breaker.text_1": "When given Rotational Force, a Mechanical Saw will cut trees directly in front of it", "create.ponder.mechanical_saw_breaker.text_2": "In order to cut the tree fully, the Saw has to break the last block connecting it to the ground", @@ -2154,6 +2202,13 @@ "create.ponder.mechanical_saw_processing.text_4": "When an ingredient has multiple possible outcomes, the filter slot can specify it", "create.ponder.mechanical_saw_processing.text_5": "Without filter, the Saw would cycle through all outcomes instead", + "create.ponder.millstone.header": "Processing Items in the Millstone", + "create.ponder.millstone.text_1": "Millstones process items by grinding them", + "create.ponder.millstone.text_2": "They can be powered from the side using cogwheels", + "create.ponder.millstone.text_3": "Throw or Insert items at the top", + "create.ponder.millstone.text_4": "After some time, the result can be obtained via Right-click", + "create.ponder.millstone.text_5": "The outputs can also be extracted by automation", + "create.ponder.piston_pole.header": "Piston Extension Poles", "create.ponder.piston_pole.text_1": "Without attached Poles, a Mechanical Piston cannot move", "create.ponder.piston_pole.text_2": "The Length of pole added at its back determines the Extension Range", @@ -2239,6 +2294,11 @@ "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.speedometer.header": "Monitoring Kinetic information using the Speedometer", + "create.ponder.speedometer.text_1": "The Speedometer displays the current Speed of the attached components", + "create.ponder.speedometer.text_2": "When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", + "create.ponder.speedometer.text_3": "Comparators can emit analog Restone Signals relative to the Speedometer's measurements", + "create.ponder.stabilized_bearings.header": "Stabilized Contraptions", "create.ponder.stabilized_bearings.text_1": "Whenever Mechanical Bearings are themselves part of a moving Structure..", "create.ponder.stabilized_bearings.text_2": "..they will attempt to keep themselves upright", @@ -2251,6 +2311,11 @@ "create.ponder.sticker.text_3": "If it is now moved in a contraption, the block will move with it", "create.ponder.sticker.text_4": "Toggled once again, the block is no longer attached", + "create.ponder.stressometer.header": "Monitoring Kinetic information using the Stressometer", + "create.ponder.stressometer.text_1": "The Stressometer displays the current Stress Capacity of the attached kinetic network", + "create.ponder.stressometer.text_2": "When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", + "create.ponder.stressometer.text_3": "Comparators can emit analog Restone Signals relative to the Stressometer's measurements", + "create.ponder.super_glue.header": "Attaching blocks using Super Glue", "create.ponder.super_glue.text_1": "Super Glue can be used between any two blocks", "create.ponder.super_glue.text_2": "The attached blocks will move together when assembled into a Contraption", 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 82ea9ce8f..d8e19da81 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: 1370", + "_": "Missing Localizations: 1425", "_": "->------------------------] Game Elements [------------------------<-", @@ -1874,6 +1874,17 @@ "create.ponder.analog_lever.text_2": "UNLOCALIZED: Right-click to increase its analog power output", "create.ponder.analog_lever.text_3": "UNLOCALIZED: Right-click while Sneaking to decrease the power output again", + "create.ponder.basin.header": "UNLOCALIZED: Processing Items in the Basin", + "create.ponder.basin.text_1": "UNLOCALIZED: A Basin can hold Items and Fluids for Processing", + "create.ponder.basin.text_2": "UNLOCALIZED: After a processing step, basins try to output below to the side of them", + "create.ponder.basin.text_3": "UNLOCALIZED: When a valid component is present, the Basin will show an output faucet", + "create.ponder.basin.text_4": "UNLOCALIZED: A number of options are applicable here", + "create.ponder.basin.text_5": "UNLOCALIZED: Outputs will be caught by the inventory below", + "create.ponder.basin.text_6": "UNLOCALIZED: Without output faucet, the Basin will retain items created in its processing", + "create.ponder.basin.text_7": "UNLOCALIZED: This can be useful if outputs should be re-used as ingredients", + "create.ponder.basin.text_8": "UNLOCALIZED: Desired outputs will then have to be extracted from the basin", + "create.ponder.basin.text_9": "UNLOCALIZED: A Filter might be necessary to avoid pulling out un-processed items", + "create.ponder.bearing_modes.header": "UNLOCALIZED: Movement Modes of the Mechanical Bearing", "create.ponder.bearing_modes.text_1": "UNLOCALIZED: When Stopped, the Bearing will place the structure at the nearest grid-aligned Angle", "create.ponder.bearing_modes.text_2": "UNLOCALIZED: It can be configured never to revert to solid blocks, or only near the angle it started at", @@ -1902,6 +1913,12 @@ "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.blaze_burner.header": "UNLOCALIZED: Feeding Blaze Burners", + "create.ponder.blaze_burner.text_1": "UNLOCALIZED: Blaze Burners can provide Heat to Items processed in a Basin", + "create.ponder.blaze_burner.text_2": "UNLOCALIZED: For this, the Blaze has to be fed with flammable items", + "create.ponder.blaze_burner.text_3": "UNLOCALIZED: With a Blaze Cake, the Burner can reach an even stronger level of heat", + "create.ponder.blaze_burner.text_4": "UNLOCALIZED: The feeding process can be automated using Deployers or Mechanical Arms", + "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.", @@ -1968,6 +1985,12 @@ "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.crushing_wheels.header": "UNLOCALIZED: Processing Items with Crushing Wheels", + "create.ponder.crushing_wheels.text_1": "UNLOCALIZED: A pair of Crushing Wheels can grind items very effectively", + "create.ponder.crushing_wheels.text_2": "UNLOCALIZED: Their Rotational Input has to make them spin into each other", + "create.ponder.crushing_wheels.text_3": "UNLOCALIZED: Items thrown or inserted into the top will get processed", + "create.ponder.crushing_wheels.text_4": "UNLOCALIZED: Items can be inserted and picked up through automated means as well", + "create.ponder.deployer.header": "UNLOCALIZED: Using the Deployer", "create.ponder.deployer.text_1": "UNLOCALIZED: Given Rotational Force, a Deployer can imitate player interactions", "create.ponder.deployer.text_10": "UNLOCALIZED: Right-click the front to give it an Item to use", @@ -1999,6 +2022,13 @@ "create.ponder.deployer_redstone.text_2": "UNLOCALIZED: Before stopping, the Deployer will finish any started cycles", "create.ponder.deployer_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.empty_blaze_burner.header": "UNLOCALIZED: Using Empty Blaze Burners", + "create.ponder.empty_blaze_burner.text_1": "UNLOCALIZED: Right-click a Blaze with the empty burner to capture it", + "create.ponder.empty_blaze_burner.text_2": "UNLOCALIZED: Alternatively, Blazes can be collected from their Spawners directly", + "create.ponder.empty_blaze_burner.text_3": "UNLOCALIZED: You now have an ideal heat source for various machines", + "create.ponder.empty_blaze_burner.text_4": "UNLOCALIZED: For Aesthetic purposes, Empty Blaze Burners can also be lit using Flint and Steel", + "create.ponder.empty_blaze_burner.text_5": "UNLOCALIZED: However, these are not suitable for industrial heating", + "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", @@ -2125,6 +2155,12 @@ "create.ponder.mechanical_harvester.text_1": "UNLOCALIZED: Whenever Harvesters are moved as part of an animated Contraption...", "create.ponder.mechanical_harvester.text_2": "UNLOCALIZED: They will harvest and reset any mature crops on their way", + "create.ponder.mechanical_mixer.header": "UNLOCALIZED: Processing Items with the Mechanical Mixer", + "create.ponder.mechanical_mixer.text_1": "UNLOCALIZED: With a Mixer and Basin, some Crafting Recipes can be automated", + "create.ponder.mechanical_mixer.text_2": "UNLOCALIZED: Available recipes include any Shapeless Crafting Recipe, plus a couple extra ones", + "create.ponder.mechanical_mixer.text_3": "UNLOCALIZED: Some of those recipes may require the heat of a Blaze Burner", + "create.ponder.mechanical_mixer.text_4": "UNLOCALIZED: The filter slot can be used in case two recipes are conflicting.", + "create.ponder.mechanical_piston.header": "UNLOCALIZED: Moving Structures using Mechanical Pistons", "create.ponder.mechanical_piston.text_1": "UNLOCALIZED: Mechanical Pistons can move blocks in front of them", "create.ponder.mechanical_piston.text_2": "UNLOCALIZED: Speed and direction of movement depend on the Rotational Input", @@ -2140,6 +2176,18 @@ "create.ponder.mechanical_plough.text_3": "UNLOCALIZED: Additionally, ploughs can create farmland", "create.ponder.mechanical_plough.text_4": "UNLOCALIZED: ...they can also launch entities without hurting them", + "create.ponder.mechanical_press.header": "UNLOCALIZED: Processing Items with the Mechanical Press", + "create.ponder.mechanical_press.text_1": "UNLOCALIZED: The Mechanical Press can process items provided beneath it", + "create.ponder.mechanical_press.text_2": "UNLOCALIZED: The Input items can be dropped or placed on a Depot under the Press", + "create.ponder.mechanical_press.text_3": "UNLOCALIZED: When items are provided on a belt...", + "create.ponder.mechanical_press.text_4": "UNLOCALIZED: The Press will hold and process them automatically", + + "create.ponder.mechanical_press_compacting.header": "UNLOCALIZED: Compacting items with the Mechanical Press", + "create.ponder.mechanical_press_compacting.text_1": "UNLOCALIZED: Pressing items held in a Basin will cause them to be Compacted", + "create.ponder.mechanical_press_compacting.text_2": "UNLOCALIZED: Compacting includes any filled 2x2 or 3x3 Crafting Recipe, plus a couple extra ones", + "create.ponder.mechanical_press_compacting.text_3": "UNLOCALIZED: Some of those recipes may require the heat of a Blaze Burner", + "create.ponder.mechanical_press_compacting.text_4": "UNLOCALIZED: The filter slot can be used in case two recipes are conflicting.", + "create.ponder.mechanical_saw_breaker.header": "UNLOCALIZED: Cutting Trees with the Mechanical Saw", "create.ponder.mechanical_saw_breaker.text_1": "UNLOCALIZED: When given Rotational Force, a Mechanical Saw will cut trees directly in front of it", "create.ponder.mechanical_saw_breaker.text_2": "UNLOCALIZED: In order to cut the tree fully, the Saw has to break the last block connecting it to the ground", @@ -2155,6 +2203,13 @@ "create.ponder.mechanical_saw_processing.text_4": "UNLOCALIZED: When an ingredient has multiple possible outcomes, the filter slot can specify it", "create.ponder.mechanical_saw_processing.text_5": "UNLOCALIZED: Without filter, the Saw would cycle through all outcomes instead", + "create.ponder.millstone.header": "UNLOCALIZED: Processing Items in the Millstone", + "create.ponder.millstone.text_1": "UNLOCALIZED: Millstones process items by grinding them", + "create.ponder.millstone.text_2": "UNLOCALIZED: They can be powered from the side using cogwheels", + "create.ponder.millstone.text_3": "UNLOCALIZED: Throw or Insert items at the top", + "create.ponder.millstone.text_4": "UNLOCALIZED: After some time, the result can be obtained via Right-click", + "create.ponder.millstone.text_5": "UNLOCALIZED: The outputs can also be extracted by automation", + "create.ponder.piston_pole.header": "UNLOCALIZED: Piston Extension Poles", "create.ponder.piston_pole.text_1": "UNLOCALIZED: Without attached Poles, a Mechanical Piston cannot move", "create.ponder.piston_pole.text_2": "UNLOCALIZED: The Length of pole added at its back determines the Extension Range", @@ -2240,6 +2295,11 @@ "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.speedometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Speedometer", + "create.ponder.speedometer.text_1": "UNLOCALIZED: The Speedometer displays the current Speed of the attached components", + "create.ponder.speedometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", + "create.ponder.speedometer.text_3": "UNLOCALIZED: Comparators can emit analog Restone Signals relative to the Speedometer's measurements", + "create.ponder.stabilized_bearings.header": "UNLOCALIZED: Stabilized Contraptions", "create.ponder.stabilized_bearings.text_1": "UNLOCALIZED: Whenever Mechanical Bearings are themselves part of a moving Structure..", "create.ponder.stabilized_bearings.text_2": "UNLOCALIZED: ..they will attempt to keep themselves upright", @@ -2252,6 +2312,11 @@ "create.ponder.sticker.text_3": "UNLOCALIZED: If it is now moved in a contraption, the block will move with it", "create.ponder.sticker.text_4": "UNLOCALIZED: Toggled once again, the block is no longer attached", + "create.ponder.stressometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Stressometer", + "create.ponder.stressometer.text_1": "UNLOCALIZED: The Stressometer displays the current Stress Capacity of the attached kinetic network", + "create.ponder.stressometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", + "create.ponder.stressometer.text_3": "UNLOCALIZED: Comparators can emit analog Restone Signals relative to the Stressometer's measurements", + "create.ponder.super_glue.header": "UNLOCALIZED: Attaching blocks using Super Glue", "create.ponder.super_glue.text_1": "UNLOCALIZED: Super Glue can be used between any two blocks", "create.ponder.super_glue.text_2": "UNLOCALIZED: The attached blocks will move together when assembled into a Contraption", 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 477c1075f..5bc39f897 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: 401", + "_": "Missing Localizations: 456", "_": "->------------------------] Game Elements [------------------------<-", @@ -1874,6 +1874,17 @@ "create.ponder.analog_lever.text_2": "UNLOCALIZED: Right-click to increase its analog power output", "create.ponder.analog_lever.text_3": "UNLOCALIZED: Right-click while Sneaking to decrease the power output again", + "create.ponder.basin.header": "UNLOCALIZED: Processing Items in the Basin", + "create.ponder.basin.text_1": "UNLOCALIZED: A Basin can hold Items and Fluids for Processing", + "create.ponder.basin.text_2": "UNLOCALIZED: After a processing step, basins try to output below to the side of them", + "create.ponder.basin.text_3": "UNLOCALIZED: When a valid component is present, the Basin will show an output faucet", + "create.ponder.basin.text_4": "UNLOCALIZED: A number of options are applicable here", + "create.ponder.basin.text_5": "UNLOCALIZED: Outputs will be caught by the inventory below", + "create.ponder.basin.text_6": "UNLOCALIZED: Without output faucet, the Basin will retain items created in its processing", + "create.ponder.basin.text_7": "UNLOCALIZED: This can be useful if outputs should be re-used as ingredients", + "create.ponder.basin.text_8": "UNLOCALIZED: Desired outputs will then have to be extracted from the basin", + "create.ponder.basin.text_9": "UNLOCALIZED: A Filter might be necessary to avoid pulling out un-processed items", + "create.ponder.bearing_modes.header": "UNLOCALIZED: Movement Modes of the Mechanical Bearing", "create.ponder.bearing_modes.text_1": "UNLOCALIZED: When Stopped, the Bearing will place the structure at the nearest grid-aligned Angle", "create.ponder.bearing_modes.text_2": "UNLOCALIZED: It can be configured never to revert to solid blocks, or only near the angle it started at", @@ -1902,6 +1913,12 @@ "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.blaze_burner.header": "UNLOCALIZED: Feeding Blaze Burners", + "create.ponder.blaze_burner.text_1": "UNLOCALIZED: Blaze Burners can provide Heat to Items processed in a Basin", + "create.ponder.blaze_burner.text_2": "UNLOCALIZED: For this, the Blaze has to be fed with flammable items", + "create.ponder.blaze_burner.text_3": "UNLOCALIZED: With a Blaze Cake, the Burner can reach an even stronger level of heat", + "create.ponder.blaze_burner.text_4": "UNLOCALIZED: The feeding process can be automated using Deployers or Mechanical Arms", + "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.", @@ -1968,6 +1985,12 @@ "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.crushing_wheels.header": "UNLOCALIZED: Processing Items with Crushing Wheels", + "create.ponder.crushing_wheels.text_1": "UNLOCALIZED: A pair of Crushing Wheels can grind items very effectively", + "create.ponder.crushing_wheels.text_2": "UNLOCALIZED: Their Rotational Input has to make them spin into each other", + "create.ponder.crushing_wheels.text_3": "UNLOCALIZED: Items thrown or inserted into the top will get processed", + "create.ponder.crushing_wheels.text_4": "UNLOCALIZED: Items can be inserted and picked up through automated means as well", + "create.ponder.deployer.header": "UNLOCALIZED: Using the Deployer", "create.ponder.deployer.text_1": "UNLOCALIZED: Given Rotational Force, a Deployer can imitate player interactions", "create.ponder.deployer.text_10": "UNLOCALIZED: Right-click the front to give it an Item to use", @@ -1999,6 +2022,13 @@ "create.ponder.deployer_redstone.text_2": "UNLOCALIZED: Before stopping, the Deployer will finish any started cycles", "create.ponder.deployer_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.empty_blaze_burner.header": "UNLOCALIZED: Using Empty Blaze Burners", + "create.ponder.empty_blaze_burner.text_1": "UNLOCALIZED: Right-click a Blaze with the empty burner to capture it", + "create.ponder.empty_blaze_burner.text_2": "UNLOCALIZED: Alternatively, Blazes can be collected from their Spawners directly", + "create.ponder.empty_blaze_burner.text_3": "UNLOCALIZED: You now have an ideal heat source for various machines", + "create.ponder.empty_blaze_burner.text_4": "UNLOCALIZED: For Aesthetic purposes, Empty Blaze Burners can also be lit using Flint and Steel", + "create.ponder.empty_blaze_burner.text_5": "UNLOCALIZED: However, these are not suitable for industrial heating", + "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", @@ -2125,6 +2155,12 @@ "create.ponder.mechanical_harvester.text_1": "UNLOCALIZED: Whenever Harvesters are moved as part of an animated Contraption...", "create.ponder.mechanical_harvester.text_2": "UNLOCALIZED: They will harvest and reset any mature crops on their way", + "create.ponder.mechanical_mixer.header": "UNLOCALIZED: Processing Items with the Mechanical Mixer", + "create.ponder.mechanical_mixer.text_1": "UNLOCALIZED: With a Mixer and Basin, some Crafting Recipes can be automated", + "create.ponder.mechanical_mixer.text_2": "UNLOCALIZED: Available recipes include any Shapeless Crafting Recipe, plus a couple extra ones", + "create.ponder.mechanical_mixer.text_3": "UNLOCALIZED: Some of those recipes may require the heat of a Blaze Burner", + "create.ponder.mechanical_mixer.text_4": "UNLOCALIZED: The filter slot can be used in case two recipes are conflicting.", + "create.ponder.mechanical_piston.header": "UNLOCALIZED: Moving Structures using Mechanical Pistons", "create.ponder.mechanical_piston.text_1": "UNLOCALIZED: Mechanical Pistons can move blocks in front of them", "create.ponder.mechanical_piston.text_2": "UNLOCALIZED: Speed and direction of movement depend on the Rotational Input", @@ -2140,6 +2176,18 @@ "create.ponder.mechanical_plough.text_3": "UNLOCALIZED: Additionally, ploughs can create farmland", "create.ponder.mechanical_plough.text_4": "UNLOCALIZED: ...they can also launch entities without hurting them", + "create.ponder.mechanical_press.header": "UNLOCALIZED: Processing Items with the Mechanical Press", + "create.ponder.mechanical_press.text_1": "UNLOCALIZED: The Mechanical Press can process items provided beneath it", + "create.ponder.mechanical_press.text_2": "UNLOCALIZED: The Input items can be dropped or placed on a Depot under the Press", + "create.ponder.mechanical_press.text_3": "UNLOCALIZED: When items are provided on a belt...", + "create.ponder.mechanical_press.text_4": "UNLOCALIZED: The Press will hold and process them automatically", + + "create.ponder.mechanical_press_compacting.header": "UNLOCALIZED: Compacting items with the Mechanical Press", + "create.ponder.mechanical_press_compacting.text_1": "UNLOCALIZED: Pressing items held in a Basin will cause them to be Compacted", + "create.ponder.mechanical_press_compacting.text_2": "UNLOCALIZED: Compacting includes any filled 2x2 or 3x3 Crafting Recipe, plus a couple extra ones", + "create.ponder.mechanical_press_compacting.text_3": "UNLOCALIZED: Some of those recipes may require the heat of a Blaze Burner", + "create.ponder.mechanical_press_compacting.text_4": "UNLOCALIZED: The filter slot can be used in case two recipes are conflicting.", + "create.ponder.mechanical_saw_breaker.header": "UNLOCALIZED: Cutting Trees with the Mechanical Saw", "create.ponder.mechanical_saw_breaker.text_1": "UNLOCALIZED: When given Rotational Force, a Mechanical Saw will cut trees directly in front of it", "create.ponder.mechanical_saw_breaker.text_2": "UNLOCALIZED: In order to cut the tree fully, the Saw has to break the last block connecting it to the ground", @@ -2155,6 +2203,13 @@ "create.ponder.mechanical_saw_processing.text_4": "UNLOCALIZED: When an ingredient has multiple possible outcomes, the filter slot can specify it", "create.ponder.mechanical_saw_processing.text_5": "UNLOCALIZED: Without filter, the Saw would cycle through all outcomes instead", + "create.ponder.millstone.header": "UNLOCALIZED: Processing Items in the Millstone", + "create.ponder.millstone.text_1": "UNLOCALIZED: Millstones process items by grinding them", + "create.ponder.millstone.text_2": "UNLOCALIZED: They can be powered from the side using cogwheels", + "create.ponder.millstone.text_3": "UNLOCALIZED: Throw or Insert items at the top", + "create.ponder.millstone.text_4": "UNLOCALIZED: After some time, the result can be obtained via Right-click", + "create.ponder.millstone.text_5": "UNLOCALIZED: The outputs can also be extracted by automation", + "create.ponder.piston_pole.header": "UNLOCALIZED: Piston Extension Poles", "create.ponder.piston_pole.text_1": "UNLOCALIZED: Without attached Poles, a Mechanical Piston cannot move", "create.ponder.piston_pole.text_2": "UNLOCALIZED: The Length of pole added at its back determines the Extension Range", @@ -2240,6 +2295,11 @@ "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.speedometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Speedometer", + "create.ponder.speedometer.text_1": "UNLOCALIZED: The Speedometer displays the current Speed of the attached components", + "create.ponder.speedometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", + "create.ponder.speedometer.text_3": "UNLOCALIZED: Comparators can emit analog Restone Signals relative to the Speedometer's measurements", + "create.ponder.stabilized_bearings.header": "UNLOCALIZED: Stabilized Contraptions", "create.ponder.stabilized_bearings.text_1": "UNLOCALIZED: Whenever Mechanical Bearings are themselves part of a moving Structure..", "create.ponder.stabilized_bearings.text_2": "UNLOCALIZED: ..they will attempt to keep themselves upright", @@ -2252,6 +2312,11 @@ "create.ponder.sticker.text_3": "UNLOCALIZED: If it is now moved in a contraption, the block will move with it", "create.ponder.sticker.text_4": "UNLOCALIZED: Toggled once again, the block is no longer attached", + "create.ponder.stressometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Stressometer", + "create.ponder.stressometer.text_1": "UNLOCALIZED: The Stressometer displays the current Stress Capacity of the attached kinetic network", + "create.ponder.stressometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", + "create.ponder.stressometer.text_3": "UNLOCALIZED: Comparators can emit analog Restone Signals relative to the Stressometer's measurements", + "create.ponder.super_glue.header": "UNLOCALIZED: Attaching blocks using Super Glue", "create.ponder.super_glue.text_1": "UNLOCALIZED: Super Glue can be used between any two blocks", "create.ponder.super_glue.text_2": "UNLOCALIZED: The attached blocks will move together when assembled into a Contraption", 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 5b8a24ac5..2dc445799 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: 1300", + "_": "Missing Localizations: 1355", "_": "->------------------------] Game Elements [------------------------<-", @@ -1874,6 +1874,17 @@ "create.ponder.analog_lever.text_2": "UNLOCALIZED: Right-click to increase its analog power output", "create.ponder.analog_lever.text_3": "UNLOCALIZED: Right-click while Sneaking to decrease the power output again", + "create.ponder.basin.header": "UNLOCALIZED: Processing Items in the Basin", + "create.ponder.basin.text_1": "UNLOCALIZED: A Basin can hold Items and Fluids for Processing", + "create.ponder.basin.text_2": "UNLOCALIZED: After a processing step, basins try to output below to the side of them", + "create.ponder.basin.text_3": "UNLOCALIZED: When a valid component is present, the Basin will show an output faucet", + "create.ponder.basin.text_4": "UNLOCALIZED: A number of options are applicable here", + "create.ponder.basin.text_5": "UNLOCALIZED: Outputs will be caught by the inventory below", + "create.ponder.basin.text_6": "UNLOCALIZED: Without output faucet, the Basin will retain items created in its processing", + "create.ponder.basin.text_7": "UNLOCALIZED: This can be useful if outputs should be re-used as ingredients", + "create.ponder.basin.text_8": "UNLOCALIZED: Desired outputs will then have to be extracted from the basin", + "create.ponder.basin.text_9": "UNLOCALIZED: A Filter might be necessary to avoid pulling out un-processed items", + "create.ponder.bearing_modes.header": "UNLOCALIZED: Movement Modes of the Mechanical Bearing", "create.ponder.bearing_modes.text_1": "UNLOCALIZED: When Stopped, the Bearing will place the structure at the nearest grid-aligned Angle", "create.ponder.bearing_modes.text_2": "UNLOCALIZED: It can be configured never to revert to solid blocks, or only near the angle it started at", @@ -1902,6 +1913,12 @@ "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.blaze_burner.header": "UNLOCALIZED: Feeding Blaze Burners", + "create.ponder.blaze_burner.text_1": "UNLOCALIZED: Blaze Burners can provide Heat to Items processed in a Basin", + "create.ponder.blaze_burner.text_2": "UNLOCALIZED: For this, the Blaze has to be fed with flammable items", + "create.ponder.blaze_burner.text_3": "UNLOCALIZED: With a Blaze Cake, the Burner can reach an even stronger level of heat", + "create.ponder.blaze_burner.text_4": "UNLOCALIZED: The feeding process can be automated using Deployers or Mechanical Arms", + "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.", @@ -1968,6 +1985,12 @@ "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.crushing_wheels.header": "UNLOCALIZED: Processing Items with Crushing Wheels", + "create.ponder.crushing_wheels.text_1": "UNLOCALIZED: A pair of Crushing Wheels can grind items very effectively", + "create.ponder.crushing_wheels.text_2": "UNLOCALIZED: Their Rotational Input has to make them spin into each other", + "create.ponder.crushing_wheels.text_3": "UNLOCALIZED: Items thrown or inserted into the top will get processed", + "create.ponder.crushing_wheels.text_4": "UNLOCALIZED: Items can be inserted and picked up through automated means as well", + "create.ponder.deployer.header": "UNLOCALIZED: Using the Deployer", "create.ponder.deployer.text_1": "UNLOCALIZED: Given Rotational Force, a Deployer can imitate player interactions", "create.ponder.deployer.text_10": "UNLOCALIZED: Right-click the front to give it an Item to use", @@ -1999,6 +2022,13 @@ "create.ponder.deployer_redstone.text_2": "UNLOCALIZED: Before stopping, the Deployer will finish any started cycles", "create.ponder.deployer_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.empty_blaze_burner.header": "UNLOCALIZED: Using Empty Blaze Burners", + "create.ponder.empty_blaze_burner.text_1": "UNLOCALIZED: Right-click a Blaze with the empty burner to capture it", + "create.ponder.empty_blaze_burner.text_2": "UNLOCALIZED: Alternatively, Blazes can be collected from their Spawners directly", + "create.ponder.empty_blaze_burner.text_3": "UNLOCALIZED: You now have an ideal heat source for various machines", + "create.ponder.empty_blaze_burner.text_4": "UNLOCALIZED: For Aesthetic purposes, Empty Blaze Burners can also be lit using Flint and Steel", + "create.ponder.empty_blaze_burner.text_5": "UNLOCALIZED: However, these are not suitable for industrial heating", + "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", @@ -2125,6 +2155,12 @@ "create.ponder.mechanical_harvester.text_1": "UNLOCALIZED: Whenever Harvesters are moved as part of an animated Contraption...", "create.ponder.mechanical_harvester.text_2": "UNLOCALIZED: They will harvest and reset any mature crops on their way", + "create.ponder.mechanical_mixer.header": "UNLOCALIZED: Processing Items with the Mechanical Mixer", + "create.ponder.mechanical_mixer.text_1": "UNLOCALIZED: With a Mixer and Basin, some Crafting Recipes can be automated", + "create.ponder.mechanical_mixer.text_2": "UNLOCALIZED: Available recipes include any Shapeless Crafting Recipe, plus a couple extra ones", + "create.ponder.mechanical_mixer.text_3": "UNLOCALIZED: Some of those recipes may require the heat of a Blaze Burner", + "create.ponder.mechanical_mixer.text_4": "UNLOCALIZED: The filter slot can be used in case two recipes are conflicting.", + "create.ponder.mechanical_piston.header": "UNLOCALIZED: Moving Structures using Mechanical Pistons", "create.ponder.mechanical_piston.text_1": "UNLOCALIZED: Mechanical Pistons can move blocks in front of them", "create.ponder.mechanical_piston.text_2": "UNLOCALIZED: Speed and direction of movement depend on the Rotational Input", @@ -2140,6 +2176,18 @@ "create.ponder.mechanical_plough.text_3": "UNLOCALIZED: Additionally, ploughs can create farmland", "create.ponder.mechanical_plough.text_4": "UNLOCALIZED: ...they can also launch entities without hurting them", + "create.ponder.mechanical_press.header": "UNLOCALIZED: Processing Items with the Mechanical Press", + "create.ponder.mechanical_press.text_1": "UNLOCALIZED: The Mechanical Press can process items provided beneath it", + "create.ponder.mechanical_press.text_2": "UNLOCALIZED: The Input items can be dropped or placed on a Depot under the Press", + "create.ponder.mechanical_press.text_3": "UNLOCALIZED: When items are provided on a belt...", + "create.ponder.mechanical_press.text_4": "UNLOCALIZED: The Press will hold and process them automatically", + + "create.ponder.mechanical_press_compacting.header": "UNLOCALIZED: Compacting items with the Mechanical Press", + "create.ponder.mechanical_press_compacting.text_1": "UNLOCALIZED: Pressing items held in a Basin will cause them to be Compacted", + "create.ponder.mechanical_press_compacting.text_2": "UNLOCALIZED: Compacting includes any filled 2x2 or 3x3 Crafting Recipe, plus a couple extra ones", + "create.ponder.mechanical_press_compacting.text_3": "UNLOCALIZED: Some of those recipes may require the heat of a Blaze Burner", + "create.ponder.mechanical_press_compacting.text_4": "UNLOCALIZED: The filter slot can be used in case two recipes are conflicting.", + "create.ponder.mechanical_saw_breaker.header": "UNLOCALIZED: Cutting Trees with the Mechanical Saw", "create.ponder.mechanical_saw_breaker.text_1": "UNLOCALIZED: When given Rotational Force, a Mechanical Saw will cut trees directly in front of it", "create.ponder.mechanical_saw_breaker.text_2": "UNLOCALIZED: In order to cut the tree fully, the Saw has to break the last block connecting it to the ground", @@ -2155,6 +2203,13 @@ "create.ponder.mechanical_saw_processing.text_4": "UNLOCALIZED: When an ingredient has multiple possible outcomes, the filter slot can specify it", "create.ponder.mechanical_saw_processing.text_5": "UNLOCALIZED: Without filter, the Saw would cycle through all outcomes instead", + "create.ponder.millstone.header": "UNLOCALIZED: Processing Items in the Millstone", + "create.ponder.millstone.text_1": "UNLOCALIZED: Millstones process items by grinding them", + "create.ponder.millstone.text_2": "UNLOCALIZED: They can be powered from the side using cogwheels", + "create.ponder.millstone.text_3": "UNLOCALIZED: Throw or Insert items at the top", + "create.ponder.millstone.text_4": "UNLOCALIZED: After some time, the result can be obtained via Right-click", + "create.ponder.millstone.text_5": "UNLOCALIZED: The outputs can also be extracted by automation", + "create.ponder.piston_pole.header": "UNLOCALIZED: Piston Extension Poles", "create.ponder.piston_pole.text_1": "UNLOCALIZED: Without attached Poles, a Mechanical Piston cannot move", "create.ponder.piston_pole.text_2": "UNLOCALIZED: The Length of pole added at its back determines the Extension Range", @@ -2240,6 +2295,11 @@ "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.speedometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Speedometer", + "create.ponder.speedometer.text_1": "UNLOCALIZED: The Speedometer displays the current Speed of the attached components", + "create.ponder.speedometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", + "create.ponder.speedometer.text_3": "UNLOCALIZED: Comparators can emit analog Restone Signals relative to the Speedometer's measurements", + "create.ponder.stabilized_bearings.header": "UNLOCALIZED: Stabilized Contraptions", "create.ponder.stabilized_bearings.text_1": "UNLOCALIZED: Whenever Mechanical Bearings are themselves part of a moving Structure..", "create.ponder.stabilized_bearings.text_2": "UNLOCALIZED: ..they will attempt to keep themselves upright", @@ -2252,6 +2312,11 @@ "create.ponder.sticker.text_3": "UNLOCALIZED: If it is now moved in a contraption, the block will move with it", "create.ponder.sticker.text_4": "UNLOCALIZED: Toggled once again, the block is no longer attached", + "create.ponder.stressometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Stressometer", + "create.ponder.stressometer.text_1": "UNLOCALIZED: The Stressometer displays the current Stress Capacity of the attached kinetic network", + "create.ponder.stressometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", + "create.ponder.stressometer.text_3": "UNLOCALIZED: Comparators can emit analog Restone Signals relative to the Stressometer's measurements", + "create.ponder.super_glue.header": "UNLOCALIZED: Attaching blocks using Super Glue", "create.ponder.super_glue.text_1": "UNLOCALIZED: Super Glue can be used between any two blocks", "create.ponder.super_glue.text_2": "UNLOCALIZED: The attached blocks will move together when assembled into a Contraption", 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 54fec9d1c..347fa2a27 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: 1082", + "_": "Missing Localizations: 1137", "_": "->------------------------] Game Elements [------------------------<-", @@ -1874,6 +1874,17 @@ "create.ponder.analog_lever.text_2": "UNLOCALIZED: Right-click to increase its analog power output", "create.ponder.analog_lever.text_3": "UNLOCALIZED: Right-click while Sneaking to decrease the power output again", + "create.ponder.basin.header": "UNLOCALIZED: Processing Items in the Basin", + "create.ponder.basin.text_1": "UNLOCALIZED: A Basin can hold Items and Fluids for Processing", + "create.ponder.basin.text_2": "UNLOCALIZED: After a processing step, basins try to output below to the side of them", + "create.ponder.basin.text_3": "UNLOCALIZED: When a valid component is present, the Basin will show an output faucet", + "create.ponder.basin.text_4": "UNLOCALIZED: A number of options are applicable here", + "create.ponder.basin.text_5": "UNLOCALIZED: Outputs will be caught by the inventory below", + "create.ponder.basin.text_6": "UNLOCALIZED: Without output faucet, the Basin will retain items created in its processing", + "create.ponder.basin.text_7": "UNLOCALIZED: This can be useful if outputs should be re-used as ingredients", + "create.ponder.basin.text_8": "UNLOCALIZED: Desired outputs will then have to be extracted from the basin", + "create.ponder.basin.text_9": "UNLOCALIZED: A Filter might be necessary to avoid pulling out un-processed items", + "create.ponder.bearing_modes.header": "UNLOCALIZED: Movement Modes of the Mechanical Bearing", "create.ponder.bearing_modes.text_1": "UNLOCALIZED: When Stopped, the Bearing will place the structure at the nearest grid-aligned Angle", "create.ponder.bearing_modes.text_2": "UNLOCALIZED: It can be configured never to revert to solid blocks, or only near the angle it started at", @@ -1902,6 +1913,12 @@ "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.blaze_burner.header": "UNLOCALIZED: Feeding Blaze Burners", + "create.ponder.blaze_burner.text_1": "UNLOCALIZED: Blaze Burners can provide Heat to Items processed in a Basin", + "create.ponder.blaze_burner.text_2": "UNLOCALIZED: For this, the Blaze has to be fed with flammable items", + "create.ponder.blaze_burner.text_3": "UNLOCALIZED: With a Blaze Cake, the Burner can reach an even stronger level of heat", + "create.ponder.blaze_burner.text_4": "UNLOCALIZED: The feeding process can be automated using Deployers or Mechanical Arms", + "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.", @@ -1968,6 +1985,12 @@ "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.crushing_wheels.header": "UNLOCALIZED: Processing Items with Crushing Wheels", + "create.ponder.crushing_wheels.text_1": "UNLOCALIZED: A pair of Crushing Wheels can grind items very effectively", + "create.ponder.crushing_wheels.text_2": "UNLOCALIZED: Their Rotational Input has to make them spin into each other", + "create.ponder.crushing_wheels.text_3": "UNLOCALIZED: Items thrown or inserted into the top will get processed", + "create.ponder.crushing_wheels.text_4": "UNLOCALIZED: Items can be inserted and picked up through automated means as well", + "create.ponder.deployer.header": "UNLOCALIZED: Using the Deployer", "create.ponder.deployer.text_1": "UNLOCALIZED: Given Rotational Force, a Deployer can imitate player interactions", "create.ponder.deployer.text_10": "UNLOCALIZED: Right-click the front to give it an Item to use", @@ -1999,6 +2022,13 @@ "create.ponder.deployer_redstone.text_2": "UNLOCALIZED: Before stopping, the Deployer will finish any started cycles", "create.ponder.deployer_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.empty_blaze_burner.header": "UNLOCALIZED: Using Empty Blaze Burners", + "create.ponder.empty_blaze_burner.text_1": "UNLOCALIZED: Right-click a Blaze with the empty burner to capture it", + "create.ponder.empty_blaze_burner.text_2": "UNLOCALIZED: Alternatively, Blazes can be collected from their Spawners directly", + "create.ponder.empty_blaze_burner.text_3": "UNLOCALIZED: You now have an ideal heat source for various machines", + "create.ponder.empty_blaze_burner.text_4": "UNLOCALIZED: For Aesthetic purposes, Empty Blaze Burners can also be lit using Flint and Steel", + "create.ponder.empty_blaze_burner.text_5": "UNLOCALIZED: However, these are not suitable for industrial heating", + "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", @@ -2125,6 +2155,12 @@ "create.ponder.mechanical_harvester.text_1": "UNLOCALIZED: Whenever Harvesters are moved as part of an animated Contraption...", "create.ponder.mechanical_harvester.text_2": "UNLOCALIZED: They will harvest and reset any mature crops on their way", + "create.ponder.mechanical_mixer.header": "UNLOCALIZED: Processing Items with the Mechanical Mixer", + "create.ponder.mechanical_mixer.text_1": "UNLOCALIZED: With a Mixer and Basin, some Crafting Recipes can be automated", + "create.ponder.mechanical_mixer.text_2": "UNLOCALIZED: Available recipes include any Shapeless Crafting Recipe, plus a couple extra ones", + "create.ponder.mechanical_mixer.text_3": "UNLOCALIZED: Some of those recipes may require the heat of a Blaze Burner", + "create.ponder.mechanical_mixer.text_4": "UNLOCALIZED: The filter slot can be used in case two recipes are conflicting.", + "create.ponder.mechanical_piston.header": "UNLOCALIZED: Moving Structures using Mechanical Pistons", "create.ponder.mechanical_piston.text_1": "UNLOCALIZED: Mechanical Pistons can move blocks in front of them", "create.ponder.mechanical_piston.text_2": "UNLOCALIZED: Speed and direction of movement depend on the Rotational Input", @@ -2140,6 +2176,18 @@ "create.ponder.mechanical_plough.text_3": "UNLOCALIZED: Additionally, ploughs can create farmland", "create.ponder.mechanical_plough.text_4": "UNLOCALIZED: ...they can also launch entities without hurting them", + "create.ponder.mechanical_press.header": "UNLOCALIZED: Processing Items with the Mechanical Press", + "create.ponder.mechanical_press.text_1": "UNLOCALIZED: The Mechanical Press can process items provided beneath it", + "create.ponder.mechanical_press.text_2": "UNLOCALIZED: The Input items can be dropped or placed on a Depot under the Press", + "create.ponder.mechanical_press.text_3": "UNLOCALIZED: When items are provided on a belt...", + "create.ponder.mechanical_press.text_4": "UNLOCALIZED: The Press will hold and process them automatically", + + "create.ponder.mechanical_press_compacting.header": "UNLOCALIZED: Compacting items with the Mechanical Press", + "create.ponder.mechanical_press_compacting.text_1": "UNLOCALIZED: Pressing items held in a Basin will cause them to be Compacted", + "create.ponder.mechanical_press_compacting.text_2": "UNLOCALIZED: Compacting includes any filled 2x2 or 3x3 Crafting Recipe, plus a couple extra ones", + "create.ponder.mechanical_press_compacting.text_3": "UNLOCALIZED: Some of those recipes may require the heat of a Blaze Burner", + "create.ponder.mechanical_press_compacting.text_4": "UNLOCALIZED: The filter slot can be used in case two recipes are conflicting.", + "create.ponder.mechanical_saw_breaker.header": "UNLOCALIZED: Cutting Trees with the Mechanical Saw", "create.ponder.mechanical_saw_breaker.text_1": "UNLOCALIZED: When given Rotational Force, a Mechanical Saw will cut trees directly in front of it", "create.ponder.mechanical_saw_breaker.text_2": "UNLOCALIZED: In order to cut the tree fully, the Saw has to break the last block connecting it to the ground", @@ -2155,6 +2203,13 @@ "create.ponder.mechanical_saw_processing.text_4": "UNLOCALIZED: When an ingredient has multiple possible outcomes, the filter slot can specify it", "create.ponder.mechanical_saw_processing.text_5": "UNLOCALIZED: Without filter, the Saw would cycle through all outcomes instead", + "create.ponder.millstone.header": "UNLOCALIZED: Processing Items in the Millstone", + "create.ponder.millstone.text_1": "UNLOCALIZED: Millstones process items by grinding them", + "create.ponder.millstone.text_2": "UNLOCALIZED: They can be powered from the side using cogwheels", + "create.ponder.millstone.text_3": "UNLOCALIZED: Throw or Insert items at the top", + "create.ponder.millstone.text_4": "UNLOCALIZED: After some time, the result can be obtained via Right-click", + "create.ponder.millstone.text_5": "UNLOCALIZED: The outputs can also be extracted by automation", + "create.ponder.piston_pole.header": "UNLOCALIZED: Piston Extension Poles", "create.ponder.piston_pole.text_1": "UNLOCALIZED: Without attached Poles, a Mechanical Piston cannot move", "create.ponder.piston_pole.text_2": "UNLOCALIZED: The Length of pole added at its back determines the Extension Range", @@ -2240,6 +2295,11 @@ "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.speedometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Speedometer", + "create.ponder.speedometer.text_1": "UNLOCALIZED: The Speedometer displays the current Speed of the attached components", + "create.ponder.speedometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", + "create.ponder.speedometer.text_3": "UNLOCALIZED: Comparators can emit analog Restone Signals relative to the Speedometer's measurements", + "create.ponder.stabilized_bearings.header": "UNLOCALIZED: Stabilized Contraptions", "create.ponder.stabilized_bearings.text_1": "UNLOCALIZED: Whenever Mechanical Bearings are themselves part of a moving Structure..", "create.ponder.stabilized_bearings.text_2": "UNLOCALIZED: ..they will attempt to keep themselves upright", @@ -2252,6 +2312,11 @@ "create.ponder.sticker.text_3": "UNLOCALIZED: If it is now moved in a contraption, the block will move with it", "create.ponder.sticker.text_4": "UNLOCALIZED: Toggled once again, the block is no longer attached", + "create.ponder.stressometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Stressometer", + "create.ponder.stressometer.text_1": "UNLOCALIZED: The Stressometer displays the current Stress Capacity of the attached kinetic network", + "create.ponder.stressometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", + "create.ponder.stressometer.text_3": "UNLOCALIZED: Comparators can emit analog Restone Signals relative to the Stressometer's measurements", + "create.ponder.super_glue.header": "UNLOCALIZED: Attaching blocks using Super Glue", "create.ponder.super_glue.text_1": "UNLOCALIZED: Super Glue can be used between any two blocks", "create.ponder.super_glue.text_2": "UNLOCALIZED: The attached blocks will move together when assembled into a Contraption", 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 8f188d3ce..763c8bb7b 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: 418", + "_": "Missing Localizations: 473", "_": "->------------------------] Game Elements [------------------------<-", @@ -1874,6 +1874,17 @@ "create.ponder.analog_lever.text_2": "UNLOCALIZED: Right-click to increase its analog power output", "create.ponder.analog_lever.text_3": "UNLOCALIZED: Right-click while Sneaking to decrease the power output again", + "create.ponder.basin.header": "UNLOCALIZED: Processing Items in the Basin", + "create.ponder.basin.text_1": "UNLOCALIZED: A Basin can hold Items and Fluids for Processing", + "create.ponder.basin.text_2": "UNLOCALIZED: After a processing step, basins try to output below to the side of them", + "create.ponder.basin.text_3": "UNLOCALIZED: When a valid component is present, the Basin will show an output faucet", + "create.ponder.basin.text_4": "UNLOCALIZED: A number of options are applicable here", + "create.ponder.basin.text_5": "UNLOCALIZED: Outputs will be caught by the inventory below", + "create.ponder.basin.text_6": "UNLOCALIZED: Without output faucet, the Basin will retain items created in its processing", + "create.ponder.basin.text_7": "UNLOCALIZED: This can be useful if outputs should be re-used as ingredients", + "create.ponder.basin.text_8": "UNLOCALIZED: Desired outputs will then have to be extracted from the basin", + "create.ponder.basin.text_9": "UNLOCALIZED: A Filter might be necessary to avoid pulling out un-processed items", + "create.ponder.bearing_modes.header": "UNLOCALIZED: Movement Modes of the Mechanical Bearing", "create.ponder.bearing_modes.text_1": "UNLOCALIZED: When Stopped, the Bearing will place the structure at the nearest grid-aligned Angle", "create.ponder.bearing_modes.text_2": "UNLOCALIZED: It can be configured never to revert to solid blocks, or only near the angle it started at", @@ -1902,6 +1913,12 @@ "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.blaze_burner.header": "UNLOCALIZED: Feeding Blaze Burners", + "create.ponder.blaze_burner.text_1": "UNLOCALIZED: Blaze Burners can provide Heat to Items processed in a Basin", + "create.ponder.blaze_burner.text_2": "UNLOCALIZED: For this, the Blaze has to be fed with flammable items", + "create.ponder.blaze_burner.text_3": "UNLOCALIZED: With a Blaze Cake, the Burner can reach an even stronger level of heat", + "create.ponder.blaze_burner.text_4": "UNLOCALIZED: The feeding process can be automated using Deployers or Mechanical Arms", + "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.", @@ -1968,6 +1985,12 @@ "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.crushing_wheels.header": "UNLOCALIZED: Processing Items with Crushing Wheels", + "create.ponder.crushing_wheels.text_1": "UNLOCALIZED: A pair of Crushing Wheels can grind items very effectively", + "create.ponder.crushing_wheels.text_2": "UNLOCALIZED: Their Rotational Input has to make them spin into each other", + "create.ponder.crushing_wheels.text_3": "UNLOCALIZED: Items thrown or inserted into the top will get processed", + "create.ponder.crushing_wheels.text_4": "UNLOCALIZED: Items can be inserted and picked up through automated means as well", + "create.ponder.deployer.header": "UNLOCALIZED: Using the Deployer", "create.ponder.deployer.text_1": "UNLOCALIZED: Given Rotational Force, a Deployer can imitate player interactions", "create.ponder.deployer.text_10": "UNLOCALIZED: Right-click the front to give it an Item to use", @@ -1999,6 +2022,13 @@ "create.ponder.deployer_redstone.text_2": "UNLOCALIZED: Before stopping, the Deployer will finish any started cycles", "create.ponder.deployer_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.empty_blaze_burner.header": "UNLOCALIZED: Using Empty Blaze Burners", + "create.ponder.empty_blaze_burner.text_1": "UNLOCALIZED: Right-click a Blaze with the empty burner to capture it", + "create.ponder.empty_blaze_burner.text_2": "UNLOCALIZED: Alternatively, Blazes can be collected from their Spawners directly", + "create.ponder.empty_blaze_burner.text_3": "UNLOCALIZED: You now have an ideal heat source for various machines", + "create.ponder.empty_blaze_burner.text_4": "UNLOCALIZED: For Aesthetic purposes, Empty Blaze Burners can also be lit using Flint and Steel", + "create.ponder.empty_blaze_burner.text_5": "UNLOCALIZED: However, these are not suitable for industrial heating", + "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", @@ -2125,6 +2155,12 @@ "create.ponder.mechanical_harvester.text_1": "UNLOCALIZED: Whenever Harvesters are moved as part of an animated Contraption...", "create.ponder.mechanical_harvester.text_2": "UNLOCALIZED: They will harvest and reset any mature crops on their way", + "create.ponder.mechanical_mixer.header": "UNLOCALIZED: Processing Items with the Mechanical Mixer", + "create.ponder.mechanical_mixer.text_1": "UNLOCALIZED: With a Mixer and Basin, some Crafting Recipes can be automated", + "create.ponder.mechanical_mixer.text_2": "UNLOCALIZED: Available recipes include any Shapeless Crafting Recipe, plus a couple extra ones", + "create.ponder.mechanical_mixer.text_3": "UNLOCALIZED: Some of those recipes may require the heat of a Blaze Burner", + "create.ponder.mechanical_mixer.text_4": "UNLOCALIZED: The filter slot can be used in case two recipes are conflicting.", + "create.ponder.mechanical_piston.header": "UNLOCALIZED: Moving Structures using Mechanical Pistons", "create.ponder.mechanical_piston.text_1": "UNLOCALIZED: Mechanical Pistons can move blocks in front of them", "create.ponder.mechanical_piston.text_2": "UNLOCALIZED: Speed and direction of movement depend on the Rotational Input", @@ -2140,6 +2176,18 @@ "create.ponder.mechanical_plough.text_3": "UNLOCALIZED: Additionally, ploughs can create farmland", "create.ponder.mechanical_plough.text_4": "UNLOCALIZED: ...they can also launch entities without hurting them", + "create.ponder.mechanical_press.header": "UNLOCALIZED: Processing Items with the Mechanical Press", + "create.ponder.mechanical_press.text_1": "UNLOCALIZED: The Mechanical Press can process items provided beneath it", + "create.ponder.mechanical_press.text_2": "UNLOCALIZED: The Input items can be dropped or placed on a Depot under the Press", + "create.ponder.mechanical_press.text_3": "UNLOCALIZED: When items are provided on a belt...", + "create.ponder.mechanical_press.text_4": "UNLOCALIZED: The Press will hold and process them automatically", + + "create.ponder.mechanical_press_compacting.header": "UNLOCALIZED: Compacting items with the Mechanical Press", + "create.ponder.mechanical_press_compacting.text_1": "UNLOCALIZED: Pressing items held in a Basin will cause them to be Compacted", + "create.ponder.mechanical_press_compacting.text_2": "UNLOCALIZED: Compacting includes any filled 2x2 or 3x3 Crafting Recipe, plus a couple extra ones", + "create.ponder.mechanical_press_compacting.text_3": "UNLOCALIZED: Some of those recipes may require the heat of a Blaze Burner", + "create.ponder.mechanical_press_compacting.text_4": "UNLOCALIZED: The filter slot can be used in case two recipes are conflicting.", + "create.ponder.mechanical_saw_breaker.header": "UNLOCALIZED: Cutting Trees with the Mechanical Saw", "create.ponder.mechanical_saw_breaker.text_1": "UNLOCALIZED: When given Rotational Force, a Mechanical Saw will cut trees directly in front of it", "create.ponder.mechanical_saw_breaker.text_2": "UNLOCALIZED: In order to cut the tree fully, the Saw has to break the last block connecting it to the ground", @@ -2155,6 +2203,13 @@ "create.ponder.mechanical_saw_processing.text_4": "UNLOCALIZED: When an ingredient has multiple possible outcomes, the filter slot can specify it", "create.ponder.mechanical_saw_processing.text_5": "UNLOCALIZED: Without filter, the Saw would cycle through all outcomes instead", + "create.ponder.millstone.header": "UNLOCALIZED: Processing Items in the Millstone", + "create.ponder.millstone.text_1": "UNLOCALIZED: Millstones process items by grinding them", + "create.ponder.millstone.text_2": "UNLOCALIZED: They can be powered from the side using cogwheels", + "create.ponder.millstone.text_3": "UNLOCALIZED: Throw or Insert items at the top", + "create.ponder.millstone.text_4": "UNLOCALIZED: After some time, the result can be obtained via Right-click", + "create.ponder.millstone.text_5": "UNLOCALIZED: The outputs can also be extracted by automation", + "create.ponder.piston_pole.header": "UNLOCALIZED: Piston Extension Poles", "create.ponder.piston_pole.text_1": "UNLOCALIZED: Without attached Poles, a Mechanical Piston cannot move", "create.ponder.piston_pole.text_2": "UNLOCALIZED: The Length of pole added at its back determines the Extension Range", @@ -2240,6 +2295,11 @@ "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.speedometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Speedometer", + "create.ponder.speedometer.text_1": "UNLOCALIZED: The Speedometer displays the current Speed of the attached components", + "create.ponder.speedometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", + "create.ponder.speedometer.text_3": "UNLOCALIZED: Comparators can emit analog Restone Signals relative to the Speedometer's measurements", + "create.ponder.stabilized_bearings.header": "UNLOCALIZED: Stabilized Contraptions", "create.ponder.stabilized_bearings.text_1": "UNLOCALIZED: Whenever Mechanical Bearings are themselves part of a moving Structure..", "create.ponder.stabilized_bearings.text_2": "UNLOCALIZED: ..they will attempt to keep themselves upright", @@ -2252,6 +2312,11 @@ "create.ponder.sticker.text_3": "UNLOCALIZED: If it is now moved in a contraption, the block will move with it", "create.ponder.sticker.text_4": "UNLOCALIZED: Toggled once again, the block is no longer attached", + "create.ponder.stressometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Stressometer", + "create.ponder.stressometer.text_1": "UNLOCALIZED: The Stressometer displays the current Stress Capacity of the attached kinetic network", + "create.ponder.stressometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", + "create.ponder.stressometer.text_3": "UNLOCALIZED: Comparators can emit analog Restone Signals relative to the Stressometer's measurements", + "create.ponder.super_glue.header": "UNLOCALIZED: Attaching blocks using Super Glue", "create.ponder.super_glue.text_1": "UNLOCALIZED: Super Glue can be used between any two blocks", "create.ponder.super_glue.text_2": "UNLOCALIZED: The attached blocks will move together when assembled into a Contraption", 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 6a407c0a5..9b23ee4d0 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: 425", + "_": "Missing Localizations: 480", "_": "->------------------------] Game Elements [------------------------<-", @@ -1874,6 +1874,17 @@ "create.ponder.analog_lever.text_2": "UNLOCALIZED: Right-click to increase its analog power output", "create.ponder.analog_lever.text_3": "UNLOCALIZED: Right-click while Sneaking to decrease the power output again", + "create.ponder.basin.header": "UNLOCALIZED: Processing Items in the Basin", + "create.ponder.basin.text_1": "UNLOCALIZED: A Basin can hold Items and Fluids for Processing", + "create.ponder.basin.text_2": "UNLOCALIZED: After a processing step, basins try to output below to the side of them", + "create.ponder.basin.text_3": "UNLOCALIZED: When a valid component is present, the Basin will show an output faucet", + "create.ponder.basin.text_4": "UNLOCALIZED: A number of options are applicable here", + "create.ponder.basin.text_5": "UNLOCALIZED: Outputs will be caught by the inventory below", + "create.ponder.basin.text_6": "UNLOCALIZED: Without output faucet, the Basin will retain items created in its processing", + "create.ponder.basin.text_7": "UNLOCALIZED: This can be useful if outputs should be re-used as ingredients", + "create.ponder.basin.text_8": "UNLOCALIZED: Desired outputs will then have to be extracted from the basin", + "create.ponder.basin.text_9": "UNLOCALIZED: A Filter might be necessary to avoid pulling out un-processed items", + "create.ponder.bearing_modes.header": "UNLOCALIZED: Movement Modes of the Mechanical Bearing", "create.ponder.bearing_modes.text_1": "UNLOCALIZED: When Stopped, the Bearing will place the structure at the nearest grid-aligned Angle", "create.ponder.bearing_modes.text_2": "UNLOCALIZED: It can be configured never to revert to solid blocks, or only near the angle it started at", @@ -1902,6 +1913,12 @@ "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.blaze_burner.header": "UNLOCALIZED: Feeding Blaze Burners", + "create.ponder.blaze_burner.text_1": "UNLOCALIZED: Blaze Burners can provide Heat to Items processed in a Basin", + "create.ponder.blaze_burner.text_2": "UNLOCALIZED: For this, the Blaze has to be fed with flammable items", + "create.ponder.blaze_burner.text_3": "UNLOCALIZED: With a Blaze Cake, the Burner can reach an even stronger level of heat", + "create.ponder.blaze_burner.text_4": "UNLOCALIZED: The feeding process can be automated using Deployers or Mechanical Arms", + "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.", @@ -1968,6 +1985,12 @@ "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.crushing_wheels.header": "UNLOCALIZED: Processing Items with Crushing Wheels", + "create.ponder.crushing_wheels.text_1": "UNLOCALIZED: A pair of Crushing Wheels can grind items very effectively", + "create.ponder.crushing_wheels.text_2": "UNLOCALIZED: Their Rotational Input has to make them spin into each other", + "create.ponder.crushing_wheels.text_3": "UNLOCALIZED: Items thrown or inserted into the top will get processed", + "create.ponder.crushing_wheels.text_4": "UNLOCALIZED: Items can be inserted and picked up through automated means as well", + "create.ponder.deployer.header": "UNLOCALIZED: Using the Deployer", "create.ponder.deployer.text_1": "UNLOCALIZED: Given Rotational Force, a Deployer can imitate player interactions", "create.ponder.deployer.text_10": "UNLOCALIZED: Right-click the front to give it an Item to use", @@ -1999,6 +2022,13 @@ "create.ponder.deployer_redstone.text_2": "UNLOCALIZED: Before stopping, the Deployer will finish any started cycles", "create.ponder.deployer_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.empty_blaze_burner.header": "UNLOCALIZED: Using Empty Blaze Burners", + "create.ponder.empty_blaze_burner.text_1": "UNLOCALIZED: Right-click a Blaze with the empty burner to capture it", + "create.ponder.empty_blaze_burner.text_2": "UNLOCALIZED: Alternatively, Blazes can be collected from their Spawners directly", + "create.ponder.empty_blaze_burner.text_3": "UNLOCALIZED: You now have an ideal heat source for various machines", + "create.ponder.empty_blaze_burner.text_4": "UNLOCALIZED: For Aesthetic purposes, Empty Blaze Burners can also be lit using Flint and Steel", + "create.ponder.empty_blaze_burner.text_5": "UNLOCALIZED: However, these are not suitable for industrial heating", + "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", @@ -2125,6 +2155,12 @@ "create.ponder.mechanical_harvester.text_1": "UNLOCALIZED: Whenever Harvesters are moved as part of an animated Contraption...", "create.ponder.mechanical_harvester.text_2": "UNLOCALIZED: They will harvest and reset any mature crops on their way", + "create.ponder.mechanical_mixer.header": "UNLOCALIZED: Processing Items with the Mechanical Mixer", + "create.ponder.mechanical_mixer.text_1": "UNLOCALIZED: With a Mixer and Basin, some Crafting Recipes can be automated", + "create.ponder.mechanical_mixer.text_2": "UNLOCALIZED: Available recipes include any Shapeless Crafting Recipe, plus a couple extra ones", + "create.ponder.mechanical_mixer.text_3": "UNLOCALIZED: Some of those recipes may require the heat of a Blaze Burner", + "create.ponder.mechanical_mixer.text_4": "UNLOCALIZED: The filter slot can be used in case two recipes are conflicting.", + "create.ponder.mechanical_piston.header": "UNLOCALIZED: Moving Structures using Mechanical Pistons", "create.ponder.mechanical_piston.text_1": "UNLOCALIZED: Mechanical Pistons can move blocks in front of them", "create.ponder.mechanical_piston.text_2": "UNLOCALIZED: Speed and direction of movement depend on the Rotational Input", @@ -2140,6 +2176,18 @@ "create.ponder.mechanical_plough.text_3": "UNLOCALIZED: Additionally, ploughs can create farmland", "create.ponder.mechanical_plough.text_4": "UNLOCALIZED: ...they can also launch entities without hurting them", + "create.ponder.mechanical_press.header": "UNLOCALIZED: Processing Items with the Mechanical Press", + "create.ponder.mechanical_press.text_1": "UNLOCALIZED: The Mechanical Press can process items provided beneath it", + "create.ponder.mechanical_press.text_2": "UNLOCALIZED: The Input items can be dropped or placed on a Depot under the Press", + "create.ponder.mechanical_press.text_3": "UNLOCALIZED: When items are provided on a belt...", + "create.ponder.mechanical_press.text_4": "UNLOCALIZED: The Press will hold and process them automatically", + + "create.ponder.mechanical_press_compacting.header": "UNLOCALIZED: Compacting items with the Mechanical Press", + "create.ponder.mechanical_press_compacting.text_1": "UNLOCALIZED: Pressing items held in a Basin will cause them to be Compacted", + "create.ponder.mechanical_press_compacting.text_2": "UNLOCALIZED: Compacting includes any filled 2x2 or 3x3 Crafting Recipe, plus a couple extra ones", + "create.ponder.mechanical_press_compacting.text_3": "UNLOCALIZED: Some of those recipes may require the heat of a Blaze Burner", + "create.ponder.mechanical_press_compacting.text_4": "UNLOCALIZED: The filter slot can be used in case two recipes are conflicting.", + "create.ponder.mechanical_saw_breaker.header": "UNLOCALIZED: Cutting Trees with the Mechanical Saw", "create.ponder.mechanical_saw_breaker.text_1": "UNLOCALIZED: When given Rotational Force, a Mechanical Saw will cut trees directly in front of it", "create.ponder.mechanical_saw_breaker.text_2": "UNLOCALIZED: In order to cut the tree fully, the Saw has to break the last block connecting it to the ground", @@ -2155,6 +2203,13 @@ "create.ponder.mechanical_saw_processing.text_4": "UNLOCALIZED: When an ingredient has multiple possible outcomes, the filter slot can specify it", "create.ponder.mechanical_saw_processing.text_5": "UNLOCALIZED: Without filter, the Saw would cycle through all outcomes instead", + "create.ponder.millstone.header": "UNLOCALIZED: Processing Items in the Millstone", + "create.ponder.millstone.text_1": "UNLOCALIZED: Millstones process items by grinding them", + "create.ponder.millstone.text_2": "UNLOCALIZED: They can be powered from the side using cogwheels", + "create.ponder.millstone.text_3": "UNLOCALIZED: Throw or Insert items at the top", + "create.ponder.millstone.text_4": "UNLOCALIZED: After some time, the result can be obtained via Right-click", + "create.ponder.millstone.text_5": "UNLOCALIZED: The outputs can also be extracted by automation", + "create.ponder.piston_pole.header": "UNLOCALIZED: Piston Extension Poles", "create.ponder.piston_pole.text_1": "UNLOCALIZED: Without attached Poles, a Mechanical Piston cannot move", "create.ponder.piston_pole.text_2": "UNLOCALIZED: The Length of pole added at its back determines the Extension Range", @@ -2240,6 +2295,11 @@ "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.speedometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Speedometer", + "create.ponder.speedometer.text_1": "UNLOCALIZED: The Speedometer displays the current Speed of the attached components", + "create.ponder.speedometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", + "create.ponder.speedometer.text_3": "UNLOCALIZED: Comparators can emit analog Restone Signals relative to the Speedometer's measurements", + "create.ponder.stabilized_bearings.header": "UNLOCALIZED: Stabilized Contraptions", "create.ponder.stabilized_bearings.text_1": "UNLOCALIZED: Whenever Mechanical Bearings are themselves part of a moving Structure..", "create.ponder.stabilized_bearings.text_2": "UNLOCALIZED: ..they will attempt to keep themselves upright", @@ -2252,6 +2312,11 @@ "create.ponder.sticker.text_3": "UNLOCALIZED: If it is now moved in a contraption, the block will move with it", "create.ponder.sticker.text_4": "UNLOCALIZED: Toggled once again, the block is no longer attached", + "create.ponder.stressometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Stressometer", + "create.ponder.stressometer.text_1": "UNLOCALIZED: The Stressometer displays the current Stress Capacity of the attached kinetic network", + "create.ponder.stressometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", + "create.ponder.stressometer.text_3": "UNLOCALIZED: Comparators can emit analog Restone Signals relative to the Stressometer's measurements", + "create.ponder.super_glue.header": "UNLOCALIZED: Attaching blocks using Super Glue", "create.ponder.super_glue.text_1": "UNLOCALIZED: Super Glue can be used between any two blocks", "create.ponder.super_glue.text_2": "UNLOCALIZED: The attached blocks will move together when assembled into a Contraption", 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 735d654f7..51410c720 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: 471", + "_": "Missing Localizations: 526", "_": "->------------------------] Game Elements [------------------------<-", @@ -1874,6 +1874,17 @@ "create.ponder.analog_lever.text_2": "UNLOCALIZED: Right-click to increase its analog power output", "create.ponder.analog_lever.text_3": "UNLOCALIZED: Right-click while Sneaking to decrease the power output again", + "create.ponder.basin.header": "UNLOCALIZED: Processing Items in the Basin", + "create.ponder.basin.text_1": "UNLOCALIZED: A Basin can hold Items and Fluids for Processing", + "create.ponder.basin.text_2": "UNLOCALIZED: After a processing step, basins try to output below to the side of them", + "create.ponder.basin.text_3": "UNLOCALIZED: When a valid component is present, the Basin will show an output faucet", + "create.ponder.basin.text_4": "UNLOCALIZED: A number of options are applicable here", + "create.ponder.basin.text_5": "UNLOCALIZED: Outputs will be caught by the inventory below", + "create.ponder.basin.text_6": "UNLOCALIZED: Without output faucet, the Basin will retain items created in its processing", + "create.ponder.basin.text_7": "UNLOCALIZED: This can be useful if outputs should be re-used as ingredients", + "create.ponder.basin.text_8": "UNLOCALIZED: Desired outputs will then have to be extracted from the basin", + "create.ponder.basin.text_9": "UNLOCALIZED: A Filter might be necessary to avoid pulling out un-processed items", + "create.ponder.bearing_modes.header": "UNLOCALIZED: Movement Modes of the Mechanical Bearing", "create.ponder.bearing_modes.text_1": "UNLOCALIZED: When Stopped, the Bearing will place the structure at the nearest grid-aligned Angle", "create.ponder.bearing_modes.text_2": "UNLOCALIZED: It can be configured never to revert to solid blocks, or only near the angle it started at", @@ -1902,6 +1913,12 @@ "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.blaze_burner.header": "UNLOCALIZED: Feeding Blaze Burners", + "create.ponder.blaze_burner.text_1": "UNLOCALIZED: Blaze Burners can provide Heat to Items processed in a Basin", + "create.ponder.blaze_burner.text_2": "UNLOCALIZED: For this, the Blaze has to be fed with flammable items", + "create.ponder.blaze_burner.text_3": "UNLOCALIZED: With a Blaze Cake, the Burner can reach an even stronger level of heat", + "create.ponder.blaze_burner.text_4": "UNLOCALIZED: The feeding process can be automated using Deployers or Mechanical Arms", + "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.", @@ -1968,6 +1985,12 @@ "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.crushing_wheels.header": "UNLOCALIZED: Processing Items with Crushing Wheels", + "create.ponder.crushing_wheels.text_1": "UNLOCALIZED: A pair of Crushing Wheels can grind items very effectively", + "create.ponder.crushing_wheels.text_2": "UNLOCALIZED: Their Rotational Input has to make them spin into each other", + "create.ponder.crushing_wheels.text_3": "UNLOCALIZED: Items thrown or inserted into the top will get processed", + "create.ponder.crushing_wheels.text_4": "UNLOCALIZED: Items can be inserted and picked up through automated means as well", + "create.ponder.deployer.header": "UNLOCALIZED: Using the Deployer", "create.ponder.deployer.text_1": "UNLOCALIZED: Given Rotational Force, a Deployer can imitate player interactions", "create.ponder.deployer.text_10": "UNLOCALIZED: Right-click the front to give it an Item to use", @@ -1999,6 +2022,13 @@ "create.ponder.deployer_redstone.text_2": "UNLOCALIZED: Before stopping, the Deployer will finish any started cycles", "create.ponder.deployer_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.empty_blaze_burner.header": "UNLOCALIZED: Using Empty Blaze Burners", + "create.ponder.empty_blaze_burner.text_1": "UNLOCALIZED: Right-click a Blaze with the empty burner to capture it", + "create.ponder.empty_blaze_burner.text_2": "UNLOCALIZED: Alternatively, Blazes can be collected from their Spawners directly", + "create.ponder.empty_blaze_burner.text_3": "UNLOCALIZED: You now have an ideal heat source for various machines", + "create.ponder.empty_blaze_burner.text_4": "UNLOCALIZED: For Aesthetic purposes, Empty Blaze Burners can also be lit using Flint and Steel", + "create.ponder.empty_blaze_burner.text_5": "UNLOCALIZED: However, these are not suitable for industrial heating", + "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", @@ -2125,6 +2155,12 @@ "create.ponder.mechanical_harvester.text_1": "UNLOCALIZED: Whenever Harvesters are moved as part of an animated Contraption...", "create.ponder.mechanical_harvester.text_2": "UNLOCALIZED: They will harvest and reset any mature crops on their way", + "create.ponder.mechanical_mixer.header": "UNLOCALIZED: Processing Items with the Mechanical Mixer", + "create.ponder.mechanical_mixer.text_1": "UNLOCALIZED: With a Mixer and Basin, some Crafting Recipes can be automated", + "create.ponder.mechanical_mixer.text_2": "UNLOCALIZED: Available recipes include any Shapeless Crafting Recipe, plus a couple extra ones", + "create.ponder.mechanical_mixer.text_3": "UNLOCALIZED: Some of those recipes may require the heat of a Blaze Burner", + "create.ponder.mechanical_mixer.text_4": "UNLOCALIZED: The filter slot can be used in case two recipes are conflicting.", + "create.ponder.mechanical_piston.header": "UNLOCALIZED: Moving Structures using Mechanical Pistons", "create.ponder.mechanical_piston.text_1": "UNLOCALIZED: Mechanical Pistons can move blocks in front of them", "create.ponder.mechanical_piston.text_2": "UNLOCALIZED: Speed and direction of movement depend on the Rotational Input", @@ -2140,6 +2176,18 @@ "create.ponder.mechanical_plough.text_3": "UNLOCALIZED: Additionally, ploughs can create farmland", "create.ponder.mechanical_plough.text_4": "UNLOCALIZED: ...they can also launch entities without hurting them", + "create.ponder.mechanical_press.header": "UNLOCALIZED: Processing Items with the Mechanical Press", + "create.ponder.mechanical_press.text_1": "UNLOCALIZED: The Mechanical Press can process items provided beneath it", + "create.ponder.mechanical_press.text_2": "UNLOCALIZED: The Input items can be dropped or placed on a Depot under the Press", + "create.ponder.mechanical_press.text_3": "UNLOCALIZED: When items are provided on a belt...", + "create.ponder.mechanical_press.text_4": "UNLOCALIZED: The Press will hold and process them automatically", + + "create.ponder.mechanical_press_compacting.header": "UNLOCALIZED: Compacting items with the Mechanical Press", + "create.ponder.mechanical_press_compacting.text_1": "UNLOCALIZED: Pressing items held in a Basin will cause them to be Compacted", + "create.ponder.mechanical_press_compacting.text_2": "UNLOCALIZED: Compacting includes any filled 2x2 or 3x3 Crafting Recipe, plus a couple extra ones", + "create.ponder.mechanical_press_compacting.text_3": "UNLOCALIZED: Some of those recipes may require the heat of a Blaze Burner", + "create.ponder.mechanical_press_compacting.text_4": "UNLOCALIZED: The filter slot can be used in case two recipes are conflicting.", + "create.ponder.mechanical_saw_breaker.header": "UNLOCALIZED: Cutting Trees with the Mechanical Saw", "create.ponder.mechanical_saw_breaker.text_1": "UNLOCALIZED: When given Rotational Force, a Mechanical Saw will cut trees directly in front of it", "create.ponder.mechanical_saw_breaker.text_2": "UNLOCALIZED: In order to cut the tree fully, the Saw has to break the last block connecting it to the ground", @@ -2155,6 +2203,13 @@ "create.ponder.mechanical_saw_processing.text_4": "UNLOCALIZED: When an ingredient has multiple possible outcomes, the filter slot can specify it", "create.ponder.mechanical_saw_processing.text_5": "UNLOCALIZED: Without filter, the Saw would cycle through all outcomes instead", + "create.ponder.millstone.header": "UNLOCALIZED: Processing Items in the Millstone", + "create.ponder.millstone.text_1": "UNLOCALIZED: Millstones process items by grinding them", + "create.ponder.millstone.text_2": "UNLOCALIZED: They can be powered from the side using cogwheels", + "create.ponder.millstone.text_3": "UNLOCALIZED: Throw or Insert items at the top", + "create.ponder.millstone.text_4": "UNLOCALIZED: After some time, the result can be obtained via Right-click", + "create.ponder.millstone.text_5": "UNLOCALIZED: The outputs can also be extracted by automation", + "create.ponder.piston_pole.header": "UNLOCALIZED: Piston Extension Poles", "create.ponder.piston_pole.text_1": "UNLOCALIZED: Without attached Poles, a Mechanical Piston cannot move", "create.ponder.piston_pole.text_2": "UNLOCALIZED: The Length of pole added at its back determines the Extension Range", @@ -2240,6 +2295,11 @@ "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.speedometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Speedometer", + "create.ponder.speedometer.text_1": "UNLOCALIZED: The Speedometer displays the current Speed of the attached components", + "create.ponder.speedometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", + "create.ponder.speedometer.text_3": "UNLOCALIZED: Comparators can emit analog Restone Signals relative to the Speedometer's measurements", + "create.ponder.stabilized_bearings.header": "UNLOCALIZED: Stabilized Contraptions", "create.ponder.stabilized_bearings.text_1": "UNLOCALIZED: Whenever Mechanical Bearings are themselves part of a moving Structure..", "create.ponder.stabilized_bearings.text_2": "UNLOCALIZED: ..they will attempt to keep themselves upright", @@ -2252,6 +2312,11 @@ "create.ponder.sticker.text_3": "UNLOCALIZED: If it is now moved in a contraption, the block will move with it", "create.ponder.sticker.text_4": "UNLOCALIZED: Toggled once again, the block is no longer attached", + "create.ponder.stressometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Stressometer", + "create.ponder.stressometer.text_1": "UNLOCALIZED: The Stressometer displays the current Stress Capacity of the attached kinetic network", + "create.ponder.stressometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", + "create.ponder.stressometer.text_3": "UNLOCALIZED: Comparators can emit analog Restone Signals relative to the Stressometer's measurements", + "create.ponder.super_glue.header": "UNLOCALIZED: Attaching blocks using Super Glue", "create.ponder.super_glue.text_1": "UNLOCALIZED: Super Glue can be used between any two blocks", "create.ponder.super_glue.text_2": "UNLOCALIZED: The attached blocks will move together when assembled into a Contraption", 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 f3dbea0b4..402bc2bca 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: 1569", + "_": "Missing Localizations: 1624", "_": "->------------------------] Game Elements [------------------------<-", @@ -1874,6 +1874,17 @@ "create.ponder.analog_lever.text_2": "UNLOCALIZED: Right-click to increase its analog power output", "create.ponder.analog_lever.text_3": "UNLOCALIZED: Right-click while Sneaking to decrease the power output again", + "create.ponder.basin.header": "UNLOCALIZED: Processing Items in the Basin", + "create.ponder.basin.text_1": "UNLOCALIZED: A Basin can hold Items and Fluids for Processing", + "create.ponder.basin.text_2": "UNLOCALIZED: After a processing step, basins try to output below to the side of them", + "create.ponder.basin.text_3": "UNLOCALIZED: When a valid component is present, the Basin will show an output faucet", + "create.ponder.basin.text_4": "UNLOCALIZED: A number of options are applicable here", + "create.ponder.basin.text_5": "UNLOCALIZED: Outputs will be caught by the inventory below", + "create.ponder.basin.text_6": "UNLOCALIZED: Without output faucet, the Basin will retain items created in its processing", + "create.ponder.basin.text_7": "UNLOCALIZED: This can be useful if outputs should be re-used as ingredients", + "create.ponder.basin.text_8": "UNLOCALIZED: Desired outputs will then have to be extracted from the basin", + "create.ponder.basin.text_9": "UNLOCALIZED: A Filter might be necessary to avoid pulling out un-processed items", + "create.ponder.bearing_modes.header": "UNLOCALIZED: Movement Modes of the Mechanical Bearing", "create.ponder.bearing_modes.text_1": "UNLOCALIZED: When Stopped, the Bearing will place the structure at the nearest grid-aligned Angle", "create.ponder.bearing_modes.text_2": "UNLOCALIZED: It can be configured never to revert to solid blocks, or only near the angle it started at", @@ -1902,6 +1913,12 @@ "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.blaze_burner.header": "UNLOCALIZED: Feeding Blaze Burners", + "create.ponder.blaze_burner.text_1": "UNLOCALIZED: Blaze Burners can provide Heat to Items processed in a Basin", + "create.ponder.blaze_burner.text_2": "UNLOCALIZED: For this, the Blaze has to be fed with flammable items", + "create.ponder.blaze_burner.text_3": "UNLOCALIZED: With a Blaze Cake, the Burner can reach an even stronger level of heat", + "create.ponder.blaze_burner.text_4": "UNLOCALIZED: The feeding process can be automated using Deployers or Mechanical Arms", + "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.", @@ -1968,6 +1985,12 @@ "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.crushing_wheels.header": "UNLOCALIZED: Processing Items with Crushing Wheels", + "create.ponder.crushing_wheels.text_1": "UNLOCALIZED: A pair of Crushing Wheels can grind items very effectively", + "create.ponder.crushing_wheels.text_2": "UNLOCALIZED: Their Rotational Input has to make them spin into each other", + "create.ponder.crushing_wheels.text_3": "UNLOCALIZED: Items thrown or inserted into the top will get processed", + "create.ponder.crushing_wheels.text_4": "UNLOCALIZED: Items can be inserted and picked up through automated means as well", + "create.ponder.deployer.header": "UNLOCALIZED: Using the Deployer", "create.ponder.deployer.text_1": "UNLOCALIZED: Given Rotational Force, a Deployer can imitate player interactions", "create.ponder.deployer.text_10": "UNLOCALIZED: Right-click the front to give it an Item to use", @@ -1999,6 +2022,13 @@ "create.ponder.deployer_redstone.text_2": "UNLOCALIZED: Before stopping, the Deployer will finish any started cycles", "create.ponder.deployer_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.empty_blaze_burner.header": "UNLOCALIZED: Using Empty Blaze Burners", + "create.ponder.empty_blaze_burner.text_1": "UNLOCALIZED: Right-click a Blaze with the empty burner to capture it", + "create.ponder.empty_blaze_burner.text_2": "UNLOCALIZED: Alternatively, Blazes can be collected from their Spawners directly", + "create.ponder.empty_blaze_burner.text_3": "UNLOCALIZED: You now have an ideal heat source for various machines", + "create.ponder.empty_blaze_burner.text_4": "UNLOCALIZED: For Aesthetic purposes, Empty Blaze Burners can also be lit using Flint and Steel", + "create.ponder.empty_blaze_burner.text_5": "UNLOCALIZED: However, these are not suitable for industrial heating", + "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", @@ -2125,6 +2155,12 @@ "create.ponder.mechanical_harvester.text_1": "UNLOCALIZED: Whenever Harvesters are moved as part of an animated Contraption...", "create.ponder.mechanical_harvester.text_2": "UNLOCALIZED: They will harvest and reset any mature crops on their way", + "create.ponder.mechanical_mixer.header": "UNLOCALIZED: Processing Items with the Mechanical Mixer", + "create.ponder.mechanical_mixer.text_1": "UNLOCALIZED: With a Mixer and Basin, some Crafting Recipes can be automated", + "create.ponder.mechanical_mixer.text_2": "UNLOCALIZED: Available recipes include any Shapeless Crafting Recipe, plus a couple extra ones", + "create.ponder.mechanical_mixer.text_3": "UNLOCALIZED: Some of those recipes may require the heat of a Blaze Burner", + "create.ponder.mechanical_mixer.text_4": "UNLOCALIZED: The filter slot can be used in case two recipes are conflicting.", + "create.ponder.mechanical_piston.header": "UNLOCALIZED: Moving Structures using Mechanical Pistons", "create.ponder.mechanical_piston.text_1": "UNLOCALIZED: Mechanical Pistons can move blocks in front of them", "create.ponder.mechanical_piston.text_2": "UNLOCALIZED: Speed and direction of movement depend on the Rotational Input", @@ -2140,6 +2176,18 @@ "create.ponder.mechanical_plough.text_3": "UNLOCALIZED: Additionally, ploughs can create farmland", "create.ponder.mechanical_plough.text_4": "UNLOCALIZED: ...they can also launch entities without hurting them", + "create.ponder.mechanical_press.header": "UNLOCALIZED: Processing Items with the Mechanical Press", + "create.ponder.mechanical_press.text_1": "UNLOCALIZED: The Mechanical Press can process items provided beneath it", + "create.ponder.mechanical_press.text_2": "UNLOCALIZED: The Input items can be dropped or placed on a Depot under the Press", + "create.ponder.mechanical_press.text_3": "UNLOCALIZED: When items are provided on a belt...", + "create.ponder.mechanical_press.text_4": "UNLOCALIZED: The Press will hold and process them automatically", + + "create.ponder.mechanical_press_compacting.header": "UNLOCALIZED: Compacting items with the Mechanical Press", + "create.ponder.mechanical_press_compacting.text_1": "UNLOCALIZED: Pressing items held in a Basin will cause them to be Compacted", + "create.ponder.mechanical_press_compacting.text_2": "UNLOCALIZED: Compacting includes any filled 2x2 or 3x3 Crafting Recipe, plus a couple extra ones", + "create.ponder.mechanical_press_compacting.text_3": "UNLOCALIZED: Some of those recipes may require the heat of a Blaze Burner", + "create.ponder.mechanical_press_compacting.text_4": "UNLOCALIZED: The filter slot can be used in case two recipes are conflicting.", + "create.ponder.mechanical_saw_breaker.header": "UNLOCALIZED: Cutting Trees with the Mechanical Saw", "create.ponder.mechanical_saw_breaker.text_1": "UNLOCALIZED: When given Rotational Force, a Mechanical Saw will cut trees directly in front of it", "create.ponder.mechanical_saw_breaker.text_2": "UNLOCALIZED: In order to cut the tree fully, the Saw has to break the last block connecting it to the ground", @@ -2155,6 +2203,13 @@ "create.ponder.mechanical_saw_processing.text_4": "UNLOCALIZED: When an ingredient has multiple possible outcomes, the filter slot can specify it", "create.ponder.mechanical_saw_processing.text_5": "UNLOCALIZED: Without filter, the Saw would cycle through all outcomes instead", + "create.ponder.millstone.header": "UNLOCALIZED: Processing Items in the Millstone", + "create.ponder.millstone.text_1": "UNLOCALIZED: Millstones process items by grinding them", + "create.ponder.millstone.text_2": "UNLOCALIZED: They can be powered from the side using cogwheels", + "create.ponder.millstone.text_3": "UNLOCALIZED: Throw or Insert items at the top", + "create.ponder.millstone.text_4": "UNLOCALIZED: After some time, the result can be obtained via Right-click", + "create.ponder.millstone.text_5": "UNLOCALIZED: The outputs can also be extracted by automation", + "create.ponder.piston_pole.header": "UNLOCALIZED: Piston Extension Poles", "create.ponder.piston_pole.text_1": "UNLOCALIZED: Without attached Poles, a Mechanical Piston cannot move", "create.ponder.piston_pole.text_2": "UNLOCALIZED: The Length of pole added at its back determines the Extension Range", @@ -2240,6 +2295,11 @@ "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.speedometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Speedometer", + "create.ponder.speedometer.text_1": "UNLOCALIZED: The Speedometer displays the current Speed of the attached components", + "create.ponder.speedometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", + "create.ponder.speedometer.text_3": "UNLOCALIZED: Comparators can emit analog Restone Signals relative to the Speedometer's measurements", + "create.ponder.stabilized_bearings.header": "UNLOCALIZED: Stabilized Contraptions", "create.ponder.stabilized_bearings.text_1": "UNLOCALIZED: Whenever Mechanical Bearings are themselves part of a moving Structure..", "create.ponder.stabilized_bearings.text_2": "UNLOCALIZED: ..they will attempt to keep themselves upright", @@ -2252,6 +2312,11 @@ "create.ponder.sticker.text_3": "UNLOCALIZED: If it is now moved in a contraption, the block will move with it", "create.ponder.sticker.text_4": "UNLOCALIZED: Toggled once again, the block is no longer attached", + "create.ponder.stressometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Stressometer", + "create.ponder.stressometer.text_1": "UNLOCALIZED: The Stressometer displays the current Stress Capacity of the attached kinetic network", + "create.ponder.stressometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", + "create.ponder.stressometer.text_3": "UNLOCALIZED: Comparators can emit analog Restone Signals relative to the Stressometer's measurements", + "create.ponder.super_glue.header": "UNLOCALIZED: Attaching blocks using Super Glue", "create.ponder.super_glue.text_1": "UNLOCALIZED: Super Glue can be used between any two blocks", "create.ponder.super_glue.text_2": "UNLOCALIZED: The attached blocks will move together when assembled into a Contraption", 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 659fc213b..92c791d67 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: 1635", + "_": "Missing Localizations: 1690", "_": "->------------------------] Game Elements [------------------------<-", @@ -1874,6 +1874,17 @@ "create.ponder.analog_lever.text_2": "UNLOCALIZED: Right-click to increase its analog power output", "create.ponder.analog_lever.text_3": "UNLOCALIZED: Right-click while Sneaking to decrease the power output again", + "create.ponder.basin.header": "UNLOCALIZED: Processing Items in the Basin", + "create.ponder.basin.text_1": "UNLOCALIZED: A Basin can hold Items and Fluids for Processing", + "create.ponder.basin.text_2": "UNLOCALIZED: After a processing step, basins try to output below to the side of them", + "create.ponder.basin.text_3": "UNLOCALIZED: When a valid component is present, the Basin will show an output faucet", + "create.ponder.basin.text_4": "UNLOCALIZED: A number of options are applicable here", + "create.ponder.basin.text_5": "UNLOCALIZED: Outputs will be caught by the inventory below", + "create.ponder.basin.text_6": "UNLOCALIZED: Without output faucet, the Basin will retain items created in its processing", + "create.ponder.basin.text_7": "UNLOCALIZED: This can be useful if outputs should be re-used as ingredients", + "create.ponder.basin.text_8": "UNLOCALIZED: Desired outputs will then have to be extracted from the basin", + "create.ponder.basin.text_9": "UNLOCALIZED: A Filter might be necessary to avoid pulling out un-processed items", + "create.ponder.bearing_modes.header": "UNLOCALIZED: Movement Modes of the Mechanical Bearing", "create.ponder.bearing_modes.text_1": "UNLOCALIZED: When Stopped, the Bearing will place the structure at the nearest grid-aligned Angle", "create.ponder.bearing_modes.text_2": "UNLOCALIZED: It can be configured never to revert to solid blocks, or only near the angle it started at", @@ -1902,6 +1913,12 @@ "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.blaze_burner.header": "UNLOCALIZED: Feeding Blaze Burners", + "create.ponder.blaze_burner.text_1": "UNLOCALIZED: Blaze Burners can provide Heat to Items processed in a Basin", + "create.ponder.blaze_burner.text_2": "UNLOCALIZED: For this, the Blaze has to be fed with flammable items", + "create.ponder.blaze_burner.text_3": "UNLOCALIZED: With a Blaze Cake, the Burner can reach an even stronger level of heat", + "create.ponder.blaze_burner.text_4": "UNLOCALIZED: The feeding process can be automated using Deployers or Mechanical Arms", + "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.", @@ -1968,6 +1985,12 @@ "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.crushing_wheels.header": "UNLOCALIZED: Processing Items with Crushing Wheels", + "create.ponder.crushing_wheels.text_1": "UNLOCALIZED: A pair of Crushing Wheels can grind items very effectively", + "create.ponder.crushing_wheels.text_2": "UNLOCALIZED: Their Rotational Input has to make them spin into each other", + "create.ponder.crushing_wheels.text_3": "UNLOCALIZED: Items thrown or inserted into the top will get processed", + "create.ponder.crushing_wheels.text_4": "UNLOCALIZED: Items can be inserted and picked up through automated means as well", + "create.ponder.deployer.header": "UNLOCALIZED: Using the Deployer", "create.ponder.deployer.text_1": "UNLOCALIZED: Given Rotational Force, a Deployer can imitate player interactions", "create.ponder.deployer.text_10": "UNLOCALIZED: Right-click the front to give it an Item to use", @@ -1999,6 +2022,13 @@ "create.ponder.deployer_redstone.text_2": "UNLOCALIZED: Before stopping, the Deployer will finish any started cycles", "create.ponder.deployer_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.empty_blaze_burner.header": "UNLOCALIZED: Using Empty Blaze Burners", + "create.ponder.empty_blaze_burner.text_1": "UNLOCALIZED: Right-click a Blaze with the empty burner to capture it", + "create.ponder.empty_blaze_burner.text_2": "UNLOCALIZED: Alternatively, Blazes can be collected from their Spawners directly", + "create.ponder.empty_blaze_burner.text_3": "UNLOCALIZED: You now have an ideal heat source for various machines", + "create.ponder.empty_blaze_burner.text_4": "UNLOCALIZED: For Aesthetic purposes, Empty Blaze Burners can also be lit using Flint and Steel", + "create.ponder.empty_blaze_burner.text_5": "UNLOCALIZED: However, these are not suitable for industrial heating", + "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", @@ -2125,6 +2155,12 @@ "create.ponder.mechanical_harvester.text_1": "UNLOCALIZED: Whenever Harvesters are moved as part of an animated Contraption...", "create.ponder.mechanical_harvester.text_2": "UNLOCALIZED: They will harvest and reset any mature crops on their way", + "create.ponder.mechanical_mixer.header": "UNLOCALIZED: Processing Items with the Mechanical Mixer", + "create.ponder.mechanical_mixer.text_1": "UNLOCALIZED: With a Mixer and Basin, some Crafting Recipes can be automated", + "create.ponder.mechanical_mixer.text_2": "UNLOCALIZED: Available recipes include any Shapeless Crafting Recipe, plus a couple extra ones", + "create.ponder.mechanical_mixer.text_3": "UNLOCALIZED: Some of those recipes may require the heat of a Blaze Burner", + "create.ponder.mechanical_mixer.text_4": "UNLOCALIZED: The filter slot can be used in case two recipes are conflicting.", + "create.ponder.mechanical_piston.header": "UNLOCALIZED: Moving Structures using Mechanical Pistons", "create.ponder.mechanical_piston.text_1": "UNLOCALIZED: Mechanical Pistons can move blocks in front of them", "create.ponder.mechanical_piston.text_2": "UNLOCALIZED: Speed and direction of movement depend on the Rotational Input", @@ -2140,6 +2176,18 @@ "create.ponder.mechanical_plough.text_3": "UNLOCALIZED: Additionally, ploughs can create farmland", "create.ponder.mechanical_plough.text_4": "UNLOCALIZED: ...they can also launch entities without hurting them", + "create.ponder.mechanical_press.header": "UNLOCALIZED: Processing Items with the Mechanical Press", + "create.ponder.mechanical_press.text_1": "UNLOCALIZED: The Mechanical Press can process items provided beneath it", + "create.ponder.mechanical_press.text_2": "UNLOCALIZED: The Input items can be dropped or placed on a Depot under the Press", + "create.ponder.mechanical_press.text_3": "UNLOCALIZED: When items are provided on a belt...", + "create.ponder.mechanical_press.text_4": "UNLOCALIZED: The Press will hold and process them automatically", + + "create.ponder.mechanical_press_compacting.header": "UNLOCALIZED: Compacting items with the Mechanical Press", + "create.ponder.mechanical_press_compacting.text_1": "UNLOCALIZED: Pressing items held in a Basin will cause them to be Compacted", + "create.ponder.mechanical_press_compacting.text_2": "UNLOCALIZED: Compacting includes any filled 2x2 or 3x3 Crafting Recipe, plus a couple extra ones", + "create.ponder.mechanical_press_compacting.text_3": "UNLOCALIZED: Some of those recipes may require the heat of a Blaze Burner", + "create.ponder.mechanical_press_compacting.text_4": "UNLOCALIZED: The filter slot can be used in case two recipes are conflicting.", + "create.ponder.mechanical_saw_breaker.header": "UNLOCALIZED: Cutting Trees with the Mechanical Saw", "create.ponder.mechanical_saw_breaker.text_1": "UNLOCALIZED: When given Rotational Force, a Mechanical Saw will cut trees directly in front of it", "create.ponder.mechanical_saw_breaker.text_2": "UNLOCALIZED: In order to cut the tree fully, the Saw has to break the last block connecting it to the ground", @@ -2155,6 +2203,13 @@ "create.ponder.mechanical_saw_processing.text_4": "UNLOCALIZED: When an ingredient has multiple possible outcomes, the filter slot can specify it", "create.ponder.mechanical_saw_processing.text_5": "UNLOCALIZED: Without filter, the Saw would cycle through all outcomes instead", + "create.ponder.millstone.header": "UNLOCALIZED: Processing Items in the Millstone", + "create.ponder.millstone.text_1": "UNLOCALIZED: Millstones process items by grinding them", + "create.ponder.millstone.text_2": "UNLOCALIZED: They can be powered from the side using cogwheels", + "create.ponder.millstone.text_3": "UNLOCALIZED: Throw or Insert items at the top", + "create.ponder.millstone.text_4": "UNLOCALIZED: After some time, the result can be obtained via Right-click", + "create.ponder.millstone.text_5": "UNLOCALIZED: The outputs can also be extracted by automation", + "create.ponder.piston_pole.header": "UNLOCALIZED: Piston Extension Poles", "create.ponder.piston_pole.text_1": "UNLOCALIZED: Without attached Poles, a Mechanical Piston cannot move", "create.ponder.piston_pole.text_2": "UNLOCALIZED: The Length of pole added at its back determines the Extension Range", @@ -2240,6 +2295,11 @@ "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.speedometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Speedometer", + "create.ponder.speedometer.text_1": "UNLOCALIZED: The Speedometer displays the current Speed of the attached components", + "create.ponder.speedometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", + "create.ponder.speedometer.text_3": "UNLOCALIZED: Comparators can emit analog Restone Signals relative to the Speedometer's measurements", + "create.ponder.stabilized_bearings.header": "UNLOCALIZED: Stabilized Contraptions", "create.ponder.stabilized_bearings.text_1": "UNLOCALIZED: Whenever Mechanical Bearings are themselves part of a moving Structure..", "create.ponder.stabilized_bearings.text_2": "UNLOCALIZED: ..they will attempt to keep themselves upright", @@ -2252,6 +2312,11 @@ "create.ponder.sticker.text_3": "UNLOCALIZED: If it is now moved in a contraption, the block will move with it", "create.ponder.sticker.text_4": "UNLOCALIZED: Toggled once again, the block is no longer attached", + "create.ponder.stressometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Stressometer", + "create.ponder.stressometer.text_1": "UNLOCALIZED: The Stressometer displays the current Stress Capacity of the attached kinetic network", + "create.ponder.stressometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", + "create.ponder.stressometer.text_3": "UNLOCALIZED: Comparators can emit analog Restone Signals relative to the Stressometer's measurements", + "create.ponder.super_glue.header": "UNLOCALIZED: Attaching blocks using Super Glue", "create.ponder.super_glue.text_1": "UNLOCALIZED: Super Glue can be used between any two blocks", "create.ponder.super_glue.text_2": "UNLOCALIZED: The attached blocks will move together when assembled into a Contraption", 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 bbfb96413..660e3c42c 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: 421", + "_": "Missing Localizations: 476", "_": "->------------------------] Game Elements [------------------------<-", @@ -1874,6 +1874,17 @@ "create.ponder.analog_lever.text_2": "UNLOCALIZED: Right-click to increase its analog power output", "create.ponder.analog_lever.text_3": "UNLOCALIZED: Right-click while Sneaking to decrease the power output again", + "create.ponder.basin.header": "UNLOCALIZED: Processing Items in the Basin", + "create.ponder.basin.text_1": "UNLOCALIZED: A Basin can hold Items and Fluids for Processing", + "create.ponder.basin.text_2": "UNLOCALIZED: After a processing step, basins try to output below to the side of them", + "create.ponder.basin.text_3": "UNLOCALIZED: When a valid component is present, the Basin will show an output faucet", + "create.ponder.basin.text_4": "UNLOCALIZED: A number of options are applicable here", + "create.ponder.basin.text_5": "UNLOCALIZED: Outputs will be caught by the inventory below", + "create.ponder.basin.text_6": "UNLOCALIZED: Without output faucet, the Basin will retain items created in its processing", + "create.ponder.basin.text_7": "UNLOCALIZED: This can be useful if outputs should be re-used as ingredients", + "create.ponder.basin.text_8": "UNLOCALIZED: Desired outputs will then have to be extracted from the basin", + "create.ponder.basin.text_9": "UNLOCALIZED: A Filter might be necessary to avoid pulling out un-processed items", + "create.ponder.bearing_modes.header": "UNLOCALIZED: Movement Modes of the Mechanical Bearing", "create.ponder.bearing_modes.text_1": "UNLOCALIZED: When Stopped, the Bearing will place the structure at the nearest grid-aligned Angle", "create.ponder.bearing_modes.text_2": "UNLOCALIZED: It can be configured never to revert to solid blocks, or only near the angle it started at", @@ -1902,6 +1913,12 @@ "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.blaze_burner.header": "UNLOCALIZED: Feeding Blaze Burners", + "create.ponder.blaze_burner.text_1": "UNLOCALIZED: Blaze Burners can provide Heat to Items processed in a Basin", + "create.ponder.blaze_burner.text_2": "UNLOCALIZED: For this, the Blaze has to be fed with flammable items", + "create.ponder.blaze_burner.text_3": "UNLOCALIZED: With a Blaze Cake, the Burner can reach an even stronger level of heat", + "create.ponder.blaze_burner.text_4": "UNLOCALIZED: The feeding process can be automated using Deployers or Mechanical Arms", + "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.", @@ -1968,6 +1985,12 @@ "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.crushing_wheels.header": "UNLOCALIZED: Processing Items with Crushing Wheels", + "create.ponder.crushing_wheels.text_1": "UNLOCALIZED: A pair of Crushing Wheels can grind items very effectively", + "create.ponder.crushing_wheels.text_2": "UNLOCALIZED: Their Rotational Input has to make them spin into each other", + "create.ponder.crushing_wheels.text_3": "UNLOCALIZED: Items thrown or inserted into the top will get processed", + "create.ponder.crushing_wheels.text_4": "UNLOCALIZED: Items can be inserted and picked up through automated means as well", + "create.ponder.deployer.header": "UNLOCALIZED: Using the Deployer", "create.ponder.deployer.text_1": "UNLOCALIZED: Given Rotational Force, a Deployer can imitate player interactions", "create.ponder.deployer.text_10": "UNLOCALIZED: Right-click the front to give it an Item to use", @@ -1999,6 +2022,13 @@ "create.ponder.deployer_redstone.text_2": "UNLOCALIZED: Before stopping, the Deployer will finish any started cycles", "create.ponder.deployer_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.empty_blaze_burner.header": "UNLOCALIZED: Using Empty Blaze Burners", + "create.ponder.empty_blaze_burner.text_1": "UNLOCALIZED: Right-click a Blaze with the empty burner to capture it", + "create.ponder.empty_blaze_burner.text_2": "UNLOCALIZED: Alternatively, Blazes can be collected from their Spawners directly", + "create.ponder.empty_blaze_burner.text_3": "UNLOCALIZED: You now have an ideal heat source for various machines", + "create.ponder.empty_blaze_burner.text_4": "UNLOCALIZED: For Aesthetic purposes, Empty Blaze Burners can also be lit using Flint and Steel", + "create.ponder.empty_blaze_burner.text_5": "UNLOCALIZED: However, these are not suitable for industrial heating", + "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", @@ -2125,6 +2155,12 @@ "create.ponder.mechanical_harvester.text_1": "UNLOCALIZED: Whenever Harvesters are moved as part of an animated Contraption...", "create.ponder.mechanical_harvester.text_2": "UNLOCALIZED: They will harvest and reset any mature crops on their way", + "create.ponder.mechanical_mixer.header": "UNLOCALIZED: Processing Items with the Mechanical Mixer", + "create.ponder.mechanical_mixer.text_1": "UNLOCALIZED: With a Mixer and Basin, some Crafting Recipes can be automated", + "create.ponder.mechanical_mixer.text_2": "UNLOCALIZED: Available recipes include any Shapeless Crafting Recipe, plus a couple extra ones", + "create.ponder.mechanical_mixer.text_3": "UNLOCALIZED: Some of those recipes may require the heat of a Blaze Burner", + "create.ponder.mechanical_mixer.text_4": "UNLOCALIZED: The filter slot can be used in case two recipes are conflicting.", + "create.ponder.mechanical_piston.header": "UNLOCALIZED: Moving Structures using Mechanical Pistons", "create.ponder.mechanical_piston.text_1": "UNLOCALIZED: Mechanical Pistons can move blocks in front of them", "create.ponder.mechanical_piston.text_2": "UNLOCALIZED: Speed and direction of movement depend on the Rotational Input", @@ -2140,6 +2176,18 @@ "create.ponder.mechanical_plough.text_3": "UNLOCALIZED: Additionally, ploughs can create farmland", "create.ponder.mechanical_plough.text_4": "UNLOCALIZED: ...they can also launch entities without hurting them", + "create.ponder.mechanical_press.header": "UNLOCALIZED: Processing Items with the Mechanical Press", + "create.ponder.mechanical_press.text_1": "UNLOCALIZED: The Mechanical Press can process items provided beneath it", + "create.ponder.mechanical_press.text_2": "UNLOCALIZED: The Input items can be dropped or placed on a Depot under the Press", + "create.ponder.mechanical_press.text_3": "UNLOCALIZED: When items are provided on a belt...", + "create.ponder.mechanical_press.text_4": "UNLOCALIZED: The Press will hold and process them automatically", + + "create.ponder.mechanical_press_compacting.header": "UNLOCALIZED: Compacting items with the Mechanical Press", + "create.ponder.mechanical_press_compacting.text_1": "UNLOCALIZED: Pressing items held in a Basin will cause them to be Compacted", + "create.ponder.mechanical_press_compacting.text_2": "UNLOCALIZED: Compacting includes any filled 2x2 or 3x3 Crafting Recipe, plus a couple extra ones", + "create.ponder.mechanical_press_compacting.text_3": "UNLOCALIZED: Some of those recipes may require the heat of a Blaze Burner", + "create.ponder.mechanical_press_compacting.text_4": "UNLOCALIZED: The filter slot can be used in case two recipes are conflicting.", + "create.ponder.mechanical_saw_breaker.header": "UNLOCALIZED: Cutting Trees with the Mechanical Saw", "create.ponder.mechanical_saw_breaker.text_1": "UNLOCALIZED: When given Rotational Force, a Mechanical Saw will cut trees directly in front of it", "create.ponder.mechanical_saw_breaker.text_2": "UNLOCALIZED: In order to cut the tree fully, the Saw has to break the last block connecting it to the ground", @@ -2155,6 +2203,13 @@ "create.ponder.mechanical_saw_processing.text_4": "UNLOCALIZED: When an ingredient has multiple possible outcomes, the filter slot can specify it", "create.ponder.mechanical_saw_processing.text_5": "UNLOCALIZED: Without filter, the Saw would cycle through all outcomes instead", + "create.ponder.millstone.header": "UNLOCALIZED: Processing Items in the Millstone", + "create.ponder.millstone.text_1": "UNLOCALIZED: Millstones process items by grinding them", + "create.ponder.millstone.text_2": "UNLOCALIZED: They can be powered from the side using cogwheels", + "create.ponder.millstone.text_3": "UNLOCALIZED: Throw or Insert items at the top", + "create.ponder.millstone.text_4": "UNLOCALIZED: After some time, the result can be obtained via Right-click", + "create.ponder.millstone.text_5": "UNLOCALIZED: The outputs can also be extracted by automation", + "create.ponder.piston_pole.header": "UNLOCALIZED: Piston Extension Poles", "create.ponder.piston_pole.text_1": "UNLOCALIZED: Without attached Poles, a Mechanical Piston cannot move", "create.ponder.piston_pole.text_2": "UNLOCALIZED: The Length of pole added at its back determines the Extension Range", @@ -2240,6 +2295,11 @@ "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.speedometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Speedometer", + "create.ponder.speedometer.text_1": "UNLOCALIZED: The Speedometer displays the current Speed of the attached components", + "create.ponder.speedometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", + "create.ponder.speedometer.text_3": "UNLOCALIZED: Comparators can emit analog Restone Signals relative to the Speedometer's measurements", + "create.ponder.stabilized_bearings.header": "UNLOCALIZED: Stabilized Contraptions", "create.ponder.stabilized_bearings.text_1": "UNLOCALIZED: Whenever Mechanical Bearings are themselves part of a moving Structure..", "create.ponder.stabilized_bearings.text_2": "UNLOCALIZED: ..they will attempt to keep themselves upright", @@ -2252,6 +2312,11 @@ "create.ponder.sticker.text_3": "UNLOCALIZED: If it is now moved in a contraption, the block will move with it", "create.ponder.sticker.text_4": "UNLOCALIZED: Toggled once again, the block is no longer attached", + "create.ponder.stressometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Stressometer", + "create.ponder.stressometer.text_1": "UNLOCALIZED: The Stressometer displays the current Stress Capacity of the attached kinetic network", + "create.ponder.stressometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", + "create.ponder.stressometer.text_3": "UNLOCALIZED: Comparators can emit analog Restone Signals relative to the Stressometer's measurements", + "create.ponder.super_glue.header": "UNLOCALIZED: Attaching blocks using Super Glue", "create.ponder.super_glue.text_1": "UNLOCALIZED: Super Glue can be used between any two blocks", "create.ponder.super_glue.text_2": "UNLOCALIZED: The attached blocks will move together when assembled into a Contraption", 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 68ae1cb13..7f3b14f8d 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: 419", + "_": "Missing Localizations: 474", "_": "->------------------------] Game Elements [------------------------<-", @@ -1874,6 +1874,17 @@ "create.ponder.analog_lever.text_2": "UNLOCALIZED: Right-click to increase its analog power output", "create.ponder.analog_lever.text_3": "UNLOCALIZED: Right-click while Sneaking to decrease the power output again", + "create.ponder.basin.header": "UNLOCALIZED: Processing Items in the Basin", + "create.ponder.basin.text_1": "UNLOCALIZED: A Basin can hold Items and Fluids for Processing", + "create.ponder.basin.text_2": "UNLOCALIZED: After a processing step, basins try to output below to the side of them", + "create.ponder.basin.text_3": "UNLOCALIZED: When a valid component is present, the Basin will show an output faucet", + "create.ponder.basin.text_4": "UNLOCALIZED: A number of options are applicable here", + "create.ponder.basin.text_5": "UNLOCALIZED: Outputs will be caught by the inventory below", + "create.ponder.basin.text_6": "UNLOCALIZED: Without output faucet, the Basin will retain items created in its processing", + "create.ponder.basin.text_7": "UNLOCALIZED: This can be useful if outputs should be re-used as ingredients", + "create.ponder.basin.text_8": "UNLOCALIZED: Desired outputs will then have to be extracted from the basin", + "create.ponder.basin.text_9": "UNLOCALIZED: A Filter might be necessary to avoid pulling out un-processed items", + "create.ponder.bearing_modes.header": "UNLOCALIZED: Movement Modes of the Mechanical Bearing", "create.ponder.bearing_modes.text_1": "UNLOCALIZED: When Stopped, the Bearing will place the structure at the nearest grid-aligned Angle", "create.ponder.bearing_modes.text_2": "UNLOCALIZED: It can be configured never to revert to solid blocks, or only near the angle it started at", @@ -1902,6 +1913,12 @@ "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.blaze_burner.header": "UNLOCALIZED: Feeding Blaze Burners", + "create.ponder.blaze_burner.text_1": "UNLOCALIZED: Blaze Burners can provide Heat to Items processed in a Basin", + "create.ponder.blaze_burner.text_2": "UNLOCALIZED: For this, the Blaze has to be fed with flammable items", + "create.ponder.blaze_burner.text_3": "UNLOCALIZED: With a Blaze Cake, the Burner can reach an even stronger level of heat", + "create.ponder.blaze_burner.text_4": "UNLOCALIZED: The feeding process can be automated using Deployers or Mechanical Arms", + "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.", @@ -1968,6 +1985,12 @@ "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.crushing_wheels.header": "UNLOCALIZED: Processing Items with Crushing Wheels", + "create.ponder.crushing_wheels.text_1": "UNLOCALIZED: A pair of Crushing Wheels can grind items very effectively", + "create.ponder.crushing_wheels.text_2": "UNLOCALIZED: Their Rotational Input has to make them spin into each other", + "create.ponder.crushing_wheels.text_3": "UNLOCALIZED: Items thrown or inserted into the top will get processed", + "create.ponder.crushing_wheels.text_4": "UNLOCALIZED: Items can be inserted and picked up through automated means as well", + "create.ponder.deployer.header": "UNLOCALIZED: Using the Deployer", "create.ponder.deployer.text_1": "UNLOCALIZED: Given Rotational Force, a Deployer can imitate player interactions", "create.ponder.deployer.text_10": "UNLOCALIZED: Right-click the front to give it an Item to use", @@ -1999,6 +2022,13 @@ "create.ponder.deployer_redstone.text_2": "UNLOCALIZED: Before stopping, the Deployer will finish any started cycles", "create.ponder.deployer_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.empty_blaze_burner.header": "UNLOCALIZED: Using Empty Blaze Burners", + "create.ponder.empty_blaze_burner.text_1": "UNLOCALIZED: Right-click a Blaze with the empty burner to capture it", + "create.ponder.empty_blaze_burner.text_2": "UNLOCALIZED: Alternatively, Blazes can be collected from their Spawners directly", + "create.ponder.empty_blaze_burner.text_3": "UNLOCALIZED: You now have an ideal heat source for various machines", + "create.ponder.empty_blaze_burner.text_4": "UNLOCALIZED: For Aesthetic purposes, Empty Blaze Burners can also be lit using Flint and Steel", + "create.ponder.empty_blaze_burner.text_5": "UNLOCALIZED: However, these are not suitable for industrial heating", + "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", @@ -2125,6 +2155,12 @@ "create.ponder.mechanical_harvester.text_1": "UNLOCALIZED: Whenever Harvesters are moved as part of an animated Contraption...", "create.ponder.mechanical_harvester.text_2": "UNLOCALIZED: They will harvest and reset any mature crops on their way", + "create.ponder.mechanical_mixer.header": "UNLOCALIZED: Processing Items with the Mechanical Mixer", + "create.ponder.mechanical_mixer.text_1": "UNLOCALIZED: With a Mixer and Basin, some Crafting Recipes can be automated", + "create.ponder.mechanical_mixer.text_2": "UNLOCALIZED: Available recipes include any Shapeless Crafting Recipe, plus a couple extra ones", + "create.ponder.mechanical_mixer.text_3": "UNLOCALIZED: Some of those recipes may require the heat of a Blaze Burner", + "create.ponder.mechanical_mixer.text_4": "UNLOCALIZED: The filter slot can be used in case two recipes are conflicting.", + "create.ponder.mechanical_piston.header": "UNLOCALIZED: Moving Structures using Mechanical Pistons", "create.ponder.mechanical_piston.text_1": "UNLOCALIZED: Mechanical Pistons can move blocks in front of them", "create.ponder.mechanical_piston.text_2": "UNLOCALIZED: Speed and direction of movement depend on the Rotational Input", @@ -2140,6 +2176,18 @@ "create.ponder.mechanical_plough.text_3": "UNLOCALIZED: Additionally, ploughs can create farmland", "create.ponder.mechanical_plough.text_4": "UNLOCALIZED: ...they can also launch entities without hurting them", + "create.ponder.mechanical_press.header": "UNLOCALIZED: Processing Items with the Mechanical Press", + "create.ponder.mechanical_press.text_1": "UNLOCALIZED: The Mechanical Press can process items provided beneath it", + "create.ponder.mechanical_press.text_2": "UNLOCALIZED: The Input items can be dropped or placed on a Depot under the Press", + "create.ponder.mechanical_press.text_3": "UNLOCALIZED: When items are provided on a belt...", + "create.ponder.mechanical_press.text_4": "UNLOCALIZED: The Press will hold and process them automatically", + + "create.ponder.mechanical_press_compacting.header": "UNLOCALIZED: Compacting items with the Mechanical Press", + "create.ponder.mechanical_press_compacting.text_1": "UNLOCALIZED: Pressing items held in a Basin will cause them to be Compacted", + "create.ponder.mechanical_press_compacting.text_2": "UNLOCALIZED: Compacting includes any filled 2x2 or 3x3 Crafting Recipe, plus a couple extra ones", + "create.ponder.mechanical_press_compacting.text_3": "UNLOCALIZED: Some of those recipes may require the heat of a Blaze Burner", + "create.ponder.mechanical_press_compacting.text_4": "UNLOCALIZED: The filter slot can be used in case two recipes are conflicting.", + "create.ponder.mechanical_saw_breaker.header": "UNLOCALIZED: Cutting Trees with the Mechanical Saw", "create.ponder.mechanical_saw_breaker.text_1": "UNLOCALIZED: When given Rotational Force, a Mechanical Saw will cut trees directly in front of it", "create.ponder.mechanical_saw_breaker.text_2": "UNLOCALIZED: In order to cut the tree fully, the Saw has to break the last block connecting it to the ground", @@ -2155,6 +2203,13 @@ "create.ponder.mechanical_saw_processing.text_4": "UNLOCALIZED: When an ingredient has multiple possible outcomes, the filter slot can specify it", "create.ponder.mechanical_saw_processing.text_5": "UNLOCALIZED: Without filter, the Saw would cycle through all outcomes instead", + "create.ponder.millstone.header": "UNLOCALIZED: Processing Items in the Millstone", + "create.ponder.millstone.text_1": "UNLOCALIZED: Millstones process items by grinding them", + "create.ponder.millstone.text_2": "UNLOCALIZED: They can be powered from the side using cogwheels", + "create.ponder.millstone.text_3": "UNLOCALIZED: Throw or Insert items at the top", + "create.ponder.millstone.text_4": "UNLOCALIZED: After some time, the result can be obtained via Right-click", + "create.ponder.millstone.text_5": "UNLOCALIZED: The outputs can also be extracted by automation", + "create.ponder.piston_pole.header": "UNLOCALIZED: Piston Extension Poles", "create.ponder.piston_pole.text_1": "UNLOCALIZED: Without attached Poles, a Mechanical Piston cannot move", "create.ponder.piston_pole.text_2": "UNLOCALIZED: The Length of pole added at its back determines the Extension Range", @@ -2240,6 +2295,11 @@ "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.speedometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Speedometer", + "create.ponder.speedometer.text_1": "UNLOCALIZED: The Speedometer displays the current Speed of the attached components", + "create.ponder.speedometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", + "create.ponder.speedometer.text_3": "UNLOCALIZED: Comparators can emit analog Restone Signals relative to the Speedometer's measurements", + "create.ponder.stabilized_bearings.header": "UNLOCALIZED: Stabilized Contraptions", "create.ponder.stabilized_bearings.text_1": "UNLOCALIZED: Whenever Mechanical Bearings are themselves part of a moving Structure..", "create.ponder.stabilized_bearings.text_2": "UNLOCALIZED: ..they will attempt to keep themselves upright", @@ -2252,6 +2312,11 @@ "create.ponder.sticker.text_3": "UNLOCALIZED: If it is now moved in a contraption, the block will move with it", "create.ponder.sticker.text_4": "UNLOCALIZED: Toggled once again, the block is no longer attached", + "create.ponder.stressometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Stressometer", + "create.ponder.stressometer.text_1": "UNLOCALIZED: The Stressometer displays the current Stress Capacity of the attached kinetic network", + "create.ponder.stressometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", + "create.ponder.stressometer.text_3": "UNLOCALIZED: Comparators can emit analog Restone Signals relative to the Stressometer's measurements", + "create.ponder.super_glue.header": "UNLOCALIZED: Attaching blocks using Super Glue", "create.ponder.super_glue.text_1": "UNLOCALIZED: Super Glue can be used between any two blocks", "create.ponder.super_glue.text_2": "UNLOCALIZED: The attached blocks will move together when assembled into a Contraption", 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 fff451d2d..6121864c8 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: 424", + "_": "Missing Localizations: 479", "_": "->------------------------] Game Elements [------------------------<-", @@ -1874,6 +1874,17 @@ "create.ponder.analog_lever.text_2": "UNLOCALIZED: Right-click to increase its analog power output", "create.ponder.analog_lever.text_3": "UNLOCALIZED: Right-click while Sneaking to decrease the power output again", + "create.ponder.basin.header": "UNLOCALIZED: Processing Items in the Basin", + "create.ponder.basin.text_1": "UNLOCALIZED: A Basin can hold Items and Fluids for Processing", + "create.ponder.basin.text_2": "UNLOCALIZED: After a processing step, basins try to output below to the side of them", + "create.ponder.basin.text_3": "UNLOCALIZED: When a valid component is present, the Basin will show an output faucet", + "create.ponder.basin.text_4": "UNLOCALIZED: A number of options are applicable here", + "create.ponder.basin.text_5": "UNLOCALIZED: Outputs will be caught by the inventory below", + "create.ponder.basin.text_6": "UNLOCALIZED: Without output faucet, the Basin will retain items created in its processing", + "create.ponder.basin.text_7": "UNLOCALIZED: This can be useful if outputs should be re-used as ingredients", + "create.ponder.basin.text_8": "UNLOCALIZED: Desired outputs will then have to be extracted from the basin", + "create.ponder.basin.text_9": "UNLOCALIZED: A Filter might be necessary to avoid pulling out un-processed items", + "create.ponder.bearing_modes.header": "UNLOCALIZED: Movement Modes of the Mechanical Bearing", "create.ponder.bearing_modes.text_1": "UNLOCALIZED: When Stopped, the Bearing will place the structure at the nearest grid-aligned Angle", "create.ponder.bearing_modes.text_2": "UNLOCALIZED: It can be configured never to revert to solid blocks, or only near the angle it started at", @@ -1902,6 +1913,12 @@ "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.blaze_burner.header": "UNLOCALIZED: Feeding Blaze Burners", + "create.ponder.blaze_burner.text_1": "UNLOCALIZED: Blaze Burners can provide Heat to Items processed in a Basin", + "create.ponder.blaze_burner.text_2": "UNLOCALIZED: For this, the Blaze has to be fed with flammable items", + "create.ponder.blaze_burner.text_3": "UNLOCALIZED: With a Blaze Cake, the Burner can reach an even stronger level of heat", + "create.ponder.blaze_burner.text_4": "UNLOCALIZED: The feeding process can be automated using Deployers or Mechanical Arms", + "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.", @@ -1968,6 +1985,12 @@ "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.crushing_wheels.header": "UNLOCALIZED: Processing Items with Crushing Wheels", + "create.ponder.crushing_wheels.text_1": "UNLOCALIZED: A pair of Crushing Wheels can grind items very effectively", + "create.ponder.crushing_wheels.text_2": "UNLOCALIZED: Their Rotational Input has to make them spin into each other", + "create.ponder.crushing_wheels.text_3": "UNLOCALIZED: Items thrown or inserted into the top will get processed", + "create.ponder.crushing_wheels.text_4": "UNLOCALIZED: Items can be inserted and picked up through automated means as well", + "create.ponder.deployer.header": "UNLOCALIZED: Using the Deployer", "create.ponder.deployer.text_1": "UNLOCALIZED: Given Rotational Force, a Deployer can imitate player interactions", "create.ponder.deployer.text_10": "UNLOCALIZED: Right-click the front to give it an Item to use", @@ -1999,6 +2022,13 @@ "create.ponder.deployer_redstone.text_2": "UNLOCALIZED: Before stopping, the Deployer will finish any started cycles", "create.ponder.deployer_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.empty_blaze_burner.header": "UNLOCALIZED: Using Empty Blaze Burners", + "create.ponder.empty_blaze_burner.text_1": "UNLOCALIZED: Right-click a Blaze with the empty burner to capture it", + "create.ponder.empty_blaze_burner.text_2": "UNLOCALIZED: Alternatively, Blazes can be collected from their Spawners directly", + "create.ponder.empty_blaze_burner.text_3": "UNLOCALIZED: You now have an ideal heat source for various machines", + "create.ponder.empty_blaze_burner.text_4": "UNLOCALIZED: For Aesthetic purposes, Empty Blaze Burners can also be lit using Flint and Steel", + "create.ponder.empty_blaze_burner.text_5": "UNLOCALIZED: However, these are not suitable for industrial heating", + "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", @@ -2125,6 +2155,12 @@ "create.ponder.mechanical_harvester.text_1": "UNLOCALIZED: Whenever Harvesters are moved as part of an animated Contraption...", "create.ponder.mechanical_harvester.text_2": "UNLOCALIZED: They will harvest and reset any mature crops on their way", + "create.ponder.mechanical_mixer.header": "UNLOCALIZED: Processing Items with the Mechanical Mixer", + "create.ponder.mechanical_mixer.text_1": "UNLOCALIZED: With a Mixer and Basin, some Crafting Recipes can be automated", + "create.ponder.mechanical_mixer.text_2": "UNLOCALIZED: Available recipes include any Shapeless Crafting Recipe, plus a couple extra ones", + "create.ponder.mechanical_mixer.text_3": "UNLOCALIZED: Some of those recipes may require the heat of a Blaze Burner", + "create.ponder.mechanical_mixer.text_4": "UNLOCALIZED: The filter slot can be used in case two recipes are conflicting.", + "create.ponder.mechanical_piston.header": "UNLOCALIZED: Moving Structures using Mechanical Pistons", "create.ponder.mechanical_piston.text_1": "UNLOCALIZED: Mechanical Pistons can move blocks in front of them", "create.ponder.mechanical_piston.text_2": "UNLOCALIZED: Speed and direction of movement depend on the Rotational Input", @@ -2140,6 +2176,18 @@ "create.ponder.mechanical_plough.text_3": "UNLOCALIZED: Additionally, ploughs can create farmland", "create.ponder.mechanical_plough.text_4": "UNLOCALIZED: ...they can also launch entities without hurting them", + "create.ponder.mechanical_press.header": "UNLOCALIZED: Processing Items with the Mechanical Press", + "create.ponder.mechanical_press.text_1": "UNLOCALIZED: The Mechanical Press can process items provided beneath it", + "create.ponder.mechanical_press.text_2": "UNLOCALIZED: The Input items can be dropped or placed on a Depot under the Press", + "create.ponder.mechanical_press.text_3": "UNLOCALIZED: When items are provided on a belt...", + "create.ponder.mechanical_press.text_4": "UNLOCALIZED: The Press will hold and process them automatically", + + "create.ponder.mechanical_press_compacting.header": "UNLOCALIZED: Compacting items with the Mechanical Press", + "create.ponder.mechanical_press_compacting.text_1": "UNLOCALIZED: Pressing items held in a Basin will cause them to be Compacted", + "create.ponder.mechanical_press_compacting.text_2": "UNLOCALIZED: Compacting includes any filled 2x2 or 3x3 Crafting Recipe, plus a couple extra ones", + "create.ponder.mechanical_press_compacting.text_3": "UNLOCALIZED: Some of those recipes may require the heat of a Blaze Burner", + "create.ponder.mechanical_press_compacting.text_4": "UNLOCALIZED: The filter slot can be used in case two recipes are conflicting.", + "create.ponder.mechanical_saw_breaker.header": "UNLOCALIZED: Cutting Trees with the Mechanical Saw", "create.ponder.mechanical_saw_breaker.text_1": "UNLOCALIZED: When given Rotational Force, a Mechanical Saw will cut trees directly in front of it", "create.ponder.mechanical_saw_breaker.text_2": "UNLOCALIZED: In order to cut the tree fully, the Saw has to break the last block connecting it to the ground", @@ -2155,6 +2203,13 @@ "create.ponder.mechanical_saw_processing.text_4": "UNLOCALIZED: When an ingredient has multiple possible outcomes, the filter slot can specify it", "create.ponder.mechanical_saw_processing.text_5": "UNLOCALIZED: Without filter, the Saw would cycle through all outcomes instead", + "create.ponder.millstone.header": "UNLOCALIZED: Processing Items in the Millstone", + "create.ponder.millstone.text_1": "UNLOCALIZED: Millstones process items by grinding them", + "create.ponder.millstone.text_2": "UNLOCALIZED: They can be powered from the side using cogwheels", + "create.ponder.millstone.text_3": "UNLOCALIZED: Throw or Insert items at the top", + "create.ponder.millstone.text_4": "UNLOCALIZED: After some time, the result can be obtained via Right-click", + "create.ponder.millstone.text_5": "UNLOCALIZED: The outputs can also be extracted by automation", + "create.ponder.piston_pole.header": "UNLOCALIZED: Piston Extension Poles", "create.ponder.piston_pole.text_1": "UNLOCALIZED: Without attached Poles, a Mechanical Piston cannot move", "create.ponder.piston_pole.text_2": "UNLOCALIZED: The Length of pole added at its back determines the Extension Range", @@ -2240,6 +2295,11 @@ "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.speedometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Speedometer", + "create.ponder.speedometer.text_1": "UNLOCALIZED: The Speedometer displays the current Speed of the attached components", + "create.ponder.speedometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", + "create.ponder.speedometer.text_3": "UNLOCALIZED: Comparators can emit analog Restone Signals relative to the Speedometer's measurements", + "create.ponder.stabilized_bearings.header": "UNLOCALIZED: Stabilized Contraptions", "create.ponder.stabilized_bearings.text_1": "UNLOCALIZED: Whenever Mechanical Bearings are themselves part of a moving Structure..", "create.ponder.stabilized_bearings.text_2": "UNLOCALIZED: ..they will attempt to keep themselves upright", @@ -2252,6 +2312,11 @@ "create.ponder.sticker.text_3": "UNLOCALIZED: If it is now moved in a contraption, the block will move with it", "create.ponder.sticker.text_4": "UNLOCALIZED: Toggled once again, the block is no longer attached", + "create.ponder.stressometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Stressometer", + "create.ponder.stressometer.text_1": "UNLOCALIZED: The Stressometer displays the current Stress Capacity of the attached kinetic network", + "create.ponder.stressometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", + "create.ponder.stressometer.text_3": "UNLOCALIZED: Comparators can emit analog Restone Signals relative to the Stressometer's measurements", + "create.ponder.super_glue.header": "UNLOCALIZED: Attaching blocks using Super Glue", "create.ponder.super_glue.text_1": "UNLOCALIZED: Super Glue can be used between any two blocks", "create.ponder.super_glue.text_2": "UNLOCALIZED: The attached blocks will move together when assembled into a Contraption", 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/main/java/com/simibubi/create/content/contraptions/components/mixer/MechanicalMixerTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MechanicalMixerTileEntity.java index 6073f366e..7f9eb0859 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MechanicalMixerTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MechanicalMixerTileEntity.java @@ -116,7 +116,7 @@ public class MechanicalMixerTileEntity extends BasinOperatingTileEntity { if (world.isRemote && runningTicks == 20) renderParticles(); - if (!world.isRemote && runningTicks == 20) { + if ((!world.isRemote || isVirtual()) && runningTicks == 20) { if (processingTicks < 0) { processingTicks = MathHelper.clamp((MathHelper.log2((int) (512 / speed))) * 15 + 1, 1, 512); } else { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/press/MechanicalPressTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/press/MechanicalPressTileEntity.java index ddc48fb8b..8b8f7fbf9 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/press/MechanicalPressTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/press/MechanicalPressTileEntity.java @@ -120,6 +120,7 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity { public void start(Mode mode) { this.mode = mode; running = true; + prevRunningTicks = 0; runningTicks = 0; pressedItems.clear(); sendData(); @@ -203,7 +204,7 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity { if (prevRunningTicks < CYCLE / 2 && runningTicks >= CYCLE / 2) { runningTicks = CYCLE / 2; // Pause the ticks until a packet is received - if (world.isRemote) + if (world.isRemote && !isVirtual()) runningTicks = -(CYCLE / 2); } } @@ -342,7 +343,7 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity { return Optional.of(AllTriggers.PRESS_COMPACT); } - enum Mode { + public enum Mode { WORLD(1), BELT(19f / 16f), BASIN(22f / 16f) ; diff --git a/src/main/java/com/simibubi/create/content/contraptions/processing/burner/BlazeBurnerTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/processing/burner/BlazeBurnerTileEntity.java index 611c523be..32745013f 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/processing/burner/BlazeBurnerTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/processing/burner/BlazeBurnerTileEntity.java @@ -75,8 +75,14 @@ public class BlazeBurnerTileEntity extends SmartTileEntity { ClientPlayerEntity player = Minecraft.getInstance().player; float target = 0; if (player != null) { - double dx = player.getX() - (getPos().getX() + 0.5); - double dz = player.getZ() - (getPos().getZ() + 0.5); + double x = player.getX(); + double z = player.getZ(); + if (isVirtual()) { + x = -4; + z = -10; + } + double dx = x - (getPos().getX() + 0.5); + double dz = z - (getPos().getZ() + 0.5); target = AngleHelper.deg(-MathHelper.atan2(dz, dx)) - 90; } target = headAngle.getValue() + AngleHelper.getShortestAngleDiff(headAngle.getValue(), target); diff --git a/src/main/java/com/simibubi/create/foundation/ponder/PonderUI.java b/src/main/java/com/simibubi/create/foundation/ponder/PonderUI.java index b9feddb16..0b241cae0 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/PonderUI.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/PonderUI.java @@ -446,6 +446,7 @@ public class PonderUI extends NavigatableSimiScreen { // X AXIS RenderSystem.pushMatrix(); RenderSystem.translated(4, -3, 0); + RenderSystem.translated(0, 0, -2 / 1024f); for (int x = 0; x <= bounds.getXSize(); x++) { RenderSystem.translated(-16, 0, 0); font.drawString(x == bounds.getXSize() ? "x" : "" + x, 0, 0, 0xFFFFFFFF); diff --git a/src/main/java/com/simibubi/create/foundation/ponder/PonderWorld.java b/src/main/java/com/simibubi/create/foundation/ponder/PonderWorld.java index bed230311..b43adcffa 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/PonderWorld.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/PonderWorld.java @@ -206,6 +206,11 @@ public class PonderWorld extends SchematicWorld { addParticle(makeParticle(data, x, y, z, mx, my, mz)); } + @Override + public void addOptionalParticle(IParticleData data, double x, double y, double z, double mx, double my, double mz) { + addParticle(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, @@ -297,5 +302,10 @@ public class PonderWorld extends SchematicWorld { public boolean isBlockPresent(BlockPos pos) { return true; // fix particle lighting } - + + @Override + public boolean isPlayerWithin(double p_217358_1_, double p_217358_3_, double p_217358_5_, double p_217358_7_) { + return true; // always enable spawner animations + } + } diff --git a/src/main/java/com/simibubi/create/foundation/ponder/SceneBuilder.java b/src/main/java/com/simibubi/create/foundation/ponder/SceneBuilder.java index 92450e9d8..ead35f82a 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/SceneBuilder.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/SceneBuilder.java @@ -367,10 +367,6 @@ public class SceneBuilder { addInstruction(new OutlineSelectionInstruction(color, slot, selection, duration)); } - public void hideElement(ElementLink link, Direction direction) { - addInstruction(new FadeOutOfSceneInstruction<>(15, direction, link)); - } - } public class SpecialInstructions { @@ -430,6 +426,10 @@ public class SceneBuilder { addInstruction(AnimateMinecartInstruction.move(link, offset, duration)); } + public void hideElement(ElementLink link, Direction direction) { + addInstruction(new FadeOutOfSceneInstruction<>(15, direction, link)); + } + } public class WorldInstructions { @@ -689,11 +689,13 @@ public class SceneBuilder { addInstruction(scene -> { PonderWorld world = scene.getWorld(); TileEntity tileEntity = world.getTileEntity(beltLocation); - if (!(tileEntity instanceof BeltTileEntity)) + if (!(tileEntity instanceof SmartTileEntity)) return; - BeltTileEntity beltTileEntity = (BeltTileEntity) tileEntity; + SmartTileEntity beltTileEntity = (SmartTileEntity) tileEntity; TransportedItemStackHandlerBehaviour transporter = beltTileEntity.getBehaviour(TransportedItemStackHandlerBehaviour.TYPE); + if (transporter == null) + return; transporter.handleCenteredProcessingOnAllItems(.52f, tis -> TransportedResult.removeItem()); }); } diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/CartAssemblerScenes.java b/src/main/java/com/simibubi/create/foundation/ponder/content/CartAssemblerScenes.java index 037078293..aa89113eb 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/content/CartAssemblerScenes.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/CartAssemblerScenes.java @@ -237,7 +237,7 @@ public class CartAssemblerScenes { scene.world.hideIndependentSection(contraption, Direction.UP); scene.world.hideIndependentSection(anchor, Direction.UP); - scene.overlay.hideElement(cart, Direction.UP); + scene.special.hideElement(cart, Direction.UP); scene.idle(25); Vec3d blockSurface = util.vector.blockSurface(assemblerPos, Direction.NORTH) @@ -440,7 +440,7 @@ public class CartAssemblerScenes { scene.world.moveSection(anchor, util.vector.of(-2, 0, 0), 10); scene.special.moveCart(cart, util.vector.of(-5, 0, 0), 25); scene.idle(30); - scene.overlay.hideElement(cart, Direction.UP); + scene.special.hideElement(cart, Direction.UP); scene.world.hideIndependentSection(contraption, Direction.UP); scene.world.moveSection(anchor, util.vector.of(0, -3, 0), 0); scene.idle(30); @@ -482,7 +482,7 @@ public class CartAssemblerScenes { scene.special.moveCart(cart, util.vector.of(-3, 0, 0), 15); scene.idle(30); - scene.overlay.hideElement(cart, Direction.UP); + scene.special.hideElement(cart, Direction.UP); scene.world.hideIndependentSection(anchor, Direction.UP); scene.world.hideIndependentSection(contraption, Direction.UP); scene.idle(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 index 2e6dfe173..0bdaa16e6 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/content/KineticsScenes.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/KineticsScenes.java @@ -1,12 +1,16 @@ package com.simibubi.create.foundation.ponder.content; import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllItems; import com.simibubi.create.content.contraptions.components.crank.ValveHandleBlock; +import com.simibubi.create.content.contraptions.components.crusher.CrushingWheelBlock; import com.simibubi.create.content.contraptions.components.waterwheel.WaterWheelBlock; import com.simibubi.create.content.contraptions.relays.advanced.sequencer.SequencedGearshiftBlock; 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.content.contraptions.relays.gauge.GaugeBlock; +import com.simibubi.create.content.contraptions.relays.gauge.StressGaugeTileEntity; import com.simibubi.create.content.logistics.block.redstone.NixieTubeTileEntity; import com.simibubi.create.foundation.ponder.ElementLink; import com.simibubi.create.foundation.ponder.SceneBuilder; @@ -1010,4 +1014,97 @@ public class KineticsScenes { scene.idle(35); } + public static void speedometer(SceneBuilder scene, SceneBuildingUtil util) { + gauge(scene, util, true); + } + + public static void stressometer(SceneBuilder scene, SceneBuildingUtil util) { + gauge(scene, util, false); + } + + private static void gauge(SceneBuilder scene, SceneBuildingUtil util, boolean speed) { + String component = speed ? "Speedometer" : "Stressometer"; + String title = "Monitoring Kinetic information using the " + component; + scene.title(speed ? "speedometer" : "stressometer", title); + scene.configureBasePlate(1, 0, 5); + + BlockPos gaugePos = util.grid.at(2, 1, 3); + + scene.world.showSection(util.select.layer(0), Direction.UP); + scene.idle(5); + + for (int x = 6; x >= 0; x--) { + scene.idle(2); + scene.world.showSection(util.select.position(x, 1, 3), Direction.DOWN); + } + scene.idle(10); + + scene.world.setBlock(gaugePos, (speed ? AllBlocks.SPEEDOMETER : AllBlocks.STRESSOMETER).getDefaultState() + .with(GaugeBlock.FACING, Direction.UP), true); + scene.world.setKineticSpeed(util.select.position(gaugePos), 32); + scene.idle(10); + + scene.overlay.showText(80) + .text("The " + component + " displays the current " + (speed ? "Speed" : "Stress Capacity") + + " of the attached " + (speed ? "components" : "kinetic network")) + .attachKeyFrame() + .pointAt(util.vector.topOf(gaugePos)) + .placeNearTarget(); + scene.idle(90); + + if (speed) { + scene.world.multiplyKineticSpeed(util.select.everywhere(), 4); + scene.effects.rotationSpeedIndicator(util.grid.at(6, 1, 3)); + scene.idle(5); + scene.effects.indicateSuccess(gaugePos); + + } else { + BlockState state = AllBlocks.CRUSHING_WHEEL.getDefaultState() + .with(CrushingWheelBlock.AXIS, Axis.X); + scene.world.setBlock(util.grid.at(5, 1, 3), state, true); + scene.world.setKineticSpeed(util.select.position(5, 1, 3), 32); + scene.world.modifyTileNBT(util.select.position(gaugePos), StressGaugeTileEntity.class, + nbt -> nbt.putFloat("Value", .5f)); + scene.effects.indicateRedstone(gaugePos); + scene.idle(20); + scene.world.setBlock(util.grid.at(4, 1, 3), state, true); + scene.world.setKineticSpeed(util.select.position(4, 1, 3), 32); + scene.world.modifyTileNBT(util.select.position(gaugePos), StressGaugeTileEntity.class, + nbt -> nbt.putFloat("Value", .9f)); + scene.effects.indicateRedstone(gaugePos); + scene.idle(10); + } + + scene.idle(30); + + Vec3d blockSurface = util.vector.blockSurface(gaugePos, Direction.NORTH); + scene.overlay.showControls( + new InputWindowElement(blockSurface, Pointing.RIGHT).withItem(AllItems.GOGGLES.asStack()), 40); + scene.idle(7); + scene.overlay.showText(80) + .text("When wearing Engineers' Goggles, the player can get more detailed information from the Gauge") + .attachKeyFrame() + .colored(PonderPalette.MEDIUM) + .pointAt(blockSurface) + .placeNearTarget(); + scene.idle(100); + + Selection comparator = util.select.fromTo(2, 1, 1, 2, 1, 2); + scene.world.showSection(comparator, Direction.SOUTH); + scene.idle(10); + scene.world.toggleRedstonePower(comparator); + scene.effects.indicateRedstone(util.grid.at(2, 1, 2)); + scene.idle(20); + + scene.overlay.showText(120) + .text("Comparators can emit analog Restone Signals relative to the " + component + "'s measurements") + .attachKeyFrame() + .colored(PonderPalette.RED) + .pointAt(util.vector.centerOf(2, 1, 2) + .add(0, -0.35, 0)) + .placeNearTarget(); + scene.idle(130); + scene.markAsFinished(); + } + } 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 index fa3411878..9ff2b9854 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/content/PonderIndex.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderIndex.java @@ -77,6 +77,25 @@ public class PonderIndex { PonderRegistry.forComponents(AllBlocks.ROTATION_SPEED_CONTROLLER) .addStoryBoard("speed_controller", KineticsScenes::speedController); + // Gauges + PonderRegistry.addStoryBoard(AllBlocks.SPEEDOMETER, "gauges", KineticsScenes::speedometer); + PonderRegistry.addStoryBoard(AllBlocks.STRESSOMETER, "gauges", KineticsScenes::stressometer); + + // Item Processing + PonderRegistry.addStoryBoard(AllBlocks.MILLSTONE, "millstone", ProcessingScenes::millstone); + PonderRegistry.addStoryBoard(AllBlocks.CRUSHING_WHEEL, "crushing_wheel", ProcessingScenes::crushingWheels); + PonderRegistry.addStoryBoard(AllBlocks.MECHANICAL_MIXER, "mechanical_mixer/mixing", ProcessingScenes::mixing); + PonderRegistry.forComponents(AllBlocks.MECHANICAL_PRESS) + .addStoryBoard("mechanical_press/pressing", ProcessingScenes::pressing) + .addStoryBoard("mechanical_press/compacting", ProcessingScenes::compacting); + PonderRegistry.forComponents(AllBlocks.BASIN) + .addStoryBoard("basin", ProcessingScenes::basin) + .addStoryBoard("mechanical_mixer/mixing", ProcessingScenes::mixing) + .addStoryBoard("mechanical_press/compacting", ProcessingScenes::compacting); + PonderRegistry.addStoryBoard(AllItems.EMPTY_BLAZE_BURNER, "empty_blaze_burner", + ProcessingScenes::emptyBlazeBurner); + PonderRegistry.addStoryBoard(AllBlocks.BLAZE_BURNER, "blaze_burner", ProcessingScenes::blazeBurner); + // Funnels PonderRegistry.addStoryBoard(AllBlocks.BRASS_FUNNEL, "funnels/brass", FunnelScenes::brass); PonderRegistry.forComponents(AllBlocks.ANDESITE_FUNNEL, AllBlocks.BRASS_FUNNEL) diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/ProcessingScenes.java b/src/main/java/com/simibubi/create/foundation/ponder/content/ProcessingScenes.java new file mode 100644 index 000000000..354a8b363 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/ProcessingScenes.java @@ -0,0 +1,895 @@ +package com.simibubi.create.foundation.ponder.content; + +import com.google.common.collect.ImmutableList; +import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllItems; +import com.simibubi.create.content.contraptions.components.deployer.DeployerTileEntity; +import com.simibubi.create.content.contraptions.components.millstone.MillstoneTileEntity; +import com.simibubi.create.content.contraptions.components.mixer.MechanicalMixerTileEntity; +import com.simibubi.create.content.contraptions.components.press.MechanicalPressTileEntity; +import com.simibubi.create.content.contraptions.components.press.MechanicalPressTileEntity.Mode; +import com.simibubi.create.content.contraptions.processing.BasinBlock; +import com.simibubi.create.content.contraptions.processing.BasinTileEntity; +import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock; +import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock.HeatLevel; +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.WorldSectionElement; +import com.simibubi.create.foundation.ponder.instructions.EmitParticlesInstruction.Emitter; +import com.simibubi.create.foundation.utility.IntAttached; +import com.simibubi.create.foundation.utility.Iterate; +import com.simibubi.create.foundation.utility.NBTHelper; +import com.simibubi.create.foundation.utility.Pointing; + +import net.minecraft.block.Blocks; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.item.ItemEntity; +import net.minecraft.entity.monster.BlazeEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.particles.ItemParticleData; +import net.minecraft.particles.ParticleTypes; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; + +public class ProcessingScenes { + + public static void millstone(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("millstone", "Processing Items in the Millstone"); + scene.configureBasePlate(0, 0, 5); + + Selection belt = util.select.fromTo(1, 1, 5, 0, 1, 2) + .add(util.select.position(1, 2, 2)); + Selection beltCog = util.select.position(2, 0, 5); + + scene.world.showSection(util.select.layer(0) + .substract(beltCog), Direction.UP); + + BlockPos millstone = util.grid.at(2, 2, 2); + Selection millstoneSelect = util.select.position(2, 2, 2); + Selection cogs = util.select.fromTo(3, 1, 2, 3, 2, 2); + scene.world.setKineticSpeed(millstoneSelect, 0); + + scene.idle(5); + scene.world.showSection(util.select.position(4, 1, 3), Direction.DOWN); + scene.world.showSection(util.select.position(2, 1, 2), Direction.DOWN); + scene.idle(10); + scene.world.showSection(util.select.position(millstone), Direction.DOWN); + scene.idle(10); + Vec3d millstoneTop = util.vector.topOf(millstone); + scene.overlay.showText(60) + .attachKeyFrame() + .text("Millstones process items by grinding them") + .pointAt(millstoneTop) + .placeNearTarget(); + scene.idle(70); + + scene.world.showSection(cogs, Direction.DOWN); + scene.idle(10); + scene.world.setKineticSpeed(millstoneSelect, 32); + scene.effects.indicateSuccess(millstone); + scene.idle(10); + + scene.overlay.showText(60) + .attachKeyFrame() + .colored(PonderPalette.GREEN) + .text("They can be powered from the side using cogwheels") + .pointAt(util.vector.topOf(millstone.east())) + .placeNearTarget(); + scene.idle(70); + + ItemStack itemStack = new ItemStack(Items.WHEAT); + Vec3d entitySpawn = util.vector.topOf(millstone.up(3)); + + ElementLink entity1 = + scene.world.createItemEntity(entitySpawn, util.vector.of(0, 0.2, 0), itemStack); + scene.idle(18); + scene.world.modifyEntity(entity1, Entity::remove); + scene.world.modifyTileEntity(millstone, MillstoneTileEntity.class, + ms -> ms.inputInv.setStackInSlot(0, itemStack)); + scene.idle(10); + scene.overlay.showControls(new InputWindowElement(millstoneTop, Pointing.DOWN).withItem(itemStack), 30); + scene.idle(7); + + scene.overlay.showText(40) + .attachKeyFrame() + .text("Throw or Insert items at the top") + .pointAt(millstoneTop) + .placeNearTarget(); + scene.idle(60); + + scene.world.modifyTileEntity(millstone, MillstoneTileEntity.class, + ms -> ms.inputInv.setStackInSlot(0, ItemStack.EMPTY)); + + scene.overlay.showText(50) + .text("After some time, the result can be obtained via Right-click") + .pointAt(util.vector.blockSurface(millstone, Direction.WEST)) + .placeNearTarget(); + scene.idle(60); + + ItemStack flour = AllItems.WHEAT_FLOUR.asStack(); + scene.overlay.showControls( + new InputWindowElement(util.vector.blockSurface(millstone, Direction.NORTH), Pointing.RIGHT).rightClick() + .withItem(flour), + 40); + scene.idle(50); + + scene.addKeyframe(); + scene.world.showSection(beltCog, Direction.UP); + scene.world.showSection(belt, Direction.EAST); + scene.idle(15); + + BlockPos beltPos = util.grid.at(1, 1, 2); + scene.world.createItemOnBelt(beltPos, Direction.EAST, flour); + scene.idle(15); + scene.world.createItemOnBelt(beltPos, Direction.EAST, new ItemStack(Items.WHEAT_SEEDS)); + scene.idle(20); + + scene.overlay.showText(50) + .text("The outputs can also be extracted by automation") + .pointAt(util.vector.blockSurface(millstone, Direction.WEST) + .add(-.5, .4, 0)) + .placeNearTarget(); + scene.idle(60); + } + + public static void crushingWheels(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("crushing_wheels", "Processing Items with Crushing Wheels"); + scene.configureBasePlate(0, 0, 5); + scene.scaleSceneView(.9f); + + Selection wheels = util.select.fromTo(3, 2, 2, 1, 2, 2); + Selection kinetics = util.select.fromTo(0, 1, 5, 4, 1, 3); + Selection kinetics2 = util.select.fromTo(0, 2, 5, 4, 2, 3); + Selection beltCog = util.select.position(5, 0, 1); + scene.world.setKineticSpeed(wheels, 0); + scene.world.setBlock(util.grid.at(2, 3, 2), Blocks.AIR.getDefaultState(), false); + + scene.world.showSection(util.select.layer(0) + .substract(beltCog), Direction.UP); + scene.idle(5); + + Selection belt = util.select.fromTo(4, 1, 2, 4, 4, 2) + .add(util.select.fromTo(4, 3, 3, 4, 4, 3)) + .add(util.select.position(3, 3, 2)) + .add(util.select.position(2, 3, 2)); + Selection bottomBelt = util.select.fromTo(5, 1, 0, 2, 1, 0) + .add(util.select.fromTo(2, 1, 2, 2, 1, 1)); + + BlockPos center = util.grid.at(2, 2, 2); + Selection wWheel = util.select.position(center.west()); + Selection eWheel = util.select.position(center.east()); + + scene.world.showSection(wWheel, Direction.SOUTH); + scene.idle(3); + scene.world.showSection(eWheel, Direction.SOUTH); + scene.idle(10); + + Vec3d centerTop = util.vector.topOf(center); + scene.overlay.showText(60) + .attachKeyFrame() + .text("A pair of Crushing Wheels can grind items very effectively") + .pointAt(centerTop) + .placeNearTarget(); + scene.idle(70); + + scene.world.showSection(kinetics, Direction.DOWN); + scene.idle(3); + scene.world.showSection(kinetics2, Direction.DOWN); + scene.world.setKineticSpeed(wWheel, -16); + scene.world.setKineticSpeed(eWheel, 16); + scene.idle(5); + scene.effects.rotationDirectionIndicator(center.west()); + scene.effects.rotationDirectionIndicator(center.east()); + scene.idle(10); + + scene.overlay.showText(60) + .attachKeyFrame() + .text("Their Rotational Input has to make them spin into each other") + .pointAt(util.vector.blockSurface(center.west(), Direction.NORTH)) + .placeNearTarget(); + scene.idle(40); + scene.effects.rotationDirectionIndicator(center.west()); + scene.effects.rotationDirectionIndicator(center.east()); + scene.idle(30); + + ItemStack input = new ItemStack(Items.GOLD_ORE); + ItemStack output = AllItems.CRUSHED_GOLD.asStack(); + Vec3d entitySpawn = util.vector.topOf(center.up(2)); + + ElementLink entity1 = + scene.world.createItemEntity(entitySpawn, util.vector.of(0, 0.2, 0), input); + scene.idle(18); + scene.world.modifyEntity(entity1, Entity::remove); + Emitter blockSpace = + Emitter.withinBlockSpace(new ItemParticleData(ParticleTypes.ITEM, input), util.vector.of(0, 0, 0)); + scene.effects.emitParticles(util.vector.centerOf(center) + .add(0, -0.2, 0), blockSpace, 3, 40); + scene.idle(10); + scene.overlay.showControls(new InputWindowElement(centerTop, Pointing.DOWN).withItem(input), 30); + scene.idle(7); + + scene.overlay.showText(50) + .attachKeyFrame() + .text("Items thrown or inserted into the top will get processed") + .pointAt(centerTop) + .placeNearTarget(); + scene.idle(60); + + scene.world.createItemEntity(centerTop.add(0, -1.4, 0), util.vector.of(0, 0, 0), output); + scene.idle(10); + scene.world.createItemEntity(centerTop.add(0, -1.4, 0), util.vector.of(0, 0, 0), output); + scene.overlay.showControls(new InputWindowElement(centerTop.add(0, -2, 0), Pointing.UP).withItem(output), 30); + scene.idle(40); + + scene.world.restoreBlocks(util.select.position(2, 3, 2)); + scene.world.showSection(belt, Direction.DOWN); + scene.idle(5); + scene.world.showSection(beltCog, Direction.UP); + scene.idle(5); + scene.world.modifyEntities(ItemEntity.class, Entity::remove); + scene.world.showSection(bottomBelt, Direction.SOUTH); + scene.idle(5); + + scene.overlay.showText(50) + .attachKeyFrame() + .text("Items can be inserted and picked up through automated means as well") + .pointAt(centerTop.add(0, .5, 0)) + .placeNearTarget(); + scene.idle(40); + + for (int i = 0; i < 5; i++) { + if (i < 4) + scene.world.createItemOnBelt(util.grid.at(4, 4, 2), Direction.EAST, input); + scene.idle(15); + if (i < 3) + scene.world.createItemOnBelt(util.grid.at(4, 4, 2), Direction.EAST, input); + scene.idle(15); + if (i > 0) { + scene.world.createItemOnBelt(center.down(), Direction.UP, output); + scene.idle(15); + scene.world.createItemOnBelt(center.down(), Direction.UP, output); + } + scene.world.removeItemsFromBelt(util.grid.at(3, 3, 2)); + if (i < 4) + scene.effects.emitParticles(util.vector.centerOf(center) + .add(0, -0.2, 0), blockSpace, 3, 28); + if (i == 0) + scene.markAsFinished(); + } + } + + public static void pressing(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("mechanical_press", "Processing Items with the Mechanical Press"); + scene.configureBasePlate(0, 0, 5); + scene.world.showSection(util.select.layer(0), Direction.UP); + scene.idle(5); + + ElementLink depot = + scene.world.showIndependentSection(util.select.position(2, 1, 1), Direction.DOWN); + scene.world.moveSection(depot, util.vector.of(0, 0, 1), 0); + scene.idle(10); + + Selection pressS = util.select.position(2, 3, 2); + BlockPos pressPos = util.grid.at(2, 3, 2); + BlockPos depotPos = util.grid.at(2, 1, 1); + scene.world.setKineticSpeed(pressS, 0); + scene.world.showSection(pressS, Direction.DOWN); + scene.idle(10); + + scene.world.showSection(util.select.fromTo(2, 1, 3, 2, 1, 5), Direction.NORTH); + scene.idle(3); + scene.world.showSection(util.select.position(2, 2, 3), Direction.SOUTH); + scene.idle(3); + scene.world.showSection(util.select.position(2, 3, 3), Direction.NORTH); + scene.world.setKineticSpeed(pressS, -32); + scene.effects.indicateSuccess(pressPos); + scene.idle(10); + + Vec3d pressSide = util.vector.blockSurface(pressPos, Direction.WEST); + scene.overlay.showText(60) + .pointAt(pressSide) + .placeNearTarget() + .attachKeyFrame() + .text("The Mechanical Press can process items provided beneath it"); + scene.idle(70); + scene.overlay.showText(60) + .pointAt(pressSide.subtract(0, 2, 0)) + .placeNearTarget() + .text("The Input items can be dropped or placed on a Depot under the Press"); + scene.idle(50); + ItemStack copper = AllItems.COPPER_INGOT.asStack(); + scene.world.createItemOnBeltLike(depotPos, Direction.NORTH, copper); + Vec3d depotCenter = util.vector.centerOf(depotPos.south()); + scene.overlay.showControls(new InputWindowElement(depotCenter, Pointing.UP).withItem(copper), 30); + scene.idle(10); + + Class type = MechanicalPressTileEntity.class; + scene.world.modifyTileEntity(pressPos, type, pte -> pte.start(Mode.BELT)); + scene.idle(30); + scene.world.modifyTileEntity(pressPos, type, + pte -> pte.makePressingParticleEffect(depotCenter.add(0, 8 / 16f, 0), copper)); + scene.world.removeItemsFromBelt(depotPos); + ItemStack sheet = AllItems.COPPER_SHEET.asStack(); + scene.world.createItemOnBeltLike(depotPos, Direction.UP, sheet); + scene.idle(10); + scene.overlay.showControls(new InputWindowElement(depotCenter, Pointing.UP).withItem(sheet), 50); + scene.idle(60); + + scene.world.hideIndependentSection(depot, Direction.NORTH); + scene.idle(5); + scene.world.showSection(util.select.fromTo(0, 1, 3, 0, 2, 3), Direction.DOWN); + scene.idle(10); + scene.world.showSection(util.select.fromTo(4, 1, 2, 0, 2, 2), Direction.SOUTH); + scene.idle(20); + BlockPos beltPos = util.grid.at(0, 1, 2); + scene.overlay.showText(40) + .pointAt(util.vector.blockSurface(beltPos, Direction.WEST)) + .placeNearTarget() + .attachKeyFrame() + .text("When items are provided on a belt..."); + scene.idle(30); + + ElementLink ingot = scene.world.createItemOnBelt(beltPos, Direction.SOUTH, copper); + scene.idle(15); + ElementLink ingot2 = scene.world.createItemOnBelt(beltPos, Direction.SOUTH, copper); + scene.idle(15); + scene.world.stallBeltItem(ingot, true); + scene.world.modifyTileEntity(pressPos, type, pte -> pte.start(Mode.BELT)); + + scene.overlay.showText(50) + .pointAt(pressSide) + .placeNearTarget() + .attachKeyFrame() + .text("The Press will hold and process them automatically"); + + scene.idle(30); + scene.world.modifyTileEntity(pressPos, type, + pte -> pte.makePressingParticleEffect(depotCenter.add(0, 8 / 16f, 0), copper)); + scene.world.removeItemsFromBelt(pressPos.down(2)); + ingot = scene.world.createItemOnBelt(pressPos.down(2), Direction.UP, sheet); + scene.world.stallBeltItem(ingot, true); + scene.idle(15); + scene.world.stallBeltItem(ingot, false); + scene.idle(15); + scene.world.stallBeltItem(ingot2, true); + scene.world.modifyTileEntity(pressPos, type, pte -> pte.start(Mode.BELT)); + scene.idle(30); + scene.world.modifyTileEntity(pressPos, type, + pte -> pte.makePressingParticleEffect(depotCenter.add(0, 8 / 16f, 0), copper)); + scene.world.removeItemsFromBelt(pressPos.down(2)); + ingot2 = scene.world.createItemOnBelt(pressPos.down(2), Direction.UP, sheet); + scene.world.stallBeltItem(ingot2, true); + scene.idle(15); + scene.world.stallBeltItem(ingot2, false); + + } + + public static void mixing(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("mechanical_mixer", "Processing Items with the Mechanical Mixer"); + scene.configureBasePlate(0, 0, 5); + scene.world.setBlock(util.grid.at(1, 1, 2), AllBlocks.ANDESITE_CASING.getDefaultState(), false); + scene.world.showSection(util.select.layer(0), Direction.UP); + scene.idle(5); + scene.world.showSection(util.select.fromTo(1, 4, 3, 1, 1, 5), Direction.DOWN); + scene.idle(5); + scene.world.showSection(util.select.position(1, 1, 2), Direction.DOWN); + scene.idle(5); + scene.world.showSection(util.select.position(1, 2, 2), Direction.DOWN); + scene.idle(5); + scene.world.showSection(util.select.position(1, 4, 2), Direction.SOUTH); + scene.idle(5); + scene.world.showSection(util.select.fromTo(3, 1, 1, 1, 1, 1), Direction.SOUTH); + scene.world.showSection(util.select.fromTo(3, 1, 5, 3, 1, 2), Direction.SOUTH); + scene.idle(20); + + BlockPos basin = util.grid.at(1, 2, 2); + BlockPos pressPos = util.grid.at(1, 4, 2); + Vec3d basinSide = util.vector.blockSurface(basin, Direction.WEST); + + ItemStack blue = new ItemStack(Items.BLUE_DYE); + ItemStack red = new ItemStack(Items.RED_DYE); + ItemStack purple = new ItemStack(Items.PURPLE_DYE); + + scene.overlay.showText(60) + .pointAt(basinSide) + .placeNearTarget() + .attachKeyFrame() + .text("With a Mixer and Basin, some Crafting Recipes can be automated"); + scene.idle(40); + + scene.overlay.showControls(new InputWindowElement(util.vector.topOf(basin), Pointing.LEFT).withItem(blue), 30); + scene.overlay.showControls(new InputWindowElement(util.vector.topOf(basin), Pointing.RIGHT).withItem(red), 30); + scene.idle(30); + Class type = MechanicalMixerTileEntity.class; + scene.world.modifyTileEntity(pressPos, type, pte -> pte.startProcessingBasin()); + scene.world.createItemOnBeltLike(basin, Direction.UP, red); + scene.world.createItemOnBeltLike(basin, Direction.UP, blue); + scene.idle(80); + scene.world.modifyTileNBT(util.select.position(basin), BasinTileEntity.class, nbt -> { + nbt.put("VisualizedItems", + NBTHelper.writeCompoundList(ImmutableList.of(IntAttached.with(1, purple)), ia -> ia.getValue() + .serializeNBT())); + }); + scene.idle(4); + scene.world.createItemOnBelt(util.grid.at(1, 1, 1), Direction.UP, purple); + scene.idle(30); + + scene.overlay.showText(80) + .pointAt(basinSide) + .placeNearTarget() + .attachKeyFrame() + .text("Available recipes include any Shapeless Crafting Recipe, plus a couple extra ones"); + scene.idle(80); + + scene.rotateCameraY(-30); + scene.idle(10); + scene.world.setBlock(util.grid.at(1, 1, 2), AllBlocks.BLAZE_BURNER.getDefaultState() + .with(BlazeBurnerBlock.HEAT_LEVEL, HeatLevel.KINDLED), true); + scene.idle(10); + + scene.overlay.showText(80) + .pointAt(basinSide.subtract(0, 1, 0)) + .placeNearTarget() + .text("Some of those recipes may require the heat of a Blaze Burner"); + scene.idle(40); + + scene.rotateCameraY(30); + + scene.idle(60); + Vec3d filterPos = util.vector.of(1, 2.75f, 2.5f); + scene.overlay.showFilterSlotInput(filterPos, 100); + scene.overlay.showText(120) + .pointAt(filterPos) + .placeNearTarget() + .attachKeyFrame() + .text("The filter slot can be used in case two recipes are conflicting."); + scene.idle(60); + } + + public static void compacting(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("mechanical_press_compacting", "Compacting items with the Mechanical Press"); + scene.configureBasePlate(0, 0, 5); + scene.world.setBlock(util.grid.at(1, 1, 2), AllBlocks.ANDESITE_CASING.getDefaultState(), false); + scene.world.showSection(util.select.layer(0), Direction.UP); + scene.idle(5); + scene.world.showSection(util.select.fromTo(1, 4, 3, 1, 1, 5), Direction.DOWN); + scene.idle(5); + scene.world.showSection(util.select.position(1, 1, 2), Direction.DOWN); + scene.idle(5); + scene.world.showSection(util.select.position(1, 2, 2), Direction.DOWN); + scene.idle(5); + scene.world.showSection(util.select.position(1, 4, 2), Direction.SOUTH); + scene.idle(5); + scene.world.showSection(util.select.fromTo(3, 1, 1, 1, 1, 1), Direction.SOUTH); + scene.world.showSection(util.select.fromTo(3, 1, 5, 3, 1, 2), Direction.SOUTH); + scene.idle(20); + + BlockPos basin = util.grid.at(1, 2, 2); + BlockPos pressPos = util.grid.at(1, 4, 2); + Vec3d basinSide = util.vector.blockSurface(basin, Direction.WEST); + + ItemStack copper = AllItems.COPPER_INGOT.asStack(); + ItemStack copperBlock = AllBlocks.COPPER_BLOCK.asStack(); + + scene.overlay.showText(60) + .pointAt(basinSide) + .placeNearTarget() + .attachKeyFrame() + .text("Pressing items held in a Basin will cause them to be Compacted"); + scene.idle(40); + + scene.overlay.showControls(new InputWindowElement(util.vector.topOf(basin), Pointing.DOWN).withItem(copper), + 30); + scene.idle(30); + Class type = MechanicalPressTileEntity.class; + scene.world.modifyTileEntity(pressPos, type, pte -> pte.start(Mode.BASIN)); + scene.idle(30); + scene.world.modifyTileEntity(pressPos, type, + pte -> pte.makeCompactingParticleEffect(util.vector.centerOf(basin), copper)); + scene.world.modifyTileNBT(util.select.position(basin), BasinTileEntity.class, nbt -> { + nbt.put("VisualizedItems", + NBTHelper.writeCompoundList(ImmutableList.of(IntAttached.with(1, copperBlock)), ia -> ia.getValue() + .serializeNBT())); + }); + scene.idle(4); + scene.world.createItemOnBelt(util.grid.at(1, 1, 1), Direction.UP, copperBlock); + scene.idle(30); + + scene.overlay.showText(80) + .pointAt(basinSide) + .placeNearTarget() + .attachKeyFrame() + .text("Compacting includes any filled 2x2 or 3x3 Crafting Recipe, plus a couple extra ones"); + + scene.idle(30); + ItemStack log = new ItemStack(Items.OAK_LOG); + ItemStack bark = new ItemStack(Items.OAK_WOOD); + + scene.overlay.showControls(new InputWindowElement(util.vector.topOf(basin), Pointing.DOWN).withItem(log), 30); + scene.idle(30); + scene.world.modifyTileEntity(pressPos, type, pte -> pte.start(Mode.BASIN)); + scene.idle(30); + scene.world.modifyTileEntity(pressPos, type, + pte -> pte.makeCompactingParticleEffect(util.vector.centerOf(basin), log)); + scene.world.modifyTileNBT(util.select.position(basin), BasinTileEntity.class, nbt -> { + nbt.put("VisualizedItems", + NBTHelper.writeCompoundList(ImmutableList.of(IntAttached.with(1, bark)), ia -> ia.getValue() + .serializeNBT())); + }); + scene.idle(4); + scene.world.createItemOnBelt(util.grid.at(1, 1, 1), Direction.UP, bark); + scene.idle(30); + + scene.rotateCameraY(-30); + scene.idle(10); + scene.world.setBlock(util.grid.at(1, 1, 2), AllBlocks.BLAZE_BURNER.getDefaultState() + .with(BlazeBurnerBlock.HEAT_LEVEL, HeatLevel.KINDLED), true); + scene.idle(10); + + scene.overlay.showText(80) + .pointAt(basinSide.subtract(0, 1, 0)) + .placeNearTarget() + .text("Some of those recipes may require the heat of a Blaze Burner"); + scene.idle(40); + + scene.rotateCameraY(30); + + scene.idle(60); + Vec3d filterPos = util.vector.of(1, 2.75f, 2.5f); + scene.overlay.showFilterSlotInput(filterPos, 100); + scene.overlay.showText(120) + .pointAt(filterPos) + .placeNearTarget() + .attachKeyFrame() + .text("The filter slot can be used in case two recipes are conflicting."); + scene.idle(60); + } + + public static void emptyBlazeBurner(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("empty_blaze_burner", "Using Empty Blaze Burners"); + scene.configureBasePlate(0, 0, 5); + scene.world.showSection(util.select.layer(0), Direction.UP); + scene.idle(10); + BlockPos center = util.grid.at(2, 0, 2); + + scene.world.createEntity(w -> { + BlazeEntity blazeEntity = EntityType.BLAZE.create(w); + Vec3d v = util.vector.topOf(center); + blazeEntity.setPos(v.x, v.y, v.z); + blazeEntity.prevRotationYaw = blazeEntity.rotationYaw = 180; + return blazeEntity; + }); + + scene.idle(20); + scene.overlay + .showControls(new InputWindowElement(util.vector.centerOf(center.up(2)), Pointing.DOWN).rightClick() + .withItem(AllItems.EMPTY_BLAZE_BURNER.asStack()), 40); + scene.idle(10); + scene.overlay.showText(60) + .text("Right-click a Blaze with the empty burner to capture it") + .attachKeyFrame() + .pointAt(util.vector.blockSurface(center.up(2), Direction.WEST)) + .placeNearTarget(); + scene.idle(50); + + scene.world.modifyEntities(BlazeEntity.class, Entity::remove); + scene.idle(20); + + scene.world.showSection(util.select.position(2, 1, 2), Direction.DOWN); + scene.idle(20); + scene.overlay.showControls(new InputWindowElement(util.vector.topOf(center.up()), Pointing.DOWN).rightClick() + .withItem(AllItems.EMPTY_BLAZE_BURNER.asStack()), 40); + scene.idle(10); + scene.overlay.showText(60) + .text("Alternatively, Blazes can be collected from their Spawners directly") + .attachKeyFrame() + .pointAt(util.vector.blockSurface(center.up(), Direction.WEST)) + .placeNearTarget(); + scene.idle(50); + scene.world.hideSection(util.select.position(2, 1, 2), Direction.UP); + scene.idle(20); + scene.world.showSection(util.select.position(1, 1, 2), Direction.DOWN); + scene.idle(20); + + scene.world.modifyBlock(util.grid.at(1, 1, 2), s -> s.with(BlazeBurnerBlock.HEAT_LEVEL, HeatLevel.KINDLED), + false); + scene.overlay.showText(70) + .text("You now have an ideal heat source for various machines") + .attachKeyFrame() + .pointAt(util.vector.blockSurface(center.west() + .up(), Direction.WEST)) + .placeNearTarget(); + scene.idle(80); + + scene.world.showSection(util.select.position(3, 1, 2), Direction.DOWN); + scene.idle(20); + scene.overlay.showControls(new InputWindowElement(util.vector.topOf(center.east() + .up()), Pointing.DOWN).rightClick() + .withItem(new ItemStack(Items.FLINT_AND_STEEL)), + 40); + scene.idle(7); + scene.world.setBlock(util.grid.at(3, 1, 2), AllBlocks.LIT_BLAZE_BURNER.getDefaultState(), true); + scene.idle(10); + scene.overlay.showText(90) + .text("For Aesthetic purposes, Empty Blaze Burners can also be lit using Flint and Steel") + .attachKeyFrame() + .pointAt(util.vector.blockSurface(center.east() + .up(), Direction.UP)) + .placeNearTarget(); + scene.idle(70); + scene.overlay.showText(90) + .colored(PonderPalette.RED) + .text("However, these are not suitable for industrial heating") + .pointAt(util.vector.blockSurface(center.east() + .up(), Direction.UP)) + .placeNearTarget(); + scene.idle(70); + } + + public static void blazeBurner(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("blaze_burner", "Feeding Blaze Burners"); + scene.configureBasePlate(0, 0, 5); + scene.showBasePlate(); + scene.idle(10); + + BlockPos burner = util.grid.at(2, 1, 2); + scene.world.showSection(util.select.position(burner), Direction.DOWN); + scene.idle(10); + scene.world.showSection(util.select.position(burner.up()), Direction.DOWN); + scene.idle(10); + + scene.overlay.showText(70) + .attachKeyFrame() + .text("Blaze Burners can provide Heat to Items processed in a Basin") + .pointAt(util.vector.blockSurface(burner, Direction.WEST)) + .placeNearTarget(); + scene.idle(80); + + scene.world.hideSection(util.select.position(burner.up()), Direction.UP); + scene.idle(20); + scene.world.setBlock(burner.up(), Blocks.AIR.getDefaultState(), false); + scene.overlay.showControls(new InputWindowElement(util.vector.topOf(burner), Pointing.DOWN).rightClick() + .withItem(new ItemStack(Items.OAK_PLANKS)), 15); + scene.idle(7); + scene.world.modifyBlock(burner, s -> s.with(BlazeBurnerBlock.HEAT_LEVEL, HeatLevel.FADING), false); + scene.idle(15); + scene.overlay.showControls(new InputWindowElement(util.vector.topOf(burner), Pointing.DOWN).rightClick() + .withItem(new ItemStack(Items.OAK_PLANKS)), 15); + scene.idle(7); + scene.world.modifyBlock(burner, s -> s.with(BlazeBurnerBlock.HEAT_LEVEL, HeatLevel.KINDLED), false); + scene.idle(20); + + scene.overlay.showText(70) + .attachKeyFrame() + .text("For this, the Blaze has to be fed with flammable items") + .pointAt(util.vector.blockSurface(burner, Direction.WEST)) + .placeNearTarget(); + scene.idle(80); + + scene.idle(20); + scene.overlay.showControls(new InputWindowElement(util.vector.topOf(burner), Pointing.DOWN).rightClick() + .withItem(AllItems.BLAZE_CAKE.asStack()), 30); + scene.idle(7); + scene.world.modifyBlock(burner, s -> s.with(BlazeBurnerBlock.HEAT_LEVEL, HeatLevel.SEETHING), false); + scene.idle(20); + + scene.overlay.showText(80) + .attachKeyFrame() + .colored(PonderPalette.MEDIUM) + .text("With a Blaze Cake, the Burner can reach an even stronger level of heat") + .pointAt(util.vector.blockSurface(burner, Direction.WEST)) + .placeNearTarget(); + scene.idle(90); + + Class teType = DeployerTileEntity.class; + scene.world.modifyTileNBT(util.select.position(4, 1, 2), teType, + nbt -> nbt.put("HeldItem", AllItems.BLAZE_CAKE.asStack() + .serializeNBT())); + + scene.world.showSection(util.select.fromTo(3, 0, 5, 2, 0, 5), Direction.UP); + scene.idle(5); + scene.world.showSection(util.select.fromTo(4, 1, 2, 4, 1, 5), Direction.DOWN); + scene.idle(5); + scene.world.showSection(util.select.fromTo(2, 1, 4, 2, 1, 5), Direction.DOWN); + scene.idle(10); + + scene.overlay.showText(80) + .attachKeyFrame() + .text("The feeding process can be automated using Deployers or Mechanical Arms") + .pointAt(util.vector.blockSurface(burner.east(2), Direction.UP)); + scene.idle(90); + } + + public static void basin(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("basin", "Processing Items in the Basin"); + scene.configureBasePlate(0, 0, 5); + scene.world.showSection(util.select.layer(0), Direction.UP); + scene.idle(5); + + scene.world.showSection(util.select.position(1, 1, 2), Direction.DOWN); + scene.idle(10); + BlockPos basinPos = util.grid.at(1, 2, 2); + scene.world.modifyBlock(basinPos, s -> s.with(BasinBlock.FACING, Direction.DOWN), false); + scene.world.showSection(util.select.position(basinPos), Direction.DOWN); + scene.idle(10); + Vec3d basinSide = util.vector.blockSurface(basinPos, Direction.WEST); + scene.overlay.showText(80) + .attachKeyFrame() + .text("A Basin can hold Items and Fluids for Processing") + .pointAt(basinSide) + .placeNearTarget(); + scene.idle(10); + + ItemStack stack = new ItemStack(Items.BRICK); + for (int i = 0; i < 4; i++) { + scene.world.createItemEntity(util.vector.centerOf(basinPos.up(3)), util.vector.of(0, 0, 0), stack); + scene.idle(10); + } + scene.idle(10); + scene.overlay.showControls(new InputWindowElement(util.vector.topOf(basinPos), Pointing.DOWN).withItem(stack), + 30); + scene.idle(30); + + for (Direction d : Iterate.horizontalDirections) { + scene.overlay.showOutline(PonderPalette.GREEN, new Object(), util.select.position(basinPos.down() + .offset(d)), 60); + scene.idle(4); + } + + scene.overlay.showText(80) + .attachKeyFrame() + .colored(PonderPalette.GREEN) + .text("After a processing step, basins try to output below to the side of them") + .pointAt(basinSide) + .placeNearTarget(); + scene.idle(90); + + ElementLink depot = + scene.world.showIndependentSection(util.select.position(3, 1, 1), Direction.EAST); + scene.world.moveSection(depot, util.vector.of(-2, 0, 0), 0); + scene.idle(10); + scene.world.modifyBlock(basinPos, s -> s.with(BasinBlock.FACING, Direction.NORTH), false); + scene.idle(10); + + scene.overlay.showText(80) + .attachKeyFrame() + .colored(PonderPalette.GREEN) + .text("When a valid component is present, the Basin will show an output faucet") + .pointAt(basinSide.add(0.15, 0, -0.5)) + .placeNearTarget(); + scene.idle(90); + + scene.world.hideIndependentSection(depot, Direction.EAST); + scene.idle(15); + depot = scene.world.showIndependentSection(util.select.position(0, 1, 1), Direction.EAST); + scene.world.moveSection(depot, util.vector.of(1, 0, 0), 0); + scene.idle(20); + scene.world.hideIndependentSection(depot, Direction.EAST); + + scene.overlay.showText(80) + .text("A number of options are applicable here") + .pointAt(util.vector.centerOf(util.grid.at(1, 1, 1))) + .placeNearTarget(); + + scene.idle(15); + depot = scene.world.showIndependentSection(util.select.position(1, 1, 0), Direction.EAST); + scene.world.moveSection(depot, util.vector.of(0, 0, 1), 0); + scene.idle(20); + scene.world.hideIndependentSection(depot, Direction.EAST); + scene.idle(15); + depot = scene.world.showIndependentSection(util.select.position(1, 1, 1), Direction.EAST); + scene.idle(20); + scene.world.hideIndependentSection(depot, Direction.EAST); + scene.idle(15); + depot = scene.world.showIndependentSection(util.select.fromTo(3, 1, 0, 2, 1, 0), Direction.EAST); + scene.world.moveSection(depot, util.vector.of(-2, 0, 1), 0); + scene.idle(20); + scene.world.hideIndependentSection(depot, Direction.EAST); + scene.idle(15); + depot = scene.world.showIndependentSection(util.select.position(2, 1, 1), Direction.EAST); + scene.world.moveSection(depot, util.vector.of(-1, 0, 0), 0); + + scene.idle(25); + + BlockPos pressPos = util.grid.at(1, 4, 2); + scene.world.showSection(util.select.position(pressPos), Direction.DOWN); + scene.idle(5); + scene.world.showSection(util.select.fromTo(1, 4, 3, 1, 1, 5), Direction.NORTH); + scene.idle(10); + + Class type = MechanicalPressTileEntity.class; + scene.world.modifyTileEntity(pressPos, type, pte -> pte.start(Mode.BASIN)); + scene.idle(30); + scene.world.modifyTileEntity(pressPos, type, + pte -> pte.makeCompactingParticleEffect(util.vector.centerOf(basinPos), stack)); + scene.world.modifyTileNBT(util.select.position(basinPos), BasinTileEntity.class, nbt -> { + nbt.put("VisualizedItems", + NBTHelper.writeCompoundList(ImmutableList.of(IntAttached.with(1, new ItemStack(Blocks.BRICKS))), + ia -> ia.getValue() + .serializeNBT())); + }); + scene.idle(4); + scene.overlay.showControls(new InputWindowElement(util.vector.topOf(basinPos.down() + .north()), Pointing.RIGHT).withItem(new ItemStack(Items.BRICKS)), 30); + + scene.overlay.showText(60) + .attachKeyFrame() + .colored(PonderPalette.GREEN) + .text("Outputs will be caught by the inventory below") + .pointAt(basinSide.add(0, -1, -1)) + .placeNearTarget(); + scene.idle(70); + + scene.world.hideIndependentSection(depot, Direction.NORTH); + scene.idle(10); + scene.world.modifyBlock(basinPos, s -> s.with(BasinBlock.FACING, Direction.DOWN), false); + scene.idle(20); + + scene.overlay.showText(80) + .attachKeyFrame() + .text("Without output faucet, the Basin will retain items created in its processing") + .pointAt(basinSide) + .placeNearTarget(); + scene.idle(50); + + ItemStack nugget = AllItems.COPPER_NUGGET.asStack(); + scene.overlay.showControls(new InputWindowElement(util.vector.topOf(basinPos), Pointing.RIGHT).withItem(nugget), + 30); + scene.idle(30); + scene.world.modifyTileEntity(pressPos, type, pte -> pte.start(Mode.BASIN)); + scene.idle(30); + scene.world.modifyTileEntity(pressPos, type, + pte -> pte.makeCompactingParticleEffect(util.vector.centerOf(basinPos), nugget)); + + ItemStack ingot = AllItems.COPPER_INGOT.asStack(); + scene.idle(30); + scene.overlay.showControls(new InputWindowElement(util.vector.topOf(basinPos), Pointing.RIGHT).withItem(ingot), + 30); + scene.idle(30); + scene.world.modifyTileEntity(pressPos, type, pte -> pte.start(Mode.BASIN)); + scene.idle(30); + scene.world.modifyTileEntity(pressPos, type, + pte -> pte.makeCompactingParticleEffect(util.vector.centerOf(basinPos), ingot)); + + ItemStack block = AllBlocks.COPPER_BLOCK.asStack(); + scene.idle(30); + scene.overlay.showControls(new InputWindowElement(util.vector.topOf(basinPos), Pointing.RIGHT).withItem(block), + 30); + scene.overlay.showText(70) + .attachKeyFrame() + .colored(PonderPalette.GREEN) + .text("This can be useful if outputs should be re-used as ingredients") + .pointAt(basinSide) + .placeNearTarget(); + scene.idle(80); + + scene.world.showSection(util.select.fromTo(2, 2, 5, 4, 1, 2), Direction.DOWN); + scene.rotateCameraY(70); + scene.world.createItemOnBelt(util.grid.at(2, 1, 2), Direction.WEST, block); + scene.idle(40); + scene.overlay.showText(70) + .text("Desired outputs will then have to be extracted from the basin") + .pointAt(util.vector.topOf(util.grid.at(3, 1, 2)) + .subtract(0, 3 / 16f, 0)) + .placeNearTarget(); + scene.idle(80); + + Vec3d filter = util.vector.of(2.5, 2.85, 2.5); + scene.overlay.showFilterSlotInput(filter, 80); + scene.overlay.showText(70) + .text("A Filter might be necessary to avoid pulling out un-processed items") + .pointAt(filter) + .placeNearTarget(); + scene.idle(40); + scene.markAsFinished(); + } + +} diff --git a/src/main/resources/assets/create/models/block/funnel/block_vertical.json b/src/main/resources/assets/create/models/block/funnel/block_vertical.json index 9af30934a..e72ebfa9d 100644 --- a/src/main/resources/assets/create/models/block/funnel/block_vertical.json +++ b/src/main/resources/assets/create/models/block/funnel/block_vertical.json @@ -113,8 +113,8 @@ }, { "name": "Back", - "from": [1.95, -1.95, 1.95], - "to": [14.05, 2, 14.05], + "from": [1.925, -1.95, 1.925], + "to": [14.075, 2, 14.075], "rotation": {"angle": 0, "axis": "y", "origin": [8, 0.025, 8]}, "faces": { "north": {"uv": [2, 12, 14, 16], "texture": "#9"}, @@ -179,7 +179,6 @@ } } ], - "display": {}, "groups": [ { "name": "block_retracted", 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 index ca31358f9..6d16d099c 100644 --- 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 @@ -4,7 +4,6 @@ "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", @@ -113,8 +112,8 @@ }, { "name": "Back", - "from": [1.95, -1.95, 1.95], - "to": [14.05, 2, 14.05], + "from": [1.925, -1.95, 1.925], + "to": [14.075, 2, 14.075], "rotation": {"angle": 0, "axis": "y", "origin": [8, 0.025, 8]}, "faces": { "north": {"uv": [2, 12, 14, 16], "texture": "#9"}, @@ -135,7 +134,6 @@ } } ], - "display": {}, "groups": [ { "name": "block_retracted", @@ -162,7 +160,7 @@ { "name": "Item Filter", "origin": [8, 0, 8], - "children": [12, 13, 14, 15] + "children": [] } ] } \ No newline at end of file diff --git a/src/main/resources/ponder/basin.nbt b/src/main/resources/ponder/basin.nbt new file mode 100644 index 0000000000000000000000000000000000000000..e5340dadfc687295939fe02a16a540deb3bc614d GIT binary patch literal 1484 zcmV;-1vB~|iwFP!000000PR`Za@#f#U0y9wa&0$BoA2mb(l)K*)DzF7vTM7Uwl5x- zgd|QVf&)NSoF{)$pZWoPPx~?b0C&NQL{XFs#dMOHgfkkA#NEZ7gT+~Z^Z?pmi|`G# z06=}5{NuKvMPnJtkP1*&8{G4V`LBeBKfY;$l`v5_O)m=^A&I29N7=@xu`wz(rbZk~ zBaW>Rr?`w2af}+9Y8+D|j-?UD)`(MFrUuWZ2G6VFSQ>F`jW|aBDchJ!a9J92VQI|8 zsyLQL99tt!aoHMkVQb9AsyLQL9J@A-2UdJ8J?I>cWiplrl8(^BKEV~QMrnhS{spx%*)xDQ|%p2Cz8_W9oC#myb!v4RH3@IF>5A?PsAN=MfD~5|)mhBg=C+C2=Mu zrU%XodO;%xoRfso;K`NJAorB;0ZpAS>OSK>HPGTEiN*!Cj*79zVu?!Cg7$ti4uc*U zQP`R#MMsIew7}gRsk{mZ?|DEAx*2D)KifIkpArpO#dLj6u|6N46A{MPW)3eX??-F` zHI)y=Dk@dAl~*;E<&-?*15D}G5obOX2x4#=Vq=^k+{qD!xN6Pqz1nx0eWJ;a9_}PAcv5N>_HsR*RxzY1=}=29q?wsEHHk% zzP|nkzkf&T$N2pRe)rJN-BVLD0K0eC`^kg$L41MiFn&3w1O{v#F@ZaT3wp={$`>Zj ztU>AAj1tyCX*7hgMscgDyHho_6$z{5&jI^r97T{qe(;n@$ws>&-^V&fS(GI9>Eep; zhhs@oPch6qyK1D2WfrekALU)cMxLhy+oznwqEGoAV^P2+@f!MFBU!mao@{>{$23|} z*yVg$pS#euM~f=&p0F{poICux;85*FWkt3;*yvF?Vf>W?tv!+uKa`ixuN0^P z{Eh>i-5|h)C^>e`AFfo(GY^96>;JC6`SB6Xd3I;-PpEHRntjMvHht!bKBPgcaVNz7 zve5q4C3bTy8kZDZnHz6?Zp`;nbZc|7bsKK%8gAU_vfnx46jwJdbrz?0czpW&b8q={ zdrP&Ed`x?un!Z=FdowEq-}!*MNwX%OZk~?;t^F_##SqUB8bUQap&`3Jvw&uk-$_j~ zE2yf`+gy#lpDMM6;I!wv+%Bx_at3T1BXA{%8698ebd0D!Bys4I=qypzH4|l5h}mpt ztMGQALEWI*Rfpr1TLoK#MCXHT6^ipq`N`iGn#5`V>)r_CK@LNNqa>nduW&iZ(7&ls z9xvNVmT_z~wB@;Vfvn#0=oE;1o3>u4T$!8ghPFKK%+0rrakFt-ZmipLV>Qanca3q= zx-B<$g`1t`w83sj8>%#)EYmpq9kf9MN9T?-ZUKj-fn)dTopG2A;V4c)k8&KR%idZ! zB^+NiHy_p=;aFN%WgPdK!{NOz99AukHf$s$qEb?Il)2wR$x`QmhqDduWEe_%=Cc^n zK&Qgu{>(zeY;u;qMW5dND$kjqa*EVH6GRlyBhC`a)eCsk$v!fobTZv{7tZs0`QqQ2 zw-425`5;c8M1rDULby!9a#~pvn*nm;1eJwfhb)W_PJ}qi4=>dr(}#h2 zytv628`@=K@-31GU+D7VO3d-JK mGNg-Bt`}>oSfoW13p&q;Brho!>5H${U+_Q4tE;@MBme*k#K?jG literal 0 HcmV?d00001 diff --git a/src/main/resources/ponder/blaze_burner.nbt b/src/main/resources/ponder/blaze_burner.nbt new file mode 100644 index 0000000000000000000000000000000000000000..e83a314083c35e8d7ff7f22a6e24453ca91fa8c1 GIT binary patch literal 1047 zcmV+y1nB!8iwFP!000000OeQBlG;WPZXpQ}*kxQvs&Y@_yg&}#JtQI6o24qolwqBp z3z?M~nA(v>r5P6Qp7yD7PM#vkgCtkdBhUgeuwx%wTNPDN0@3}=*Z-{sKmeZN*XRO( z`S`1QHGn!Mnrn^<%oRZOT*&Z3HR#7@0l2ADh0^Wig0D2wxYF2^adyZ!C7Fr^j%$JA zS>P0xa{$NLAydYwSm3x8IGzPgaaAn*T(R);Asp8N$Fsn>4TXiDT?;=S!f`EdJPVxS z@+|!9S@`)7j%$JA?Zjz-o1AMGg7FN+4|s_pw+kMh&$495V|;}%;|WhD=6M||Jc5tH z3`zg^T(D~#P0jag2Wh7i)XM5GAN)az7=4$^w0iVaJMX{V3@J7 zK4v^~!0#AXhYa%vInCOS?e4JK`@R9S9_qQwE_|qWSjs}KuTF1_b>4tl9bs2}XttvW zqk+y)sc&zLk1O41vG|vaO^Pl?M2E zauu=v`o>I&>X2m<%ysCX6G=gJNa8gUvm!g22BRYrO>?9U!HJmhsK;W2M{AxKr~1l; z>Y9Pk{J;kWD`)?oY+h!}gQ6WU#S@zNFE2403pp?RQtk_tQdWDGeZi(A?<~MiR%8{A zQ-PxkvQP8yuAcJ6zUtf@0Dj4iKW_H*H@`n+3gO}4dHYr8bkyzj&xV5l9(O4M84ER+ zNni3rtD-=+$o*L&_k<+srzj#*)Q5}Mht>;ui7~~wpUH{w%{RFNTgxQLPwgfVzF8i8 zr^CJN9@vK49{A7iQ2F)gb_iT(4#G?dahrVGL5VS(vV@0Bj93=$?~TQD*&Jon`=3Qm z_GOWGAdA|2vdAVl2SV{Kb`%Nsbe|o?isEnBQM0Uu4;YWXR(2e%?D%ru8ntOh{r<+| z=ukYIk{!YQtB-O#_SVOy9SxGHrA(mKXvS=l*2R2QeY);>^C{Oj3S~kxNU4zccrBq4 zIUnV(qGn5?UYKHL-cqSI=UXi_70o#jVP-bp0$_XbH5)Q5nI-+|m^?;0-W(MT(-wQf z)rbk1Oh#j#DGmOZ3AH9w-U#>NMRK0pYHiKjvPyGqHgX{+6Kb8y<4DgC0q6QH2sI^# zlp$&%a$$}wvEALN--W=H9RWKV3Od3}FADf%K1F(ic`rIeAl?V%dOr%yyk|_a*O)09 R>r^1W!GCvyl8!ME008Ej2$}!@ literal 0 HcmV?d00001 diff --git a/src/main/resources/ponder/crushing_wheel.nbt b/src/main/resources/ponder/crushing_wheel.nbt new file mode 100644 index 0000000000000000000000000000000000000000..67be32a3013539b093a7b7d509767e0847525a9f GIT binary patch literal 1271 zcmVdiwFP!000000M%LDa@#}{UP~)mmYp`t0K;XUfKq-g8fd|F%itNt?U29# zH|a)N+nUH)&1xMdxyrln4&1{_aN9@V5jbm0vb>h$b!>ytj7N#Jd(M8}clMmKvV%|) z;n=^WCPGMl>hQ7Ty@_lZ3Sam%M)GQ+`bEIp%h-W`zGxydVsSbtyG&%of(V+-$d9QN zjHxMO3=KP`h8?V7C%tMFc4`G&X#gCB(BV{=C zLXTd{ZfeNU7AdA zlnEb$+jcKr7=|U+zo+3)jO6ki)aX+&W&F}Yc9%rN^~KG1?<6pM3W*2C*ccf-55D;Z z8Gk>uz@OkWj$gc$&yeAJsO54BU`{S*APP91X_4c`(Bx((Yx^KsTkMacfSzCaAr-!> zvesH*tso9m9OmKSXs^S8|6e$sCO96eIIIF3Si#YG_n+f9(!n9Gd|k0N&mFZ*bBEpO zzkGGtJ6p*g>ZAk7A9;T2oAZPA#?NDwpW4R!Sg6(UJnGGP`T9;q@&=4KsM!mzpc`cT zrU{S*9nX8h8ajHzV(1aC=xgr5%8H7%Bsbq6G!$~@hE~a~+65&!C-25q-28F3$zHw7 z^VeABuY)rF3`yaFzb;zYy)K``BhdSNI-)dCwYC$jzf81#Qq*M_3bLkx?D=nhIdi9v z3Z0(2S?J`I1o1ji6!_Hpfx3P~AuBw1!>VCtDao^=_JD&~*VFBY^oOR-QSy}EKo z&7XVGuD*lUzEUJS4h(C=-DQTa&=Nw zAu%+9s#Ov~k8}!&S-?+wKVhM|QFEP!42AV-Co(*#tXEnxl-4UfVeVhAaJuhu8rxAMO>}Vzj`>jp8`+Qe8Qa!$^!h!dPV_*B@v$A}Zf5CNp`1xuD z2iCxG0Qo9CcBC&2J}-N@X&rXHa@OH6HE3 zK!TXU)QE6_Od5LdYyfP?XCdQaWW%BYn24Maeua!}J8phO@Kl{j8*7280hKtHrib-mu`4jJEpN_q>4ajJZN5 zGBmjOSJb)DQzsdHyF%ges|0nLbwvW$JPEiI4xSy?Q%h^#*{DVv5t~w;gOb`cCJ`J2 z>9yd*6^n?^JbjpWB5(wZ<$g+z`8tv;Zx=kJvB>nWC7vna-tH9N#zB?bw>#NMt6@;R hlk{vY2cU^sFNq*OQ6Bp&gf#p+`Ujv;KOC(e0036-eZK$z literal 0 HcmV?d00001 diff --git a/src/main/resources/ponder/empty_blaze_burner.nbt b/src/main/resources/ponder/empty_blaze_burner.nbt new file mode 100644 index 0000000000000000000000000000000000000000..b134772cd16d3450c93f884924efce1d5ea4c0d8 GIT binary patch literal 481 zcmV<70UrJziwFP!000000F9Kvj?*v@h9|aDnyk=LEl3Wry_eY5*+Pwr&(abubXtNrzR7W=z--6SQKO2Zwubga@b2IoQJq zJ7U@#=E30}9O1#Ka}GUx4n2I{$Kf6v;lZhMW*$B>51;pOxCcjgaO#}7htJ%@=Y1UR z!4aLDA+YSi2@sPUG5LL4wtG6JTf6?@OP)|;5%K< z>H34NXKk&$j`wro}b8_;>r(<W@#|Ef3zYFg-#Y^?1D5wb>F49laejt+~)qzE9Qu4o5dG8LFjL`2ZZV8xRI zbi1|qzeJx@iSA0#k8)a%`J8gP58~#&j-j*;c&0OARIboRUs670+LTY5|9F9oz_qUs qoZa>IV(TFJZ5@S83uTa|)yaG55Qh&FZc%v;BGQn4gdfNe?!;+ literal 0 HcmV?d00001 diff --git a/src/main/resources/ponder/mechanical_mixer/mixing.nbt b/src/main/resources/ponder/mechanical_mixer/mixing.nbt new file mode 100644 index 0000000000000000000000000000000000000000..21114955b6b94979f3bb8dfab935594692ca1927 GIT binary patch literal 1142 zcmV-+1d00}iwFP!000000OeTAZsRr-r9?@wwoD%0bI5yquLDAS;^h1S zC?Q0@-0J1|qz8%OibGEH(;D=9qLbEilC(SNO+*~mQ)r`e4R?8TxF~&B) zp$0gP0Zx5cOK_}~F-;uX0EZgjI0iWNWgF;h8|b_YhZ^8G1~{{=FwmJA=)4Sv8sInv zIQ8Wi=1Jc!%jkhEPrT>&66&tncM> zU|iCB3CT!}b@%~U+XppG<%vsrJ1k=%SLZ)oYGTeI8V`=ybV+|ZiXb{v67u}pOU>Bc zi>|KzMGgOX>S6@NH#;BW=pM0oMEaowq_=epLIuR%OHR?PQhDwpT?KLJSr*xNmFDPS zr*I%6jI3=Fi`Rm%_WgymIuZ8oyM!h87534+WNbOSO>OA?wXs*C&1Y||&BohkLtC_Q zDs3q7hZ7Jl;S@w+G~~(gL?%Z(hSv}?o@kP@Mc%6y5$pm6WBp#6$#eibp{D2NRV|RFS;%;QVX(tPN~0F&O3Ta)CmY z;cvtka46YOZ844>;O?Z8L}`zG{DSA~SfKG_X|a0c&s8i(EGf$!Ji~6WpS9f2FZC99 zM@)`Dl}_XCrl^I5Bi=AEsU5nnG4v@#cj^&;S4?=c&tf2(^PnKk)HxpC?O4ZEQ+US< zQnFrZHh<_>V*j6HC{N6Kos`;F=aP)?QDN!fhjfyK(u@6KoYEArVJJZK9Kue<$lJL1u-0b0+M-QW>)$HVKG z$FpTT=<0Z^b>yNJbzm8__D2&EVwN2=y#Xr!HV+y1`pc8qnYR1 z58n@aMf>s9ZJoWlz+=6;{qWz_xvKYLk;ev(S<9FJr9hWZk9yeO=sM)1c^xtxa|MGi zO)!k&*SQ?={(MB9q|-t1@0&J`S2E2&>ObbNX$s4x$sID015VADRK@ZV>mF~2dgzu4 zSdJgvT;NO+j8n-kur^|1w%D~^$7l^N=20YIwTnLctU@DyAlo(KV#Nac)wlGJt5$&%6{ELqOaIp3V~&6#h`xDDWg ztHe1n05G>#+)W=^7-^veDlnH1&0`q{C#p?f9{IqMSd~uWi-D&!*I0N=+c-5gPQ|8S zfx|3tTnn7?a^~PTH8xe8h6N6@z;P{b%Bx|)bHjq?c{t1h$F;y2PlW}~%!226ILrda zwZJJa*Meu)g6DZS%mT-)#c2bJjG=cww@J?*>G=p+(A?%qL_Ki#_V>PSL-QaWrU4cXe_V5LV0Bkb zfN99)3ygZYZ^CcG${y-boSt~l+U5xlgg*P`!X)M%knoVrx(A)DFvRdcr>NA^3zKnU zH@v+3>lbMJ_QazIvVXRJBI_13L#U%f8InaEKKY|G}aVvl^eD=H;r52=99bShShN67ThrK zyF-*O@DybxH1P0vm_~C`Yy@mKvao9I2uVcd z;jaxS;2`B)y~zb>fVUkFBW*Nx{kc&5Sd#E0aW;CP&qXYUJj&Z0s$nmi&yw!1F3c1( z4|&={ohyyE6B8E>S-j?QSSobKV3;Z;b!vgXBZnf~;{${Tlb~>r=rbzct$~TFOyOT1 zkilxs+2lvRAp8GBLtZhf<)So-M2+zNDW+W+kD#cJ>gsG%s(PiUY6n_7wBA)8L$Hv{ zLqY9zJ{j(}afo?>oy;`1g6g6xh4jnuqO(}>53laGTQGCKeVawF@@g1ms+F_zQNhjt zgFcT$z~xb5tZRsIE5x*JscG4`Y5%A?Jf7RMxHcr-D4WY|QKtJ<|Ng80<5}v@YSe$( zt=7WjurartSbjOo(2!|v+PBndS#$IG{o#iFb8gsDx%uM$aN}0E=`2qhI`y$Vn{1SJ z+EAtW(^(qlzJoU0p~hXygIVOUb#do;lqdKnMIN8cde`Dj<*|DI=A)X&%(|M+W9>hf z2dmA)hn0j&)EZ55{$7hD%XGLOPdeODUuZlE;)uc^r_$nsiG_;d(NXqZ*NE!NG)^!z zuY5@dgIou_E|&_)HQ}kwhEJ)ZZgzV(byL!GiF9K+jsQ7nA=F~6aUeBBp$}ssGp};vG zBbA2|)u)NOmSmBL7sV;hSjdyUH<*|$*<`u_c_;yoU t%7irMT3WBYQ6Evh8`gsYYmCC6^PFq`8dD|Wh?MDP_#4yOv84AI006nPVFmyI literal 0 HcmV?d00001 diff --git a/src/main/resources/ponder/mechanical_press/pressing.nbt b/src/main/resources/ponder/mechanical_press/pressing.nbt new file mode 100644 index 0000000000000000000000000000000000000000..649276a51467368e132c7e12809424fcc21e0b35 GIT binary patch literal 1042 zcmV+t1nv7DiwFP!000000Nq&Ij^jiSEnky38FnAINj$QE_=KHBLbHJtkzi)UEC_gs zdhANl8pmyQcQ!loG@roN@B#c0msb?36FV1=lkKcB+JTlVC+@0KRi~@F%8me9;46NO z9srmtpv$K#Y(Wz<%{4~_X0#x@NJV_9BKq@r3%p#YQfWCn2$W_T3ypOdr$)x9$ha0b zo&}C?fm04=2aZ!CQ^j#Da6Ahf-vXx`t_9Do1<$*1JPRD(0%y4t7Cd_vJnzEsEO2}a z94LHRmvOhmKvpSKho==9VI zm`sM>Vm8zxnhhdooT8ozc^N>n%W@WTef7XujK?hP=SI3_gL@TXT9!$CkR*Dq@Kf<| zo?`!!R$cS>bzA?FZJon074DI$FEJ%G3MD%A-0~s&Pd3 zcXglaio^Tw#8Ixtr`xi0y^HQt;yAf^>v5FD$bN;WMMcujcxT zdS1?Nyg-@selA6h(tIMJ;$H{{1C}Zzm7GaEcUsc>S2!RRO>2Nm(ceI&qzTbTNPbNn z085ufHfpw&jd0A9B*i;6l252fxw=~;9%jj*EHrX4MQJ*Q!bG4(jBpzHM2!f3Whcml zq^7F`{ivD+2EAW2E!8mUA-0zGih6rWQZg08;hLX5d&Lzv*Gseq1zIeI(-Gcwq84RI z;uH;uzP_T^L&JHx+77ph>>K%4ZVTdf@P-iOX^}EHG~2ca)Pwd{OtT+RDlVu8ZT<%T M0`d*QXtERl0C#ThPXGV_ literal 0 HcmV?d00001 diff --git a/src/main/resources/ponder/millstone.nbt b/src/main/resources/ponder/millstone.nbt new file mode 100644 index 0000000000000000000000000000000000000000..81dc4503718a6bdf8854a908de907a8d468f20e8 GIT binary patch literal 946 zcmV;j15NxNiwFP!000000L@p;ZsRr(9*L4|$w@bd-J(G6eTF7mpiSKtYhaNqkZsZS z5-`%(79x`ZNw1Tf@(6vJp4)w~?a0=Ttw>&`b+I83$Ps5g&iBob9EAV@csjX51_1eA zuY3kDKw%P-poV+|(7Q@ybge`B=c@o%CUxml4Fp3w7mdVUQ9=#98e#1y=<^RpjA=v~N#im=ncfrGKGfhpwPYZOy6 z%Owb*e}-l$)wK_U5zly(nA=zPIWg~o4kxndd*F`abyog5_Gvw%Q0tr#1>+_$3?qd^ z=Hv=f(~_%Z4YJ2;1OJOQ$4zaVM{DE5@HCDwUTgC0eO?WZP%DIBEZ)&+FV$^8bPdjR zq1oXZsp$@QhvzD$$l40LDXiBJ_I-!27Q}i54O)WzQPUXJG+q=mbTZFUyu3~Xnk3qi zd>vjx@|F$OxRd-m~$}f)I&1-aEdF<}xO0eM3av+~{opPHzf(DP%PoEF=v3z(f zJi@1+kC$Ef@OI?mKkSda@K||o=i{5McGchDF??eAXyMVBk4+v2WYf=hipF66#dtWN zZivqjzNjzC#ytdFnE-zP~oz?8;Ma-Oq%(^^{gCRrd&<)s%Yo33+t}JIw%W!Mpg9hMBQgN`^0*XYzD(0xZ%H` U(ut(jbnqwq17iHD)7KFI0Lf?7aR2}S literal 0 HcmV?d00001 From 3d0898c59b4afe5ab9761fcfb3a03d3b164dbb67 Mon Sep 17 00:00:00 2001 From: JozsefA Date: Sat, 20 Mar 2021 13:16:20 -0700 Subject: [PATCH 02/14] Smooth harvesters, step sounds v1. --- .../components/actors/DrillActorInstance.java | 3 +- .../actors/HarvesterActorInstance.java | 77 ++++++++++++---- .../deployer/DeployerActorInstance.java | 6 +- .../components/deployer/DeployerInstance.java | 4 +- .../structureMovement/Contraption.java | 10 +++ .../ContraptionCollider.java | 54 ++++++++--- .../structureMovement/ContraptionWorld.java | 48 ++++++++++ .../render/ActorInstance.java | 11 +-- .../render/ContraptionKineticRenderer.java | 11 ++- .../render/ContraptionRenderDispatcher.java | 8 +- .../fluids/pipes/FluidValveInstance.java | 5 +- .../foundation/mixin/AddRemoveTileMixin.java | 14 ++- .../foundation/mixin/RenderHooksMixin.java | 1 + .../foundation/mixin/StepSoundMixin.java | 90 +++++++++++++++++++ .../instancing/InstancedTileRenderer.java | 2 +- .../create/flywheel/shaders/rotating.vert | 13 ++- src/main/resources/create.mixins.json | 12 +-- 17 files changed, 294 insertions(+), 75 deletions(-) create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionWorld.java create mode 100644 src/main/java/com/simibubi/create/foundation/mixin/StepSoundMixin.java diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillActorInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillActorInstance.java index 525b3e4bb..9fc849324 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillActorInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillActorInstance.java @@ -48,11 +48,10 @@ public class DrillActorInstance extends ActorInstance { } @Override - protected void tick() { + public void beginFrame() { drillHead.getInstance().setSpeed(getSpeed(facing)); } - @Override protected float getSpeed(Direction facing) { if (context.contraption.stalled || !VecHelper.isVecPointingTowards(context.relativeMotion, facing.getOpposite())) return context.getAnimationSpeed(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterActorInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterActorInstance.java index 16a07d2a6..bc6cae2c9 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterActorInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterActorInstance.java @@ -1,5 +1,6 @@ package com.simibubi.create.content.contraptions.components.actors; +import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; import com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance; @@ -7,45 +8,87 @@ import com.simibubi.create.content.contraptions.components.structureMovement.ren import com.simibubi.create.foundation.render.backend.instancing.InstanceKey; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial; +import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData; +import com.simibubi.create.foundation.utility.AngleHelper; +import com.simibubi.create.foundation.utility.AnimationTickHolder; +import com.simibubi.create.foundation.utility.MatrixStacker; +import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.block.BlockState; -import net.minecraft.client.renderer.Quaternion; -import net.minecraft.client.renderer.Vector3f; import net.minecraft.util.Direction; -import net.minecraft.world.LightType; +import net.minecraft.util.math.Vec3d; import static net.minecraft.state.properties.BlockStateProperties.HORIZONTAL_FACING; public class HarvesterActorInstance extends ActorInstance { + static double oneOverRadius = 16.0 / 6.5; + static float originOffset = 1 / 16f; + static Vec3d rotOffset = new Vec3d(0.5f, -2 * originOffset + 0.5f, originOffset + 0.5f); - InstanceKey harvester; + + InstanceKey harvester; private Direction facing; + private float horizontalAngle; + + private double rotation; + private double previousRotation; + public HarvesterActorInstance(ContraptionKineticRenderer modelManager, MovementContext context) { super(modelManager, context); - RenderMaterial> renderMaterial = modelManager.getActorMaterial(); + RenderMaterial> renderMaterial = modelManager.getBasicMaterial(); BlockState state = context.state; facing = state.get(HORIZONTAL_FACING); - float originOffset = 1 / 16f; - Vector3f rotOffset = new Vector3f(0.5f, -2 * originOffset + 0.5f, originOffset + 0.5f); harvester = renderMaterial.getModel(AllBlockPartials.HARVESTER_BLADE, state).createInstance(); - float horizontalAngle = facing.getHorizontalAngle() + ((facing.getAxis() == Direction.Axis.X) ? 180 : 0); + horizontalAngle = facing.getHorizontalAngle() + ((facing.getAxis() == Direction.Axis.X) ? 180 : 0); + harvester.getInstance() - .setPosition(context.localPos) - .setBlockLight(localBlockLight()) - .setRotationOffset(0) - .setRotationCenter(rotOffset) - .setRotationAxis(-1, 0, 0) - .setLocalRotation(new Quaternion(Vector3f.POSITIVE_Y, horizontalAngle, true)) - .setSpeed(getSpeed(facing)); + .setBlockLight(localBlockLight()); } @Override - protected void tick() { - harvester.getInstance().setSpeed(getSpeed(facing)); + public void tick() { + super.tick(); + + previousRotation = rotation; + + if (context.contraption.stalled || VecHelper.isVecPointingTowards(context.relativeMotion, facing.getOpposite())) + return; + + double arcLength = context.motion.length(); + + double radians = arcLength * oneOverRadius; + + float deg = AngleHelper.deg(radians); + + deg = (float) (((int) (deg * 3000)) / 3000); + + rotation += deg * 1.25; + + rotation %= 360; + } + + @Override + public void beginFrame() { + MatrixStack ms = new MatrixStack(); + MatrixStacker msr = MatrixStacker.of(ms); + + msr.translate(context.localPos) + .centre() + .rotateY(horizontalAngle) + .unCentre() + .translate(rotOffset) + .rotateX(getRotation()) + .translateBack(rotOffset); + + harvester.getInstance().setTransform(ms); + } + + private double getRotation() { + return AngleHelper.angleLerp(AnimationTickHolder.getPartialTicks(), previousRotation, rotation); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerActorInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerActorInstance.java index 6b307b176..eff34d5db 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerActorInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerActorInstance.java @@ -7,7 +7,6 @@ import com.simibubi.create.content.contraptions.components.structureMovement.Mov import com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance; import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionKineticRenderer; import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionProgram; -import com.simibubi.create.foundation.render.Compartment; import com.simibubi.create.foundation.render.backend.instancing.InstanceKey; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial; @@ -18,7 +17,6 @@ import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; -import net.minecraft.world.World; import static com.simibubi.create.content.contraptions.base.DirectionalAxisKineticBlock.AXIS_ALONG_FIRST_COORDINATE; import static com.simibubi.create.content.contraptions.base.DirectionalKineticBlock.FACING; @@ -39,7 +37,7 @@ public class DeployerActorInstance extends ActorInstance { public DeployerActorInstance(ContraptionKineticRenderer modelManager, MovementContext context) { super(modelManager, context); - RenderMaterial> mat = modelManager.basicMaterial(); + RenderMaterial> mat = modelManager.getBasicMaterial(); BlockState state = context.state; DeployerTileEntity.Mode mode = NBTHelper.readEnum(context.tileData, "Mode", DeployerTileEntity.Mode.class); @@ -73,7 +71,7 @@ public class DeployerActorInstance extends ActorInstance { } @Override - protected void tick() { + public void beginFrame() { double factor; if (context.contraption.stalled || context.position == null || context.data.contains("StationaryTimer")) { factor = MathHelper.sin(AnimationTickHolder.getRenderTime() * .5f) * .25f + .25f; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerInstance.java index bb12c93dd..86803cd0e 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerInstance.java @@ -50,7 +50,7 @@ public class DeployerInstance extends ShaftInstance implements ITickableInstance zRot = facing == Direction.UP ? 270 : facing == Direction.DOWN ? 90 : 0; zRotPole = rotatePole ? 90 : 0; - pole = modelManager.basicMaterial().getModel(AllBlockPartials.DEPLOYER_POLE, lastState).createInstance(); + pole = modelManager.getBasicMaterial().getModel(AllBlockPartials.DEPLOYER_POLE, lastState).createInstance(); updateHandPose(); relight(pos, pole.getInstance()); @@ -100,7 +100,7 @@ public class DeployerInstance extends ShaftInstance implements ITickableInstance if (hand != null) hand.delete(); - hand = modelManager.basicMaterial().getModel(currentHand, lastState).createInstance(); + hand = modelManager.getBasicMaterial().getModel(currentHand, lastState).createInstance(); relight(pos, hand.getInstance()); 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 660ced0b3..40ae4a7b0 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 @@ -131,6 +131,8 @@ public abstract class Contraption { public List maybeInstancedTileEntities; public List specialRenderedTileEntities; + protected ContraptionWorld world; + public Contraption() { blocks = new HashMap<>(); storage = new HashMap<>(); @@ -148,6 +150,14 @@ public abstract class Contraption { stabilizedSubContraptions = new HashMap<>(); } + public ContraptionWorld getContraptionWorld() { + if (world == null) { + world = new ContraptionWorld(entity.world, this); + } + + return world; + } + public abstract boolean assemble(World world, BlockPos pos) throws AssemblyException; public abstract boolean canBeStabilized(Direction facing, BlockPos localPos); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java index f9922623a..281cb1785 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java @@ -70,7 +70,6 @@ public class ContraptionCollider { Vec3d contraptionPosition = contraptionEntity.getPositionVec(); Vec3d contraptionMotion = contraptionPosition.subtract(contraptionEntity.getPrevPositionVec()); Vec3d anchorVec = contraptionEntity.getAnchorVec(); - Vec3d centerOfBlock = VecHelper.CENTER_OF_ORIGIN; ContraptionRotationState rotation = null; // After death, multiple refs to the client player may show up in the area @@ -103,19 +102,10 @@ public class ContraptionCollider { // Transform entity position and motion to local space Vec3d entityPosition = entity.getPositionVec(); AxisAlignedBB entityBounds = entity.getBoundingBox(); - Vec3d centerY = new Vec3d(0, entityBounds.getYSize() / 2, 0); Vec3d motion = entity.getMotion(); float yawOffset = rotation.getYawOffset(); - Vec3d position = entityPosition; - position = position.add(centerY); - position = position.subtract(centerOfBlock); - position = position.subtract(anchorVec); - position = VecHelper.rotate(position, -yawOffset, Axis.Y); - position = rotationMatrix.transform(position); - position = position.add(centerOfBlock); - position = position.subtract(centerY); - position = position.subtract(entityPosition); + Vec3d position = getWorldToLocalTranslation(entity, anchorVec, rotationMatrix, yawOffset); // Find all potential block shapes to collide with AxisAlignedBB localBB = entityBounds.offset(position) @@ -264,6 +254,48 @@ public class ContraptionCollider { } + public static Vec3d getWorldToLocalTranslation(Entity entity, AbstractContraptionEntity contraptionEntity) { + return getWorldToLocalTranslation(entity, contraptionEntity.getAnchorVec(), contraptionEntity.getRotationState()); + } + + public static Vec3d getWorldToLocalTranslation(Entity entity, Vec3d anchorVec, ContraptionRotationState rotation) { + return getWorldToLocalTranslation(entity, anchorVec, rotation.asMatrix(), rotation.getYawOffset()); + } + + public static Vec3d getWorldToLocalTranslation(Entity entity, Vec3d anchorVec, Matrix3d rotationMatrix, float yawOffset) { + Vec3d entityPosition = entity.getPositionVec(); + Vec3d centerY = new Vec3d(0, entity.getBoundingBox().getYSize() / 2, 0); + Vec3d position = entityPosition; + position = position.add(centerY); + position = position.subtract(VecHelper.CENTER_OF_ORIGIN); + position = position.subtract(anchorVec); + position = VecHelper.rotate(position, -yawOffset, Axis.Y); + position = rotationMatrix.transform(position); + position = position.add(VecHelper.CENTER_OF_ORIGIN); + position = position.subtract(centerY); + position = position.subtract(entityPosition); + return position; + } + + public static Vec3d getWorldToLocalTranslation(Vec3d entity, AbstractContraptionEntity contraptionEntity) { + return getWorldToLocalTranslation(entity, contraptionEntity.getAnchorVec(), contraptionEntity.getRotationState()); + } + + public static Vec3d getWorldToLocalTranslation(Vec3d inPos, Vec3d anchorVec, ContraptionRotationState rotation) { + return getWorldToLocalTranslation(inPos, anchorVec, rotation.asMatrix(), rotation.getYawOffset()); + } + + public static Vec3d getWorldToLocalTranslation(Vec3d inPos, Vec3d anchorVec, Matrix3d rotationMatrix, float yawOffset) { + Vec3d position = inPos; + position = position.subtract(VecHelper.CENTER_OF_ORIGIN); + position = position.subtract(anchorVec); + position = VecHelper.rotate(position, -yawOffset, Axis.Y); + position = rotationMatrix.transform(position); + position = position.add(VecHelper.CENTER_OF_ORIGIN); + position = position.subtract(inPos); + return position; + } + /** From Entity#getAllowedMovement **/ static Vec3d getAllowedMovement(Vec3d movement, Entity e) { AxisAlignedBB bb = e.getBoundingBox(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionWorld.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionWorld.java new file mode 100644 index 000000000..9ff74865a --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionWorld.java @@ -0,0 +1,48 @@ +package com.simibubi.create.content.contraptions.components.structureMovement; + +import com.simibubi.create.foundation.utility.worldWrappers.WrappedWorld; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; +import net.minecraft.world.gen.feature.template.Template; + +public class ContraptionWorld extends WrappedWorld { + final Contraption contraption; + + public ContraptionWorld(World world, Contraption contraption) { + super(world); + + this.contraption = contraption; + } + + + @Override + public BlockState getBlockState(BlockPos pos) { + Template.BlockInfo blockInfo = contraption.getBlocks().get(pos); + + if (blockInfo != null) + return blockInfo.state; + + return Blocks.AIR.getDefaultState(); + } + + @Override + public void playSound(PlayerEntity player, double x, double y, double z, SoundEvent soundIn, SoundCategory category, float volume, float pitch) { + + Vec3d worldPos = ContraptionCollider.getWorldToLocalTranslation(new Vec3d(x, y, z), this.contraption.entity); + + worldPos = worldPos.add(x, y, z); + + world.playSound(player, worldPos.x, worldPos.y, worldPos.z, soundIn, category, volume, pitch); + } + + @Override + public void playSound(double x, double y, double z, SoundEvent p_184134_7_, SoundCategory p_184134_8_, float p_184134_9_, float p_184134_10_, boolean p_184134_11_) { + world.playSound(x, y, z, p_184134_7_, p_184134_8_, p_184134_9_, p_184134_10_, p_184134_11_); + } +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ActorInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ActorInstance.java index 97d7ecc34..3991672c7 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ActorInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ActorInstance.java @@ -1,8 +1,6 @@ package com.simibubi.create.content.contraptions.components.structureMovement.render; import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; -import com.simibubi.create.foundation.utility.VecHelper; -import net.minecraft.util.Direction; import net.minecraft.world.LightType; public abstract class ActorInstance { @@ -14,14 +12,9 @@ public abstract class ActorInstance { this.context = context; } - protected void tick() { } + public void tick() { } - protected float getSpeed(Direction facing) { - if (context.contraption.stalled) - return 0; - - return !VecHelper.isVecPointingTowards(context.relativeMotion, facing.getOpposite()) ? context.getAnimationSpeed() : 0; - } + public void beginFrame() { } protected int localBlockLight() { return modelManager.contraption.renderWorld.getLightLevel(LightType.BLOCK, context.localPos); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionKineticRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionKineticRenderer.java index 56d968c93..80f2cd8d2 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionKineticRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionKineticRenderer.java @@ -10,21 +10,16 @@ import com.simibubi.create.content.contraptions.components.structureMovement.Mov import com.simibubi.create.content.contraptions.relays.belt.BeltInstancedModel; import com.simibubi.create.content.logistics.block.FlapInstancedModel; import com.simibubi.create.foundation.render.AllProgramSpecs; -import com.simibubi.create.foundation.render.backend.Backend; import com.simibubi.create.foundation.render.backend.RenderMaterials; import com.simibubi.create.foundation.render.backend.instancing.*; import com.simibubi.create.foundation.render.backend.instancing.impl.BasicInstancedModel; -import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.BlockPos; import net.minecraft.world.gen.feature.template.Template; -import org.apache.commons.lang3.tuple.MutablePair; import org.apache.commons.lang3.tuple.Pair; import javax.annotation.Nullable; import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; public class ContraptionKineticRenderer extends InstancedTileRenderer { @@ -46,12 +41,16 @@ public class ContraptionKineticRenderer extends InstancedTileRenderer(this, AllProgramSpecs.C_ACTOR, RotatingActorModel::new)); } + @Override + public void tick() { + actors.forEach(ActorInstance::tick); + } @Override public void beginFrame(double cameraX, double cameraY, double cameraZ) { super.beginFrame(cameraX, cameraY, cameraZ); - actors.forEach(ActorInstance::tick); + actors.forEach(ActorInstance::beginFrame); } @Nullable diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionRenderDispatcher.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionRenderDispatcher.java index aeff61450..1c880b362 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionRenderDispatcher.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionRenderDispatcher.java @@ -4,9 +4,7 @@ import java.util.List; import java.util.Random; import org.apache.commons.lang3.tuple.Pair; -import org.lwjgl.opengl.GL11; -import org.lwjgl.opengl.GL13; -import org.lwjgl.opengl.GL40; +import org.lwjgl.opengl.*; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllMovementBehaviours; @@ -81,8 +79,12 @@ public class ContraptionRenderDispatcher { } public static void tick() { + if (Minecraft.getInstance().isGamePaused()) return; + for (RenderedContraption contraption : renderers.values()) { contraption.getLighter().tick(contraption); + + contraption.kinetics.tick(); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/pipes/FluidValveInstance.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/pipes/FluidValveInstance.java index fac0a31ca..4e180a43d 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/pipes/FluidValveInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/pipes/FluidValveInstance.java @@ -5,8 +5,6 @@ import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; import com.simibubi.create.content.contraptions.relays.encased.ShaftInstance; -import com.simibubi.create.foundation.render.SuperByteBuffer; -import com.simibubi.create.foundation.render.backend.RenderMaterials; import com.simibubi.create.foundation.render.backend.instancing.ITickableInstance; import com.simibubi.create.foundation.render.backend.instancing.InstanceKey; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; @@ -14,7 +12,6 @@ import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData; import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.MatrixStacker; -import net.minecraft.block.BlockState; import net.minecraft.util.Direction; import net.minecraft.util.math.MathHelper; @@ -46,7 +43,7 @@ public class FluidValveInstance extends ShaftInstance implements ITickableInstan if (pipeAxis.isHorizontal() && shaftAxis == Direction.Axis.Z || pipeAxis.isVertical()) pointerRotationOffset = 90; - pointer = modelManager.basicMaterial().getModel(AllBlockPartials.FLUID_VALVE_POINTER, lastState).createInstance(); + pointer = modelManager.getBasicMaterial().getModel(AllBlockPartials.FLUID_VALVE_POINTER, lastState).createInstance(); updateLight(); transformPointer((FluidValveTileEntity) tile); diff --git a/src/main/java/com/simibubi/create/foundation/mixin/AddRemoveTileMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/AddRemoveTileMixin.java index 24321c5ad..795b607ab 100644 --- a/src/main/java/com/simibubi/create/foundation/mixin/AddRemoveTileMixin.java +++ b/src/main/java/com/simibubi/create/foundation/mixin/AddRemoveTileMixin.java @@ -33,7 +33,13 @@ public class AddRemoveTileMixin { * to a change in block state, even on the client. By hooking into this method, * we gain easy access to the information while having no impact on performance. */ - @Inject(at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/world/World;getTileEntity(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/tileentity/TileEntity;"), method = "removeTileEntity", locals = LocalCapture.CAPTURE_FAILHARD) + @Inject(at = @At( + value = "INVOKE_ASSIGN", + target = "Lnet/minecraft/world/World;getTileEntity(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/tileentity/TileEntity;" + ), + method = "removeTileEntity", + locals = LocalCapture.CAPTURE_FAILHARD + ) private void onRemoveTile(BlockPos pos, CallbackInfo ci, TileEntity te) { if (isRemote) { World thi = (World)(Object) this; @@ -49,7 +55,11 @@ public class AddRemoveTileMixin { } } - @Inject(at = @At(value = "INVOKE", target = "Ljava/util/Set;clear()V", ordinal = 0), method = "tickBlockEntities") + @Inject(at = @At( + value = "INVOKE", + target = "Ljava/util/Set;clear()V", ordinal = 0 + ), + method = "tickBlockEntities") private void onChunkUnload(CallbackInfo ci) { if (isRemote) { World thi = (World)(Object) this; 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 2bdf89fb7..8c5b51e66 100644 --- a/src/main/java/com/simibubi/create/foundation/mixin/RenderHooksMixin.java +++ b/src/main/java/com/simibubi/create/foundation/mixin/RenderHooksMixin.java @@ -2,6 +2,7 @@ package com.simibubi.create.foundation.mixin; import com.simibubi.create.foundation.render.KineticRenderer; import net.minecraft.client.renderer.*; +import net.minecraft.client.renderer.texture.AtlasTexture; import net.minecraft.util.math.Vec3d; import org.lwjgl.opengl.GL20; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/com/simibubi/create/foundation/mixin/StepSoundMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/StepSoundMixin.java new file mode 100644 index 000000000..5a5cff258 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/mixin/StepSoundMixin.java @@ -0,0 +1,90 @@ +package com.simibubi.create.foundation.mixin; + +import com.simibubi.create.content.contraptions.components.structureMovement.*; +import net.minecraft.block.BlockState; +import net.minecraft.entity.Entity; +import net.minecraft.entity.MoverType; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; +import net.minecraft.world.gen.feature.template.Template; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.lang.ref.Reference; +import java.util.Set; +import java.util.stream.Collectors; + +@Mixin(Entity.class) +public abstract class StepSoundMixin { + + @Shadow public boolean collided; + + @Shadow public World world; + + @Shadow public abstract BlockPos getPosition(); + + @Shadow public abstract Vec3d getPositionVec(); + + @Shadow private float nextStepDistance; + + @Shadow protected abstract float determineNextStepDistance(); + + @Shadow public abstract AxisAlignedBB getBoundingBox(); + + @Shadow protected abstract void playStepSound(BlockPos p_180429_1_, BlockState p_180429_2_); + + @Inject(at = @At( + value = "JUMP", + opcode = 154, //IFNE + ordinal = 4 + ), + method = "move" + ) + private void movementMixin(MoverType mover, Vec3d movement, CallbackInfo ci) { + Entity thi = (Entity) (Object) this; + + World entityWorld = world; + + Set contraptions = ContraptionHandler.loadedContraptions.get(entityWorld) + .values() + .stream() + .map(Reference::get) + .filter(cEntity -> cEntity != null && cEntity.collidingEntities.containsKey(thi)).collect(Collectors.toSet()); + + contraptions.addAll(entityWorld.getEntitiesWithinAABB(AbstractContraptionEntity.class, getBoundingBox().grow(1f))); + + Vec3d worldPos = thi.getPositionVector().add(0, -0.2, 0); + + boolean stepped = false; + for (AbstractContraptionEntity cEntity : contraptions) { + Vec3d localPos = ContraptionCollider.getWorldToLocalTranslation(worldPos, cEntity); + + localPos = worldPos.add(localPos); + + BlockPos blockPos = new BlockPos(localPos); + Contraption contraption = cEntity.getContraption(); + Template.BlockInfo info = contraption.getBlocks().get(blockPos); + + if (info != null) { + BlockState blockstate = info.state; + + this.world = contraption.getContraptionWorld(); + + this.playStepSound(blockPos, blockstate); + + stepped = true; + } + } + + if (stepped) + this.nextStepDistance = this.determineNextStepDistance(); + + world = entityWorld; + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java index 5871c5d8e..172431730 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java @@ -69,7 +69,7 @@ public abstract class InstancedTileRenderer

{ return (RenderMaterial) materials.get(materialType); } - public RenderMaterial> basicMaterial() { + public RenderMaterial> getBasicMaterial() { return getMaterial(RenderMaterials.MODELS); } diff --git a/src/main/resources/assets/create/flywheel/shaders/rotating.vert b/src/main/resources/assets/create/flywheel/shaders/rotating.vert index 53d258bfd..f183276f9 100644 --- a/src/main/resources/assets/create/flywheel/shaders/rotating.vert +++ b/src/main/resources/assets/create/flywheel/shaders/rotating.vert @@ -39,13 +39,18 @@ uniform vec3 uCameraPos; varying float FragDistance; #endif -void main() { +mat4 kineticRotation() { float degrees = aOffset + uTime * aSpeed * 3./10.; - vec4 kineticRot = quat(aAxis, degrees); + float angle = fract(degrees / 360.) * PI * 2.; - vec4 worldPos = vec4(rotateVertexByQuat(aPos - .5, kineticRot) + aInstancePos + .5, 1.); + return rotate(aAxis, angle); +} - vec3 norm = rotateVertexByQuat(aNormal, kineticRot); +void main() { + mat4 kineticRotation = kineticRotation(); + vec4 worldPos = kineticRotation * vec4(aPos - .5, 1.) + vec4(aInstancePos + .5, 0.); + + vec3 norm = modelToNormal(kineticRotation) * aNormal; #ifdef CONTRAPTION worldPos = uModel * worldPos; diff --git a/src/main/resources/create.mixins.json b/src/main/resources/create.mixins.json index 37137f8a6..285af7c77 100644 --- a/src/main/resources/create.mixins.json +++ b/src/main/resources/create.mixins.json @@ -3,17 +3,9 @@ "package": "com.simibubi.create.foundation.mixin", "compatibilityLevel": "JAVA_8", "refmap": "create.refmap.json", - "client": [ - "AddRemoveTileMixin", - "ShaderCloseMixin", - "CancelTileEntityRenderMixin", - "LightUpdateMixin", - "RenderHooksMixin", - "FogColorTrackerMixin", - "NetworkLightUpdateMixin" - ], + "client": ["AddRemoveTileMixin", "CancelTileEntityRenderMixin", "FogColorTrackerMixin", "LightUpdateMixin", "NetworkLightUpdateMixin", "RenderHooksMixin", "ShaderCloseMixin"], "injectors": { "defaultRequire": 1 }, - "minVersion": "0.8" + "minVersion": "0.8", "mixins": ["StepSoundMixin"] } \ No newline at end of file From 9df9a9918572f0b8c30c89dca0830f2cb515f030 Mon Sep 17 00:00:00 2001 From: grimmauld Date: Sat, 20 Mar 2021 22:49:42 +0100 Subject: [PATCH 03/14] We have SPONGE! (and not only for mixins...) --- .../content/contraptions/processing/BasinBlock.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/com/simibubi/create/content/contraptions/processing/BasinBlock.java b/src/main/java/com/simibubi/create/content/contraptions/processing/BasinBlock.java index d11a5a6fc..eaaba35bf 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/processing/BasinBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/processing/BasinBlock.java @@ -22,6 +22,7 @@ import net.minecraft.entity.item.ItemEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemUseContext; +import net.minecraft.item.Items; import net.minecraft.state.DirectionProperty; import net.minecraft.state.StateContainer.Builder; import net.minecraft.state.properties.BlockStateProperties; @@ -36,6 +37,10 @@ import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.world.IBlockReader; import net.minecraft.world.IWorldReader; import net.minecraft.world.World; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.capability.CapabilityFluidHandler; +import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.ItemHandlerHelper; import net.minecraftforge.items.ItemStackHandler; @@ -95,6 +100,11 @@ public class BasinBlock extends Block implements ITE, IWrenchab if (EmptyingByBasin.canItemBeEmptied(worldIn, heldItem) || GenericItemFilling.canItemBeFilled(worldIn, heldItem)) return ActionResultType.SUCCESS; + if (heldItem.getItem().equals(Items.SPONGE) && + !te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY).map(iFluidHandler -> + iFluidHandler.drain(Integer.MAX_VALUE, IFluidHandler.FluidAction.EXECUTE)).orElse(FluidStack.EMPTY).isEmpty()) { + return ActionResultType.SUCCESS; + } return ActionResultType.PASS; } From f6cfd377a7afab0d73818a83e88ef6248af96141 Mon Sep 17 00:00:00 2001 From: JozsefA Date: Sat, 20 Mar 2021 16:30:09 -0700 Subject: [PATCH 04/14] Ticking things. - Differentiate tickable and dynamic instances. - Instanced repeaters. --- .../com/simibubi/create/AllTileEntities.java | 3 + .../contraptions/base/HalfShaftInstance.java | 8 +-- .../base/HorizontalHalfShaftInstance.java | 6 +- .../base/KineticTileInstance.java | 4 +- .../base/SingleRotatingInstance.java | 6 +- .../crafter/MechanicalCrafterInstance.java | 8 +-- .../components/crank/HandCrankInstance.java | 16 ++--- .../components/deployer/DeployerInstance.java | 12 ++-- .../components/fan/FanInstance.java | 17 ++---- .../components/flywheel/FlyWheelInstance.java | 34 +++++------ .../flywheel/engine/EngineInstance.java | 12 +--- .../components/mixer/MixerInstance.java | 16 ++--- .../components/press/PressInstance.java | 13 ++--- .../components/saw/SawInstance.java | 8 +-- .../chassis/StickerInstance.java | 16 ++--- .../gantry/GantryCarriageInstance.java | 19 +++--- .../fluids/pipes/FluidValveInstance.java | 12 ++-- .../relays/belt/BeltInstance.java | 16 +++-- .../relays/encased/SplitShaftInstance.java | 10 ++-- .../relays/gauge/GaugeInstance.java | 16 ++--- .../relays/gearbox/GearboxInstance.java | 8 +-- .../belts/tunnel/BeltTunnelInstance.java | 9 +-- .../diodes/AdjustableRepeaterInstance.java | 58 +++++++++++++++++++ .../diodes/AdjustableRepeaterTileEntity.java | 4 +- .../block/funnel/FunnelInstance.java | 13 ++--- .../block/mechanicalArm/ArmInstance.java | 26 ++++----- .../block/redstone/AnalogLeverInstance.java | 17 ++---- .../block/SchematicannonInstance.java | 20 ++----- .../backend/instancing/IDynamicInstance.java | 8 +++ .../backend/instancing/ITickableInstance.java | 4 +- .../instancing/InstancedTileRenderer.java | 22 +++++-- .../instancing/TileEntityInstance.java | 9 ++- .../ColoredOverlayTileEntityRenderer.java | 13 +++-- 33 files changed, 221 insertions(+), 242 deletions(-) create mode 100644 src/main/java/com/simibubi/create/content/logistics/block/diodes/AdjustableRepeaterInstance.java create mode 100644 src/main/java/com/simibubi/create/foundation/render/backend/instancing/IDynamicInstance.java diff --git a/src/main/java/com/simibubi/create/AllTileEntities.java b/src/main/java/com/simibubi/create/AllTileEntities.java index 88b073b28..2a10eda64 100644 --- a/src/main/java/com/simibubi/create/AllTileEntities.java +++ b/src/main/java/com/simibubi/create/AllTileEntities.java @@ -97,6 +97,7 @@ import com.simibubi.create.content.logistics.block.chute.SmartChuteTileEntity; import com.simibubi.create.content.logistics.block.depot.DepotRenderer; import com.simibubi.create.content.logistics.block.depot.DepotTileEntity; import com.simibubi.create.content.logistics.block.diodes.AdjustablePulseRepeaterTileEntity; +import com.simibubi.create.content.logistics.block.diodes.AdjustableRepeaterInstance; import com.simibubi.create.content.logistics.block.diodes.AdjustableRepeaterRenderer; import com.simibubi.create.content.logistics.block.diodes.AdjustableRepeaterTileEntity; import com.simibubi.create.content.logistics.block.funnel.FunnelInstance; @@ -595,6 +596,7 @@ public class AllTileEntities { public static final TileEntityEntry ADJUSTABLE_REPEATER = Create.registrate() .tileEntity("adjustable_repeater", AdjustableRepeaterTileEntity::new) + .instance(() -> AdjustableRepeaterInstance::new) .validBlocks(AllBlocks.ADJUSTABLE_REPEATER) .renderer(() -> AdjustableRepeaterRenderer::new) .register(); @@ -602,6 +604,7 @@ public class AllTileEntities { public static final TileEntityEntry ADJUSTABLE_PULSE_REPEATER = Create.registrate() .tileEntity("adjustable_pulse_repeater", AdjustablePulseRepeaterTileEntity::new) + .instance(() -> AdjustableRepeaterInstance::new) .validBlocks(AllBlocks.ADJUSTABLE_PULSE_REPEATER) .renderer(() -> AdjustableRepeaterRenderer::new) .register(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/HalfShaftInstance.java b/src/main/java/com/simibubi/create/content/contraptions/base/HalfShaftInstance.java index 6002f3140..7b5249963 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/HalfShaftInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/HalfShaftInstance.java @@ -2,14 +2,10 @@ package com.simibubi.create.content.contraptions.base; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; -import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderRegistry; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; import net.minecraft.state.properties.BlockStateProperties; -import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; public class HalfShaftInstance extends SingleRotatingInstance { public HalfShaftInstance(InstancedTileRenderer modelManager, KineticTileEntity tile) { @@ -19,10 +15,10 @@ public class HalfShaftInstance extends SingleRotatingInstance { @Override protected InstancedModel getModel() { Direction dir = getShaftDirection(); - return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(modelManager, lastState, dir); + return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(modelManager, blockState, dir); } protected Direction getShaftDirection() { - return lastState.get(BlockStateProperties.FACING); + return blockState.get(BlockStateProperties.FACING); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/HorizontalHalfShaftInstance.java b/src/main/java/com/simibubi/create/content/contraptions/base/HorizontalHalfShaftInstance.java index af5bfec0f..d5a21d468 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/HorizontalHalfShaftInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/HorizontalHalfShaftInstance.java @@ -1,13 +1,9 @@ package com.simibubi.create.content.contraptions.base; -import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderRegistry; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; import net.minecraft.state.properties.BlockStateProperties; -import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; public class HorizontalHalfShaftInstance extends HalfShaftInstance { @@ -17,6 +13,6 @@ public class HorizontalHalfShaftInstance extends HalfShaftInstance { @Override protected Direction getShaftDirection() { - return lastState.get(BlockStateProperties.HORIZONTAL_FACING).getOpposite(); + return blockState.get(BlockStateProperties.HORIZONTAL_FACING).getOpposite(); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileInstance.java b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileInstance.java index be44b81f3..9c94b9062 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileInstance.java @@ -37,7 +37,7 @@ public abstract class KineticTileInstance extends T } protected float getRotationOffset(final Direction.Axis axis) { - float offset = CogWheelBlock.isLargeCog(lastState) ? 11.25f : 0; + float offset = CogWheelBlock.isLargeCog(blockState) ? 11.25f : 0; double d = (((axis == Direction.Axis.X) ? 0 : pos.getX()) + ((axis == Direction.Axis.Y) ? 0 : pos.getY()) + ((axis == Direction.Axis.Z) ? 0 : pos.getZ())) % 2; if (d == 0) { @@ -52,7 +52,7 @@ public abstract class KineticTileInstance extends T } public Direction.Axis getRotationAxis() { - return ((IRotate) lastState.getBlock()).getRotationAxis(lastState); + return ((IRotate) blockState.getBlock()).getRotationAxis(blockState); } protected final RenderMaterial> rotatingMaterial() { diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/SingleRotatingInstance.java b/src/main/java/com/simibubi/create/content/contraptions/base/SingleRotatingInstance.java index 44e9c93d0..ed80fdc9c 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/SingleRotatingInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/SingleRotatingInstance.java @@ -19,13 +19,13 @@ public class SingleRotatingInstance extends KineticTileInstance getModel() { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/crafter/MechanicalCrafterInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/crafter/MechanicalCrafterInstance.java index 3cdf21954..adb9fd3e2 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/crafter/MechanicalCrafterInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/crafter/MechanicalCrafterInstance.java @@ -8,14 +8,10 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.RotatingData; import com.simibubi.create.content.contraptions.base.SingleRotatingInstance; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; -import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderRegistry; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; import com.simibubi.create.foundation.utility.MatrixStacker; -import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; public class MechanicalCrafterInstance extends SingleRotatingInstance { @@ -25,7 +21,7 @@ public class MechanicalCrafterInstance extends SingleRotatingInstance { @Override protected InstancedModel getModel() { - Direction facing = lastState.get(MechanicalCrafterBlock.HORIZONTAL_FACING); + Direction facing = blockState.get(MechanicalCrafterBlock.HORIZONTAL_FACING); Supplier ms = () -> { MatrixStack stack = new MatrixStack(); @@ -39,6 +35,6 @@ public class MechanicalCrafterInstance extends SingleRotatingInstance { stacker.unCentre(); return stack; }; - return rotatingMaterial().getModel(AllBlockPartials.SHAFTLESS_COGWHEEL, lastState, facing, ms); + return rotatingMaterial().getModel(AllBlockPartials.SHAFTLESS_COGWHEEL, blockState, facing, ms); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/crank/HandCrankInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/crank/HandCrankInstance.java index cb5240516..309be16a0 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/crank/HandCrankInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/crank/HandCrankInstance.java @@ -4,21 +4,15 @@ import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.SingleRotatingInstance; -import com.simibubi.create.content.logistics.block.redstone.AnalogLeverInstance; -import com.simibubi.create.content.logistics.block.redstone.AnalogLeverTileEntity; -import com.simibubi.create.foundation.render.backend.RenderMaterials; import com.simibubi.create.foundation.render.backend.instancing.*; import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData; import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.MatrixStacker; import net.minecraft.block.Block; import net.minecraft.state.properties.BlockStateProperties; -import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; -public class HandCrankInstance extends SingleRotatingInstance implements ITickableInstance { +public class HandCrankInstance extends SingleRotatingInstance implements IDynamicInstance { private InstanceKey crank; private Direction facing; @@ -31,22 +25,22 @@ public class HandCrankInstance extends SingleRotatingInstance implements ITickab protected void init() { super.init(); - Block block = lastState.getBlock(); + Block block = blockState.getBlock(); AllBlockPartials renderedHandle = null; if (block instanceof HandCrankBlock) renderedHandle = ((HandCrankBlock) block).getRenderedHandle(); if (renderedHandle == null) return; - facing = lastState.get(BlockStateProperties.FACING); - InstancedModel model = renderedHandle.renderOnDirectionalSouthModel(modelManager, lastState, facing.getOpposite()); + facing = blockState.get(BlockStateProperties.FACING); + InstancedModel model = renderedHandle.renderOnDirectionalSouthModel(modelManager, blockState, facing.getOpposite()); crank = model.createInstance(); updateLight(); } @Override - public void tick() { + public void beginFrame() { if (crank == null) return; HandCrankTileEntity crankTile = (HandCrankTileEntity) tile; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerInstance.java index 86803cd0e..4cd49184a 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerInstance.java @@ -16,7 +16,7 @@ import net.minecraft.util.math.Vec3d; import static com.simibubi.create.content.contraptions.base.DirectionalAxisKineticBlock.AXIS_ALONG_FIRST_COORDINATE; import static com.simibubi.create.content.contraptions.base.DirectionalKineticBlock.FACING; -public class DeployerInstance extends ShaftInstance implements ITickableInstance { +public class DeployerInstance extends ShaftInstance implements IDynamicInstance { DeployerTileEntity tile; @@ -42,22 +42,22 @@ public class DeployerInstance extends ShaftInstance implements ITickableInstance super.init(); this.tile = (DeployerTileEntity) super.tile; - facing = lastState.get(FACING); + facing = blockState.get(FACING); - boolean rotatePole = lastState.get(AXIS_ALONG_FIRST_COORDINATE) ^ facing.getAxis() == Direction.Axis.Z; + boolean rotatePole = blockState.get(AXIS_ALONG_FIRST_COORDINATE) ^ facing.getAxis() == Direction.Axis.Z; yRot = AngleHelper.horizontalAngle(facing); zRot = facing == Direction.UP ? 270 : facing == Direction.DOWN ? 90 : 0; zRotPole = rotatePole ? 90 : 0; - pole = modelManager.getBasicMaterial().getModel(AllBlockPartials.DEPLOYER_POLE, lastState).createInstance(); + pole = modelManager.getBasicMaterial().getModel(AllBlockPartials.DEPLOYER_POLE, blockState).createInstance(); updateHandPose(); relight(pos, pole.getInstance()); } @Override - public void tick() { + public void beginFrame() { boolean newHand = updateHandPose(); @@ -100,7 +100,7 @@ public class DeployerInstance extends ShaftInstance implements ITickableInstance if (hand != null) hand.delete(); - hand = modelManager.getBasicMaterial().getModel(currentHand, lastState).createInstance(); + hand = modelManager.getBasicMaterial().getModel(currentHand, blockState).createInstance(); relight(pos, hand.getInstance()); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/fan/FanInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/fan/FanInstance.java index 0416c1564..b2ba34186 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/fan/FanInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/fan/FanInstance.java @@ -8,16 +8,11 @@ import com.simibubi.create.content.contraptions.base.KineticTileInstance; import com.simibubi.create.content.contraptions.base.RotatingData; import com.simibubi.create.foundation.render.backend.instancing.InstanceKey; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; -import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderRegistry; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; -import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; -import net.minecraft.world.LightType; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; public class FanInstance extends KineticTileInstance { @@ -30,13 +25,13 @@ public class FanInstance extends KineticTileInstance { @Override protected void init() { - final Direction direction = lastState.get(FACING); - final Direction.Axis axis = ((IRotate) lastState.getBlock()).getRotationAxis(lastState); + final Direction direction = blockState.get(FACING); + final Direction.Axis axis = ((IRotate) blockState.getBlock()).getRotationAxis(blockState); InstancedModel shaftHalf = - AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(modelManager, lastState, direction.getOpposite()); + AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(modelManager, blockState, direction.getOpposite()); InstancedModel fanInner = - AllBlockPartials.ENCASED_FAN_INNER.renderOnDirectionalSouthRotating(modelManager, lastState, direction.getOpposite()); + AllBlockPartials.ENCASED_FAN_INNER.renderOnDirectionalSouthRotating(modelManager, blockState, direction.getOpposite()); shaft = shaftHalf.createInstance(); shaft.getInstance() @@ -67,7 +62,7 @@ public class FanInstance extends KineticTileInstance { @Override protected void onUpdate() { - Direction.Axis axis = lastState.get(FACING).getAxis(); + Direction.Axis axis = blockState.get(FACING).getAxis(); updateRotation(shaft, axis); fan.getInstance() @@ -79,7 +74,7 @@ public class FanInstance extends KineticTileInstance { @Override public void updateLight() { - final Direction direction = lastState.get(FACING); + final Direction direction = blockState.get(FACING); BlockPos behind = pos.offset(direction.getOpposite()); relight(behind, shaft.getInstance()); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlyWheelInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlyWheelInstance.java index bb2279a6f..132e4713d 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlyWheelInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlyWheelInstance.java @@ -1,17 +1,14 @@ package com.simibubi.create.content.contraptions.components.flywheel; -import java.util.ArrayList; import java.util.Collections; import java.util.List; -import com.google.common.collect.Collections2; import com.google.common.collect.Lists; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.IRotate; import com.simibubi.create.content.contraptions.base.KineticTileInstance; import com.simibubi.create.content.contraptions.base.RotatingData; -import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.render.backend.RenderMaterials; import com.simibubi.create.foundation.render.backend.instancing.*; @@ -20,16 +17,11 @@ import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.MatrixStacker; import net.minecraft.state.properties.BlockStateProperties; -import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; import net.minecraft.util.Rotation; -import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; -import net.minecraft.world.LightType; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; -public class FlyWheelInstance extends KineticTileInstance implements ITickableInstance { +public class FlyWheelInstance extends KineticTileInstance implements IDynamicInstance { protected Direction facing; protected boolean connectedLeft; @@ -57,16 +49,16 @@ public class FlyWheelInstance extends KineticTileInstance im @Override protected void init() { - facing = lastState.get(BlockStateProperties.HORIZONTAL_FACING); + facing = blockState.get(BlockStateProperties.HORIZONTAL_FACING); - Direction.Axis axis = ((IRotate) lastState.getBlock()).getRotationAxis(lastState); + Direction.Axis axis = ((IRotate) blockState.getBlock()).getRotationAxis(blockState); shaft = setup(shaftModel().createInstance(), tile.getSpeed(), axis); - wheel = AllBlockPartials.FLYWHEEL.renderOnHorizontalModel(modelManager, lastState.rotate(Rotation.CLOCKWISE_90)).createInstance(); + wheel = AllBlockPartials.FLYWHEEL.renderOnHorizontalModel(modelManager, blockState.rotate(Rotation.CLOCKWISE_90)).createInstance(); - connection = FlywheelBlock.getConnection(lastState); + connection = FlywheelBlock.getConnection(blockState); if (connection != null) { - connectedLeft = lastState.get(FlywheelBlock.CONNECTION) == FlywheelBlock.ConnectionState.LEFT; + connectedLeft = blockState.get(FlywheelBlock.CONNECTION) == FlywheelBlock.ConnectionState.LEFT; boolean flipAngle = connection.getAxis() == Direction.Axis.X ^ connection.getAxisDirection() == Direction.AxisDirection.NEGATIVE; @@ -74,10 +66,10 @@ public class FlyWheelInstance extends KineticTileInstance im RenderMaterial> mat = modelManager.getMaterial(RenderMaterials.MODELS); - upperRotating = mat.getModel(AllBlockPartials.FLYWHEEL_UPPER_ROTATING, lastState).createInstance(); - lowerRotating = mat.getModel(AllBlockPartials.FLYWHEEL_LOWER_ROTATING, lastState).createInstance(); - upperSliding = mat.getModel(AllBlockPartials.FLYWHEEL_UPPER_SLIDING, lastState).createInstance(); - lowerSliding = mat.getModel(AllBlockPartials.FLYWHEEL_LOWER_SLIDING, lastState).createInstance(); + upperRotating = mat.getModel(AllBlockPartials.FLYWHEEL_UPPER_ROTATING, blockState).createInstance(); + lowerRotating = mat.getModel(AllBlockPartials.FLYWHEEL_LOWER_ROTATING, blockState).createInstance(); + upperSliding = mat.getModel(AllBlockPartials.FLYWHEEL_UPPER_SLIDING, blockState).createInstance(); + lowerSliding = mat.getModel(AllBlockPartials.FLYWHEEL_LOWER_SLIDING, blockState).createInstance(); connectors = Lists.newArrayList(upperRotating, lowerRotating, upperSliding, lowerSliding); } else { @@ -89,7 +81,7 @@ public class FlyWheelInstance extends KineticTileInstance im } @Override - public void tick() { + public void beginFrame() { float partialTicks = AnimationTickHolder.getPartialTicks(); @@ -144,7 +136,7 @@ public class FlyWheelInstance extends KineticTileInstance im @Override protected void onUpdate() { - Direction.Axis axis = ((IRotate) lastState.getBlock()).getRotationAxis(lastState); + Direction.Axis axis = ((IRotate) blockState.getBlock()).getRotationAxis(blockState); updateRotation(shaft, axis); } @@ -167,7 +159,7 @@ public class FlyWheelInstance extends KineticTileInstance im } protected InstancedModel shaftModel() { - return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(modelManager, lastState, facing.getOpposite()); + return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(modelManager, blockState, facing.getOpposite()); } protected void transformConnector(MatrixStacker ms, boolean upper, boolean rotating, float angle, boolean flip) { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/engine/EngineInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/engine/EngineInstance.java index cac76a426..ebee39e59 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/engine/EngineInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/engine/EngineInstance.java @@ -4,7 +4,6 @@ import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.foundation.render.backend.RenderMaterials; import com.simibubi.create.foundation.render.backend.instancing.InstanceKey; -import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderRegistry; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; import com.simibubi.create.foundation.render.backend.instancing.TileEntityInstance; import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData; @@ -12,12 +11,7 @@ import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.MatrixStacker; import net.minecraft.block.Block; import net.minecraft.state.properties.BlockStateProperties; -import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.LightType; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; public class EngineInstance extends TileEntityInstance { @@ -29,7 +23,7 @@ public class EngineInstance extends TileEntityInstance { @Override protected void init() { - Block block = lastState + Block block = blockState .getBlock(); if (!(block instanceof EngineBlock)) return; @@ -37,9 +31,9 @@ public class EngineInstance extends TileEntityInstance { EngineBlock engineBlock = (EngineBlock) block; AllBlockPartials frame = engineBlock.getFrameModel(); - Direction facing = lastState.get(BlockStateProperties.HORIZONTAL_FACING); + Direction facing = blockState.get(BlockStateProperties.HORIZONTAL_FACING); - this.frame = modelManager.getMaterial(RenderMaterials.MODELS).getModel(frame, lastState).createInstance(); + this.frame = modelManager.getMaterial(RenderMaterials.MODELS).getModel(frame, blockState).createInstance(); float angle = AngleHelper.rad(AngleHelper.horizontalAngle(facing)); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MixerInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MixerInstance.java index d8325b5b0..bd9ce61da 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MixerInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MixerInstance.java @@ -5,22 +5,14 @@ import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.RotatingData; import com.simibubi.create.content.contraptions.base.ShaftlessCogInstance; -import com.simibubi.create.content.contraptions.components.press.MechanicalPressTileEntity; import com.simibubi.create.foundation.render.backend.RenderMaterials; import com.simibubi.create.foundation.render.backend.instancing.*; import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData; import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.MatrixStacker; -import net.minecraft.client.renderer.Vector3d; -import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; -import net.minecraft.world.LightType; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; -public class MixerInstance extends ShaftlessCogInstance implements ITickableInstance { +public class MixerInstance extends ShaftlessCogInstance implements IDynamicInstance { private InstanceKey mixerHead; private InstanceKey mixerPole; @@ -33,14 +25,14 @@ public class MixerInstance extends ShaftlessCogInstance implements ITickableInst protected void init() { super.init(); - mixerHead = rotatingMaterial().getModel(AllBlockPartials.MECHANICAL_MIXER_HEAD, lastState) + mixerHead = rotatingMaterial().getModel(AllBlockPartials.MECHANICAL_MIXER_HEAD, blockState) .createInstance(); mixerHead.getInstance() .setRotationAxis(Direction.Axis.Y); mixerPole = modelManager.getMaterial(RenderMaterials.MODELS) - .getModel(AllBlockPartials.MECHANICAL_MIXER_POLE, lastState) + .getModel(AllBlockPartials.MECHANICAL_MIXER_POLE, blockState) .createInstance(); @@ -53,7 +45,7 @@ public class MixerInstance extends ShaftlessCogInstance implements ITickableInst } @Override - public void tick() { + public void beginFrame() { MechanicalMixerTileEntity mixer = (MechanicalMixerTileEntity) tile; float renderedHeadOffset = getRenderedHeadOffset(mixer); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/press/PressInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/press/PressInstance.java index 8af6fa19f..831539c69 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/press/PressInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/press/PressInstance.java @@ -5,19 +5,14 @@ import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.relays.encased.ShaftInstance; import com.simibubi.create.foundation.render.backend.RenderMaterials; -import com.simibubi.create.foundation.render.backend.instancing.ITickableInstance; +import com.simibubi.create.foundation.render.backend.instancing.IDynamicInstance; import com.simibubi.create.foundation.render.backend.instancing.InstanceKey; -import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderRegistry; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData; import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.MatrixStacker; -import net.minecraft.tileentity.TileEntityType; -import net.minecraft.world.LightType; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; -public class PressInstance extends ShaftInstance implements ITickableInstance { +public class PressInstance extends ShaftInstance implements IDynamicInstance { private InstanceKey pressHead; @@ -30,7 +25,7 @@ public class PressInstance extends ShaftInstance implements ITickableInstance { super.init(); pressHead = modelManager.getMaterial(RenderMaterials.MODELS) - .getModel(AllBlockPartials.MECHANICAL_PRESS_HEAD, lastState) + .getModel(AllBlockPartials.MECHANICAL_PRESS_HEAD, blockState) .createInstance(); updateLight(); @@ -38,7 +33,7 @@ public class PressInstance extends ShaftInstance implements ITickableInstance { } @Override - public void tick() { + public void beginFrame() { MechanicalPressTileEntity press = (MechanicalPressTileEntity) tile; if (!press.running) return; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawInstance.java index 7cff62d3a..7b06a384a 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawInstance.java @@ -8,13 +8,9 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; import com.simibubi.create.content.contraptions.base.RotatingData; import com.simibubi.create.content.contraptions.base.SingleRotatingInstance; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; -import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderRegistry; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; -import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Rotation; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; public class SawInstance extends SingleRotatingInstance { @@ -24,8 +20,8 @@ public class SawInstance extends SingleRotatingInstance { @Override protected InstancedModel getModel() { - if (lastState.get(FACING).getAxis().isHorizontal()) - return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(modelManager, lastState.rotate(tile.getWorld(), tile.getPos(), Rotation.CLOCKWISE_180)); + if (blockState.get(FACING).getAxis().isHorizontal()) + return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(modelManager, blockState.rotate(tile.getWorld(), tile.getPos(), Rotation.CLOCKWISE_180)); else return rotatingMaterial().getModel(KineticTileEntityRenderer.KINETIC_TILE, shaft(getRotationAxis())); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerInstance.java index 6e692fcb9..7499176f5 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerInstance.java @@ -9,13 +9,9 @@ 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.tileentity.TileEntityType; import net.minecraft.util.Direction; -import net.minecraft.world.LightType; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; -public class StickerInstance extends TileEntityInstance implements ITickableInstance { +public class StickerInstance extends TileEntityInstance implements IDynamicInstance { float lastOffset = Float.NaN; @@ -27,24 +23,24 @@ public class StickerInstance extends TileEntityInstance imple @Override protected void init() { - head = modelManager.getMaterial(RenderMaterials.MODELS).getModel(AllBlockPartials.STICKER_HEAD, lastState).createInstance(); + head = modelManager.getMaterial(RenderMaterials.MODELS).getModel(AllBlockPartials.STICKER_HEAD, blockState).createInstance(); updateLight(); } @Override - public void tick() { - lastState = world.getBlockState(pos); + public void beginFrame() { + blockState = world.getBlockState(pos); float offset = tile.piston.getValue(AnimationTickHolder.getPartialTicks()); if (tile.getWorld() != Minecraft.getInstance().world) - offset = lastState.get(StickerBlock.EXTENDED) ? 1 : 0; + offset = blockState.get(StickerBlock.EXTENDED) ? 1 : 0; if (Math.abs(offset - lastOffset) < 1e-4) return; - Direction facing = lastState.get(StickerBlock.FACING); + Direction facing = blockState.get(StickerBlock.FACING); MatrixStack stack = new MatrixStack(); MatrixStacker.of(stack) .translate(getFloatingPos()) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageInstance.java index 1b9cc2e27..085819e38 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageInstance.java @@ -6,23 +6,18 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; import com.simibubi.create.content.contraptions.relays.encased.ShaftInstance; import com.simibubi.create.foundation.render.backend.RenderMaterials; -import com.simibubi.create.foundation.render.backend.instancing.ITickableInstance; +import com.simibubi.create.foundation.render.backend.instancing.IDynamicInstance; import com.simibubi.create.foundation.render.backend.instancing.InstanceKey; -import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderRegistry; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData; 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.Vector3f; -import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; -import net.minecraft.world.LightType; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; -public class GantryCarriageInstance extends ShaftInstance implements ITickableInstance { +public class GantryCarriageInstance extends ShaftInstance implements IDynamicInstance { private InstanceKey gantryCogs; @@ -35,17 +30,17 @@ public class GantryCarriageInstance extends ShaftInstance implements ITickableIn super.init(); gantryCogs = modelManager.getMaterial(RenderMaterials.MODELS) - .getModel(AllBlockPartials.GANTRY_COGS, lastState) + .getModel(AllBlockPartials.GANTRY_COGS, blockState) .createInstance(); updateLight(); } @Override - public void tick() { - lastState = tile.getBlockState(); - Direction facing = lastState.get(GantryCarriageBlock.FACING); - Boolean alongFirst = lastState.get(GantryCarriageBlock.AXIS_ALONG_FIRST_COORDINATE); + public void beginFrame() { + blockState = tile.getBlockState(); + Direction facing = blockState.get(GantryCarriageBlock.FACING); + Boolean alongFirst = blockState.get(GantryCarriageBlock.AXIS_ALONG_FIRST_COORDINATE); Direction.Axis rotationAxis = KineticTileEntityRenderer.getRotationAxisOf(tile); BlockPos visualPos = facing.getAxisDirection() == Direction.AxisDirection.POSITIVE ? tile.getPos() : tile.getPos() diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/pipes/FluidValveInstance.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/pipes/FluidValveInstance.java index 4e180a43d..765156582 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/pipes/FluidValveInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/pipes/FluidValveInstance.java @@ -5,7 +5,7 @@ import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; import com.simibubi.create.content.contraptions.relays.encased.ShaftInstance; -import com.simibubi.create.foundation.render.backend.instancing.ITickableInstance; +import com.simibubi.create.foundation.render.backend.instancing.IDynamicInstance; import com.simibubi.create.foundation.render.backend.instancing.InstanceKey; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData; @@ -15,7 +15,7 @@ import com.simibubi.create.foundation.utility.MatrixStacker; import net.minecraft.util.Direction; import net.minecraft.util.math.MathHelper; -public class FluidValveInstance extends ShaftInstance implements ITickableInstance { +public class FluidValveInstance extends ShaftInstance implements IDynamicInstance { protected InstanceKey pointer; @@ -31,26 +31,26 @@ public class FluidValveInstance extends ShaftInstance implements ITickableInstan protected void init() { super.init(); - Direction facing = lastState.get(FluidValveBlock.FACING); + Direction facing = blockState.get(FluidValveBlock.FACING); yRot = AngleHelper.horizontalAngle(facing); xRot = facing == Direction.UP ? 0 : facing == Direction.DOWN ? 180 : 90; - Direction.Axis pipeAxis = FluidValveBlock.getPipeAxis(lastState); + Direction.Axis pipeAxis = FluidValveBlock.getPipeAxis(blockState); Direction.Axis shaftAxis = KineticTileEntityRenderer.getRotationAxisOf(tile); pointerRotationOffset = 0; if (pipeAxis.isHorizontal() && shaftAxis == Direction.Axis.Z || pipeAxis.isVertical()) pointerRotationOffset = 90; - pointer = modelManager.getBasicMaterial().getModel(AllBlockPartials.FLUID_VALVE_POINTER, lastState).createInstance(); + pointer = modelManager.getBasicMaterial().getModel(AllBlockPartials.FLUID_VALVE_POINTER, blockState).createInstance(); updateLight(); transformPointer((FluidValveTileEntity) tile); } @Override - public void tick() { + public void beginFrame() { FluidValveTileEntity valve = (FluidValveTileEntity) tile; diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstance.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstance.java index 1891a7a2b..8b2845933 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstance.java @@ -6,14 +6,12 @@ import java.util.function.Supplier; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.AllBlocks; -import com.simibubi.create.content.contraptions.base.KineticData; import com.simibubi.create.content.contraptions.base.KineticTileInstance; import com.simibubi.create.content.contraptions.base.RotatingData; import com.simibubi.create.foundation.block.render.SpriteShiftEntry; import com.simibubi.create.foundation.render.backend.instancing.InstanceKey; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; -import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.MatrixStacker; @@ -41,13 +39,13 @@ public class BeltInstance extends KineticTileInstance { @Override protected void init() { - if (!AllBlocks.BELT.has(lastState)) + if (!AllBlocks.BELT.has(blockState)) return; keys = new ArrayList<>(2); - beltSlope = lastState.get(BeltBlock.SLOPE); - facing = lastState.get(BeltBlock.HORIZONTAL_FACING); + beltSlope = blockState.get(BeltBlock.SLOPE); + facing = blockState.get(BeltBlock.HORIZONTAL_FACING); upward = beltSlope == BeltSlope.UPWARD; diagonal = beltSlope.isDiagonal(); sideways = beltSlope == BeltSlope.SIDEWAYS; @@ -55,7 +53,7 @@ public class BeltInstance extends KineticTileInstance { alongX = facing.getAxis() == Direction.Axis.X; alongZ = facing.getAxis() == Direction.Axis.Z; - BeltPart part = lastState.get(BeltBlock.PART); + BeltPart part = blockState.get(BeltBlock.PART); boolean start = part == BeltPart.START; boolean end = part == BeltPart.END; DyeColor color = tile.color.orElse(null); @@ -64,7 +62,7 @@ public class BeltInstance extends KineticTileInstance { AllBlockPartials beltPartial = BeltRenderer.getBeltPartial(diagonal, start, end, bottom); SpriteShiftEntry spriteShift = BeltRenderer.getSpriteShiftEntry(color, diagonal, bottom); - InstancedModel beltModel = beltPartial.renderOnBelt(modelManager, lastState); + InstancedModel beltModel = beltPartial.renderOnBelt(modelManager, blockState); keys.add(setup(beltModel.createInstance(), bottom, spriteShift)); @@ -144,11 +142,11 @@ public class BeltInstance extends KineticTileInstance { return modelTransform; }; - return rotatingMaterial().getModel(AllBlockPartials.BELT_PULLEY, lastState, dir, ms); + return rotatingMaterial().getModel(AllBlockPartials.BELT_PULLEY, blockState, dir, ms); } private Direction getOrientation() { - Direction dir = lastState.get(BeltBlock.HORIZONTAL_FACING) + Direction dir = blockState.get(BeltBlock.HORIZONTAL_FACING) .rotateY(); if (beltSlope == BeltSlope.SIDEWAYS) dir = Direction.UP; diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftInstance.java b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftInstance.java index 641d72a68..73a3d6a28 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftInstance.java @@ -27,14 +27,14 @@ public class SplitShaftInstance extends KineticTileInstance(2); - Block block = lastState.getBlock(); - final Direction.Axis boxAxis = ((IRotate) block).getRotationAxis(lastState); + Block block = blockState.getBlock(); + final Direction.Axis boxAxis = ((IRotate) block).getRotationAxis(blockState); float speed = tile.getSpeed(); for (Direction dir : Iterate.directionsInAxis(boxAxis)) { - InstancedModel half = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(modelManager, lastState, dir); + InstancedModel half = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(modelManager, blockState, dir); float splitSpeed = speed * tile.getRotationSpeedModifier(dir); @@ -44,8 +44,8 @@ public class SplitShaftInstance extends KineticTileInstance faces; @@ -33,9 +33,9 @@ public abstract class GaugeInstance extends ShaftInstance implements ITickableIn faces = new ArrayList<>(2); GaugeTileEntity gaugeTile = (GaugeTileEntity) tile; - GaugeBlock gaugeBlock = (GaugeBlock) lastState.getBlock(); + GaugeBlock gaugeBlock = (GaugeBlock) blockState.getBlock(); - InstancedModel dialModel = modelManager.getMaterial(RenderMaterials.MODELS).getModel(AllBlockPartials.GAUGE_DIAL, lastState); + InstancedModel dialModel = modelManager.getMaterial(RenderMaterials.MODELS).getModel(AllBlockPartials.GAUGE_DIAL, blockState); InstancedModel headModel = getHeadModel(); ms = new MatrixStack(); @@ -45,7 +45,7 @@ public abstract class GaugeInstance extends ShaftInstance implements ITickableIn float progress = MathHelper.lerp(AnimationTickHolder.getPartialTicks(), gaugeTile.prevDialState, gaugeTile.dialState); for (Direction facing : Iterate.directions) { - if (!gaugeBlock.shouldRenderHeadOnFace(world, pos, lastState, facing)) + if (!gaugeBlock.shouldRenderHeadOnFace(world, pos, blockState, facing)) continue; DialFace face = makeFace(facing, dialModel, headModel); @@ -63,7 +63,7 @@ public abstract class GaugeInstance extends ShaftInstance implements ITickableIn } @Override - public void tick() { + public void beginFrame() { GaugeTileEntity gaugeTile = (GaugeTileEntity) tile; if (MathHelper.epsilonEquals(gaugeTile.prevDialState, gaugeTile.dialState)) @@ -156,7 +156,7 @@ public abstract class GaugeInstance extends ShaftInstance implements ITickableIn @Override protected InstancedModel getHeadModel() { - return modelManager.getMaterial(RenderMaterials.MODELS).getModel(AllBlockPartials.GAUGE_HEAD_SPEED, lastState); + return modelManager.getMaterial(RenderMaterials.MODELS).getModel(AllBlockPartials.GAUGE_HEAD_SPEED, blockState); } } @@ -167,7 +167,7 @@ public abstract class GaugeInstance extends ShaftInstance implements ITickableIn @Override protected InstancedModel getHeadModel() { - return modelManager.getMaterial(RenderMaterials.MODELS).getModel(AllBlockPartials.GAUGE_HEAD_STRESS, lastState); + return modelManager.getMaterial(RenderMaterials.MODELS).getModel(AllBlockPartials.GAUGE_HEAD_STRESS, blockState); } } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxInstance.java b/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxInstance.java index ec75b02a6..77d89ad6d 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxInstance.java @@ -8,17 +8,13 @@ import com.simibubi.create.content.contraptions.base.KineticTileInstance; import com.simibubi.create.content.contraptions.base.RotatingData; import com.simibubi.create.foundation.render.backend.instancing.InstanceKey; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; -import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderRegistry; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; import com.simibubi.create.foundation.utility.Iterate; import net.minecraft.state.properties.BlockStateProperties; -import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; import net.minecraft.world.LightType; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; public class GearboxInstance extends KineticTileInstance { @@ -33,7 +29,7 @@ public class GearboxInstance extends KineticTileInstance { protected void init() { keys = new EnumMap<>(Direction.class); - final Direction.Axis boxAxis = lastState.get(BlockStateProperties.AXIS); + final Direction.Axis boxAxis = blockState.get(BlockStateProperties.AXIS); int blockLight = world.getLightLevel(LightType.BLOCK, pos); int skyLight = world.getLightLevel(LightType.SKY, pos); @@ -44,7 +40,7 @@ public class GearboxInstance extends KineticTileInstance { if (boxAxis == axis) continue; - InstancedModel shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(modelManager, lastState, direction); + InstancedModel shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(modelManager, blockState, direction); InstanceKey key = shaft.createInstance(); diff --git a/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelInstance.java b/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelInstance.java index 31b3dd558..47aaf49bb 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelInstance.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelInstance.java @@ -6,18 +6,15 @@ import com.simibubi.create.content.logistics.block.FlapData; import com.simibubi.create.foundation.gui.widgets.InterpolatedValue; import com.simibubi.create.foundation.render.backend.instancing.*; import com.simibubi.create.foundation.utility.AnimationTickHolder; -import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; import net.minecraft.world.LightType; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; import java.util.ArrayList; import java.util.Collection; import java.util.EnumMap; import java.util.Map; -public class BeltTunnelInstance extends TileEntityInstance implements ITickableInstance { +public class BeltTunnelInstance extends TileEntityInstance implements IDynamicInstance { private Map>> tunnelFlaps; @@ -31,7 +28,7 @@ public class BeltTunnelInstance extends TileEntityInstance tunnelFlaps = new EnumMap<>(Direction.class); InstancedModel model = modelManager.getMaterial(KineticRenderMaterials.FLAPS) - .getModel(AllBlockPartials.BELT_TUNNEL_FLAP, lastState); + .getModel(AllBlockPartials.BELT_TUNNEL_FLAP, blockState); int blockLight = world.getLightLevel(LightType.BLOCK, pos); int skyLight = world.getLightLevel(LightType.SKY, pos); @@ -71,7 +68,7 @@ public class BeltTunnelInstance extends TileEntityInstance } @Override - public void tick() { + public void beginFrame() { tunnelFlaps.forEach((direction, keys) -> { InterpolatedValue flapValue = tile.flaps.get(direction); if (flapValue == null) { diff --git a/src/main/java/com/simibubi/create/content/logistics/block/diodes/AdjustableRepeaterInstance.java b/src/main/java/com/simibubi/create/content/logistics/block/diodes/AdjustableRepeaterInstance.java new file mode 100644 index 000000000..3d4ef9fdc --- /dev/null +++ b/src/main/java/com/simibubi/create/content/logistics/block/diodes/AdjustableRepeaterInstance.java @@ -0,0 +1,58 @@ +package com.simibubi.create.content.logistics.block.diodes; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.AllBlockPartials; +import com.simibubi.create.foundation.render.backend.instancing.*; +import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData; +import com.simibubi.create.foundation.utility.ColorHelper; +import com.simibubi.create.foundation.utility.MatrixStacker; + +public class AdjustableRepeaterInstance extends TileEntityInstance implements ITickableInstance { + + protected InstanceKey indicator; + + protected int previousState; + + public AdjustableRepeaterInstance(InstancedTileRenderer modelManager, AdjustableRepeaterTileEntity tile) { + super(modelManager, tile); + } + + @Override + protected void init() { + indicator = modelManager.getBasicMaterial().getModel(AllBlockPartials.FLEXPEATER_INDICATOR, blockState).createInstance(); + + MatrixStack ms = new MatrixStack(); + MatrixStacker.of(ms).translate(getFloatingPos()); + + indicator.getInstance() + .setTransform(ms) + .setColor(getColor()); + + previousState = tile.state; + + updateLight(); + } + + @Override + public void tick() { + if (previousState == tile.state) return; + + indicator.getInstance().setColor(getColor()); + + previousState = tile.state; + } + + @Override + public void updateLight() { + relight(pos, indicator.getInstance()); + } + + @Override + public void remove() { + indicator.delete(); + } + + protected int getColor() { + return ColorHelper.mixColors(0x2C0300, 0xCD0000, tile.state / (float) tile.maxState.getValue()); + } +} diff --git a/src/main/java/com/simibubi/create/content/logistics/block/diodes/AdjustableRepeaterTileEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/diodes/AdjustableRepeaterTileEntity.java index 7c4515a1c..543d8c93d 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/diodes/AdjustableRepeaterTileEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/diodes/AdjustableRepeaterTileEntity.java @@ -5,6 +5,7 @@ import static net.minecraft.block.RedstoneDiodeBlock.POWERED; import java.util.List; +import com.simibubi.create.foundation.render.backend.instancing.IInstanceRendered; import com.simibubi.create.foundation.tileEntity.SmartTileEntity; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollValueBehaviour; @@ -15,7 +16,7 @@ import net.minecraft.nbt.CompoundNBT; import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.math.MathHelper; -public class AdjustableRepeaterTileEntity extends SmartTileEntity { +public class AdjustableRepeaterTileEntity extends SmartTileEntity implements IInstanceRendered { public int state; public boolean charging; @@ -119,5 +120,4 @@ public class AdjustableRepeaterTileEntity extends SmartTileEntity { state += charging ? 1 : -1; } - } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelInstance.java b/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelInstance.java index 693e045b7..d3db0c74d 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelInstance.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelInstance.java @@ -5,15 +5,12 @@ import com.simibubi.create.content.contraptions.base.KineticRenderMaterials; import com.simibubi.create.content.logistics.block.FlapData; import com.simibubi.create.foundation.render.backend.instancing.*; import com.simibubi.create.foundation.utility.AnimationTickHolder; -import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; import net.minecraft.world.LightType; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; import java.util.ArrayList; -public class FunnelInstance extends TileEntityInstance implements ITickableInstance { +public class FunnelInstance extends TileEntityInstance implements IDynamicInstance { private ArrayList> flaps; @@ -27,15 +24,15 @@ public class FunnelInstance extends TileEntityInstance impleme if (!tile.hasFlap()) return; - AllBlockPartials flapPartial = (lastState.getBlock() instanceof FunnelBlock ? AllBlockPartials.FUNNEL_FLAP + AllBlockPartials flapPartial = (blockState.getBlock() instanceof FunnelBlock ? AllBlockPartials.FUNNEL_FLAP : AllBlockPartials.BELT_FUNNEL_FLAP); InstancedModel model = modelManager.getMaterial(KineticRenderMaterials.FLAPS) - .getModel(flapPartial, lastState); + .getModel(flapPartial, blockState); int blockLight = world.getLightLevel(LightType.BLOCK, pos); int skyLight = world.getLightLevel(LightType.SKY, pos); - Direction direction = FunnelBlock.getFunnelFacing(lastState); + Direction direction = FunnelBlock.getFunnelFacing(blockState); float flapness = tile.flap.get(AnimationTickHolder.getPartialTicks()); float horizontalAngle = direction.getOpposite().getHorizontalAngle(); @@ -62,7 +59,7 @@ public class FunnelInstance extends TileEntityInstance impleme } @Override - public void tick() { + public void beginFrame() { if (flaps == null) return; float flapness = tile.flap.get(AnimationTickHolder.getPartialTicks()); diff --git a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInstance.java b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInstance.java index 7a504c7b1..b63c070d3 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInstance.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInstance.java @@ -6,7 +6,6 @@ import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.RotatingData; import com.simibubi.create.content.contraptions.base.SingleRotatingInstance; -import com.simibubi.create.foundation.gui.widgets.InterpolatedValue; import com.simibubi.create.foundation.render.backend.RenderMaterials; import com.simibubi.create.foundation.render.backend.instancing.*; @@ -19,16 +18,11 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.ItemRenderer; import net.minecraft.item.BlockItem; import net.minecraft.item.ItemStack; -import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.math.MathHelper; -import net.minecraft.world.LightType; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; import java.util.ArrayList; -import java.util.stream.Stream; -public class ArmInstance extends SingleRotatingInstance implements ITickableInstance { +public class ArmInstance extends SingleRotatingInstance implements IDynamicInstance { private InstanceKey base; private InstanceKey lowerBody; @@ -51,13 +45,13 @@ public class ArmInstance extends SingleRotatingInstance implements ITickableInst RenderMaterial> mat = modelManager.getMaterial(RenderMaterials.MODELS); - base = mat.getModel(AllBlockPartials.ARM_BASE, lastState).createInstance(); - lowerBody = mat.getModel(AllBlockPartials.ARM_LOWER_BODY, lastState).createInstance(); - upperBody = mat.getModel(AllBlockPartials.ARM_UPPER_BODY, lastState).createInstance(); - head = mat.getModel(AllBlockPartials.ARM_HEAD, lastState).createInstance(); - claw = mat.getModel(AllBlockPartials.ARM_CLAW_BASE, lastState).createInstance(); + base = mat.getModel(AllBlockPartials.ARM_BASE, blockState).createInstance(); + lowerBody = mat.getModel(AllBlockPartials.ARM_LOWER_BODY, blockState).createInstance(); + upperBody = mat.getModel(AllBlockPartials.ARM_UPPER_BODY, blockState).createInstance(); + head = mat.getModel(AllBlockPartials.ARM_HEAD, blockState).createInstance(); + claw = mat.getModel(AllBlockPartials.ARM_CLAW_BASE, blockState).createInstance(); - InstancedModel clawHalfModel = mat.getModel(AllBlockPartials.ARM_CLAW_GRIP, lastState); + InstancedModel clawHalfModel = mat.getModel(AllBlockPartials.ARM_CLAW_GRIP, blockState); InstanceKey clawGrip1 = clawHalfModel.createInstance(); InstanceKey clawGrip2 = clawHalfModel.createInstance(); @@ -65,12 +59,12 @@ public class ArmInstance extends SingleRotatingInstance implements ITickableInst models = Lists.newArrayList(base, lowerBody, upperBody, head, claw, clawGrip1, clawGrip2); firstTick = true; - tick(); + beginFrame(); updateLight(); } @Override - public void tick() { + public void beginFrame() { ArmTileEntity arm = (ArmTileEntity) tile; boolean settled = arm.baseAngle.settled() && arm.lowerArmAngle.settled() && arm.upperArmAngle.settled() && arm.headAngle.settled(); @@ -107,7 +101,7 @@ public class ArmInstance extends SingleRotatingInstance implements ITickableInst msr.translate(getFloatingPos()); msr.centre(); - if (lastState.get(ArmBlock.CEILING)) + if (blockState.get(ArmBlock.CEILING)) msr.rotateX(180); ArmRenderer.transformBase(msr, baseAngle); diff --git a/src/main/java/com/simibubi/create/content/logistics/block/redstone/AnalogLeverInstance.java b/src/main/java/com/simibubi/create/content/logistics/block/redstone/AnalogLeverInstance.java index b14a2cef2..def1976ce 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/redstone/AnalogLeverInstance.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/redstone/AnalogLeverInstance.java @@ -2,8 +2,6 @@ package com.simibubi.create.content.logistics.block.redstone; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlockPartials; -import com.simibubi.create.content.contraptions.components.flywheel.FlyWheelInstance; -import com.simibubi.create.content.contraptions.components.flywheel.FlywheelTileEntity; import com.simibubi.create.foundation.render.backend.RenderMaterials; import com.simibubi.create.foundation.render.backend.instancing.*; import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData; @@ -12,12 +10,9 @@ import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.ColorHelper; import com.simibubi.create.foundation.utility.MatrixStacker; import net.minecraft.state.properties.AttachFace; -import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; -public class AnalogLeverInstance extends TileEntityInstance implements ITickableInstance { +public class AnalogLeverInstance extends TileEntityInstance implements IDynamicInstance { protected InstanceKey handle; protected InstanceKey indicator; @@ -33,19 +28,19 @@ public class AnalogLeverInstance extends TileEntityInstance> mat = modelManager.getMaterial(RenderMaterials.MODELS); - handle = mat.getModel(AllBlockPartials.ANALOG_LEVER_HANDLE, lastState).createInstance(); - indicator = mat.getModel(AllBlockPartials.ANALOG_LEVER_INDICATOR, lastState).createInstance(); + handle = mat.getModel(AllBlockPartials.ANALOG_LEVER_HANDLE, blockState).createInstance(); + indicator = mat.getModel(AllBlockPartials.ANALOG_LEVER_INDICATOR, blockState).createInstance(); - AttachFace face = lastState.get(AnalogLeverBlock.FACE); + AttachFace face = blockState.get(AnalogLeverBlock.FACE); rX = face == AttachFace.FLOOR ? 0 : face == AttachFace.WALL ? 90 : 180; - rY = AngleHelper.horizontalAngle(lastState.get(AnalogLeverBlock.HORIZONTAL_FACING)); + rY = AngleHelper.horizontalAngle(blockState.get(AnalogLeverBlock.HORIZONTAL_FACING)); setupModel(); updateLight(); } @Override - public void tick() { + public void beginFrame() { if (!tile.clientState.settled()) setupModel(); } diff --git a/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonInstance.java b/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonInstance.java index 97f27b930..fd9ddce84 100644 --- a/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonInstance.java +++ b/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonInstance.java @@ -1,27 +1,15 @@ package com.simibubi.create.content.schematics.block; import com.mojang.blaze3d.matrix.MatrixStack; -import com.mojang.blaze3d.vertex.IVertexBuilder; import com.simibubi.create.AllBlockPartials; -import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelInstance; -import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelTileEntity; -import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.render.backend.RenderMaterials; import com.simibubi.create.foundation.render.backend.instancing.*; import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData; import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.MatrixStacker; -import net.minecraft.block.BlockState; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.WorldRenderer; -import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.LightType; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; -public class SchematicannonInstance extends TileEntityInstance implements ITickableInstance { +public class SchematicannonInstance extends TileEntityInstance implements IDynamicInstance { private InstanceKey connector; private InstanceKey pipe; @@ -35,14 +23,14 @@ public class SchematicannonInstance extends TileEntityInstance> mat = modelManager.getMaterial(RenderMaterials.MODELS); - connector = mat.getModel(AllBlockPartials.SCHEMATICANNON_CONNECTOR, lastState).createInstance(); - pipe = mat.getModel(AllBlockPartials.SCHEMATICANNON_PIPE, lastState).createInstance(); + connector = mat.getModel(AllBlockPartials.SCHEMATICANNON_CONNECTOR, blockState).createInstance(); + pipe = mat.getModel(AllBlockPartials.SCHEMATICANNON_PIPE, blockState).createInstance(); updateLight(); } @Override - public void tick() { + public void beginFrame() { float partialTicks = AnimationTickHolder.getPartialTicks(); double[] cannonAngles = SchematicannonRenderer.getCannonAngles(tile, pos, partialTicks); diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/IDynamicInstance.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/IDynamicInstance.java new file mode 100644 index 000000000..0af4bc1eb --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/IDynamicInstance.java @@ -0,0 +1,8 @@ +package com.simibubi.create.foundation.render.backend.instancing; + +public interface IDynamicInstance { + /** + * Called every frame, this can be used to make more dynamic animations. + */ + void beginFrame(); +} diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/ITickableInstance.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/ITickableInstance.java index 4d79545a4..04a6f7ec0 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/ITickableInstance.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/ITickableInstance.java @@ -1,8 +1,6 @@ package com.simibubi.create.foundation.render.backend.instancing; public interface ITickableInstance { - /** - * Called every frame, this can be used to make more dynamic animations. - */ + void tick(); } diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java index 172431730..54142c6e4 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java @@ -4,7 +4,6 @@ import java.util.*; import javax.annotation.Nullable; -import com.simibubi.create.foundation.ponder.PonderWorld; import com.simibubi.create.foundation.render.backend.Backend; import com.simibubi.create.foundation.render.backend.RenderMaterials; import com.simibubi.create.foundation.render.backend.gl.BasicProgram; @@ -26,6 +25,7 @@ public abstract class InstancedTileRenderer

{ protected Map> instances = new HashMap<>(); protected Map tickableInstances = new HashMap<>(); + protected Map dynamicInstances = new HashMap<>(); protected Map, RenderMaterial> materials = new HashMap<>(); @@ -45,12 +45,18 @@ public abstract class InstancedTileRenderer

{ if (ticks % 10 == 0) { clean(); } + + if (tickableInstances.size() > 0) + tickableInstances.values().forEach(ITickableInstance::tick); } public void beginFrame(double cameraX, double cameraY, double cameraZ) { - queuedAdditions.forEach(this::add); - queuedAdditions.clear(); - tickableInstances.values().forEach(ITickableInstance::tick); + if (queuedAdditions.size() > 0) { + queuedAdditions.forEach(this::add); + queuedAdditions.clear(); + } + if (dynamicInstances.size() > 0) + dynamicInstances.values().forEach(IDynamicInstance::beginFrame); } public void render(RenderType layer, Matrix4f viewProjection, double camX, double camY, double camZ) { @@ -93,8 +99,11 @@ public abstract class InstancedTileRenderer

{ if (renderer != null) { instances.put(tile, renderer); + if (renderer instanceof IDynamicInstance) + dynamicInstances.put(tile, (IDynamicInstance) renderer); + if (renderer instanceof ITickableInstance) - tickableInstances.put(tile, (ITickableInstance) renderer); + tickableInstances.put(tile, ((ITickableInstance) renderer)); } return renderer; @@ -148,6 +157,7 @@ public abstract class InstancedTileRenderer

{ if (instance != null) { instance.remove(); instances.remove(tile); + dynamicInstances.remove(tile); tickableInstances.remove(tile); } } @@ -162,7 +172,7 @@ public abstract class InstancedTileRenderer

{ material.delete(); } instances.clear(); - tickableInstances.clear(); + dynamicInstances.clear(); } public boolean canCreateInstance(TileEntity tile) { diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/TileEntityInstance.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/TileEntityInstance.java index b5241999c..fd31e3569 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/TileEntityInstance.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/TileEntityInstance.java @@ -1,7 +1,6 @@ package com.simibubi.create.foundation.render.backend.instancing; import com.simibubi.create.foundation.render.backend.instancing.impl.IFlatLight; -import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData; import net.minecraft.block.BlockState; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.BlockPos; @@ -17,24 +16,24 @@ public abstract class TileEntityInstance { protected final T tile; protected final World world; protected final BlockPos pos; - protected BlockState lastState; + protected BlockState blockState; public TileEntityInstance(InstancedTileRenderer modelManager, T tile) { this.modelManager = modelManager; this.tile = tile; this.world = tile.getWorld(); this.pos = tile.getPos(); - this.lastState = tile.getBlockState(); + this.blockState = tile.getBlockState(); init(); } public final void update() { BlockState currentState = tile.getBlockState(); - if (lastState == currentState) { + if (blockState == currentState) { onUpdate(); } else { remove(); - lastState = currentState; + blockState = currentState; init(); } } diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/renderer/ColoredOverlayTileEntityRenderer.java b/src/main/java/com/simibubi/create/foundation/tileEntity/renderer/ColoredOverlayTileEntityRenderer.java index 23df51f8f..a72e40dc2 100644 --- a/src/main/java/com/simibubi/create/foundation/tileEntity/renderer/ColoredOverlayTileEntityRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/tileEntity/renderer/ColoredOverlayTileEntityRenderer.java @@ -3,6 +3,7 @@ package com.simibubi.create.foundation.tileEntity.renderer; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.foundation.render.SuperByteBuffer; +import com.simibubi.create.foundation.render.backend.FastRenderDispatcher; import net.minecraft.block.BlockState; import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.RenderType; @@ -21,8 +22,10 @@ public abstract class ColoredOverlayTileEntityRenderer ext @Override protected void renderSafe(T te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) { - SuperByteBuffer render = render(te.getWorld(), te.getPos(), te.getBlockState(), getOverlayBuffer(te), - getColor(te, partialTicks)); + + if (FastRenderDispatcher.available(te.getWorld())) return; + + SuperByteBuffer render = render(getOverlayBuffer(te), getColor(te, partialTicks), light); render.renderInto(ms, buffer.getBuffer(RenderType.getSolid())); } @@ -30,10 +33,8 @@ public abstract class ColoredOverlayTileEntityRenderer ext protected abstract SuperByteBuffer getOverlayBuffer(T te); - public static SuperByteBuffer render(World world, BlockPos pos, BlockState state, SuperByteBuffer buffer, - int color) { - int packedLightmapCoords = WorldRenderer.getLightmapCoordinates(world, state, pos); - return buffer.color(color).light(packedLightmapCoords); + public static SuperByteBuffer render(SuperByteBuffer buffer, int color, int light) { + return buffer.color(color).light(light); } } From a356f8a91a4117fe28dc79376fc7370ae17c0af0 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Sun, 21 Mar 2021 03:51:22 +0100 Subject: [PATCH 05/14] Ponder and Polish - Ponder scenes for depot, chute and smart chute - Fixed saws and drains ejecting items when mounted funnel is backstuffed - Fixed extracting funnels allowing items to be inserted by arms and belt input - Vanilla items in ponder tags are marked purple instead of red - Vertical funnels now block chutes - Large cogs can no longer be placed right next to crafters or millstones - Mechanical Arms now stall targeted belt items --- src/generated/resources/.cache/cache | 32 +-- .../assets/create/blockstates/fluid_pipe.json | 110 ++++---- .../create/blockstates/radial_chassis.json | 96 +++---- .../resources/assets/create/lang/en_us.json | 26 +- .../assets/create/lang/unfinished/de_de.json | 28 +- .../assets/create/lang/unfinished/es_es.json | 28 +- .../assets/create/lang/unfinished/es_mx.json | 28 +- .../assets/create/lang/unfinished/fr_fr.json | 28 +- .../assets/create/lang/unfinished/it_it.json | 28 +- .../assets/create/lang/unfinished/ja_jp.json | 28 +- .../assets/create/lang/unfinished/ko_kr.json | 28 +- .../assets/create/lang/unfinished/nl_nl.json | 28 +- .../assets/create/lang/unfinished/pt_br.json | 28 +- .../assets/create/lang/unfinished/ru_ru.json | 28 +- .../assets/create/lang/unfinished/zh_cn.json | 28 +- .../assets/create/lang/unfinished/zh_tw.json | 28 +- .../data/create/advancements/aesthetics.json | 4 +- .../components/saw/SawTileEntity.java | 38 +-- .../fluids/actors/ItemDrainTileEntity.java | 20 +- .../relays/belt/BeltTileEntity.java | 9 +- .../relays/belt/transport/BeltInventory.java | 6 + .../belt/transport/TransportedItemStack.java | 7 +- .../relays/elementary/CogWheelBlock.java | 174 ++++++------ .../belts/tunnel/BeltTunnelRenderer.java | 1 - .../belts/tunnel/BeltTunnelTileEntity.java | 28 +- .../block/chute/ChuteTileEntity.java | 9 +- .../block/depot/DepotTileEntity.java | 4 + .../block/funnel/FunnelTileEntity.java | 2 + .../mechanicalArm/ArmInteractionPoint.java | 119 +++++--- .../block/mechanicalArm/ArmTileEntity.java | 12 +- .../content/schematics/SchematicWorld.java | 6 +- .../create/foundation/ponder/PonderWorld.java | 24 +- .../foundation/ponder/SceneBuilder.java | 12 + .../ponder/content/BearingScenes.java | 3 + .../foundation/ponder/content/BeltScenes.java | 115 +++++++- .../ponder/content/ChuteScenes.java | 265 ++++++++++++++++++ .../ponder/content/FunnelScenes.java | 2 +- .../ponder/content/PonderIndex.java | 14 +- .../ponder/content/PonderTagScreen.java | 24 +- .../ponder/content/ProcessingScenes.java | 6 +- .../TileEntityDataInstruction.java | 2 +- .../foundation/ponder/ui/PonderButton.java | 15 +- .../belt/DirectBeltInputBehaviour.java | 11 +- src/main/resources/ponder/chute/downward.nbt | Bin 0 -> 485 bytes src/main/resources/ponder/chute/smart.nbt | Bin 0 -> 575 bytes src/main/resources/ponder/chute/upward.nbt | Bin 0 -> 1008 bytes src/main/resources/ponder/depot.nbt | Bin 0 -> 1154 bytes 47 files changed, 1174 insertions(+), 358 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/ponder/content/ChuteScenes.java create mode 100644 src/main/resources/ponder/chute/downward.nbt create mode 100644 src/main/resources/ponder/chute/smart.nbt create mode 100644 src/main/resources/ponder/chute/upward.nbt create mode 100644 src/main/resources/ponder/depot.nbt diff --git a/src/generated/resources/.cache/cache b/src/generated/resources/.cache/cache index a7b18ba48..2ed629144 100644 --- a/src/generated/resources/.cache/cache +++ b/src/generated/resources/.cache/cache @@ -140,7 +140,7 @@ de8a40b7daf1497d5aecee47a43b3e0b1d030b00 assets/create/blockstates/fancy_scoria_ fc9ac0a7e7191b93516719455a17177fa6524ecc assets/create/blockstates/fancy_weathered_limestone_bricks_slab.json b2a7c321b1795f20e7433f81a55ce4683de081b8 assets/create/blockstates/fancy_weathered_limestone_bricks_stairs.json 6372fe02ba0065acb0758121c45a15a1a8fdc5de assets/create/blockstates/fancy_weathered_limestone_bricks_wall.json -48086bf71a824faf14841b698050cc8544b09a9b assets/create/blockstates/fluid_pipe.json +37bc041b7449dc4d7962225e606125ba1b188974 assets/create/blockstates/fluid_pipe.json f0eaab18e16c4f3f65ebf3b55b08f0dc445720fe assets/create/blockstates/fluid_tank.json 5408d92ab02af86539ac42971d4033545970bb3a assets/create/blockstates/fluid_valve.json e9da1794b6ece7f9aa8bcb43d42c23a55446133b assets/create/blockstates/flywheel.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 +8d7e653bfd9846e684a0d3725595714a19201017 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 @@ -402,19 +402,19 @@ a3a11524cd3515fc01d905767b4b7ea782adaf03 assets/create/blockstates/yellow_seat.j 7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json 2b12f3cf99e498899207a8c4855210e7b5dc55cd assets/create/lang/en_ud.json -cb22b256847375aa973491ca51858a704a3edf2c assets/create/lang/en_us.json -d2c8c43f990f7844f3dea35fd0a98ee7f4d40576 assets/create/lang/unfinished/de_de.json -69ce4c93ab2d6afd93352fd269be68f4c53ed963 assets/create/lang/unfinished/es_es.json -2a63880625f84655bee39fa5ff0e4d5f0933f8f9 assets/create/lang/unfinished/es_mx.json -a568c0d8943021d8f438d80692a62e7987b35c7d assets/create/lang/unfinished/fr_fr.json -b21c69ffdb9f09324bfb51fb843af000bf9c2c13 assets/create/lang/unfinished/it_it.json -230ab0c62a7e8b6a6e0c68b3081f06e0148e120a assets/create/lang/unfinished/ja_jp.json -c42a6c5d2ae9b97d4c79751cd7f60f70864f8c36 assets/create/lang/unfinished/ko_kr.json -b640c6137991b8e25139105a44d0d13b0b66ed18 assets/create/lang/unfinished/nl_nl.json -b9c2f45ac232045e6c1124d48017154504096dbd assets/create/lang/unfinished/pt_br.json -d69e5e26891d5ff7a1d93a1f5cc0bd775e1dfa08 assets/create/lang/unfinished/ru_ru.json -dbf513ee2276e1460adf3f3f50f336d104a74884 assets/create/lang/unfinished/zh_cn.json -40fd381d585db529a20f31adf001ecaf6dc77104 assets/create/lang/unfinished/zh_tw.json +3522bc1dd15fd219aaf506766fb96be5f65b1939 assets/create/lang/en_us.json +d389c171d3d6a7382fb5b2e80b14e9bee53d8179 assets/create/lang/unfinished/de_de.json +b3caab7bb37be53ea93895cbaae2081452cd095e assets/create/lang/unfinished/es_es.json +0039068794faea032b0a39c954f142e2c8e4dfc1 assets/create/lang/unfinished/es_mx.json +1e34083359caea11cf9fdbb3f04a5881ea62a55e assets/create/lang/unfinished/fr_fr.json +c9abd10d296055f56877317a5c7dee14d0e33bf5 assets/create/lang/unfinished/it_it.json +83298d57034c2bb54924dff2d9b5257502ac3b9a assets/create/lang/unfinished/ja_jp.json +2c0e5fbfc813949d973e9f95af9501ed65b80b82 assets/create/lang/unfinished/ko_kr.json +4b3b113e5f9351b741974bc18d13d9d648d38f91 assets/create/lang/unfinished/nl_nl.json +9bddfffdf5349353d37d7003546c94799c6e812d assets/create/lang/unfinished/pt_br.json +5119b6690e8faa7e25450674caebf3c9c53fd54b assets/create/lang/unfinished/ru_ru.json +f11eb922b49753b60894f0dfe8baabe004d13e05 assets/create/lang/unfinished/zh_cn.json +017a9c9cc6f4538c8c497097cbd59f590b4af160 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 @@ -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 -0f1b4b980afba9bf2caf583b88e261bba8b10313 data/create/advancements/aesthetics.json +5d0cc4c0255dc241e61c173b31ddca70c88d08e4 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 diff --git a/src/generated/resources/assets/create/blockstates/fluid_pipe.json b/src/generated/resources/assets/create/blockstates/fluid_pipe.json index 80a25280c..37315d0be 100644 --- a/src/generated/resources/assets/create/blockstates/fluid_pipe.json +++ b/src/generated/resources/assets/create/blockstates/fluid_pipe.json @@ -181,10 +181,10 @@ }, { "when": { - "south": "true", + "east": "false", "west": "true", - "north": "false", - "east": "false" + "south": "true", + "north": "false" }, "apply": { "model": "create:block/fluid_pipe/lu_y" @@ -192,10 +192,10 @@ }, { "when": { - "south": "true", + "east": "true", "west": "false", - "north": "false", - "east": "true" + "south": "true", + "north": "false" }, "apply": { "model": "create:block/fluid_pipe/ru_y" @@ -203,10 +203,10 @@ }, { "when": { - "south": "false", + "east": "false", "west": "true", - "north": "true", - "east": "false" + "south": "false", + "north": "true" }, "apply": { "model": "create:block/fluid_pipe/ld_y" @@ -214,10 +214,10 @@ }, { "when": { - "south": "false", + "east": "true", "west": "false", - "north": "true", - "east": "true" + "south": "false", + "north": "true" }, "apply": { "model": "create:block/fluid_pipe/rd_y" @@ -225,10 +225,10 @@ }, { "when": { + "east": "false", + "west": "false", "south": "true", - "west": "false", - "north": "true", - "east": "false" + "north": "true" }, "apply": { "model": "create:block/fluid_pipe/ud_y" @@ -236,10 +236,10 @@ }, { "when": { + "east": "false", + "west": "false", "south": "true", - "west": "false", - "north": "false", - "east": "false" + "north": "false" }, "apply": { "model": "create:block/fluid_pipe/ud_y" @@ -247,10 +247,10 @@ }, { "when": { - "south": "false", + "east": "false", "west": "false", - "north": "true", - "east": "false" + "south": "false", + "north": "true" }, "apply": { "model": "create:block/fluid_pipe/ud_y" @@ -258,10 +258,10 @@ }, { "when": { - "south": "false", + "east": "true", "west": "true", - "north": "false", - "east": "true" + "south": "false", + "north": "false" }, "apply": { "model": "create:block/fluid_pipe/lr_y" @@ -269,10 +269,10 @@ }, { "when": { - "south": "false", + "east": "false", "west": "true", - "north": "false", - "east": "false" + "south": "false", + "north": "false" }, "apply": { "model": "create:block/fluid_pipe/lr_y" @@ -280,10 +280,10 @@ }, { "when": { - "south": "false", + "east": "true", "west": "false", - "north": "false", - "east": "true" + "south": "false", + "north": "false" }, "apply": { "model": "create:block/fluid_pipe/lr_y" @@ -291,10 +291,10 @@ }, { "when": { - "south": "false", + "east": "false", "west": "false", - "north": "false", - "east": "false" + "south": "false", + "north": "false" }, "apply": { "model": "create:block/fluid_pipe/none_y" @@ -303,9 +303,9 @@ { "when": { "down": "false", - "up": "true", + "east": "true", "west": "false", - "east": "true" + "up": "true" }, "apply": { "model": "create:block/fluid_pipe/lu_z" @@ -314,9 +314,9 @@ { "when": { "down": "false", - "up": "true", + "east": "false", "west": "true", - "east": "false" + "up": "true" }, "apply": { "model": "create:block/fluid_pipe/ru_z" @@ -325,9 +325,9 @@ { "when": { "down": "true", - "up": "false", + "east": "true", "west": "false", - "east": "true" + "up": "false" }, "apply": { "model": "create:block/fluid_pipe/ld_z" @@ -336,9 +336,9 @@ { "when": { "down": "true", - "up": "false", + "east": "false", "west": "true", - "east": "false" + "up": "false" }, "apply": { "model": "create:block/fluid_pipe/rd_z" @@ -347,9 +347,9 @@ { "when": { "down": "true", - "up": "true", + "east": "false", "west": "false", - "east": "false" + "up": "true" }, "apply": { "model": "create:block/fluid_pipe/ud_z" @@ -358,9 +358,9 @@ { "when": { "down": "false", - "up": "true", + "east": "false", "west": "false", - "east": "false" + "up": "true" }, "apply": { "model": "create:block/fluid_pipe/ud_z" @@ -369,9 +369,9 @@ { "when": { "down": "true", - "up": "false", + "east": "false", "west": "false", - "east": "false" + "up": "false" }, "apply": { "model": "create:block/fluid_pipe/ud_z" @@ -380,9 +380,9 @@ { "when": { "down": "false", - "up": "false", + "east": "true", "west": "true", - "east": "true" + "up": "false" }, "apply": { "model": "create:block/fluid_pipe/lr_z" @@ -391,9 +391,9 @@ { "when": { "down": "false", - "up": "false", + "east": "true", "west": "false", - "east": "true" + "up": "false" }, "apply": { "model": "create:block/fluid_pipe/lr_z" @@ -402,9 +402,9 @@ { "when": { "down": "false", - "up": "false", + "east": "false", "west": "true", - "east": "false" + "up": "false" }, "apply": { "model": "create:block/fluid_pipe/lr_z" @@ -413,9 +413,9 @@ { "when": { "down": "false", - "up": "false", + "east": "false", "west": "false", - "east": "false" + "up": "false" }, "apply": { "model": "create:block/fluid_pipe/none_z" diff --git a/src/generated/resources/assets/create/blockstates/radial_chassis.json b/src/generated/resources/assets/create/blockstates/radial_chassis.json index 8bd829ffc..9d00ea8b1 100644 --- a/src/generated/resources/assets/create/blockstates/radial_chassis.json +++ b/src/generated/resources/assets/create/blockstates/radial_chassis.json @@ -29,8 +29,8 @@ }, { "when": { - "axis": "x", - "sticky_south": "true" + "sticky_south": "true", + "axis": "x" }, "apply": { "model": "create:block/radial_chassis_side_x_sticky", @@ -39,8 +39,8 @@ }, { "when": { - "axis": "y", - "sticky_south": "true" + "sticky_south": "true", + "axis": "y" }, "apply": { "model": "create:block/radial_chassis_side_y_sticky" @@ -48,8 +48,8 @@ }, { "when": { - "axis": "z", - "sticky_south": "true" + "sticky_south": "true", + "axis": "z" }, "apply": { "model": "create:block/radial_chassis_side_x_sticky", @@ -59,8 +59,8 @@ }, { "when": { - "axis": "x", - "sticky_south": "false" + "sticky_south": "false", + "axis": "x" }, "apply": { "model": "create:block/radial_chassis_side_x", @@ -69,8 +69,8 @@ }, { "when": { - "axis": "y", - "sticky_south": "false" + "sticky_south": "false", + "axis": "y" }, "apply": { "model": "create:block/radial_chassis_side_y" @@ -78,8 +78,8 @@ }, { "when": { - "axis": "z", - "sticky_south": "false" + "sticky_south": "false", + "axis": "z" }, "apply": { "model": "create:block/radial_chassis_side_x", @@ -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_us.json b/src/generated/resources/assets/create/lang/en_us.json index b3751d222..43b6dae4a 100644 --- a/src/generated/resources/assets/create/lang/en_us.json +++ b/src/generated/resources/assets/create/lang/en_us.json @@ -1906,7 +1906,7 @@ "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_directions.text_6": "These are all possible directions. Belts 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", @@ -1957,6 +1957,16 @@ "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.chute.header": "Transporting Items downward via Chutes", + "create.ponder.chute.text_1": "Chutes can transport items vertically from and to inventories", + "create.ponder.chute.text_2": "Using the Wrench, a window can be created", + "create.ponder.chute.text_3": "Placing chutes targeting the side faces of another will make it diagonal", + + "create.ponder.chute_upward.header": "Transporting Items upward via Chutes", + "create.ponder.chute_upward.text_1": "Using Encased Fans at the top or bottom, a Chute can move items upward", + "create.ponder.chute_upward.text_2": "Inspecting chutes with Engineers' Goggles reveals information about the movement direction", + "create.ponder.chute_upward.text_3": "On the 'blocked' end, items will have to be inserted/taken from the sides", + "create.ponder.clockwork_bearing.header": "Animating Structures using Clockwork Bearings", "create.ponder.clockwork_bearing.text_1": "Clockwork Bearings attach to blocks in front of them", "create.ponder.clockwork_bearing.text_2": "Upon receiving Rotational Force, the structure will be rotated according to the hour of the day", @@ -2021,6 +2031,12 @@ "create.ponder.deployer_redstone.text_2": "Before stopping, the Deployer will finish any started cycles", "create.ponder.deployer_redstone.text_3": "Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.depot.header": "Using Depots", + "create.ponder.depot.text_1": "Depots can serve as 'stationary' belt elements", + "create.ponder.depot.text_2": "Right-Click to manually place or remove Items from it", + "create.ponder.depot.text_3": "Just like Mechanical Belts, it can provide items to processing", + "create.ponder.depot.text_4": "...as well as provide Items to Mechanical Arms", + "create.ponder.empty_blaze_burner.header": "Using Empty Blaze Burners", "create.ponder.empty_blaze_burner.text_1": "Right-click a Blaze with the empty burner to capture it", "create.ponder.empty_blaze_burner.text_2": "Alternatively, Blazes can be collected from their Spawners directly", @@ -2068,7 +2084,7 @@ "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_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.", @@ -2294,6 +2310,12 @@ "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.smart_chute.header": "Filtering Items using Smart Chutes", + "create.ponder.smart_chute.text_1": "Smart Chutes are vertical chutes with additional control", + "create.ponder.smart_chute.text_2": "Items in the filter slot specify what exactly they can extract and transfer", + "create.ponder.smart_chute.text_3": "Use the Mouse Wheel to specify the extracted stack size", + "create.ponder.smart_chute.text_4": "Redstone power will prevent Smart Chutes from acting.", + "create.ponder.speedometer.header": "Monitoring Kinetic information using the Speedometer", "create.ponder.speedometer.text_1": "The Speedometer displays the current Speed of the attached components", "create.ponder.speedometer.text_2": "When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", 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 d8e19da81..9db22f031 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: 1425", + "_": "Missing Localizations: 1443", "_": "->------------------------] Game Elements [------------------------<-", @@ -1907,7 +1907,7 @@ "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_directions.text_6": "UNLOCALIZED: These are all possible directions. Belts 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", @@ -1958,6 +1958,16 @@ "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.chute.header": "UNLOCALIZED: Transporting Items downward via Chutes", + "create.ponder.chute.text_1": "UNLOCALIZED: Chutes can transport items vertically from and to inventories", + "create.ponder.chute.text_2": "UNLOCALIZED: Using the Wrench, a window can be created", + "create.ponder.chute.text_3": "UNLOCALIZED: Placing chutes targeting the side faces of another will make it diagonal", + + "create.ponder.chute_upward.header": "UNLOCALIZED: Transporting Items upward via Chutes", + "create.ponder.chute_upward.text_1": "UNLOCALIZED: Using Encased Fans at the top or bottom, a Chute can move items upward", + "create.ponder.chute_upward.text_2": "UNLOCALIZED: Inspecting chutes with Engineers' Goggles reveals information about the movement direction", + "create.ponder.chute_upward.text_3": "UNLOCALIZED: On the 'blocked' end, items will have to be inserted/taken from the sides", + "create.ponder.clockwork_bearing.header": "UNLOCALIZED: Animating Structures using Clockwork Bearings", "create.ponder.clockwork_bearing.text_1": "UNLOCALIZED: Clockwork Bearings attach to blocks in front of them", "create.ponder.clockwork_bearing.text_2": "UNLOCALIZED: Upon receiving Rotational Force, the structure will be rotated according to the hour of the day", @@ -2022,6 +2032,12 @@ "create.ponder.deployer_redstone.text_2": "UNLOCALIZED: Before stopping, the Deployer will finish any started cycles", "create.ponder.deployer_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.depot.header": "UNLOCALIZED: Using Depots", + "create.ponder.depot.text_1": "UNLOCALIZED: Depots can serve as 'stationary' belt elements", + "create.ponder.depot.text_2": "UNLOCALIZED: Right-Click to manually place or remove Items from it", + "create.ponder.depot.text_3": "UNLOCALIZED: Just like Mechanical Belts, it can provide items to processing", + "create.ponder.depot.text_4": "UNLOCALIZED: ...as well as provide Items to Mechanical Arms", + "create.ponder.empty_blaze_burner.header": "UNLOCALIZED: Using Empty Blaze Burners", "create.ponder.empty_blaze_burner.text_1": "UNLOCALIZED: Right-click a Blaze with the empty burner to capture it", "create.ponder.empty_blaze_burner.text_2": "UNLOCALIZED: Alternatively, Blazes can be collected from their Spawners directly", @@ -2069,7 +2085,7 @@ "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_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.", @@ -2295,6 +2311,12 @@ "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.smart_chute.header": "UNLOCALIZED: Filtering Items using Smart Chutes", + "create.ponder.smart_chute.text_1": "UNLOCALIZED: Smart Chutes are vertical chutes with additional control", + "create.ponder.smart_chute.text_2": "UNLOCALIZED: Items in the filter slot specify what exactly they can extract and transfer", + "create.ponder.smart_chute.text_3": "UNLOCALIZED: Use the Mouse Wheel to specify the extracted stack size", + "create.ponder.smart_chute.text_4": "UNLOCALIZED: Redstone power will prevent Smart Chutes from acting.", + "create.ponder.speedometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Speedometer", "create.ponder.speedometer.text_1": "UNLOCALIZED: The Speedometer displays the current Speed of the attached components", "create.ponder.speedometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", 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 5bc39f897..4b1671b37 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: 456", + "_": "Missing Localizations: 474", "_": "->------------------------] Game Elements [------------------------<-", @@ -1907,7 +1907,7 @@ "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_directions.text_6": "UNLOCALIZED: These are all possible directions. Belts 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", @@ -1958,6 +1958,16 @@ "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.chute.header": "UNLOCALIZED: Transporting Items downward via Chutes", + "create.ponder.chute.text_1": "UNLOCALIZED: Chutes can transport items vertically from and to inventories", + "create.ponder.chute.text_2": "UNLOCALIZED: Using the Wrench, a window can be created", + "create.ponder.chute.text_3": "UNLOCALIZED: Placing chutes targeting the side faces of another will make it diagonal", + + "create.ponder.chute_upward.header": "UNLOCALIZED: Transporting Items upward via Chutes", + "create.ponder.chute_upward.text_1": "UNLOCALIZED: Using Encased Fans at the top or bottom, a Chute can move items upward", + "create.ponder.chute_upward.text_2": "UNLOCALIZED: Inspecting chutes with Engineers' Goggles reveals information about the movement direction", + "create.ponder.chute_upward.text_3": "UNLOCALIZED: On the 'blocked' end, items will have to be inserted/taken from the sides", + "create.ponder.clockwork_bearing.header": "UNLOCALIZED: Animating Structures using Clockwork Bearings", "create.ponder.clockwork_bearing.text_1": "UNLOCALIZED: Clockwork Bearings attach to blocks in front of them", "create.ponder.clockwork_bearing.text_2": "UNLOCALIZED: Upon receiving Rotational Force, the structure will be rotated according to the hour of the day", @@ -2022,6 +2032,12 @@ "create.ponder.deployer_redstone.text_2": "UNLOCALIZED: Before stopping, the Deployer will finish any started cycles", "create.ponder.deployer_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.depot.header": "UNLOCALIZED: Using Depots", + "create.ponder.depot.text_1": "UNLOCALIZED: Depots can serve as 'stationary' belt elements", + "create.ponder.depot.text_2": "UNLOCALIZED: Right-Click to manually place or remove Items from it", + "create.ponder.depot.text_3": "UNLOCALIZED: Just like Mechanical Belts, it can provide items to processing", + "create.ponder.depot.text_4": "UNLOCALIZED: ...as well as provide Items to Mechanical Arms", + "create.ponder.empty_blaze_burner.header": "UNLOCALIZED: Using Empty Blaze Burners", "create.ponder.empty_blaze_burner.text_1": "UNLOCALIZED: Right-click a Blaze with the empty burner to capture it", "create.ponder.empty_blaze_burner.text_2": "UNLOCALIZED: Alternatively, Blazes can be collected from their Spawners directly", @@ -2069,7 +2085,7 @@ "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_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.", @@ -2295,6 +2311,12 @@ "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.smart_chute.header": "UNLOCALIZED: Filtering Items using Smart Chutes", + "create.ponder.smart_chute.text_1": "UNLOCALIZED: Smart Chutes are vertical chutes with additional control", + "create.ponder.smart_chute.text_2": "UNLOCALIZED: Items in the filter slot specify what exactly they can extract and transfer", + "create.ponder.smart_chute.text_3": "UNLOCALIZED: Use the Mouse Wheel to specify the extracted stack size", + "create.ponder.smart_chute.text_4": "UNLOCALIZED: Redstone power will prevent Smart Chutes from acting.", + "create.ponder.speedometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Speedometer", "create.ponder.speedometer.text_1": "UNLOCALIZED: The Speedometer displays the current Speed of the attached components", "create.ponder.speedometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", 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 2dc445799..087f4834d 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: 1355", + "_": "Missing Localizations: 1373", "_": "->------------------------] Game Elements [------------------------<-", @@ -1907,7 +1907,7 @@ "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_directions.text_6": "UNLOCALIZED: These are all possible directions. Belts 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", @@ -1958,6 +1958,16 @@ "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.chute.header": "UNLOCALIZED: Transporting Items downward via Chutes", + "create.ponder.chute.text_1": "UNLOCALIZED: Chutes can transport items vertically from and to inventories", + "create.ponder.chute.text_2": "UNLOCALIZED: Using the Wrench, a window can be created", + "create.ponder.chute.text_3": "UNLOCALIZED: Placing chutes targeting the side faces of another will make it diagonal", + + "create.ponder.chute_upward.header": "UNLOCALIZED: Transporting Items upward via Chutes", + "create.ponder.chute_upward.text_1": "UNLOCALIZED: Using Encased Fans at the top or bottom, a Chute can move items upward", + "create.ponder.chute_upward.text_2": "UNLOCALIZED: Inspecting chutes with Engineers' Goggles reveals information about the movement direction", + "create.ponder.chute_upward.text_3": "UNLOCALIZED: On the 'blocked' end, items will have to be inserted/taken from the sides", + "create.ponder.clockwork_bearing.header": "UNLOCALIZED: Animating Structures using Clockwork Bearings", "create.ponder.clockwork_bearing.text_1": "UNLOCALIZED: Clockwork Bearings attach to blocks in front of them", "create.ponder.clockwork_bearing.text_2": "UNLOCALIZED: Upon receiving Rotational Force, the structure will be rotated according to the hour of the day", @@ -2022,6 +2032,12 @@ "create.ponder.deployer_redstone.text_2": "UNLOCALIZED: Before stopping, the Deployer will finish any started cycles", "create.ponder.deployer_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.depot.header": "UNLOCALIZED: Using Depots", + "create.ponder.depot.text_1": "UNLOCALIZED: Depots can serve as 'stationary' belt elements", + "create.ponder.depot.text_2": "UNLOCALIZED: Right-Click to manually place or remove Items from it", + "create.ponder.depot.text_3": "UNLOCALIZED: Just like Mechanical Belts, it can provide items to processing", + "create.ponder.depot.text_4": "UNLOCALIZED: ...as well as provide Items to Mechanical Arms", + "create.ponder.empty_blaze_burner.header": "UNLOCALIZED: Using Empty Blaze Burners", "create.ponder.empty_blaze_burner.text_1": "UNLOCALIZED: Right-click a Blaze with the empty burner to capture it", "create.ponder.empty_blaze_burner.text_2": "UNLOCALIZED: Alternatively, Blazes can be collected from their Spawners directly", @@ -2069,7 +2085,7 @@ "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_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.", @@ -2295,6 +2311,12 @@ "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.smart_chute.header": "UNLOCALIZED: Filtering Items using Smart Chutes", + "create.ponder.smart_chute.text_1": "UNLOCALIZED: Smart Chutes are vertical chutes with additional control", + "create.ponder.smart_chute.text_2": "UNLOCALIZED: Items in the filter slot specify what exactly they can extract and transfer", + "create.ponder.smart_chute.text_3": "UNLOCALIZED: Use the Mouse Wheel to specify the extracted stack size", + "create.ponder.smart_chute.text_4": "UNLOCALIZED: Redstone power will prevent Smart Chutes from acting.", + "create.ponder.speedometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Speedometer", "create.ponder.speedometer.text_1": "UNLOCALIZED: The Speedometer displays the current Speed of the attached components", "create.ponder.speedometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", 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 347fa2a27..55a1d458a 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: 1137", + "_": "Missing Localizations: 1155", "_": "->------------------------] Game Elements [------------------------<-", @@ -1907,7 +1907,7 @@ "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_directions.text_6": "UNLOCALIZED: These are all possible directions. Belts 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", @@ -1958,6 +1958,16 @@ "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.chute.header": "UNLOCALIZED: Transporting Items downward via Chutes", + "create.ponder.chute.text_1": "UNLOCALIZED: Chutes can transport items vertically from and to inventories", + "create.ponder.chute.text_2": "UNLOCALIZED: Using the Wrench, a window can be created", + "create.ponder.chute.text_3": "UNLOCALIZED: Placing chutes targeting the side faces of another will make it diagonal", + + "create.ponder.chute_upward.header": "UNLOCALIZED: Transporting Items upward via Chutes", + "create.ponder.chute_upward.text_1": "UNLOCALIZED: Using Encased Fans at the top or bottom, a Chute can move items upward", + "create.ponder.chute_upward.text_2": "UNLOCALIZED: Inspecting chutes with Engineers' Goggles reveals information about the movement direction", + "create.ponder.chute_upward.text_3": "UNLOCALIZED: On the 'blocked' end, items will have to be inserted/taken from the sides", + "create.ponder.clockwork_bearing.header": "UNLOCALIZED: Animating Structures using Clockwork Bearings", "create.ponder.clockwork_bearing.text_1": "UNLOCALIZED: Clockwork Bearings attach to blocks in front of them", "create.ponder.clockwork_bearing.text_2": "UNLOCALIZED: Upon receiving Rotational Force, the structure will be rotated according to the hour of the day", @@ -2022,6 +2032,12 @@ "create.ponder.deployer_redstone.text_2": "UNLOCALIZED: Before stopping, the Deployer will finish any started cycles", "create.ponder.deployer_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.depot.header": "UNLOCALIZED: Using Depots", + "create.ponder.depot.text_1": "UNLOCALIZED: Depots can serve as 'stationary' belt elements", + "create.ponder.depot.text_2": "UNLOCALIZED: Right-Click to manually place or remove Items from it", + "create.ponder.depot.text_3": "UNLOCALIZED: Just like Mechanical Belts, it can provide items to processing", + "create.ponder.depot.text_4": "UNLOCALIZED: ...as well as provide Items to Mechanical Arms", + "create.ponder.empty_blaze_burner.header": "UNLOCALIZED: Using Empty Blaze Burners", "create.ponder.empty_blaze_burner.text_1": "UNLOCALIZED: Right-click a Blaze with the empty burner to capture it", "create.ponder.empty_blaze_burner.text_2": "UNLOCALIZED: Alternatively, Blazes can be collected from their Spawners directly", @@ -2069,7 +2085,7 @@ "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_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.", @@ -2295,6 +2311,12 @@ "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.smart_chute.header": "UNLOCALIZED: Filtering Items using Smart Chutes", + "create.ponder.smart_chute.text_1": "UNLOCALIZED: Smart Chutes are vertical chutes with additional control", + "create.ponder.smart_chute.text_2": "UNLOCALIZED: Items in the filter slot specify what exactly they can extract and transfer", + "create.ponder.smart_chute.text_3": "UNLOCALIZED: Use the Mouse Wheel to specify the extracted stack size", + "create.ponder.smart_chute.text_4": "UNLOCALIZED: Redstone power will prevent Smart Chutes from acting.", + "create.ponder.speedometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Speedometer", "create.ponder.speedometer.text_1": "UNLOCALIZED: The Speedometer displays the current Speed of the attached components", "create.ponder.speedometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", 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 763c8bb7b..aad6e8ef3 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: 473", + "_": "Missing Localizations: 491", "_": "->------------------------] Game Elements [------------------------<-", @@ -1907,7 +1907,7 @@ "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_directions.text_6": "UNLOCALIZED: These are all possible directions. Belts 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", @@ -1958,6 +1958,16 @@ "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.chute.header": "UNLOCALIZED: Transporting Items downward via Chutes", + "create.ponder.chute.text_1": "UNLOCALIZED: Chutes can transport items vertically from and to inventories", + "create.ponder.chute.text_2": "UNLOCALIZED: Using the Wrench, a window can be created", + "create.ponder.chute.text_3": "UNLOCALIZED: Placing chutes targeting the side faces of another will make it diagonal", + + "create.ponder.chute_upward.header": "UNLOCALIZED: Transporting Items upward via Chutes", + "create.ponder.chute_upward.text_1": "UNLOCALIZED: Using Encased Fans at the top or bottom, a Chute can move items upward", + "create.ponder.chute_upward.text_2": "UNLOCALIZED: Inspecting chutes with Engineers' Goggles reveals information about the movement direction", + "create.ponder.chute_upward.text_3": "UNLOCALIZED: On the 'blocked' end, items will have to be inserted/taken from the sides", + "create.ponder.clockwork_bearing.header": "UNLOCALIZED: Animating Structures using Clockwork Bearings", "create.ponder.clockwork_bearing.text_1": "UNLOCALIZED: Clockwork Bearings attach to blocks in front of them", "create.ponder.clockwork_bearing.text_2": "UNLOCALIZED: Upon receiving Rotational Force, the structure will be rotated according to the hour of the day", @@ -2022,6 +2032,12 @@ "create.ponder.deployer_redstone.text_2": "UNLOCALIZED: Before stopping, the Deployer will finish any started cycles", "create.ponder.deployer_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.depot.header": "UNLOCALIZED: Using Depots", + "create.ponder.depot.text_1": "UNLOCALIZED: Depots can serve as 'stationary' belt elements", + "create.ponder.depot.text_2": "UNLOCALIZED: Right-Click to manually place or remove Items from it", + "create.ponder.depot.text_3": "UNLOCALIZED: Just like Mechanical Belts, it can provide items to processing", + "create.ponder.depot.text_4": "UNLOCALIZED: ...as well as provide Items to Mechanical Arms", + "create.ponder.empty_blaze_burner.header": "UNLOCALIZED: Using Empty Blaze Burners", "create.ponder.empty_blaze_burner.text_1": "UNLOCALIZED: Right-click a Blaze with the empty burner to capture it", "create.ponder.empty_blaze_burner.text_2": "UNLOCALIZED: Alternatively, Blazes can be collected from their Spawners directly", @@ -2069,7 +2085,7 @@ "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_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.", @@ -2295,6 +2311,12 @@ "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.smart_chute.header": "UNLOCALIZED: Filtering Items using Smart Chutes", + "create.ponder.smart_chute.text_1": "UNLOCALIZED: Smart Chutes are vertical chutes with additional control", + "create.ponder.smart_chute.text_2": "UNLOCALIZED: Items in the filter slot specify what exactly they can extract and transfer", + "create.ponder.smart_chute.text_3": "UNLOCALIZED: Use the Mouse Wheel to specify the extracted stack size", + "create.ponder.smart_chute.text_4": "UNLOCALIZED: Redstone power will prevent Smart Chutes from acting.", + "create.ponder.speedometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Speedometer", "create.ponder.speedometer.text_1": "UNLOCALIZED: The Speedometer displays the current Speed of the attached components", "create.ponder.speedometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", 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 9b23ee4d0..47b38141f 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: 480", + "_": "Missing Localizations: 498", "_": "->------------------------] Game Elements [------------------------<-", @@ -1907,7 +1907,7 @@ "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_directions.text_6": "UNLOCALIZED: These are all possible directions. Belts 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", @@ -1958,6 +1958,16 @@ "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.chute.header": "UNLOCALIZED: Transporting Items downward via Chutes", + "create.ponder.chute.text_1": "UNLOCALIZED: Chutes can transport items vertically from and to inventories", + "create.ponder.chute.text_2": "UNLOCALIZED: Using the Wrench, a window can be created", + "create.ponder.chute.text_3": "UNLOCALIZED: Placing chutes targeting the side faces of another will make it diagonal", + + "create.ponder.chute_upward.header": "UNLOCALIZED: Transporting Items upward via Chutes", + "create.ponder.chute_upward.text_1": "UNLOCALIZED: Using Encased Fans at the top or bottom, a Chute can move items upward", + "create.ponder.chute_upward.text_2": "UNLOCALIZED: Inspecting chutes with Engineers' Goggles reveals information about the movement direction", + "create.ponder.chute_upward.text_3": "UNLOCALIZED: On the 'blocked' end, items will have to be inserted/taken from the sides", + "create.ponder.clockwork_bearing.header": "UNLOCALIZED: Animating Structures using Clockwork Bearings", "create.ponder.clockwork_bearing.text_1": "UNLOCALIZED: Clockwork Bearings attach to blocks in front of them", "create.ponder.clockwork_bearing.text_2": "UNLOCALIZED: Upon receiving Rotational Force, the structure will be rotated according to the hour of the day", @@ -2022,6 +2032,12 @@ "create.ponder.deployer_redstone.text_2": "UNLOCALIZED: Before stopping, the Deployer will finish any started cycles", "create.ponder.deployer_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.depot.header": "UNLOCALIZED: Using Depots", + "create.ponder.depot.text_1": "UNLOCALIZED: Depots can serve as 'stationary' belt elements", + "create.ponder.depot.text_2": "UNLOCALIZED: Right-Click to manually place or remove Items from it", + "create.ponder.depot.text_3": "UNLOCALIZED: Just like Mechanical Belts, it can provide items to processing", + "create.ponder.depot.text_4": "UNLOCALIZED: ...as well as provide Items to Mechanical Arms", + "create.ponder.empty_blaze_burner.header": "UNLOCALIZED: Using Empty Blaze Burners", "create.ponder.empty_blaze_burner.text_1": "UNLOCALIZED: Right-click a Blaze with the empty burner to capture it", "create.ponder.empty_blaze_burner.text_2": "UNLOCALIZED: Alternatively, Blazes can be collected from their Spawners directly", @@ -2069,7 +2085,7 @@ "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_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.", @@ -2295,6 +2311,12 @@ "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.smart_chute.header": "UNLOCALIZED: Filtering Items using Smart Chutes", + "create.ponder.smart_chute.text_1": "UNLOCALIZED: Smart Chutes are vertical chutes with additional control", + "create.ponder.smart_chute.text_2": "UNLOCALIZED: Items in the filter slot specify what exactly they can extract and transfer", + "create.ponder.smart_chute.text_3": "UNLOCALIZED: Use the Mouse Wheel to specify the extracted stack size", + "create.ponder.smart_chute.text_4": "UNLOCALIZED: Redstone power will prevent Smart Chutes from acting.", + "create.ponder.speedometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Speedometer", "create.ponder.speedometer.text_1": "UNLOCALIZED: The Speedometer displays the current Speed of the attached components", "create.ponder.speedometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", 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 51410c720..92968da8a 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: 526", + "_": "Missing Localizations: 544", "_": "->------------------------] Game Elements [------------------------<-", @@ -1907,7 +1907,7 @@ "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_directions.text_6": "UNLOCALIZED: These are all possible directions. Belts 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", @@ -1958,6 +1958,16 @@ "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.chute.header": "UNLOCALIZED: Transporting Items downward via Chutes", + "create.ponder.chute.text_1": "UNLOCALIZED: Chutes can transport items vertically from and to inventories", + "create.ponder.chute.text_2": "UNLOCALIZED: Using the Wrench, a window can be created", + "create.ponder.chute.text_3": "UNLOCALIZED: Placing chutes targeting the side faces of another will make it diagonal", + + "create.ponder.chute_upward.header": "UNLOCALIZED: Transporting Items upward via Chutes", + "create.ponder.chute_upward.text_1": "UNLOCALIZED: Using Encased Fans at the top or bottom, a Chute can move items upward", + "create.ponder.chute_upward.text_2": "UNLOCALIZED: Inspecting chutes with Engineers' Goggles reveals information about the movement direction", + "create.ponder.chute_upward.text_3": "UNLOCALIZED: On the 'blocked' end, items will have to be inserted/taken from the sides", + "create.ponder.clockwork_bearing.header": "UNLOCALIZED: Animating Structures using Clockwork Bearings", "create.ponder.clockwork_bearing.text_1": "UNLOCALIZED: Clockwork Bearings attach to blocks in front of them", "create.ponder.clockwork_bearing.text_2": "UNLOCALIZED: Upon receiving Rotational Force, the structure will be rotated according to the hour of the day", @@ -2022,6 +2032,12 @@ "create.ponder.deployer_redstone.text_2": "UNLOCALIZED: Before stopping, the Deployer will finish any started cycles", "create.ponder.deployer_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.depot.header": "UNLOCALIZED: Using Depots", + "create.ponder.depot.text_1": "UNLOCALIZED: Depots can serve as 'stationary' belt elements", + "create.ponder.depot.text_2": "UNLOCALIZED: Right-Click to manually place or remove Items from it", + "create.ponder.depot.text_3": "UNLOCALIZED: Just like Mechanical Belts, it can provide items to processing", + "create.ponder.depot.text_4": "UNLOCALIZED: ...as well as provide Items to Mechanical Arms", + "create.ponder.empty_blaze_burner.header": "UNLOCALIZED: Using Empty Blaze Burners", "create.ponder.empty_blaze_burner.text_1": "UNLOCALIZED: Right-click a Blaze with the empty burner to capture it", "create.ponder.empty_blaze_burner.text_2": "UNLOCALIZED: Alternatively, Blazes can be collected from their Spawners directly", @@ -2069,7 +2085,7 @@ "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_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.", @@ -2295,6 +2311,12 @@ "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.smart_chute.header": "UNLOCALIZED: Filtering Items using Smart Chutes", + "create.ponder.smart_chute.text_1": "UNLOCALIZED: Smart Chutes are vertical chutes with additional control", + "create.ponder.smart_chute.text_2": "UNLOCALIZED: Items in the filter slot specify what exactly they can extract and transfer", + "create.ponder.smart_chute.text_3": "UNLOCALIZED: Use the Mouse Wheel to specify the extracted stack size", + "create.ponder.smart_chute.text_4": "UNLOCALIZED: Redstone power will prevent Smart Chutes from acting.", + "create.ponder.speedometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Speedometer", "create.ponder.speedometer.text_1": "UNLOCALIZED: The Speedometer displays the current Speed of the attached components", "create.ponder.speedometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", 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 402bc2bca..c8f125878 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: 1624", + "_": "Missing Localizations: 1642", "_": "->------------------------] Game Elements [------------------------<-", @@ -1907,7 +1907,7 @@ "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_directions.text_6": "UNLOCALIZED: These are all possible directions. Belts 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", @@ -1958,6 +1958,16 @@ "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.chute.header": "UNLOCALIZED: Transporting Items downward via Chutes", + "create.ponder.chute.text_1": "UNLOCALIZED: Chutes can transport items vertically from and to inventories", + "create.ponder.chute.text_2": "UNLOCALIZED: Using the Wrench, a window can be created", + "create.ponder.chute.text_3": "UNLOCALIZED: Placing chutes targeting the side faces of another will make it diagonal", + + "create.ponder.chute_upward.header": "UNLOCALIZED: Transporting Items upward via Chutes", + "create.ponder.chute_upward.text_1": "UNLOCALIZED: Using Encased Fans at the top or bottom, a Chute can move items upward", + "create.ponder.chute_upward.text_2": "UNLOCALIZED: Inspecting chutes with Engineers' Goggles reveals information about the movement direction", + "create.ponder.chute_upward.text_3": "UNLOCALIZED: On the 'blocked' end, items will have to be inserted/taken from the sides", + "create.ponder.clockwork_bearing.header": "UNLOCALIZED: Animating Structures using Clockwork Bearings", "create.ponder.clockwork_bearing.text_1": "UNLOCALIZED: Clockwork Bearings attach to blocks in front of them", "create.ponder.clockwork_bearing.text_2": "UNLOCALIZED: Upon receiving Rotational Force, the structure will be rotated according to the hour of the day", @@ -2022,6 +2032,12 @@ "create.ponder.deployer_redstone.text_2": "UNLOCALIZED: Before stopping, the Deployer will finish any started cycles", "create.ponder.deployer_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.depot.header": "UNLOCALIZED: Using Depots", + "create.ponder.depot.text_1": "UNLOCALIZED: Depots can serve as 'stationary' belt elements", + "create.ponder.depot.text_2": "UNLOCALIZED: Right-Click to manually place or remove Items from it", + "create.ponder.depot.text_3": "UNLOCALIZED: Just like Mechanical Belts, it can provide items to processing", + "create.ponder.depot.text_4": "UNLOCALIZED: ...as well as provide Items to Mechanical Arms", + "create.ponder.empty_blaze_burner.header": "UNLOCALIZED: Using Empty Blaze Burners", "create.ponder.empty_blaze_burner.text_1": "UNLOCALIZED: Right-click a Blaze with the empty burner to capture it", "create.ponder.empty_blaze_burner.text_2": "UNLOCALIZED: Alternatively, Blazes can be collected from their Spawners directly", @@ -2069,7 +2085,7 @@ "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_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.", @@ -2295,6 +2311,12 @@ "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.smart_chute.header": "UNLOCALIZED: Filtering Items using Smart Chutes", + "create.ponder.smart_chute.text_1": "UNLOCALIZED: Smart Chutes are vertical chutes with additional control", + "create.ponder.smart_chute.text_2": "UNLOCALIZED: Items in the filter slot specify what exactly they can extract and transfer", + "create.ponder.smart_chute.text_3": "UNLOCALIZED: Use the Mouse Wheel to specify the extracted stack size", + "create.ponder.smart_chute.text_4": "UNLOCALIZED: Redstone power will prevent Smart Chutes from acting.", + "create.ponder.speedometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Speedometer", "create.ponder.speedometer.text_1": "UNLOCALIZED: The Speedometer displays the current Speed of the attached components", "create.ponder.speedometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", 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 92c791d67..969babaa9 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: 1690", + "_": "Missing Localizations: 1708", "_": "->------------------------] Game Elements [------------------------<-", @@ -1907,7 +1907,7 @@ "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_directions.text_6": "UNLOCALIZED: These are all possible directions. Belts 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", @@ -1958,6 +1958,16 @@ "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.chute.header": "UNLOCALIZED: Transporting Items downward via Chutes", + "create.ponder.chute.text_1": "UNLOCALIZED: Chutes can transport items vertically from and to inventories", + "create.ponder.chute.text_2": "UNLOCALIZED: Using the Wrench, a window can be created", + "create.ponder.chute.text_3": "UNLOCALIZED: Placing chutes targeting the side faces of another will make it diagonal", + + "create.ponder.chute_upward.header": "UNLOCALIZED: Transporting Items upward via Chutes", + "create.ponder.chute_upward.text_1": "UNLOCALIZED: Using Encased Fans at the top or bottom, a Chute can move items upward", + "create.ponder.chute_upward.text_2": "UNLOCALIZED: Inspecting chutes with Engineers' Goggles reveals information about the movement direction", + "create.ponder.chute_upward.text_3": "UNLOCALIZED: On the 'blocked' end, items will have to be inserted/taken from the sides", + "create.ponder.clockwork_bearing.header": "UNLOCALIZED: Animating Structures using Clockwork Bearings", "create.ponder.clockwork_bearing.text_1": "UNLOCALIZED: Clockwork Bearings attach to blocks in front of them", "create.ponder.clockwork_bearing.text_2": "UNLOCALIZED: Upon receiving Rotational Force, the structure will be rotated according to the hour of the day", @@ -2022,6 +2032,12 @@ "create.ponder.deployer_redstone.text_2": "UNLOCALIZED: Before stopping, the Deployer will finish any started cycles", "create.ponder.deployer_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.depot.header": "UNLOCALIZED: Using Depots", + "create.ponder.depot.text_1": "UNLOCALIZED: Depots can serve as 'stationary' belt elements", + "create.ponder.depot.text_2": "UNLOCALIZED: Right-Click to manually place or remove Items from it", + "create.ponder.depot.text_3": "UNLOCALIZED: Just like Mechanical Belts, it can provide items to processing", + "create.ponder.depot.text_4": "UNLOCALIZED: ...as well as provide Items to Mechanical Arms", + "create.ponder.empty_blaze_burner.header": "UNLOCALIZED: Using Empty Blaze Burners", "create.ponder.empty_blaze_burner.text_1": "UNLOCALIZED: Right-click a Blaze with the empty burner to capture it", "create.ponder.empty_blaze_burner.text_2": "UNLOCALIZED: Alternatively, Blazes can be collected from their Spawners directly", @@ -2069,7 +2085,7 @@ "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_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.", @@ -2295,6 +2311,12 @@ "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.smart_chute.header": "UNLOCALIZED: Filtering Items using Smart Chutes", + "create.ponder.smart_chute.text_1": "UNLOCALIZED: Smart Chutes are vertical chutes with additional control", + "create.ponder.smart_chute.text_2": "UNLOCALIZED: Items in the filter slot specify what exactly they can extract and transfer", + "create.ponder.smart_chute.text_3": "UNLOCALIZED: Use the Mouse Wheel to specify the extracted stack size", + "create.ponder.smart_chute.text_4": "UNLOCALIZED: Redstone power will prevent Smart Chutes from acting.", + "create.ponder.speedometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Speedometer", "create.ponder.speedometer.text_1": "UNLOCALIZED: The Speedometer displays the current Speed of the attached components", "create.ponder.speedometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", 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 660e3c42c..7d277317b 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: 476", + "_": "Missing Localizations: 494", "_": "->------------------------] Game Elements [------------------------<-", @@ -1907,7 +1907,7 @@ "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_directions.text_6": "UNLOCALIZED: These are all possible directions. Belts 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", @@ -1958,6 +1958,16 @@ "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.chute.header": "UNLOCALIZED: Transporting Items downward via Chutes", + "create.ponder.chute.text_1": "UNLOCALIZED: Chutes can transport items vertically from and to inventories", + "create.ponder.chute.text_2": "UNLOCALIZED: Using the Wrench, a window can be created", + "create.ponder.chute.text_3": "UNLOCALIZED: Placing chutes targeting the side faces of another will make it diagonal", + + "create.ponder.chute_upward.header": "UNLOCALIZED: Transporting Items upward via Chutes", + "create.ponder.chute_upward.text_1": "UNLOCALIZED: Using Encased Fans at the top or bottom, a Chute can move items upward", + "create.ponder.chute_upward.text_2": "UNLOCALIZED: Inspecting chutes with Engineers' Goggles reveals information about the movement direction", + "create.ponder.chute_upward.text_3": "UNLOCALIZED: On the 'blocked' end, items will have to be inserted/taken from the sides", + "create.ponder.clockwork_bearing.header": "UNLOCALIZED: Animating Structures using Clockwork Bearings", "create.ponder.clockwork_bearing.text_1": "UNLOCALIZED: Clockwork Bearings attach to blocks in front of them", "create.ponder.clockwork_bearing.text_2": "UNLOCALIZED: Upon receiving Rotational Force, the structure will be rotated according to the hour of the day", @@ -2022,6 +2032,12 @@ "create.ponder.deployer_redstone.text_2": "UNLOCALIZED: Before stopping, the Deployer will finish any started cycles", "create.ponder.deployer_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.depot.header": "UNLOCALIZED: Using Depots", + "create.ponder.depot.text_1": "UNLOCALIZED: Depots can serve as 'stationary' belt elements", + "create.ponder.depot.text_2": "UNLOCALIZED: Right-Click to manually place or remove Items from it", + "create.ponder.depot.text_3": "UNLOCALIZED: Just like Mechanical Belts, it can provide items to processing", + "create.ponder.depot.text_4": "UNLOCALIZED: ...as well as provide Items to Mechanical Arms", + "create.ponder.empty_blaze_burner.header": "UNLOCALIZED: Using Empty Blaze Burners", "create.ponder.empty_blaze_burner.text_1": "UNLOCALIZED: Right-click a Blaze with the empty burner to capture it", "create.ponder.empty_blaze_burner.text_2": "UNLOCALIZED: Alternatively, Blazes can be collected from their Spawners directly", @@ -2069,7 +2085,7 @@ "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_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.", @@ -2295,6 +2311,12 @@ "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.smart_chute.header": "UNLOCALIZED: Filtering Items using Smart Chutes", + "create.ponder.smart_chute.text_1": "UNLOCALIZED: Smart Chutes are vertical chutes with additional control", + "create.ponder.smart_chute.text_2": "UNLOCALIZED: Items in the filter slot specify what exactly they can extract and transfer", + "create.ponder.smart_chute.text_3": "UNLOCALIZED: Use the Mouse Wheel to specify the extracted stack size", + "create.ponder.smart_chute.text_4": "UNLOCALIZED: Redstone power will prevent Smart Chutes from acting.", + "create.ponder.speedometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Speedometer", "create.ponder.speedometer.text_1": "UNLOCALIZED: The Speedometer displays the current Speed of the attached components", "create.ponder.speedometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", 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 7f3b14f8d..7befc4728 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: 474", + "_": "Missing Localizations: 492", "_": "->------------------------] Game Elements [------------------------<-", @@ -1907,7 +1907,7 @@ "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_directions.text_6": "UNLOCALIZED: These are all possible directions. Belts 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", @@ -1958,6 +1958,16 @@ "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.chute.header": "UNLOCALIZED: Transporting Items downward via Chutes", + "create.ponder.chute.text_1": "UNLOCALIZED: Chutes can transport items vertically from and to inventories", + "create.ponder.chute.text_2": "UNLOCALIZED: Using the Wrench, a window can be created", + "create.ponder.chute.text_3": "UNLOCALIZED: Placing chutes targeting the side faces of another will make it diagonal", + + "create.ponder.chute_upward.header": "UNLOCALIZED: Transporting Items upward via Chutes", + "create.ponder.chute_upward.text_1": "UNLOCALIZED: Using Encased Fans at the top or bottom, a Chute can move items upward", + "create.ponder.chute_upward.text_2": "UNLOCALIZED: Inspecting chutes with Engineers' Goggles reveals information about the movement direction", + "create.ponder.chute_upward.text_3": "UNLOCALIZED: On the 'blocked' end, items will have to be inserted/taken from the sides", + "create.ponder.clockwork_bearing.header": "UNLOCALIZED: Animating Structures using Clockwork Bearings", "create.ponder.clockwork_bearing.text_1": "UNLOCALIZED: Clockwork Bearings attach to blocks in front of them", "create.ponder.clockwork_bearing.text_2": "UNLOCALIZED: Upon receiving Rotational Force, the structure will be rotated according to the hour of the day", @@ -2022,6 +2032,12 @@ "create.ponder.deployer_redstone.text_2": "UNLOCALIZED: Before stopping, the Deployer will finish any started cycles", "create.ponder.deployer_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.depot.header": "UNLOCALIZED: Using Depots", + "create.ponder.depot.text_1": "UNLOCALIZED: Depots can serve as 'stationary' belt elements", + "create.ponder.depot.text_2": "UNLOCALIZED: Right-Click to manually place or remove Items from it", + "create.ponder.depot.text_3": "UNLOCALIZED: Just like Mechanical Belts, it can provide items to processing", + "create.ponder.depot.text_4": "UNLOCALIZED: ...as well as provide Items to Mechanical Arms", + "create.ponder.empty_blaze_burner.header": "UNLOCALIZED: Using Empty Blaze Burners", "create.ponder.empty_blaze_burner.text_1": "UNLOCALIZED: Right-click a Blaze with the empty burner to capture it", "create.ponder.empty_blaze_burner.text_2": "UNLOCALIZED: Alternatively, Blazes can be collected from their Spawners directly", @@ -2069,7 +2085,7 @@ "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_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.", @@ -2295,6 +2311,12 @@ "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.smart_chute.header": "UNLOCALIZED: Filtering Items using Smart Chutes", + "create.ponder.smart_chute.text_1": "UNLOCALIZED: Smart Chutes are vertical chutes with additional control", + "create.ponder.smart_chute.text_2": "UNLOCALIZED: Items in the filter slot specify what exactly they can extract and transfer", + "create.ponder.smart_chute.text_3": "UNLOCALIZED: Use the Mouse Wheel to specify the extracted stack size", + "create.ponder.smart_chute.text_4": "UNLOCALIZED: Redstone power will prevent Smart Chutes from acting.", + "create.ponder.speedometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Speedometer", "create.ponder.speedometer.text_1": "UNLOCALIZED: The Speedometer displays the current Speed of the attached components", "create.ponder.speedometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", 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 6121864c8..e8d27316c 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: 479", + "_": "Missing Localizations: 497", "_": "->------------------------] Game Elements [------------------------<-", @@ -1907,7 +1907,7 @@ "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_directions.text_6": "UNLOCALIZED: These are all possible directions. Belts 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", @@ -1958,6 +1958,16 @@ "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.chute.header": "UNLOCALIZED: Transporting Items downward via Chutes", + "create.ponder.chute.text_1": "UNLOCALIZED: Chutes can transport items vertically from and to inventories", + "create.ponder.chute.text_2": "UNLOCALIZED: Using the Wrench, a window can be created", + "create.ponder.chute.text_3": "UNLOCALIZED: Placing chutes targeting the side faces of another will make it diagonal", + + "create.ponder.chute_upward.header": "UNLOCALIZED: Transporting Items upward via Chutes", + "create.ponder.chute_upward.text_1": "UNLOCALIZED: Using Encased Fans at the top or bottom, a Chute can move items upward", + "create.ponder.chute_upward.text_2": "UNLOCALIZED: Inspecting chutes with Engineers' Goggles reveals information about the movement direction", + "create.ponder.chute_upward.text_3": "UNLOCALIZED: On the 'blocked' end, items will have to be inserted/taken from the sides", + "create.ponder.clockwork_bearing.header": "UNLOCALIZED: Animating Structures using Clockwork Bearings", "create.ponder.clockwork_bearing.text_1": "UNLOCALIZED: Clockwork Bearings attach to blocks in front of them", "create.ponder.clockwork_bearing.text_2": "UNLOCALIZED: Upon receiving Rotational Force, the structure will be rotated according to the hour of the day", @@ -2022,6 +2032,12 @@ "create.ponder.deployer_redstone.text_2": "UNLOCALIZED: Before stopping, the Deployer will finish any started cycles", "create.ponder.deployer_redstone.text_3": "UNLOCALIZED: Thus, a negative pulse can be used to trigger exactly one activation cycle", + "create.ponder.depot.header": "UNLOCALIZED: Using Depots", + "create.ponder.depot.text_1": "UNLOCALIZED: Depots can serve as 'stationary' belt elements", + "create.ponder.depot.text_2": "UNLOCALIZED: Right-Click to manually place or remove Items from it", + "create.ponder.depot.text_3": "UNLOCALIZED: Just like Mechanical Belts, it can provide items to processing", + "create.ponder.depot.text_4": "UNLOCALIZED: ...as well as provide Items to Mechanical Arms", + "create.ponder.empty_blaze_burner.header": "UNLOCALIZED: Using Empty Blaze Burners", "create.ponder.empty_blaze_burner.text_1": "UNLOCALIZED: Right-click a Blaze with the empty burner to capture it", "create.ponder.empty_blaze_burner.text_2": "UNLOCALIZED: Alternatively, Blazes can be collected from their Spawners directly", @@ -2069,7 +2085,7 @@ "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_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.", @@ -2295,6 +2311,12 @@ "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.smart_chute.header": "UNLOCALIZED: Filtering Items using Smart Chutes", + "create.ponder.smart_chute.text_1": "UNLOCALIZED: Smart Chutes are vertical chutes with additional control", + "create.ponder.smart_chute.text_2": "UNLOCALIZED: Items in the filter slot specify what exactly they can extract and transfer", + "create.ponder.smart_chute.text_3": "UNLOCALIZED: Use the Mouse Wheel to specify the extracted stack size", + "create.ponder.smart_chute.text_4": "UNLOCALIZED: Redstone power will prevent Smart Chutes from acting.", + "create.ponder.speedometer.header": "UNLOCALIZED: Monitoring Kinetic information using the Speedometer", "create.ponder.speedometer.text_1": "UNLOCALIZED: The Speedometer displays the current Speed of the attached components", "create.ponder.speedometer.text_2": "UNLOCALIZED: When wearing Engineers' Goggles, the player can get more detailed information from the Gauge", diff --git a/src/generated/resources/data/create/advancements/aesthetics.json b/src/generated/resources/data/create/advancements/aesthetics.json index d723cbe38..59a86f429 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:cogwheel", - "create:large_cogwheel" + "create:large_cogwheel", + "create:cogwheel" ] } }, 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 bcb39ea99..3ad112e59 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 @@ -7,6 +7,8 @@ import java.util.Random; import java.util.function.Predicate; import java.util.stream.Collectors; +import javax.annotation.ParametersAreNonnullByDefault; + import com.simibubi.create.AllRecipeTypes; import com.simibubi.create.content.contraptions.components.actors.BlockBreakingKineticTileEntity; import com.simibubi.create.content.contraptions.processing.ProcessingInventory; @@ -57,15 +59,13 @@ import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; -import javax.annotation.ParametersAreNonnullByDefault; - - @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault public class SawTileEntity extends BlockBreakingKineticTileEntity { private static final Object cuttingRecipesKey = new Object(); - public static final LazyValue> woodcuttingRecipeType = new LazyValue<>(() -> Registry.RECIPE_TYPE.getOrDefault(new ResourceLocation("druidcraft", "woodcutting"))); + public static final LazyValue> woodcuttingRecipeType = + new LazyValue<>(() -> Registry.RECIPE_TYPE.getOrDefault(new ResourceLocation("druidcraft", "woodcutting"))); public ProcessingInventory inventory; private int recipeIndex; @@ -151,10 +151,14 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity { continue; ItemStack tryExportingToBeltFunnel = getBehaviour(DirectBeltInputBehaviour.TYPE) .tryExportingToBeltFunnel(stack, itemMovementFacing.getOpposite()); - if (tryExportingToBeltFunnel.getCount() != stack.getCount()) { - inventory.setStackInSlot(slot, tryExportingToBeltFunnel); - notifyUpdate(); - return; + if (tryExportingToBeltFunnel != null) { + if (tryExportingToBeltFunnel.getCount() != stack.getCount()) { + inventory.setStackInSlot(slot, tryExportingToBeltFunnel); + notifyUpdate(); + return; + } + if (!tryExportingToBeltFunnel.isEmpty()) + return; } } @@ -277,19 +281,19 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity { private List> getRecipes() { /* - Predicate> types = AllConfigs.SERVER.recipes.allowStonecuttingOnSaw.get() - ? RecipeConditions.isOfType(IRecipeType.STONECUTTING, AllRecipeTypes.CUTTING.getType()) - : RecipeConditions.isOfType(AllRecipeTypes.CUTTING.getType()); - + * Predicate> types = + * AllConfigs.SERVER.recipes.allowStonecuttingOnSaw.get() ? + * RecipeConditions.isOfType(IRecipeType.STONECUTTING, + * AllRecipeTypes.CUTTING.getType()) : + * RecipeConditions.isOfType(AllRecipeTypes.CUTTING.getType()); + * */ - Predicate> types = RecipeConditions.isOfType( - AllRecipeTypes.CUTTING.getType(), + Predicate> types = RecipeConditions.isOfType(AllRecipeTypes.CUTTING.getType(), AllConfigs.SERVER.recipes.allowStonecuttingOnSaw.get() ? IRecipeType.STONECUTTING : null, - AllConfigs.SERVER.recipes.allowWoodcuttingOnSaw.get() ? woodcuttingRecipeType.getValue() : null - ); + AllConfigs.SERVER.recipes.allowWoodcuttingOnSaw.get() ? woodcuttingRecipeType.getValue() : null); - List> startedSearch = RecipeFinder.get(cuttingRecipesKey, world, types); + List> startedSearch = RecipeFinder.get(cuttingRecipesKey, world, types); return startedSearch.stream() .filter(RecipeConditions.outputMatchesFilter(filtering)) .filter(RecipeConditions.firstIngredientMatches(inventory.getStackInSlot(0))) 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 39f9bc7a1..671202efb 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 @@ -99,7 +99,7 @@ public class ItemDrainTileEntity extends SmartTileEntity implements IHaveGoggleI } boolean onClient = world.isRemote && !isVirtual(); - + if (processingTicks > 0) { heldItem.prevBeltPosition = .5f; boolean wasAtBeginning = processingTicks == FILLING_TIME; @@ -129,13 +129,17 @@ public class ItemDrainTileEntity extends SmartTileEntity implements IHaveGoggleI ItemStack tryExportingToBeltFunnel = getBehaviour(DirectBeltInputBehaviour.TYPE) .tryExportingToBeltFunnel(heldItem.stack, side.getOpposite()); - if (tryExportingToBeltFunnel.getCount() != heldItem.stack.getCount()) { - if (tryExportingToBeltFunnel.isEmpty()) - heldItem = null; - else - heldItem.stack = tryExportingToBeltFunnel; - notifyUpdate(); - return; + if (tryExportingToBeltFunnel != null) { + if (tryExportingToBeltFunnel.getCount() != heldItem.stack.getCount()) { + if (tryExportingToBeltFunnel.isEmpty()) + heldItem = null; + else + heldItem.stack = tryExportingToBeltFunnel; + notifyUpdate(); + return; + } + if (!tryExportingToBeltFunnel.isEmpty()) + return; } BlockPos nextPosition = pos.offset(side); diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltTileEntity.java index 49f3725d2..4c16a9d29 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltTileEntity.java @@ -237,7 +237,8 @@ public class BeltTileEntity extends KineticTileEntity implements ILightListener if (casingBefore == casing) return; - requestModelDataUpdate(); + if (!isVirtual()) + requestModelDataUpdate(); if (hasWorld()) world.notifyBlockUpdate(getPos(), getBlockState(), getBlockState(), 16); } @@ -290,10 +291,8 @@ public class BeltTileEntity extends KineticTileEntity implements ILightListener } public boolean isController() { - return controller != null && - pos.getX() == controller.getX() && - pos.getY() == controller.getY() && - pos.getZ() == controller.getZ(); + return controller != null && pos.getX() == controller.getX() && pos.getY() == controller.getY() + && pos.getZ() == controller.getZ(); } public float getBeltMovementSpeed() { 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 1dbd82087..870da7d9d 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 @@ -107,6 +107,12 @@ public class BeltInventory { // Don't move if held by processing (client) if (world.isRemote && currentItem.locked) continue; + + // Don't move if held by external components + if (currentItem.lockedExternally) { + currentItem.lockedExternally = false; + continue; + } // Don't move if other items are waiting in front float currentPos = currentItem.beltPosition; diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/transport/TransportedItemStack.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/transport/TransportedItemStack.java index 6dffb5056..5202ea1df 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/transport/TransportedItemStack.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/transport/TransportedItemStack.java @@ -20,6 +20,7 @@ public class TransportedItemStack implements Comparable { public int insertedAt; public Direction insertedFrom; public boolean locked; + public boolean lockedExternally; public float prevBeltPosition; public float prevSideOffset; @@ -73,7 +74,10 @@ public class TransportedItemStack implements Comparable { nbt.putInt("InSegment", insertedAt); nbt.putInt("Angle", angle); nbt.putInt("InDirection", insertedFrom.getIndex()); - nbt.putBoolean("Locked", locked); + if (locked) + nbt.putBoolean("Locked", locked); + if (lockedExternally) + nbt.putBoolean("LockedExternally", lockedExternally); return nbt; } @@ -87,6 +91,7 @@ public class TransportedItemStack implements Comparable { stack.angle = nbt.getInt("Angle"); stack.insertedFrom = Direction.byIndex(nbt.getInt("InDirection")); stack.locked = nbt.getBoolean("Locked"); + stack.lockedExternally = nbt.getBoolean("LockedExternally"); return stack; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/CogWheelBlock.java b/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/CogWheelBlock.java index 684498740..a3c370ccb 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/CogWheelBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/CogWheelBlock.java @@ -26,102 +26,114 @@ import net.minecraft.world.World; public class CogWheelBlock extends AbstractShaftBlock { - boolean isLarge; + boolean isLarge; - private CogWheelBlock(boolean large, Properties properties) { - super(properties); - isLarge = large; - } + private CogWheelBlock(boolean large, Properties properties) { + super(properties); + isLarge = large; + } - public static CogWheelBlock small(Properties properties) { - return new CogWheelBlock(false, properties); - } + public static CogWheelBlock small(Properties properties) { + return new CogWheelBlock(false, properties); + } - public static CogWheelBlock large(Properties properties) { - return new CogWheelBlock(true, properties); - } + public static CogWheelBlock large(Properties properties) { + return new CogWheelBlock(true, properties); + } - public static boolean isSmallCog(BlockState state) { - return AllBlocks.COGWHEEL.has(state); - } + public static boolean isSmallCog(BlockState state) { + return AllBlocks.COGWHEEL.has(state); + } - public static boolean isLargeCog(BlockState state) { - return AllBlocks.LARGE_COGWHEEL.has(state); - } + public static boolean isLargeCog(BlockState state) { + return AllBlocks.LARGE_COGWHEEL.has(state); + } - @Override - public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) { - return (isLarge ? AllShapes.LARGE_GEAR : AllShapes.SMALL_GEAR).get(state.get(AXIS)); - } + @Override + public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) { + return (isLarge ? AllShapes.LARGE_GEAR : AllShapes.SMALL_GEAR).get(state.get(AXIS)); + } - @Override - public boolean isValidPosition(BlockState state, IWorldReader worldIn, BlockPos pos) { - for (Direction facing : Iterate.directions) { - if (facing.getAxis() == state.get(AXIS)) - continue; + @Override + public boolean isValidPosition(BlockState state, IWorldReader worldIn, BlockPos pos) { + for (Direction facing : Iterate.directions) { + if (facing.getAxis() == state.get(AXIS)) + continue; - BlockState blockState = worldIn.getBlockState(pos.offset(facing)); - if (blockState.has(AXIS) && facing.getAxis() == blockState.get(AXIS)) - continue; - - if (isLargeCog(blockState) || isLarge && isSmallCog(blockState)) - return false; - } - return true; - } + BlockPos offsetPos = pos.offset(facing); + BlockState blockState = worldIn.getBlockState(offsetPos); + if (blockState.has(AXIS) && facing.getAxis() == blockState.get(AXIS)) + continue; - @Override - public BlockState getStateForPlacement(BlockItemUseContext context) { - BlockPos placedOnPos = context.getPos().offset(context.getFace().getOpposite()); - World world = context.getWorld(); - BlockState placedAgainst = world.getBlockState(placedOnPos); - Block block = placedAgainst.getBlock(); + boolean smallCog = isSmallCog(blockState); + if (!smallCog && blockState.getBlock() instanceof IRotate) + smallCog = ((IRotate) blockState.getBlock()).hasIntegratedCogwheel(worldIn, offsetPos, blockState); - if (context.getPlayer() != null && context.getPlayer().isSneaking()) - return this.getDefaultState().with(AXIS, context.getFace().getAxis()); - - BlockState stateBelow = world.getBlockState(context.getPos() - .down()); - IFluidState ifluidstate = context.getWorld().getFluidState(context.getPos()); - if (AllBlocks.ROTATION_SPEED_CONTROLLER.has(stateBelow) && isLarge) { - return this.getDefaultState() - .with(BlockStateProperties.WATERLOGGED, ifluidstate.getFluid() == Fluids.WATER) - .with(AXIS, stateBelow.get(SpeedControllerBlock.HORIZONTAL_AXIS) == Axis.X ? Axis.Z : Axis.X); - } + if (isLargeCog(blockState) || isLarge && smallCog) + return false; + } + return true; + } - if (!(block instanceof IRotate) - || !(((IRotate) block).hasIntegratedCogwheel(world, placedOnPos, placedAgainst))) { - Axis preferredAxis = getPreferredAxis(context); - if (preferredAxis != null) - return this.getDefaultState() - .with(AXIS, preferredAxis) - .with(BlockStateProperties.WATERLOGGED, ifluidstate.getFluid() == Fluids.WATER); - return this.getDefaultState() - .with(AXIS, context.getFace().getAxis()) - .with(BlockStateProperties.WATERLOGGED, ifluidstate.getFluid() == Fluids.WATER); - } + @Override + public BlockState getStateForPlacement(BlockItemUseContext context) { + BlockPos placedOnPos = context.getPos() + .offset(context.getFace() + .getOpposite()); + World world = context.getWorld(); + BlockState placedAgainst = world.getBlockState(placedOnPos); + Block block = placedAgainst.getBlock(); - return getDefaultState().with(AXIS, ((IRotate) block).getRotationAxis(placedAgainst)); - } + if (context.getPlayer() != null && context.getPlayer() + .isSneaking()) + return this.getDefaultState() + .with(AXIS, context.getFace() + .getAxis()); - @Override - public float getParticleTargetRadius() { - return isLarge ? 1.125f : .65f; - } + BlockState stateBelow = world.getBlockState(context.getPos() + .down()); + IFluidState ifluidstate = context.getWorld() + .getFluidState(context.getPos()); + if (AllBlocks.ROTATION_SPEED_CONTROLLER.has(stateBelow) && isLarge) { + return this.getDefaultState() + .with(BlockStateProperties.WATERLOGGED, ifluidstate.getFluid() == Fluids.WATER) + .with(AXIS, stateBelow.get(SpeedControllerBlock.HORIZONTAL_AXIS) == Axis.X ? Axis.Z : Axis.X); + } - @Override - public float getParticleInitialRadius() { - return isLarge ? 1f : .75f; - } + if (!(block instanceof IRotate) + || !(((IRotate) block).hasIntegratedCogwheel(world, placedOnPos, placedAgainst))) { + Axis preferredAxis = getPreferredAxis(context); + if (preferredAxis != null) + return this.getDefaultState() + .with(AXIS, preferredAxis) + .with(BlockStateProperties.WATERLOGGED, ifluidstate.getFluid() == Fluids.WATER); + return this.getDefaultState() + .with(AXIS, context.getFace() + .getAxis()) + .with(BlockStateProperties.WATERLOGGED, ifluidstate.getFluid() == Fluids.WATER); + } - public void fillItemGroup(ItemGroup group, NonNullList items) { - items.add(new ItemStack(this)); - } + return getDefaultState().with(AXIS, ((IRotate) block).getRotationAxis(placedAgainst)); + } - // IRotate + @Override + public float getParticleTargetRadius() { + return isLarge ? 1.125f : .65f; + } - @Override - public boolean hasIntegratedCogwheel(IWorldReader world, BlockPos pos, BlockState state) { - return !isLarge; - } + @Override + public float getParticleInitialRadius() { + return isLarge ? 1f : .75f; + } + + public void fillItemGroup(ItemGroup group, NonNullList items) { + items.add(new ItemStack(this)); + } + + // IRotate + + @Override + public boolean hasIntegratedCogwheel(IWorldReader world, BlockPos pos, BlockState state) { + return !isLarge; + } } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelRenderer.java b/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelRenderer.java index b605298bf..716ba2a6c 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelRenderer.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelRenderer.java @@ -4,7 +4,6 @@ import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.vertex.IVertexBuilder; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.foundation.render.SuperByteBuffer; -import com.simibubi.create.foundation.render.backend.Backend; import com.simibubi.create.foundation.render.backend.FastRenderDispatcher; import com.simibubi.create.foundation.tileEntity.renderer.SmartTileEntityRenderer; import com.simibubi.create.foundation.utility.AngleHelper; diff --git a/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelTileEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelTileEntity.java index c1a58610f..650edfba7 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelTileEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelTileEntity.java @@ -1,19 +1,22 @@ package com.simibubi.create.content.logistics.block.belts.tunnel; -import java.util.*; +import java.util.EnumMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; -import com.simibubi.create.content.logistics.packet.TunnelFlapPacket; -import com.simibubi.create.foundation.gui.widgets.InterpolatedChasingValue; -import com.simibubi.create.foundation.networking.AllPackets; -import com.simibubi.create.foundation.render.backend.FastRenderDispatcher; -import com.simibubi.create.foundation.render.backend.instancing.IInstanceRendered; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; import org.apache.commons.lang3.tuple.Pair; import com.simibubi.create.AllBlocks; import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelBlock.Shape; import com.simibubi.create.content.logistics.block.funnel.BeltFunnelBlock; +import com.simibubi.create.content.logistics.packet.TunnelFlapPacket; +import com.simibubi.create.foundation.gui.widgets.InterpolatedChasingValue; +import com.simibubi.create.foundation.networking.AllPackets; +import com.simibubi.create.foundation.render.backend.FastRenderDispatcher; +import com.simibubi.create.foundation.render.backend.instancing.IInstanceRendered; import com.simibubi.create.foundation.tileEntity.SmartTileEntity; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.utility.Iterate; @@ -29,9 +32,11 @@ import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; import net.minecraft.util.Direction.AxisDirection; +import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.util.Constants.NBT; import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; @@ -100,7 +105,7 @@ public class BeltTunnelTileEntity extends SmartTileEntity implements IInstanceRe super.read(compound, clientPacket); if (clientPacket) - DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> FastRenderDispatcher.enqueueUpdate(this)); + DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> FastRenderDispatcher.enqueueUpdate(this)); } public void updateTunnelConnections() { @@ -172,6 +177,11 @@ public class BeltTunnelTileEntity extends SmartTileEntity implements IInstanceRe flapsToSend.clear(); } + @Override + public boolean shouldRenderAsTE() { + return true; + } + @Override public void addBehaviours(List behaviours) {} diff --git a/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteTileEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteTileEntity.java index 605e2e19e..408907020 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteTileEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/chute/ChuteTileEntity.java @@ -13,6 +13,7 @@ import com.simibubi.create.content.contraptions.components.fan.EncasedFanBlock; import com.simibubi.create.content.contraptions.components.fan.EncasedFanTileEntity; import com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation; import com.simibubi.create.content.contraptions.particle.AirParticleData; +import com.simibubi.create.content.logistics.block.funnel.FunnelBlock; import com.simibubi.create.foundation.advancement.AllTriggers; import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.gui.widgets.InterpolatedValue; @@ -155,7 +156,7 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor if (!handleDownwardOutput(true)) nextOffset = .5f; else if (nextOffset < 0) { - handleDownwardOutput(world.isRemote); + handleDownwardOutput(world.isRemote && !isVirtual()); return; } } @@ -166,7 +167,7 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor if (!handleUpwardOutput(true)) nextOffset = .5f; else if (nextOffset > 1) { - handleUpwardOutput(world.isRemote); + handleUpwardOutput(world.isRemote && !isVirtual()); return; } } @@ -380,6 +381,8 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor .isHorizontal()) return false; + if (FunnelBlock.getFunnelFacing(world.getBlockState(pos.down())) == Direction.DOWN) + return false; if (Block.hasSolidSideOnTop(world, pos.down())) return false; @@ -434,6 +437,8 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor return true; } + if (FunnelBlock.getFunnelFacing(world.getBlockState(pos.up())) == Direction.UP) + return false; if (Block.hasSolidSide(stateAbove, world, pos.up(), Direction.DOWN)) return false; if (!inputChutes.isEmpty()) diff --git a/src/main/java/com/simibubi/create/content/logistics/block/depot/DepotTileEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/depot/DepotTileEntity.java index 2eeedb782..bc0f5ade9 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/depot/DepotTileEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/depot/DepotTileEntity.java @@ -98,6 +98,8 @@ public class DepotTileEntity extends SmartTileEntity { continue; ItemStack afterInsert = getBehaviour(DirectBeltInputBehaviour.TYPE).tryExportingToBeltFunnel(previousItem, null); + if (afterInsert == null) + return false; if (previousItem.getCount() != afterInsert.getCount()) { processingOutputBuffer.setStackInSlot(slot, afterInsert); notifyUpdate(); @@ -108,6 +110,8 @@ public class DepotTileEntity extends SmartTileEntity { ItemStack previousItem = heldItem.stack; ItemStack afterInsert = getBehaviour(DirectBeltInputBehaviour.TYPE).tryExportingToBeltFunnel(previousItem, null); + if (afterInsert == null) + return false; if (previousItem.getCount() != afterInsert.getCount()) { if (afterInsert.isEmpty()) heldItem = null; diff --git a/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelTileEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelTileEntity.java index b32718469..663f81567 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelTileEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelTileEntity.java @@ -263,6 +263,8 @@ public class FunnelTileEntity extends SmartTileEntity implements IHaveHoveringIn return false; if (!(blockState.getBlock() instanceof FunnelBlock)) return false; + if (blockState.get(FunnelBlock.EXTRACTING)) + return false; return FunnelBlock.getFunnelFacing(blockState) == Direction.UP; } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInteractionPoint.java b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInteractionPoint.java index 563bd51cc..4809bb3e1 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInteractionPoint.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInteractionPoint.java @@ -1,5 +1,11 @@ package com.simibubi.create.content.logistics.block.mechanicalArm; +import java.util.function.Supplier; + +import javax.annotation.Nullable; + +import org.apache.commons.lang3.mutable.MutableBoolean; + import com.google.common.collect.ImmutableMap; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlockPartials; @@ -10,17 +16,25 @@ import com.simibubi.create.content.contraptions.components.crafter.MechanicalCra import com.simibubi.create.content.contraptions.components.deployer.DeployerBlock; import com.simibubi.create.content.contraptions.components.saw.SawBlock; import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock; +import com.simibubi.create.content.contraptions.relays.belt.BeltHelper; +import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity; import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelBlock; import com.simibubi.create.content.logistics.block.chute.AbstractChuteBlock; +import com.simibubi.create.content.logistics.block.funnel.AbstractFunnelBlock; +import com.simibubi.create.content.logistics.block.funnel.BeltFunnelBlock; +import com.simibubi.create.content.logistics.block.funnel.BeltFunnelBlock.Shape; import com.simibubi.create.content.logistics.block.funnel.FunnelBlock; import com.simibubi.create.content.logistics.block.funnel.FunnelTileEntity; import com.simibubi.create.foundation.advancement.AllTriggers; import com.simibubi.create.foundation.item.SmartInventory; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; +import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour; +import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour.TransportedResult; import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.inventory.InvManipulationBehaviour; import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.foundation.utility.VecHelper; + import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.block.ComposterBlock; @@ -39,6 +53,7 @@ import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.IBlockReader; +import net.minecraft.world.IWorld; import net.minecraft.world.World; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; @@ -48,9 +63,6 @@ import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.ItemHandlerHelper; import net.minecraftforge.items.wrapper.InvWrapper; -import javax.annotation.Nullable; -import java.util.function.Supplier; - public abstract class ArmInteractionPoint { enum Mode { @@ -65,21 +77,21 @@ public abstract class ArmInteractionPoint { private ArmAngleTarget cachedAngles; private static ImmutableMap> POINTS = - ImmutableMap.>builder() - .put(new Saw(), Saw::new) - .put(new Belt(), Belt::new) - .put(new Depot(), Depot::new) - .put(new Chute(), Chute::new) - .put(new Basin(), Basin::new) - .put(new Funnel(), Funnel::new) - .put(new Jukebox(), Jukebox::new) - .put(new Crafter(), Crafter::new) - .put(new Deployer(), Deployer::new) - .put(new Composter(), Composter::new) - .put(new Millstone(), Millstone::new) - .put(new BlazeBurner(), BlazeBurner::new) - .put(new CrushingWheels(), CrushingWheels::new) - .build(); + ImmutableMap.>builder() + .put(new Saw(), Saw::new) + .put(new Belt(), Belt::new) + .put(new Depot(), Depot::new) + .put(new Chute(), Chute::new) + .put(new Basin(), Basin::new) + .put(new Funnel(), Funnel::new) + .put(new Jukebox(), Jukebox::new) + .put(new Crafter(), Crafter::new) + .put(new Deployer(), Deployer::new) + .put(new Composter(), Composter::new) + .put(new Millstone(), Millstone::new) + .put(new BlazeBurner(), BlazeBurner::new) + .put(new CrushingWheels(), CrushingWheels::new) + .build(); public ArmInteractionPoint() { cachedHandler = LazyOptional.empty(); @@ -108,6 +120,8 @@ public abstract class ArmInteractionPoint { return isValid(reader, pos, reader.getBlockState(pos)); } + void keepAlive(IWorld world) {} + abstract boolean isValid(IBlockReader reader, BlockPos pos, BlockState state); static boolean isInteractable(IBlockReader reader, BlockPos pos, BlockState state) { @@ -119,7 +133,8 @@ public abstract class ArmInteractionPoint { ArmAngleTarget getTargetAngles(BlockPos armPos, boolean ceiling) { if (cachedAngles == null) - cachedAngles = new ArmAngleTarget(armPos, getInteractionPositionVector(), getInteractionDirection(), ceiling); + cachedAngles = + new ArmAngleTarget(armPos, getInteractionPositionVector(), getInteractionDirection(), ceiling); return cachedAngles; } @@ -167,7 +182,8 @@ public abstract class ArmInteractionPoint { for (ArmInteractionPoint armInteractionPoint : POINTS.keySet()) if (armInteractionPoint.isValid(world, pos, state)) - point = POINTS.get(armInteractionPoint).get(); + point = POINTS.get(armInteractionPoint) + .get(); if (point != null) { point.state = state; @@ -222,7 +238,7 @@ public abstract class ArmInteractionPoint { @Override boolean isValid(IBlockReader reader, BlockPos pos, BlockState state) { return AllBlocks.MECHANICAL_SAW.has(state) && state.get(SawBlock.FACING) == Direction.UP - && ((KineticTileEntity) reader.getTileEntity(pos)).getSpeed() != 0; + && ((KineticTileEntity) reader.getTileEntity(pos)).getSpeed() != 0; } } @@ -260,7 +276,8 @@ public abstract class ArmInteractionPoint { @Nullable @Override IItemHandler getHandler(World world) { - return new InvWrapper(((ComposterBlock) Blocks.COMPOSTER).createInventory(world.getBlockState(pos), world, pos)); + return new InvWrapper( + ((ComposterBlock) Blocks.COMPOSTER).createInventory(world.getBlockState(pos), world, pos)); } } @@ -273,12 +290,14 @@ public abstract class ArmInteractionPoint { @Override Direction getInteractionDirection() { - return state.get(DeployerBlock.FACING).getOpposite(); + return state.get(DeployerBlock.FACING) + .getOpposite(); } @Override Vec3d getInteractionPositionVector() { - return super.getInteractionPositionVector().add(new Vec3d(getInteractionDirection().getDirectionVec()).scale(.65f)); + return super.getInteractionPositionVector() + .add(new Vec3d(getInteractionDirection().getDirectionVec()).scale(.65f)); } } @@ -298,13 +317,15 @@ public abstract class ArmInteractionPoint { @Override ItemStack insert(World world, ItemStack stack, boolean simulate) { ItemStack input = stack.copy(); - if (!BlazeBurnerBlock.tryInsert(state, world, pos, input, false, true).getResult().isEmpty()) { + if (!BlazeBurnerBlock.tryInsert(state, world, pos, input, false, true) + .getResult() + .isEmpty()) { return stack; } ActionResult res = BlazeBurnerBlock.tryInsert(state, world, pos, input, false, simulate); return res.getType() == ActionResultType.SUCCESS - ? ItemHandlerHelper.copyStackWithSize(stack, stack.getCount() - 1) - : stack; + ? ItemHandlerHelper.copyStackWithSize(stack, stack.getCount() - 1) + : stack; } @Override @@ -321,7 +342,8 @@ public abstract class ArmInteractionPoint { @Override Direction getInteractionDirection() { - return state.get(MechanicalCrafterBlock.HORIZONTAL_FACING).getOpposite(); + return state.get(MechanicalCrafterBlock.HORIZONTAL_FACING) + .getOpposite(); } @Override @@ -339,7 +361,8 @@ public abstract class ArmInteractionPoint { @Override Vec3d getInteractionPositionVector() { - return super.getInteractionPositionVector().add(new Vec3d(getInteractionDirection().getDirectionVec()).scale(.5f)); + return super.getInteractionPositionVector() + .add(new Vec3d(getInteractionDirection().getDirectionVec()).scale(.5f)); } } @@ -374,7 +397,8 @@ public abstract class ArmInteractionPoint { return stack; JukeboxBlock jukeboxBlock = (JukeboxBlock) state.getBlock(); JukeboxTileEntity jukeboxTE = (JukeboxTileEntity) tileEntity; - if (!jukeboxTE.getRecord().isEmpty()) + if (!jukeboxTE.getRecord() + .isEmpty()) return stack; if (!(stack.getItem() instanceof MusicDiscItem)) return stack; @@ -413,8 +437,30 @@ public abstract class ArmInteractionPoint { @Override boolean isValid(IBlockReader reader, BlockPos pos, BlockState state) { - return AllBlocks.BELT.has(state) && !(reader.getBlockState(pos.up()).getBlock() instanceof BeltTunnelBlock); + return AllBlocks.BELT.has(state) && !(reader.getBlockState(pos.up()) + .getBlock() instanceof BeltTunnelBlock); } + + @Override + void keepAlive(IWorld world) { + super.keepAlive(world); + BeltTileEntity beltTE = BeltHelper.getSegmentTE(world, pos); + if (beltTE == null) + return; + TransportedItemStackHandlerBehaviour transport = + beltTE.getBehaviour(TransportedItemStackHandlerBehaviour.TYPE); + if (transport == null) + return; + MutableBoolean found = new MutableBoolean(false); + transport.handleProcessingOnAllItems(tis -> { + if (found.isTrue()) + return TransportedResult.doNothing(); + tis.lockedExternally = true; + found.setTrue(); + return TransportedResult.doNothing(); + }); + } + } static class Chute extends TopFaceArmInteractionPoint { @@ -429,7 +475,9 @@ public abstract class ArmInteractionPoint { @Override Vec3d getInteractionPositionVector() { - return VecHelper.getCenterOf(pos).add(new Vec3d(FunnelBlock.getFunnelFacing(state).getDirectionVec()).scale(-.15f)); + return VecHelper.getCenterOf(pos) + .add(new Vec3d(FunnelBlock.getFunnelFacing(state) + .getDirectionVec()).scale(-.15f)); } @Override @@ -444,7 +492,8 @@ public abstract class ArmInteractionPoint { @Override Direction getInteractionDirection() { - return FunnelBlock.getFunnelFacing(state).getOpposite(); + return FunnelBlock.getFunnelFacing(state) + .getOpposite(); } @Override @@ -475,7 +524,9 @@ public abstract class ArmInteractionPoint { @Override boolean isValid(IBlockReader reader, BlockPos pos, BlockState state) { - return state.getBlock() instanceof FunnelBlock && !state.get(FunnelBlock.EXTRACTING); + return state.getBlock() instanceof AbstractFunnelBlock + && !(state.has(FunnelBlock.EXTRACTING) && state.get(FunnelBlock.EXTRACTING)) + && !(state.has(BeltFunnelBlock.SHAPE) && state.get(BeltFunnelBlock.SHAPE) == Shape.PUSHING); } @Override diff --git a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmTileEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmTileEntity.java index ab7aaf009..986115f01 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmTileEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmTileEntity.java @@ -66,7 +66,7 @@ public class ArmTileEntity extends KineticTileEntity { protected int lastOutputIndex = -1; protected boolean redstoneLocked; - enum Phase { + public enum Phase { SEARCH_INPUTS, MOVE_TO_INPUT, SEARCH_OUTPUTS, MOVE_TO_OUTPUT, DANCING } @@ -108,9 +108,15 @@ public class ArmTileEntity extends KineticTileEntity { initInteractionPoints(); boolean targetReached = tickMovementProgress(); - if (world.isRemote) + if (chasedPointProgress < 1) { + if (phase == Phase.MOVE_TO_INPUT) { + ArmInteractionPoint point = getTargetedInteractionPoint(); + if (point != null) + point.keepAlive(world); + } return; - if (chasedPointProgress < 1) + } + if (world.isRemote) return; if (phase == Phase.MOVE_TO_INPUT) 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 1b6c7e5ab..95aeb5c07 100644 --- a/src/main/java/com/simibubi/create/content/schematics/SchematicWorld.java +++ b/src/main/java/com/simibubi/create/content/schematics/SchematicWorld.java @@ -94,7 +94,7 @@ public class SchematicWorld extends WrappedWorld { try { TileEntity tileEntity = blockState.createTileEntity(this); if (tileEntity != null) { - tileEntity.setLocation(this, pos); + onTEadded(tileEntity, pos); tileEntities.put(pos, tileEntity); renderedTileEntities.add(tileEntity); } @@ -105,6 +105,10 @@ public class SchematicWorld extends WrappedWorld { } return null; } + + protected void onTEadded(TileEntity tileEntity, BlockPos pos) { + tileEntity.setLocation(this, pos); + } @Override public BlockState getBlockState(BlockPos globalPos) { diff --git a/src/main/java/com/simibubi/create/foundation/ponder/PonderWorld.java b/src/main/java/com/simibubi/create/foundation/ponder/PonderWorld.java index b43adcffa..01328c7a4 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/PonderWorld.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/PonderWorld.java @@ -92,14 +92,14 @@ public class PonderWorld extends SchematicWorld { 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()); + onTEadded(te, te.getPos()); tileEntities.put(k, te); renderedTileEntities.add(te); }); originalEntities.forEach(e -> EntityType.loadEntityUnchecked(e.serializeNBT(), this) .ifPresent(entities::add)); particles.clearEffects(); - fixVirtualTileEntities(); + fixBeltTileEntities(); } public void restoreBlocks(Selection selection) { @@ -225,16 +225,20 @@ public class PonderWorld extends SchematicWorld { particles.addParticle(p); } - public void fixVirtualTileEntities() { - for (TileEntity tileEntity : tileEntities.values()) { - if (!(tileEntity instanceof SmartTileEntity)) - continue; - SmartTileEntity smartTileEntity = (SmartTileEntity) tileEntity; - smartTileEntity.markVirtual(); + @Override + protected void onTEadded(TileEntity tileEntity, BlockPos pos) { + super.onTEadded(tileEntity, pos); + if (!(tileEntity instanceof SmartTileEntity)) + return; + SmartTileEntity smartTileEntity = (SmartTileEntity) tileEntity; + smartTileEntity.markVirtual(); + } - if (!(smartTileEntity instanceof BeltTileEntity)) + public void fixBeltTileEntities() { + for (TileEntity tileEntity : tileEntities.values()) { + if (!(tileEntity instanceof BeltTileEntity)) continue; - BeltTileEntity beltTileEntity = (BeltTileEntity) smartTileEntity; + BeltTileEntity beltTileEntity = (BeltTileEntity) tileEntity; if (!beltTileEntity.isController()) continue; BlockPos controllerPos = tileEntity.getPos(); diff --git a/src/main/java/com/simibubi/create/foundation/ponder/SceneBuilder.java b/src/main/java/com/simibubi/create/foundation/ponder/SceneBuilder.java index ead35f82a..7c0f52c56 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/SceneBuilder.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/SceneBuilder.java @@ -16,6 +16,7 @@ import com.simibubi.create.content.contraptions.particle.RotationIndicatorPartic 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.content.logistics.block.mechanicalArm.ArmTileEntity; import com.simibubi.create.foundation.ponder.content.PonderPalette; import com.simibubi.create.foundation.ponder.elements.AnimatedSceneElement; import com.simibubi.create.foundation.ponder.elements.BeltItemElement; @@ -56,6 +57,7 @@ import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputB 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.NBTHelper; import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.block.BlockState; @@ -761,6 +763,16 @@ public class SceneBuilder { }, reDrawBlocks)); } + public void instructArm(BlockPos armLocation, ArmTileEntity.Phase phase, ItemStack heldItem, + int targetedPoint) { + modifyTileNBT(scene.getSceneBuildingUtil().select.position(armLocation), ArmTileEntity.class, compound -> { + NBTHelper.writeEnum(compound, "Phase", phase); + compound.put("HeldItem", heldItem.serializeNBT()); + compound.putInt("TargetPointIndex", targetedPoint); + compound.putFloat("MovementProgress", 0); + }); + } + public void flapFunnel(BlockPos position, boolean outward) { modifyTileEntity(position, FunnelTileEntity.class, funnel -> funnel.flap(!outward)); } diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/BearingScenes.java b/src/main/java/com/simibubi/create/foundation/ponder/content/BearingScenes.java index 689a14165..59aac1a8d 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/content/BearingScenes.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/BearingScenes.java @@ -3,6 +3,7 @@ package com.simibubi.create.foundation.ponder.content; import com.simibubi.create.AllBlocks; import com.simibubi.create.content.contraptions.components.actors.HarvesterTileEntity; import com.simibubi.create.content.contraptions.components.structureMovement.bearing.SailBlock; +import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity; import com.simibubi.create.foundation.ponder.ElementLink; import com.simibubi.create.foundation.ponder.SceneBuilder; import com.simibubi.create.foundation.ponder.SceneBuildingUtil; @@ -12,6 +13,7 @@ import com.simibubi.create.foundation.ponder.elements.WorldSectionElement; import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Pointing; +import net.minecraft.entity.Entity; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; @@ -149,6 +151,7 @@ public class BearingScenes { scene.title("windmill_structure", "Windmill Contraptions"); scene.configureBasePlate(1, 1, 5); scene.setSceneOffsetY(-1); + scene.world.modifyEntities(SuperGlueEntity.class, Entity::remove); scene.world.showSection(util.select.layer(0), Direction.UP); scene.idle(5); 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 index ed9604071..de354e77d 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/content/BeltScenes.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/BeltScenes.java @@ -6,10 +6,14 @@ import java.util.List; import com.simibubi.create.AllBlocks; import com.simibubi.create.AllItems; +import com.simibubi.create.content.contraptions.components.press.MechanicalPressTileEntity; +import com.simibubi.create.content.contraptions.components.press.MechanicalPressTileEntity.Mode; +import com.simibubi.create.content.contraptions.fluids.actors.SpoutTileEntity; 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.content.logistics.block.mechanicalArm.ArmTileEntity.Phase; import com.simibubi.create.foundation.ponder.ElementLink; import com.simibubi.create.foundation.ponder.SceneBuilder; import com.simibubi.create.foundation.ponder.SceneBuildingUtil; @@ -23,6 +27,7 @@ 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.block.Blocks; import net.minecraft.entity.Entity; import net.minecraft.entity.item.ItemEntity; import net.minecraft.item.DyeColor; @@ -299,7 +304,7 @@ public class BeltScenes { scene.idle(10); scene.overlay.showText(160) - .text("These are all possible directions.\nBelts can span any Length between 2 and 20 blocks"); + .text("These are all possible directions. Belts can span any Length between 2 and 20 blocks"); scene.markAsFinished(); } @@ -461,4 +466,112 @@ public class BeltScenes { .pointAt(util.vector.blockSurface(beltPos.south(), Direction.WEST)); } + public static void depot(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("depot", "Using Depots"); + scene.configureBasePlate(0, 0, 5); + scene.showBasePlate(); + scene.idle(5); + scene.world.setBlock(util.grid.at(3, 2, 2), Blocks.WATER.getDefaultState(), false); + + BlockPos depotPos = util.grid.at(2, 1, 2); + scene.world.showSection(util.select.position(2, 1, 2), Direction.DOWN); + Vec3d topOf = util.vector.topOf(depotPos); + scene.overlay.showText(60) + .attachKeyFrame() + .text("Depots can serve as 'stationary' belt elements") + .placeNearTarget() + .pointAt(topOf); + scene.idle(70); + + scene.overlay.showControls(new InputWindowElement(topOf, Pointing.DOWN).rightClick() + .withItem(AllBlocks.COPPER_BLOCK.asStack()), 20); + scene.idle(7); + scene.world.createItemOnBeltLike(depotPos, Direction.NORTH, AllBlocks.COPPER_BLOCK.asStack()); + scene.idle(10); + scene.overlay.showText(70) + .attachKeyFrame() + .text("Right-Click to manually place or remove Items from it") + .placeNearTarget() + .pointAt(topOf); + scene.idle(80); + + scene.overlay.showControls(new InputWindowElement(topOf, Pointing.DOWN).rightClick(), 20); + scene.idle(7); + scene.world.removeItemsFromBelt(depotPos); + scene.effects.indicateSuccess(depotPos); + scene.idle(20); + + scene.world.showSection(util.select.position(depotPos.up(2)), Direction.SOUTH); + scene.overlay.showText(70) + .attachKeyFrame() + .text("Just like Mechanical Belts, it can provide items to processing") + .placeNearTarget() + .pointAt(util.vector.blockSurface(depotPos.up(2), Direction.WEST)); + ItemStack bottle = new ItemStack(Items.BUCKET); + scene.world.createItemOnBeltLike(depotPos, Direction.NORTH, bottle); + scene.idle(20); + scene.world.modifyTileNBT(util.select.position(depotPos.up(2)), SpoutTileEntity.class, + nbt -> nbt.putInt("ProcessingTicks", 20)); + scene.idle(20); + scene.world.removeItemsFromBelt(depotPos); + scene.world.createItemOnBeltLike(depotPos, Direction.UP, new ItemStack(Items.WATER_BUCKET)); + scene.world.modifyTileNBT(util.select.position(depotPos.up(2)), SpoutTileEntity.class, + nbt -> nbt.putBoolean("Splash", true)); + scene.idle(30); + scene.world.removeItemsFromBelt(depotPos); + scene.world.hideSection(util.select.position(depotPos.up(2)), Direction.SOUTH); + scene.idle(20); + ElementLink spout = scene.world.showIndependentSection(util.select.position(depotPos.up(2) + .west()), Direction.SOUTH); + scene.world.moveSection(spout, util.vector.of(1, 0, 0), 0); + + BlockPos pressPos = depotPos.up(2) + .west(); + ItemStack copper = AllItems.COPPER_INGOT.asStack(); + scene.world.createItemOnBeltLike(depotPos, Direction.NORTH, copper); + Vec3d depotCenter = util.vector.centerOf(depotPos); + scene.idle(10); + + Class type = MechanicalPressTileEntity.class; + scene.world.modifyTileEntity(pressPos, type, pte -> pte.start(Mode.BELT)); + scene.idle(15); + scene.world.modifyTileEntity(pressPos, type, + pte -> pte.makePressingParticleEffect(depotCenter.add(0, 8 / 16f, 0), copper)); + scene.world.removeItemsFromBelt(depotPos); + ItemStack sheet = AllItems.COPPER_SHEET.asStack(); + scene.world.createItemOnBeltLike(depotPos, Direction.UP, sheet); + + scene.idle(20); + scene.world.hideIndependentSection(spout, Direction.SOUTH); + scene.idle(10); + + Selection fanSelect = util.select.fromTo(4, 1, 3, 5, 2, 2) + .add(util.select.position(3, 1, 2)) + .add(util.select.position(5, 0, 2)); + scene.world.showSection(fanSelect, Direction.SOUTH); + ElementLink water = + scene.world.showIndependentSection(util.select.position(3, 1, 0), Direction.SOUTH); + scene.world.moveSection(water, util.vector.of(0, 1, 2), 0); + scene.idle(30); + + scene.world.hideSection(fanSelect, Direction.SOUTH); + scene.world.hideIndependentSection(water, Direction.SOUTH); + scene.idle(30); + + scene.world.showSection(util.select.fromTo(2, 1, 4, 2, 1, 5) + .add(util.select.position(2, 0, 5)), Direction.DOWN); + BlockPos armPos = util.grid.at(2, 1, 4); + scene.overlay.showText(70) + .attachKeyFrame() + .text("...as well as provide Items to Mechanical Arms") + .placeNearTarget() + .pointAt(util.vector.blockSurface(armPos, Direction.WEST)); + scene.idle(20); + + scene.world.instructArm(armPos, Phase.MOVE_TO_INPUT, ItemStack.EMPTY, 0); + scene.idle(37); + scene.world.removeItemsFromBelt(depotPos); + scene.world.instructArm(armPos, Phase.SEARCH_OUTPUTS, sheet, -1); + } + } diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/ChuteScenes.java b/src/main/java/com/simibubi/create/foundation/ponder/content/ChuteScenes.java new file mode 100644 index 000000000..d6f8e5225 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/ChuteScenes.java @@ -0,0 +1,265 @@ +package com.simibubi.create.foundation.ponder.content; + +import static com.simibubi.create.content.logistics.block.chute.ChuteBlock.SHAPE; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllItems; +import com.simibubi.create.content.logistics.block.chute.ChuteBlock; +import com.simibubi.create.content.logistics.block.chute.ChuteBlock.Shape; +import com.simibubi.create.content.logistics.block.chute.SmartChuteTileEntity; +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.entity.Entity; +import net.minecraft.entity.item.ItemEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; + +public class ChuteScenes { + + public static void downward(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("chute", "Transporting Items downward via Chutes"); + scene.configureBasePlate(0, 0, 5); + scene.scaleSceneView(.9f); + scene.world.showSection(util.select.layer(0), Direction.UP); + + ElementLink top = + scene.world.showIndependentSection(util.select.fromTo(3, 3, 3, 3, 4, 3), Direction.DOWN); + ElementLink bottom = + scene.world.showIndependentSection(util.select.fromTo(3, 2, 3, 3, 1, 3), Direction.DOWN); + scene.world.moveSection(bottom, util.vector.of(-2, 0, -1), 0); + scene.world.moveSection(top, util.vector.of(0, 0, -1), 0); + scene.idle(20); + + ItemStack stack = AllBlocks.COPPER_BLOCK.asStack(); + scene.world.createItemEntity(util.vector.centerOf(util.grid.at(3, 3, 2)), util.vector.of(0, -0.1, 0), stack); + scene.idle(20); + ElementLink remove = + scene.world.createItemEntity(util.vector.centerOf(util.grid.at(1, 5, 2)), util.vector.of(0, 0.1, 0), stack); + scene.idle(15); + scene.world.modifyEntity(remove, Entity::remove); + + scene.overlay.showText(60) + .attachKeyFrame() + .pointAt(util.vector.topOf(util.grid.at(1, 2, 2))) + .placeNearTarget() + .text("Chutes can transport items vertically from and to inventories"); + scene.idle(70); + scene.world.modifyEntities(ItemEntity.class, Entity::remove); + scene.world.moveSection(bottom, util.vector.of(1, 0, 0), 10); + scene.world.moveSection(top, util.vector.of(-1, 0, 0), 10); + scene.idle(20); + scene.overlay.showControls( + new InputWindowElement(util.vector.blockSurface(util.grid.at(2, 3, 2), Direction.NORTH), Pointing.RIGHT) + .rightClick() + .withWrench(), + 40); + scene.idle(7); + scene.world.modifyBlock(util.grid.at(3, 3, 3), s -> s.with(ChuteBlock.SHAPE, ChuteBlock.Shape.WINDOW), false); + scene.overlay.showText(50) + .attachKeyFrame() + .pointAt(util.vector.blockSurface(util.grid.at(2, 3, 2), Direction.WEST)) + .placeNearTarget() + .text("Using the Wrench, a window can be created"); + + scene.idle(10); + scene.world.modifyBlock(util.grid.at(3, 2, 3), s -> s.with(SHAPE, Shape.WINDOW), false); + + for (int i = 0; i < 8; i++) { + scene.idle(10); + scene.world.createItemOnBeltLike(util.grid.at(3, 3, 3), Direction.UP, stack); + } + scene.idle(20); + scene.world.hideIndependentSection(bottom, Direction.EAST); + scene.world.hideIndependentSection(top, Direction.EAST); + scene.idle(15); + + scene.rotateCameraY(-90); + scene.world.modifyBlock(util.grid.at(2, 2, 1), s -> s.with(SHAPE, Shape.NORMAL), false); + scene.world.showSection(util.select.fromTo(2, 1, 1, 2, 2, 1), Direction.DOWN); + scene.idle(30); + ItemStack chuteItem = AllBlocks.CHUTE.asStack(); + scene.overlay.showControls( + new InputWindowElement(util.vector.blockSurface(util.grid.at(2, 2, 1), Direction.SOUTH), Pointing.LEFT) + .rightClick() + .withItem(chuteItem), + 30); + scene.idle(7); + scene.world.showSection(util.select.position(2, 3, 2), Direction.NORTH); + scene.world.restoreBlocks(util.select.position(2, 2, 1)); + scene.idle(35); + scene.overlay.showControls( + new InputWindowElement(util.vector.blockSurface(util.grid.at(2, 3, 2), Direction.SOUTH), Pointing.LEFT) + .rightClick() + .withItem(chuteItem), + 30); + scene.idle(7); + scene.world.showSection(util.select.position(2, 4, 3), Direction.NORTH); + scene.idle(35); + + scene.overlay.showText(70) + .attachKeyFrame() + .pointAt(util.vector.blockSurface(util.grid.at(2, 4, 3), Direction.WEST)) + .placeNearTarget() + .text("Placing chutes targeting the side faces of another will make it diagonal"); + scene.idle(15); + scene.rotateCameraY(90); + + scene.idle(35); + + Direction offset = Direction.NORTH; + for (int i = 0; i < 3; i++) { + remove = scene.world.createItemEntity(util.vector.centerOf(util.grid.at(2, 6, 3) + .offset(offset)), util.vector.of(0, 0.1, 0) + .add(new Vec3d(offset.getDirectionVec()).scale(-.1)), + stack); + scene.idle(12); + scene.world.createItemOnBeltLike(util.grid.at(2, 4, 3), Direction.UP, stack); + scene.world.modifyEntity(remove, Entity::remove); + scene.idle(3); + offset = offset.rotateY(); + } + + scene.idle(10); + scene.overlay.showControls( + new InputWindowElement(util.vector.blockSurface(util.grid.at(2, 1, 1), Direction.NORTH), Pointing.RIGHT) + .withItem(stack), + 50); + } + + public static void upward(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("chute_upward", "Transporting Items upward via Chutes"); + scene.configureBasePlate(0, 0, 5); + scene.scaleSceneView(.9f); + scene.showBasePlate(); + Selection chute = util.select.fromTo(1, 2, 2, 1, 4, 2); + scene.world.setBlocks(chute, Blocks.AIR.getDefaultState(), false); + scene.world.showSection(util.select.position(1, 1, 2), Direction.UP); + scene.idle(20); + + scene.world.restoreBlocks(chute); + scene.world.showSection(chute, Direction.DOWN); + scene.idle(20); + scene.world.setKineticSpeed(util.select.position(1, 1, 2), 0); + Vec3d surface = util.vector.blockSurface(util.grid.at(1, 2, 2), Direction.WEST); + scene.overlay.showText(70) + .text("Using Encased Fans at the top or bottom, a Chute can move items upward") + .attachKeyFrame() + .pointAt(surface) + .placeNearTarget(); + scene.idle(80); + scene.overlay.showControls( + new InputWindowElement(util.vector.blockSurface(util.grid.at(1, 2, 2), Direction.NORTH), Pointing.RIGHT) + .withItem(AllItems.GOGGLES.asStack()), + 50); + scene.overlay.showText(70) + .text("Inspecting chutes with Engineers' Goggles reveals information about the movement direction") + .attachKeyFrame() + .pointAt(surface) + .placeNearTarget(); + scene.idle(80); + + scene.world.showSection(util.select.fromTo(2, 2, 2, 4, 1, 5) + .add(util.select.position(3, 0, 5)), Direction.DOWN); + ItemStack stack = AllBlocks.COPPER_BLOCK.asStack(); + scene.world.createItemOnBelt(util.grid.at(4, 1, 2), Direction.EAST, stack); + scene.idle(10); + scene.rotateCameraY(60); + scene.overlay.showText(70) + .text("On the 'blocked' end, items will have to be inserted/taken from the sides") + .attachKeyFrame() + .pointAt(util.vector.centerOf(util.grid.at(3, 1, 2)) + .add(0, 3 / 16f, 0)) + .placeNearTarget(); + scene.idle(32); + scene.world.flapFunnel(util.grid.at(2, 2, 2), false); + scene.world.removeItemsFromBelt(util.grid.at(2, 1, 2)); + scene.world.createItemOnBeltLike(util.grid.at(1, 2, 2), Direction.EAST, stack); + } + + public static void smart(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("smart_chute", "Filtering Items using Smart Chutes"); + scene.configureBasePlate(0, 0, 5); + scene.scaleSceneView(.9f); + + Selection lever = util.select.fromTo(0, 1, 2, 1, 3, 2); + BlockPos smarty = util.grid.at(2, 3, 2); + + scene.world.showSection(util.select.layer(0), Direction.UP); + scene.idle(5); + scene.world.showSection(util.select.fromTo(2, 1, 2, 2, 2, 2), Direction.DOWN); + scene.idle(10); + scene.world.showSection(util.select.position(2, 3, 2), Direction.DOWN); + scene.idle(5); + scene.world.showSection(util.select.position(2, 4, 2), Direction.DOWN); + + scene.overlay.showText(60) + .text("Smart Chutes are vertical chutes with additional control") + .attachKeyFrame() + .pointAt(util.vector.blockSurface(smarty, Direction.WEST)) + .placeNearTarget(); + scene.idle(70); + + Vec3d filter = util.vector.blockSurface(smarty, Direction.NORTH) + .add(0, 0.25, 0); + scene.overlay.showFilterSlotInput(filter, 60); + ItemStack copper = new ItemStack(Items.IRON_INGOT); + scene.overlay.showControls(new InputWindowElement(filter, Pointing.DOWN).rightClick() + .withItem(copper), 40); + scene.idle(7); + scene.world.setFilterData(util.select.position(smarty), SmartChuteTileEntity.class, copper); + scene.idle(10); + scene.rotateCameraY(20); + scene.overlay.showText(60) + .text("Items in the filter slot specify what exactly they can extract and transfer") + .attachKeyFrame() + .pointAt(filter) + .placeNearTarget(); + scene.idle(10); + + for (int i = 0; i < 18; i++) { + scene.idle(10); + scene.world.createItemOnBeltLike(util.grid.at(2, 2, 2), Direction.UP, copper); + if (i == 8) { + scene.rotateCameraY(-20); + scene.overlay.showControls(new InputWindowElement(filter, Pointing.DOWN).scroll(), 40); + scene.overlay.showText(50) + .text("Use the Mouse Wheel to specify the extracted stack size") + .attachKeyFrame() + .pointAt(filter) + .placeNearTarget(); + } + if (i == 13) + scene.world.showSection(lever, Direction.NORTH); + } + + scene.world.toggleRedstonePower(lever.add(util.select.position(smarty))); + scene.effects.indicateRedstone(util.grid.at(0, 3, 2)); + scene.overlay.showText(50) + .text("Redstone power will prevent Smart Chutes from acting.") + .attachKeyFrame() + .colored(PonderPalette.RED) + .pointAt(util.vector.blockSurface(util.grid.at(0, 2, 2), Direction.UP)) + .placeNearTarget(); + scene.idle(70); + + scene.world.toggleRedstonePower(lever.add(util.select.position(smarty))); + scene.markAsFinished(); + for (int i = 0; i < 8; i++) { + scene.idle(10); + scene.world.createItemOnBeltLike(util.grid.at(2, 2, 2), Direction.UP, copper); + } + + } + +} 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 index c8f9c6c44..38e243636 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/content/FunnelScenes.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/FunnelScenes.java @@ -332,7 +332,7 @@ public class FunnelScenes { scene.overlay.chaseBoundingBoxOutline(PonderPalette.RED, funnel, redstoneBB, 80); scene.overlay.showText(80) .colored(PonderPalette.RED) - .text("Redstone power will prevent any funnel from acting.") + .text("Redstone power will prevent any funnel from acting") .pointAt(util.vector.blockSurface(funnel, Direction.DOWN)); } else { scene.idle(4); 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 index 9ff2b9854..7d5877ff9 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/content/PonderIndex.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderIndex.java @@ -95,6 +95,14 @@ public class PonderIndex { PonderRegistry.addStoryBoard(AllItems.EMPTY_BLAZE_BURNER, "empty_blaze_burner", ProcessingScenes::emptyBlazeBurner); PonderRegistry.addStoryBoard(AllBlocks.BLAZE_BURNER, "blaze_burner", ProcessingScenes::blazeBurner); + PonderRegistry.addStoryBoard(AllBlocks.DEPOT, "depot", BeltScenes::depot); + + // Chutes + PonderRegistry.forComponents(AllBlocks.CHUTE) + .addStoryBoard("chute/downward", ChuteScenes::downward, PonderTag.LOGISTICS) + .addStoryBoard("chute/upward", ChuteScenes::upward); + PonderRegistry.forComponents(AllBlocks.CHUTE, AllBlocks.SMART_CHUTE) + .addStoryBoard("chute/smart", ChuteScenes::smart); // Funnels PonderRegistry.addStoryBoard(AllBlocks.BRASS_FUNNEL, "funnels/brass", FunnelScenes::brass); @@ -287,10 +295,10 @@ public class PonderIndex { .add(AllBlocks.MILLSTONE) .add(AllBlocks.DEPLOYER) .add(AllBlocks.MECHANICAL_SAW) - .add(Blocks.COMPOSTER) .add(AllBlocks.BLAZE_BURNER) - .add(Blocks.JUKEBOX) - .add(AllBlocks.CRUSHING_WHEEL); + .add(AllBlocks.CRUSHING_WHEEL) + .add(Blocks.COMPOSTER) + .add(Blocks.JUKEBOX); PonderRegistry.tags.forTag(PonderTag.LOGISTICS) .add(AllItems.BELT_CONNECTOR) 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 index 2ad235153..f14cb3394 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/content/PonderTagScreen.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderTagScreen.java @@ -7,6 +7,7 @@ import java.util.Objects; import org.apache.commons.lang3.mutable.MutableBoolean; import com.mojang.blaze3d.systems.RenderSystem; +import com.simibubi.create.Create; import com.simibubi.create.foundation.gui.ScreenOpener; import com.simibubi.create.foundation.gui.UIRenderHelper; import com.simibubi.create.foundation.ponder.NavigatableSimiScreen; @@ -25,6 +26,7 @@ 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.ResourceLocation; import net.minecraft.util.math.MathHelper; import net.minecraftforge.registries.ForgeRegistries; @@ -87,7 +89,12 @@ public class PonderTagScreen extends NavigatableSimiScreen { ScreenOpener.transitionTo(PonderUI.of(new ItemStack(i), tag)); }).showing(new ItemStack(i)); if (!canClick) - button.noClickEvent(); + if (i.getRegistryName() + .getNamespace() + .equals(Create.ID)) + button.customColors(0x70984500, 0x70692400); + else + button.customColors(0x505000FF, 0x50300077); button.fade(1); widgets.add(button); @@ -96,9 +103,10 @@ public class PonderTagScreen extends NavigatableSimiScreen { if (!tag.getMainItem() .isEmpty()) { - final boolean canClick = PonderRegistry.all.containsKey(tag.getMainItem() + ResourceLocation registryName = tag.getMainItem() .getItem() - .getRegistryName()); + .getRegistryName(); + final boolean canClick = PonderRegistry.all.containsKey(registryName); PonderButton button = new PonderButton(itemCenterX - layout.getTotalWidth() / 2 - 42, itemCenterY - 10, (mouseX, mouseY) -> { if (!canClick) @@ -107,7 +115,11 @@ public class PonderTagScreen extends NavigatableSimiScreen { ScreenOpener.transitionTo(PonderUI.of(tag.getMainItem(), tag)); }).showing(tag.getMainItem()); if (!canClick) - button.noClickEvent(); + if (registryName.getNamespace() + .equals(Create.ID)) + button.customColors(0x70984500, 0x70692400); + else + button.customColors(0x505000FF, 0x50300077); button.fade(1); widgets.add(button); @@ -202,7 +214,7 @@ public class PonderTagScreen extends NavigatableSimiScreen { RenderSystem.translated(0, 0, 100); FontHelper.drawSplitString(font, desc, x, y, w, 0xeeeeee); RenderSystem.popMatrix(); - + } protected void renderItems(int mouseX, int mouseY, float partialTicks) { @@ -301,7 +313,7 @@ public class PonderTagScreen extends NavigatableSimiScreen { return tag == ((PonderTagScreen) other).tag; return super.isEquivalentTo(other); } - + @Override public boolean isPauseScreen() { return true; diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/ProcessingScenes.java b/src/main/java/com/simibubi/create/foundation/ponder/content/ProcessingScenes.java index 354a8b363..7082ec1f4 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/content/ProcessingScenes.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/ProcessingScenes.java @@ -618,14 +618,14 @@ public class ProcessingScenes { scene.idle(7); scene.world.setBlock(util.grid.at(3, 1, 2), AllBlocks.LIT_BLAZE_BURNER.getDefaultState(), true); scene.idle(10); - scene.overlay.showText(90) + scene.overlay.showText(70) .text("For Aesthetic purposes, Empty Blaze Burners can also be lit using Flint and Steel") .attachKeyFrame() .pointAt(util.vector.blockSurface(center.east() .up(), Direction.UP)) .placeNearTarget(); - scene.idle(70); - scene.overlay.showText(90) + scene.idle(80); + scene.overlay.showText(60) .colored(PonderPalette.RED) .text("However, these are not suitable for industrial heating") .pointAt(util.vector.blockSurface(center.east() 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 index d484bae49..93f174f4d 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/instructions/TileEntityDataInstruction.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/instructions/TileEntityDataInstruction.java @@ -35,9 +35,9 @@ public class TileEntityDataInstruction extends WorldModifyInstruction { if (!type.isInstance(tileEntity)) return; CompoundNBT apply = data.apply(tileEntity.write(new CompoundNBT())); - tileEntity.read(apply); if (tileEntity instanceof SyncedTileEntity) ((SyncedTileEntity) tileEntity).readClientUpdate(apply); + tileEntity.read(apply); }); } 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 index c60da8df9..46cce7309 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/ui/PonderButton.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/ui/PonderButton.java @@ -8,6 +8,7 @@ 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.ColorHelper; +import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.animation.LerpedFloat; import net.minecraft.client.Minecraft; @@ -25,7 +26,7 @@ public class PonderButton extends AbstractSimiWidget { private float fade; private KeyBinding shortcut; private LerpedFloat flash; - private boolean noClickEvent; + private Couple customPassiveBorder; public static final int SIZE = 20; @@ -54,8 +55,8 @@ public class PonderButton extends AbstractSimiWidget { return this; } - public PonderButton noClickEvent() { - this.noClickEvent = true; + public PonderButton customColors(int start, int end) { + this.customPassiveBorder = Couple.create(start, end); return this; } @@ -103,10 +104,10 @@ public class PonderButton extends AbstractSimiWidget { fade *= 3 * flashValue + Math.sin((PonderUI.ponderTicks + partialTicks) / 6); int backgroundColor = ColorHelper.applyAlpha(0xdd000000, fade); - int borderColorStart = - ColorHelper.applyAlpha(noClickEvent ? 0x70984500 : isHovered ? 0x70ffffff : 0x40aa9999, fade); - int borderColorEnd = - ColorHelper.applyAlpha(noClickEvent ? 0x70692400 : isHovered ? 0x30ffffff : 0x20aa9999, fade); + int borderColorStart = customPassiveBorder != null ? customPassiveBorder.getFirst() : isHovered ? 0x70ffffff : 0x40aa9999; + int borderColorEnd = customPassiveBorder != null ? customPassiveBorder.getSecond() : isHovered ? 0x30ffffff : 0x20aa9999; + borderColorStart = ColorHelper.applyAlpha(borderColorStart, fade); + borderColorEnd = ColorHelper.applyAlpha(borderColorEnd, fade); PonderUI.renderBox(x, y, width, height, backgroundColor, borderColorStart, borderColorEnd); RenderSystem.translated(0, 0, 800); diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/belt/DirectBeltInputBehaviour.java b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/belt/DirectBeltInputBehaviour.java index ed571d3a5..f7f0164e0 100644 --- a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/belt/DirectBeltInputBehaviour.java +++ b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/belt/DirectBeltInputBehaviour.java @@ -47,7 +47,7 @@ public class DirectBeltInputBehaviour extends TileEntityBehaviour { supportsBeltFunnels = pred; return this; } - + public DirectBeltInputBehaviour allowingBeltFunnels() { supportsBeltFunnels = () -> true; return this; @@ -97,20 +97,21 @@ public class DirectBeltInputBehaviour extends TileEntityBehaviour { public boolean test(Direction side); } + @Nullable public ItemStack tryExportingToBeltFunnel(ItemStack stack, @Nullable Direction side) { BlockPos funnelPos = tileEntity.getPos() .up(); World world = getWorld(); BlockState funnelState = world.getBlockState(funnelPos); if (!(funnelState.getBlock() instanceof BeltFunnelBlock)) - return stack; + return null; if (funnelState.get(BeltFunnelBlock.SHAPE) != Shape.PULLING) - return stack; + return null; if (side != null && FunnelBlock.getFunnelFacing(funnelState) != side) - return stack; + return null; TileEntity te = world.getTileEntity(funnelPos); if (!(te instanceof FunnelTileEntity)) - return stack; + return null; ItemStack insert = FunnelBlock.tryInsert(world, funnelPos, stack, false); if (insert.getCount() != stack.getCount()) ((FunnelTileEntity) te).flap(true); diff --git a/src/main/resources/ponder/chute/downward.nbt b/src/main/resources/ponder/chute/downward.nbt new file mode 100644 index 0000000000000000000000000000000000000000..9ed64894197b32f02bb6e7b24691ea8c6b28ef8c GIT binary patch literal 485 zcmV1thM#1~*`Zv=`J9*OfP&HWrRu z#ZyJ_U_9U2ZPSF%MuxqVkt{3G%s0Ph?8GHN0m7-D$N?aXv>yfJXh@Ml2f+%+p0%yM zyV5_rFMw~Y>w`|lA$24Pj}c>^Eb2oZgZdPIAU)%3%>49>Eb2oZeVO zomoVk=QuoqBO*AbRz%d9N7Q+a!y`B%g43IbsI!Qu^BjjqaKu?o3EVtW0qG-Qb2y|q zFtvjFMj5PHxuy?QjgHQ!3hKu@jU8zvh(J4V?goxjZ35|MyEEix5X+s`Az=z{KUpH% zd{pfhZMz5MiKfCq%%W=1=kQ8)g!@QWA0iha)6zQsjj`rJ$Js4E>pY9{E^)zXJ8l<^rHR-uLiTdZtnPORTrZ~>HgHI39GdCu;rejVfQWn5U# btQZcr50d0JAGhB~`7d|@j&?n8#t8rbKJ$riwFP!000000Hv18j?*v{hEHOrO*2JEhynJz0Bd#wqmkI4uGm(d^t7=^ z?8-hRf(PUIu+v;hnrW>WOHpOz|G#sy;${E~;8y-Y1_1s^x@Q3?Dv~78f?o@mJ(fEE zX*0L^xB#}-wlnpML1IY|wvJOxG@*$`nmB;N0ysQ?)2-+NCz{ZVIdK4o1#ox(r(1DA zpW}c&U*fO;4iDf!o71T#p2+!{2HL!@ajt2)#RBHe0_J{+!vZ)wfYU7=Fn1m>_e&fW zz~Pge448VP1ti}HtK&x_g;;LjbtM(%Mr`SGUZACktj5!4EiD7?X-Cehfg_}eAo;2f zirg>o)uAkXzyxl;Xd+$RN%K(Z`d&Js%5g|$nHzL5TqXy?#%YVAbLk_kv~}M+t)7_p z_;m4S=9$6lL6(H(n&atm7%Y#7yUL4)3g5I9+DaH&Kd(+Usxx`fbotqI&(HTb;%wr4 zk2Q0rneRo3MCh-jGzI=$R0to2oa#anu5+ziSDdL+yd4x)>3ZGVZT;JKZ3~6kpl$rZ zO0{!M$W})0(fDgIg`3)mOsRJ}+(5DwrNtCxTakNhqO_sH5$X3HVdnki5dW-eBXnX5 z;cc~48(j}n?slrD{CAkgi1}XEX!^{0)5Q50Te*vd&R1$}&Oj$6T795ms-_Zup*f?X zaD{TE6{elH+cnMVcD(i-asNv;{#6qlqECIC_d^_)l_lp{*V3RnA2;`c#1AyKIoj!8 N_y@7Vzf|G~005m5A3Oj6 literal 0 HcmV?d00001 diff --git a/src/main/resources/ponder/chute/upward.nbt b/src/main/resources/ponder/chute/upward.nbt new file mode 100644 index 0000000000000000000000000000000000000000..d067f74906102adf80b22aa8b5c1f0b785d08c0c GIT binary patch literal 1008 zcmV9g3t(Q8F472~eOfed$NUFRiWAt$@HW;5KN| z7Q&hwNrb6gVs{lLe$prOYx-LB2MYIF+IMx97m21Ql};VR3lOWz%$YN1FEjK3df=$& z8f^eDk6S$59(c%gq$5;dMi07|u?Vh|PhY<5ft?6dI<1EduF_0n;Ze1*8f>hZO{WEp z-2%sHfm04^502GfQ^)DFz_DB4I4y9>(P_bFpN-vMvrEH$IBS_(XlS?Kybs52f#bBm zDTmWyuR1OE>OLI11&-5*eQ3*L|= zEQs{GQ3mW>(4jUoT{t`rLk!EmPnRZUXB4hhe=ouP^{ETp3oTKplV#@FzX+s=yQ@Ee8t*Beel0YTf6^r+Q{+Hj4b+vMRDyNcs<5|2Gv$ z&AR3y_6rd&G1d)dp{|W{cWtbD(PrD>qiSO}Xye{p8~7mFysm3w-C3L4hx4n=?b1#y zA9^GHhB^%)-}NY6jq|+Uu;B1qDC$4n;0qZNv!=_wE^N0D)(6KR<>3zJ5ywEXi9TWx z;kZMw;F@M|&KGeE*@8Sd5n7A+aU@S;kv@wEkq7wuvgBOef5B{_G4oWjlgx8qBIQ&C z-%(6DHJ%3rPa7V6FBw-8ltUrnP^3Ix>+We3Yn1yFuwjs!9nZ}V8-WiCvXcep7&jc& zIv?+zb=y$+f4bQ_bbDw#ogF;itNPvb@_ABFSJ6C)aePH;=qUKFqyN*c^Hgn~dJjL3 zpLgZq?8)Pg|Bp(9(}SoNLY+oqj{ekcvP?09O1Lg zSx#q>#&IAx(IBVN;_=2pagmO*mr^6lxfBUX^S(+&a6%bV5$r6IwPTr1Hc?d>=dElD z&xZDK%Pq*Ot~+6|LUK%))LN_!+iOn%_cgp97K@UnOv=vEuiDnfT2g<*^z zHi%g^sqZU>t7eScx@p9z-c?Yu>Q^G%x{vD+2Z=~gVz}m6VD@OINET?Us*X(QHSFgF zETgtcnf+xLj*B{3i_%ZYQpRFBtweIz+em?Ry+xE5Otx}u2T|_Kn8~Tx@zZpM?@Q;C eQnwO?Ug(}N&0eBZS^e^UgMR@m6PJee5dZ*n!SG!G literal 0 HcmV?d00001 diff --git a/src/main/resources/ponder/depot.nbt b/src/main/resources/ponder/depot.nbt new file mode 100644 index 0000000000000000000000000000000000000000..cb1824d1b61cd9062113617d737617177ba93279 GIT binary patch literal 1154 zcmV-|1bzD-iwFP!000000L@p;Zrer>UW%lC?b<2&ckH>R9%DC1q9}1Jv~h*V2@<1# zx+X``!W5TSt}G`fKSCeDPtkMRCvkxm=p(e3sK6U(9YHg7w_>xHmAyH3@)K5L`oP}-t=c^Vm10JSM*<%trlvG0Ek+(4l zYz)n&RsqMXfMZp_siiUHY-$BK@3KiBV?#VfflX07@4_)F;8+!L49%vDSFJ)#YZYp` z3CFB}V^zd4G#j&|rkiZi$E;9OvqDWb;g}V0tO_{kV^ye^RiR#+aLfugRv}KCnEt7> zi9HMe++Q!1-|i9q8Ae~c2wb!@+N5y=a>2!!O`1I#P>0DkhnEW28se}*Alo9fzPnuh z^N`p-?b)P0lmf!=k=mq5YRn~{Isy=EKV-AOgV7oDK{BU}mV7Q89C*g7<#PEauCLK& z57!f1U+Y}$0^L~&k9ec4WFr>>F56`5`?(C}^3i-e2C)jb*&=pd!YoYiilDY5ok-ehNMaDw#h?viWgB5`2e-;Eu-B*HigNlFDz&QfVbb^CauH zPZBAQ{e;I!ktB2;sU!^2JYYTxr{I#5({ESBoY4K4;fWfxHnE;@7vl7HBGcH4=;2)_ z;oZx^E6h#*DxaI$x&XQ>0sM`8uI^>odi-S+LF4({_gB^bJW1RPoGJC0L%mU;tPAFg zsU@b7BnIVwO#S%!fYr3WgLClG4Bfv}S*;&aF#-7?l7M}{k+XpoFR3>N^(7*86h@Ex z67MEW(mL?w%srwrAUiWGrX%QB?k{j-Y`l7R#^=7oi2hPh?FFa~bjRG@CXXps-c~Ncgi@|y+ zW?XVnBCb4zwmv0>$1_QpJ_* zKI7*wLv^EECn{eLBEjs&tr3OT_g%P%57Q!nUFQp9mG?bL?w7k+S$aPfl|>U_uKlT) z;glHg1qhsUC8t^b?C;ta>V<#^^n!)NxX8eE5-^8P7E=H( zd$D$B)3NJgEEaBQEg+PcOTi7O%+dC_kkibw^z_uDiBF&pVwx(&Q*&aJ@vRnM>KrZX z97gf{)tnm+Ffa0sg1F(mJ{{hN#+#d&n4&g54B|%3H5A)ZHxFWbz4FlR4r&fQrjot{ U5#qUk&G<9<4}}6PxhfF=05}9Z^8f$< literal 0 HcmV?d00001 From 6a0ad77fe79aac3e9c79280390f4de2c38ff2f35 Mon Sep 17 00:00:00 2001 From: JozsefA Date: Sat, 20 Mar 2021 22:33:24 -0700 Subject: [PATCH 06/14] Refactor away TileEntityInstance#init - Move it to the constructor. - An instance is now discarded and recreated if TileEntityInstance#shouldReset return true. - Mark a bunch of stuff final. --- .../base/KineticTileInstance.java | 17 +++++-- .../base/SingleRotatingInstance.java | 7 +-- .../components/crank/HandCrankInstance.java | 5 -- .../components/deployer/DeployerInstance.java | 21 +++----- .../components/fan/FanInstance.java | 48 +++++-------------- .../components/flywheel/FlyWheelInstance.java | 17 +++---- .../flywheel/engine/EngineInstance.java | 5 +- .../components/mixer/MixerInstance.java | 9 +--- .../components/press/PressInstance.java | 7 +-- .../chassis/StickerInstance.java | 22 +++++---- .../gantry/GantryCarriageInstance.java | 27 ++++++----- .../fluids/pipes/FluidValveInstance.java | 16 ++----- .../relays/belt/BeltInstance.java | 21 ++++---- .../relays/encased/SplitShaftInstance.java | 7 +-- .../relays/gauge/GaugeInstance.java | 7 +-- .../relays/gearbox/GearboxInstance.java | 7 +-- .../content/logistics/block/FlapData.java | 5 +- .../belts/tunnel/BeltTunnelInstance.java | 9 +--- .../diodes/AdjustableRepeaterInstance.java | 5 +- .../block/funnel/FunnelInstance.java | 17 ++----- .../block/mechanicalArm/ArmInstance.java | 21 +++----- .../block/redstone/AnalogLeverInstance.java | 11 ++--- .../block/SchematicannonInstance.java | 8 +--- .../instancing/InstancedTileRenderer.java | 43 ++++++++++------- .../instancing/TileEntityInstance.java | 39 ++++++--------- 25 files changed, 155 insertions(+), 246 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileInstance.java b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileInstance.java index 9c94b9062..6beb6bdac 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileInstance.java @@ -17,13 +17,24 @@ public abstract class KineticTileInstance extends T } protected final void updateRotation(InstanceKey key, Direction.Axis axis) { - key.getInstance() - .setColor(tile.network) - .setRotationalSpeed(tile.getSpeed()) + updateRotation(key, axis, tile.getSpeed()); + } + + protected final void updateRotation(InstanceKey key, Direction.Axis axis, float speed) { + updateRotation(key.getInstance(), axis, speed); + } + + protected final void updateRotation(RotatingData key, Direction.Axis axis, float speed) { + key.setColor(tile.network) + .setRotationalSpeed(speed) .setRotationOffset(getRotationOffset(axis)) .setRotationAxis(axis); } + protected final void updateRotation(RotatingData key, Direction.Axis axis) { + updateRotation(key, axis, tile.getSpeed()); + } + protected final InstanceKey setup(InstanceKey key, float speed, Direction.Axis axis) { key.getInstance() .setBlockLight(world.getLightLevel(LightType.BLOCK, pos)) diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/SingleRotatingInstance.java b/src/main/java/com/simibubi/create/content/contraptions/base/SingleRotatingInstance.java index ed80fdc9c..ab81c0462 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/SingleRotatingInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/SingleRotatingInstance.java @@ -11,20 +11,17 @@ import net.minecraft.util.Direction; public class SingleRotatingInstance extends KineticTileInstance { - protected InstanceKey rotatingModelKey; + protected final InstanceKey rotatingModelKey; public SingleRotatingInstance(InstancedTileRenderer modelManager, KineticTileEntity tile) { super(modelManager, tile); - } - @Override - protected void init() { Direction.Axis axis = ((IRotate) blockState.getBlock()).getRotationAxis(blockState); rotatingModelKey = setup(getModel().createInstance(), tile.getSpeed(), axis); } @Override - public void onUpdate() { + public void update() { Direction.Axis axis = ((IRotate) blockState.getBlock()).getRotationAxis(blockState); updateRotation(rotatingModelKey, axis); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/crank/HandCrankInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/crank/HandCrankInstance.java index 309be16a0..86c353eae 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/crank/HandCrankInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/crank/HandCrankInstance.java @@ -19,11 +19,6 @@ public class HandCrankInstance extends SingleRotatingInstance implements IDynami public HandCrankInstance(InstancedTileRenderer modelManager, KineticTileEntity tile) { super(modelManager, tile); - } - - @Override - protected void init() { - super.init(); Block block = blockState.getBlock(); AllBlockPartials renderedHandle = null; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerInstance.java index 4cd49184a..a6b7de237 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerInstance.java @@ -18,28 +18,21 @@ import static com.simibubi.create.content.contraptions.base.DirectionalKineticBl public class DeployerInstance extends ShaftInstance implements IDynamicInstance { - DeployerTileEntity tile; + final DeployerTileEntity tile; + final Direction facing; + final float yRot; + final float zRot; + final float zRotPole; - Direction facing; + protected final InstanceKey pole; - InstanceKey pole; + protected InstanceKey hand; AllBlockPartials currentHand; - InstanceKey hand; - - float yRot; - float zRot; - float zRotPole; - float progress = Float.NaN; public DeployerInstance(InstancedTileRenderer dispatcher, KineticTileEntity tile) { super(dispatcher, tile); - } - - @Override - protected void init() { - super.init(); this.tile = (DeployerTileEntity) super.tile; facing = blockState.get(FACING); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/fan/FanInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/fan/FanInstance.java index b2ba34186..ff7cfcfad 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/fan/FanInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/fan/FanInstance.java @@ -10,43 +10,29 @@ import com.simibubi.create.foundation.render.backend.instancing.InstanceKey; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; +import net.minecraft.client.renderer.Vector3f; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; public class FanInstance extends KineticTileInstance { - protected InstanceKey shaft; - protected InstanceKey fan; + protected final InstanceKey shaft; + protected final InstanceKey fan; + final Direction.Axis axis; + final Direction direction; public FanInstance(InstancedTileRenderer modelManager, EncasedFanTileEntity tile) { super(modelManager, tile); - } - @Override - protected void init() { - final Direction direction = blockState.get(FACING); - final Direction.Axis axis = ((IRotate) blockState.getBlock()).getRotationAxis(blockState); + direction = blockState.get(FACING); + axis = ((IRotate) blockState.getBlock()).getRotationAxis(blockState); - InstancedModel shaftHalf = - AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(modelManager, blockState, direction.getOpposite()); - InstancedModel fanInner = - AllBlockPartials.ENCASED_FAN_INNER.renderOnDirectionalSouthRotating(modelManager, blockState, direction.getOpposite()); + shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(modelManager, blockState, direction.getOpposite()).createInstance(); + fan = AllBlockPartials.ENCASED_FAN_INNER.renderOnDirectionalSouthRotating(modelManager, blockState, direction.getOpposite()).createInstance(); - shaft = shaftHalf.createInstance(); - shaft.getInstance() - .setRotationalSpeed(tile.getSpeed()) - .setRotationOffset(getRotationOffset(axis)) - .setRotationAxis(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getUnitVector()) - .setTileEntity(tile); - - - fan = fanInner.createInstance(); - fan.getInstance() - .setRotationalSpeed(getFanSpeed()) - .setRotationOffset(getRotationOffset(axis)) - .setRotationAxis(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getUnitVector()) - .setTileEntity(tile); + updateRotation(shaft.getInstance().setTileEntity(tile), axis); + updateRotation(fan.getInstance().setTileEntity(tile), axis, getFanSpeed()); updateLight(); } @@ -61,21 +47,13 @@ public class FanInstance extends KineticTileInstance { } @Override - protected void onUpdate() { - Direction.Axis axis = blockState.get(FACING).getAxis(); + protected void update() { updateRotation(shaft, axis); - - fan.getInstance() - .setColor(tile.network) - .setRotationalSpeed(getFanSpeed()) - .setRotationOffset(getRotationOffset(axis)) - .setRotationAxis(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getUnitVector()); + updateRotation(fan, axis, getFanSpeed()); } @Override public void updateLight() { - final Direction direction = blockState.get(FACING); - BlockPos behind = pos.offset(direction.getOpposite()); relight(behind, shaft.getInstance()); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlyWheelInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlyWheelInstance.java index 132e4713d..5393afc6b 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlyWheelInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlyWheelInstance.java @@ -23,21 +23,22 @@ import net.minecraft.util.math.MathHelper; public class FlyWheelInstance extends KineticTileInstance implements IDynamicInstance { - protected Direction facing; + protected final Direction facing; + protected final Direction connection; + protected boolean connectedLeft; protected float connectorAngleMult; - protected Direction connection; + protected final InstanceKey shaft; - protected InstanceKey shaft; + protected final InstanceKey wheel; - protected InstanceKey wheel; + protected List> connectors; protected InstanceKey upperRotating; protected InstanceKey lowerRotating; protected InstanceKey upperSliding; protected InstanceKey lowerSliding; - protected List> connectors; protected float lastAngle = Float.NaN; @@ -45,10 +46,7 @@ public class FlyWheelInstance extends KineticTileInstance im public FlyWheelInstance(InstancedTileRenderer modelManager, FlywheelTileEntity tile) { super(modelManager, tile); - } - @Override - protected void init() { facing = blockState.get(BlockStateProperties.HORIZONTAL_FACING); Direction.Axis axis = ((IRotate) blockState.getBlock()).getRotationAxis(blockState); @@ -77,7 +75,6 @@ public class FlyWheelInstance extends KineticTileInstance im } updateLight(); - firstFrame = true; } @Override @@ -135,7 +132,7 @@ public class FlyWheelInstance extends KineticTileInstance im } @Override - protected void onUpdate() { + protected void update() { Direction.Axis axis = ((IRotate) blockState.getBlock()).getRotationAxis(blockState); updateRotation(shaft, axis); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/engine/EngineInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/engine/EngineInstance.java index ebee39e59..ce01d7646 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/engine/EngineInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/engine/EngineInstance.java @@ -19,12 +19,9 @@ public class EngineInstance extends TileEntityInstance { public EngineInstance(InstancedTileRenderer modelManager, EngineTileEntity tile) { super(modelManager, tile); - } - @Override - protected void init() { Block block = blockState - .getBlock(); + .getBlock(); if (!(block instanceof EngineBlock)) return; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MixerInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MixerInstance.java index bd9ce61da..5623900f4 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MixerInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MixerInstance.java @@ -14,16 +14,11 @@ import net.minecraft.util.Direction; public class MixerInstance extends ShaftlessCogInstance implements IDynamicInstance { - private InstanceKey mixerHead; - private InstanceKey mixerPole; + private final InstanceKey mixerHead; + private final InstanceKey mixerPole; public MixerInstance(InstancedTileRenderer dispatcher, KineticTileEntity tile) { super(dispatcher, tile); - } - - @Override - protected void init() { - super.init(); mixerHead = rotatingMaterial().getModel(AllBlockPartials.MECHANICAL_MIXER_HEAD, blockState) .createInstance(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/press/PressInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/press/PressInstance.java index 831539c69..2927d7ea5 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/press/PressInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/press/PressInstance.java @@ -14,15 +14,10 @@ import com.simibubi.create.foundation.utility.MatrixStacker; public class PressInstance extends ShaftInstance implements IDynamicInstance { - private InstanceKey pressHead; + private final InstanceKey pressHead; public PressInstance(InstancedTileRenderer dispatcher, KineticTileEntity tile) { super(dispatcher, tile); - } - - @Override - protected void init() { - super.init(); pressHead = modelManager.getMaterial(RenderMaterials.MODELS) .getModel(AllBlockPartials.MECHANICAL_PRESS_HEAD, blockState) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerInstance.java index 7499176f5..a56bbc689 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerInstance.java @@ -10,37 +10,39 @@ import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.MatrixStacker; import net.minecraft.client.Minecraft; import net.minecraft.util.Direction; +import net.minecraft.util.math.MathHelper; public class StickerInstance extends TileEntityInstance implements IDynamicInstance { float lastOffset = Float.NaN; + final Direction facing; + final boolean fakeWorld; + final int offset; - private InstanceKey head; + private final InstanceKey head; public StickerInstance(InstancedTileRenderer modelManager, StickerTileEntity tile) { super(modelManager, tile); - } - @Override - protected void init() { head = modelManager.getMaterial(RenderMaterials.MODELS).getModel(AllBlockPartials.STICKER_HEAD, blockState).createInstance(); + fakeWorld = tile.getWorld() != Minecraft.getInstance().world; + facing = blockState.get(StickerBlock.FACING); + offset = blockState.get(StickerBlock.EXTENDED) ? 1 : 0; + updateLight(); } @Override public void beginFrame() { - blockState = world.getBlockState(pos); - float offset = tile.piston.getValue(AnimationTickHolder.getPartialTicks()); - if (tile.getWorld() != Minecraft.getInstance().world) - offset = blockState.get(StickerBlock.EXTENDED) ? 1 : 0; + if (fakeWorld) + offset = this.offset; - if (Math.abs(offset - lastOffset) < 1e-4) + if (MathHelper.epsilonEquals(offset, lastOffset)) return; - Direction facing = blockState.get(StickerBlock.FACING); MatrixStack stack = new MatrixStack(); MatrixStacker.of(stack) .translate(getFloatingPos()) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageInstance.java index 085819e38..d2d5a8404 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageInstance.java @@ -19,32 +19,33 @@ import net.minecraft.util.math.BlockPos; public class GantryCarriageInstance extends ShaftInstance implements IDynamicInstance { - private InstanceKey gantryCogs; + private final InstanceKey gantryCogs; + + final Direction facing; + final Boolean alongFirst; + final Direction.Axis rotationAxis; + final BlockPos visualPos; public GantryCarriageInstance(InstancedTileRenderer dispatcher, KineticTileEntity tile) { super(dispatcher, tile); - } - - @Override - protected void init() { - super.init(); gantryCogs = modelManager.getMaterial(RenderMaterials.MODELS) .getModel(AllBlockPartials.GANTRY_COGS, blockState) .createInstance(); + facing = blockState.get(GantryCarriageBlock.FACING); + alongFirst = blockState.get(GantryCarriageBlock.AXIS_ALONG_FIRST_COORDINATE); + rotationAxis = KineticTileEntityRenderer.getRotationAxisOf(tile); + + visualPos = facing.getAxisDirection() == Direction.AxisDirection.POSITIVE ? tile.getPos() + : tile.getPos() + .offset(facing.getOpposite()); + updateLight(); } @Override public void beginFrame() { - blockState = tile.getBlockState(); - Direction facing = blockState.get(GantryCarriageBlock.FACING); - Boolean alongFirst = blockState.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 = GantryCarriageRenderer.getAngleForTe(tile, visualPos, rotationAxis); Direction.Axis gantryAxis = Direction.Axis.X; diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/pipes/FluidValveInstance.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/pipes/FluidValveInstance.java index 765156582..8566a1a22 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/pipes/FluidValveInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/pipes/FluidValveInstance.java @@ -19,17 +19,12 @@ public class FluidValveInstance extends ShaftInstance implements IDynamicInstanc protected InstanceKey pointer; - protected double xRot; - protected double yRot; - protected int pointerRotationOffset; + protected final double xRot; + protected final double yRot; + protected final int pointerRotationOffset; public FluidValveInstance(InstancedTileRenderer dispatcher, KineticTileEntity tile) { super(dispatcher, tile); - } - - @Override - protected void init() { - super.init(); Direction facing = blockState.get(FluidValveBlock.FACING); @@ -39,9 +34,8 @@ public class FluidValveInstance extends ShaftInstance implements IDynamicInstanc Direction.Axis pipeAxis = FluidValveBlock.getPipeAxis(blockState); Direction.Axis shaftAxis = KineticTileEntityRenderer.getRotationAxisOf(tile); - pointerRotationOffset = 0; - if (pipeAxis.isHorizontal() && shaftAxis == Direction.Axis.Z || pipeAxis.isVertical()) - pointerRotationOffset = 90; + boolean twist = pipeAxis.isHorizontal() && shaftAxis == Direction.Axis.Z || pipeAxis.isVertical(); + pointerRotationOffset = twist ? 90 : 0; pointer = modelManager.getBasicMaterial().getModel(AllBlockPartials.FLUID_VALVE_POINTER, blockState).createInstance(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstance.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstance.java index 8b2845933..273ff564a 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstance.java @@ -22,23 +22,20 @@ import net.minecraft.world.LightType; public class BeltInstance extends KineticTileInstance { - private boolean upward; - private boolean diagonal; - private boolean sideways; - private boolean vertical; - private boolean alongX; - private boolean alongZ; - private BeltSlope beltSlope; - private Direction facing; + boolean upward; + boolean diagonal; + boolean sideways; + boolean vertical; + boolean alongX; + boolean alongZ; + BeltSlope beltSlope; + Direction facing; protected ArrayList> keys; protected InstanceKey pulleyKey; public BeltInstance(InstancedTileRenderer modelManager, BeltTileEntity tile) { super(modelManager, tile); - } - @Override - protected void init() { if (!AllBlocks.BELT.has(blockState)) return; @@ -77,7 +74,7 @@ public class BeltInstance extends KineticTileInstance { } @Override - public void onUpdate() { + public void update() { DyeColor color = tile.color.orElse(null); boolean bottom = true; diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftInstance.java b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftInstance.java index 73a3d6a28..5ef3575ad 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftInstance.java @@ -17,14 +17,11 @@ import net.minecraft.util.Direction; public class SplitShaftInstance extends KineticTileInstance { - protected ArrayList> keys; + protected final ArrayList> keys; public SplitShaftInstance(InstancedTileRenderer modelManager, SplitShaftTileEntity tile) { super(modelManager, tile); - } - @Override - protected void init() { keys = new ArrayList<>(2); Block block = blockState.getBlock(); @@ -43,7 +40,7 @@ public class SplitShaftInstance extends KineticTileInstance faces; + protected final ArrayList faces; protected MatrixStack ms; protected GaugeInstance(InstancedTileRenderer dispatcher, KineticTileEntity tile) { super(dispatcher, tile); - } - - @Override - protected void init() { - super.init(); faces = new ArrayList<>(2); diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxInstance.java b/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxInstance.java index 77d89ad6d..8f2e4fd99 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxInstance.java @@ -18,15 +18,12 @@ import net.minecraft.world.LightType; public class GearboxInstance extends KineticTileInstance { - protected EnumMap> keys; + protected final EnumMap> keys; protected Direction sourceFacing; public GearboxInstance(InstancedTileRenderer modelManager, GearboxTileEntity tile) { super(modelManager, tile); - } - @Override - protected void init() { keys = new EnumMap<>(Direction.class); final Direction.Axis boxAxis = blockState.get(BlockStateProperties.AXIS); @@ -78,7 +75,7 @@ public class GearboxInstance extends KineticTileInstance { } @Override - public void onUpdate() { + public void update() { updateSourceFacing(); for (Map.Entry> key : keys.entrySet()) { Direction direction = key.getKey(); diff --git a/src/main/java/com/simibubi/create/content/logistics/block/FlapData.java b/src/main/java/com/simibubi/create/content/logistics/block/FlapData.java index a42d8af3b..841fd523b 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/FlapData.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/FlapData.java @@ -3,12 +3,13 @@ package com.simibubi.create.content.logistics.block; import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat; import com.simibubi.create.foundation.render.backend.instancing.InstanceData; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; +import com.simibubi.create.foundation.render.backend.instancing.impl.IFlatLight; import net.minecraft.client.renderer.Vector3f; import net.minecraft.util.math.BlockPos; import java.nio.ByteBuffer; -public class FlapData extends InstanceData { +public class FlapData extends InstanceData implements IFlatLight { public static VertexFormat FORMAT = VertexFormat.builder() .addAttributes(FlapVertexAttributes.class) @@ -61,11 +62,13 @@ public class FlapData extends InstanceData { return this; } + @Override public FlapData setBlockLight(int blockLight) { this.blockLight = (byte) ((blockLight & 0xF) << 4); return this; } + @Override public FlapData setSkyLight(int skyLight) { this.skyLight = (byte) ((skyLight & 0xF) << 4); return this; diff --git a/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelInstance.java b/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelInstance.java index 47aaf49bb..48f643efa 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelInstance.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BeltTunnelInstance.java @@ -16,15 +16,11 @@ import java.util.Map; public class BeltTunnelInstance extends TileEntityInstance implements IDynamicInstance { - - private Map>> tunnelFlaps; + private final Map>> tunnelFlaps; public BeltTunnelInstance(InstancedTileRenderer modelManager, BeltTunnelTileEntity tile) { super(modelManager, tile); - } - @Override - protected void init() { tunnelFlaps = new EnumMap<>(Direction.class); InstancedModel model = modelManager.getMaterial(KineticRenderMaterials.FLAPS) @@ -82,9 +78,6 @@ public class BeltTunnelInstance extends TileEntityInstance }); } - @Override - protected void onUpdate() { } - @Override public void updateLight() { int blockLight = world.getLightLevel(LightType.BLOCK, pos); diff --git a/src/main/java/com/simibubi/create/content/logistics/block/diodes/AdjustableRepeaterInstance.java b/src/main/java/com/simibubi/create/content/logistics/block/diodes/AdjustableRepeaterInstance.java index 3d4ef9fdc..b7c26136d 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/diodes/AdjustableRepeaterInstance.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/diodes/AdjustableRepeaterInstance.java @@ -9,16 +9,13 @@ import com.simibubi.create.foundation.utility.MatrixStacker; public class AdjustableRepeaterInstance extends TileEntityInstance implements ITickableInstance { - protected InstanceKey indicator; + protected final InstanceKey indicator; protected int previousState; public AdjustableRepeaterInstance(InstancedTileRenderer modelManager, AdjustableRepeaterTileEntity tile) { super(modelManager, tile); - } - @Override - protected void init() { indicator = modelManager.getBasicMaterial().getModel(AllBlockPartials.FLEXPEATER_INDICATOR, blockState).createInstance(); MatrixStack ms = new MatrixStack(); diff --git a/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelInstance.java b/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelInstance.java index d3db0c74d..9d2e4fb25 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelInstance.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelInstance.java @@ -12,14 +12,11 @@ import java.util.ArrayList; public class FunnelInstance extends TileEntityInstance implements IDynamicInstance { - private ArrayList> flaps; + private final ArrayList> flaps; public FunnelInstance(InstancedTileRenderer modelManager, FunnelTileEntity tile) { super(modelManager, tile); - } - @Override - protected void init() { flaps = new ArrayList<>(4); if (!tile.hasFlap()) return; @@ -71,16 +68,8 @@ public class FunnelInstance extends TileEntityInstance impleme @Override public void updateLight() { - if (flaps == null) return; - - int blockLight = world.getLightLevel(LightType.BLOCK, pos); - int skyLight = world.getLightLevel(LightType.SKY, pos); - - for (InstanceKey it : flaps) { - it.getInstance() - .setBlockLight(blockLight) - .setSkyLight(skyLight); - } + if (flaps != null) + relight(pos, flaps.stream().map(InstanceKey::getInstance)); } @Override diff --git a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInstance.java b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInstance.java index b63c070d3..12fed5bfd 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInstance.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInstance.java @@ -24,24 +24,19 @@ import java.util.ArrayList; public class ArmInstance extends SingleRotatingInstance implements IDynamicInstance { - private InstanceKey base; - private InstanceKey lowerBody; - private InstanceKey upperBody; - private InstanceKey head; - private InstanceKey claw; - private ArrayList> clawGrips; + final InstanceKey base; + final InstanceKey lowerBody; + final InstanceKey upperBody; + final InstanceKey head; + final InstanceKey claw; + private final ArrayList> clawGrips; - private ArrayList> models; + private final ArrayList> models; private boolean firstTick = true; public ArmInstance(InstancedTileRenderer modelManager, KineticTileEntity tile) { super(modelManager, tile); - } - - @Override - protected void init() { - super.init(); RenderMaterial> mat = modelManager.getMaterial(RenderMaterials.MODELS); @@ -58,8 +53,6 @@ public class ArmInstance extends SingleRotatingInstance implements IDynamicInsta clawGrips = Lists.newArrayList(clawGrip1, clawGrip2); models = Lists.newArrayList(base, lowerBody, upperBody, head, claw, clawGrip1, clawGrip2); - firstTick = true; - beginFrame(); updateLight(); } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/redstone/AnalogLeverInstance.java b/src/main/java/com/simibubi/create/content/logistics/block/redstone/AnalogLeverInstance.java index def1976ce..4227837e8 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/redstone/AnalogLeverInstance.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/redstone/AnalogLeverInstance.java @@ -14,18 +14,15 @@ import net.minecraft.util.Direction; public class AnalogLeverInstance extends TileEntityInstance implements IDynamicInstance { - protected InstanceKey handle; - protected InstanceKey indicator; + protected final InstanceKey handle; + protected final InstanceKey indicator; - private float rX; - private float rY; + final float rX; + final float rY; public AnalogLeverInstance(InstancedTileRenderer modelManager, AnalogLeverTileEntity tile) { super(modelManager, tile); - } - @Override - protected void init() { RenderMaterial> mat = modelManager.getMaterial(RenderMaterials.MODELS); handle = mat.getModel(AllBlockPartials.ANALOG_LEVER_HANDLE, blockState).createInstance(); diff --git a/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonInstance.java b/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonInstance.java index fd9ddce84..10aa4011b 100644 --- a/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonInstance.java +++ b/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonInstance.java @@ -11,15 +11,11 @@ import net.minecraft.util.Direction; public class SchematicannonInstance extends TileEntityInstance implements IDynamicInstance { - private InstanceKey connector; - private InstanceKey pipe; + private final InstanceKey connector; + private final InstanceKey pipe; public SchematicannonInstance(InstancedTileRenderer modelManager, SchematicannonTileEntity tile) { super(modelManager, tile); - } - - @Override - protected void init() { RenderMaterial> mat = modelManager.getMaterial(RenderMaterials.MODELS); diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java index 54142c6e4..5d31998f5 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java @@ -79,11 +79,6 @@ public abstract class InstancedTileRenderer

{ return getMaterial(RenderMaterials.MODELS); } - @Nullable - public TileEntityInstance getInstance(T tile) { - return getInstance(tile, true); - } - @SuppressWarnings("unchecked") @Nullable public TileEntityInstance getInstance(T tile, boolean create) { @@ -127,7 +122,7 @@ public abstract class InstancedTileRenderer

{ if (!Backend.canUseInstancing()) return; if (tile instanceof IInstanceRendered) { - getInstance(tile); + getInstance(tile, true); } } @@ -143,8 +138,16 @@ public abstract class InstancedTileRenderer

{ if (tile instanceof IInstanceRendered) { TileEntityInstance instance = getInstance(tile, false); - if (instance != null) - instance.update(); + if (instance != null) { + + if (instance.shouldReset()) { + removeInternal(tile, instance); + + getInstance(tile, true); + } else { + instance.update(); + } + } } } @@ -152,17 +155,25 @@ public abstract class InstancedTileRenderer

{ if (!Backend.canUseInstancing()) return; if (tile instanceof IInstanceRendered) { - TileEntityInstance instance = getInstance(tile, false); - - if (instance != null) { - instance.remove(); - instances.remove(tile); - dynamicInstances.remove(tile); - tickableInstances.remove(tile); - } + removeInternal(tile); } } + private void removeInternal(T tile) { + TileEntityInstance instance = getInstance(tile, false); + + if (instance != null) { + removeInternal(tile, instance); + } + } + + private void removeInternal(T tile, TileEntityInstance instance) { + instance.remove(); + instances.remove(tile); + dynamicInstances.remove(tile); + tickableInstances.remove(tile); + } + public void clean() { instances.keySet().removeIf(TileEntity::isRemoved); } diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/TileEntityInstance.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/TileEntityInstance.java index fd31e3569..4c66529da 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/TileEntityInstance.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/TileEntityInstance.java @@ -16,7 +16,7 @@ public abstract class TileEntityInstance { protected final T tile; protected final World world; protected final BlockPos pos; - protected BlockState blockState; + protected final BlockState blockState; public TileEntityInstance(InstancedTileRenderer modelManager, T tile) { this.modelManager = modelManager; @@ -24,30 +24,15 @@ public abstract class TileEntityInstance { this.world = tile.getWorld(); this.pos = tile.getPos(); this.blockState = tile.getBlockState(); - init(); - } - - public final void update() { - BlockState currentState = tile.getBlockState(); - if (blockState == currentState) { - onUpdate(); - } else { - remove(); - blockState = currentState; - init(); - } } /** - * Acquire all {@link InstanceKey}s and initialize any data you may need to calculate the instance properties. + * Update instance data here. Good for when data doesn't change very often and when animations are GPU based. + * Don't query lighting data here, that's handled separately in {@link #updateLight()}. + * + * If your animations are complex and more CPU driven, use {@link IDynamicInstance} or {@link ITickableInstance}. */ - protected abstract void init(); - - /** - * Update changed instance data using the {@link InstanceKey}s you got in {@link #init()}. - * You don't have to update light data. That should be done in {@link #updateLight()} - */ - protected void onUpdate() { } + protected void update() { } /** * Called when a light update occurs in the world. If your model needs it, update light here. @@ -59,23 +44,27 @@ public abstract class TileEntityInstance { */ public abstract void remove(); + public boolean shouldReset() { + return tile.getBlockState() != blockState; + } + public BlockPos getFloatingPos() { return pos.subtract(modelManager.getOriginCoordinate()); } - protected > void relight(BlockPos pos, IFlatLight... models) { + protected void relight(BlockPos pos, IFlatLight... models) { relight(world.getLightLevel(LightType.BLOCK, pos), world.getLightLevel(LightType.SKY, pos), models); } - protected > void relight(BlockPos pos, Stream> models) { + protected void relight(BlockPos pos, Stream> models) { relight(world.getLightLevel(LightType.BLOCK, pos), world.getLightLevel(LightType.SKY, pos), models); } - protected > void relight(int block, int sky, IFlatLight... models) { + protected void relight(int block, int sky, IFlatLight... models) { relight(block, sky, Arrays.stream(models)); } - protected > void relight(int block, int sky, Stream> models) { + protected void relight(int block, int sky, Stream> models) { models.forEach(model -> model.setBlockLight(block).setSkyLight(sky)); } } From 9a493b79773618862f8536dcc7bec8733cd8d304 Mon Sep 17 00:00:00 2001 From: JozsefA Date: Sat, 20 Mar 2021 23:35:13 -0700 Subject: [PATCH 07/14] Sticker fixer. --- .../components/structureMovement/chassis/StickerTileEntity.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerTileEntity.java index 7a706797d..a59293331 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerTileEntity.java @@ -70,6 +70,8 @@ public class StickerTileEntity extends SmartTileEntity implements IInstanceRende if (isAttachedToBlock() && target == 0 && piston.getChaseTarget() == 1) DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> playSound(false)); piston.chase(target, .4f, Chaser.LINEAR); + + DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> CreateClient.kineticRenderer.get(world).update(this)); } public boolean isAttachedToBlock() { From c75a0f8aa73bcf488756fb8b6fd903a8c72443bc Mon Sep 17 00:00:00 2001 From: grimmauld Date: Sun, 21 Mar 2021 17:16:17 +0100 Subject: [PATCH 08/14] Particular immersion --- .../foundation/mixin/StepSoundMixin.java | 134 ++++++++++++------ 1 file changed, 88 insertions(+), 46 deletions(-) diff --git a/src/main/java/com/simibubi/create/foundation/mixin/StepSoundMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/StepSoundMixin.java index 5a5cff258..ba640af84 100644 --- a/src/main/java/com/simibubi/create/foundation/mixin/StepSoundMixin.java +++ b/src/main/java/com/simibubi/create/foundation/mixin/StepSoundMixin.java @@ -1,14 +1,21 @@ package com.simibubi.create.foundation.mixin; -import com.simibubi.create.content.contraptions.components.structureMovement.*; +import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity; +import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; +import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionCollider; +import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionHandler; +import net.minecraft.block.BlockRenderType; import net.minecraft.block.BlockState; import net.minecraft.entity.Entity; import net.minecraft.entity.MoverType; +import net.minecraft.particles.BlockParticleData; +import net.minecraft.particles.ParticleTypes; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; import net.minecraft.world.gen.feature.template.Template; +import org.apache.logging.log4j.util.TriConsumer; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -16,75 +23,110 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.lang.ref.Reference; +import java.util.Random; import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; @Mixin(Entity.class) public abstract class StepSoundMixin { - @Shadow public boolean collided; + @Shadow + public boolean collided; - @Shadow public World world; + @Shadow + public World world; - @Shadow public abstract BlockPos getPosition(); + @Shadow + protected Random rand; - @Shadow public abstract Vec3d getPositionVec(); + @Shadow + private float nextStepDistance; - @Shadow private float nextStepDistance; + @Shadow + public abstract BlockPos getPosition(); - @Shadow protected abstract float determineNextStepDistance(); + @Shadow + public abstract Vec3d getPositionVec(); - @Shadow public abstract AxisAlignedBB getBoundingBox(); + @Shadow + protected abstract float determineNextStepDistance(); - @Shadow protected abstract void playStepSound(BlockPos p_180429_1_, BlockState p_180429_2_); + @Shadow + public abstract AxisAlignedBB getBoundingBox(); - @Inject(at = @At( - value = "JUMP", - opcode = 154, //IFNE - ordinal = 4 - ), - method = "move" - ) - private void movementMixin(MoverType mover, Vec3d movement, CallbackInfo ci) { - Entity thi = (Entity) (Object) this; + @Shadow + protected abstract void playStepSound(BlockPos p_180429_1_, BlockState p_180429_2_); - World entityWorld = world; + private Set getIntersectingContraptions(Entity entity) { + Set contraptions = ContraptionHandler.loadedContraptions.get(entity.world) + .values() + .stream() + .map(Reference::get) + .filter(cEntity -> cEntity != null && cEntity.collidingEntities.containsKey(entity)) + .collect(Collectors.toSet()); - Set contraptions = ContraptionHandler.loadedContraptions.get(entityWorld) - .values() - .stream() - .map(Reference::get) - .filter(cEntity -> cEntity != null && cEntity.collidingEntities.containsKey(thi)).collect(Collectors.toSet()); + contraptions.addAll(entity.world.getEntitiesWithinAABB(AbstractContraptionEntity.class, getBoundingBox().grow(1f))); + return contraptions; + } - contraptions.addAll(entityWorld.getEntitiesWithinAABB(AbstractContraptionEntity.class, getBoundingBox().grow(1f))); + private void forCollision(Vec3d anchorPos, TriConsumer action) { + Entity thi = (Entity) (Object) this; + getIntersectingContraptions(thi).forEach(cEntity -> { + Vec3d localPos = ContraptionCollider.getWorldToLocalTranslation(anchorPos, cEntity); - Vec3d worldPos = thi.getPositionVector().add(0, -0.2, 0); + localPos = anchorPos.add(localPos); - boolean stepped = false; - for (AbstractContraptionEntity cEntity : contraptions) { - Vec3d localPos = ContraptionCollider.getWorldToLocalTranslation(worldPos, cEntity); + BlockPos blockPos = new BlockPos(localPos); + Contraption contraption = cEntity.getContraption(); + Template.BlockInfo info = contraption.getBlocks().get(blockPos); - localPos = worldPos.add(localPos); + if (info != null) { + BlockState blockstate = info.state; + action.accept(contraption, blockstate, blockPos); + } + }); + } - BlockPos blockPos = new BlockPos(localPos); - Contraption contraption = cEntity.getContraption(); - Template.BlockInfo info = contraption.getBlocks().get(blockPos); + @Inject(at = @At( + value = "JUMP", + opcode = 154, //IFNE + ordinal = 4 + ), + method = "move" + ) + private void movementMixin(MoverType mover, Vec3d movement, CallbackInfo ci) { + Entity thi = (Entity) (Object) this; + World entityWorld = world; + Vec3d worldPos = thi.getPositionVector().add(0, -0.2, 0); + AtomicBoolean stepped = new AtomicBoolean(false); - if (info != null) { - BlockState blockstate = info.state; + forCollision(worldPos, (contraption, blockstate, blockPos) -> { + this.world = contraption.getContraptionWorld(); + this.playStepSound(blockPos, blockstate); + stepped.set(true); + }); - this.world = contraption.getContraptionWorld(); + if (stepped.get()) + this.nextStepDistance = this.determineNextStepDistance(); - this.playStepSound(blockPos, blockstate); + world = entityWorld; + } - stepped = true; - } - } - - if (stepped) - this.nextStepDistance = this.determineNextStepDistance(); - - world = entityWorld; - } + @Inject(method = {"Lnet/minecraft/entity/Entity;createRunningParticles()V"}, at = @At(value = "TAIL")) + private void createRunningParticlesMixin(CallbackInfo ci) { + Entity thi = (Entity) (Object) this; + Vec3d worldPos = thi.getPositionVector().add(0, -0.2, 0); + BlockPos pos = new BlockPos(worldPos); // pos where particles are spawned + forCollision(worldPos, (contraption, blockstate, blockpos) -> { + if (!blockstate.addRunningEffects(world, blockpos, thi) && blockstate.getRenderType() != BlockRenderType.INVISIBLE) { + Vec3d vec3d = thi.getMotion(); + this.world.addParticle(new BlockParticleData(ParticleTypes.BLOCK, blockstate).setPos(pos), + thi.getX() + ((double) rand.nextFloat() - 0.5D) * (double) thi.getWidth(), + thi.getY() + 0.1D, thi.getZ() + ((double) rand.nextFloat() - 0.5D) * (double) thi.getWidth(), + vec3d.x * -4.0D, 1.5D, vec3d.z * -4.0D); + } + }); + } } From 140cd9a85a5094175de87474066162722ecf0eb1 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Sun, 21 Mar 2021 17:38:33 +0100 Subject: [PATCH 09/14] Sailing craft - Front face of crafters now supports hoppers and co - Scenes for Sails and Mechanical Crafters - Fixed a couple strange quirks of Ponder text windows --- .../crafter/MechanicalCrafterTileEntity.java | 62 ++- .../create/foundation/ponder/PonderScene.java | 17 +- .../create/foundation/ponder/PonderUI.java | 8 +- .../foundation/ponder/SceneBuilder.java | 13 + .../ponder/content/BearingScenes.java | 94 +++- .../ponder/content/CrafterScenes.java | 453 ++++++++++++++++++ .../ponder/content/PonderIndex.java | 16 + .../foundation/ponder/content/PonderTag.java | 4 + .../ponder/elements/InputWindowElement.java | 2 +- .../ponder/elements/ParrotElement.java | 2 +- .../ponder/elements/TextWindowElement.java | 10 +- .../ponder/mechanical_crafter/connect.nbt | Bin 0 -> 1144 bytes .../ponder/mechanical_crafter/covers.nbt | Bin 0 -> 825 bytes .../ponder/mechanical_crafter/setup.nbt | Bin 0 -> 904 bytes src/main/resources/ponder/sail.nbt | Bin 0 -> 447 bytes 15 files changed, 634 insertions(+), 47 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/ponder/content/CrafterScenes.java create mode 100644 src/main/resources/ponder/mechanical_crafter/connect.nbt create mode 100644 src/main/resources/ponder/mechanical_crafter/covers.nbt create mode 100644 src/main/resources/ponder/mechanical_crafter/setup.nbt create mode 100644 src/main/resources/ponder/sail.nbt diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/crafter/MechanicalCrafterTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/crafter/MechanicalCrafterTileEntity.java index 64dc60b2d..6303c90c6 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/crafter/MechanicalCrafterTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/crafter/MechanicalCrafterTileEntity.java @@ -37,7 +37,6 @@ import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.util.LazyOptional; -import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; public class MechanicalCrafterTileEntity extends KineticTileEntity { @@ -46,7 +45,7 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { IDLE, ACCEPTING, ASSEMBLING, EXPORTING, WAITING, CRAFTING, INSERTING; } - static class Inventory extends SmartInventory { + public static class Inventory extends SmartInventory { private MechanicalCrafterTileEntity te; @@ -57,11 +56,11 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { whenContentsChanged(slot -> { if (getStackInSlot(slot).isEmpty()) return; - if(te.phase == Phase.IDLE) + if (te.phase == Phase.IDLE) te.checkCompletedRecipe(false); }); } - + @Override public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) { if (te.phase != Phase.IDLE) @@ -70,9 +69,9 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { return stack; return super.insertItem(slot, stack, simulate); } - + } - + protected Inventory inventory; protected GroupedItems groupedItems = new GroupedItems(); protected ConnectedInput input = new ConnectedInput(); @@ -87,13 +86,15 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { private InvManipulationBehaviour inserting; private EdgeInteractionBehaviour connectivity; + private ItemStack scriptedResult = ItemStack.EMPTY; + public MechanicalCrafterTileEntity(TileEntityType type) { super(type); setLazyTickRate(20); phase = Phase.IDLE; groupedItemsBeforeCraft = new GroupedItems(); inventory = new Inventory(this); - + // Does not get serialized due to active checking in tick wasPoweredBefore = true; } @@ -118,7 +119,7 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { public BlockFace getTargetFace(World world, BlockPos pos, BlockState state) { return new BlockFace(pos, MechanicalCrafterBlock.getTargetDirection(state)); } - + public Direction getTargetDirection() { return MechanicalCrafterBlock.getTargetDirection(getBlockState()); } @@ -145,7 +146,7 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { compound.putBoolean("Cover", covered); super.write(compound, clientPacket); - + if (clientPacket && reRender) { compound.putBoolean("Redraw", true); reRender = false; @@ -156,7 +157,7 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { protected void read(CompoundNBT compound, boolean clientPacket) { Phase phaseBefore = phase; GroupedItems before = this.groupedItems; - + inventory.deserializeNBT(compound.getCompound("Inventory")); input.read(compound.getCompound("ConnectedInput")); groupedItems = GroupedItems.read(compound.getCompound("GroupedItems")); @@ -169,7 +170,7 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { countDown = compound.getInt("CountDown"); covered = compound.getBoolean("Cover"); super.read(compound, clientPacket); - + if (!clientPacket) return; if (compound.contains("Redraw")) @@ -205,10 +206,13 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { if (phase == Phase.ACCEPTING) return; + boolean onClient = world.isRemote; + boolean runLogic = !onClient || isVirtual(); + if (wasPoweredBefore != world.isBlockPowered(pos)) { wasPoweredBefore = world.isBlockPowered(pos); if (wasPoweredBefore) { - if (world.isRemote) + if (!runLogic) return; checkCompletedRecipe(true); } @@ -218,7 +222,7 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { countDown -= getCountDownSpeed(); if (countDown < 0) { countDown = 0; - if (world.isRemote) + if (!runLogic) return; if (RecipeGridHandler.getTargetingCrafter(this) != null) { phase = Phase.EXPORTING; @@ -226,9 +230,11 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { sendData(); return; } - ItemStack result = RecipeGridHandler.tryToApplyRecipe(world, groupedItems); - if (result != null) { + ItemStack result = + isVirtual() ? scriptedResult : RecipeGridHandler.tryToApplyRecipe(world, groupedItems); + + if (result != null) { List containers = new ArrayList<>(); groupedItems.grid.values() .forEach(stack -> { @@ -237,6 +243,9 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { .copy()); }); + if (isVirtual()) + groupedItemsBeforeCraft = groupedItems; + groupedItems = new GroupedItems(result); for (int i = 0; i < containers.size(); i++) { ItemStack stack = containers.get(i); @@ -260,7 +269,7 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { if (countDown < 0) { countDown = 0; - if (world.isRemote) + if (!runLogic) return; MechanicalCrafterTileEntity targetingCrafter = RecipeGridHandler.getTargetingCrafter(this); @@ -283,7 +292,7 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { if (phase == Phase.CRAFTING) { - if (world.isRemote) { + if (onClient) { Direction facing = getBlockState().get(MechanicalCrafterBlock.HORIZONTAL_FACING); float progress = countDown / 2000f; Vec3d facingVec = new Vec3d(facing.getDirectionVec()); @@ -319,7 +328,7 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { countDown -= getCountDownSpeed(); if (countDown < 0) { countDown = 0; - if (world.isRemote) + if (!runLogic) return; tryInsert(); return; @@ -327,7 +336,7 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { } if (phase == Phase.INSERTING) { - if (!world.isRemote && isTargetingBelt()) + if (runLogic && isTargetingBelt()) tryInsert(); return; } @@ -364,7 +373,7 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { stack.setCount(remainder.getCount()); continue; } - + inserted.add(pair); } @@ -410,7 +419,7 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { @Override public void lazyTick() { super.lazyTick(); - if (world.isRemote) + if (world.isRemote && !isVirtual()) return; if (phase == Phase.IDLE && craftingItemPresent()) checkCompletedRecipe(false); @@ -431,7 +440,7 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { protected void checkCompletedRecipe(boolean poweredStart) { if (getSpeed() == 0) return; - if (world.isRemote) + if (world.isRemote && !isVirtual()) return; List chain = RecipeGridHandler.getAllCraftersOfChainIf(this, poweredStart ? MechanicalCrafterTileEntity::craftingItemPresent @@ -471,11 +480,8 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { @Override public LazyOptional getCapability(Capability cap, Direction side) { - if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { - if (getBlockState().get(HORIZONTAL_FACING) == side) - return LazyOptional.empty(); + if (isItemHandlerCap(cap)) return invSupplier.cast(); - } return super.getCapability(cap, side); } @@ -495,4 +501,8 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { return true; } + public void setScriptedResult(ItemStack scriptedResult) { + this.scriptedResult = scriptedResult; + } + } diff --git a/src/main/java/com/simibubi/create/foundation/ponder/PonderScene.java b/src/main/java/com/simibubi/create/foundation/ponder/PonderScene.java index 679854274..68d4fa0b2 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/PonderScene.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/PonderScene.java @@ -451,14 +451,13 @@ public class PonderScene { return ms; } - public void updateSceneRVE() { - Vec3d v = screenToScene(width / 2, height / 2, 500); + public void updateSceneRVE(float pt) { + Vec3d v = screenToScene(width / 2, height / 2, 500, pt); renderViewEntity.setPosition(v.x, v.y, v.z); } - public Vec3d screenToScene(double x, double y, int depth) { - refreshMatrix(); - float pt = AnimationTickHolder.getPartialTicks(); + public Vec3d screenToScene(double x, double y, int depth, float pt) { + refreshMatrix(pt); Vec3d vec = new Vec3d(x, y, depth); vec = vec.subtract(width / 2, height / 2, 200 + offset); @@ -479,17 +478,17 @@ public class PonderScene { return vec; } - public Vec2f sceneToScreen(Vec3d vec) { - refreshMatrix(); + public Vec2f sceneToScreen(Vec3d vec, float pt) { + refreshMatrix(pt); 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() { + protected void refreshMatrix(float pt) { if (cachedMat != null) return; - cachedMat = apply(new MatrixStack()).peek() + cachedMat = apply(new MatrixStack(), pt, false).peek() .getModel(); } diff --git a/src/main/java/com/simibubi/create/foundation/ponder/PonderUI.java b/src/main/java/com/simibubi/create/foundation/ponder/PonderUI.java index 0b241cae0..8cc99fedd 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/PonderUI.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/PonderUI.java @@ -305,8 +305,8 @@ public class PonderUI extends NavigatableSimiScreen { 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); + Vec3d vec1 = t.screenToScene(mouseX, mouseY, 1000, 0); + Vec3d vec2 = t.screenToScene(mouseX, mouseY, -100, 0); Pair pair = activeScene.rayTraceScene(vec1, vec2); hoveredTooltipItem = pair.getFirst(); hoveredBlockPos = pair.getSecond(); @@ -391,7 +391,7 @@ public class PonderUI extends NavigatableSimiScreen { ms.push(); story.transform.updateScreenParams(width, height, slide); story.transform.apply(ms, partialTicks, false); - story.transform.updateSceneRVE(); + story.transform.updateSceneRVE(partialTicks); story.renderScene(buffer, ms, partialTicks); buffer.draw(); @@ -698,7 +698,7 @@ public class PonderUI extends NavigatableSimiScreen { RenderSystem.pushMatrix(); PonderScene story = scenes.get(i); MatrixStack ms = new MatrixStack(); - story.renderOverlay(this, ms, partialTicks); + story.renderOverlay(this, ms, skipCooling > 0 ? 0 : identifyMode ? ponderPartialTicksPaused : partialTicks); RenderSystem.popMatrix(); } diff --git a/src/main/java/com/simibubi/create/foundation/ponder/SceneBuilder.java b/src/main/java/com/simibubi/create/foundation/ponder/SceneBuilder.java index 7c0f52c56..51d2925be 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/SceneBuilder.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/SceneBuilder.java @@ -10,6 +10,8 @@ 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.crafter.ConnectedInputHandler; +import com.simibubi.create.content.contraptions.components.crafter.MechanicalCrafterTileEntity; import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity; import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueItem; import com.simibubi.create.content.contraptions.particle.RotationIndicatorParticleData; @@ -777,6 +779,17 @@ public class SceneBuilder { modifyTileEntity(position, FunnelTileEntity.class, funnel -> funnel.flap(!outward)); } + public void setCraftingResult(BlockPos crafter, ItemStack output) { + modifyTileEntity(crafter, MechanicalCrafterTileEntity.class, mct -> mct.setScriptedResult(output)); + } + + public void connectCrafterInvs(BlockPos position1, BlockPos position2) { + addInstruction(s -> { + ConnectedInputHandler.toggleConnection(s.getWorld(), position1, position2); + s.forEach(WorldSectionElement.class, WorldSectionElement::queueRedraw); + }); + } + } public class DebugInstructions { diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/BearingScenes.java b/src/main/java/com/simibubi/create/foundation/ponder/content/BearingScenes.java index 59aac1a8d..eca104623 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/content/BearingScenes.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/BearingScenes.java @@ -14,6 +14,9 @@ import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Pointing; import net.minecraft.entity.Entity; +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.BlockPos; @@ -25,7 +28,7 @@ public class BearingScenes { scene.title("windmill_source", "Generating Rotational Force using Windmill Bearings"); scene.configureBasePlate(1, 1, 5); scene.setSceneOffsetY(-1); - + scene.world.showSection(util.select.fromTo(1, 0, 1, 5, 0, 5), Direction.UP); scene.world.setBlock(util.grid.at(2, -1, 0), AllBlocks.SAIL.getDefaultState() .with(SailBlock.FACING, Direction.NORTH), false); @@ -280,7 +283,7 @@ public class BearingScenes { scene.title("bearing_modes", "Movement Modes of the Mechanical Bearing"); scene.configureBasePlate(1, 1, 6); scene.setSceneOffsetY(-1); - + Selection sideCog = util.select.position(util.grid.at(7, 0, 3)); Selection cogColumn = util.select.fromTo(6, 1, 3, 6, 4, 3); Selection cogAndClutch = util.select.fromTo(5, 3, 1, 5, 4, 2); @@ -566,4 +569,91 @@ public class BearingScenes { } } + public static void sail(SceneBuilder scene, SceneBuildingUtil util) { + sails(scene, util, false); + } + + public static void sailFrame(SceneBuilder scene, SceneBuildingUtil util) { + sails(scene, util, true); + } + + private static void sails(SceneBuilder scene, SceneBuildingUtil util, boolean frame) { + String plural = frame ? "Sail Frames" : "Sails"; + scene.title(frame ? "sail_frame" : "sail", "Assembling Windmills using " + plural); + scene.configureBasePlate(0, 0, 5); + scene.scaleSceneView(0.9f); + scene.world.showSection(util.select.layer(0), Direction.UP); + scene.idle(5); + + BlockPos bearingPos = util.grid.at(2, 1, 2); + scene.world.showSection(util.select.position(bearingPos), Direction.DOWN); + scene.idle(5); + ElementLink plank = + scene.world.showIndependentSection(util.select.position(bearingPos.up()), Direction.DOWN); + scene.idle(10); + + for (int i = 0; i < 3; i++) { + for (Direction d : Iterate.horizontalDirections) { + BlockPos location = bearingPos.up(i + 1) + .offset(d); + if (frame) + scene.world.modifyBlock(location, s -> AllBlocks.SAIL_FRAME.getDefaultState() + .with(SailBlock.FACING, s.get(SailBlock.FACING)), false); + scene.world.showSectionAndMerge(util.select.position(location), d.getOpposite(), plank); + scene.idle(2); + } + } + + scene.overlay.showText(70) + .text(plural + " are handy blocks to create Windmills with") + .pointAt(util.vector.blockSurface(util.grid.at(1, 3, 2), Direction.WEST)) + .placeNearTarget() + .attachKeyFrame(); + scene.idle(80); + + scene.overlay.showSelectionWithText(util.select.position(bearingPos.up()), 80) + .colored(PonderPalette.GREEN) + .text("They will attach to blocks and each other without the need of Super Glue or Chassis Blocks") + .attachKeyFrame() + .placeNearTarget(); + scene.idle(40); + scene.world.configureCenterOfRotation(plank, util.vector.centerOf(bearingPos)); + + if (!frame) { + scene.world.rotateBearing(bearingPos, 180, 75); + scene.world.rotateSection(plank, 0, 180, 0, 75); + scene.idle(76); + scene.world.rotateBearing(bearingPos, 180, 0); + scene.world.rotateSection(plank, 0, 180, 0, 0); + scene.rotateCameraY(-30); + scene.idle(10); + InputWindowElement input = + new InputWindowElement(util.vector.blockSurface(util.grid.at(2, 3, 1), Direction.NORTH), Pointing.RIGHT) + .withItem(new ItemStack(Items.BLUE_DYE)); + scene.overlay.showControls(input, 30); + scene.idle(7); + scene.world.setBlock(util.grid.at(2, 3, 1), AllBlocks.DYED_SAILS[DyeColor.BLUE.ordinal()].getDefaultState() + .with(SailBlock.FACING, Direction.WEST), true); + scene.idle(10); + scene.overlay.showText(40) + .colored(PonderPalette.BLUE) + .text("Right Click with Dye to paint them") + .attachKeyFrame() + .pointAt(util.vector.blockSurface(util.grid.at(2, 3, 1), Direction.WEST)) + .placeNearTarget(); + scene.idle(20); + scene.overlay.showControls(input, 30); + scene.idle(7); + scene.world.replaceBlocks(util.select.fromTo(2, 2, 1, 2, 4, 1), + AllBlocks.DYED_SAILS[DyeColor.BLUE.ordinal()].getDefaultState() + .with(SailBlock.FACING, Direction.WEST), + true); + scene.idle(20); + } + + scene.world.rotateBearing(bearingPos, 720, 300); + scene.world.rotateSection(plank, 0, 720, 0, 300); + + } + } diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/CrafterScenes.java b/src/main/java/com/simibubi/create/foundation/ponder/content/CrafterScenes.java new file mode 100644 index 000000000..e4823d247 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/CrafterScenes.java @@ -0,0 +1,453 @@ +package com.simibubi.create.foundation.ponder.content; + +import java.util.Collection; + +import com.google.common.collect.ImmutableList; +import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllItems; +import com.simibubi.create.content.contraptions.components.crafter.MechanicalCrafterBlock; +import com.simibubi.create.content.contraptions.components.crafter.MechanicalCrafterTileEntity; +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.utility.Couple; +import com.simibubi.create.foundation.utility.Pointing; + +import net.minecraft.block.Blocks; +import net.minecraft.entity.Entity; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +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 CrafterScenes { + + public static void setup(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("mechanical_crafter", "Setting up Mechanical Crafters"); + scene.configureBasePlate(0, 0, 5); + scene.world.showSection(util.select.layer(0), Direction.UP); + scene.world.modifyKineticSpeed(util.select.everywhere(), f -> 1.5f * f); + + Selection redstone = util.select.fromTo(3, 1, 0, 3, 1, 1); + Selection kinetics = util.select.fromTo(4, 1, 2, 4, 1, 5); + BlockPos depotPos = util.grid.at(0, 1, 2); + Selection crafters = util.select.fromTo(1, 1, 2, 3, 3, 2); + + scene.world.modifyBlocks(crafters, s -> s.with(MechanicalCrafterBlock.POINTING, Pointing.DOWN), false); + scene.world.setKineticSpeed(crafters, 0); + + for (int y = 0; y < 3; y++) { + for (int x = 0; x < 3; x++) { + scene.world.showSection(util.select.position(y == 1 ? x + 1 : 3 - x, y + 1, 2), Direction.DOWN); + scene.idle(2); + } + } + + scene.overlay.showText(70) + .text("An array of Mechanical Crafters can be used to automate any Crafting Recipe") + .pointAt(util.vector.blockSurface(util.grid.at(1, 2, 2), Direction.WEST)) + .attachKeyFrame() + .placeNearTarget(); + scene.idle(80); + + scene.overlay.showControls( + new InputWindowElement(util.vector.blockSurface(util.grid.at(2, 3, 2), Direction.NORTH), Pointing.RIGHT) + .rightClick() + .withWrench(), + 40); + scene.idle(7); + scene.world.cycleBlockProperty(util.grid.at(2, 3, 2), MechanicalCrafterBlock.POINTING); + scene.idle(10); + scene.overlay.showText(50) + .text("Using a Wrench, the Crafters' paths can be arranged") + .pointAt(util.vector.blockSurface(util.grid.at(2, 3, 2), Direction.NORTH)) + .attachKeyFrame() + .placeNearTarget(); + scene.idle(60); + + BlockPos[] positions = new BlockPos[] { util.grid.at(3, 1, 2), util.grid.at(2, 1, 2), util.grid.at(1, 1, 2) }; + + for (BlockPos pos : positions) { + scene.overlay.showControls( + new InputWindowElement(util.vector.blockSurface(pos, Direction.NORTH), Pointing.RIGHT).rightClick() + .withWrench(), + 10); + scene.idle(7); + scene.world.cycleBlockProperty(pos, MechanicalCrafterBlock.POINTING); + scene.idle(15); + } + + scene.overlay.showText(100) + .text("For a valid setup, all paths have to converge into one exit at any side") + .pointAt(util.vector.blockSurface(util.grid.at(1, 1, 2), Direction.WEST) + .add(0, 0, -.5f)) + .colored(PonderPalette.GREEN) + .attachKeyFrame() + .placeNearTarget(); + scene.idle(60); + + Collection> couples = + ImmutableList.of(Couple.create(util.grid.at(3, 3, 2), util.grid.at(3, 2, 2)), + Couple.create(util.grid.at(3, 2, 2), util.grid.at(3, 1, 2)), + Couple.create(util.grid.at(2, 3, 2), util.grid.at(1, 3, 2)), + Couple.create(util.grid.at(3, 1, 2), util.grid.at(2, 1, 2)), + Couple.create(util.grid.at(1, 3, 2), util.grid.at(1, 2, 2)), + Couple.create(util.grid.at(2, 2, 2), util.grid.at(2, 1, 2)), + Couple.create(util.grid.at(1, 2, 2), util.grid.at(1, 1, 2)), + Couple.create(util.grid.at(2, 1, 2), util.grid.at(1, 1, 2)), + Couple.create(util.grid.at(1, 1, 2), util.grid.at(0, 1, 2))); + + for (Couple c : couples) { + scene.idle(5); + Vec3d p1 = util.vector.blockSurface(c.getFirst(), Direction.NORTH) + .add(0, 0, -0.125); + Vec3d p2 = util.vector.blockSurface(c.getSecond(), Direction.NORTH) + .add(0, 0, -0.125); + AxisAlignedBB point = new AxisAlignedBB(p1, p1); + AxisAlignedBB line = new AxisAlignedBB(p1, p2); + scene.overlay.chaseBoundingBoxOutline(PonderPalette.GREEN, p1, point, 2); + scene.idle(1); + scene.overlay.chaseBoundingBoxOutline(PonderPalette.GREEN, p1, line, 30); + } + + scene.world.showSection(util.select.position(depotPos), Direction.EAST); + scene.idle(20); + scene.overlay.showText(60) + .text("The outputs will be placed into the inventory at the exit") + .pointAt(util.vector.blockSurface(util.grid.at(0, 1, 2), Direction.NORTH)) + .placeNearTarget(); + scene.idle(70); + + scene.rotateCameraY(60); + scene.idle(20); + scene.world.showSection(kinetics, Direction.NORTH); + scene.overlay.showText(60) + .text("Mechanical Crafters require Rotational Force to operate") + .pointAt(util.vector.blockSurface(util.grid.at(4, 1, 2), Direction.NORTH)) + .attachKeyFrame() + .placeNearTarget(); + scene.idle(8); + scene.world.setKineticSpeed(crafters, -48); + scene.world.multiplyKineticSpeed(util.select.position(3, 2, 2) + .add(util.select.position(2, 3, 2)) + .add(util.select.position(1, 2, 2)) + .add(util.select.position(2, 1, 2)), -1); + scene.idle(55); + scene.rotateCameraY(-60); + + scene.idle(40); + ItemStack planks = new ItemStack(Items.OAK_PLANKS); + scene.overlay.showControls( + new InputWindowElement(util.vector.blockSurface(util.grid.at(1, 3, 2), Direction.NORTH), Pointing.RIGHT) + .rightClick() + .withItem(planks), + 40); + scene.idle(7); + Class type = MechanicalCrafterTileEntity.class; + scene.world.modifyTileEntity(util.grid.at(1, 3, 2), type, mct -> mct.getInventory() + .insertItem(0, planks.copy(), false)); + + scene.idle(10); + scene.overlay.showText(50) + .text("Right-Click the front to insert Items manually") + .pointAt(util.vector.blockSurface(util.grid.at(1, 3, 2), Direction.NORTH)) + .attachKeyFrame() + .placeNearTarget(); + scene.idle(60); + + ItemStack alloy = AllItems.ANDESITE_ALLOY.asStack(); + ItemStack log = new ItemStack(Items.OAK_LOG); + + scene.world.setCraftingResult(util.grid.at(1, 1, 2), AllBlocks.ANDESITE_CASING.asStack(4)); + + scene.world.modifyTileEntity(util.grid.at(2, 3, 2), type, mct -> mct.getInventory() + .insertItem(0, planks.copy(), false)); + scene.idle(5); + scene.world.modifyTileEntity(util.grid.at(3, 3, 2), type, mct -> mct.getInventory() + .insertItem(0, planks.copy(), false)); + scene.idle(5); + scene.world.modifyTileEntity(util.grid.at(3, 2, 2), type, mct -> mct.getInventory() + .insertItem(0, alloy.copy(), false)); + scene.idle(5); + scene.world.modifyTileEntity(util.grid.at(2, 2, 2), type, mct -> mct.getInventory() + .insertItem(0, log.copy(), false)); + scene.idle(5); + scene.world.modifyTileEntity(util.grid.at(1, 2, 2), type, mct -> mct.getInventory() + .insertItem(0, alloy.copy(), false)); + scene.idle(5); + scene.world.modifyTileEntity(util.grid.at(1, 1, 2), type, mct -> mct.getInventory() + .insertItem(0, planks.copy(), false)); + scene.idle(5); + scene.world.modifyTileEntity(util.grid.at(2, 1, 2), type, mct -> mct.getInventory() + .insertItem(0, planks.copy(), false)); + scene.idle(5); + scene.world.modifyTileEntity(util.grid.at(3, 1, 2), type, mct -> mct.getInventory() + .insertItem(0, planks.copy(), false)); + + scene.overlay.showText(80) + .attachKeyFrame() + .text("Once every slot of a path contains an Item, the crafting process will begin") + .pointAt(util.vector.blockSurface(util.grid.at(1, 3, 2), Direction.WEST)) + .placeNearTarget(); + scene.idle(180); + + scene.world.removeItemsFromBelt(depotPos); + + ItemStack stick = new ItemStack(Items.STICK); + ItemStack iron = new ItemStack(Items.IRON_INGOT); + + scene.world.setCraftingResult(util.grid.at(1, 1, 2), new ItemStack(Items.IRON_PICKAXE)); + + scene.world.modifyTileEntity(util.grid.at(1, 3, 2), type, mct -> mct.getInventory() + .insertItem(0, iron.copy(), false)); + scene.idle(2); + scene.world.modifyTileEntity(util.grid.at(2, 3, 2), type, mct -> mct.getInventory() + .insertItem(0, iron.copy(), false)); + scene.idle(2); + scene.world.modifyTileEntity(util.grid.at(3, 3, 2), type, mct -> mct.getInventory() + .insertItem(0, iron.copy(), false)); + scene.idle(2); + scene.world.modifyTileEntity(util.grid.at(2, 2, 2), type, mct -> mct.getInventory() + .insertItem(0, stick.copy(), false)); + scene.idle(2); + scene.world.modifyTileEntity(util.grid.at(2, 1, 2), type, mct -> mct.getInventory() + .insertItem(0, stick.copy(), false)); + scene.world.showSection(redstone, Direction.SOUTH); + scene.idle(10); + + scene.overlay.showText(90) + .attachKeyFrame() + .colored(PonderPalette.RED) + .text("For recipes not fully occupying the crafter setup, the start can be forced using a Redstone Pulse") + .pointAt(util.vector.blockSurface(util.grid.at(1, 2, 2), Direction.NORTH)) + .placeNearTarget(); + scene.idle(100); + scene.effects.indicateRedstone(util.grid.at(3, 1, 0)); + scene.world.toggleRedstonePower(redstone); + scene.idle(20); + scene.world.toggleRedstonePower(redstone); + } + + public static void connect(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("mechanical_crafter_connect", "Connecting Inventories of Crafters"); + scene.configureBasePlate(0, 0, 5); + scene.world.showSection(util.select.layer(0), Direction.UP); + + for (int y = 0; y < 3; y++) { + for (int x = 0; x < 2; x++) { + scene.world.showSection(util.select.position(y == 1 ? x + 1 : 2 - x, y + 1, 2), Direction.DOWN); + scene.idle(2); + } + } + + Class type = MechanicalCrafterTileEntity.class; + BlockPos depotPos = util.grid.at(0, 1, 2); + Selection funnel = util.select.fromTo(4, 1, 5, 4, 1, 2) + .add(util.select.fromTo(3, 2, 2, 3, 1, 2)); + Selection kinetics = util.select.position(3, 3, 2) + .add(util.select.fromTo(3, 3, 3, 3, 1, 3)); + scene.idle(5); + + scene.world.showSection(kinetics, Direction.NORTH); + scene.idle(5); + scene.world.showSection(util.select.position(depotPos), Direction.EAST); + scene.idle(10); + scene.world.showSection(funnel, Direction.WEST); + scene.rotateCameraY(60); + ItemStack planks = new ItemStack(Items.OAK_PLANKS); + scene.world.createItemOnBelt(util.grid.at(4, 1, 2), Direction.EAST, planks.copy()); + scene.idle(22); + + scene.world.modifyTileEntity(util.grid.at(2, 2, 2), type, mct -> mct.getInventory() + .insertItem(0, planks.copy(), false)); + scene.world.removeItemsFromBelt(util.grid.at(3, 1, 2)); + scene.world.flapFunnel(util.grid.at(3, 2, 2), false); + + scene.overlay.showSelectionWithText(util.select.position(2, 2, 2), 70) + .attachKeyFrame() + .placeNearTarget() + .pointAt(util.vector.blockSurface(util.grid.at(2, 2, 2), Direction.NORTH)) + .text("Items can be inserted to Crafters automatically"); + scene.idle(80); + + scene.rotateCameraY(-60 - 90 - 30); + scene.idle(40); + + Vec3d v = util.vector.blockSurface(util.grid.at(2, 2, 2), Direction.WEST); + AxisAlignedBB bb = new AxisAlignedBB(v, v).grow(.125f, .5, .5); + v = v.add(0, 0, .5); + + scene.overlay.chaseBoundingBoxOutline(PonderPalette.WHITE, new Object(), bb, 45); + scene.overlay.showControls(new InputWindowElement(v, Pointing.LEFT).rightClick() + .withWrench(), 40); + scene.idle(7); + scene.world.connectCrafterInvs(util.grid.at(2, 2, 2), util.grid.at(1, 2, 2)); + scene.idle(40); + scene.overlay.showSelectionWithText(util.select.fromTo(2, 2, 2, 1, 2, 2), 70) + .attachKeyFrame() + .placeNearTarget() + .pointAt(v) + .text("Using the Wrench at their backs, Mechanical Crafter inputs can be combined"); + scene.idle(80); + scene.overlay.showControls(new InputWindowElement(v.add(0, 1, 0), Pointing.LEFT).rightClick() + .withWrench(), 20); + scene.idle(7); + scene.world.connectCrafterInvs(util.grid.at(2, 3, 2), util.grid.at(1, 3, 2)); + scene.idle(20); + scene.overlay.showControls(new InputWindowElement(v.add(0, -1, 0), Pointing.LEFT).rightClick() + .withWrench(), 20); + scene.idle(7); + scene.world.connectCrafterInvs(util.grid.at(2, 1, 2), util.grid.at(1, 1, 2)); + scene.idle(20); + scene.overlay.showControls(new InputWindowElement(v.add(.5, -.5, 0), Pointing.LEFT).rightClick() + .withWrench(), 20); + scene.idle(7); + scene.world.connectCrafterInvs(util.grid.at(2, 1, 2), util.grid.at(2, 2, 2)); + scene.idle(10); + scene.overlay.showControls(new InputWindowElement(v.add(.5, .5, 0), Pointing.LEFT).rightClick() + .withWrench(), 20); + scene.idle(7); + scene.world.connectCrafterInvs(util.grid.at(2, 2, 2), util.grid.at(2, 3, 2)); + scene.idle(20); + + scene.rotateCameraY(90 + 30); + scene.idle(40); + scene.overlay.showSelectionWithText(util.select.fromTo(1, 1, 2, 2, 3, 2), 70) + .attachKeyFrame() + .placeNearTarget() + .text("All connected Crafters can now be accessed by the same input location"); + scene.idle(60); + scene.overlay.showControls( + new InputWindowElement(util.vector.centerOf(util.grid.at(4, 2, 2)), Pointing.DOWN).withItem(planks), 40); + scene.idle(7); + scene.world.createItemOnBelt(util.grid.at(4, 1, 2), Direction.EAST, + ItemHandlerHelper.copyStackWithSize(planks, 16)); + scene.idle(22); + + scene.world.removeItemsFromBelt(util.grid.at(3, 1, 2)); + BlockPos[] positions = new BlockPos[] { util.grid.at(2, 3, 2), util.grid.at(1, 3, 2), util.grid.at(1, 2, 2), + util.grid.at(2, 1, 2), util.grid.at(1, 1, 2) }; + + scene.world.setCraftingResult(util.grid.at(1, 1, 2), new ItemStack(Items.OAK_DOOR, 3)); + for (BlockPos pos : positions) { + scene.world.modifyTileEntity(pos, type, mct -> mct.getInventory() + .insertItem(0, planks.copy(), false)); + scene.idle(1); + } + + } + + public static void covers(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("mechanical_crafter_covers", "Covering slots of Mechanical Crafters"); + scene.configureBasePlate(0, 0, 5); + scene.world.showSection(util.select.layer(0), Direction.UP); + + scene.world.setBlock(util.grid.at(2, 2, 2), Blocks.AIR.getDefaultState(), false); + + Selection kinetics = util.select.fromTo(3, 1, 2, 3, 1, 5); + scene.world.setKineticSpeed(util.select.fromTo(1, 2, 2, 3, 1, 2), 0); + + scene.world.showSection(util.select.position(3, 2, 2), Direction.EAST); + scene.idle(5); + scene.world.showSection(util.select.position(2, 1, 2), Direction.DOWN); + scene.idle(5); + scene.world.showSection(util.select.position(1, 2, 2), Direction.WEST); + scene.idle(5); + + ItemStack iron = new ItemStack(Items.IRON_INGOT); + + Class type = MechanicalCrafterTileEntity.class; + scene.world.modifyTileEntity(util.grid.at(3, 2, 2), type, mct -> mct.getInventory() + .insertItem(0, iron.copy(), false)); + scene.idle(5); + scene.world.modifyTileEntity(util.grid.at(2, 1, 2), type, mct -> mct.getInventory() + .insertItem(0, iron.copy(), false)); + scene.idle(5); + scene.world.modifyTileEntity(util.grid.at(1, 2, 2), type, mct -> mct.getInventory() + .insertItem(0, iron.copy(), false)); + scene.idle(5); + + Selection emptyCrafter = util.select.position(2, 2, 2); + scene.overlay.showSelectionWithText(emptyCrafter, 90) + .attachKeyFrame() + .colored(PonderPalette.RED) + .text("Some recipes will require additional Crafters to bridge gaps in the path") + .placeNearTarget(); + scene.idle(70); + scene.world.restoreBlocks(emptyCrafter); + scene.world.setCraftingResult(util.grid.at(2, 2, 2), new ItemStack(Items.BUCKET)); + scene.world.showSection(emptyCrafter, Direction.DOWN); + scene.idle(10); + scene.world.showSection(util.select.position(2, 3, 2), Direction.DOWN); + scene.world.showSection(kinetics, Direction.NORTH); + scene.idle(5); + scene.world.setKineticSpeed(util.select.fromTo(3, 1, 2, 1, 2, 2), -32); + scene.world.setKineticSpeed(util.select.position(3, 1, 2) + .add(emptyCrafter), 32); + + scene.idle(20); + + scene.overlay.showText(90) + .attachKeyFrame() + .colored(PonderPalette.GREEN) + .pointAt(util.vector.blockSurface(util.grid.at(2, 2, 2), Direction.NORTH)) + .text("Using Slot Covers, Crafters can be set to act as an Empty Slot in the arrangement") + .placeNearTarget(); + scene.idle(100); + scene.overlay + .showControls(new InputWindowElement(util.vector.blockSurface(util.grid.at(2, 2, 2), Direction.NORTH) + .add(0.5, 0, 0), Pointing.RIGHT).withItem(AllItems.CRAFTER_SLOT_COVER.asStack()) + .rightClick(), + 50); + scene.idle(7); + scene.world.modifyTileNBT(emptyCrafter, type, compound -> compound.putBoolean("Cover", true)); + scene.idle(130); + + scene.overlay.showControls( + new InputWindowElement(util.vector.blockSurface(util.grid.at(2, 3, 2), Direction.WEST), Pointing.LEFT) + .withItem(new ItemStack(Items.BUCKET)), + 40); + scene.idle(50); + scene.world.showSection(util.select.position(4, 2, 2), Direction.DOWN); + + scene.world.connectCrafterInvs(util.grid.at(3, 2, 2), util.grid.at(2, 2, 2)); + scene.idle(5); + scene.world.connectCrafterInvs(util.grid.at(2, 1, 2), util.grid.at(2, 2, 2)); + scene.idle(5); + scene.world.connectCrafterInvs(util.grid.at(1, 2, 2), util.grid.at(2, 2, 2)); + scene.idle(10); + + scene.overlay.showSelectionWithText(util.select.fromTo(3, 2, 2, 1, 2, 2) + .add(util.select.position(2, 1, 2)), 80) + .attachKeyFrame() + .pointAt(util.vector.blockSurface(util.grid.at(2, 2, 2), Direction.NORTH)) + .text("Shared Inputs created with the Wrench at the back can also reach across covered Crafters") + .placeNearTarget(); + scene.idle(60); + + ElementLink ingot = + scene.world.createItemEntity(util.vector.centerOf(4, 4, 2), util.vector.of(0, 0.2, 0), iron); + scene.idle(17); + scene.world.modifyEntity(ingot, Entity::remove); + scene.world.modifyTileEntity(util.grid.at(3, 2, 2), type, mct -> mct.getInventory() + .insertItem(0, iron.copy(), false)); + ingot = scene.world.createItemEntity(util.vector.centerOf(4, 4, 2), util.vector.of(0, 0.2, 0), iron); + scene.idle(17); + scene.world.modifyEntity(ingot, Entity::remove); + scene.world.modifyTileEntity(util.grid.at(2, 1, 2), type, mct -> mct.getInventory() + .insertItem(0, iron.copy(), false)); + ingot = scene.world.createItemEntity(util.vector.centerOf(4, 4, 2), util.vector.of(0, 0.2, 0), iron); + scene.idle(17); + scene.world.modifyEntity(ingot, Entity::remove); + scene.world.modifyTileEntity(util.grid.at(1, 2, 2), type, mct -> mct.getInventory() + .insertItem(0, iron.copy(), false)); + + } + +} 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 index 7d5877ff9..32c8a6445 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/content/PonderIndex.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderIndex.java @@ -97,6 +97,13 @@ public class PonderIndex { PonderRegistry.addStoryBoard(AllBlocks.BLAZE_BURNER, "blaze_burner", ProcessingScenes::blazeBurner); PonderRegistry.addStoryBoard(AllBlocks.DEPOT, "depot", BeltScenes::depot); + // Crafters + PonderRegistry.forComponents(AllBlocks.MECHANICAL_CRAFTER) + .addStoryBoard("mechanical_crafter/setup", CrafterScenes::setup) + .addStoryBoard("mechanical_crafter/connect", CrafterScenes::connect); + PonderRegistry.forComponents(AllBlocks.MECHANICAL_CRAFTER, AllItems.CRAFTER_SLOT_COVER) + .addStoryBoard("mechanical_crafter/covers", CrafterScenes::covers); + // Chutes PonderRegistry.forComponents(AllBlocks.CHUTE) .addStoryBoard("chute/downward", ChuteScenes::downward, PonderTag.LOGISTICS) @@ -148,6 +155,10 @@ public class PonderIndex { .addStoryBoard("windmill_bearing/source", BearingScenes::windmillsAsSource, PonderTag.KINETIC_SOURCES) .addStoryBoard("windmill_bearing/structure", BearingScenes::windmillsAnyStructure, PonderTag.MOVEMENT_ANCHOR); + PonderRegistry.forComponents(AllBlocks.SAIL) + .addStoryBoard("sail", BearingScenes::sail); + PonderRegistry.forComponents(AllBlocks.SAIL_FRAME) + .addStoryBoard("sail", BearingScenes::sailFrame); // Mechanical Bearing PonderRegistry.forComponents(AllBlocks.MECHANICAL_BEARING) @@ -332,6 +343,11 @@ public class PonderIndex { .add(AllBlocks.CREATIVE_FLUID_TANK) .add(AllBlocks.CREATIVE_MOTOR); + PonderRegistry.tags.forTag(PonderTag.SAILS) + .add(AllBlocks.SAIL) + .add(AllBlocks.SAIL_FRAME) + .add(Blocks.WHITE_WOOL); + PonderRegistry.tags.forTag(PonderTag.REDSTONE) .add(AllBlocks.NIXIE_TUBE) .add(AllBlocks.REDSTONE_CONTACT) 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 index bf649665d..6eca976b0 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/content/PonderTag.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderTag.java @@ -59,6 +59,10 @@ public class PonderTag implements IScreenRenderable { .defaultLang("Block Attachment Utility", "Tools and Components used to assemble structures moved as an animated Contraption"), + SAILS = new PonderTag("windmill_sails").item(AllBlocks.WINDMILL_BEARING.get(), true, true) + .defaultLang("Sails for Windmill Bearings", + "Blocks that count towards the strength of a Windmill Contraption when assembled"), + // FLUID_TRANSFER = new PonderTag("fluid_transfer").idAsIcon(), // // OPEN_INVENTORY = new PonderTag("open_inventory").item(AllBlocks.BASIN.get() 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 index 0932b7443..dfa195ead 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/elements/InputWindowElement.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/elements/InputWindowElement.java @@ -93,7 +93,7 @@ public class InputWindowElement extends AnimatedOverlayElement { if (fade < 1 / 16f) return; Vec2f sceneToScreen = scene.getTransform() - .sceneToScreen(sceneSpace); + .sceneToScreen(sceneSpace, partialTicks); if (hasIcon) { width += 24; 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 index 99d8081aa..262a64dee 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/elements/ParrotElement.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/elements/ParrotElement.java @@ -246,7 +246,7 @@ public class ParrotElement extends AnimatedSceneElement { double mouseX = minecraft.mouseHelper.getMouseX() * w.getScaledWidth() / w.getWidth(); double mouseY = minecraft.mouseHelper.getMouseY() * w.getScaledHeight() / w.getHeight(); return scene.getTransform() - .screenToScene(mouseX, mouseY, 300); + .screenToScene(mouseX, mouseY, 300, 0); } } 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 index cb985822c..7c28c5e01 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/elements/TextWindowElement.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/elements/TextWindowElement.java @@ -10,7 +10,6 @@ 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.FontHelper; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec2f; @@ -87,7 +86,7 @@ public class TextWindowElement extends AnimatedOverlayElement { if (fade < 1 / 16f) return; Vec2f sceneToScreen = vec != null ? scene.getTransform() - .sceneToScreen(vec) : new Vec2f(screen.width / 2, (screen.height - 200) / 2 + y - 8); + .sceneToScreen(vec, partialTicks) : new Vec2f(screen.width / 2, (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)); @@ -122,8 +121,11 @@ public class TextWindowElement extends AnimatedOverlayElement { RenderSystem.popMatrix(); } - FontHelper.drawSplitString(screen.getFontRenderer(), bakedText, targetX - 10, 3, textWidth, - ColorHelper.applyAlpha(brighterColor, fade)); + for (int i = 0; i < list.size(); i++) { + String s = list.get(i); + screen.getFontRenderer() + .drawString(s, targetX - 10, 3 + 9 * i, ColorHelper.applyAlpha(brighterColor, fade)); + } RenderSystem.popMatrix(); } diff --git a/src/main/resources/ponder/mechanical_crafter/connect.nbt b/src/main/resources/ponder/mechanical_crafter/connect.nbt new file mode 100644 index 0000000000000000000000000000000000000000..27dac0c32b5fc7555c8f8ca246612c305ab3361c GIT binary patch literal 1144 zcmV-;1c&<{iwFP!000000Nq*JZrer>U0y{>a*_fq(4wEvFNjm1N#ryU5ZDIX7HwaI z6*-a!Q(R(qWhH*{SLMC^g1)8chxApQrAS>UQChijD~JGLo7_D!bI#0gNY@GRi7ldA zum~aQbnvwCbbaDMA|n}rAnNdm+l^UpE$aBkH$JgaCW=k7!y=B5R6@REagDKNjZs=- zYT#HJIJO2(aTptLj5TY@IHm@UrGaB>;1q|c!LzBs^Clci1IO0DnMt9+v!%iFCLBux z$JW3p4qJm~TZ89KIF<&Ey%wiVtfVVFVn!ip1|0DEX$UEkb<(^T$#f)Nj(R=d7O}6e z!f}V^6Q?awVQiGbSR;k?5K{cUS1Fzyp%mr@DYhjvZfPeWyi>R9ivr}l z{k4+99&uY#L`k36=NIR%%0#bjFi5j4=D_Hh`xcVE94MDH2(GQCGb3V3XCtSx3$a|& zyUN_yyK_Sxgqv=e8)H{)+~wr^?yf5ND%e^~x1}62$jK!WI9uJo1rJp{u4(vXVx7aS z|BpxBip`P~?%_Wbzdb@J%nedlW2EWCZ zXn%hiyIaRBJ&nsFVNf+^Eyhvb({TTO9TkfT}NW&O#g~ho?t5j!He8r3aQzYAKCD zN>KC8BM<9~4uO0*pM=MQNJ1xI3A%xsiWQ&FSBQj-JK5L&+1;fNj!O1R&Qjp&-vwC8 zJ>&sP*-03e1CMwqixQb#;Zc7eXDHQ^#|mUH?G8?l#sYAEO1UH!B;nkgJq96h5EC)( zBlQ8}(JeLz8qe%4wL2{fib*c_W}}iAJ9}fUgc)O+$O?Q*nm}pbx_Xgt5C$Qs;-I2(_wM$x7nPely>EGqZLZAOxn;bMye9ynMPC zU9AuT%yp_$R8X!ETF04)PE?zIJPpAsgsL}9mj}MmT%*}BZ{sYnaT+$R1&(Kd!z^&> z<*dPRme@3LTnik}0*6`P)XTNVvuly(bvT{{4zs|SN@0;_&mzz3a6AhfW`R>LW|3!R zk>_sf-WTKiDv;KZ7|94r zcazEFhjI7JxZ`B8^;(KiK_O}!DhlznOk*&i_#JVIl8iPEP>+Q?@geB&f=8)7dvj4n z&5me9m7aXqd=bYOA8Cn7J+E@(cH_z9=LNJ5cYTVa`lmzNAOM$~Jc%R{hrJ<23D47r zXT3=BzDC)Gu$!OKloRr7=EDiWuc9gBSoFXmn*VpL-4nB9vM0+9Tpk( zPSPB88Z{-jG!pC?367VQU6Y6Rzoc%Xq#RRL^HQ*XA;qe?{4*&o@39o_5-Hrf+ZD|& zzfV$3<(QMgH&S@8^G@p_d(lTC_z-`aq zq6C#*Qa)Y-ZR74A4$-Q^Vg4B@xcfZfRXo@l9^Wo*okxAR?HV4q>e<(y;}PCHJ(@gL z>fv8|=m=q>;2CO-9aji!5WjaXy29k|w)CI7CIX}*bHPdo5Q(u literal 0 HcmV?d00001 diff --git a/src/main/resources/ponder/mechanical_crafter/setup.nbt b/src/main/resources/ponder/mechanical_crafter/setup.nbt new file mode 100644 index 0000000000000000000000000000000000000000..5b744378fd29fa0b2522cfd421067bdca67db524 GIT binary patch literal 904 zcmV;319$u%iwFP!000000Nq*5j?+jGF5B&l;~4=5R=fKOoVYS@0A>(GS`8zOSOJ%) z$F3w+oNlYTgMrgL6?b?NeqLg4*|M=cCODZE8itULtR!~zSM}A`RdzZdKp&V+-l7Kp z#o^Pz=;-w!Kw%P-poU`fp?8|fXsSc{a;pzsCUrfj86NoBaD&y1wvE$a<1E>@7C4>- z4zs|ihqDI9>9ASGaV>B>3mj&FQxDf7&#pzD*Wq{;ILrd4k-{R+o<*M5;dmA}%mSw# z%p%XsBG2n^JPRDwi4%e+PE7!A62o4kkk0SNm`M}D-qX3s=H}siG(zP8JE01v89^WX zfx(%s@V;m5EUD>MUP8EbAcerlU_1~6O>N_l8(uU6TCvXaGNs_WsNP>zXd%rqN~S3) zhkA>Dk|D+)%1bwn=%X%AJj-Ho=LFy%Pq;>4gTsFwdC)(Qb72l;F22(3oyfV0uyD6n zEIw84_A7UsEcPBNInOA>f+U6bSW#}OQ2Yb=3Kbdc9HGgjn)(nN@Qg=^dGq9~h`LVG zbsu&g#4*MvMxoaCO9k9Pyjc8q2EF4uK1EVqIlNIMwG`m*N`M(g6E2d7r^86`kwFzg ze;{5_FO}-exesTp6i$Z}-p`QY;iXD(cMGL(uS$x`sfsUKTorX?bV+g1g0>-eA)P-e zIy#wUDGsNJK$AolNpRYA3tHyEHn+MzZt;?GstRvQ;csqr*Nyhx7E0k>l@ym#6`!}b zDjGR{kE*B})HXhTIJF$VS5<6lgSrwaE~hF!Z*f&Ll5|M1!B2wGswctrW<+oEdBm%D zur)m1pZ#(kbxGW*c;Kqd7{A41XY=$}=CM)_|C?VJ-M^;Vo20=CoA#z;pI$o|Pth1G z+FKX^JK{5hzh)F|S=9UaBr!OQq#!ypskXRzZlQ(DhvkNHbM>1&EJ}KKtYn6&*ntk9 zH==xsG5A6%GYKHbWFky?MkV8kX;4--nq|n{oa|I8$777aAMsQpf$-Of2Ip;qcfG=k zy`@V zO2=GHhmuc+r*mVZ_zu3D$AlCF=4&}Oljd8Q(&GP#xClSTmSGtNIJX;*f1Z1!@HBbC eVV)?YHN0EgiT_2V6LJs1JNO@`1_t5x7ytl?0j^H~ literal 0 HcmV?d00001 diff --git a/src/main/resources/ponder/sail.nbt b/src/main/resources/ponder/sail.nbt new file mode 100644 index 0000000000000000000000000000000000000000..9b325ae4d6ba5651d410acdac9a291182c6336b2 GIT binary patch literal 447 zcmV;w0YLsAiwFP!000000G*ZLO2aS^$FEJgbrV5B&^PcM{3Zx~5fMedj;uX3EK5p~ zG4R2BKGSOEsA+e25NLb<|Bv+ULgoN7;7)!Z1AulFam}Da?WLFKpp6+!mdaEsHxDnD zGhmHz(XDr zjKJXpP9E2uCLj1OM(712^kR&|2pmq}#NdQpa6&J}IE=vINzNRYUit!xrv|Zx&UbPj z9$ok0xv7IP3;ApPrtmvIecWg*^;^ImJyq5y^&-@!OO}w!8qO<=!FIKkx?W4A7E2U1 z7z#MP6VBhFMjP_=K!>v4G_Zk***^(9pi0F11cwngeNBqP37o#B z&xtkMpWx|04G(E}LNjfILhrG?49XJty;vh$tfj`vidTQNeU}~=mC<2Tf+;G_eicre z?V`I;QduKbi$)2(a$$t$57snj+pDOA$*ZW^;mkM9&NwuXLtef`=XdVY= Date: Mon, 22 Mar 2021 02:05:47 +0100 Subject: [PATCH 10/14] Thinking Arms - Ponder Scenes for the Mechanical Arm - Fixed empty basins showing a fluid container tooltip --- .../java/com/simibubi/create/AllShapes.java | 12 +- .../goggles/IHaveGoggleInformation.java | 25 +- .../block/mechanicalArm/ArmTileEntity.java | 2 +- .../foundation/ponder/content/ArmScenes.java | 611 ++++++++++++++++++ .../ponder/content/BearingScenes.java | 33 +- .../ponder/content/PonderIndex.java | 8 + .../ponder/content/PonderPalette.java | 3 + .../foundation/ponder/content/PonderTag.java | 2 +- .../ponder/content/PonderTagScreen.java | 6 + .../models/block/mechanical_arm/block.json | 17 +- .../models/block/mechanical_arm/item.json | 81 +-- .../ponder/mechanical_arm/filter.nbt | Bin 0 -> 1214 bytes .../resources/ponder/mechanical_arm/modes.nbt | Bin 0 -> 1210 bytes .../ponder/mechanical_arm/redstone.nbt | Bin 0 -> 1113 bytes .../resources/ponder/mechanical_arm/setup.nbt | Bin 0 -> 1005 bytes 15 files changed, 733 insertions(+), 67 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/ponder/content/ArmScenes.java create mode 100644 src/main/resources/ponder/mechanical_arm/filter.nbt create mode 100644 src/main/resources/ponder/mechanical_arm/modes.nbt create mode 100644 src/main/resources/ponder/mechanical_arm/redstone.nbt create mode 100644 src/main/resources/ponder/mechanical_arm/setup.nbt diff --git a/src/main/java/com/simibubi/create/AllShapes.java b/src/main/java/com/simibubi/create/AllShapes.java index 7c102139e..3afa8656a 100644 --- a/src/main/java/com/simibubi/create/AllShapes.java +++ b/src/main/java/com/simibubi/create/AllShapes.java @@ -108,9 +108,7 @@ public class AllShapes { PUMP = shape(2, 0, 2, 14, 5, 14).add(4, 0, 4, 12, 16, 12) .add(3, 12, 3, 13, 16, 13) .forDirectional(Direction.UP), - CRUSHING_WHEEL_CONTROLLER_COLLISION = shape(0, 0, 0, 16, 13, 16) - .forDirectional(Direction.DOWN) - + CRUSHING_WHEEL_CONTROLLER_COLLISION = shape(0, 0, 0, 16, 13, 16).forDirectional(Direction.DOWN) ; @@ -144,12 +142,12 @@ public class AllShapes { .add(2, 0, 2, 14, 2, 14) .build(), SPEED_CONTROLLER = shape(0, 0, 0, 16, 4, 16).add(1, 1, 1, 15, 13, 15) - .add(0, 8, 0, 16, 14, 16).build(), + .add(0, 8, 0, 16, 14, 16) + .build(), HEATER_BLOCK_SHAPE = shape(2, 0, 2, 14, 14, 14).add(0, 0, 0, 16, 4, 16) .build(), HEATER_BLOCK_SPECIAL_COLLISION_SHAPE = shape(0, 0, 0, 16, 4, 16).build(), - CRUSHING_WHEEL_COLLISION_SHAPE = cuboid(0, 0, 0, 16, 16, 16), - SEAT = cuboid(0, 0, 0, 16, 8, 16), + CRUSHING_WHEEL_COLLISION_SHAPE = cuboid(0, 0, 0, 16, 16, 16), SEAT = cuboid(0, 0, 0, 16, 8, 16), SEAT_COLLISION = cuboid(0, 0, 0, 16, 6, 16), MECHANICAL_PROCESSOR_SHAPE = shape(VoxelShapes.fullCube()).erase(4, 0, 4, 12, 16, 12) .build(), @@ -172,8 +170,10 @@ public class AllShapes { GAUGE_SHAPE_UP = shape(1, 0, 0, 15, 2, 16).add(2, 2, 1, 14, 14, 15) .build(), MECHANICAL_ARM = shape(2, 0, 2, 14, 10, 14).add(3, 0, 3, 13, 14, 13) + .add(0, 0, 0, 16, 6, 16) .build(), MECHANICAL_ARM_CEILING = shape(2, 6, 2, 14, 16, 14).add(3, 2, 3, 13, 16, 13) + .add(0, 10, 0, 16, 16, 16) .build(), CHUTE = shape(1, 8, 1, 15, 16, 15).add(2, 0, 2, 14, 8, 14) .build(), diff --git a/src/main/java/com/simibubi/create/content/contraptions/goggles/IHaveGoggleInformation.java b/src/main/java/com/simibubi/create/content/contraptions/goggles/IHaveGoggleInformation.java index 1c21fe6b0..692c2fa8e 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/goggles/IHaveGoggleInformation.java +++ b/src/main/java/com/simibubi/create/content/contraptions/goggles/IHaveGoggleInformation.java @@ -1,6 +1,11 @@ package com.simibubi.create.content.contraptions.goggles; +import java.text.NumberFormat; +import java.util.List; +import java.util.Locale; + import com.simibubi.create.foundation.utility.Lang; + import net.minecraft.client.Minecraft; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.StringTextComponent; @@ -10,10 +15,6 @@ import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.capability.IFluidHandler; -import java.text.NumberFormat; -import java.util.List; -import java.util.Locale; - /* * Implement this Interface in the TileEntity class that wants to add info to the screen * */ @@ -34,7 +35,8 @@ public interface IHaveGoggleInformation { } static String format(double d) { - return numberFormat.get().format(d); + return numberFormat.get() + .format(d); } default boolean containedFluidTooltip(List tooltip, boolean isPlayerSneaking, @@ -74,7 +76,13 @@ public interface IHaveGoggleInformation { isEmpty = false; } - if (tank.getTanks() > 1 || !isEmpty) + if (tank.getTanks() > 1) { + if (isEmpty) + tooltip.remove(tooltip.size() - 1); + return true; + } + + if (!isEmpty) return true; ITextComponent capacity = new StringTextComponent(Lang.translate("gui.goggles.fluid_container.capacity")) @@ -101,7 +109,10 @@ public interface IHaveGoggleInformation { } public void update() { - format = NumberFormat.getInstance(Minecraft.getInstance().getLanguageManager().getCurrentLanguage().getJavaLocale()); + format = NumberFormat.getInstance(Minecraft.getInstance() + .getLanguageManager() + .getCurrentLanguage() + .getJavaLocale()); format.setMaximumFractionDigits(2); format.setMinimumFractionDigits(0); format.setGroupingUsed(true); diff --git a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmTileEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmTileEntity.java index 986115f01..d77eb4e69 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmTileEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmTileEntity.java @@ -498,7 +498,7 @@ public class ArmTileEntity extends KineticTileEntity { @Override protected Vec3d getLocalOffset(BlockState state) { int yPos = state.get(ArmBlock.CEILING) ? 16 - 3 : 3; - Vec3d location = VecHelper.voxelSpace(8, yPos, 14.5); + Vec3d location = VecHelper.voxelSpace(8, yPos, 15.95); location = VecHelper.rotateCentered(location, AngleHelper.horizontalAngle(getSide()), Direction.Axis.Y); return location; } diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/ArmScenes.java b/src/main/java/com/simibubi/create/foundation/ponder/content/ArmScenes.java new file mode 100644 index 000000000..527e31151 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/ArmScenes.java @@ -0,0 +1,611 @@ +package com.simibubi.create.foundation.ponder.content; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllItems; +import com.simibubi.create.AllShapes; +import com.simibubi.create.content.contraptions.components.crafter.MechanicalCrafterTileEntity; +import com.simibubi.create.content.logistics.block.funnel.FunnelTileEntity; +import com.simibubi.create.content.logistics.block.mechanicalArm.ArmTileEntity.Phase; +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 net.minecraft.block.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +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 ArmScenes { + + public static void setup(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("mechanical_arm", "Setting up Mechanical Arms"); + scene.configureBasePlate(0, 0, 5); + scene.showBasePlate(); + + ItemStack armItem = AllBlocks.MECHANICAL_ARM.asStack(); + BlockPos armPos = util.grid.at(2, 1, 2); + Selection armSel = util.select.position(armPos); + BlockPos inputDepot = util.grid.at(4, 2, 1); + Vec3d depotSurface = util.vector.blockSurface(inputDepot, Direction.NORTH); + Vec3d armSurface = util.vector.blockSurface(armPos, Direction.WEST); + + scene.idle(20); + + scene.world.setKineticSpeed(armSel, 0); + scene.world.showSection(armSel, Direction.DOWN); + scene.idle(10); + scene.effects.indicateRedstone(armPos); + scene.overlay.showSelectionWithText(armSel, 70) + .attachKeyFrame() + .colored(PonderPalette.RED) + .text("Mechanical Arms have to be assigned their in- and outputs before they are placed") + .pointAt(armSurface) + .placeNearTarget(); + scene.idle(80); + scene.world.showSection(util.select.fromTo(4, 1, 1, 4, 2, 1), Direction.DOWN); + scene.world.showSection(util.select.fromTo(0, 1, 1, 0, 2, 1), Direction.DOWN); + scene.world.hideSection(armSel, Direction.UP); + scene.idle(20); + scene.overlay.showControls(new InputWindowElement(depotSurface, Pointing.RIGHT).rightClick() + .withItem(armItem), 50); + scene.idle(7); + AxisAlignedBB depotBounds = AllShapes.DEPOT.getBoundingBox(); + scene.overlay.chaseBoundingBoxOutline(PonderPalette.INPUT, new Object(), depotBounds.offset(4, 2, 1), 400); + + scene.overlay.showText(70) + .attachKeyFrame() + .colored(PonderPalette.INPUT) + .text("Right-Click inventories while holding the Arm to assign them as Targets") + .pointAt(util.vector.blockSurface(inputDepot, Direction.WEST)) + .placeNearTarget(); + scene.idle(80); + + BlockPos outputDepot = util.grid.at(0, 2, 1); + InputWindowElement input = + new InputWindowElement(util.vector.blockSurface(outputDepot, Direction.NORTH), Pointing.RIGHT).rightClick() + .withItem(armItem); + scene.overlay.showControls(input, 20); + scene.idle(7); + Object second = new Object(); + scene.overlay.chaseBoundingBoxOutline(PonderPalette.INPUT, second, depotBounds.offset(0, 2, 1), 100); + scene.idle(25); + scene.overlay.showControls(input, 30); + scene.idle(7); + scene.overlay.chaseBoundingBoxOutline(PonderPalette.OUTPUT, second, depotBounds.offset(0, 2, 1), 280); + scene.overlay.showText(70) + .colored(PonderPalette.OUTPUT) + .text("Right-Click again to toggle between Input (Blue) and Output (Orange)") + .pointAt(util.vector.blockSurface(outputDepot, Direction.WEST)) + .placeNearTarget(); + + scene.idle(80); + scene.world.showSection(util.select.position(1, 1, 0), Direction.DOWN); + scene.idle(15); + scene.overlay.chaseBoundingBoxOutline(PonderPalette.INPUT, new Object(), depotBounds.offset(1, 1, 0), 43); + + scene.overlay.showText(50) + .colored(PonderPalette.WHITE) + .text("Left-Click components to remove their Selection") + .pointAt(util.vector.blockSurface(util.grid.at(1, 1, 0), Direction.WEST)) + .placeNearTarget(); + + scene.idle(35); + scene.overlay + .showControls(new InputWindowElement(util.vector.topOf(util.grid.at(1, 1, 0)), Pointing.DOWN).leftClick() + .withItem(armItem), 30); + scene.idle(50); + + scene.world.showSection(armSel, Direction.DOWN); + scene.idle(10); + Vec3d armTop = armSurface.add(0.5, 1.5, 0); + scene.overlay.showText(70) + .attachKeyFrame() + .colored(PonderPalette.GREEN) + .text("Once placed, the Mechanical Arm will target the blocks selected previously") + .pointAt(armTop) + .placeNearTarget(); + scene.idle(80); + + scene.effects.indicateSuccess(armPos); + scene.world.showSection(util.select.fromTo(2, 1, 5, 2, 1, 3) + .add(util.select.position(2, 0, 5)), Direction.DOWN); + ItemStack copper = AllItems.COPPER_INGOT.asStack(); + scene.world.createItemOnBeltLike(inputDepot, Direction.SOUTH, copper); + scene.idle(10); + + scene.world.setKineticSpeed(armSel, -48); + scene.idle(20); + scene.world.instructArm(armPos, Phase.MOVE_TO_INPUT, ItemStack.EMPTY, 0); + scene.idle(24); + scene.world.removeItemsFromBelt(inputDepot); + scene.world.instructArm(armPos, Phase.SEARCH_OUTPUTS, copper, -1); + scene.idle(20); + scene.world.instructArm(armPos, Phase.MOVE_TO_OUTPUT, copper, 0); + scene.idle(24); + scene.world.createItemOnBeltLike(outputDepot, Direction.UP, copper); + scene.world.instructArm(armPos, Phase.SEARCH_INPUTS, ItemStack.EMPTY, -1); + scene.idle(44); + + scene.world.showSection(util.select.fromTo(1, 1, 4, 1, 3, 4), Direction.DOWN); + scene.idle(5); + scene.world.showSection(util.select.position(4, 1, 2), Direction.DOWN); + scene.idle(5); + + scene.overlay.chaseBoundingBoxOutline(PonderPalette.OUTPUT, new Object(), depotBounds.offset(0, 2, 1), 60); + scene.idle(5); + scene.overlay.chaseBoundingBoxOutline(PonderPalette.INPUT, new Object(), depotBounds.offset(4, 2, 1), 60); + scene.idle(5); + scene.overlay.chaseBoundingBoxOutline(PonderPalette.OUTPUT, new Object(), depotBounds.offset(1, 1, 0), 60); + scene.idle(5); + scene.overlay.chaseBoundingBoxOutline(PonderPalette.INPUT, new Object(), depotBounds.offset(1, 3, 4), 60); + scene.idle(5); + scene.overlay.chaseBoundingBoxOutline(PonderPalette.INPUT, new Object(), depotBounds.offset(4, 1, 2), 60); + scene.idle(5); + + scene.overlay.showText(80) + .attachKeyFrame() + .text("They can have any amount of in- and outputs within their range") + .pointAt(util.vector.blockSurface(util.grid.at(1, 3, 4), Direction.WEST)) + .placeNearTarget(); + + inputDepot = util.grid.at(1, 3, 4); + outputDepot = util.grid.at(1, 1, 0); + copper = AllBlocks.COPPER_BLOCK.asStack(); + scene.world.createItemOnBeltLike(inputDepot, Direction.SOUTH, copper); + scene.idle(20); + scene.world.instructArm(armPos, Phase.MOVE_TO_INPUT, ItemStack.EMPTY, 2); + scene.idle(24); + scene.world.removeItemsFromBelt(inputDepot); + scene.world.instructArm(armPos, Phase.SEARCH_OUTPUTS, copper, -1); + scene.idle(20); + scene.world.instructArm(armPos, Phase.MOVE_TO_OUTPUT, copper, 2); + scene.idle(24); + scene.world.createItemOnBeltLike(outputDepot, Direction.UP, copper); + scene.world.instructArm(armPos, Phase.SEARCH_INPUTS, ItemStack.EMPTY, -1); + + scene.world.hideSection(util.select.fromTo(4, 2, 1, 4, 1, 1), Direction.UP); + scene.idle(2); + scene.world.hideSection(util.select.fromTo(1, 1, 4, 1, 3, 4), Direction.UP); + scene.idle(5); + scene.world.hideSection(util.select.fromTo(0, 1, 1, 0, 2, 1), Direction.UP); + scene.idle(2); + scene.world.hideSection(util.select.position(1, 1, 0), Direction.UP); + scene.idle(5); + scene.world.hideSection(util.select.position(4, 1, 2), Direction.UP); + scene.idle(15); + + scene.world.showSection(util.select.fromTo(4, 1, 3, 4, 2, 3), Direction.NORTH); + scene.idle(5); + scene.world.showSection(util.select.fromTo(0, 1, 3, 0, 2, 3), Direction.NORTH); + scene.idle(15); + + Object in = new Object(); + Object out = new Object(); + AxisAlignedBB chestBounds = new AxisAlignedBB(1 / 16f, 0, 1 / 16f, 15 / 16f, 14 / 16f, 15 / 16f); + AxisAlignedBB funnelBounds = new AxisAlignedBB(0, 0, 8 / 16f, 16 / 16f, 16 / 16f, 16 / 16f); + + scene.overlay.chaseBoundingBoxOutline(PonderPalette.RED, in, chestBounds.offset(4, 2, 3), 120); + scene.overlay.chaseBoundingBoxOutline(PonderPalette.RED, out, chestBounds.offset(0, 2, 3), 120); + scene.overlay.showText(80) + .attachKeyFrame() + .text("However, not every type of Inventory can be interacted with directly") + .colored(PonderPalette.RED) + .placeNearTarget() + .pointAt(util.vector.blockSurface(util.grid.at(0, 2, 3), Direction.WEST)); + scene.idle(90); + + scene.world.showSection(util.select.fromTo(4, 1, 2, 4, 2, 2), Direction.SOUTH); + scene.idle(5); + scene.world.showSection(util.select.position(0, 2, 2), Direction.SOUTH); + scene.idle(10); + + scene.overlay.chaseBoundingBoxOutline(PonderPalette.INPUT, in, depotBounds.offset(4, 1, 2), 80); + scene.idle(5); + scene.overlay.chaseBoundingBoxOutline(PonderPalette.OUTPUT, out, funnelBounds.offset(0, 2, 2), 80); + scene.idle(5); + + scene.overlay.showText(60) + .text("Funnels and Depots can help to Bridge that gap") + .colored(PonderPalette.OUTPUT) + .placeNearTarget() + .pointAt(util.vector.topOf(util.grid.at(0, 2, 2)) + .add(0, 0, 0.25)); + scene.idle(70); + ItemStack sword = new ItemStack(Items.GOLDEN_SWORD); + inputDepot = util.grid.at(4, 1, 2); + scene.overlay + .showControls(new InputWindowElement(util.vector.topOf(inputDepot), Pointing.RIGHT).withItem(sword), 30); + scene.world.createItemOnBeltLike(inputDepot, Direction.SOUTH, sword); + + scene.idle(20); + scene.world.instructArm(armPos, Phase.MOVE_TO_INPUT, ItemStack.EMPTY, 1); + scene.idle(24); + scene.world.removeItemsFromBelt(inputDepot); + scene.world.instructArm(armPos, Phase.SEARCH_OUTPUTS, sword, -1); + scene.idle(20); + scene.world.instructArm(armPos, Phase.MOVE_TO_OUTPUT, sword, 1); + scene.idle(24); + scene.world.flapFunnel(util.grid.at(0, 2, 2), false); + scene.world.instructArm(armPos, Phase.SEARCH_INPUTS, ItemStack.EMPTY, -1); + scene.idle(5); + scene.overlay.showControls( + new InputWindowElement(util.vector.blockSurface(util.grid.at(0, 2, 3), Direction.WEST), Pointing.LEFT) + .withItem(sword), + 30); + + } + + public static void filtering(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("mechanical_arm_filtering", "Filtering Outputs of the Mechanical Arm"); + scene.configureBasePlate(0, 0, 6); + scene.scaleSceneView(0.9f); + scene.world.setKineticSpeed(util.select.fromTo(4, 1, 4, 6, 0, 5), 0); + scene.world.showSection(util.select.layer(0), Direction.UP); + scene.idle(10); + scene.world.showSection(util.select.fromTo(4, 1, 4, 5, 1, 5), Direction.DOWN); + scene.idle(10); + + for (int x = 0; x < 2; x++) { + scene.idle(3); + scene.world.showSection(util.select.position(x + 1, 1, 4), Direction.DOWN); + } + + for (int y = 0; y < 3; y++) { + for (int x = 0; x < 3; x++) { + scene.world.showSection(util.select.position(y == 1 ? x + 3 : 5 - x, y + 1, 1), Direction.DOWN); + scene.idle(2); + } + } + scene.world.showSection(util.select.position(2, 1, 1), Direction.EAST); + + ItemStack sand = new ItemStack(Items.SAND, 64); + ItemStack sulphur = new ItemStack(Items.GUNPOWDER, 64); + scene.world.createItemOnBeltLike(util.grid.at(2, 1, 4), Direction.SOUTH, sand); + scene.world.createItemOnBeltLike(util.grid.at(1, 1, 4), Direction.SOUTH, sulphur); + + scene.overlay.showSelectionWithText(util.select.fromTo(2, 1, 4, 1, 1, 4), 60) + .text("Inputs") + .placeNearTarget() + .colored(PonderPalette.INPUT); + scene.idle(50); + scene.overlay.showSelectionWithText(util.select.fromTo(5, 3, 1, 3, 1, 1), 40) + .text("Outputs") + .placeNearTarget() + .colored(PonderPalette.OUTPUT); + scene.idle(50); + + scene.overlay.showText(80) + .attachKeyFrame() + .text("Sometimes it is desirable to restrict targets of the Arm by matching a filter") + .placeNearTarget() + .pointAt(util.vector.blockSurface(util.grid.at(3, 3, 1), Direction.WEST)); + + scene.idle(90); + scene.rotateCameraY(-90 - 30); + scene.idle(20); + + scene.overlay.showSelectionWithText(util.select.position(4, 1, 4), 80) + .colored(PonderPalette.RED) + .text("Mechanical Arms by themselves do not provide any options for filtering") + .placeNearTarget(); + scene.idle(90); + + for (int y = 0; y < 3; y++) { + scene.world.showSection(util.select.fromTo(5, y + 1, 2, 3, y + 1, 2), Direction.NORTH); + scene.idle(2); + } + + Vec3d filterSlot = util.vector.of(3.5, 3.75, 2.6); + scene.overlay.showFilterSlotInput(filterSlot, 80); + scene.idle(10); + scene.overlay.showText(80) + .attachKeyFrame() + .colored(PonderPalette.GREEN) + .pointAt(filterSlot) + .text("Brass Funnels as Targets do however communicate their own filter to the Arm") + .placeNearTarget(); + scene.idle(90); + + for (int y = 0; y < 3; y++) { + for (int x = 0; x < 3; x++) { + ItemStack item = (x + y) % 2 == 0 ? sulphur : sand; + scene.overlay + .showControls(new InputWindowElement(filterSlot.add(2 - x, -y, 0), Pointing.LEFT).rightClick() + .withItem(item), 5); + scene.idle(7); + scene.world.setFilterData(util.select.position(5 - x, 3 - y, 2), FunnelTileEntity.class, item); + scene.idle(4); + } + } + + scene.world.setKineticSpeed(util.select.fromTo(4, 1, 4, 6, 0, 5), 24); + scene.world.multiplyKineticSpeed(util.select.position(5, 1, 5), -1); + scene.world.multiplyKineticSpeed(util.select.position(4, 1, 4), 2); + scene.idle(10); + + BlockPos armPos = util.grid.at(4, 1, 4); + scene.world.instructArm(armPos, Phase.MOVE_TO_INPUT, ItemStack.EMPTY, 1); + scene.idle(24); + scene.world.instructArm(armPos, Phase.SEARCH_OUTPUTS, sand, -1); + scene.idle(20); + + scene.overlay.showText(80) + .attachKeyFrame() + .pointAt(util.vector.topOf(2, 1, 4)) + .text("The Arm is smart enough not to pick up items it couldn't distribute") + .placeNearTarget(); + scene.idle(90); + + for (int i = 0; i < 4; i++) { + int index = i * 2 + 1; + scene.world.instructArm(armPos, Phase.MOVE_TO_OUTPUT, sand, index); + scene.idle(24); + BlockPos funnelPos = util.grid.at(5 - index % 3, 1 + index / 3, 2); + scene.world.flapFunnel(funnelPos, false); + scene.world.instructArm(armPos, Phase.SEARCH_INPUTS, i == 3 ? ItemStack.EMPTY : sand, -1); + scene.world.modifyTileEntity(funnelPos.north(), MechanicalCrafterTileEntity.class, mct -> mct.getInventory() + .insertItem(0, sand.copy(), false)); + scene.idle(10); + } + + scene.world.instructArm(armPos, Phase.MOVE_TO_INPUT, ItemStack.EMPTY, 0); + scene.idle(24); + scene.world.instructArm(armPos, Phase.SEARCH_OUTPUTS, sulphur, -1); + scene.idle(20); + + scene.rotateCameraY(120); + scene.world.setCraftingResult(util.grid.at(3, 1, 1), new ItemStack(Blocks.TNT)); + + for (int i = 0; i < 5; i++) { + int index = i * 2; + scene.world.instructArm(armPos, Phase.MOVE_TO_OUTPUT, sulphur, index); + scene.idle(24); + BlockPos funnelPos = util.grid.at(3 + index % 3, 1 + index / 3, 2); + scene.world.flapFunnel(funnelPos, false); + scene.world.instructArm(armPos, Phase.SEARCH_INPUTS, i == 4 ? ItemStack.EMPTY : sulphur, -1); + scene.world.modifyTileEntity(funnelPos.north(), MechanicalCrafterTileEntity.class, mct -> mct.getInventory() + .insertItem(0, sulphur.copy(), false)); + scene.idle(10); + } + + scene.idle(120); + } + + public static void modes(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("mechanical_arm_modes", "Distribution modes of the Mechanical Arm"); + scene.configureBasePlate(0, 1, 5); + scene.world.setBlock(util.grid.at(3, 1, 0), Blocks.BARRIER.getDefaultState(), false); + + scene.world.showSection(util.select.layer(0), Direction.UP); + scene.idle(5); + scene.world.showSection(util.select.fromTo(3, 1, 4, 4, 1, 5), Direction.DOWN); + scene.idle(5); + scene.world.showSection(util.select.fromTo(1, 1, 4, 1, 2, 5), Direction.NORTH); + scene.idle(5); + scene.world.showSection(util.select.fromTo(1, 1, 1, 5, 1, 2), Direction.SOUTH); + scene.idle(10); + + AxisAlignedBB depotBox = AllShapes.DEPOT.getBoundingBox(); + AxisAlignedBB beltBox = depotBox.contract(0, -3 / 16f, 0) + .grow(1, 0, 0); + BlockPos depotPos = util.grid.at(1, 1, 4); + BlockPos armPos = util.grid.at(3, 1, 4); + + scene.overlay.chaseBoundingBoxOutline(PonderPalette.INPUT, depotBox, depotBox.offset(1, 1, 4), 60); + scene.overlay.showText(30) + .text("Input") + .pointAt(util.vector.blockSurface(depotPos, Direction.WEST)) + .placeNearTarget() + .colored(PonderPalette.INPUT); + scene.idle(40); + scene.overlay.chaseBoundingBoxOutline(PonderPalette.OUTPUT, depotBox, beltBox.offset(2, 1, 2), 40); + scene.overlay.showText(40) + .text("Outputs") + .pointAt(util.vector.blockSurface(util.grid.at(1, 1, 2), Direction.WEST)) + .placeNearTarget() + .colored(PonderPalette.OUTPUT); + scene.idle(50); + + ItemStack item = new ItemStack(Items.SNOWBALL); + + scene.world.createItemOnBeltLike(depotPos, Direction.SOUTH, item); + scene.overlay.showText(60) + .attachKeyFrame() + .text("Whenever an Arm has to choose between multiple valid outputs...") + .pointAt(util.vector.blockSurface(util.grid.at(2, 1, 2), Direction.UP)) + .placeNearTarget() + .colored(PonderPalette.OUTPUT); + scene.idle(70); + + Vec3d scrollSlot = util.vector.of(3.5, 1.25, 4); + scene.overlay.showFilterSlotInput(scrollSlot, 120); + scene.overlay.showText(50) + .text("...it will act according to its setting") + .pointAt(scrollSlot) + .placeNearTarget(); + scene.idle(60); + + scene.overlay.showControls(new InputWindowElement(scrollSlot, Pointing.RIGHT).scroll() + .withWrench(), 40); + scene.idle(10); + scene.overlay.showText(50) + .text("Scrolling with a Wrench will allow you to configure it") + .pointAt(scrollSlot) + .placeNearTarget(); + scene.idle(60); + + ElementLink blockage = + scene.world.showIndependentSection(util.select.position(4, 1, 0), Direction.UP); + scene.world.moveSection(blockage, util.vector.of(-1, 0, 0), 0); + + for (int i = 0; i < 20; i++) { + + if (i == 2) { + scene.overlay.showText(60) + .attachKeyFrame() + .text("Round Robin mode simply cycles through all outputs that are available") + .pointAt(util.vector.blockSurface(util.grid.at(2, 1, 2), Direction.UP)) + .placeNearTarget() + .colored(PonderPalette.OUTPUT); + } + if (i == 6) + continue; + if (i == 7) { + scene.overlay.showText(60) + .attachKeyFrame() + .text("If an output is unable to take more items, it will be skipped") + .pointAt(util.vector.blockSurface(util.grid.at(3, 1, 2), Direction.UP)) + .placeNearTarget() + .colored(PonderPalette.GREEN); + } + + if (i == 12) { + scene.world.moveSection(blockage, util.vector.of(-1, 0, 0), 10); + scene.world.setBlock(util.grid.at(3, 1, 0), Blocks.BARRIER.getDefaultState(), false); + } + + int index = i % 3; + + if (i == 13) { + scene.world.setBlock(util.grid.at(2, 1, 0), Blocks.BARRIER.getDefaultState(), false); + ElementLink blockage2 = + scene.world.showIndependentSection(util.select.position(4, 1, 0), Direction.UP); + scene.world.moveSection(blockage2, util.vector.of(-2, 0, 0), 0); + scene.overlay.showText(60) + .attachKeyFrame() + .text("Prefer First prioritizes the outputs selected earliest when configuring this Arm") + .pointAt(util.vector.blockSurface(util.grid.at(3, 1, 2), Direction.UP)) + .placeNearTarget() + .colored(PonderPalette.GREEN); + index = 0; + } + + if (i == 14) + index = 1; + if (i == 15) + index = 1; + if (i >= 16) + index = 2; + + scene.idle(5); + scene.world.instructArm(armPos, Phase.MOVE_TO_INPUT, ItemStack.EMPTY, 0); + scene.idle(12); + scene.world.instructArm(armPos, Phase.SEARCH_OUTPUTS, item, -1); + scene.world.removeItemsFromBelt(depotPos); + scene.idle(5); + + if (i == 9) { + scene.overlay.showText(80) + .attachKeyFrame() + .text("Forced Round Robin mode will never skip outputs, and instead wait until they are free") + .pointAt(util.vector.blockSurface(util.grid.at(3, 1, 2), Direction.UP)) + .placeNearTarget() + .colored(PonderPalette.RED); + scene.idle(40); + scene.world.moveSection(blockage, util.vector.of(1, 0, 0), 10); + scene.world.setBlock(util.grid.at(3, 1, 0), Blocks.AIR.getDefaultState(), false); + scene.idle(50); + scene.world.multiplyKineticSpeed(util.select.fromTo(1, 1, 1, 5, 0, 3), 2); + } + + scene.world.instructArm(armPos, Phase.MOVE_TO_OUTPUT, item, index); + scene.world.createItemOnBeltLike(depotPos, Direction.SOUTH, item); + scene.idle(12); + scene.world.instructArm(armPos, Phase.SEARCH_INPUTS, ItemStack.EMPTY, -1); + scene.world.createItemOnBelt(util.grid.at(3 - index, 1, 2), Direction.UP, item); + } + + } + + public static void redstone(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("mechanical_arm_redstone", "Controlling Mechanical Arms with Redstone"); + scene.configureBasePlate(0, 0, 5); + scene.world.showSection(util.select.layer(0), Direction.UP); + scene.idle(5); + scene.world.showSection(util.select.fromTo(1, 1, 3, 2, 1, 4), Direction.DOWN); + scene.idle(5); + scene.world.showSection(util.select.fromTo(3, 1, 5, 4, 1, 3), Direction.WEST); + scene.idle(5); + scene.world.showSection(util.select.position(4, 1, 2), Direction.SOUTH); + scene.idle(5); + scene.world.showSection(util.select.fromTo(2, 1, 1, 4, 1, 1), Direction.EAST); + scene.idle(10); + Selection redstone = util.select.fromTo(1, 1, 0, 1, 1, 2); + scene.world.showSection(redstone, Direction.SOUTH); + + BlockPos armPos = util.grid.at(1, 1, 3); + BlockPos leverPos = util.grid.at(1, 1, 0); + ItemStack item = new ItemStack(Items.REDSTONE_ORE); + + scene.world.createItemOnBeltLike(util.grid.at(4, 1, 1), Direction.SOUTH, item); + + for (int i = 0; i < 3; i++) { + scene.idle(12); + + if (i == 1) { + scene.world.toggleRedstonePower(redstone); + scene.effects.indicateRedstone(leverPos); + scene.idle(10); + + scene.overlay.showText(60) + .colored(PonderPalette.RED) + .attachKeyFrame() + .pointAt(util.vector.topOf(armPos.up())) + .placeNearTarget() + .text("When powered by Redstone, Mechanical Arms will not activate"); + scene.idle(70); + scene.world.toggleRedstonePower(redstone); + } + + if (i == 2) { + scene.idle(60); + scene.world.toggleRedstonePower(redstone); + scene.idle(3); + scene.world.toggleRedstonePower(redstone); + scene.effects.indicateRedstone(leverPos); + } + + scene.world.instructArm(armPos, Phase.MOVE_TO_INPUT, ItemStack.EMPTY, 0); + scene.idle(18); + scene.world.instructArm(armPos, Phase.SEARCH_OUTPUTS, item, -1); + scene.world.removeItemsFromBelt(util.grid.at(3, 1, 1)); + scene.idle(5); + + if (i == 1) { + scene.world.toggleRedstonePower(redstone); + scene.effects.indicateRedstone(leverPos); + scene.overlay.showText(60) + .pointAt(util.vector.topOf(armPos.up())) + .placeNearTarget() + .text("Before stopping, it will finish any started cycles"); + } + + scene.idle(10); + + if (i == 2) { + scene.overlay.showText(100) + .colored(PonderPalette.GREEN) + .attachKeyFrame() + .pointAt(util.vector.topOf(armPos.up())) + .placeNearTarget() + .text("Thus, a negative pulse can be used to trigger exactly one activation cycle"); + } + + scene.world.instructArm(armPos, Phase.MOVE_TO_OUTPUT, item, 0); + scene.world.createItemOnBeltLike(util.grid.at(4, 1, 1), Direction.SOUTH, item); + scene.idle(18); + scene.world.instructArm(armPos, Phase.SEARCH_INPUTS, ItemStack.EMPTY, -1); + scene.world.createItemOnBelt(util.grid.at(3, 1, 3), Direction.UP, item); + } + + scene.idle(5); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/BearingScenes.java b/src/main/java/com/simibubi/create/foundation/ponder/content/BearingScenes.java index eca104623..646844ba6 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/content/BearingScenes.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/BearingScenes.java @@ -618,7 +618,7 @@ public class BearingScenes { .placeNearTarget(); scene.idle(40); scene.world.configureCenterOfRotation(plank, util.vector.centerOf(bearingPos)); - + if (!frame) { scene.world.rotateBearing(bearingPos, 180, 75); scene.world.rotateSection(plank, 0, 180, 0, 75); @@ -633,11 +633,11 @@ public class BearingScenes { scene.overlay.showControls(input, 30); scene.idle(7); scene.world.setBlock(util.grid.at(2, 3, 1), AllBlocks.DYED_SAILS[DyeColor.BLUE.ordinal()].getDefaultState() - .with(SailBlock.FACING, Direction.WEST), true); + .with(SailBlock.FACING, Direction.WEST), false); scene.idle(10); scene.overlay.showText(40) .colored(PonderPalette.BLUE) - .text("Right Click with Dye to paint them") + .text("Right-Click with Dye to paint them") .attachKeyFrame() .pointAt(util.vector.blockSurface(util.grid.at(2, 3, 1), Direction.WEST)) .placeNearTarget(); @@ -647,7 +647,32 @@ public class BearingScenes { scene.world.replaceBlocks(util.select.fromTo(2, 2, 1, 2, 4, 1), AllBlocks.DYED_SAILS[DyeColor.BLUE.ordinal()].getDefaultState() .with(SailBlock.FACING, Direction.WEST), - true); + false); + + scene.idle(20); + scene.world.rotateBearing(bearingPos, 90, 33); + scene.world.rotateSection(plank, 0, 90, 0, 33); + scene.idle(40); + + input = + new InputWindowElement(util.vector.blockSurface(util.grid.at(2, 3, 1), Direction.NORTH), Pointing.RIGHT) + .withItem(new ItemStack(Items.SHEARS)); + + scene.overlay.showControls(input, 30); + scene.idle(7); + scene.world.setBlock(util.grid.at(3, 3, 2), AllBlocks.SAIL_FRAME.getDefaultState() + .with(SailBlock.FACING, Direction.NORTH), false); + scene.idle(10); + scene.overlay.showText(40) + .text("Right-Click with Shears to turn them back into frames") + .attachKeyFrame() + .pointAt(util.vector.blockSurface(util.grid.at(2, 3, 1), Direction.WEST)) + .placeNearTarget(); + scene.idle(20); + scene.overlay.showControls(input, 30); + scene.idle(7); + scene.world.replaceBlocks(util.select.fromTo(3, 2, 2, 3, 4, 2), AllBlocks.SAIL_FRAME.getDefaultState() + .with(SailBlock.FACING, Direction.NORTH), false); scene.idle(20); } 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 index 32c8a6445..9eaf3c289 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/content/PonderIndex.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderIndex.java @@ -132,6 +132,13 @@ public class PonderIndex { PonderRegistry.forComponents(AllBlocks.STICKER) .addStoryBoard("sticker", RedstoneScenes::sticker, PonderTag.CONTRAPTION_ASSEMBLY); + // Mechanical Arm + PonderRegistry.forComponents(AllBlocks.MECHANICAL_ARM) + .addStoryBoard("mechanical_arm/setup", ArmScenes::setup, PonderTag.ARM_TARGETS) + .addStoryBoard("mechanical_arm/filter", ArmScenes::filtering) + .addStoryBoard("mechanical_arm/modes", ArmScenes::modes) + .addStoryBoard("mechanical_arm/redstone", ArmScenes::redstone); + // Mechanical Piston PonderRegistry.forComponents(AllBlocks.MECHANICAL_PISTON, AllBlocks.STICKY_MECHANICAL_PISTON) .addStoryBoard("mechanical_piston/anchor", PistonScenes::movement, PonderTag.KINETIC_APPLIANCES, @@ -296,6 +303,7 @@ public class PonderIndex { .add(AllBlocks.CREATIVE_FLUID_TANK); PonderRegistry.tags.forTag(PonderTag.ARM_TARGETS) + .add(AllBlocks.MECHANICAL_ARM) .add(AllItems.BELT_CONNECTOR) .add(AllBlocks.CHUTE) .add(AllBlocks.DEPOT) 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 index ede4108ed..5e5fbae39 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/content/PonderPalette.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderPalette.java @@ -13,6 +13,9 @@ public enum PonderPalette { MEDIUM(0xFF_0084ff), FAST(0xFF_ff55ff), + INPUT(0xFF_4f8a8b), + OUTPUT(0xFF_ffcb74), + ; private int 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 index 6eca976b0..a6e0b045c 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/content/PonderTag.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderTag.java @@ -61,7 +61,7 @@ public class PonderTag implements IScreenRenderable { SAILS = new PonderTag("windmill_sails").item(AllBlocks.WINDMILL_BEARING.get(), true, true) .defaultLang("Sails for Windmill Bearings", - "Blocks that count towards the strength of a Windmill Contraption when assembled"), + "Blocks that count towards the strength of a Windmill Contraption when assembled. Each of these have equal efficiency in doing so."), // FLUID_TRANSFER = new PonderTag("fluid_transfer").idAsIcon(), // 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 index f14cb3394..6be9b2be7 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/content/PonderTagScreen.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderTagScreen.java @@ -61,6 +61,12 @@ public class PonderTagScreen extends NavigatableSimiScreen { items.clear(); PonderRegistry.tags.getItems(tag) .stream() + .filter(rl -> tag.getMainItem() + .isEmpty() + || tag.getMainItem() + .getItem() + .getRegistryName() + .equals(rl)) .map(key -> { Item item = ForgeRegistries.ITEMS.getValue(key); if (item == null) { diff --git a/src/main/resources/assets/create/models/block/mechanical_arm/block.json b/src/main/resources/assets/create/models/block/mechanical_arm/block.json index f815bab53..0031d075b 100644 --- a/src/main/resources/assets/create/models/block/mechanical_arm/block.json +++ b/src/main/resources/assets/create/models/block/mechanical_arm/block.json @@ -2,6 +2,7 @@ "credit": "Made with Blockbench", "parent": "block/block", "textures": { + "2": "create:block/brass_casing_belt", "6": "create:block/crafter_top", "7": "create:block/brass_block", "particle": "create:block/crafter_top" @@ -9,15 +10,15 @@ "elements": [ { "name": "Base", - "from": [2, 0, 2], - "to": [14, 6, 14], + "from": [0, 0, 0], + "to": [16, 6, 16], "faces": { - "north": {"uv": [2, 0, 14, 6], "texture": "#6"}, - "east": {"uv": [2, 0, 14, 6], "texture": "#6"}, - "south": {"uv": [2, 0, 14, 6], "texture": "#6"}, - "west": {"uv": [2, 0, 14, 6], "texture": "#6"}, - "up": {"uv": [2, 2, 14, 14], "texture": "#7"}, - "down": {"uv": [2, 2, 14, 14], "texture": "#6"} + "north": {"uv": [8, 12.5, 16, 15.5], "texture": "#2"}, + "east": {"uv": [8, 12.5, 16, 15.5], "texture": "#2"}, + "south": {"uv": [8, 12.5, 16, 15.5], "texture": "#2"}, + "west": {"uv": [8, 12.5, 16, 15.5], "texture": "#2"}, + "up": {"uv": [0, 0, 16, 16], "texture": "#7"}, + "down": {"uv": [0, 0, 16, 16], "texture": "#6"} } } ], diff --git a/src/main/resources/assets/create/models/block/mechanical_arm/item.json b/src/main/resources/assets/create/models/block/mechanical_arm/item.json index 8df140ad6..d02438478 100644 --- a/src/main/resources/assets/create/models/block/mechanical_arm/item.json +++ b/src/main/resources/assets/create/models/block/mechanical_arm/item.json @@ -2,6 +2,7 @@ "credit": "Made with Blockbench", "parent": "block/block", "textures": { + "3": "create:block/brass_casing_belt", "5": "create:block/mechanical_arm", "6": "create:block/crafter_top", "7": "create:block/brass_block", @@ -52,9 +53,9 @@ }, { "name": "ConnectorR", - "from": [5, 12, 0], - "to": [7, 14, 6], - "rotation": {"angle": 45, "axis": "x", "origin": [8, -4, 5]}, + "from": [5, 7.02944, 12], + "to": [7, 9.02944, 18], + "rotation": {"angle": 22.5, "axis": "x", "origin": [8, 8, 17]}, "faces": { "east": {"uv": [15, 0, 16, 3], "rotation": 90, "texture": "#5"}, "south": {"uv": [15, 0, 16, 1], "rotation": 90, "texture": "#5"}, @@ -65,9 +66,9 @@ }, { "name": "ConnectorR", - "from": [9, 12, 0], - "to": [11, 14, 6], - "rotation": {"angle": 45, "axis": "x", "origin": [12, -4, 5]}, + "from": [9, 7.02944, 12], + "to": [11, 9.02944, 18], + "rotation": {"angle": 22.5, "axis": "x", "origin": [8, 8, 17]}, "faces": { "east": {"uv": [15, 0, 16, 3], "rotation": 90, "texture": "#5"}, "south": {"uv": [15, 0, 16, 1], "rotation": 90, "texture": "#5"}, @@ -78,9 +79,9 @@ }, { "name": "UpperBody", - "from": [4.5, 11, -10], - "to": [11.5, 15, 1], - "rotation": {"angle": 45, "axis": "x", "origin": [8, -4, 5]}, + "from": [4.5, 6.02944, 2], + "to": [11.5, 10.02944, 13], + "rotation": {"angle": 22.5, "axis": "x", "origin": [8, 8, 17]}, "faces": { "north": {"uv": [11, 9, 14.5, 11], "texture": "#5"}, "east": {"uv": [14, 3.5, 16, 9], "rotation": 270, "texture": "#5"}, @@ -92,9 +93,9 @@ }, { "name": "Head", - "from": [4, 16.5, 4], - "to": [12, 20.5, 8], - "rotation": {"angle": 0, "axis": "y", "origin": [8, 2, 8]}, + "from": [4, 11.59915, 0.63821], + "to": [12, 15.59915, 4.63821], + "rotation": {"angle": -22.5, "axis": "x", "origin": [8, 14, 3]}, "faces": { "north": {"uv": [7, 9.5, 9, 13.5], "rotation": 90, "texture": "#5"}, "east": {"uv": [7, 13.5, 9, 15.5], "texture": "#5"}, @@ -106,23 +107,23 @@ }, { "name": "Base", - "from": [2, -16, 2], - "to": [14, -10, 14], + "from": [0, -16, 0], + "to": [16, -10, 16], "rotation": {"angle": 0, "axis": "y", "origin": [8, -8, 8]}, "faces": { - "north": {"uv": [2, 0, 14, 6], "texture": "#6"}, - "east": {"uv": [2, 0, 14, 6], "texture": "#6"}, - "south": {"uv": [2, 0, 14, 6], "texture": "#6"}, - "west": {"uv": [2, 0, 14, 6], "texture": "#6"}, - "up": {"uv": [2, 2, 14, 14], "texture": "#7"}, - "down": {"uv": [2, 2, 14, 14], "texture": "#6"} + "north": {"uv": [8, 12.5, 16, 15.5], "texture": "#3"}, + "east": {"uv": [8, 12.5, 16, 15.5], "texture": "#3"}, + "south": {"uv": [8, 12.5, 16, 15.5], "texture": "#3"}, + "west": {"uv": [8, 12.5, 16, 15.5], "texture": "#3"}, + "up": {"uv": [0, 0, 16, 16], "texture": "#7"}, + "down": {"uv": [0, 0, 16, 16], "texture": "#6"} } }, { "name": "ClawBase", - "from": [5, 15.5, 1], - "to": [11, 21.5, 3], - "rotation": {"angle": 0, "axis": "y", "origin": [8, 2, 8]}, + "from": [5, 10.59915, -2.36179], + "to": [11, 16.59915, -0.36179], + "rotation": {"angle": -22.5, "axis": "x", "origin": [8, 14, 3]}, "faces": { "north": {"uv": [12, 0, 15, 3], "texture": "#5"}, "east": {"uv": [12, 0, 13, 3], "texture": "#5"}, @@ -134,23 +135,23 @@ }, { "name": "ClawTop", - "from": [5.5, 20.5, -3], - "to": [10.5, 22.5, 2], - "rotation": {"angle": -22.5, "axis": "x", "origin": [8, 21.5, 2]}, + "from": [5.5, 5.96489, -2.07049], + "to": [10.5, 10.96489, -0.07049], + "rotation": {"angle": 45, "axis": "x", "origin": [8, 14, 3]}, "faces": { - "north": {"uv": [9.5, 1.5, 12, 2.5], "rotation": 180, "texture": "#5"}, - "east": {"uv": [9.5, 0, 12, 1], "rotation": 180, "texture": "#5"}, - "south": {"uv": [9.5, 0, 12, 1], "rotation": 180, "texture": "#5"}, - "west": {"uv": [9.5, 0, 12, 1], "rotation": 180, "texture": "#5"}, - "up": {"uv": [9.5, 0, 12, 2.5], "rotation": 180, "texture": "#5"}, - "down": {"uv": [9.5, 0, 12, 2.5], "rotation": 180, "texture": "#5"} + "north": {"uv": [9.5, 0, 12, 2.5], "texture": "#5"}, + "east": {"uv": [9.5, 0, 12, 1], "rotation": 270, "texture": "#5"}, + "south": {"uv": [9.5, 0, 12, 2.5], "rotation": 180, "texture": "#5"}, + "west": {"uv": [9.5, 0, 12, 1], "rotation": 90, "texture": "#5"}, + "up": {"uv": [9.5, 0, 12, 1], "rotation": 180, "texture": "#5"}, + "down": {"uv": [9.5, 1.5, 12, 2.5], "texture": "#5"} } }, { "name": "ClawBottom", - "from": [5.5, 14.5, -3], - "to": [10.5, 16.5, 2], - "rotation": {"angle": 22.5, "axis": "x", "origin": [8, 15.5, 2]}, + "from": [5.5, 8.18885, -4.72832], + "to": [10.5, 10.18885, 0.27168], + "rotation": {"angle": 0, "axis": "x", "origin": [8, 14, 3]}, "faces": { "north": {"uv": [9.5, 0, 12, 1], "rotation": 180, "texture": "#5"}, "east": {"uv": [9.5, 1.5, 12, 2.5], "rotation": 180, "texture": "#5"}, @@ -162,9 +163,9 @@ }, { "name": "ClawConnector", - "from": [6.5, 17.5, 3], - "to": [9.5, 19.5, 4], - "rotation": {"angle": 0, "axis": "y", "origin": [8, 2, 8]}, + "from": [6.5, 12.59915, -0.36179], + "to": [9.5, 14.59915, 0.63821], + "rotation": {"angle": -22.5, "axis": "x", "origin": [8, 14, 3]}, "faces": { "east": {"uv": [10.5, 2.5, 11, 3.5], "texture": "#5"}, "west": {"uv": [11.5, 2.5, 12, 3.5], "texture": "#5"}, @@ -282,8 +283,8 @@ "scale": [0.25, 0.25, 0.25] }, "gui": { - "rotation": [30, 225, 0], - "translation": [0, 3, 0], + "rotation": [30, 135, 0], + "translation": [0, 4.25, 0], "scale": [0.45, 0.45, 0.45] }, "head": { diff --git a/src/main/resources/ponder/mechanical_arm/filter.nbt b/src/main/resources/ponder/mechanical_arm/filter.nbt new file mode 100644 index 0000000000000000000000000000000000000000..f7e859d447cd2f454b9cfb912a1eb08143bb1cfe GIT binary patch literal 1214 zcmV;v1VQ^BiwFP!000000Nq+qbK67^URigxtRxTyIssGdXab4-cgzF; zbvE!Mc-EU>u~7QbXECUw3H7spyXUcu|9sa3Gvaa9C_hY~v2-L$TNE+I0*q0@)HHZZ z4IZMwLp6A^!>GU*3ovC{H4Pq9gNJDFPz|2!sA=d`)6lDm$JF2<8az~kCzn)1FH=LW zDjrjVhiLFn4W8^E8hQ~8y{dRj4IZMwLp6A^gKFqSHT0_DF*SII1`l1xV}luVRFjFIR&fjM2_pr%g(+cCOw>lk!XiNt>Xb~{|@BK zrxfZvDOemIyut4*sQDf|as@-Oz1SZ|0qdXpA(OsqBa%;qixat_u;1YI7rZ{j>#uli zmt(D`aTMo?S{ld9&~|FbV-c4&Y`>hyXd<6a1_LJM4qHv29m&RV%6D5Cqh!TQt=RBU zn};EDCG$EVQsYu|;7G@w;gc{R4Fl3J6q}8$q~JlogaP+;xdpU4a$*LgbMVul3C%X2 zgz|t-!zYV#_O1?tEJuBo+@38fA`?%jZ z>ApJcHQ|#^h<)m~(&u59`=Lx;jcp-oS6MdRTwh=Rb!&aLfV|)yuD7SH9}nRM`0r)F z*F~^uoP!$&huxRG&S?Rk;+DZ1{}OL3>5mq^5bv`1+LHe0;td^q_2bLXTajEL~V{9bXmeEpoHoYQc?qE1K6^ z?W?43wtB8ADPKFmgv}?AN4G05M~n?l0_p;Pd&|oQ{0S`YsRA z4Q!MlKAR)rkWc%`4+gMXY#g%@6Y94F7Hmz?jtKa0h~t9}oFHb{-nsB&Fy7@<0!hb7p7N{q-0c_a7d5-IC4VrELv=3F5-?~>mxnw@_a0LA04m^!@QT_1 zpgzU4FIAvSV;Rbj3Q(;A#nXuSXTrlDk1Jp&Ok{%`{8%vg;R;D4O-C%oWX)QLv9uU# zMNC19DH!0`1~`rZPSy%*aI6(EI!?g=$2P!m3~;h$8|Z8s=)4ZcHo$QVaI)qY=>B924#zgYaSYdEX)!i8vH$p*=ylfF}d(M2{2NX zNiz=Ug}Uv5S7)*0EQ%<%!Fr1qf583^?Dw(%6Z>DF48=MTVcZ9&b<}EjQ0%Y~_vxAe z_Q53u`?zsn!FE&3=fG7KU(vWP2a34|r52TA#?M?R*GWSBP+q>cR$QD8dKt!e4iuUJ z_Sazl`^3emC8t8v-r>D66v6!-e#|S=PuhT|nM}o_<67%Q z<3W`wd_<*m;<=TYC6x23dHAq8*_+V`Hd1)2Qt+G{Kgoi-DA9yzB+JiwLd2aK$07dJ650MAB5%aYzDa3_aF|52dltr2hQ2QU&$r}XaVXJw6hB=aPf{Mg>O9;P zJW3jm>h**3cx=K$wZ+4DIpr~(Xgi%Kpb5hS-aZ=1WF()DdOcO8*@DYU>3o+HFCL#O znp*$7Tdh_Z-1dM73Ok)f?YRE3+ibO8pL8nlWiytP6JLfbZnH3!lNV73QQK-}>+Q|W z&HI!;r2G{*=a2>H2Pd`P8!!(}gJ!{M@GQ7=&}biZnkTRXev>o)y-ECfJ9~x^<(D)H zl-ASdvopj;?{m_V`y@o;aO-RoOZ8;;4%s;!qT94N>t}vt!`=zueJUrCP0UwOS(%f~ z>S9hh%jQ>ux%uI@y?K@%R3{v_I=-^mHzXQSxRtj<>JLa9`XuTSKD40JW@E}}aF_8d zrjD1Uj^e^eEHD%6j70$($J33Z_*)oZZmbu`hV5xsZ8*J9<=?Uct-El+3Nor~xXs95!aRM60N^aB6%RH>~} zMYZArk1sH$l#qx@NtMIwV%4_Dkiu8l&d!Mt-N}Dpklp)kuGe@FO4{{VjNu5FMSMMv z5HTBTcJpcdz literal 0 HcmV?d00001 diff --git a/src/main/resources/ponder/mechanical_arm/redstone.nbt b/src/main/resources/ponder/mechanical_arm/redstone.nbt new file mode 100644 index 0000000000000000000000000000000000000000..3c80e9c829c1a92073c7990a27f5174809c68ffe GIT binary patch literal 1113 zcmV-f1g85RiwFP!000000M%FBZsSB0K90xvZFhqN0-k_NmdmYROGqm&>? zYM&-n9gj6LY1&@#R9pj3vJZkNXVN(Fx^_EhgS3ofIgZbKXU=zi-2`X=Q{gqb0AMbU zt_oe%2GlXup$<`jSq-S3M#4W=O?vpE0d68xx@oms@Ra5nmpigDPJxV*lc`wXxE46f z0w-P0JvdH*Odh9Vf#X`>FbkY?RV;X}Snzxwj%$I#EO1t?u;AIX;Q2lr*8+!G;G~OL z@XRcDz7NN>z+r_rO>pB=?SVH;5QFc2HT&9q`l%Lwyh#F*G~v{X1H3e_O=xyStfhz| zlrA_w(Vt(@{b#!G(ft>?e+_l0cDV}UF|ht||F8+wp_oY@OE);M(^G3;I&$>~jK_Ln zC}={hk9scTxd-(wPq-iItD|?uFgB#ZLozJ}m0m#iKY+DgdZbTFRO(=d-qoQJ2GH^) zk}-Ry80iB3j4!fzQ`wvw_)oa`CeMwtF*hExIzfQJEhqcGnP}L6ttK>j@dZ_KA+H)_ zuEyzYJ$GPtAQaX23p|zqovbKP^2EA1V*e^3b}LSQwlrgmT%L-{hq!)KW< zx%!i(tEcEscpUmX8gV&wpf(V5lo%8hUnf_@JaKEGlAf1LDg0kPH1 zi7o6jPbT)&lRHhln8xnkHl2nQa8t{1^XI!q7sQ9pmS%|xr%8mPb4qa?`eoJO<&w2; zizX>!M|PU1Z?CX#%Z|MF@7UoM*wM(@(fRQF(J7m3y^I~r56>SD##QQ%tR1bA!kzsx z+bNOB4j#KDF`SioR)Ul5|IbOLmhcF*M$@?4)NK2FityRGVa_L^#*r^#qJ=i45+AQ6 zR4nGB#n-TL6gAQWrTI{%dgkBOGw+N?3TbP?r3M${fZm;vcTBCDqtY~BsEGDKb0TDT zO(l&-D^>3mAuA2WK&iK-gYnByfpfJI&W&Pu`I?Vmv_8~oTX9=|q(#WL&RWhdPtwqu z(;FFy@tDSym6|+}DI<}YwkXEN^9f?K3D)%rYbQL3%Pz;B*aQ^p&XnSD?OjC z_0XY|Cb7{xlz2zqghyvkJr!DuX$dpsrrjnbBe)otma}!He4Z&TiJbX3(vl|uQDtTE f@@Xp;(~N$=HGhjz(KinDh~ME~DtY!{ClmkxFqR>X literal 0 HcmV?d00001 diff --git a/src/main/resources/ponder/mechanical_arm/setup.nbt b/src/main/resources/ponder/mechanical_arm/setup.nbt new file mode 100644 index 0000000000000000000000000000000000000000..4c935edb07d87e1e767e0fc19cd856c5e15e35e4 GIT binary patch literal 1005 zcmV5Ea)P!O zVNH%C!W5U-U6yuF{#88}{b5aa`5{phMJ<8^$pQo<>dl*(H?y;=A;18L2>(I{0QBRk zhp4AF01sms$`A$UHGtl2#QZxkR9}7=fRiv$8EuvWu8>q>X;H^mEf}kTu?=_}10G_) zQ!T55$7;bed29n7$AE_z@Knn-(AhT7xr@g!;2{P)n^G9)>=@|W#p4+85Ca}4W2$59 z7M^36Y7v8a5rcYl@i+!Nq?Km~PJAmpu)_dOeU9q=MSuyDLpXh%$|RM~)5QY017xNq zg|hGl;7%m2Maj3HQJz)Ji}S&~K&gxMQN553FD|&V1Tpycna=n8T74Axi#JK2kd_DT zbVUWi+3a%k>-cIuxt_kcnGN8JNi305UxqB6vM`qUOzkPwsrGFB2KknC?c4CZ z8B4j3WwPIwCKsiPmkQxsVHD^p7L`9+hcWt`F60FbxdrZ+rLok9+xaW@C$81OHsx%| zQHY-&weRyA%9kkfVoc%y?~8rWzebrce&>QWrU~^!`7n8=@m2HmTsRp80R}Uv$wqm{ z*pooD(Ib$@r>=@U|7HA7p5w{P=PZie(kR7393AdgWuvaqU(q=9X*8#NZ9#v^GUOPv zjY11{$1eFOt>5%gwZ2x2(^x3FF=J7{vba#J_cDxBZ+Dl$fztvuS{E-WAJftO_USl*oKQJ0hTC1axcH2gT>mioT?YlLsMJ2P8_66ZdP zl`P7rLVUSJh?r&b{O{rB*RM+rsX9(YZcjxRFE_vMG`tF9s7~Yrx&FWDLEpzP(r9-< zBe8Yaep2pPC*`?WSbNZ0s5a1SG2?Qj1_<8E{QkA?VK3}*_8)WMiWN=NttCmtO3^lb zZuq}z^50@44>&o=6p}}5xvV)N^ga||J!}}Cl#D)GW-BygX(~eGgNnYVD-> Date: Mon, 22 Mar 2021 20:20:52 -0700 Subject: [PATCH 11/14] Lieutenant Scatterbrain II. - Swich to tabs. (not everything is tabs yet) - Refactor light and color attributes to their own Enum. - Quaternion/pivot/position attribute shader. - Always update an instance when the WorldRenderer checks if it should rerender a block. - Simplify some names. - Remove generics in InstanceData classes. - Deployer Tiles now use the oriented material. - Press heads now correctly orient themselves. - ModelData buffers things faster and is simpler. --- .../com/simibubi/create/AllBlockPartials.java | 3 +- .../com/simibubi/create/AllTileEntities.java | 2 - ...Attributes.java => KineticAttributes.java} | 6 +- .../contraptions/base/KineticData.java | 89 +++----- .../base/KineticRenderMaterials.java | 4 +- .../base/KineticTileInstance.java | 20 +- ...ttributes.java => RotatingAttributes.java} | 4 +- .../contraptions/base/RotatingData.java | 8 +- ...InstancedModel.java => RotatingModel.java} | 13 +- .../base/ShaftlessCogInstance.java | 5 - ...ntraptionActorData.java => ActorData.java} | 29 +-- ...otatingActorModel.java => ActorModel.java} | 14 +- .../components/actors/DrillActorInstance.java | 7 +- .../components/actors/DrillInstance.java | 10 - .../actors/HarvesterActorInstance.java | 2 +- .../components/crank/HandCrankInstance.java | 2 +- .../deployer/DeployerActorInstance.java | 27 ++- .../components/deployer/DeployerInstance.java | 72 +++--- .../components/fan/FanInstance.java | 11 +- .../components/flywheel/FlyWheelInstance.java | 4 +- .../flywheel/engine/EngineInstance.java | 4 +- .../millstone/MillStoneCogInstance.java | 5 - .../components/mixer/MixerInstance.java | 4 +- .../components/press/PressInstance.java | 7 +- .../chassis/StickerInstance.java | 4 +- .../chassis/StickerTileEntity.java | 3 +- .../gantry/GantryCarriageInstance.java | 4 +- ...ibutes.java => ContraptionAttributes.java} | 4 +- .../render/ContraptionKineticRenderer.java | 32 +-- .../render/ContraptionModel.java | 2 +- .../render/RenderedContraption.java | 8 - .../contraptions/fluids/PumpCogInstance.java | 5 - .../fluids/pipes/FluidValveInstance.java | 2 +- ...texAttributes.java => BeltAttributes.java} | 4 +- .../contraptions/relays/belt/BeltData.java | 9 +- .../relays/belt/BeltInstance.java | 16 +- .../relays/belt/BeltInstancedModel.java | 18 +- .../relays/encased/SplitShaftInstance.java | 10 +- .../relays/gauge/GaugeInstance.java | 6 +- .../relays/gearbox/GearboxInstance.java | 22 +- ...texAttributes.java => FlapAttributes.java} | 4 +- .../content/logistics/block/FlapData.java | 175 ++++++++------- .../logistics/block/FlapInstancedModel.java | 22 -- .../content/logistics/block/FlapModel.java | 26 +++ .../diodes/AdjustableRepeaterInstance.java | 2 +- .../block/mechanicalArm/ArmInstance.java | 204 ++++++++--------- .../block/redstone/AnalogLeverInstance.java | 4 +- .../block/SchematicannonInstance.java | 4 +- .../foundation/mixin/RenderHooksMixin.java | 8 + .../foundation/render/AllProgramSpecs.java | 205 ++++++++++-------- .../foundation/render/KineticRenderer.java | 17 +- .../render/backend/RenderMaterials.java | 4 +- .../foundation/render/backend/RenderUtil.java | 81 ++++--- .../gl/attrib/ModelVertexAttributes.java | 36 --- .../backend/instancing/InstanceKey.java | 2 - .../backend/instancing/InstancedModel.java | 5 +- .../instancing/InstancedTileRenderer.java | 57 +++-- .../backend/instancing/MaterialType.java | 9 +- .../instancing/impl/BasicAttributes.java | 39 ++++ .../backend/instancing/impl/BasicData.java | 73 +++++++ .../instancing/impl/ModelAttributes.java | 41 ++++ .../backend/instancing/impl/ModelData.java | 87 +------- .../instancing/impl/OrientedAttributes.java | 40 ++++ .../backend/instancing/impl/OrientedData.java | 107 +++++++++ .../instancing/impl/OrientedModel.java | 28 +++ .../impl/TransformAttributes.java} | 12 +- ...tancedModel.java => TransformedModel.java} | 10 +- .../assets/create/flywheel/shaders/belt.vert | 6 +- .../assets/create/flywheel/shaders/model.vert | 10 +- .../create/flywheel/shaders/oriented.vert | 63 ++++++ .../create/flywheel/shaders/rotating.vert | 8 +- 71 files changed, 1094 insertions(+), 796 deletions(-) rename src/main/java/com/simibubi/create/content/contraptions/base/{KineticVertexAttributes.java => KineticAttributes.java} (80%) rename src/main/java/com/simibubi/create/content/contraptions/base/{RotatingVertexAttributes.java => RotatingAttributes.java} (86%) rename src/main/java/com/simibubi/create/content/contraptions/base/{RotatingInstancedModel.java => RotatingModel.java} (53%) rename src/main/java/com/simibubi/create/content/contraptions/components/actors/{ContraptionActorData.java => ActorData.java} (67%) rename src/main/java/com/simibubi/create/content/contraptions/components/actors/{RotatingActorModel.java => ActorModel.java} (56%) rename src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/{ContraptionVertexAttributes.java => ContraptionAttributes.java} (88%) rename src/main/java/com/simibubi/create/content/contraptions/relays/belt/{BeltVertexAttributes.java => BeltAttributes.java} (89%) rename src/main/java/com/simibubi/create/content/logistics/block/{FlapVertexAttributes.java => FlapAttributes.java} (90%) delete mode 100644 src/main/java/com/simibubi/create/content/logistics/block/FlapInstancedModel.java create mode 100644 src/main/java/com/simibubi/create/content/logistics/block/FlapModel.java delete mode 100644 src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/ModelVertexAttributes.java create mode 100644 src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/BasicAttributes.java create mode 100644 src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/BasicData.java create mode 100644 src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/ModelAttributes.java create mode 100644 src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/OrientedAttributes.java create mode 100644 src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/OrientedData.java create mode 100644 src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/OrientedModel.java rename src/main/java/com/simibubi/create/foundation/render/backend/{gl/attrib/InstanceVertexAttributes.java => instancing/impl/TransformAttributes.java} (56%) rename src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/{BasicInstancedModel.java => TransformedModel.java} (68%) create mode 100644 src/main/resources/assets/create/flywheel/shaders/oriented.vert diff --git a/src/main/java/com/simibubi/create/AllBlockPartials.java b/src/main/java/com/simibubi/create/AllBlockPartials.java index bfc1cb9fd..47cfd2963 100644 --- a/src/main/java/com/simibubi/create/AllBlockPartials.java +++ b/src/main/java/com/simibubi/create/AllBlockPartials.java @@ -19,7 +19,6 @@ import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.render.backend.RenderMaterials; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; -import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial; import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData; import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.Iterate; @@ -277,7 +276,7 @@ public class AllBlockPartials { .unCentre(); return stack; }; - return dispatcher.getMaterial(RenderMaterials.MODELS).getModel(this, referenceState, facing, ms); + return dispatcher.getMaterial(RenderMaterials.TRANSFORMED).getModel(this, referenceState, facing, ms); } } diff --git a/src/main/java/com/simibubi/create/AllTileEntities.java b/src/main/java/com/simibubi/create/AllTileEntities.java index 2a10eda64..914ab8678 100644 --- a/src/main/java/com/simibubi/create/AllTileEntities.java +++ b/src/main/java/com/simibubi/create/AllTileEntities.java @@ -115,8 +115,6 @@ import com.simibubi.create.content.schematics.block.SchematicannonRenderer; import com.simibubi.create.content.schematics.block.SchematicannonTileEntity; import com.simibubi.create.foundation.tileEntity.renderer.SmartTileEntityRenderer; import com.tterrag.registrate.util.entry.TileEntityEntry; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; public class AllTileEntities { diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/KineticVertexAttributes.java b/src/main/java/com/simibubi/create/content/contraptions/base/KineticAttributes.java similarity index 80% rename from src/main/java/com/simibubi/create/content/contraptions/base/KineticVertexAttributes.java rename to src/main/java/com/simibubi/create/content/contraptions/base/KineticAttributes.java index bb6585755..8f7b9b15b 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/KineticVertexAttributes.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/KineticAttributes.java @@ -5,10 +5,8 @@ import com.simibubi.create.foundation.render.backend.gl.attrib.IAttribSpec; import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib; import com.simibubi.create.foundation.render.backend.gl.attrib.VertexAttribSpec; -public enum KineticVertexAttributes implements IVertexAttrib { +public enum KineticAttributes implements IVertexAttrib { INSTANCE_POSITION("aInstancePos", CommonAttributes.VEC3), - LIGHT("aLight", CommonAttributes.LIGHT), - NETWORK_COLOR("aNetworkTint", CommonAttributes.RGB), SPEED("aSpeed", CommonAttributes.FLOAT), OFFSET("aOffset", CommonAttributes.FLOAT), ; @@ -16,7 +14,7 @@ public enum KineticVertexAttributes implements IVertexAttrib { private final String name; private final VertexAttribSpec spec; - KineticVertexAttributes(String name, VertexAttribSpec spec) { + KineticAttributes(String name, VertexAttribSpec spec) { this.name = name; this.spec = spec; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/KineticData.java b/src/main/java/com/simibubi/create/content/contraptions/base/KineticData.java index 944223f5c..56b0714d3 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/KineticData.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/KineticData.java @@ -2,23 +2,17 @@ package com.simibubi.create.content.contraptions.base; import java.nio.ByteBuffer; -import com.simibubi.create.foundation.render.backend.instancing.InstanceData; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; -import com.simibubi.create.foundation.render.backend.instancing.impl.IFlatLight; +import com.simibubi.create.foundation.render.backend.instancing.impl.BasicData; import com.simibubi.create.foundation.utility.ColorHelper; import net.minecraft.client.renderer.Vector3f; import net.minecraft.util.math.BlockPos; -public class KineticData> extends InstanceData implements IFlatLight { +public class KineticData extends BasicData { private float x; private float y; private float z; - private byte blockLight; - private byte skyLight; - private byte r; - private byte g; - private byte b; private float rotationalSpeed; private float rotationOffset; @@ -26,25 +20,25 @@ public class KineticData> extends InstanceData implemen super(owner); } - public D setTileEntity(KineticTileEntity te) { + public KineticData setTileEntity(KineticTileEntity te) { setPosition(te.getPos()); if (te.hasSource()) { setColor(te.network); }else { setColor(0xFF, 0xFF, 0x00); } - return (D) this; + return this; } - public D setPosition(BlockPos pos) { + public KineticData setPosition(BlockPos pos) { return setPosition(pos.getX(), pos.getY(), pos.getZ()); } - public D setPosition(Vector3f pos) { + public KineticData setPosition(Vector3f pos) { return setPosition(pos.getX(), pos.getY(), pos.getZ()); } - public D setPosition(int x, int y, int z) { + public KineticData setPosition(int x, int y, int z) { BlockPos origin = owner.renderer.getOriginCoordinate(); return setPosition((float) (x - origin.getX()), @@ -52,75 +46,62 @@ public class KineticData> extends InstanceData implemen (float) (z - origin.getZ())); } - public D setPosition(float x, float y, float z) { + public KineticData setPosition(float x, float y, float z) { this.x = x; this.y = y; this.z = z; - return (D) this; + return this; } - public D nudge(float x, float y, float z) { + public KineticData nudge(float x, float y, float z) { this.x += x; this.y += y; this.z += z; - return (D) this; + return this; } - @Override - public D setBlockLight(int blockLight) { - this.blockLight = (byte) ((blockLight & 0xF) << 4); - return (D) this; - } - - @Override - public D setSkyLight(int skyLight) { - this.skyLight = (byte) ((skyLight & 0xF) << 4); - return (D) this; - } - - public D setColor(Long l) { + public KineticData setColor(Long l) { if (l != null) return setColor(l.longValue()); - else - return setColor(0xFF, 0xFF, 0xFF); + else { + setColor(0xFF, 0xFF, 0xFF); + return this; + } } - private D setColor(long l) { + private KineticData setColor(long l) { int color = ColorHelper.colorFromLong(l); byte r = (byte) ((color >> 16) & 0xFF); byte g = (byte) ((color >> 8) & 0xFF); byte b = (byte) (color & 0xFF); - return setColor(r, g, b); + setColor(r, g, b); + + return this; } - public D setColor(int r, int g, int b) { - return setColor((byte) r, (byte) g, (byte) b); - } - - public D setColor(byte r, byte g, byte b) { - this.r = r; - this.g = g; - this.b = b; - return (D) this; - } - - public D setRotationalSpeed(float rotationalSpeed) { + public KineticData setRotationalSpeed(float rotationalSpeed) { this.rotationalSpeed = rotationalSpeed; - return (D) this; + return this; } - public D setRotationOffset(float rotationOffset) { + public KineticData setRotationOffset(float rotationOffset) { this.rotationOffset = rotationOffset; - return (D) this; + return this; } @Override public void write(ByteBuffer buf) { - putVec3(buf, x, y, z); - putVec2(buf, blockLight, skyLight); - putVec3(buf, r, g, b); - put(buf, rotationalSpeed); - put(buf, rotationOffset); + super.write(buf); + + buf.asFloatBuffer().put(new float[] { + x, + y, + z, + rotationalSpeed, + rotationOffset + }); + + buf.position(buf.position() + 5 * 4); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/KineticRenderMaterials.java b/src/main/java/com/simibubi/create/content/contraptions/base/KineticRenderMaterials.java index 8d3d32d31..2320fcb41 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/KineticRenderMaterials.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/KineticRenderMaterials.java @@ -1,6 +1,6 @@ package com.simibubi.create.content.contraptions.base; -import com.simibubi.create.content.contraptions.components.actors.ContraptionActorData; +import com.simibubi.create.content.contraptions.components.actors.ActorData; import com.simibubi.create.content.contraptions.relays.belt.BeltData; import com.simibubi.create.content.logistics.block.FlapData; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; @@ -10,7 +10,7 @@ public class KineticRenderMaterials { public static final MaterialType> ROTATING = new MaterialType<>(); public static final MaterialType> BELTS = new MaterialType<>(); - public static final MaterialType> ACTORS = new MaterialType<>(); + public static final MaterialType> ACTORS = new MaterialType<>(); public static final MaterialType> FLAPS = new MaterialType<>(); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileInstance.java b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileInstance.java index 6beb6bdac..a31e26f09 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileInstance.java @@ -25,10 +25,10 @@ public abstract class KineticTileInstance extends T } protected final void updateRotation(RotatingData key, Direction.Axis axis, float speed) { - key.setColor(tile.network) - .setRotationalSpeed(speed) - .setRotationOffset(getRotationOffset(axis)) - .setRotationAxis(axis); + key.setRotationAxis(axis) + .setRotationOffset(getRotationOffset(axis)) + .setRotationalSpeed(speed) + .setColor(tile.network); } protected final void updateRotation(RotatingData key, Direction.Axis axis) { @@ -37,12 +37,12 @@ public abstract class KineticTileInstance extends T protected final InstanceKey setup(InstanceKey key, float speed, Direction.Axis axis) { key.getInstance() - .setBlockLight(world.getLightLevel(LightType.BLOCK, pos)) - .setSkyLight(world.getLightLevel(LightType.SKY, pos)) - .setTileEntity(tile) - .setRotationalSpeed(speed) - .setRotationOffset(getRotationOffset(axis)) - .setRotationAxis(axis); + .setRotationAxis(axis) + .setRotationalSpeed(speed) + .setRotationOffset(getRotationOffset(axis)) + .setTileEntity(tile) + .setSkyLight(world.getLightLevel(LightType.SKY, pos)) + .setBlockLight(world.getLightLevel(LightType.BLOCK, pos)); return key; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/RotatingVertexAttributes.java b/src/main/java/com/simibubi/create/content/contraptions/base/RotatingAttributes.java similarity index 86% rename from src/main/java/com/simibubi/create/content/contraptions/base/RotatingVertexAttributes.java rename to src/main/java/com/simibubi/create/content/contraptions/base/RotatingAttributes.java index e264731cc..ef0e1122c 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/RotatingVertexAttributes.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/RotatingAttributes.java @@ -5,14 +5,14 @@ import com.simibubi.create.foundation.render.backend.gl.attrib.IAttribSpec; import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib; import com.simibubi.create.foundation.render.backend.gl.attrib.VertexAttribSpec; -public enum RotatingVertexAttributes implements IVertexAttrib { +public enum RotatingAttributes implements IVertexAttrib { AXIS("aAxis", CommonAttributes.NORMAL), ; private final String name; private final VertexAttribSpec spec; - RotatingVertexAttributes(String name, VertexAttribSpec spec) { + RotatingAttributes(String name, VertexAttribSpec spec) { this.name = name; this.spec = spec; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/RotatingData.java b/src/main/java/com/simibubi/create/content/contraptions/base/RotatingData.java index dcc5ca5f7..22d33f30e 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/RotatingData.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/RotatingData.java @@ -2,18 +2,12 @@ package com.simibubi.create.content.contraptions.base; import java.nio.ByteBuffer; -import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; import net.minecraft.client.renderer.Vector3f; import net.minecraft.util.Direction; -public class RotatingData extends KineticData { - public static VertexFormat FORMAT = VertexFormat.builder() - .addAttributes(KineticVertexAttributes.class) - .addAttributes(RotatingVertexAttributes.class) - .build(); - +public class RotatingData extends KineticData { private byte rotationAxisX; private byte rotationAxisY; private byte rotationAxisZ; diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/RotatingInstancedModel.java b/src/main/java/com/simibubi/create/content/contraptions/base/RotatingModel.java similarity index 53% rename from src/main/java/com/simibubi/create/content/contraptions/base/RotatingInstancedModel.java rename to src/main/java/com/simibubi/create/content/contraptions/base/RotatingModel.java index 6f439ca42..8c0d77c17 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/RotatingInstancedModel.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/RotatingModel.java @@ -3,11 +3,18 @@ package com.simibubi.create.content.contraptions.base; import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; +import com.simibubi.create.foundation.render.backend.instancing.impl.BasicAttributes; import net.minecraft.client.renderer.BufferBuilder; -public class RotatingInstancedModel extends InstancedModel { - public RotatingInstancedModel(InstancedTileRenderer renderer, BufferBuilder buf) { +public class RotatingModel extends InstancedModel { + public static VertexFormat FORMAT = VertexFormat.builder() + .addAttributes(BasicAttributes.class) + .addAttributes(KineticAttributes.class) + .addAttributes(RotatingAttributes.class) + .build(); + + public RotatingModel(InstancedTileRenderer renderer, BufferBuilder buf) { super(renderer, buf); } @@ -18,7 +25,7 @@ public class RotatingInstancedModel extends InstancedModel { @Override protected VertexFormat getInstanceFormat() { - return RotatingData.FORMAT; + return FORMAT; } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/ShaftlessCogInstance.java b/src/main/java/com/simibubi/create/content/contraptions/base/ShaftlessCogInstance.java index 66ae7c750..952846454 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/ShaftlessCogInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/ShaftlessCogInstance.java @@ -2,13 +2,8 @@ package com.simibubi.create.content.contraptions.base; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; -import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderRegistry; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; -import net.minecraft.tileentity.TileEntityType; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; - public class ShaftlessCogInstance extends SingleRotatingInstance { public ShaftlessCogInstance(InstancedTileRenderer modelManager, KineticTileEntity tile) { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/ContraptionActorData.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/ActorData.java similarity index 67% rename from src/main/java/com/simibubi/create/content/contraptions/components/actors/ContraptionActorData.java rename to src/main/java/com/simibubi/create/content/contraptions/components/actors/ActorData.java index 719825e17..d360fb92b 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/ContraptionActorData.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/ActorData.java @@ -2,7 +2,6 @@ package com.simibubi.create.content.contraptions.components.actors; import java.nio.ByteBuffer; -import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat; import com.simibubi.create.foundation.render.backend.instancing.InstanceData; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; @@ -10,11 +9,7 @@ import net.minecraft.client.renderer.Quaternion; import net.minecraft.client.renderer.Vector3f; import net.minecraft.util.math.BlockPos; -public class ContraptionActorData extends InstanceData { - public static VertexFormat FORMAT = VertexFormat.builder() - .addAttributes(ActorVertexAttributes.class) - .build(); - +public class ActorData extends InstanceData { private float x; private float y; private float z; @@ -34,63 +29,63 @@ public class ContraptionActorData extends InstanceData { private float speed; - protected ContraptionActorData(InstancedModel owner) { + protected ActorData(InstancedModel owner) { super(owner); } - public ContraptionActorData setPosition(BlockPos pos) { + public ActorData setPosition(BlockPos pos) { this.x = pos.getX(); this.y = pos.getY(); this.z = pos.getZ(); return this; } - public ContraptionActorData setBlockLight(int blockLight) { + public ActorData setBlockLight(int blockLight) { this.blockLight = (byte) ((blockLight & 0xF) << 4); return this; } - public ContraptionActorData setSkyLight(int skyLight) { + public ActorData setSkyLight(int skyLight) { this.skyLight = (byte) ((skyLight & 0xF) << 4); return this; } - public ContraptionActorData setRotationOffset(float rotationOffset) { + public ActorData setRotationOffset(float rotationOffset) { this.rotationOffset = rotationOffset; return this; } - public ContraptionActorData setSpeed(float speed) { + public ActorData setSpeed(float speed) { this.speed = speed; return this; } - public ContraptionActorData setRotationAxis(Vector3f axis) { + public ActorData setRotationAxis(Vector3f axis) { setRotationAxis(axis.getX(), axis.getY(), axis.getZ()); return this; } - public ContraptionActorData setRotationAxis(float rotationAxisX, float rotationAxisY, float rotationAxisZ) { + public ActorData setRotationAxis(float rotationAxisX, float rotationAxisY, float rotationAxisZ) { this.rotationAxisX = (byte) (rotationAxisX * 127); this.rotationAxisY = (byte) (rotationAxisY * 127); this.rotationAxisZ = (byte) (rotationAxisZ * 127); return this; } - public ContraptionActorData setRotationCenter(Vector3f axis) { + public ActorData setRotationCenter(Vector3f axis) { setRotationCenter(axis.getX(), axis.getY(), axis.getZ()); return this; } - public ContraptionActorData setRotationCenter(float rotationCenterX, float rotationCenterY, float rotationCenterZ) { + public ActorData setRotationCenter(float rotationCenterX, float rotationCenterY, float rotationCenterZ) { this.rotationCenterX = (byte) (rotationCenterX * 127); this.rotationCenterY = (byte) (rotationCenterY * 127); this.rotationCenterZ = (byte) (rotationCenterZ * 127); return this; } - public ContraptionActorData setLocalRotation(Quaternion q) { + public ActorData setLocalRotation(Quaternion q) { this.qX = q.getX(); this.qY = q.getY(); this.qZ = q.getZ(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/RotatingActorModel.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/ActorModel.java similarity index 56% rename from src/main/java/com/simibubi/create/content/contraptions/components/actors/RotatingActorModel.java rename to src/main/java/com/simibubi/create/content/contraptions/components/actors/ActorModel.java index 8715c6f99..a8fdeac6c 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/RotatingActorModel.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/ActorModel.java @@ -6,18 +6,22 @@ import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRen import net.minecraft.client.renderer.BufferBuilder; -public class RotatingActorModel extends InstancedModel { - public RotatingActorModel(InstancedTileRenderer renderer, BufferBuilder buf) { +public class ActorModel extends InstancedModel { + public static VertexFormat FORMAT = VertexFormat.builder() + .addAttributes(ActorVertexAttributes.class) + .build(); + + public ActorModel(InstancedTileRenderer renderer, BufferBuilder buf) { super(renderer, buf); } @Override protected VertexFormat getInstanceFormat() { - return ContraptionActorData.FORMAT; + return FORMAT; } @Override - protected ContraptionActorData newInstance() { - return new ContraptionActorData(this); + protected ActorData newInstance() { + return new ActorData(this); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillActorInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillActorInstance.java index 9fc849324..7c4f42fde 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillActorInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillActorInstance.java @@ -2,7 +2,6 @@ package com.simibubi.create.content.contraptions.components.actors; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; -import com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance; import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionKineticRenderer; import com.simibubi.create.foundation.render.backend.instancing.InstanceKey; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; @@ -13,15 +12,15 @@ import net.minecraft.block.BlockState; import net.minecraft.client.renderer.Quaternion; import net.minecraft.util.Direction; -public class DrillActorInstance extends ActorInstance { +public class DrillActorInstance extends com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance { - InstanceKey drillHead; + InstanceKey drillHead; private Direction facing; public DrillActorInstance(ContraptionKineticRenderer modelManager, MovementContext context) { super(modelManager, context); - RenderMaterial> renderMaterial = modelManager.getActorMaterial(); + RenderMaterial> renderMaterial = modelManager.getActorMaterial(); BlockState state = context.state; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillInstance.java index cb9a66d2d..dbd7b9b92 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillInstance.java @@ -4,17 +4,7 @@ import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.RotatingData; import com.simibubi.create.content.contraptions.base.SingleRotatingInstance; -import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; -import com.simibubi.create.content.contraptions.components.structureMovement.render.RenderedContraption; import com.simibubi.create.foundation.render.backend.instancing.*; -import com.simibubi.create.foundation.utility.AngleHelper; - -import net.minecraft.block.BlockState; -import net.minecraft.tileentity.TileEntityType; -import net.minecraft.util.Direction; -import net.minecraft.world.LightType; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; public class DrillInstance extends SingleRotatingInstance { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterActorInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterActorInstance.java index bc6cae2c9..1ce83ff38 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterActorInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterActorInstance.java @@ -36,7 +36,7 @@ public class HarvesterActorInstance extends ActorInstance { public HarvesterActorInstance(ContraptionKineticRenderer modelManager, MovementContext context) { super(modelManager, context); - RenderMaterial> renderMaterial = modelManager.getBasicMaterial(); + RenderMaterial> renderMaterial = modelManager.transformMaterial(); BlockState state = context.state; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/crank/HandCrankInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/crank/HandCrankInstance.java index 86c353eae..382471548 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/crank/HandCrankInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/crank/HandCrankInstance.java @@ -50,7 +50,7 @@ public class HandCrankInstance extends SingleRotatingInstance implements IDynami .rotate(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis), angle) .unCentre(); - crank.getInstance().setTransformNoCopy(ms); + crank.getInstance().setTransform(ms); } @Override diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerActorInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerActorInstance.java index eff34d5db..4d73c88ef 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerActorInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerActorInstance.java @@ -37,7 +37,7 @@ public class DeployerActorInstance extends ActorInstance { public DeployerActorInstance(ContraptionKineticRenderer modelManager, MovementContext context) { super(modelManager, context); - RenderMaterial> mat = modelManager.getBasicMaterial(); + RenderMaterial> mat = modelManager.transformMaterial(); BlockState state = context.state; DeployerTileEntity.Mode mode = NBTHelper.readEnum(context.tileData, "Mode", DeployerTileEntity.Mode.class); @@ -62,9 +62,9 @@ public class DeployerActorInstance extends ActorInstance { int blockLight = localBlockLight(); shaft.getInstance() - .setBlockLight(blockLight) - .setRotationAxis(axis) - .setPosition(context.localPos); + .setRotationAxis(axis) + .setPosition(context.localPos) + .setBlockLight(blockLight); pole.getInstance().setBlockLight(blockLight); hand.getInstance().setBlockLight(blockLight); @@ -91,6 +91,23 @@ public class DeployerActorInstance extends ActorInstance { msr.translate(context.localPos) .translate(offset); - DeployerInstance.transformModel(msr, pole, hand, yRot, zRot, zRotPole); + transformModel(msr, pole, hand, yRot, zRot, zRotPole); + } + + static void transformModel(MatrixStacker msr, InstanceKey pole, InstanceKey hand, float yRot, float zRot, float zRotPole) { + + msr.centre(); + msr.rotate(Direction.SOUTH, (float) ((zRot) / 180 * Math.PI)); + msr.rotate(Direction.UP, (float) ((yRot) / 180 * Math.PI)); + + msr.push(); + msr.rotate(Direction.SOUTH, (float) ((zRotPole) / 180 * Math.PI)); + msr.unCentre(); + pole.getInstance().setTransform(msr.unwrap()); + msr.pop(); + + msr.unCentre(); + + hand.getInstance().setTransform(msr.unwrap()); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerInstance.java index a6b7de237..2b334a52e 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerInstance.java @@ -1,22 +1,24 @@ package com.simibubi.create.content.contraptions.components.deployer; -import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.relays.encased.ShaftInstance; +import com.simibubi.create.foundation.render.backend.RenderMaterials; import com.simibubi.create.foundation.render.backend.instancing.*; -import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData; +import com.simibubi.create.foundation.render.backend.instancing.impl.OrientedData; 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.renderer.Quaternion; import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.Vec3i; import static com.simibubi.create.content.contraptions.base.DirectionalAxisKineticBlock.AXIS_ALONG_FIRST_COORDINATE; import static com.simibubi.create.content.contraptions.base.DirectionalKineticBlock.FACING; -public class DeployerInstance extends ShaftInstance implements IDynamicInstance { +public class DeployerInstance extends ShaftInstance implements IDynamicInstance, ITickableInstance { final DeployerTileEntity tile; final Direction facing; @@ -24,12 +26,13 @@ public class DeployerInstance extends ShaftInstance implements IDynamicInstance final float zRot; final float zRotPole; - protected final InstanceKey pole; + protected final InstanceKey pole; - protected InstanceKey hand; + protected InstanceKey hand; AllBlockPartials currentHand; float progress = Float.NaN; + private boolean newHand = false; public DeployerInstance(InstancedTileRenderer dispatcher, KineticTileEntity tile) { super(dispatcher, tile); @@ -43,30 +46,41 @@ public class DeployerInstance extends ShaftInstance implements IDynamicInstance zRot = facing == Direction.UP ? 270 : facing == Direction.DOWN ? 90 : 0; zRotPole = rotatePole ? 90 : 0; - pole = modelManager.getBasicMaterial().getModel(AllBlockPartials.DEPLOYER_POLE, blockState).createInstance(); + pole = RenderMaterials.ORIENTED.get(modelManager).getModel(AllBlockPartials.DEPLOYER_POLE, blockState).createInstance(); updateHandPose(); relight(pos, pole.getInstance()); + + updateRotation(pole, hand, yRot, zRot, zRotPole); + } + + @Override + public void tick() { + newHand = updateHandPose(); } @Override public void beginFrame() { - boolean newHand = updateHandPose(); - float newProgress = getProgress(AnimationTickHolder.getPartialTicks()); if (!newHand && MathHelper.epsilonEquals(newProgress, progress)) return; progress = newProgress; + newHand = false; - MatrixStack ms = new MatrixStack(); - MatrixStacker msr = MatrixStacker.of(ms); + float handLength = currentHand == AllBlockPartials.DEPLOYER_HAND_POINTING ? 0 + : currentHand == AllBlockPartials.DEPLOYER_HAND_HOLDING ? 4 / 16f : 3 / 16f; + float distance = Math.min(MathHelper.clamp(progress, 0, 1) * (tile.reach + handLength), 21 / 16f); + Vec3i facingVec = facing.getDirectionVec(); + BlockPos blockPos = getFloatingPos(); - msr.translate(getFloatingPos()) - .translate(getHandOffset()); + float x = blockPos.getX() + ((float) facingVec.getX()) * distance; + float y = blockPos.getY() + ((float) facingVec.getY()) * distance; + float z = blockPos.getZ() + ((float) facingVec.getZ()) * distance; - transformModel(msr, pole, hand, yRot, zRot, zRotPole); + pole.getInstance().setPosition(x, y, z); + hand.getInstance().setPosition(x, y, z); } @@ -93,21 +107,14 @@ public class DeployerInstance extends ShaftInstance implements IDynamicInstance if (hand != null) hand.delete(); - hand = modelManager.getBasicMaterial().getModel(currentHand, blockState).createInstance(); + hand = RenderMaterials.ORIENTED.get(modelManager).getModel(currentHand, blockState).createInstance(); relight(pos, hand.getInstance()); + updateRotation(pole, hand, yRot, zRot, zRotPole); return true; } - protected Vec3d getHandOffset() { - float handLength = tile.getHandPose() == AllBlockPartials.DEPLOYER_HAND_POINTING ? 0 - : tile.getHandPose() == AllBlockPartials.DEPLOYER_HAND_HOLDING ? 4 / 16f : 3 / 16f; - float distance = Math.min(MathHelper.clamp(progress, 0, 1) * (tile.reach + handLength), 21 / 16f); - Vec3d offset = new Vec3d(facing.getDirectionVec()).scale(distance); - return offset; - } - private float getProgress(float partialTicks) { if (tile.state == DeployerTileEntity.State.EXPANDING) return 1 - (tile.timer - partialTicks * tile.getTimerSpeed()) / 1000f; @@ -116,20 +123,15 @@ public class DeployerInstance extends ShaftInstance implements IDynamicInstance return 0; } - static void transformModel(MatrixStacker msr, InstanceKey pole, InstanceKey hand, float yRot, float zRot, float zRotPole) { + static void updateRotation(InstanceKey pole, InstanceKey hand, float yRot, float zRot, float zRotPole) { - msr.centre(); - msr.rotate(Direction.SOUTH, (float) ((zRot) / 180 * Math.PI)); - msr.rotate(Direction.UP, (float) ((yRot) / 180 * Math.PI)); + Quaternion q = Direction.SOUTH.getUnitVector().getDegreesQuaternion(zRot); + q.multiply(Direction.UP.getUnitVector().getDegreesQuaternion(yRot)); - msr.push(); - msr.rotate(Direction.SOUTH, (float) ((zRotPole) / 180 * Math.PI)); - msr.unCentre(); - pole.getInstance().setTransform(msr.unwrap()); - msr.pop(); + hand.getInstance().setRotation(q); - msr.unCentre(); + q.multiply(Direction.SOUTH.getUnitVector().getDegreesQuaternion(zRotPole)); - hand.getInstance().setTransform(msr.unwrap()); + pole.getInstance().setRotation(q); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/fan/FanInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/fan/FanInstance.java index ff7cfcfad..8660b5628 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/fan/FanInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/fan/FanInstance.java @@ -7,10 +7,8 @@ import com.simibubi.create.content.contraptions.base.IRotate; import com.simibubi.create.content.contraptions.base.KineticTileInstance; import com.simibubi.create.content.contraptions.base.RotatingData; import com.simibubi.create.foundation.render.backend.instancing.InstanceKey; -import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; -import net.minecraft.client.renderer.Vector3f; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; @@ -31,8 +29,13 @@ public class FanInstance extends KineticTileInstance { shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(modelManager, blockState, direction.getOpposite()).createInstance(); fan = AllBlockPartials.ENCASED_FAN_INNER.renderOnDirectionalSouthRotating(modelManager, blockState, direction.getOpposite()).createInstance(); - updateRotation(shaft.getInstance().setTileEntity(tile), axis); - updateRotation(fan.getInstance().setTileEntity(tile), axis, getFanSpeed()); + RotatingData shaftInstance = shaft.getInstance(); + shaftInstance.setTileEntity(tile); + updateRotation(shaftInstance, axis); + + RotatingData fanInstance = fan.getInstance(); + fanInstance.setTileEntity(tile); + updateRotation(fanInstance, axis, getFanSpeed()); updateLight(); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlyWheelInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlyWheelInstance.java index 5393afc6b..6b323f0f2 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlyWheelInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlyWheelInstance.java @@ -62,7 +62,7 @@ public class FlyWheelInstance extends KineticTileInstance im connectorAngleMult = flipAngle ? -1 : 1; - RenderMaterial> mat = modelManager.getMaterial(RenderMaterials.MODELS); + RenderMaterial> mat = modelManager.getMaterial(RenderMaterials.TRANSFORMED); upperRotating = mat.getModel(AllBlockPartials.FLYWHEEL_UPPER_ROTATING, blockState).createInstance(); lowerRotating = mat.getModel(AllBlockPartials.FLYWHEEL_LOWER_ROTATING, blockState).createInstance(); @@ -125,7 +125,7 @@ public class FlyWheelInstance extends KineticTileInstance im .rotate(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, facing.getAxis()), AngleHelper.rad(angle)) .unCentre(); - wheel.getInstance().setTransformNoCopy(ms); + wheel.getInstance().setTransform(ms); lastAngle = angle; firstFrame = false; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/engine/EngineInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/engine/EngineInstance.java index ce01d7646..b2830d978 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/engine/EngineInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/engine/EngineInstance.java @@ -30,7 +30,7 @@ public class EngineInstance extends TileEntityInstance { Direction facing = blockState.get(BlockStateProperties.HORIZONTAL_FACING); - this.frame = modelManager.getMaterial(RenderMaterials.MODELS).getModel(frame, blockState).createInstance(); + this.frame = modelManager.getMaterial(RenderMaterials.TRANSFORMED).getModel(frame, blockState).createInstance(); float angle = AngleHelper.rad(AngleHelper.horizontalAngle(facing)); @@ -45,7 +45,7 @@ public class EngineInstance extends TileEntityInstance { .translate(0, 0, -1); this.frame.getInstance() - .setTransformNoCopy(ms); + .setTransform(ms); updateLight(); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/millstone/MillStoneCogInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/millstone/MillStoneCogInstance.java index 64f667c1b..cc06621a6 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/millstone/MillStoneCogInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/millstone/MillStoneCogInstance.java @@ -5,13 +5,8 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.RotatingData; import com.simibubi.create.content.contraptions.base.SingleRotatingInstance; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; -import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderRegistry; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; -import net.minecraft.tileentity.TileEntityType; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; - public class MillStoneCogInstance extends SingleRotatingInstance { public MillStoneCogInstance(InstancedTileRenderer modelManager, KineticTileEntity tile) { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MixerInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MixerInstance.java index 5623900f4..0290fdfb7 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MixerInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MixerInstance.java @@ -26,7 +26,7 @@ public class MixerInstance extends ShaftlessCogInstance implements IDynamicInsta mixerHead.getInstance() .setRotationAxis(Direction.Axis.Y); - mixerPole = modelManager.getMaterial(RenderMaterials.MODELS) + mixerPole = modelManager.getMaterial(RenderMaterials.TRANSFORMED) .getModel(AllBlockPartials.MECHANICAL_MIXER_POLE, blockState) .createInstance(); @@ -68,7 +68,7 @@ public class MixerInstance extends ShaftlessCogInstance implements IDynamicInsta msr.translate(getFloatingPos()); msr.translate(0, -renderedHeadOffset, 0); - mixerPole.getInstance().setTransformNoCopy(ms); + mixerPole.getInstance().setTransform(ms); } private float getRenderedHeadOffset(MechanicalMixerTileEntity mixer) { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/press/PressInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/press/PressInstance.java index 2927d7ea5..cacf1d99d 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/press/PressInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/press/PressInstance.java @@ -4,7 +4,6 @@ import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.relays.encased.ShaftInstance; -import com.simibubi.create.foundation.render.backend.RenderMaterials; import com.simibubi.create.foundation.render.backend.instancing.IDynamicInstance; import com.simibubi.create.foundation.render.backend.instancing.InstanceKey; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; @@ -19,9 +18,7 @@ public class PressInstance extends ShaftInstance implements IDynamicInstance { public PressInstance(InstancedTileRenderer dispatcher, KineticTileEntity tile) { super(dispatcher, tile); - pressHead = modelManager.getMaterial(RenderMaterials.MODELS) - .getModel(AllBlockPartials.MECHANICAL_PRESS_HEAD, blockState) - .createInstance(); + pressHead = AllBlockPartials.MECHANICAL_PRESS_HEAD.renderOnHorizontalModel(dispatcher, blockState).createInstance(); updateLight(); transformModels((MechanicalPressTileEntity) tile); @@ -46,7 +43,7 @@ public class PressInstance extends ShaftInstance implements IDynamicInstance { msr.translate(0, -renderedHeadOffset, 0); pressHead.getInstance() - .setTransformNoCopy(ms); + .setTransform(ms); } private float getRenderedHeadOffset(MechanicalPressTileEntity press) { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerInstance.java index a56bbc689..dffa94083 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerInstance.java @@ -24,7 +24,7 @@ public class StickerInstance extends TileEntityInstance imple public StickerInstance(InstancedTileRenderer modelManager, StickerTileEntity tile) { super(modelManager, tile); - head = modelManager.getMaterial(RenderMaterials.MODELS).getModel(AllBlockPartials.STICKER_HEAD, blockState).createInstance(); + head = modelManager.getMaterial(RenderMaterials.TRANSFORMED).getModel(AllBlockPartials.STICKER_HEAD, blockState).createInstance(); fakeWorld = tile.getWorld() != Minecraft.getInstance().world; facing = blockState.get(StickerBlock.FACING); @@ -54,7 +54,7 @@ public class StickerInstance extends TileEntityInstance imple .translate(0, (offset * offset) * 4 / 16f, 0); head.getInstance() - .setTransformNoCopy(stack); + .setTransform(stack); lastOffset = offset; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerTileEntity.java index a59293331..dc16f7e98 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/StickerTileEntity.java @@ -7,6 +7,7 @@ import com.simibubi.create.AllSoundEvents; import com.simibubi.create.CreateClient; import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity; import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueItem; +import com.simibubi.create.foundation.render.backend.FastRenderDispatcher; import com.simibubi.create.foundation.render.backend.instancing.IInstanceRendered; import com.simibubi.create.foundation.tileEntity.SmartTileEntity; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; @@ -71,7 +72,7 @@ public class StickerTileEntity extends SmartTileEntity implements IInstanceRende DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> playSound(false)); piston.chase(target, .4f, Chaser.LINEAR); - DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> CreateClient.kineticRenderer.get(world).update(this)); + DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> FastRenderDispatcher.enqueueUpdate(this)); } public boolean isAttachedToBlock() { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageInstance.java index d2d5a8404..096548d84 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/gantry/GantryCarriageInstance.java @@ -29,7 +29,7 @@ public class GantryCarriageInstance extends ShaftInstance implements IDynamicIns public GantryCarriageInstance(InstancedTileRenderer dispatcher, KineticTileEntity tile) { super(dispatcher, tile); - gantryCogs = modelManager.getMaterial(RenderMaterials.MODELS) + gantryCogs = modelManager.getMaterial(RenderMaterials.TRANSFORMED) .getModel(AllBlockPartials.GANTRY_COGS, blockState) .createInstance(); @@ -72,7 +72,7 @@ public class GantryCarriageInstance extends ShaftInstance implements IDynamicIns .translate(0, 9 / 16f, 0) .unCentre(); - gantryCogs.getInstance().setTransformNoCopy(ms); + gantryCogs.getInstance().setTransform(ms); } @Override diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionVertexAttributes.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionAttributes.java similarity index 88% rename from src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionVertexAttributes.java rename to src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionAttributes.java index 53e9931f9..4e3d65be9 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionVertexAttributes.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionAttributes.java @@ -5,7 +5,7 @@ import com.simibubi.create.foundation.render.backend.gl.attrib.IAttribSpec; import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib; import com.simibubi.create.foundation.render.backend.gl.attrib.VertexAttribSpec; -public enum ContraptionVertexAttributes implements IVertexAttrib { +public enum ContraptionAttributes implements IVertexAttrib { VERTEX_POSITION("aPos", CommonAttributes.VEC3), NORMAL("aNormal", CommonAttributes.NORMAL), TEXTURE("aTexCoords", CommonAttributes.UV), @@ -16,7 +16,7 @@ public enum ContraptionVertexAttributes implements IVertexAttrib { private final String name; private final VertexAttribSpec spec; - ContraptionVertexAttributes(String name, VertexAttribSpec spec) { + ContraptionAttributes(String name, VertexAttribSpec spec) { this.name = name; this.spec = spec; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionKineticRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionKineticRenderer.java index 80f2cd8d2..612f57787 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionKineticRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionKineticRenderer.java @@ -2,18 +2,19 @@ package com.simibubi.create.content.contraptions.components.structureMovement.re import com.simibubi.create.AllMovementBehaviours; import com.simibubi.create.content.contraptions.base.KineticRenderMaterials; -import com.simibubi.create.content.contraptions.base.RotatingInstancedModel; -import com.simibubi.create.content.contraptions.components.actors.ContraptionActorData; -import com.simibubi.create.content.contraptions.components.actors.RotatingActorModel; +import com.simibubi.create.content.contraptions.base.RotatingModel; +import com.simibubi.create.content.contraptions.components.actors.ActorData; +import com.simibubi.create.content.contraptions.components.actors.ActorModel; import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour; import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; import com.simibubi.create.content.contraptions.relays.belt.BeltInstancedModel; -import com.simibubi.create.content.logistics.block.FlapInstancedModel; +import com.simibubi.create.content.logistics.block.FlapModel; import com.simibubi.create.foundation.render.AllProgramSpecs; import com.simibubi.create.foundation.render.backend.RenderMaterials; import com.simibubi.create.foundation.render.backend.instancing.*; -import com.simibubi.create.foundation.render.backend.instancing.impl.BasicInstancedModel; +import com.simibubi.create.foundation.render.backend.instancing.impl.OrientedModel; +import com.simibubi.create.foundation.render.backend.instancing.impl.TransformedModel; import net.minecraft.util.math.BlockPos; import net.minecraft.world.gen.feature.template.Template; import org.apache.commons.lang3.tuple.Pair; @@ -23,7 +24,7 @@ import java.util.ArrayList; public class ContraptionKineticRenderer extends InstancedTileRenderer { - protected ArrayList actors = new ArrayList<>(); + protected ArrayList actors = new ArrayList<>(); public final RenderedContraption contraption; @@ -33,35 +34,36 @@ public class ContraptionKineticRenderer extends InstancedTileRenderer(this, AllProgramSpecs.C_MODEL, BasicInstancedModel::new)); + materials.put(RenderMaterials.TRANSFORMED, new RenderMaterial<>(this, AllProgramSpecs.C_MODEL, TransformedModel::new)); + materials.put(RenderMaterials.ORIENTED, new RenderMaterial<>(this, AllProgramSpecs.C_ORIENTED, OrientedModel::new)); materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(this, AllProgramSpecs.C_BELT, BeltInstancedModel::new)); - materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(this, AllProgramSpecs.C_ROTATING, RotatingInstancedModel::new)); - materials.put(KineticRenderMaterials.FLAPS, new RenderMaterial<>(this, AllProgramSpecs.C_FLAPS, FlapInstancedModel::new)); - materials.put(KineticRenderMaterials.ACTORS, new RenderMaterial<>(this, AllProgramSpecs.C_ACTOR, RotatingActorModel::new)); + materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(this, AllProgramSpecs.C_ROTATING, RotatingModel::new)); + materials.put(KineticRenderMaterials.FLAPS, new RenderMaterial<>(this, AllProgramSpecs.C_FLAPS, FlapModel::new)); + materials.put(KineticRenderMaterials.ACTORS, new RenderMaterial<>(this, AllProgramSpecs.C_ACTOR, ActorModel::new)); } @Override public void tick() { - actors.forEach(ActorInstance::tick); + actors.forEach(com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance::tick); } @Override public void beginFrame(double cameraX, double cameraY, double cameraZ) { super.beginFrame(cameraX, cameraY, cameraZ); - actors.forEach(ActorInstance::beginFrame); + actors.forEach(com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance::beginFrame); } @Nullable - public ActorInstance createActor(Pair actor) { + public com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance createActor(Pair actor) { Template.BlockInfo blockInfo = actor.getLeft(); MovementContext context = actor.getRight(); MovementBehaviour movementBehaviour = AllMovementBehaviours.of(blockInfo.state); if (movementBehaviour != null && movementBehaviour.hasSpecialInstancedRendering()) { - ActorInstance instance = movementBehaviour.createInstance(this, context); + com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance instance = movementBehaviour.createInstance(this, context); actors.add(instance); @@ -71,7 +73,7 @@ public class ContraptionKineticRenderer extends InstancedTileRenderer> getActorMaterial() { + public RenderMaterial> getActorMaterial() { return getMaterial(KineticRenderMaterials.ACTORS); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionModel.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionModel.java index 27d097aeb..c97b7c2dc 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionModel.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionModel.java @@ -14,7 +14,7 @@ import org.lwjgl.opengl.GL20; public class ContraptionModel extends BufferedModel { public static final VertexFormat FORMAT = VertexFormat.builder() - .addAttributes(ContraptionVertexAttributes.class) + .addAttributes(ContraptionAttributes.class) .build(); protected GlPrimitiveType eboIndexType; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/RenderedContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/RenderedContraption.java index 9beb21f64..66e49a9bc 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/RenderedContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/RenderedContraption.java @@ -5,22 +5,14 @@ import java.util.HashMap; import java.util.List; import java.util.Random; -import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; -import org.apache.commons.lang3.tuple.MutablePair; import org.lwjgl.opengl.GL11; import com.mojang.blaze3d.matrix.MatrixStack; -import com.simibubi.create.AllMovementBehaviours; -import com.simibubi.create.content.contraptions.base.KineticRenderMaterials; -import com.simibubi.create.content.contraptions.components.actors.ContraptionActorData; import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity; import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionLighter; -import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour; -import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; import com.simibubi.create.foundation.render.backend.Backend; import com.simibubi.create.foundation.render.backend.instancing.IInstanceRendered; -import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial; import com.simibubi.create.foundation.render.backend.light.GridAlignedBB; import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.worldWrappers.PlacementSimulationWorld; diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpCogInstance.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpCogInstance.java index b65306165..efca3411e 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpCogInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpCogInstance.java @@ -5,13 +5,8 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.RotatingData; import com.simibubi.create.content.contraptions.base.SingleRotatingInstance; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; -import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderRegistry; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; -import net.minecraft.tileentity.TileEntityType; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; - public class PumpCogInstance extends SingleRotatingInstance { public PumpCogInstance(InstancedTileRenderer modelManager, KineticTileEntity tile) { diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/pipes/FluidValveInstance.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/pipes/FluidValveInstance.java index 8566a1a22..c21a668ae 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/pipes/FluidValveInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/pipes/FluidValveInstance.java @@ -37,7 +37,7 @@ public class FluidValveInstance extends ShaftInstance implements IDynamicInstanc boolean twist = pipeAxis.isHorizontal() && shaftAxis == Direction.Axis.Z || pipeAxis.isVertical(); pointerRotationOffset = twist ? 90 : 0; - pointer = modelManager.getBasicMaterial().getModel(AllBlockPartials.FLUID_VALVE_POINTER, blockState).createInstance(); + pointer = modelManager.transformMaterial().getModel(AllBlockPartials.FLUID_VALVE_POINTER, blockState).createInstance(); updateLight(); transformPointer((FluidValveTileEntity) tile); diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltVertexAttributes.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltAttributes.java similarity index 89% rename from src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltVertexAttributes.java rename to src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltAttributes.java index b5888c49b..4753f1eb2 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltVertexAttributes.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltAttributes.java @@ -5,7 +5,7 @@ import com.simibubi.create.foundation.render.backend.gl.attrib.IAttribSpec; import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib; import com.simibubi.create.foundation.render.backend.gl.attrib.VertexAttribSpec; -public enum BeltVertexAttributes implements IVertexAttrib { +public enum BeltAttributes implements IVertexAttrib { INSTANCE_ROTATION("aInstanceRot", CommonAttributes.QUATERNION), SOURCE_TEX("aSourceTexture", CommonAttributes.UV), SCROLL_TEX("aScrollTexture", CommonAttributes.VEC4), @@ -15,7 +15,7 @@ public enum BeltVertexAttributes implements IVertexAttrib { private final String name; private final VertexAttribSpec spec; - BeltVertexAttributes(String name, VertexAttribSpec spec) { + BeltAttributes(String name, VertexAttribSpec spec) { this.name = name; this.spec = spec; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltData.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltData.java index 610b71f4e..3ac819ab7 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltData.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltData.java @@ -3,20 +3,13 @@ package com.simibubi.create.content.contraptions.relays.belt; import java.nio.ByteBuffer; import com.simibubi.create.content.contraptions.base.KineticData; -import com.simibubi.create.content.contraptions.base.KineticVertexAttributes; import com.simibubi.create.foundation.block.render.SpriteShiftEntry; -import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; import net.minecraft.client.renderer.Quaternion; import net.minecraft.client.renderer.texture.TextureAtlasSprite; -public class BeltData extends KineticData { - public static VertexFormat FORMAT = VertexFormat.builder() - .addAttributes(KineticVertexAttributes.class) - .addAttributes(BeltVertexAttributes.class) - .build(); - +public class BeltData extends KineticData { private float qX; private float qY; private float qZ; diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstance.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstance.java index 273ff564a..7b06006f3 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstance.java @@ -160,14 +160,14 @@ public class BeltInstance extends KineticTileInstance { Quaternion q = new Quaternion(rotX, rotY, rotZ, true); key.getInstance() - .setTileEntity(tile) - .setBlockLight(world.getLightLevel(LightType.BLOCK, pos)) - .setSkyLight(world.getLightLevel(LightType.SKY, pos)) - .setRotation(q) - .setRotationalSpeed(getScrollSpeed()) - .setRotationOffset(bottom ? 0.5f : 0f) - .setScrollTexture(spriteShift) - .setScrollMult(diagonal ? 3f / 8f : 0.5f); + .setScrollTexture(spriteShift) + .setScrollMult(diagonal ? 3f / 8f : 0.5f) + .setRotation(q) + .setRotationalSpeed(getScrollSpeed()) + .setRotationOffset(bottom ? 0.5f : 0f) + .setTileEntity(tile) + .setBlockLight(world.getLightLevel(LightType.BLOCK, pos)) + .setSkyLight(world.getLightLevel(LightType.SKY, pos)); return key; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstancedModel.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstancedModel.java index 86e7e26ef..efbb86b44 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstancedModel.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstancedModel.java @@ -1,24 +1,32 @@ package com.simibubi.create.content.contraptions.relays.belt; +import com.simibubi.create.content.contraptions.base.KineticAttributes; import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; +import com.simibubi.create.foundation.render.backend.instancing.impl.BasicAttributes; import net.minecraft.client.renderer.BufferBuilder; public class BeltInstancedModel extends InstancedModel { - public BeltInstancedModel(InstancedTileRenderer renderer, BufferBuilder buf) { + public static VertexFormat FORMAT = VertexFormat.builder() + .addAttributes(BasicAttributes.class) + .addAttributes(KineticAttributes.class) + .addAttributes(BeltAttributes.class) + .build(); + + public BeltInstancedModel(InstancedTileRenderer renderer, BufferBuilder buf) { super(renderer, buf); } - @Override - protected BeltData newInstance() { + @Override + protected BeltData newInstance() { return new BeltData(this); } @Override - protected VertexFormat getInstanceFormat() { - return BeltData.FORMAT; + protected VertexFormat getInstanceFormat() { + return FORMAT; } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftInstance.java b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftInstance.java index 5ef3575ad..3c4272e1f 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftInstance.java @@ -53,7 +53,7 @@ public class SplitShaftInstance extends KineticTileInstance relight(pos, ((InstanceKey>) key).getInstance())); + keys.forEach(key -> relight(pos, ((InstanceKey) key).getInstance())); } @Override @@ -66,9 +66,9 @@ public class SplitShaftInstance extends KineticTileInstance dialModel = modelManager.getMaterial(RenderMaterials.MODELS).getModel(AllBlockPartials.GAUGE_DIAL, blockState); + InstancedModel dialModel = modelManager.getMaterial(RenderMaterials.TRANSFORMED).getModel(AllBlockPartials.GAUGE_DIAL, blockState); InstancedModel headModel = getHeadModel(); ms = new MatrixStack(); @@ -151,7 +151,7 @@ public abstract class GaugeInstance extends ShaftInstance implements IDynamicIns @Override protected InstancedModel getHeadModel() { - return modelManager.getMaterial(RenderMaterials.MODELS).getModel(AllBlockPartials.GAUGE_HEAD_SPEED, blockState); + return modelManager.getMaterial(RenderMaterials.TRANSFORMED).getModel(AllBlockPartials.GAUGE_HEAD_SPEED, blockState); } } @@ -162,7 +162,7 @@ public abstract class GaugeInstance extends ShaftInstance implements IDynamicIns @Override protected InstancedModel getHeadModel() { - return modelManager.getMaterial(RenderMaterials.MODELS).getModel(AllBlockPartials.GAUGE_HEAD_STRESS, blockState); + return modelManager.getMaterial(RenderMaterials.TRANSFORMED).getModel(AllBlockPartials.GAUGE_HEAD_STRESS, blockState); } } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxInstance.java b/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxInstance.java index 8f2e4fd99..836422301 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxInstance.java @@ -42,12 +42,12 @@ public class GearboxInstance extends KineticTileInstance { InstanceKey key = shaft.createInstance(); key.getInstance() - .setBlockLight(blockLight) - .setSkyLight(skyLight) - .setRotationalSpeed(getSpeed(direction)) - .setRotationOffset(getRotationOffset(axis)) - .setRotationAxis(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getUnitVector()) - .setTileEntity(tile); + .setRotationAxis(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getUnitVector()) + .setRotationalSpeed(getSpeed(direction)) + .setRotationOffset(getRotationOffset(axis)) + .setTileEntity(tile) + .setBlockLight(blockLight) + .setSkyLight(skyLight); keys.put(direction, key); } @@ -82,11 +82,11 @@ public class GearboxInstance extends KineticTileInstance { Direction.Axis axis = direction.getAxis(); key.getValue() - .getInstance() - .setColor(tile.network) - .setRotationalSpeed(getSpeed(direction)) - .setRotationOffset(getRotationOffset(axis)) - .setRotationAxis(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getUnitVector()); + .getInstance() + .setRotationAxis(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getUnitVector()) + .setRotationalSpeed(getSpeed(direction)) + .setRotationOffset(getRotationOffset(axis)) + .setColor(tile.network); } } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/FlapVertexAttributes.java b/src/main/java/com/simibubi/create/content/logistics/block/FlapAttributes.java similarity index 90% rename from src/main/java/com/simibubi/create/content/logistics/block/FlapVertexAttributes.java rename to src/main/java/com/simibubi/create/content/logistics/block/FlapAttributes.java index 6bf8a85d5..71a8db0af 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/FlapVertexAttributes.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/FlapAttributes.java @@ -5,7 +5,7 @@ import com.simibubi.create.foundation.render.backend.gl.attrib.IAttribSpec; import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib; import com.simibubi.create.foundation.render.backend.gl.attrib.VertexAttribSpec; -public enum FlapVertexAttributes implements IVertexAttrib { +public enum FlapAttributes implements IVertexAttrib { INSTANCE_POSITION("aInstancePos",CommonAttributes.VEC3), LIGHT("aLight", CommonAttributes.LIGHT), SEGMENT_OFFSET("aSegmentOffset", CommonAttributes.VEC3), @@ -19,7 +19,7 @@ public enum FlapVertexAttributes implements IVertexAttrib { private final String name; private final VertexAttribSpec spec; - FlapVertexAttributes(String name, VertexAttribSpec spec) { + FlapAttributes(String name, VertexAttribSpec spec) { this.name = name; this.spec = spec; } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/FlapData.java b/src/main/java/com/simibubi/create/content/logistics/block/FlapData.java index 841fd523b..3b6b6a5ac 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/FlapData.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/FlapData.java @@ -1,6 +1,5 @@ package com.simibubi.create.content.logistics.block; -import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat; import com.simibubi.create.foundation.render.backend.instancing.InstanceData; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; import com.simibubi.create.foundation.render.backend.instancing.impl.IFlatLight; @@ -11,115 +10,111 @@ import java.nio.ByteBuffer; public class FlapData extends InstanceData implements IFlatLight { - public static VertexFormat FORMAT = VertexFormat.builder() - .addAttributes(FlapVertexAttributes.class) - .build(); + private float x; + private float y; + private float z; + private byte blockLight; + private byte skyLight; - private float x; - private float y; - private float z; - private byte blockLight; - private byte skyLight; + private float segmentOffsetX; + private float segmentOffsetY; + private float segmentOffsetZ; - private float segmentOffsetX; - private float segmentOffsetY; - private float segmentOffsetZ; + private float pivotX; + private float pivotY; + private float pivotZ; - private float pivotX; - private float pivotY; - private float pivotZ; + private float horizontalAngle; + private float intensity; + private float flapScale; - private float horizontalAngle; - private float intensity; - private float flapScale; + private float flapness; - private float flapness; + public FlapData(InstancedModel owner) { + super(owner); + } - public FlapData(InstancedModel owner) { - super(owner); - } + public FlapData setPosition(BlockPos pos) { + return setPosition(pos.getX(), pos.getY(), pos.getZ()); + } - public FlapData setPosition(BlockPos pos) { - return setPosition(pos.getX(), pos.getY(), pos.getZ()); - } + public FlapData setPosition(Vector3f pos) { + return setPosition(pos.getX(), pos.getY(), pos.getZ()); + } - public FlapData setPosition(Vector3f pos) { - return setPosition(pos.getX(), pos.getY(), pos.getZ()); - } + public FlapData setPosition(int x, int y, int z) { + BlockPos origin = owner.renderer.getOriginCoordinate(); - public FlapData setPosition(int x, int y, int z) { - BlockPos origin = owner.renderer.getOriginCoordinate(); + return setPosition((float) (x - origin.getX()), + (float) (y - origin.getY()), + (float) (z - origin.getZ())); + } - return setPosition((float) (x - origin.getX()), - (float) (y - origin.getY()), - (float) (z - origin.getZ())); - } + public FlapData setPosition(float x, float y, float z) { + this.x = x; + this.y = y; + this.z = z; + return this; + } - public FlapData setPosition(float x, float y, float z) { - this.x = x; - this.y = y; - this.z = z; - return this; - } + @Override + public FlapData setBlockLight(int blockLight) { + this.blockLight = (byte) ((blockLight & 0xF) << 4); + return this; + } - @Override - public FlapData setBlockLight(int blockLight) { - this.blockLight = (byte) ((blockLight & 0xF) << 4); - return this; - } + @Override + public FlapData setSkyLight(int skyLight) { + this.skyLight = (byte) ((skyLight & 0xF) << 4); + return this; + } - @Override - public FlapData setSkyLight(int skyLight) { - this.skyLight = (byte) ((skyLight & 0xF) << 4); - return this; - } + public FlapData setSegmentOffset(float x, float y, float z) { + this.segmentOffsetX = x; + this.segmentOffsetY = y; + this.segmentOffsetZ = z; + return this; + } - public FlapData setSegmentOffset(float x, float y, float z) { - this.segmentOffsetX = x; - this.segmentOffsetY = y; - this.segmentOffsetZ = z; - return this; - } + public FlapData setIntensity(float intensity) { + this.intensity = intensity; + return this; + } - public FlapData setIntensity(float intensity) { - this.intensity = intensity; - return this; - } + public FlapData setHorizontalAngle(float horizontalAngle) { + this.horizontalAngle = horizontalAngle; + return this; + } - public FlapData setHorizontalAngle(float horizontalAngle) { - this.horizontalAngle = horizontalAngle; - return this; - } + public FlapData setFlapScale(float flapScale) { + this.flapScale = flapScale; + return this; + } - public FlapData setFlapScale(float flapScale) { - this.flapScale = flapScale; - return this; - } + public FlapData setFlapness(float flapness) { + this.flapness = flapness; + return this; + } - public FlapData setFlapness(float flapness) { - this.flapness = flapness; - return this; - } + public FlapData setPivotVoxelSpace(float x, float y, float z) { + pivotX = x / 16f; + pivotY = y / 16f; + pivotZ = z / 16f; + return this; + } - public FlapData setPivotVoxelSpace(float x, float y, float z) { - pivotX = x / 16f; - pivotY = y / 16f; - pivotZ = z / 16f; - return this; - } + @Override + public void write(ByteBuffer buf) { + putVec3(buf, x, y, z); + putVec2(buf, blockLight, skyLight); - @Override - public void write(ByteBuffer buf) { - putVec3(buf, x, y, z); - putVec2(buf, blockLight, skyLight); + putVec3(buf, segmentOffsetX, segmentOffsetY, segmentOffsetZ); + putVec3(buf, pivotX, pivotY, pivotZ); - putVec3(buf, segmentOffsetX, segmentOffsetY, segmentOffsetZ); - putVec3(buf, pivotX, pivotY, pivotZ); + put(buf, horizontalAngle); + put(buf, intensity); + put(buf, flapScale); - put(buf, horizontalAngle); - put(buf, intensity); - put(buf, flapScale); - - put(buf, flapness); - } + put(buf, flapness); + } } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/FlapInstancedModel.java b/src/main/java/com/simibubi/create/content/logistics/block/FlapInstancedModel.java deleted file mode 100644 index d9502bb4d..000000000 --- a/src/main/java/com/simibubi/create/content/logistics/block/FlapInstancedModel.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.simibubi.create.content.logistics.block; - -import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat; -import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; -import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; -import net.minecraft.client.renderer.BufferBuilder; - -public class FlapInstancedModel extends InstancedModel { - public FlapInstancedModel(InstancedTileRenderer renderer, BufferBuilder buf) { - super(renderer, buf); - } - - @Override - protected FlapData newInstance() { - return new FlapData(this); - } - - @Override - protected VertexFormat getInstanceFormat() { - return FlapData.FORMAT; - } -} diff --git a/src/main/java/com/simibubi/create/content/logistics/block/FlapModel.java b/src/main/java/com/simibubi/create/content/logistics/block/FlapModel.java new file mode 100644 index 000000000..fb4731bc7 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/logistics/block/FlapModel.java @@ -0,0 +1,26 @@ +package com.simibubi.create.content.logistics.block; + +import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat; +import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; +import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; +import net.minecraft.client.renderer.BufferBuilder; + +public class FlapModel extends InstancedModel { + public static VertexFormat FORMAT = VertexFormat.builder() + .addAttributes(FlapAttributes.class) + .build(); + + public FlapModel(InstancedTileRenderer renderer, BufferBuilder buf) { + super(renderer, buf); + } + + @Override + protected FlapData newInstance() { + return new FlapData(this); + } + + @Override + protected VertexFormat getInstanceFormat() { + return FORMAT; + } +} diff --git a/src/main/java/com/simibubi/create/content/logistics/block/diodes/AdjustableRepeaterInstance.java b/src/main/java/com/simibubi/create/content/logistics/block/diodes/AdjustableRepeaterInstance.java index b7c26136d..a0a6c33ea 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/diodes/AdjustableRepeaterInstance.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/diodes/AdjustableRepeaterInstance.java @@ -16,7 +16,7 @@ public class AdjustableRepeaterInstance extends TileEntityInstance modelManager, AdjustableRepeaterTileEntity tile) { super(modelManager, tile); - indicator = modelManager.getBasicMaterial().getModel(AllBlockPartials.FLEXPEATER_INDICATOR, blockState).createInstance(); + indicator = modelManager.transformMaterial().getModel(AllBlockPartials.FLEXPEATER_INDICATOR, blockState).createInstance(); MatrixStack ms = new MatrixStack(); MatrixStacker.of(ms).translate(getFloatingPos()); diff --git a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInstance.java b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInstance.java index 12fed5bfd..046e446a8 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInstance.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInstance.java @@ -24,135 +24,135 @@ import java.util.ArrayList; public class ArmInstance extends SingleRotatingInstance implements IDynamicInstance { - final InstanceKey base; - final InstanceKey lowerBody; - final InstanceKey upperBody; - final InstanceKey head; - final InstanceKey claw; - private final ArrayList> clawGrips; + final InstanceKey base; + final InstanceKey lowerBody; + final InstanceKey upperBody; + final InstanceKey head; + final InstanceKey claw; + private final ArrayList> clawGrips; - private final ArrayList> models; + private final ArrayList> models; - private boolean firstTick = true; + private boolean firstTick = true; - public ArmInstance(InstancedTileRenderer modelManager, KineticTileEntity tile) { - super(modelManager, tile); + public ArmInstance(InstancedTileRenderer modelManager, KineticTileEntity tile) { + super(modelManager, tile); - RenderMaterial> mat = modelManager.getMaterial(RenderMaterials.MODELS); + RenderMaterial> mat = modelManager.getMaterial(RenderMaterials.TRANSFORMED); - base = mat.getModel(AllBlockPartials.ARM_BASE, blockState).createInstance(); - lowerBody = mat.getModel(AllBlockPartials.ARM_LOWER_BODY, blockState).createInstance(); - upperBody = mat.getModel(AllBlockPartials.ARM_UPPER_BODY, blockState).createInstance(); - head = mat.getModel(AllBlockPartials.ARM_HEAD, blockState).createInstance(); - claw = mat.getModel(AllBlockPartials.ARM_CLAW_BASE, blockState).createInstance(); + base = mat.getModel(AllBlockPartials.ARM_BASE, blockState).createInstance(); + lowerBody = mat.getModel(AllBlockPartials.ARM_LOWER_BODY, blockState).createInstance(); + upperBody = mat.getModel(AllBlockPartials.ARM_UPPER_BODY, blockState).createInstance(); + head = mat.getModel(AllBlockPartials.ARM_HEAD, blockState).createInstance(); + claw = mat.getModel(AllBlockPartials.ARM_CLAW_BASE, blockState).createInstance(); - InstancedModel clawHalfModel = mat.getModel(AllBlockPartials.ARM_CLAW_GRIP, blockState); - InstanceKey clawGrip1 = clawHalfModel.createInstance(); - InstanceKey clawGrip2 = clawHalfModel.createInstance(); + InstancedModel clawHalfModel = mat.getModel(AllBlockPartials.ARM_CLAW_GRIP, blockState); + InstanceKey clawGrip1 = clawHalfModel.createInstance(); + InstanceKey clawGrip2 = clawHalfModel.createInstance(); - clawGrips = Lists.newArrayList(clawGrip1, clawGrip2); - models = Lists.newArrayList(base, lowerBody, upperBody, head, claw, clawGrip1, clawGrip2); + clawGrips = Lists.newArrayList(clawGrip1, clawGrip2); + models = Lists.newArrayList(base, lowerBody, upperBody, head, claw, clawGrip1, clawGrip2); - updateLight(); - } + updateLight(); + } - @Override - public void beginFrame() { - ArmTileEntity arm = (ArmTileEntity) tile; + @Override + public void beginFrame() { + ArmTileEntity arm = (ArmTileEntity) tile; - boolean settled = arm.baseAngle.settled() && arm.lowerArmAngle.settled() && arm.upperArmAngle.settled() && arm.headAngle.settled(); - boolean rave = arm.phase == ArmTileEntity.Phase.DANCING; + boolean settled = arm.baseAngle.settled() && arm.lowerArmAngle.settled() && arm.upperArmAngle.settled() && arm.headAngle.settled(); + boolean rave = arm.phase == ArmTileEntity.Phase.DANCING; - if (!settled || rave || firstTick) - transformModels(arm, rave); + if (!settled || rave || firstTick) + transformModels(arm, rave); - if (settled) - firstTick = false; - } + if (settled) + firstTick = false; + } - private void transformModels(ArmTileEntity arm, boolean rave) { - float pt = AnimationTickHolder.getPartialTicks(); - int color = 0xFFFFFF; + private void transformModels(ArmTileEntity arm, boolean rave) { + float pt = AnimationTickHolder.getPartialTicks(); + int color = 0xFFFFFF; - float baseAngle = arm.baseAngle.get(pt); - float lowerArmAngle = arm.lowerArmAngle.get(pt) - 135; - float upperArmAngle = arm.upperArmAngle.get(pt) - 90; - float headAngle = arm.headAngle.get(pt); + float baseAngle = arm.baseAngle.get(pt); + float lowerArmAngle = arm.lowerArmAngle.get(pt) - 135; + float upperArmAngle = arm.upperArmAngle.get(pt) - 90; + float headAngle = arm.headAngle.get(pt); - if (rave) { - float renderTick = AnimationTickHolder.getRenderTime(arm.getWorld()) + (tile.hashCode() % 64); - baseAngle = (renderTick * 10) % 360; - lowerArmAngle = MathHelper.lerp((MathHelper.sin(renderTick / 4) + 1) / 2, -45, 15); - upperArmAngle = MathHelper.lerp((MathHelper.sin(renderTick / 8) + 1) / 4, -45, 95); - headAngle = -lowerArmAngle; - color = ColorHelper.rainbowColor(AnimationTickHolder.getTicks() * 100); - } + if (rave) { + float renderTick = AnimationTickHolder.getRenderTime(arm.getWorld()) + (tile.hashCode() % 64); + baseAngle = (renderTick * 10) % 360; + lowerArmAngle = MathHelper.lerp((MathHelper.sin(renderTick / 4) + 1) / 2, -45, 15); + upperArmAngle = MathHelper.lerp((MathHelper.sin(renderTick / 8) + 1) / 4, -45, 95); + headAngle = -lowerArmAngle; + color = ColorHelper.rainbowColor(AnimationTickHolder.getTicks() * 100); + } - MatrixStack msLocal = new MatrixStack(); - MatrixStacker msr = MatrixStacker.of(msLocal); - msr.translate(getFloatingPos()); - msr.centre(); + MatrixStack msLocal = new MatrixStack(); + MatrixStacker msr = MatrixStacker.of(msLocal); + msr.translate(getFloatingPos()); + msr.centre(); - if (blockState.get(ArmBlock.CEILING)) - msr.rotateX(180); + if (blockState.get(ArmBlock.CEILING)) + msr.rotateX(180); - ArmRenderer.transformBase(msr, baseAngle); - base.getInstance() - .setTransform(msLocal); + ArmRenderer.transformBase(msr, baseAngle); + base.getInstance() + .setTransform(msLocal); - ArmRenderer.transformLowerArm(msr, lowerArmAngle); - lowerBody.getInstance() - .setColor(color) - .setTransform(msLocal); + ArmRenderer.transformLowerArm(msr, lowerArmAngle); + lowerBody.getInstance() + .setTransform(msLocal) + .setColor(color); - ArmRenderer.transformUpperArm(msr, upperArmAngle); - upperBody.getInstance() - .setColor(color) - .setTransform(msLocal); + ArmRenderer.transformUpperArm(msr, upperArmAngle); + upperBody.getInstance() + .setTransform(msLocal) + .setColor(color); - ArmRenderer.transformHead(msr, headAngle); - head.getInstance() - .setTransform(msLocal); + ArmRenderer.transformHead(msr, headAngle); + head.getInstance() + .setTransform(msLocal); - ArmRenderer.transformClaw(msr); - claw.getInstance() - .setTransform(msLocal); + ArmRenderer.transformClaw(msr); + claw.getInstance() + .setTransform(msLocal); - ItemStack item = arm.heldItem; - ItemRenderer itemRenderer = Minecraft.getInstance() - .getItemRenderer(); - boolean hasItem = !item.isEmpty(); - boolean isBlockItem = hasItem && (item.getItem() instanceof BlockItem) - && itemRenderer.getItemModelWithOverrides(item, Minecraft.getInstance().world, null) - .isGui3d(); + ItemStack item = arm.heldItem; + ItemRenderer itemRenderer = Minecraft.getInstance() + .getItemRenderer(); + boolean hasItem = !item.isEmpty(); + boolean isBlockItem = hasItem && (item.getItem() instanceof BlockItem) + && itemRenderer.getItemModelWithOverrides(item, Minecraft.getInstance().world, null) + .isGui3d(); - for (int index : Iterate.zeroAndOne) { - msLocal.push(); - int flip = index * 2 - 1; - ArmRenderer.transformClawHalf(msr, hasItem, isBlockItem, flip); - clawGrips.get(index) - .getInstance() - .setTransform(msLocal); - msLocal.pop(); - } - } + for (int index : Iterate.zeroAndOne) { + msLocal.push(); + int flip = index * 2 - 1; + ArmRenderer.transformClawHalf(msr, hasItem, isBlockItem, flip); + clawGrips.get(index) + .getInstance() + .setTransform(msLocal); + msLocal.pop(); + } + } - @Override - public void updateLight() { - super.updateLight(); + @Override + public void updateLight() { + super.updateLight(); - relight(pos, models.stream().map(InstanceKey::getInstance)); - } + relight(pos, models.stream().map(InstanceKey::getInstance)); + } - @Override - protected InstancedModel getModel() { - return AllBlockPartials.ARM_COG.renderOnRotating(modelManager, tile.getBlockState()); - } + @Override + protected InstancedModel getModel() { + return AllBlockPartials.ARM_COG.renderOnRotating(modelManager, tile.getBlockState()); + } - @Override - public void remove() { - super.remove(); - models.forEach(InstanceKey::delete); - } + @Override + public void remove() { + super.remove(); + models.forEach(InstanceKey::delete); + } } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/redstone/AnalogLeverInstance.java b/src/main/java/com/simibubi/create/content/logistics/block/redstone/AnalogLeverInstance.java index 4227837e8..78fffc5c5 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/redstone/AnalogLeverInstance.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/redstone/AnalogLeverInstance.java @@ -23,7 +23,7 @@ public class AnalogLeverInstance extends TileEntityInstance modelManager, AnalogLeverTileEntity tile) { super(modelManager, tile); - RenderMaterial> mat = modelManager.getMaterial(RenderMaterials.MODELS); + RenderMaterial> mat = modelManager.getMaterial(RenderMaterials.TRANSFORMED); handle = mat.getModel(AllBlockPartials.ANALOG_LEVER_HANDLE, blockState).createInstance(); indicator = mat.getModel(AllBlockPartials.ANALOG_LEVER_INDICATOR, blockState).createInstance(); @@ -62,7 +62,7 @@ public class AnalogLeverInstance extends TileEntityInstance modelManager, SchematicannonTileEntity tile) { super(modelManager, tile); - RenderMaterial> mat = modelManager.getMaterial(RenderMaterials.MODELS); + RenderMaterial> mat = modelManager.getMaterial(RenderMaterials.TRANSFORMED); connector = mat.getModel(AllBlockPartials.SCHEMATICANNON_CONNECTOR, blockState).createInstance(); pipe = mat.getModel(AllBlockPartials.SCHEMATICANNON_PIPE, blockState).createInstance(); @@ -54,7 +54,7 @@ public class SchematicannonInstance extends TileEntityInstance MODEL = register(ProgramSpec.builder("model", BasicProgram::new) - .addAttributes(ModelVertexAttributes.class) - .addAttributes(InstanceVertexAttributes.class) - .setVert(Locations.MODEL_VERT) - .setFrag(Locations.MODEL_FRAG) - .createProgramSpec()); + public static final ProgramSpec MODEL = register(ProgramSpec.builder("model", BasicProgram::new) + .addAttributes(ModelAttributes.class) + .addAttributes(BasicAttributes.class) + .addAttributes(TransformAttributes.class) + .setVert(Locations.MODEL_VERT) + .setFrag(Locations.MODEL_FRAG) + .createProgramSpec()); - public static final ProgramSpec ROTATING = register(ProgramSpec.builder("rotating", BasicProgram::new) - .addAttributes(ModelVertexAttributes.class) - .addAttributes(KineticVertexAttributes.class) - .addAttributes(RotatingVertexAttributes.class) - .setVert(Locations.ROTATING) - .setFrag(Locations.MODEL_FRAG) - .createProgramSpec()); + public static final ProgramSpec ORIENTED = register(ProgramSpec.builder("oriented", BasicProgram::new) + .addAttributes(ModelAttributes.class) + .addAttributes(BasicAttributes.class) + .addAttributes(OrientedAttributes.class) + .setVert(Locations.ORIENTED) + .setFrag(Locations.MODEL_FRAG) + .createProgramSpec()); - public static final ProgramSpec BELT = register(ProgramSpec.builder("belt", BasicProgram::new) - .addAttributes(ModelVertexAttributes.class) - .addAttributes(KineticVertexAttributes.class) - .addAttributes(BeltVertexAttributes.class) - .setVert(Locations.BELT) - .setFrag(Locations.MODEL_FRAG) - .createProgramSpec()); + public static final ProgramSpec ROTATING = register(ProgramSpec.builder("rotating", BasicProgram::new) + .addAttributes(ModelAttributes.class) + .addAttributes(BasicAttributes.class) + .addAttributes(KineticAttributes.class) + .addAttributes(RotatingAttributes.class) + .setVert(Locations.ROTATING) + .setFrag(Locations.MODEL_FRAG) + .createProgramSpec()); - public static final ProgramSpec FLAPS = register(ProgramSpec.builder("flap", BasicProgram::new) - .addAttributes(ModelVertexAttributes.class) - .addAttributes(FlapVertexAttributes.class) - .setVert(Locations.FLAP) - .setFrag(Locations.MODEL_FRAG) - .createProgramSpec()); - public static final ProgramSpec C_STRUCTURE = register(ProgramSpec.builder("contraption_structure", ContraptionProgram::new) - .addAttributes(ContraptionVertexAttributes.class) - .setVert(Locations.CONTRAPTION_STRUCTURE) - .setFrag(Locations.CONTRAPTION) - .createProgramSpec()); - public static final ProgramSpec C_MODEL = register(ProgramSpec.builder("contraption_model", ContraptionProgram::new) - .addAttributes(ModelVertexAttributes.class) - .addAttributes(InstanceVertexAttributes.class) - .setVert(Locations.MODEL_VERT) - .setFrag(Locations.CONTRAPTION) - .setDefines(ShaderConstants.define("CONTRAPTION")) - .createProgramSpec()); - public static final ProgramSpec C_ROTATING = register(ProgramSpec.builder("contraption_rotating", ContraptionProgram::new) - .addAttributes(ModelVertexAttributes.class) - .addAttributes(KineticVertexAttributes.class) - .addAttributes(RotatingVertexAttributes.class) - .setVert(Locations.ROTATING) - .setFrag(Locations.CONTRAPTION) - .setDefines(ShaderConstants.define("CONTRAPTION")) - .createProgramSpec()); - public static final ProgramSpec C_BELT = register(ProgramSpec.builder("contraption_belt", ContraptionProgram::new) - .addAttributes(ModelVertexAttributes.class) - .addAttributes(KineticVertexAttributes.class) - .addAttributes(BeltVertexAttributes.class) - .setVert(Locations.BELT) - .setFrag(Locations.CONTRAPTION) - .setDefines(ShaderConstants.define("CONTRAPTION")) - .createProgramSpec()); - public static final ProgramSpec C_FLAPS = register(ProgramSpec.builder("contraption_flap", ContraptionProgram::new) - .addAttributes(ModelVertexAttributes.class) - .addAttributes(FlapVertexAttributes.class) - .setVert(Locations.FLAP) - .setFrag(Locations.CONTRAPTION) - .setDefines(ShaderConstants.define("CONTRAPTION")) - .createProgramSpec()); - public static final ProgramSpec C_ACTOR = register(ProgramSpec.builder("contraption_actor", ContraptionProgram::new) - .addAttributes(ModelVertexAttributes.class) - .addAttributes(ActorVertexAttributes.class) - .setVert(Locations.CONTRAPTION_ACTOR) - .setFrag(Locations.CONTRAPTION) - .createProgramSpec()); + public static final ProgramSpec BELT = register(ProgramSpec.builder("belt", BasicProgram::new) + .addAttributes(ModelAttributes.class) + .addAttributes(BasicAttributes.class) + .addAttributes(KineticAttributes.class) + .addAttributes(BeltAttributes.class) + .setVert(Locations.BELT) + .setFrag(Locations.MODEL_FRAG) + .createProgramSpec()); + + public static final ProgramSpec FLAPS = register(ProgramSpec.builder("flap", BasicProgram::new) + .addAttributes(ModelAttributes.class) + .addAttributes(FlapAttributes.class) + .setVert(Locations.FLAP) + .setFrag(Locations.MODEL_FRAG) + .createProgramSpec()); + public static final ProgramSpec C_STRUCTURE = register(ProgramSpec.builder("contraption_structure", ContraptionProgram::new) + .addAttributes(ContraptionAttributes.class) + .setVert(Locations.CONTRAPTION_STRUCTURE) + .setFrag(Locations.CONTRAPTION) + .createProgramSpec()); + public static final ProgramSpec C_MODEL = register(ProgramSpec.builder("contraption_model", ContraptionProgram::new) + .addAttributes(ModelAttributes.class) + .addAttributes(BasicAttributes.class) + .addAttributes(TransformAttributes.class) + .setVert(Locations.MODEL_VERT) + .setFrag(Locations.CONTRAPTION) + .setDefines(ShaderConstants.define("CONTRAPTION")) + .createProgramSpec()); + public static final ProgramSpec C_ORIENTED = register(ProgramSpec.builder("contraption_oriented", ContraptionProgram::new) + .addAttributes(ModelAttributes.class) + .addAttributes(BasicAttributes.class) + .addAttributes(OrientedAttributes.class) + .setVert(Locations.ORIENTED) + .setFrag(Locations.CONTRAPTION) + .setDefines(ShaderConstants.define("CONTRAPTION")) + .createProgramSpec()); + public static final ProgramSpec C_ROTATING = register(ProgramSpec.builder("contraption_rotating", ContraptionProgram::new) + .addAttributes(ModelAttributes.class) + .addAttributes(BasicAttributes.class) + .addAttributes(KineticAttributes.class) + .addAttributes(RotatingAttributes.class) + .setVert(Locations.ROTATING) + .setFrag(Locations.CONTRAPTION) + .setDefines(ShaderConstants.define("CONTRAPTION")) + .createProgramSpec()); + public static final ProgramSpec C_BELT = register(ProgramSpec.builder("contraption_belt", ContraptionProgram::new) + .addAttributes(ModelAttributes.class) + .addAttributes(BasicAttributes.class) + .addAttributes(KineticAttributes.class) + .addAttributes(BeltAttributes.class) + .setVert(Locations.BELT) + .setFrag(Locations.CONTRAPTION) + .setDefines(ShaderConstants.define("CONTRAPTION")) + .createProgramSpec()); + public static final ProgramSpec C_FLAPS = register(ProgramSpec.builder("contraption_flap", ContraptionProgram::new) + .addAttributes(ModelAttributes.class) + .addAttributes(FlapAttributes.class) + .setVert(Locations.FLAP) + .setFrag(Locations.CONTRAPTION) + .setDefines(ShaderConstants.define("CONTRAPTION")) + .createProgramSpec()); + public static final ProgramSpec C_ACTOR = register(ProgramSpec.builder("contraption_actor", ContraptionProgram::new) + .addAttributes(ModelAttributes.class) + .addAttributes(ActorVertexAttributes.class) + .setVert(Locations.CONTRAPTION_ACTOR) + .setFrag(Locations.CONTRAPTION) + .createProgramSpec()); - public static class Locations { - public static final ResourceLocation MODEL_FRAG = loc("model.frag"); - public static final ResourceLocation MODEL_VERT = loc("model.vert"); - public static final ResourceLocation CONTRAPTION = loc("contraption.frag"); + public static class Locations { + public static final ResourceLocation MODEL_FRAG = loc("model.frag"); + public static final ResourceLocation MODEL_VERT = loc("model.vert"); + public static final ResourceLocation ORIENTED = loc("oriented.vert"); + public static final ResourceLocation CONTRAPTION = loc("contraption.frag"); - public static final ResourceLocation ROTATING = loc("rotating.vert"); - public static final ResourceLocation BELT = loc("belt.vert"); - public static final ResourceLocation FLAP = loc("flap.vert"); - public static final ResourceLocation CONTRAPTION_STRUCTURE = loc("contraption_structure.vert"); - public static final ResourceLocation CONTRAPTION_ACTOR = loc("contraption_actor.vert"); + public static final ResourceLocation ROTATING = loc("rotating.vert"); + public static final ResourceLocation BELT = loc("belt.vert"); + public static final ResourceLocation FLAP = loc("flap.vert"); + public static final ResourceLocation CONTRAPTION_STRUCTURE = loc("contraption_structure.vert"); + public static final ResourceLocation CONTRAPTION_ACTOR = loc("contraption_actor.vert"); - private static ResourceLocation loc(String name) { - return new ResourceLocation(Create.ID, name); - } - } + private static ResourceLocation loc(String name) { + return new ResourceLocation(Create.ID, name); + } + } } diff --git a/src/main/java/com/simibubi/create/foundation/render/KineticRenderer.java b/src/main/java/com/simibubi/create/foundation/render/KineticRenderer.java index d41890d0d..e02db4d54 100644 --- a/src/main/java/com/simibubi/create/foundation/render/KineticRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/render/KineticRenderer.java @@ -3,20 +3,20 @@ package com.simibubi.create.foundation.render; import java.util.ArrayList; import com.simibubi.create.content.contraptions.base.KineticRenderMaterials; -import com.simibubi.create.content.contraptions.base.RotatingInstancedModel; +import com.simibubi.create.content.contraptions.base.RotatingModel; import com.simibubi.create.content.contraptions.relays.belt.BeltInstancedModel; -import com.simibubi.create.content.logistics.block.FlapInstancedModel; +import com.simibubi.create.content.logistics.block.FlapModel; import com.simibubi.create.foundation.render.backend.RenderMaterials; import com.simibubi.create.foundation.render.backend.gl.BasicProgram; import com.simibubi.create.foundation.render.backend.gl.shader.ShaderCallback; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial; -import com.simibubi.create.foundation.render.backend.instancing.impl.BasicInstancedModel; -import net.minecraft.client.Minecraft; +import com.simibubi.create.foundation.render.backend.instancing.impl.OrientedModel; +import com.simibubi.create.foundation.render.backend.instancing.impl.TransformedModel; + import net.minecraft.client.renderer.Matrix4f; import net.minecraft.client.renderer.RenderType; -import net.minecraft.entity.Entity; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; @@ -28,11 +28,12 @@ public class KineticRenderer extends InstancedTileRenderer { @Override public void registerMaterials() { - materials.put(RenderMaterials.MODELS, new RenderMaterial<>(this, AllProgramSpecs.MODEL, BasicInstancedModel::new)); + materials.put(RenderMaterials.TRANSFORMED, new RenderMaterial<>(this, AllProgramSpecs.MODEL, TransformedModel::new)); + materials.put(RenderMaterials.ORIENTED, new RenderMaterial<>(this, AllProgramSpecs.ORIENTED, OrientedModel::new)); materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(this, AllProgramSpecs.BELT, BeltInstancedModel::new)); - materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(this, AllProgramSpecs.ROTATING, RotatingInstancedModel::new)); - materials.put(KineticRenderMaterials.FLAPS, new RenderMaterial<>(this, AllProgramSpecs.FLAPS, FlapInstancedModel::new)); + materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(this, AllProgramSpecs.ROTATING, RotatingModel::new)); + materials.put(KineticRenderMaterials.FLAPS, new RenderMaterial<>(this, AllProgramSpecs.FLAPS, FlapModel::new)); } @Override diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/RenderMaterials.java b/src/main/java/com/simibubi/create/foundation/render/backend/RenderMaterials.java index b1a09fc0a..927b81601 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/RenderMaterials.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/RenderMaterials.java @@ -3,7 +3,9 @@ package com.simibubi.create.foundation.render.backend; import com.simibubi.create.foundation.render.backend.instancing.MaterialType; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData; +import com.simibubi.create.foundation.render.backend.instancing.impl.OrientedData; public class RenderMaterials { - public static final MaterialType> MODELS = new MaterialType<>(); + public static final MaterialType> TRANSFORMED = new MaterialType<>(); + public static final MaterialType> ORIENTED = new MaterialType<>(); } diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/RenderUtil.java b/src/main/java/com/simibubi/create/foundation/render/backend/RenderUtil.java index b0de2dea6..e5ee528c2 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/RenderUtil.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/RenderUtil.java @@ -7,50 +7,45 @@ import java.nio.ByteBuffer; import java.nio.FloatBuffer; public class RenderUtil { - public static int nextPowerOf2(int a) { - int h = Integer.highestOneBit(a); - return (h == a) ? h : (h << 1); - } + public static int nextPowerOf2(int a) { + int h = Integer.highestOneBit(a); + return (h == a) ? h : (h << 1); + } - public static boolean isPowerOf2(int n) { - int b = n & (n - 1); - return b == 0 && n != 0; - } + public static boolean isPowerOf2(int n) { + int b = n & (n - 1); + return b == 0 && n != 0; + } - // GPUs want matrices in column major order. + // GPUs want matrices in column major order. - public static void writeMat3(ByteBuffer buf, Matrix3f mat) { - buf.putFloat(mat.a00); - buf.putFloat(mat.a10); - buf.putFloat(mat.a20); - buf.putFloat(mat.a01); - buf.putFloat(mat.a11); - buf.putFloat(mat.a21); - buf.putFloat(mat.a02); - buf.putFloat(mat.a12); - buf.putFloat(mat.a22); - } - - public static void writeMat4(ByteBuffer buf, Matrix4f mat) { - buf.putFloat(mat.a00); - buf.putFloat(mat.a10); - buf.putFloat(mat.a20); - buf.putFloat(mat.a30); - buf.putFloat(mat.a01); - buf.putFloat(mat.a11); - buf.putFloat(mat.a21); - buf.putFloat(mat.a31); - buf.putFloat(mat.a02); - buf.putFloat(mat.a12); - buf.putFloat(mat.a22); - buf.putFloat(mat.a32); - buf.putFloat(mat.a03); - buf.putFloat(mat.a13); - buf.putFloat(mat.a23); - buf.putFloat(mat.a33); - - - - - } + public static float[] bufferMatrices(Matrix4f model, Matrix3f normal) { + return new float[] { + model.a00, + model.a10, + model.a20, + model.a30, + model.a01, + model.a11, + model.a21, + model.a31, + model.a02, + model.a12, + model.a22, + model.a32, + model.a03, + model.a13, + model.a23, + model.a33, + normal.a00, + normal.a10, + normal.a20, + normal.a01, + normal.a11, + normal.a21, + normal.a02, + normal.a12, + normal.a22, + }; + } } diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/ModelVertexAttributes.java b/src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/ModelVertexAttributes.java deleted file mode 100644 index 5fec24349..000000000 --- a/src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/ModelVertexAttributes.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.simibubi.create.foundation.render.backend.gl.attrib; - -public enum ModelVertexAttributes implements IVertexAttrib { - VERTEX_POSITION("aPos", CommonAttributes.VEC3), - NORMAL("aNormal", CommonAttributes.NORMAL), - TEXTURE("aTexCoords", CommonAttributes.UV), - ; - - private final String name; - private final VertexAttribSpec spec; - - ModelVertexAttributes(String name, VertexAttribSpec spec) { - this.name = name; - this.spec = spec; - } - - @Override - public String attribName() { - return name; - } - - @Override - public IAttribSpec attribSpec() { - return spec; - } - - @Override - public int getDivisor() { - return 0; - } - - @Override - public int getBufferIndex() { - return 0; - } -} diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstanceKey.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstanceKey.java index 6a3ec6d1e..9927128c2 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstanceKey.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstanceKey.java @@ -1,7 +1,5 @@ package com.simibubi.create.foundation.render.backend.instancing; -import java.util.function.Consumer; - public class InstanceKey { public static final int INVALID = -1; diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedModel.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedModel.java index b3f6aa49e..2cefbb58a 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedModel.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedModel.java @@ -3,7 +3,6 @@ package com.simibubi.create.foundation.render.backend.instancing; import java.nio.ByteBuffer; import java.util.*; -import java.util.function.Consumer; import com.simibubi.create.foundation.render.backend.Backend; import com.simibubi.create.foundation.render.backend.RenderUtil; @@ -14,13 +13,13 @@ import org.lwjgl.opengl.GL20; import com.simibubi.create.foundation.render.backend.BufferedModel; import com.simibubi.create.foundation.render.backend.gl.GlBuffer; import com.simibubi.create.foundation.render.backend.gl.GlVertexArray; -import com.simibubi.create.foundation.render.backend.gl.attrib.ModelVertexAttributes; +import com.simibubi.create.foundation.render.backend.instancing.impl.ModelAttributes; import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat; import net.minecraft.client.renderer.BufferBuilder; public abstract class InstancedModel extends BufferedModel { - public static final VertexFormat FORMAT = VertexFormat.builder().addAttributes(ModelVertexAttributes.class).build(); + public static final VertexFormat FORMAT = VertexFormat.builder().addAttributes(ModelAttributes.class).build(); public final InstancedTileRenderer renderer; diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java index 5d31998f5..74bda0057 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/InstancedTileRenderer.java @@ -9,6 +9,7 @@ import com.simibubi.create.foundation.render.backend.RenderMaterials; import com.simibubi.create.foundation.render.backend.gl.BasicProgram; import com.simibubi.create.foundation.render.backend.gl.shader.ShaderCallback; import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData; +import com.simibubi.create.foundation.render.backend.instancing.impl.OrientedData; import com.simibubi.create.foundation.utility.AnimationTickHolder; import net.minecraft.client.Minecraft; @@ -52,7 +53,7 @@ public abstract class InstancedTileRenderer

{ public void beginFrame(double cameraX, double cameraY, double cameraZ) { if (queuedAdditions.size() > 0) { - queuedAdditions.forEach(this::add); + queuedAdditions.forEach(this::addInternal); queuedAdditions.clear(); } if (dynamicInstances.size() > 0) @@ -75,33 +76,25 @@ public abstract class InstancedTileRenderer

{ return (RenderMaterial) materials.get(materialType); } - public RenderMaterial> getBasicMaterial() { - return getMaterial(RenderMaterials.MODELS); + public RenderMaterial> transformMaterial() { + return getMaterial(RenderMaterials.TRANSFORMED); + } + + public RenderMaterial> orientedMaterial() { + return getMaterial(RenderMaterials.ORIENTED); } @SuppressWarnings("unchecked") @Nullable public TileEntityInstance getInstance(T tile, boolean create) { - if (!Backend.canUseInstancing() || !canCreateInstance(tile)) return null; + if (!Backend.canUseInstancing()) return null; TileEntityInstance instance = instances.get(tile); if (instance != null) { return (TileEntityInstance) instance; - } else if (create) { - TileEntityInstance renderer = InstancedTileRenderRegistry.instance.create(this, tile); - - if (renderer != null) { - instances.put(tile, renderer); - - if (renderer instanceof IDynamicInstance) - dynamicInstances.put(tile, (IDynamicInstance) renderer); - - if (renderer instanceof ITickableInstance) - tickableInstances.put(tile, ((ITickableInstance) renderer)); - } - - return renderer; + } else if (create && canCreateInstance(tile)) { + return createInternal(tile); } else { return null; } @@ -122,7 +115,7 @@ public abstract class InstancedTileRenderer

{ if (!Backend.canUseInstancing()) return; if (tile instanceof IInstanceRendered) { - getInstance(tile, true); + addInternal(tile); } } @@ -143,7 +136,7 @@ public abstract class InstancedTileRenderer

{ if (instance.shouldReset()) { removeInternal(tile, instance); - getInstance(tile, true); + createInternal(tile); } else { instance.update(); } @@ -159,6 +152,10 @@ public abstract class InstancedTileRenderer

{ } } + private void addInternal(TileEntity tile) { + getInstance(tile, true); + } + private void removeInternal(T tile) { TileEntityInstance instance = getInstance(tile, false); @@ -167,14 +164,30 @@ public abstract class InstancedTileRenderer

{ } } - private void removeInternal(T tile, TileEntityInstance instance) { + private void removeInternal(TileEntity tile, TileEntityInstance instance) { instance.remove(); instances.remove(tile); dynamicInstances.remove(tile); tickableInstances.remove(tile); } - public void clean() { + private TileEntityInstance createInternal(T tile) { + TileEntityInstance renderer = InstancedTileRenderRegistry.instance.create(this, tile); + + if (renderer != null) { + instances.put(tile, renderer); + + if (renderer instanceof IDynamicInstance) + dynamicInstances.put(tile, (IDynamicInstance) renderer); + + if (renderer instanceof ITickableInstance) + tickableInstances.put(tile, ((ITickableInstance) renderer)); + } + + return renderer; + } + + private void clean() { instances.keySet().removeIf(TileEntity::isRemoved); } diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/MaterialType.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/MaterialType.java index 48ade4b2a..bda912737 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/MaterialType.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/MaterialType.java @@ -1,3 +1,10 @@ package com.simibubi.create.foundation.render.backend.instancing; -public class MaterialType { } +import com.simibubi.create.foundation.render.backend.gl.BasicProgram; + +public class MaterialType> { + + public

RenderMaterial get(InstancedTileRenderer

renderer) { + return renderer.getMaterial(this); + } +} diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/BasicAttributes.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/BasicAttributes.java new file mode 100644 index 000000000..0223037a7 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/BasicAttributes.java @@ -0,0 +1,39 @@ +package com.simibubi.create.foundation.render.backend.instancing.impl; + +import com.simibubi.create.foundation.render.backend.gl.attrib.CommonAttributes; +import com.simibubi.create.foundation.render.backend.gl.attrib.IAttribSpec; +import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib; + +public enum BasicAttributes implements IVertexAttrib { + LIGHT("aLight", CommonAttributes.LIGHT), + COLOR("aColor", CommonAttributes.RGBA), + ; + + private final String name; + private final IAttribSpec spec; + + BasicAttributes(String name, IAttribSpec spec) { + this.name = name; + this.spec = spec; + } + + @Override + public String attribName() { + return name; + } + + @Override + public IAttribSpec attribSpec() { + return spec; + } + + @Override + public int getDivisor() { + return 0; + } + + @Override + public int getBufferIndex() { + return 0; + } +} diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/BasicData.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/BasicData.java new file mode 100644 index 000000000..38fba8424 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/BasicData.java @@ -0,0 +1,73 @@ +package com.simibubi.create.foundation.render.backend.instancing.impl; + +import java.nio.ByteBuffer; +import com.simibubi.create.foundation.render.backend.instancing.InstanceData; +import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; + +public class BasicData extends InstanceData implements IFlatLight { + + protected byte blockLight; + protected byte skyLight; + + protected byte r = (byte) 0xFF; + protected byte g = (byte) 0xFF; + protected byte b = (byte) 0xFF; + protected byte a = (byte) 0xFF; + + public BasicData(InstancedModel owner) { + super(owner); + } + + @Override + public BasicData setBlockLight(int blockLight) { + this.blockLight = (byte) (blockLight << 4); + return this; + } + + @Override + public BasicData setSkyLight(int skyLight) { + this.skyLight = (byte) (skyLight << 4); + return this; + } + + public BasicData setColor(int color) { + return setColor(color, false); + } + + public BasicData setColor(int color, boolean alpha) { + byte r = (byte) ((color >> 16) & 0xFF); + byte g = (byte) ((color >> 8) & 0xFF); + byte b = (byte) (color & 0xFF); + + if (alpha) { + byte a = (byte) ((color >> 24) & 0xFF); + return setColor(r, g, b, a); + } else { + return setColor(r, g, b); + } + } + + public BasicData setColor(int r, int g, int b) { + return setColor((byte) r, (byte) g, (byte) b); + } + + public BasicData setColor(byte r, byte g, byte b) { + this.r = r; + this.g = g; + this.b = b; + return this; + } + + public BasicData setColor(byte r, byte g, byte b, byte a) { + this.r = r; + this.g = g; + this.b = b; + this.a = a; + return this; + } + + @Override + public void write(ByteBuffer buf) { + buf.put(new byte[] { blockLight, skyLight, r, g, b, a }); + } +} diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/ModelAttributes.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/ModelAttributes.java new file mode 100644 index 000000000..8854f3550 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/ModelAttributes.java @@ -0,0 +1,41 @@ +package com.simibubi.create.foundation.render.backend.instancing.impl; + +import com.simibubi.create.foundation.render.backend.gl.attrib.CommonAttributes; +import com.simibubi.create.foundation.render.backend.gl.attrib.IAttribSpec; +import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib; +import com.simibubi.create.foundation.render.backend.gl.attrib.VertexAttribSpec; + +public enum ModelAttributes implements IVertexAttrib { + VERTEX_POSITION("aPos", CommonAttributes.VEC3), + NORMAL("aNormal", CommonAttributes.NORMAL), + TEXTURE("aTexCoords", CommonAttributes.UV), + ; + + private final String name; + private final VertexAttribSpec spec; + + ModelAttributes(String name, VertexAttribSpec spec) { + this.name = name; + this.spec = spec; + } + + @Override + public String attribName() { + return name; + } + + @Override + public IAttribSpec attribSpec() { + return spec; + } + + @Override + public int getDivisor() { + return 0; + } + + @Override + public int getBufferIndex() { + return 0; + } +} diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/ModelData.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/ModelData.java index 4b0a93a9a..170d555a7 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/ModelData.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/ModelData.java @@ -2,101 +2,28 @@ package com.simibubi.create.foundation.render.backend.instancing.impl; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.foundation.render.backend.RenderUtil; -import com.simibubi.create.foundation.render.backend.instancing.InstanceData; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; -import net.minecraft.client.renderer.Matrix3f; -import net.minecraft.client.renderer.Matrix4f; import java.nio.ByteBuffer; -public class ModelData extends InstanceData implements IFlatLight { - private static final Matrix4f IDENT4 = new Matrix4f(); - private static final Matrix3f IDENT3 = new Matrix3f(); - static { - IDENT4.loadIdentity(); - IDENT3.loadIdentity(); - } +public class ModelData extends BasicData { + private static final float[] empty = new float[25]; - private Matrix4f modelMat = IDENT4; - private Matrix3f normalMat = IDENT3; - - private byte blockLight; - private byte skyLight; - - private byte r = (byte) 0xFF; - private byte g = (byte) 0xFF; - private byte b = (byte) 0xFF; - private byte a = (byte) 0xFF; + private float[] matrices = empty; public ModelData(InstancedModel owner) { super(owner); } - public ModelData setModelMat(Matrix4f modelMat) { - this.modelMat = modelMat; - return this; - } - - public ModelData setNormalMat(Matrix3f normalMat) { - this.normalMat = normalMat; - return this; - } - public ModelData setTransform(MatrixStack stack) { - this.modelMat = stack.peek().getModel().copy(); - this.normalMat = stack.peek().getNormal().copy(); - return this; - } - - public ModelData setTransformNoCopy(MatrixStack stack) { - this.modelMat = stack.peek().getModel(); - this.normalMat = stack.peek().getNormal(); - return this; - } - - @Override - public ModelData setBlockLight(int blockLight) { - this.blockLight = (byte) (blockLight << 4); - return this; - } - - @Override - public ModelData setSkyLight(int skyLight) { - this.skyLight = (byte) (skyLight << 4); - return this; - } - - public ModelData setColor(int color) { - byte a = (byte) ((color >> 24) & 0xFF); - byte r = (byte) ((color >> 16) & 0xFF); - byte g = (byte) ((color >> 8) & 0xFF); - byte b = (byte) (color & 0xFF); - return setColor(r, g, b); - } - - public ModelData setColor(int r, int g, int b) { - return setColor((byte) r, (byte) g, (byte) b); - } - - public ModelData setColor(byte r, byte g, byte b) { - this.r = r; - this.g = g; - this.b = b; - return this; - } - - public ModelData setColor(byte r, byte g, byte b, byte a) { - this.r = r; - this.g = g; - this.b = b; - this.a = a; + matrices = RenderUtil.bufferMatrices(stack.peek().getModel(), stack.peek().getNormal()); return this; } @Override public void write(ByteBuffer buf) { - RenderUtil.writeMat4(buf, modelMat); - RenderUtil.writeMat3(buf, normalMat); - buf.put(new byte[] { blockLight, skyLight, r, g, b, a }); + super.write(buf); + buf.asFloatBuffer().put(matrices); + buf.position(buf.position() + matrices.length * 4); } } diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/OrientedAttributes.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/OrientedAttributes.java new file mode 100644 index 000000000..a5a7cef0d --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/OrientedAttributes.java @@ -0,0 +1,40 @@ +package com.simibubi.create.foundation.render.backend.instancing.impl; + +import com.simibubi.create.foundation.render.backend.gl.attrib.CommonAttributes; +import com.simibubi.create.foundation.render.backend.gl.attrib.IAttribSpec; +import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib; + +public enum OrientedAttributes implements IVertexAttrib { + INSTANCE_POS("aInstancePos", CommonAttributes.VEC3), + PIVOT("aPivot", CommonAttributes.VEC3), + ROTATION("aRotation", CommonAttributes.QUATERNION), + ; + + private final String name; + private final IAttribSpec spec; + + OrientedAttributes(String name, IAttribSpec spec) { + this.name = name; + this.spec = spec; + } + + @Override + public String attribName() { + return name; + } + + @Override + public IAttribSpec attribSpec() { + return spec; + } + + @Override + public int getDivisor() { + return 0; + } + + @Override + public int getBufferIndex() { + return 0; + } +} diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/OrientedData.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/OrientedData.java new file mode 100644 index 000000000..97a741182 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/OrientedData.java @@ -0,0 +1,107 @@ +package com.simibubi.create.foundation.render.backend.instancing.impl; + +import net.minecraft.client.renderer.Quaternion; +import net.minecraft.client.renderer.Vector3f; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; + +import java.nio.ByteBuffer; +import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; + +public class OrientedData extends BasicData { + + private float posX; + private float posY; + private float posZ; + private float pivotX = 0.5f; + private float pivotY = 0.5f; + private float pivotZ = 0.5f; + private float qX; + private float qY; + private float qZ; + private float qW; + + + public OrientedData(InstancedModel owner) { + super(owner); + } + + + public OrientedData setPosition(BlockPos pos) { + return setPosition(pos.getX(), pos.getY(), pos.getZ()); + } + + public OrientedData setPosition(Vector3f pos) { + return setPosition(pos.getX(), pos.getY(), pos.getZ()); + } + + public OrientedData setPosition(int x, int y, int z) { + BlockPos origin = owner.renderer.getOriginCoordinate(); + + return setPosition((float) (x - origin.getX()), + (float) (y - origin.getY()), + (float) (z - origin.getZ())); + } + + public OrientedData setPosition(float x, float y, float z) { + this.posX = x; + this.posY = y; + this.posZ = z; + return this; + } + + public OrientedData nudge(float x, float y, float z) { + this.posX += x; + this.posY += y; + this.posZ += z; + return this; + } + + public OrientedData setPivot(Vector3f pos) { + return setPosition(pos.getX(), pos.getY(), pos.getZ()); + } + + public OrientedData setPivot(Vec3d pos) { + return setPosition((float) pos.getX(), (float) pos.getY(), (float) pos.getZ()); + } + + public OrientedData setPivot(float x, float y, float z) { + this.pivotX = x; + this.pivotY = y; + this.pivotZ = z; + return this; + } + + public OrientedData setRotation(Quaternion q) { + return setRotation(q.getX(), q.getY(), q.getZ(), q.getW()); + } + + public OrientedData setRotation(float x, float y, float z, float w) { + this.qX = x; + this.qY = y; + this.qZ = z; + this.qW = w; + return this; + } + + @Override + public void write(ByteBuffer buf) { + super.write(buf); + + buf.asFloatBuffer().put(new float[] { + posX, + posY, + posZ, + pivotX, + pivotY, + pivotZ, + qX, + qY, + qZ, + qW + }); + + buf.position(buf.position() + 10 * 4); + } +} + diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/OrientedModel.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/OrientedModel.java new file mode 100644 index 000000000..0389d119c --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/OrientedModel.java @@ -0,0 +1,28 @@ +package com.simibubi.create.foundation.render.backend.instancing.impl; + +import net.minecraft.client.renderer.BufferBuilder; + +import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat; +import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; +import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; + +public class OrientedModel extends InstancedModel { + public static final VertexFormat INSTANCE_FORMAT = VertexFormat.builder() + .addAttributes(BasicAttributes.class) + .addAttributes(OrientedAttributes.class) + .build(); + + public OrientedModel(InstancedTileRenderer renderer, BufferBuilder buf) { + super(renderer, buf); + } + + @Override + protected OrientedData newInstance() { + return new OrientedData(this); + } + + @Override + protected VertexFormat getInstanceFormat() { + return INSTANCE_FORMAT; + } +} diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/InstanceVertexAttributes.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/TransformAttributes.java similarity index 56% rename from src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/InstanceVertexAttributes.java rename to src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/TransformAttributes.java index dacecf161..31daa9542 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/gl/attrib/InstanceVertexAttributes.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/TransformAttributes.java @@ -1,16 +1,18 @@ -package com.simibubi.create.foundation.render.backend.gl.attrib; +package com.simibubi.create.foundation.render.backend.instancing.impl; -public enum InstanceVertexAttributes implements IVertexAttrib { +import com.simibubi.create.foundation.render.backend.gl.attrib.IAttribSpec; +import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib; +import com.simibubi.create.foundation.render.backend.gl.attrib.MatrixAttributes; + +public enum TransformAttributes implements IVertexAttrib { TRANSFORM("aTransform", MatrixAttributes.MAT4), NORMAL_MAT("aNormalMat", MatrixAttributes.MAT3), - LIGHT("aLight", CommonAttributes.LIGHT), - COLOR("aColor", CommonAttributes.RGBA), ; private final String name; private final IAttribSpec spec; - InstanceVertexAttributes(String name, IAttribSpec spec) { + TransformAttributes(String name, IAttribSpec spec) { this.name = name; this.spec = spec; } diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/BasicInstancedModel.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/TransformedModel.java similarity index 68% rename from src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/BasicInstancedModel.java rename to src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/TransformedModel.java index cd67de720..27fef7d04 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/BasicInstancedModel.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/impl/TransformedModel.java @@ -1,15 +1,17 @@ package com.simibubi.create.foundation.render.backend.instancing.impl; -import com.simibubi.create.foundation.render.backend.gl.attrib.InstanceVertexAttributes; import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; import net.minecraft.client.renderer.BufferBuilder; -public class BasicInstancedModel extends InstancedModel { - public static final VertexFormat INSTANCE_FORMAT = VertexFormat.builder().addAttributes(InstanceVertexAttributes.class).build(); +public class TransformedModel extends InstancedModel { + public static final VertexFormat INSTANCE_FORMAT = VertexFormat.builder() + .addAttributes(BasicAttributes.class) + .addAttributes(TransformAttributes.class) + .build(); - public BasicInstancedModel(InstancedTileRenderer renderer, BufferBuilder buf) { + public TransformedModel(InstancedTileRenderer renderer, BufferBuilder buf) { super(renderer, buf); } diff --git a/src/main/resources/assets/create/flywheel/shaders/belt.vert b/src/main/resources/assets/create/flywheel/shaders/belt.vert index 08e776ef6..3a5fefcec 100644 --- a/src/main/resources/assets/create/flywheel/shaders/belt.vert +++ b/src/main/resources/assets/create/flywheel/shaders/belt.vert @@ -9,9 +9,9 @@ attribute vec3 aPos; attribute vec3 aNormal; attribute vec2 aTexCoords; -attribute vec3 aInstancePos; attribute vec2 aLight; -attribute vec3 aNetworkTint; +attribute vec4 aColor; +attribute vec3 aInstancePos; attribute float aSpeed; attribute float aOffset; attribute vec4 aInstanceRot; @@ -77,7 +77,7 @@ void main() { } #else if (uDebug == 1) { - Color = vec4(aNetworkTint, 1.); + Color = aColor; } else if (uDebug == 2) { Color = vec4(norm, 1.); } else { diff --git a/src/main/resources/assets/create/flywheel/shaders/model.vert b/src/main/resources/assets/create/flywheel/shaders/model.vert index 9767a122c..ea4503b75 100644 --- a/src/main/resources/assets/create/flywheel/shaders/model.vert +++ b/src/main/resources/assets/create/flywheel/shaders/model.vert @@ -7,10 +7,10 @@ attribute vec3 aPos; attribute vec3 aNormal; attribute vec2 aTexCoords; -attribute mat4 aTransform; -attribute mat3 aNormalMat; attribute vec2 aLight; attribute vec4 aColor; +attribute mat4 aTransform; +attribute mat3 aNormalMat; varying vec2 TexCoords; varying vec4 Color; @@ -38,11 +38,11 @@ varying float FragDistance; void main() { vec4 worldPos = aTransform * vec4(aPos, 1.); - mat3 normalMat = aNormalMat; + vec3 norm = aNormalMat * aNormal; #ifdef CONTRAPTION worldPos = uModel * worldPos; - normalMat *= modelToNormal(uModel); + norm = modelToNormal(uModel) * norm; BoxCoord = (worldPos.xyz - uLightBoxMin) / uLightBoxSize; #if defined(USE_FOG) @@ -52,7 +52,7 @@ void main() { FragDistance = length(worldPos.xyz - uCameraPos); #endif - vec3 norm = normalize(normalMat * aNormal); + norm = normalize(norm); Diffuse = diffuse(norm); TexCoords = aTexCoords; diff --git a/src/main/resources/assets/create/flywheel/shaders/oriented.vert b/src/main/resources/assets/create/flywheel/shaders/oriented.vert new file mode 100644 index 000000000..d32feca3b --- /dev/null +++ b/src/main/resources/assets/create/flywheel/shaders/oriented.vert @@ -0,0 +1,63 @@ +#version 110 + +#flwinclude <"create:core/matutils.glsl"> +#flwinclude <"create:core/quaternion.glsl"> +#flwinclude <"create:core/diffuse.glsl"> + +attribute vec3 aPos; +attribute vec3 aNormal; +attribute vec2 aTexCoords; + +attribute vec2 aLight; +attribute vec4 aColor; +attribute vec3 aInstancePos; +attribute vec3 aPivot; +attribute vec4 aRotation; + +varying vec2 TexCoords; +varying vec4 Color; +varying float Diffuse; +varying vec2 Light; + +#if defined(CONTRAPTION) +varying vec3 BoxCoord; + +uniform vec3 uLightBoxSize; +uniform vec3 uLightBoxMin; +uniform mat4 uModel; +#endif + +uniform float uTime; +uniform mat4 uViewProjection; +uniform int uDebug; + +uniform vec3 uCameraPos; + +#if defined(USE_FOG) +varying float FragDistance; +#endif + +void main() { + vec4 worldPos = vec4(rotateVertexByQuat(aPos - aPivot, aRotation) + aPivot + aInstancePos, 1.); + + vec3 norm = rotateVertexByQuat(aNormal, aRotation); + +#ifdef CONTRAPTION + worldPos = uModel * worldPos; + norm = normalize(modelToNormal(uModel) * norm); + + BoxCoord = (worldPos.xyz - uLightBoxMin) / uLightBoxSize; + #if defined(USE_FOG) + FragDistance = length(worldPos.xyz); + #endif +#elif defined(USE_FOG) + FragDistance = length(worldPos.xyz - uCameraPos); +#endif + + Diffuse = diffuse(norm); + TexCoords = aTexCoords; + Light = aLight; + gl_Position = uViewProjection * worldPos; + + Color = aColor; +} \ No newline at end of file diff --git a/src/main/resources/assets/create/flywheel/shaders/rotating.vert b/src/main/resources/assets/create/flywheel/shaders/rotating.vert index f183276f9..091e16faa 100644 --- a/src/main/resources/assets/create/flywheel/shaders/rotating.vert +++ b/src/main/resources/assets/create/flywheel/shaders/rotating.vert @@ -9,9 +9,9 @@ attribute vec3 aPos; attribute vec3 aNormal; attribute vec2 aTexCoords; -attribute vec3 aInstancePos; attribute vec2 aLight; -attribute vec3 aNetworkTint; +attribute vec4 aColor; +attribute vec3 aInstancePos; attribute float aSpeed; attribute float aOffset; attribute vec3 aAxis; @@ -54,7 +54,7 @@ void main() { #ifdef CONTRAPTION worldPos = uModel * worldPos; - norm = modelToNormal(uModel) * norm; + norm = normalize(modelToNormal(uModel) * norm); BoxCoord = (worldPos.xyz - uLightBoxMin) / uLightBoxSize; #if defined(USE_FOG) @@ -77,7 +77,7 @@ void main() { } #else if (uDebug == 1) { - Color = vec4(aNetworkTint, 1.); + Color = aColor; } else if (uDebug == 2) { Color = vec4(norm, 1.); } else { From 20189a86fc44bdda5b456267110053c434f52b4d Mon Sep 17 00:00:00 2001 From: JozsefA Date: Tue, 23 Mar 2021 00:08:31 -0700 Subject: [PATCH 12/14] Spicy light update listening api. - Round 1, no profiling done yet, not everything uses it. - WeakHashSet could be useful elsewhere, too. --- .../structureMovement/ContraptionLighter.java | 37 +++- .../NonStationaryLighter.java | 2 + .../render/ActorInstance.java | 2 +- .../render/ContraptionKineticRenderer.java | 9 +- .../render/ContraptionRenderDispatcher.java | 6 - .../foundation/mixin/LightUpdateMixin.java | 3 +- .../mixin/NetworkLightUpdateMixin.java | 20 +- .../backend/light/LightUpdateListener.java | 26 +++ .../render/backend/light/LightUpdater.java | 198 ++++++++++++++++++ .../render/backend/light/LightVolume.java | 10 +- .../foundation/utility/WeakHashSet.java | 114 ++++++++++ 11 files changed, 400 insertions(+), 27 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/render/backend/light/LightUpdateListener.java create mode 100644 src/main/java/com/simibubi/create/foundation/render/backend/light/LightUpdater.java create mode 100644 src/main/java/com/simibubi/create/foundation/utility/WeakHashSet.java diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionLighter.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionLighter.java index ee1f26352..3ab1805e5 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionLighter.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionLighter.java @@ -1,10 +1,15 @@ package com.simibubi.create.content.contraptions.components.structureMovement; +import net.minecraft.world.ILightReader; +import net.minecraft.world.LightType; + import com.simibubi.create.content.contraptions.components.structureMovement.render.RenderedContraption; import com.simibubi.create.foundation.render.backend.light.GridAlignedBB; +import com.simibubi.create.foundation.render.backend.light.LightUpdateListener; +import com.simibubi.create.foundation.render.backend.light.LightUpdater; import com.simibubi.create.foundation.render.backend.light.LightVolume; -public abstract class ContraptionLighter { +public abstract class ContraptionLighter implements LightUpdateListener { protected final C contraption; public final LightVolume lightVolume; @@ -21,14 +26,8 @@ public abstract class ContraptionLighter { lightVolume.initialize(contraption.entity.world); scheduleRebuild = true; - } - protected GridAlignedBB contraptionBoundsToVolume(GridAlignedBB bounds) { - bounds.grow(1); // so we have at least enough data on the edges to avoid artifacts and have smooth lighting - bounds.minY = Math.max(bounds.minY, 0); - bounds.maxY = Math.min(bounds.maxY, 255); - - return bounds; + startListening(); } public void tick(RenderedContraption owner) { @@ -39,4 +38,26 @@ public abstract class ContraptionLighter { } public abstract GridAlignedBB getContraptionBounds(); + + @Override + public void onLightUpdate(ILightReader world, LightType type, GridAlignedBB changed) { + lightVolume.notifyLightUpdate(world, type, changed); + } + + @Override + public void onLightPacket(ILightReader world, int chunkX, int chunkZ) { + lightVolume.notifyLightPacket(world, chunkX, chunkZ); + } + + protected void startListening() { + LightUpdater.getInstance().startListening(bounds, this); + } + + protected GridAlignedBB contraptionBoundsToVolume(GridAlignedBB bounds) { + bounds.grow(1); // so we have at least enough data on the edges to avoid artifacts and have smooth lighting + bounds.minY = Math.max(bounds.minY, 0); + bounds.maxY = Math.min(bounds.maxY, 255); + + return bounds; + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/NonStationaryLighter.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/NonStationaryLighter.java index f93fd9beb..5678f103c 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/NonStationaryLighter.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/NonStationaryLighter.java @@ -25,6 +25,8 @@ public class NonStationaryLighter extends ContraptionLigh if (!contraptionBounds.sameAs(bounds)) { lightVolume.move(contraption.entity.world, contraptionBoundsToVolume(contraptionBounds)); bounds = contraptionBounds; + + startListening(); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ActorInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ActorInstance.java index 3991672c7..9507a05ef 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ActorInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ActorInstance.java @@ -17,6 +17,6 @@ public abstract class ActorInstance { public void beginFrame() { } protected int localBlockLight() { - return modelManager.contraption.renderWorld.getLightLevel(LightType.BLOCK, context.localPos); + return modelManager.getContraption().renderWorld.getLightLevel(LightType.BLOCK, context.localPos); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionKineticRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionKineticRenderer.java index 612f57787..c6b3df6e6 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionKineticRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionKineticRenderer.java @@ -20,16 +20,17 @@ import net.minecraft.world.gen.feature.template.Template; import org.apache.commons.lang3.tuple.Pair; import javax.annotation.Nullable; +import java.lang.ref.WeakReference; import java.util.ArrayList; public class ContraptionKineticRenderer extends InstancedTileRenderer { protected ArrayList actors = new ArrayList<>(); - public final RenderedContraption contraption; + private final WeakReference contraption; ContraptionKineticRenderer(RenderedContraption contraption) { - this.contraption = contraption; + this.contraption = new WeakReference<>(contraption); } @Override @@ -77,6 +78,10 @@ public class ContraptionKineticRenderer extends InstancedTileRenderer> CONTRAPTION = new Compartment<>(); protected static PlacementSimulationWorld renderWorld; - public static void notifyLightUpdate(ILightReader world, LightType type, SectionPos pos) { - for (RenderedContraption renderer : renderers.values()) { - renderer.getLighter().lightVolume.notifyLightUpdate(world, type, pos); - } - } - public static void notifyLightPacket(ILightReader world, int chunkX, int chunkZ) { for (RenderedContraption renderer : renderers.values()) { renderer.getLighter().lightVolume.notifyLightPacket(world, chunkX, chunkZ); diff --git a/src/main/java/com/simibubi/create/foundation/mixin/LightUpdateMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/LightUpdateMixin.java index d55539c7c..81501b16c 100644 --- a/src/main/java/com/simibubi/create/foundation/mixin/LightUpdateMixin.java +++ b/src/main/java/com/simibubi/create/foundation/mixin/LightUpdateMixin.java @@ -11,6 +11,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher; import com.simibubi.create.foundation.render.backend.light.ILightListener; +import com.simibubi.create.foundation.render.backend.light.LightUpdater; import net.minecraft.client.multiplayer.ClientChunkProvider; import net.minecraft.util.math.SectionPos; @@ -54,6 +55,6 @@ public abstract class LightUpdateMixin extends AbstractChunkProvider { }); } - ContraptionRenderDispatcher.notifyLightUpdate(world, type, pos); + LightUpdater.getInstance().onLightUpdate(world, type, pos.asLong()); } } diff --git a/src/main/java/com/simibubi/create/foundation/mixin/NetworkLightUpdateMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/NetworkLightUpdateMixin.java index a40c2c088..9e775c094 100644 --- a/src/main/java/com/simibubi/create/foundation/mixin/NetworkLightUpdateMixin.java +++ b/src/main/java/com/simibubi/create/foundation/mixin/NetworkLightUpdateMixin.java @@ -1,13 +1,19 @@ package com.simibubi.create.foundation.mixin; +import com.simibubi.create.CreateClient; import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher; import com.simibubi.create.foundation.render.backend.RenderWork; import com.simibubi.create.foundation.render.backend.light.ILightListener; +import com.simibubi.create.foundation.render.backend.light.LightUpdater; + import net.minecraft.client.Minecraft; import net.minecraft.client.network.play.ClientPlayNetHandler; import net.minecraft.client.world.ClientWorld; import net.minecraft.network.play.server.SUpdateLightPacket; +import net.minecraft.util.math.SectionPos; import net.minecraft.world.chunk.Chunk; + +import java.util.Map; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -30,14 +36,16 @@ public class NetworkLightUpdateMixin { if (chunk != null) { chunk.getTileEntityMap() - .values() - .stream() - .filter(tile -> tile instanceof ILightListener) - .map(tile -> (ILightListener) tile) - .forEach(ILightListener::onChunkLightUpdate); + .values() + .forEach(tile -> { + CreateClient.kineticRenderer.get(world).onLightUpdate(tile); + + if (tile instanceof ILightListener) + ((ILightListener) tile).onChunkLightUpdate(); + }); } - ContraptionRenderDispatcher.notifyLightPacket(world, chunkX, chunkZ); + LightUpdater.getInstance().onLightPacket(world, chunkX, chunkZ); }); } } diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/light/LightUpdateListener.java b/src/main/java/com/simibubi/create/foundation/render/backend/light/LightUpdateListener.java new file mode 100644 index 000000000..48de4e397 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/backend/light/LightUpdateListener.java @@ -0,0 +1,26 @@ +package com.simibubi.create.foundation.render.backend.light; + +import net.minecraft.world.ILightReader; +import net.minecraft.world.LightType; + +/** + * Anything can implement this, implementors should call {@link LightUpdater#startListening} + * appropriately to make sure they get the updates they want. + */ +public interface LightUpdateListener { + + /** + * Called when a light updates in a chunk the implementor cares about. + */ + void onLightUpdate(ILightReader world, LightType type, GridAlignedBB changed); + + /** + * Called when the server sends light data to the client. + */ + default void onLightPacket(ILightReader world, int chunkX, int chunkZ) { + GridAlignedBB changedVolume = GridAlignedBB.fromChunk(chunkX, chunkZ); + + onLightUpdate(world, LightType.BLOCK, changedVolume); + onLightUpdate(world, LightType.SKY, changedVolume); + } +} diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/light/LightUpdater.java b/src/main/java/com/simibubi/create/foundation/render/backend/light/LightUpdater.java new file mode 100644 index 000000000..dc6a7ca7b --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/backend/light/LightUpdater.java @@ -0,0 +1,198 @@ +package com.simibubi.create.foundation.render.backend.light; + +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.longs.LongRBTreeSet; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.SectionPos; +import net.minecraft.world.ILightReader; +import net.minecraft.world.LightType; + +import java.util.*; +import java.util.function.LongConsumer; +import com.simibubi.create.foundation.utility.WeakHashSet; + +/** + * By using WeakReferences we can automatically remove listeners when they are garbage collected. + * This allows us to easily be more clever about how we store the listeners. Each listener is associated + * with 2 sets of longs indicating what chunks and sections each listener is in. Additionally, a reverse + * mapping is created to allow for fast lookups when light updates. The reverse mapping is more interesting, + * but {@link #listenersToSections}, and {@link #listenersToChunks} are used to know what sections and + * chunks we need to remove the listeners from if they re-subscribe. Otherwise, listeners could get updates + * they no longer care about. This is done in {@link #clearSections} and {@link #clearChunks} + */ +public class LightUpdater { + + private static LightUpdater instance; + + public static LightUpdater getInstance() { + if (instance == null) + instance = new LightUpdater(); + + return instance; + } + + private final Long2ObjectMap> sections; + private final WeakHashMap listenersToSections; + + private final Long2ObjectMap> chunks; + private final WeakHashMap listenersToChunks; + + public LightUpdater() { + sections = new Long2ObjectOpenHashMap<>(); + listenersToSections = new WeakHashMap<>(); + + chunks = new Long2ObjectOpenHashMap<>(); + listenersToChunks = new WeakHashMap<>(); + } + + /** + * Add a listener associated with the given {@link BlockPos}. + * + * When a light update occurs in the chunk the position is contained in, + * {@link LightUpdateListener#onLightUpdate} will be called. + * + * @param pos The position in the world that the listener cares about. + * @param listener The object that wants to receive light update notifications. + */ + public void startListening(BlockPos pos, LightUpdateListener listener) { + LongRBTreeSet sections = clearSections(listener); + LongRBTreeSet chunks = clearChunks(listener); + + long sectionPos = worldToSection(pos); + addToSection(sectionPos, listener); + sections.add(sectionPos); + + long chunkPos = sectionToChunk(sectionPos); + addToChunk(chunkPos, listener); + chunks.add(chunkPos); + } + + /** + * Add a listener associated with the given {@link GridAlignedBB}. + * + * When a light update occurs in any chunk spanning the given volume, + * {@link LightUpdateListener#onLightUpdate} will be called. + * + * @param volume The volume in the world that the listener cares about. + * @param listener The object that wants to receive light update notifications. + */ + public void startListening(GridAlignedBB volume, LightUpdateListener listener) { + LongRBTreeSet sections = clearSections(listener); + LongRBTreeSet chunks = clearSections(listener); + + int minX = SectionPos.toChunk(volume.minX); + int minY = SectionPos.toChunk(volume.minY); + int minZ = SectionPos.toChunk(volume.minZ); + int maxX = SectionPos.toChunk(volume.maxX); + int maxY = SectionPos.toChunk(volume.maxY); + int maxZ = SectionPos.toChunk(volume.maxZ); + + for (int x = minX; x <= maxX; x++) { + for (int z = minZ; z <= maxZ; z++) { + for (int y = minY; y <= maxY; y++) { + long sectionPos = SectionPos.asLong(x, y, z); + addToSection(sectionPos, listener); + sections.add(sectionPos); + } + long chunkPos = SectionPos.asLong(x, 0, z); + addToChunk(chunkPos, listener); + chunks.add(chunkPos); + } + } + } + + /** + * Dispatch light updates to all registered {@link LightUpdateListener}s. + * + * @param world The world in which light was updated. + * @param type The type of light that changed. + * @param sectionPos A long representing the section position where light changed. + */ + public void onLightUpdate(ILightReader world, LightType type, long sectionPos) { + WeakHashSet set = sections.get(sectionPos); + + if (set == null || set.isEmpty()) return; + + GridAlignedBB chunkBox = GridAlignedBB.fromSection(SectionPos.from(sectionPos)); + + for (LightUpdateListener listener : set) { + listener.onLightUpdate(world, type, chunkBox.copy()); + } + + } + + /** + * Dispatch light updates to all registered {@link LightUpdateListener}s + * when the server sends lighting data for an entire chunk. + * + * @param world The world in which light was updated. + */ + public void onLightPacket(ILightReader world, int chunkX, int chunkZ) { + + long chunkPos = SectionPos.asLong(chunkX, 0, chunkZ); + + WeakHashSet set = chunks.get(chunkPos); + + if (set == null || set.isEmpty()) return; + + for (LightUpdateListener listener : set) { + listener.onLightPacket(world, chunkX, chunkZ); + } + + } + + private LongRBTreeSet clearChunks(LightUpdateListener listener) { + return clear(listener, listenersToChunks, chunks); + } + + private LongRBTreeSet clearSections(LightUpdateListener listener) { + return clear(listener, listenersToSections, sections); + } + + private LongRBTreeSet clear(LightUpdateListener listener, WeakHashMap listeners, Long2ObjectMap> lookup) { + LongRBTreeSet set = listeners.get(listener); + + if (set == null) { + set = new LongRBTreeSet(); + listeners.put(listener, set); + } else { + set.forEach((LongConsumer) l -> { + WeakHashSet listeningSections = lookup.get(l); + + if (listeningSections != null) listeningSections.remove(listener); + }); + + set.clear(); + } + + return set; + } + + private void addToSection(long sectionPos, LightUpdateListener listener) { + getOrCreate(sections, sectionPos).add(listener); + } + + private void addToChunk(long chunkPos, LightUpdateListener listener) { + getOrCreate(chunks, chunkPos).add(listener); + } + + private WeakHashSet getOrCreate(Long2ObjectMap> sections, long chunkPos) { + WeakHashSet set = sections.get(chunkPos); + + if (set == null) { + set = new WeakHashSet<>(); + sections.put(chunkPos, set); + } + + return set; + } + + public static long worldToSection(BlockPos pos) { + return SectionPos.asLong(pos.getX(), pos.getY(), pos.getZ()); + } + + public static long sectionToChunk(long sectionPos) { + return sectionPos & 0xFFFFFFFFFFF_00000L; + } +} diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/light/LightVolume.java b/src/main/java/com/simibubi/create/foundation/render/backend/light/LightVolume.java index 5f9290974..7c80e0765 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/light/LightVolume.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/light/LightVolume.java @@ -123,17 +123,21 @@ public class LightVolume { } } - public void notifyLightUpdate(ILightReader world, LightType type, SectionPos location) { - GridAlignedBB changedVolume = GridAlignedBB.fromSection(location); + public void notifyLightUpdate(ILightReader world, LightType type, GridAlignedBB changedVolume) { + if (removed) + return; + if (!changedVolume.intersects(sampleVolume)) return; - changedVolume.intersectAssign(sampleVolume); // compute the region contained by us that has dirty lighting data. + changedVolume = changedVolume.intersect(sampleVolume); // compute the region contained by us that has dirty lighting data. if (type == LightType.BLOCK) copyBlock(world, changedVolume); else if (type == LightType.SKY) copySky(world, changedVolume); } public void notifyLightPacket(ILightReader world, int chunkX, int chunkZ) { + if (removed) return; + GridAlignedBB changedVolume = GridAlignedBB.fromChunk(chunkX, chunkZ); if (!changedVolume.intersects(sampleVolume)) return; diff --git a/src/main/java/com/simibubi/create/foundation/utility/WeakHashSet.java b/src/main/java/com/simibubi/create/foundation/utility/WeakHashSet.java new file mode 100644 index 000000000..e4c5c6688 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/utility/WeakHashSet.java @@ -0,0 +1,114 @@ +package com.simibubi.create.foundation.utility; + +import net.minecraft.util.Unit; + +import java.util.*; + +public class WeakHashSet extends AbstractSet { + + WeakHashMap map; + + public WeakHashSet() { + map = new WeakHashMap<>(); + } + + /** + * Constructs a new set containing the elements in the specified + * collection. The HashMap is created with default load factor + * (0.75) and an initial capacity sufficient to contain the elements in + * the specified collection. + * + * @param c the collection whose elements are to be placed into this set + * @throws NullPointerException if the specified collection is null + */ + public WeakHashSet(Collection c) { + map = new WeakHashMap<>(Math.max((int) (c.size()/.75f) + 1, 16)); + addAll(c); + } + + /** + * Constructs a new, empty set; the backing HashMap instance has + * the specified initial capacity and the specified load factor. + * + * @param initialCapacity the initial capacity of the hash map + * @param loadFactor the load factor of the hash map + * @throws IllegalArgumentException if the initial capacity is less + * than zero, or if the load factor is nonpositive + */ + public WeakHashSet(int initialCapacity, float loadFactor) { + map = new WeakHashMap<>(initialCapacity, loadFactor); + } + + /** + * Constructs a new, empty set; the backing HashMap instance has + * the specified initial capacity and default load factor (0.75). + * + * @param initialCapacity the initial capacity of the hash table + * @throws IllegalArgumentException if the initial capacity is less + * than zero + */ + public WeakHashSet(int initialCapacity) { + map = new WeakHashMap<>(initialCapacity); + } + + + @Override + public Iterator iterator() { + return map.keySet().iterator(); + } + + @Override + public int size() { + return map.size(); + } + + @Override + public boolean add(T t) { + return map.put(t, Unit.INSTANCE) == null; + } + + @Override + public boolean remove(Object o) { + return map.remove((T) o) != null; + } + + @Override + public boolean isEmpty() { + return map.isEmpty(); + } + + @Override + public boolean contains(Object o) { + return map.containsKey((T) o); + } + + @Override + public Object[] toArray() { + return map.keySet().toArray(); + } + + @Override + public boolean containsAll(Collection c) { + return c.stream().allMatch(map::containsKey); + } + + @Override + public boolean addAll(Collection c) { + return false; + } + + @Override + public boolean retainAll(Collection c) { + return false; + } + + @Override + public boolean removeAll(Collection c) { + return false; + } + + @Override + public void clear() { + map.clear(); + } +} From 5eae3a53fc71e631bc1a7641a028a0a201360b67 Mon Sep 17 00:00:00 2001 From: JozsefA Date: Tue, 23 Mar 2021 02:12:09 -0700 Subject: [PATCH 13/14] Keeps getting hotter. - Belts now use the new system. - Remove ILightListener.java. - Listeners can choose to remove themselves. - Rename some static GridAlignedBB methods. --- .../structureMovement/Contraption.java | 2 +- .../structureMovement/ContraptionLighter.java | 6 +- .../NonStationaryLighter.java | 2 +- .../bearing/AnchoredLighter.java | 2 +- .../piston/PistonLighter.java | 2 +- .../pulley/PulleyLighter.java | 2 +- .../relays/belt/BeltRenderer.java | 6 +- .../relays/belt/BeltTileEntity.java | 84 +++++++++++++++---- .../foundation/mixin/LightUpdateMixin.java | 4 - .../mixin/NetworkLightUpdateMixin.java | 4 - .../render/backend/light/GridAlignedBB.java | 16 +++- .../render/backend/light/ILightListener.java | 5 -- .../backend/light/LightUpdateListener.java | 16 ++-- .../render/backend/light/LightUpdater.java | 12 +-- .../render/backend/light/LightVolume.java | 3 +- 15 files changed, 106 insertions(+), 60 deletions(-) delete mode 100644 src/main/java/com/simibubi/create/foundation/render/backend/light/ILightListener.java 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 40ae4a7b0..b4dab5758 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 @@ -1094,7 +1094,7 @@ public abstract class Contraption { GridAlignedBB betterBounds = GridAlignedBB.ofRadius(radius); - GridAlignedBB contraptionBounds = GridAlignedBB.fromAABB(bounds); + GridAlignedBB contraptionBounds = GridAlignedBB.from(bounds); if (axis == Direction.Axis.X) { betterBounds.maxX = contraptionBounds.maxX; betterBounds.minX = contraptionBounds.minX; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionLighter.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionLighter.java index 3ab1805e5..697fb4a63 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionLighter.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionLighter.java @@ -40,13 +40,15 @@ public abstract class ContraptionLighter implements Light public abstract GridAlignedBB getContraptionBounds(); @Override - public void onLightUpdate(ILightReader world, LightType type, GridAlignedBB changed) { + public boolean onLightUpdate(ILightReader world, LightType type, GridAlignedBB changed) { lightVolume.notifyLightUpdate(world, type, changed); + return false; } @Override - public void onLightPacket(ILightReader world, int chunkX, int chunkZ) { + public boolean onLightPacket(ILightReader world, int chunkX, int chunkZ) { lightVolume.notifyLightPacket(world, chunkX, chunkZ); + return false; } protected void startListening() { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/NonStationaryLighter.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/NonStationaryLighter.java index 5678f103c..c20a34145 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/NonStationaryLighter.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/NonStationaryLighter.java @@ -32,7 +32,7 @@ public class NonStationaryLighter extends ContraptionLigh @Override public GridAlignedBB getContraptionBounds() { - GridAlignedBB bb = GridAlignedBB.fromAABB(contraption.bounds); + GridAlignedBB bb = GridAlignedBB.from(contraption.bounds); bb.translate(contraption.entity.getPosition()); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/AnchoredLighter.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/AnchoredLighter.java index 09cfa2a39..b5ed7ee45 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/AnchoredLighter.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/AnchoredLighter.java @@ -12,7 +12,7 @@ public class AnchoredLighter extends ContraptionLighter { @Override public GridAlignedBB getContraptionBounds() { - GridAlignedBB bb = GridAlignedBB.fromAABB(contraption.bounds); + GridAlignedBB bb = GridAlignedBB.from(contraption.bounds); bb.translate(contraption.anchor); return bb; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonLighter.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonLighter.java index 1c8ffa5ed..bbc228cb6 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonLighter.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonLighter.java @@ -12,7 +12,7 @@ public class PistonLighter extends ContraptionLighter { @Override public GridAlignedBB getContraptionBounds() { - GridAlignedBB bounds = GridAlignedBB.fromAABB(contraption.bounds); + GridAlignedBB bounds = GridAlignedBB.from(contraption.bounds); bounds.translate(contraption.anchor); int length = contraption.extensionLength; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyLighter.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyLighter.java index 4714a30e3..426a49a4e 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyLighter.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyLighter.java @@ -15,7 +15,7 @@ public class PulleyLighter extends ContraptionLighter { @Override public GridAlignedBB getContraptionBounds() { - GridAlignedBB bounds = GridAlignedBB.fromAABB(contraption.bounds); + GridAlignedBB bounds = GridAlignedBB.from(contraption.bounds); World world = contraption.entity.world; diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltRenderer.java index c8b4c582e..e2cac72ac 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltRenderer.java @@ -294,10 +294,10 @@ public class BeltRenderer extends SafeTileEntityRenderer { } protected int getPackedLight(BeltTileEntity controller, float beltPos) { - BeltTileEntity belt = BeltHelper.getBeltForOffset(controller, beltPos); + int segment = (int) Math.floor(beltPos) * 2; - if (belt == null) return 0; + if (controller.light == null || segment >= controller.light.length) return 0; - return (belt.skyLight << 20) | (belt.blockLight << 4); + return (controller.light[segment + 1] << 20) | (controller.light[segment] << 4); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltTileEntity.java index 4c16a9d29..42efd9396 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltTileEntity.java @@ -23,7 +23,9 @@ import com.simibubi.create.content.contraptions.relays.belt.transport.ItemHandle import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack; import com.simibubi.create.content.logistics.block.belts.tunnel.BrassTunnelTileEntity; import com.simibubi.create.foundation.render.backend.FastRenderDispatcher; -import com.simibubi.create.foundation.render.backend.light.ILightListener; +import com.simibubi.create.foundation.render.backend.light.GridAlignedBB; +import com.simibubi.create.foundation.render.backend.light.LightUpdateListener; +import com.simibubi.create.foundation.render.backend.light.LightUpdater; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour; @@ -46,6 +48,7 @@ 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.ILightReader; import net.minecraft.world.LightType; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.client.model.data.IModelData; @@ -57,7 +60,7 @@ import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; -public class BeltTileEntity extends KineticTileEntity implements ILightListener { +public class BeltTileEntity extends KineticTileEntity implements LightUpdateListener { public Map passengers; public Optional color; @@ -73,8 +76,7 @@ public class BeltTileEntity extends KineticTileEntity implements ILightListener public CompoundNBT trackerUpdateTag; // client - public byte blockLight = -1; - public byte skyLight = -1; + public byte[] light; public static enum CasingType { NONE, ANDESITE, BRASS; @@ -109,8 +111,9 @@ public class BeltTileEntity extends KineticTileEntity implements ILightListener initializeItemHandler(); - if (blockLight == -1) - updateLight(); + if (light == null && isController()) + LightUpdater.getInstance().startListening(getBeltVolume(), this); + initializeLight(); // Move Items if (!isController()) @@ -513,23 +516,68 @@ public class BeltTileEntity extends KineticTileEntity implements ILightListener return 0; } - @Override - public void onChunkLightUpdate() { - updateLight(); - } - @Override public boolean shouldRenderAsTE() { return isController(); } - private void updateLight() { - if (world != null) { - skyLight = (byte) world.getLightLevel(LightType.SKY, pos); - blockLight = (byte) world.getLightLevel(LightType.BLOCK, pos); - } else { - skyLight = -1; - blockLight = -1; + @Override + public boolean onLightUpdate(ILightReader world, LightType type, GridAlignedBB changed) { + if (this.removed) { + return true; + } + + GridAlignedBB beltVolume = getBeltVolume(); + + if (beltVolume.intersects(changed)) { + GridAlignedBB section = changed.intersect(beltVolume); + + if (type == LightType.BLOCK) + section.forEachContained(this::updateBlockLight); + + if (type == LightType.SKY) + section.forEachContained(this::updateSkyLight); + } + + return false; + } + + private GridAlignedBB getBeltVolume() { + BlockPos endPos = controller.offset(getBeltFacing(), beltLength - 1); + + return GridAlignedBB.from(pos, endPos); + } + + private void updateBlockLight(int x, int y, int z) { + int segment = posToSegment(x, y, z) * 2; + + light[segment] = (byte) world.getLightLevel(LightType.BLOCK, new BlockPos(x, y, z)); + } + + private void updateSkyLight(int x, int y, int z) { + int segment = posToSegment(x, y, z) * 2; + + light[segment + 1] = (byte) world.getLightLevel(LightType.SKY, new BlockPos(x, y, z)); + } + + private int posToSegment(int x, int y, int z) { + int dX = Math.abs(controller.getX() - x); + int dY = Math.abs(controller.getY() - y); + int dZ = Math.abs(controller.getZ() - z); + return dY + dX + dZ; + } + + private void initializeLight() { + light = new byte[beltLength * 2]; + + Direction facing = getBeltFacing(); + BlockPos.Mutable pos = new BlockPos.Mutable(controller); + for (int i = 0; i < beltLength; i++) { + int segment = 2 * i; + light[segment] = (byte) world.getLightLevel(LightType.BLOCK, pos); + light[segment + 1] = (byte) world.getLightLevel(LightType.SKY, pos); + + pos.move(facing); } } } diff --git a/src/main/java/com/simibubi/create/foundation/mixin/LightUpdateMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/LightUpdateMixin.java index 81501b16c..3d07bd0bf 100644 --- a/src/main/java/com/simibubi/create/foundation/mixin/LightUpdateMixin.java +++ b/src/main/java/com/simibubi/create/foundation/mixin/LightUpdateMixin.java @@ -10,7 +10,6 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher; -import com.simibubi.create.foundation.render.backend.light.ILightListener; import com.simibubi.create.foundation.render.backend.light.LightUpdater; import net.minecraft.client.multiplayer.ClientChunkProvider; @@ -49,9 +48,6 @@ public abstract class LightUpdateMixin extends AbstractChunkProvider { .map(Map.Entry::getValue) .forEach(tile -> { CreateClient.kineticRenderer.get(world).onLightUpdate(tile); - - if (tile instanceof ILightListener) - ((ILightListener) tile).onChunkLightUpdate(); }); } diff --git a/src/main/java/com/simibubi/create/foundation/mixin/NetworkLightUpdateMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/NetworkLightUpdateMixin.java index 9e775c094..e3eda853e 100644 --- a/src/main/java/com/simibubi/create/foundation/mixin/NetworkLightUpdateMixin.java +++ b/src/main/java/com/simibubi/create/foundation/mixin/NetworkLightUpdateMixin.java @@ -3,7 +3,6 @@ package com.simibubi.create.foundation.mixin; import com.simibubi.create.CreateClient; import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher; import com.simibubi.create.foundation.render.backend.RenderWork; -import com.simibubi.create.foundation.render.backend.light.ILightListener; import com.simibubi.create.foundation.render.backend.light.LightUpdater; import net.minecraft.client.Minecraft; @@ -39,9 +38,6 @@ public class NetworkLightUpdateMixin { .values() .forEach(tile -> { CreateClient.kineticRenderer.get(world).onLightUpdate(tile); - - if (tile instanceof ILightListener) - ((ILightListener) tile).onChunkLightUpdate(); }); } diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/light/GridAlignedBB.java b/src/main/java/com/simibubi/create/foundation/render/backend/light/GridAlignedBB.java index 5ee051229..6d14579f5 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/light/GridAlignedBB.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/light/GridAlignedBB.java @@ -6,6 +6,7 @@ import com.simibubi.create.foundation.render.backend.RenderUtil; import net.minecraft.util.Direction; import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.SectionPos; import net.minecraft.util.math.Vec3i; @@ -34,7 +35,7 @@ public class GridAlignedBB { return new GridAlignedBB(bb.minX, bb.minY, bb.minZ, bb.maxX, bb.maxY, bb.maxZ); } - public static GridAlignedBB fromAABB(AxisAlignedBB aabb) { + public static GridAlignedBB from(AxisAlignedBB aabb) { int minX = (int) Math.floor(aabb.minX); int minY = (int) Math.floor(aabb.minY); int minZ = (int) Math.floor(aabb.minZ); @@ -44,7 +45,7 @@ public class GridAlignedBB { return new GridAlignedBB(minX, minY, minZ, maxX, maxY, maxZ); } - public static GridAlignedBB fromSection(SectionPos pos) { + public static GridAlignedBB from(SectionPos pos) { return new GridAlignedBB(pos.getWorldStartX(), pos.getWorldStartY(), pos.getWorldStartZ(), @@ -53,7 +54,16 @@ public class GridAlignedBB { pos.getWorldEndZ() + 1); } - public static GridAlignedBB fromChunk(int sectionX, int sectionZ) { + public static GridAlignedBB from(BlockPos start, BlockPos end) { + return new GridAlignedBB(start.getX(), + start.getY(), + start.getZ(), + end.getX() + 1, + end.getY() + 1, + end.getZ() + 1); + } + + public static GridAlignedBB from(int sectionX, int sectionZ) { int startX = sectionX << 4; int startZ = sectionZ << 4; return new GridAlignedBB(startX, diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/light/ILightListener.java b/src/main/java/com/simibubi/create/foundation/render/backend/light/ILightListener.java deleted file mode 100644 index 5fd2ff8bd..000000000 --- a/src/main/java/com/simibubi/create/foundation/render/backend/light/ILightListener.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.simibubi.create.foundation.render.backend.light; - -public interface ILightListener { - void onChunkLightUpdate(); -} diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/light/LightUpdateListener.java b/src/main/java/com/simibubi/create/foundation/render/backend/light/LightUpdateListener.java index 48de4e397..eacb5aa59 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/light/LightUpdateListener.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/light/LightUpdateListener.java @@ -11,16 +11,22 @@ public interface LightUpdateListener { /** * Called when a light updates in a chunk the implementor cares about. + * + * @return true if this object is no longer valid and should not receive any more updates. */ - void onLightUpdate(ILightReader world, LightType type, GridAlignedBB changed); + boolean onLightUpdate(ILightReader world, LightType type, GridAlignedBB changed); /** * Called when the server sends light data to the client. + * + * @return true if this object is no longer valid and should not receive any more updates. */ - default void onLightPacket(ILightReader world, int chunkX, int chunkZ) { - GridAlignedBB changedVolume = GridAlignedBB.fromChunk(chunkX, chunkZ); + default boolean onLightPacket(ILightReader world, int chunkX, int chunkZ) { + GridAlignedBB changedVolume = GridAlignedBB.from(chunkX, chunkZ); - onLightUpdate(world, LightType.BLOCK, changedVolume); - onLightUpdate(world, LightType.SKY, changedVolume); + if (onLightUpdate(world, LightType.BLOCK, changedVolume)) + return true; + + return onLightUpdate(world, LightType.SKY, changedVolume); } } diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/light/LightUpdater.java b/src/main/java/com/simibubi/create/foundation/render/backend/light/LightUpdater.java index dc6a7ca7b..634d221b1 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/light/LightUpdater.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/light/LightUpdater.java @@ -114,12 +114,9 @@ public class LightUpdater { if (set == null || set.isEmpty()) return; - GridAlignedBB chunkBox = GridAlignedBB.fromSection(SectionPos.from(sectionPos)); - - for (LightUpdateListener listener : set) { - listener.onLightUpdate(world, type, chunkBox.copy()); - } + GridAlignedBB chunkBox = GridAlignedBB.from(SectionPos.from(sectionPos)); + set.removeIf(listener -> listener.onLightUpdate(world, type, chunkBox.copy())); } /** @@ -136,10 +133,7 @@ public class LightUpdater { if (set == null || set.isEmpty()) return; - for (LightUpdateListener listener : set) { - listener.onLightPacket(world, chunkX, chunkZ); - } - + set.removeIf(listener -> listener.onLightPacket(world, chunkX, chunkZ)); } private LongRBTreeSet clearChunks(LightUpdateListener listener) { diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/light/LightVolume.java b/src/main/java/com/simibubi/create/foundation/render/backend/light/LightVolume.java index 7c80e0765..c61aafc0f 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/light/LightVolume.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/light/LightVolume.java @@ -14,7 +14,6 @@ import com.simibubi.create.foundation.render.backend.RenderWork; import com.simibubi.create.foundation.render.backend.gl.GlTexture; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.SectionPos; import net.minecraft.world.ILightReader; import net.minecraft.world.LightType; @@ -138,7 +137,7 @@ public class LightVolume { public void notifyLightPacket(ILightReader world, int chunkX, int chunkZ) { if (removed) return; - GridAlignedBB changedVolume = GridAlignedBB.fromChunk(chunkX, chunkZ); + GridAlignedBB changedVolume = GridAlignedBB.from(chunkX, chunkZ); if (!changedVolume.intersects(sampleVolume)) return; changedVolume.intersectAssign(sampleVolume); // compute the region contained by us that has dirty lighting data. From 1233ecfe805156e28cf1183b40fd01570d2ef403 Mon Sep 17 00:00:00 2001 From: JozsefA Date: Tue, 23 Mar 2021 14:13:32 -0700 Subject: [PATCH 14/14] Fix belt lighting issues, again. --- .../relays/belt/BeltTileEntity.java | 88 ++++++++++--------- .../render/backend/light/GridAlignedBB.java | 16 ++++ 2 files changed, 64 insertions(+), 40 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltTileEntity.java index 42efd9396..95b756234 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltTileEntity.java @@ -44,10 +44,7 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityType; 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.util.math.*; import net.minecraft.world.ILightReader; import net.minecraft.world.LightType; import net.minecraftforge.api.distmarker.Dist; @@ -111,13 +108,15 @@ public class BeltTileEntity extends KineticTileEntity implements LightUpdateList initializeItemHandler(); - if (light == null && isController()) - LightUpdater.getInstance().startListening(getBeltVolume(), this); - initializeLight(); - // Move Items if (!isController()) return; + + if (light == null && world.isRemote) { + initializeLight(); + LightUpdater.getInstance().startListening(getBeltVolume(), this); + } + getInventory().tick(); if (getSpeed() == 0) @@ -530,54 +529,63 @@ public class BeltTileEntity extends KineticTileEntity implements LightUpdateList GridAlignedBB beltVolume = getBeltVolume(); if (beltVolume.intersects(changed)) { - GridAlignedBB section = changed.intersect(beltVolume); - if (type == LightType.BLOCK) - section.forEachContained(this::updateBlockLight); + updateBlockLight(); if (type == LightType.SKY) - section.forEachContained(this::updateSkyLight); + updateSkyLight(); } return false; } private GridAlignedBB getBeltVolume() { - BlockPos endPos = controller.offset(getBeltFacing(), beltLength - 1); + BlockPos endPos = BeltHelper.getPositionForOffset(this, beltLength - 1); - return GridAlignedBB.from(pos, endPos); - } - - private void updateBlockLight(int x, int y, int z) { - int segment = posToSegment(x, y, z) * 2; - - light[segment] = (byte) world.getLightLevel(LightType.BLOCK, new BlockPos(x, y, z)); - } - - private void updateSkyLight(int x, int y, int z) { - int segment = posToSegment(x, y, z) * 2; - - light[segment + 1] = (byte) world.getLightLevel(LightType.SKY, new BlockPos(x, y, z)); - } - - private int posToSegment(int x, int y, int z) { - int dX = Math.abs(controller.getX() - x); - int dY = Math.abs(controller.getY() - y); - int dZ = Math.abs(controller.getZ() - z); - return dY + dX + dZ; + GridAlignedBB bb = GridAlignedBB.from(pos, endPos); + bb.fixMinMax(); + return bb; } private void initializeLight() { light = new byte[beltLength * 2]; - Direction facing = getBeltFacing(); - BlockPos.Mutable pos = new BlockPos.Mutable(controller); - for (int i = 0; i < beltLength; i++) { - int segment = 2 * i; - light[segment] = (byte) world.getLightLevel(LightType.BLOCK, pos); - light[segment + 1] = (byte) world.getLightLevel(LightType.SKY, pos); + Vec3i vec = getBeltFacing().getDirectionVec(); + BeltSlope slope = getBlockState().get(BeltBlock.SLOPE); + int verticality = slope == BeltSlope.DOWNWARD ? -1 : slope == BeltSlope.UPWARD ? 1 : 0; - pos.move(facing); + BlockPos.Mutable pos = new BlockPos.Mutable(controller); + for (int i = 0; i < beltLength * 2; i += 2) { + light[i] = (byte) world.getLightLevel(LightType.BLOCK, pos); + light[i + 1] = (byte) world.getLightLevel(LightType.SKY, pos); + + pos.move(vec.getX(), verticality, vec.getZ()); + } + } + + private void updateBlockLight() { + Vec3i vec = getBeltFacing().getDirectionVec(); + BeltSlope slope = getBlockState().get(BeltBlock.SLOPE); + int verticality = slope == BeltSlope.DOWNWARD ? -1 : slope == BeltSlope.UPWARD ? 1 : 0; + + BlockPos.Mutable pos = new BlockPos.Mutable(controller); + for (int i = 0; i < beltLength * 2; i += 2) { + light[i] = (byte) world.getLightLevel(LightType.BLOCK, pos); + + pos.move(vec.getX(), verticality, vec.getZ()); + } + } + + private void updateSkyLight() { + Vec3i vec = getBeltFacing().getDirectionVec(); + BeltSlope slope = getBlockState().get(BeltBlock.SLOPE); + int verticality = slope == BeltSlope.DOWNWARD ? -1 : slope == BeltSlope.UPWARD ? 1 : 0; + + BlockPos.Mutable pos = new BlockPos.Mutable(controller); + for (int i = 1; i < beltLength * 2; i += 2) { + light[i] = (byte) world.getLightLevel(LightType.SKY, pos); + + pos.move(vec.getX(), verticality, vec.getZ()); } } } diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/light/GridAlignedBB.java b/src/main/java/com/simibubi/create/foundation/render/backend/light/GridAlignedBB.java index 6d14579f5..305491e33 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/light/GridAlignedBB.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/light/GridAlignedBB.java @@ -91,6 +91,22 @@ public class GridAlignedBB { maxZ == other.maxZ; } + public void fixMinMax() { + int minX = Math.min(this.minX, this.maxX); + int minY = Math.min(this.minY, this.maxY); + int minZ = Math.min(this.minZ, this.maxZ); + int maxX = Math.max(this.minX, this.maxX); + int maxY = Math.max(this.minY, this.maxY); + int maxZ = Math.max(this.minZ, this.maxZ); + + this.minX = minX; + this.minY = minY; + this.minZ = minZ; + this.maxX = maxX; + this.maxY = maxY; + this.maxZ = maxZ; + } + public int sizeX() { return maxX - minX; }